# agentful
> Autonomous product development kit for Claude Code. Transform any project into a 24/7 self-building system with specialized agents.
## Deployment Guide
This guide covers deploying the agentful documentation site and publishing the npm package.
### Quick Start
**For Documentation (GitHub Pages - Recommended):**
1. Enable GitHub Pages (one-time setup, see below)
2. Push to main → Auto-deploys docs
**For Documentation (Cloudflare Pages):**
1. Add GitHub Secrets (2 min)
2. Push to main → Auto-deploys docs
**For npm Publishing:**
3\. Create tag → Auto-publishes to npm
***
### Documentation Deployment
#### Option 1: GitHub Pages (Recommended ⭐)
**Why GitHub Pages?**
* ✅ Built into GitHub - no external services
* ✅ No secrets or API tokens needed
* ✅ Automatic SSL and custom domain support
* ✅ Works out of the box with GitHub Actions
##### One-Time Setup
1. **Enable GitHub Pages** in your repository:
* Go to: [https://github.com/itz4blitz/agentful/settings/pages](https://github.com/itz4blitz/agentful/settings/pages)
* Source: GitHub Actions
2. **Enable Workflows** (if not already enabled):
* Go to: [https://github.com/itz4blitz/agentful/actions](https://github.com/itz4blitz/agentful/actions)
* Click "I understand my workflows, go ahead and enable them"
3. **Push to main:**
```bash
git push origin main
```
Docs will auto-deploy to: `https://itz4blitz.github.io/agentful/`
4. **Custom Domain** (optional - for agentful.app):
* Add CNAME record in your DNS:
```
agentful.app → itz4blitz.github.io
```
* Add custom domain in GitHub Pages settings
##### Manual Deployment
```bash
git push origin main
```
Or trigger manually: [https://github.com/itz4blitz/agentful/actions/workflows/gh-pages.yml](https://github.com/itz4blitz/agentful/actions/workflows/gh-pages.yml)
##### Local Preview
```bash
npm run docs:dev
# Opens at http://localhost:4173
```
***
#### Option 2: Cloudflare Pages
**Why Cloudflare Pages?**
* ✅ Global CDN
* ✅ Fast deployments
* ✅ Preview deployments per PR
* ⚠️ Requires Cloudflare account and API tokens
##### Setup
Add these GitHub Secrets at: [https://github.com/itz4blitz/agentful/settings/secrets/actions](https://github.com/itz4blitz/agentful/settings/secrets/actions)
**1. CLOUDFLARE\_API\_TOKEN**
Create at: [https://dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens)
* Template: "Edit Cloudflare Workers"
* Permissions: Account > Cloudflare Pages > Edit
* Account Resources: Include > Your account
**2. CLOUDFLARE\_ACCOUNT\_ID**
Value: `0dfe9b4c5087b38fdd71f813d6d4bf95`
##### Deployment
```bash
git push origin main
```
Or trigger manually: [https://github.com/itz4blitz/agentful/actions/workflows/deploy-docs.yml](https://github.com/itz4blitz/agentful/actions/workflows/deploy-docs.yml)
##### Configuration
* **Project**: agentful
* **Build command**: `npm run docs:build`
* **Output directory**: `docs/.vocs/dist`
* **Custom domain**: agentful.app
***
### npm Publishing
#### Trusted Publishing (Recommended)
**Why?** More secure than tokens - no long-lived secrets.
**Setup (one-time):**
1. Publish once manually: `npm publish --access public`
2. Go to: [https://www.npmjs.com/package/@itz4blitz/agentful/settings](https://www.npmjs.com/package/@itz4blitz/agentful/settings)
3. Add publisher: GitHub Actions
4. Repository: `itz4blitz/agentful`
**Future releases:**
```bash
git tag v0.2.0
git push origin v0.2.0
# GitHub Actions publishes automatically
```
#### Manual Publishing
```bash
npm publish
```
Requires 2FA to be enabled on your npm account.
***
### Troubleshooting
#### GitHub Pages not deploying?
1. Check Actions: [https://github.com/itz4blitz/agentful/actions](https://github.com/itz4blitz/agentful/actions)
2. Verify GitHub Pages is enabled in repository settings
3. Ensure "Source" is set to "GitHub Actions"
4. Test locally: `npm run docs:build`
#### Cloudflare Pages errors?
1. Verify API\_TOKEN has correct permissions
2. Check ACCOUNT\_ID matches your account
3. Ensure build output exists: `ls docs/.vocs/dist`
#### npm publish fails with 403?
You need 2FA enabled:
[https://www.npmjs.com/settings/itz4blitz/two-factor-authentication](https://www.npmjs.com/settings/itz4blitz/two-factor-authentication)
Or use [Trusted Publishing](#trusted-publishing) for automated releases.
***
### URLs
* **GitHub Actions**: [https://github.com/itz4blitz/agentful/actions](https://github.com/itz4blitz/agentful/actions)
* **Documentation (GitHub Pages)**: [https://itz4blitz.github.io/agentful/](https://itz4blitz.github.io/agentful/)
* **Documentation (Custom Domain)**: [https://agentful.app](https://agentful.app)
* **npm Package**: [https://www.npmjs.com/package/@itz4blitz/agentful](https://www.npmjs.com/package/@itz4blitz/agentful)
***
### Next Steps
* [Contributing Guide](https://github.com/itz4blitz/agentful/blob/main/CONTRIBUTING.md)
* [Publishing Details](https://github.com/itz4blitz/agentful/blob/main/PUBLISHING.md)
* [GitHub Workflows](https://github.com/itz4blitz/agentful/tree/main/.github/workflows)
import { Blue, Orange, Red } from '../components/colored-text.mdx'
## Philosophy
agentful is built on Anthropic's research-validated multi-agent patterns. Here's the philosophy that drives every design decision.
***
### Core Principle: Orchestrator-Worker Pattern
```mermaid
graph TD
A[Orchestrator]
A --> B[Coordinates Work]
A --> C[Never Codes Directly]
A --> D[Validates Results]
B --> E[Delegates to Specialists]
E --> F[Domain Agents]
E --> G[Project-Specific Agents]
E --> H[Temporary Agents]
F --> F1[Backend]
F --> F2[Frontend]
F --> F3[Tester]
F --> F4[Reviewer]
G --> G1[Next.js]
G --> G2[Prisma]
G --> G3[Tailwind]
```
**The orchestrator is the brain - it coordinates, plans, and validates, but NEVER writes code.**
This pattern is validated by Anthropic's own research: a multi-agent system with Claude Opus as orchestrator and Sonnet sub-agents **outperformed single-agent Opus by 90.2%** on internal evals.
#### Why This Works
**Specialization > Generalization**
* Each agent has deep expertise in one domain
* Backend agent focuses ONLY on server-side patterns
* Frontend agent focuses ONLY on UI/UX patterns
* Reviewer agent focuses ONLY on quality validation
**Parallel Execution**
* Sub-agents work on independent tasks simultaneously
* Git worktrees prevent file conflicts
* 90% time reduction for complex work
**Context Isolation**
* Each sub-agent operates in its own context window
* Returns only relevant excerpts to orchestrator
* Prevents "context rot" from bloated conversations
***
### Domain vs Ephemeral Agents
```mermaid
graph TD
A[Agent Types]
A --> B[Domain Agents]
A --> C[Project-Specific]
A --> D[Ephemeral]
B --> B1[Orchestrator]
B --> B2[Backend]
B --> B3[Frontend]
B --> B4[Tester]
B --> B5[Reviewer]
C --> C1[Next.js]
C --> C2[Prisma]
C --> C3[Django]
D --> D1[Migration Agent]
D --> D2[Refactor Agent]
style A fill:#333,stroke:#333,stroke-width:2px,color:#fff
style B fill:#196,stroke:#333,stroke-width:2px,color:#fff
style B1 fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style B2 fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style B3 fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style B4 fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style B5 fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style C fill:#F90,stroke:#333,stroke-width:2px,color:#fff
style C1 fill:#FB0,stroke:#333,stroke-width:1px,color:#fff
style C2 fill:#FB0,stroke:#333,stroke-width:1px,color:#fff
style C3 fill:#FB0,stroke:#333,stroke-width:1px,color:#fff
style D fill:#F00,stroke:#333,stroke-width:2px,color:#fff
style D1 fill:#F55,stroke:#333,stroke-width:1px,color:#fff
style D2 fill:#F55,stroke:#333,stroke-width:1px,color:#fff
```
**Three types of agents**:
1. **Domain agents** - Universal roles used across all projects
2. **Project-specific agents** - Your tech stack, generated once, committed to git
3. **Ephemeral agents** - One-off tasks, deleted when done
#### Domain Agents (Persistent)
**Location**: `.claude/agents/` (committed to git)
**Purpose**: Reusable specialists available across all projects
**Examples**:
* `orchestrator.md` - Coordination (never codes)
* `backend.md` - Server-side implementation
* `frontend.md` - Client-side implementation
* `tester.md` - Test writing and coverage
* `reviewer.md` - Quality validation with veto power
* `fixer.md` - Auto-fixes validation failures
**Lifecycle**: Permanent - refined over time across projects
#### Project-Specific Agents (Generated Once, Persistent)
**Purpose**: Stack-specific specialists for technologies you use every day
**Examples**:
* `nextjs-specialist.md` - Next.js patterns (if you use Next.js)
* `prisma-specialist.md` - Prisma ORM patterns (if you use Prisma)
* `django-specialist.md` - Django patterns (if you use Django)
* `blazor-specialist.md` - Blazor patterns (if you use .NET frontend)
**How They're Created**:
1. Architect analyzes your project on first run
2. Samples actual files to learn YOUR patterns
3. Generates specialist agents with project-specific conventions
4. **You review and commit** to git - these become part of your project
**Why Generated Instead of Manual?**
* Saves time - don't write Next.js agents from scratch
* Learns YOUR actual patterns (not generic templates)
* Adapts to your conventions (file structure, naming, etc.)
**Lifecycle**: Permanent - once generated and committed, they're part of your project forever
#### Ephemeral Agents (Task-Specific, Temporary)
**Purpose**: One-off task-specific agents that won't be reused
**Examples**:
* `migrate-prisma-to-drizzle.md` - Created for a single migration task
* `refactor-auth-system.md` - Created for a specific refactor
* `implement-oauth-provider.md` - Created for a complex one-time feature
**How They're Created**:
1. Architect identifies a complex, unique task
2. Creates specialized agent for that specific task
3. Agent is used during the task
4. **Agent is deleted** after task completes (don't commit to git)
**Why Ephemeral?**
* Don't clutter your agent library with one-offs
* Keep your agent set lean and focused
* Most work should use domain or project-specific agents
**Summary**:
* **Domain agents** = Universal roles (orchestrator, backend, frontend, reviewer)
* **Project-specific agents** = Your tech stack (Next.js, Django, Prisma - generated once, committed)
* **Ephemeral agents** = One-off tasks (temporary, deleted after use)
***
### The Reviewer Has Veto Power
```mermaid
graph TD
A[Implement Feature] --> B[Reviewer Validates]
B --> C{Passes?}
C -->|Yes| D[Merge Complete]
C -->|No| E[Fixer Auto-fixes]
E --> B
D --> F[Quality Gates: ✓ All Pass]
style D fill:#090,stroke:#333,stroke-width:2px,color:#fff
style E fill:#F00,stroke:#333,stroke-width:2px,color:#fff
style F fill:#090,stroke:#333,stroke-width:2px,color:#fff
```
**The reviewer agent is non-negotiable.**
Anthropic's research and community practice converge on this: independent review agents eliminate the need for handholding.
**How It Works**:
1. Any agent implements code
2. Reviewer automatically validates (via PostToolUse hooks)
3. If ANY quality gate fails → reviewer blocks
4. Fixer agent auto-fixes issues
5. Reviewer re-validates
6. Only when ALL gates pass → work is complete
**Quality Gates are tech-agnostic**:
* ✅ All tests passing (pytest, NUnit, Jest, etc.)
* ✅ Type safety (mypy, tsc, dotnet, etc.)
* ✅ Code formatting (black, prettier, rustfmt, etc.)
* ✅ No dead code (unused imports, functions, files)
* ✅ Test coverage ≥ 80%
* ✅ No security issues (hardcoded secrets, debug logs)
**The architect agent detects your stack and configures the appropriate tools automatically.**
**No human supervision needed** - the system polices itself.
***
### Context Management Philosophy
```mermaid
graph TD
A[Long Conversation]
A --> B[Context Rot]
C[Plan Mode]
C --> D[Clear Context]
E[External State]
E --> F[Lean Instructions]
D --> G[Execute]
E --> G
F --> G
G --> H[Compact]
H --> I[Continue]
```
**The Problem**: LLMs suffer from "context rot" - as tokens accumulate, instructions at the beginning lose importance.
**The Solution**:
1. **Keep CLAUDE.md minimal** (\< 150 lines)
2. **Use Plan Mode** for exploration (Shift+Tab twice)
3. **Externalize patterns** to agents and skills
4. **Clear context** with `/clear` before major work
5. **Use `/compact`** strategically during long tasks
6. **External state** in JSON files, not conversation memory
**Result**: Each operation starts with fresh, focused context.
***
### Test-Driven Philosophy
```mermaid
graph TD
A[Write Test] --> B[Test Fails]
B --> C[Implement Code]
C --> D[Test Passes]
D --> E[Review Validates]
style A fill:#19F,stroke:#333,stroke-width:2px,color:#fff
style B fill:#F00,stroke:#333,stroke-width:2px,color:#fff
style C fill:#F90,stroke:#333,stroke-width:2px,color:#fff
style D fill:#090,stroke:#333,stroke-width:2px,color:#fff
style E fill:#19F,stroke:#333,stroke-width:2px,color:#fff
```
**This happens automatically - you don't need to remember this workflow.**
The tester agent follows Anthropic's recommended TDD workflow automatically:
1. Write tests FIRST (based on expected behavior)
2. Confirm tests fail (don't write implementation yet)
3. Commit tests
4. Implement to pass tests (NEVER modify tests)
5. Reviewer validates implementation isn't overfitting
**Why this matters**:
* Prevents AI from hallucinating implementations
* Creates clear acceptance criteria
* Ensures code does exactly what's expected
* Makes it harder to accidentally over-engineer solutions
**Quality hooks verify everything**:
* Never trust claims like "tests are passing"
* Hooks actually run tests and verify results
* The reviewer agent validates implementation quality
***
### Parallel Execution Philosophy
```mermaid
graph TD
A[Independent Work] --> B[Spawn 3-5 Agents]
B --> C[Worktree 1: Feature A]
B --> D[Worktree 2: Feature B]
B --> E[Worktree 3: Feature C]
C --> F[Merge Results]
D --> F
E --> F
style C fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style D fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style E fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style F fill:#090,stroke:#333,stroke-width:2px,color:#fff
```
**This happens automatically under the hood.**
The orchestrator agent detects when features can be built in parallel and automatically creates git worktrees to coordinate multiple agents working simultaneously.
**When to parallelize**:
* ✅ Independent features (auth, user profile, billing)
* ✅ Separate modules (frontend, backend, infrastructure)
* ✅ Clear non-overlapping scopes
**When to run sequentially**:
* ❌ Features that share files
* ❌ Tightly coupled components
* ❌ When merge conflicts cost more than parallel savings
**How it works internally**:
* Git worktrees are created automatically
* Each agent works in isolation
* Results merge back when complete
* No manual intervention needed
***
### Adaptive vs Hardcoded
```mermaid
graph TD
A[Static Tools] --> B[Hardcoded Rules]
B --> C[If package.json has next]
D[agentful] --> E[Claude Intelligence]
E --> F[Sample actual files]
C --> G[❌ Fails on edge cases]
F --> H[✅ Adapts to any project]
style A fill:#666,stroke:#333,stroke-width:2px,color:#fff
style B fill:#666,stroke:#333,stroke-width:1px,color:#fff
style C fill:#666,stroke:#333,stroke-width:1px,color:#fff
style G fill:#F00,stroke:#333,stroke-width:2px,color:#fff
style D fill:#19F,stroke:#333,stroke-width:2px,color:#fff
style E fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style F fill:#19F,stroke:#333,stroke-width:1px,color:#fff
style H fill:#090,stroke:#333,stroke-width:2px,color:#fff
```
**Static tools hardcode patterns**:
```javascript
if (deps.next) {
stack.framework = 'Next.js';
// Assumes App Router
// Assumes TypeScript
// Assumes specific patterns
}
```
**agentful uses Claude to learn**:
```markdown
Sample src/app/page.tsx
→ Uses App Router
→ Uses 'use client' directive
→ Uses Tailwind classes
→ Generate agent with THOSE exact patterns
```
**Result**: Works with ANY language, ANY framework, ANY conventions - because it learns from the actual code.
***
### Self-Healing Philosophy
```mermaid
graph TD
A[Validation Fails]
A --> B[Auto-Fix]
B --> C[Re-Validate]
C --> D{Pass?}
D -->|No| B
D -->|Yes| E[Complete]
A --> F[TypeScript Errors]
A --> G[Dead Code]
A --> H[Coverage Gap]
A --> I[Security Issues]
F --> J[Fixer Agent]
G --> J
H --> J
I --> J
```
**The system should fix itself**:
1. Reviewer finds issues
2. Fixer automatically resolves them
3. Reviewer re-validates
4. Loop until all gates pass
5. No human intervention needed
**What gets auto-fixed (tech-agnostic)**:
* Type errors (proper types instead of `any`/`object`/`dynamic`)
* Dead code (unused imports, functions, files, dependencies)
* Coverage gaps (add tests to reach 80%)
* Security issues (hardcoded secrets, debug logs, API keys)
* Code formatting (inconsistent style, long lines)
* Lint errors (unused variables, missing imports)
**What requires humans**:
* Architecture decisions
* Feature prioritization
* Requirements clarification
***
### The Philosophy in Practice
**What YOU do**:
1. ✏️ Write `PRODUCT.md` - describe what you want to build
2. ▶️ Run `/agentful-start` - begin autonomous development
3. ❓ Answer `/agentful-decide` prompts - when agentful needs clarification
4. 📊 Check `/agentful-status` - see progress anytime
5. ✅ Run `/agentful-validate` - verify quality gates pass
**What agentful does automatically**:
1. Orchestrator analyzes your `PRODUCT.md`
2. Architect generates specialized agents for YOUR tech stack
3. Orchestrator delegates work to specialist agents
4. Tester writes tests FIRST (TDD workflow)
5. Backend/Frontend agents implement features
6. Reviewer validates every change automatically
7. Fixer auto-heals any issues found
8. Loops until 100% complete
**The Result**: You focus on WHAT to build. agentful handles HOW to build it autonomously.
***
### Further Reading
* [Orchestrator Agent Deep Dive](/agents/orchestrator)
* [Domain vs Ephemeral Agents](/agents/custom-agents)
* [Quality Gates](/autonomous-development/quality-gates)
* [Parallel Execution](/workflows/feature-development)
## Bug Fixing Workflow
Complete guide to identifying, isolating, fixing, and validating bug fixes using agentful's systematic workflow.
***
### Overview
The Bug Fixing workflow takes a bug report and systematically resolves it through reproduction, root cause analysis, fix implementation, regression testing, and validation.
#### What This Workflow Delivers
* ✅ Bug reproduction and isolation
* ✅ Root cause identification
* ✅ Minimal, targeted fix
* ✅ Regression tests to prevent recurrence
* ✅ All validation gates passing
* ✅ Documentation of the fix
#### Typical Timeline
| Bug Severity | Time | Iterations |
| -------------------------------------- | ---------------- | ---------- |
| **Trivial** (typos, simple fixes) | 2-5 minutes | 1-2 |
| **Minor** (UI glitches, edge cases) | 5-15 minutes | 2-5 |
| **Moderate** (logic errors, data flow) | 15-45 minutes | 5-10 |
| **Major** (broken features, crashes) | 45 min - 2 hours | 10-20 |
***
### Prerequisites
Before starting bug fixing, ensure:
#### 1. Bug Report Available
Create or locate a bug report with:
```markdown
## Bug Report
### Title
[Clear, concise bug description]
### Severity
[Critical / High / Medium / Low / Trivial]
### Environment
- Browser/OS: Chrome 121 / macOS
- User actions: Steps to reproduce
- Frequency: Always / Sometimes / Once
### Steps to Reproduce
1. Go to /dashboard
2. Click "New Todo" button
3. Enter todo text
4. Press Enter
5. Bug occurs
### Expected Behavior
Todo should be added to list
### Actual Behavior
Todo not visible, console error shown
### Error Messages
TypeError: Cannot read property 'map' of undefined
### Screenshots/Videos
[Attach if applicable]
```
#### 2. Codebase Accessible
```bash
# Repository available
git status
# Dependencies installed
npm install
Can run tests
npm test
Can run dev server
npm run dev
```
#### 3. agentful Initialized
```bash
# agentful ready
ls .claude/agents/
ls .agentful/
```
***
### The Bug Fixing Loop
#### Complete Workflow Diagram
```
┌─────────────────────────────────────────────────────────────┐
│ START: Bug Report Received │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 1. BUG REPORTING │
│ • Document bug details │
│ • Severity assessment │
│ • Environment information │
│ • Steps to reproduce │
│ • Error messages/stack traces │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 2. BUG REPRODUCTION │
│ • Delegate to appropriate agent (@frontend or @backend) │
│ • Follow reproduction steps │
│ • Verify bug exists │
│ • Capture error details │
│ • Identify affected files │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 3. ROOT CAUSE ANALYSIS │
│ • Inspect stack traces │
│ • Trace data flow │
│ • Check recent changes (git log) │
│ • Identify exact line causing issue │
│ • Understand why bug occurs │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 4. FIX IMPLEMENTATION │
│ • Delegate to specialist agent │
│ • Implement minimal fix │
│ • Don't refactor (separate workflow) │
│ • Add inline comment explaining fix │
│ • Ensure no side effects │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 5. REGRESSION TESTING │
│ • Delegate to @tester agent │
│ • Write test that reproduces bug │
│ • Verify test fails before fix │
│ • Verify test passes after fix │
│ • Add related edge case tests │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 6. VALIDATION │
│ • Delegate to @reviewer agent │
│ • Run all quality checks │
│ • Ensure no regressions │
│ • Verify fix doesn't break other features │
└─────────────────────────────────────────────────────────────┘
↓
Issues found?
│
┌──────────┴──────────┐
↓ ↓
┌─────────────────────────┐ ┌─────────────────────────┐
│ 7a. FIX ITERATION(S) │ │ 7b. BUG FIXED │
│ • @fixer resolves │ │ • All checks pass │
│ • Re-validate │ │ • Update progress │
│ • Loop until pass │ │ • Mark bug resolved │
└─────────────────────────┘ └─────────────────────────┘
│ │
└──────────┬──────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 8. DOCUMENTATION │
│ • Update .agentful/completion.json │
│ • Add bug to "bugs-resolved" count │
│ • Document fix in commit message │
│ • Update related documentation if needed │
└─────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────┐
│ 9. NEXT BUG / FEATURE │
│ • Loop back to bug queue or feature queue │
│ • Continue until all bugs resolved │
└─────────────────────────────────────────────────────────────┘
```
***
### Step-by-Step Guide
#### Step 1: Report the Bug
**Input:** Bug discovery or user report
**Bug Report Template:**
```markdown
## Bug: Navigation broken on mobile
**Severity:** High
**Priority:** P1
**Environment:**
- Device: iPhone 12
- Browser: Safari 16
- Screen size: 390x844
- App version: 1.2.0
**Steps to Reproduce:**
1. Open app on mobile device
2. Navigate to Settings page
3. Tap "Notifications" menu item
4. Navigation menu remains open
**Expected Behavior:**
Navigation menu should close after selection
**Actual Behavior:**
Menu stays open, overlaying content
**Console Output:**
```
Warning: setState(...): Can only update a mounted or mounting component.
```
**Frequency:**
Always (100% reproducible)
**Impact:**
Users cannot navigate effectively on mobile devices
**Workaround:**
Manually close menu by tapping outside
```
**Create bug report file:**
```bash
# Create bug report
cat > .agentful/bugs/mobile-navigation.md << 'EOF'
[Paste bug report template above]
EOF
```
***
#### Step 2: Reproduce the Bug
**Agent:** @frontend (for UI bugs) or @backend (for API bugs)
**Time:** 2-10 minutes
**Agent actions:**
```typescript
// Frontend Agent reproducing mobile navigation bug
// 1. Start dev server
// npm run dev
// 2. Access on mobile viewport (390x844)
// 3. Navigate to /settings
// 4. Click "Notifications"
// 5. Observe: Menu still open
// 6. Check browser console
// Warning: setState(...): Can only update a mounted or mounting component.
// 7. Identify affected files
// - src/components/Navigation.tsx
// - src/components/MobileMenu.tsx
// 8. Inspect the code
// src/components/MobileMenu.tsx
export function MobileMenu() {
const [isOpen, setIsOpen] = useState(false);
const handleItemClick = (item: string) => {
router.push(item); // Navigation happens
setIsOpen(false); // ❌ Bug: Component might unmount during navigation
};
return (
);
}
```
**Output:**
```
🔍 Frontend Agent reproducing bug...
Reproducing steps:
✓ Opened dev server (http://localhost:3000)
✓ Set viewport to 390x844 (mobile)
✓ Navigated to /settings
✓ Clicked "Notifications" menu item
Bug reproduced:
✅ Menu remains open after navigation
✅ Console warning: setState(...) on unmounted component
✅ Overlay blocks content interaction
Affected files identified:
• src/components/MobileMenu.tsx (line 15)
• src/components/Navigation.tsx (line 8)
Root cause hypothesis:
setState called after component unmounts during navigation
Time: 4 minutes
```
***
#### Step 3: Root Cause Analysis
**Agent:** @frontend or @backend
**Time:** 3-10 minutes
**Agent analysis:**
```typescript
// Root cause analysis
// 1. Check component lifecycle
export function MobileMenu() {
const [isOpen, setIsOpen] = useState(false);
const mountedRef = useRef(true); // ❌ Missing mount tracking
const handleItemClick = (item: string) => {
router.push(item); // This triggers unmount
setTimeout(() => { // ❌ Delayed setState
setIsOpen(false); // Component might be unmounted here
}, 100);
};
return ;
}
// 2. Why does this happen?
// - router.push() triggers navigation
// - Navigation causes component unmount
// - setTimeout delays setIsOpen
// - setIsOpen runs after unmount → Warning
// 3. Check git history for recent changes
// $ git log --oneline -10
// abc1234 feat: add mobile navigation (2 days ago)
// def5678 fix: menu animation timing
// 4. The bug was introduced in abc1234
// 5. Exact line causing issue:
// src/components/MobileMenu.tsx:15
// setIsOpen(false) called after navigation
```
**Root cause identified:**
```
🔬 Root Cause Analysis
ROOT CAUSE:
setState called after component unmounts during navigation
AFFECTED CODE:
src/components/MobileMenu.tsx, line 15
EXPLANATION:
1. User clicks menu item
2. router.push() triggers navigation (line 14)
3. Navigation causes MobileMenu component to unmount
4. setTimeout fires (line 15)
5. setIsOpen(false) called on unmounted component
6. React warns about setState on unmounted component
WHY IT HAPPENS:
Navigation is synchronous, setState is delayed by setTimeout
Component unmounts before setState executes
INTRODUCED IN:
Commit abc1234 (2 days ago)
"feat: add mobile navigation"
IMPACT:
Mobile users cannot navigate properly
Menu stays open blocking content
Time: 6 minutes
```
***
#### Step 4: Implement Fix
**Agent:** @frontend
**Time:** 2-5 minutes
**Fix implementation:**
```typescript
// BEFORE (buggy code)
export function MobileMenu() {
const [isOpen, setIsOpen] = useState(false);
const handleItemClick = (item: string) => {
router.push(item);
setTimeout(() => {
setIsOpen(false); // ❌ Bug: setState after unmount
}, 100);
};
return ;
}
// AFTER (fixed code)
export function MobileMenu() {
const [isOpen, setIsOpen] = useState(false);
const handleItemClick = (item: string) => {
setIsOpen(false); // ✅ Fix: Close menu BEFORE navigation
router.push(item); // ✅ Navigation happens after menu closes
};
return ;
}
// Alternative fix (if animation needed):
export function MobileMenu() {
const [isOpen, setIsOpen] = useState(false);
const isMountedRef = useRef(true);
useEffect(() => {
return () => {
isMountedRef.current = false; // Track unmount
};
}, []);
const handleItemClick = (item: string) => {
router.push(item);
setTimeout(() => {
if (isMountedRef.current) { // ✅ Check if still mounted
setIsOpen(false);
}
}, 100);
};
return ;
}
```
**Minimal fix principle:**
* ✅ Fix the bug only
* ❌ Don't refactor (use separate workflow)
* ✅ Add comment explaining fix
* ✅ No side effects
**Output:**
```
🔧 Frontend Agent implementing fix...
Modified:
✓ src/components/MobileMenu.tsx
Changes:
- Moved setIsOpen(false) before router.push()
- Added comment explaining fix
- Removed unnecessary setTimeout
Diff:
- const handleItemClick = (item: string) => {
- router.push(item);
- setTimeout(() => {
- setIsOpen(false);
- }, 100);
- };
+ const handleItemClick = (item: string) => {
+ setIsOpen(false); // Close menu before navigation
+ router.push(item);
+ };
Fix applied successfully!
Time: 2 minutes
```
***
#### Step 5: Regression Testing
**Agent:** @tester
**Time:** 5-15 minutes
**Test implementation:**
```typescript
// 1. Test that reproduces bug
// src/components/__tests__/MobileMenu.test.tsx
describe('MobileMenu', () => {
it('should close menu after navigation', async () => {
const mockRouter = {
push: vi.fn(),
};
render();
// Open menu
fireEvent.click(screen.getByText('Menu'));
expect(screen.getByRole('menu')).toBeVisible();
// Click menu item
fireEvent.click(screen.getByText('Notifications'));
// Verify menu closed
await waitFor(() => {
expect(screen.queryByRole('menu')).not.toBeVisible();
});
// Verify navigation occurred
expect(mockRouter.push).toHaveBeenCalledWith('/settings/notifications');
});
it('should not cause setState warning on unmount', async () => {
const mockRouter = {
push: vi.fn(),
};
const { unmount } = render();
// Open menu
fireEvent.click(screen.getByText('Menu'));
// Click item that causes navigation/unmount
fireEvent.click(screen.getByText('Notifications'));
// Unmount manually (simulating navigation)
unmount();
// Should not throw setState warning
// Test will fail if setState called after unmount
expect(() => {
// Small delay to catch any delayed setState calls
vi.advanceTimersByTime(200);
}).not.toThrow();
});
it('should handle rapid menu item clicks', async () => {
const mockRouter = {
push: vi.fn(),
};
render();
// Open menu
fireEvent.click(screen.getByText('Menu'));
// Rapidly click multiple items
fireEvent.click(screen.getByText('Notifications'));
fireEvent.click(screen.getByText('Profile'));
fireEvent.click(screen.getByText('Settings'));
// Should only navigate once (last click)
expect(mockRouter.push).toHaveBeenCalledTimes(1);
expect(mockRouter.push).toHaveBeenCalledWith('/settings');
// Menu should be closed
expect(screen.queryByRole('menu')).not.toBeVisible();
});
});
// 2. Integration test for full navigation flow
// e2e/mobile-navigation.spec.ts
test.describe('Mobile Navigation', () => {
test('should close menu after navigation', async ({ page }) => {
// Set mobile viewport
await page.setViewportSize({ width: 390, height: 844 });
// Navigate to settings
await page.goto('/settings');
// Open menu
await page.click('[aria-label="Menu"]');
await expect(page.locator('[role="menu"]')).toBeVisible();
// Click menu item
await page.click('text=Notifications');
// Verify menu closed
await expect(page.locator('[role="menu"]')).not.toBeVisible();
// Verify navigation occurred
await expect(page).toHaveURL('/settings/notifications');
// Verify no console errors
const errors = [];
page.on('console', msg => {
if (msg.type() === 'error') errors.push(msg.text());
});
expect(errors.length).toBe(0);
});
});
```
**Output:**
```
🧪 Tester Agent writing regression tests...
Created:
✓ src/components/__tests__/MobileMenu.test.tsx (3 tests)
✓ e2e/mobile-navigation.spec.ts (1 test)
Running tests...
Before fix:
✗ should close menu after navigation (FAILED)
Expected menu to close, but it remained open
✗ should not cause setState warning (FAILED)
setState warning detected in console
After fix:
✓ should close menu after navigation (PASSED)
✓ should not cause setState warning (PASSED)
✓ should handle rapid menu item clicks (PASSED)
Regression tests added: 4
Coverage: +12% for MobileMenu component
Time: 8 minutes
```
***
#### Step 6: Validation
**Agent:** @reviewer
**Time:** 1-2 minutes
**Validation checks:**
```bash
# 1. TypeScript
npx tsc --noEmit
✓ No type errors
# 2. Lint
npm run lint
✓ No lint errors
# 3. Dead Code
npx knip
✓ No dead code
# 4. Tests
npm test
✓ All tests passing (including new regression tests)
# 5. Coverage
npm test -- --coverage
✓ Coverage maintained (no decrease)
# 6. Security
npm audit --production
✓ No vulnerabilities
# 7. Regression check
# Verify fix doesn't break other navigation
npm test -- --testNamePattern="Navigation"
✓ All navigation tests still passing
```
**Output:**
```
🔍 Reviewer Agent validating fix...
Quality Gates:
✅ TypeScript: No errors (0 issues)
✅ Lint: No errors (0 issues)
✅ Dead Code: None (0 issues)
✅ Tests: All passing (47/47)
✅ Coverage: 84% (maintained)
✅ Security: No issues (0 vulnerabilities)
✅ Regression: No broken features
Overall: ✅ PASSED
Bug fix validated!
Time: 45 seconds
```
***
#### Step 7: Update Completion
**Agent:** @orchestrator
**Time:** Instant
**State update:**
```json
// .agentful/completion.json
{
"bugs_resolved": {
"mobile-navigation": {
"id": "bug-001",
"title": "Navigation broken on mobile",
"severity": "High",
"status": "resolved",
"fixed_at": "2026-01-18T01:30:00Z",
"files_modified": [
"src/components/MobileMenu.tsx"
],
"tests_added": 4,
"commit_hash": "xyz789"
}
},
"bugs_active": []
}
// .agentful/state.json
{
"current_task": null,
"current_phase": "idle",
"iterations": 3,
"bugs_fixed_this_session": 1
}
```
**Commit message:**
```bash
git add .
git commit -m "fix: close mobile menu before navigation
Fixes bug where mobile navigation menu remained open after
menu item selection, blocking content interaction.
Root cause:
setState called after component unmounts during navigation.
Solution:
Close menu synchronously before triggering navigation.
Tests:
- Added 3 unit tests for menu close behavior
- Added 1 E2E test for mobile navigation flow
- Verified no setState warnings in console
Fixes: #123
```
**Output:**
```
✅ Bug Fixed: Mobile Navigation
Severity: High
Time to fix: 22 minutes
Iterations: 3
Files modified: 1
Tests added: 4
Coverage maintained: 84%
Quality gates: All passing
Regressions: None detected
Bug resolved and committed!
Commit: xyz789
```
***
### Real Example: Debugging API Error
#### Bug Report
```markdown
## Bug: User profile returns 500 error
**Severity:** High
**Steps to Reproduce:**
1. Login as user
2. Navigate to /profile
3. Page shows error message
**Expected:**
Profile page displays user information
**Actual:**
"Internal server error" message
**Console:**
GET /api/user/profile 500
```
***
#### Reproduction
**Agent:** @backend
```typescript
// Backend Agent reproducing bug
// 1. Start dev server
// npm run dev
// 2. Make API request
// GET /api/user/profile
// 3. Observe error
// Error: Cannot read property 'email' of undefined
// 4. Check server logs
// TypeError: Cannot read property 'email' of undefined
// at src/services/user.service.ts:15
// 5. Inspect the code
// src/app/api/user/profile/route.ts
export async function GET(req: NextRequest) {
const session = await getSession(req); // Returns null if not authenticated
const service = new UserService();
const profile = await service.getProfile(session.user.id); // ❌ session is null
// ↑
// src/services/user.service.ts Error here
export class UserService {
async getProfile(userId: string) {
return this.userRepository.findById(userId);
}
}
```
**Root cause:**
```
ROOT CAUSE:
getSession() returns null, code doesn't handle this case
AFFECTED CODE:
src/app/api/user/profile/route.ts:8
EXPLANATION:
1. User session expires or is invalid
2. getSession() returns null
3. Code tries to access null.user.id
4. TypeError: Cannot read property 'email' of undefined
FIX NEEDED:
Add null check for session before accessing user data
```
***
#### Fix Implementation
```typescript
// BEFORE (buggy)
export async function GET(req: NextRequest) {
const session = await getSession(req);
const service = new UserService();
const profile = await service.getProfile(session.user.id); // ❌ Crashes
return NextResponse.json(profile);
}
// AFTER (fixed)
export async function GET(req: NextRequest) {
const session = await getSession(req);
// ✅ Handle null session
if (!session || !session.user) {
return NextResponse.json(
{ error: 'Unauthorized' },
{ status: 401 }
);
}
const service = new UserService();
const profile = await service.getProfile(session.user.id);
return NextResponse.json(profile);
}
```
***
#### Regression Tests
```typescript
// src/app/api/user/__tests__/profile.test.ts
describe('GET /api/user/profile', () => {
it('should return user profile for authenticated user', async () => {
const session = { user: { id: '123', email: 'test@example.com' } };
getSession.mockResolvedValue(session);
const res = await request(app).get('/api/user/profile');
expect(res.status).toBe(200);
expect(res.body).toHaveProperty('email', 'test@example.com');
});
it('should return 401 when session is null', async () => {
getSession.mockResolvedValue(null); // Simulate expired session
const res = await request(app).get('/api/user/profile');
expect(res.status).toBe(401);
expect(res.body).toHaveProperty('error', 'Unauthorized');
});
it('should return 401 when session.user is missing', async () => {
const session = {}; // Session exists but no user
getSession.mockResolvedValue(session);
const res = await request(app).get('/api/user/profile');
expect(res.status).toBe(401);
expect(res.body).toHaveProperty('error', 'Unauthorized');
});
});
```
***
#### Result
```
✅ Bug Fixed: User Profile API Error
Files modified: 1
Tests added: 3
Time: 18 minutes
Validation: All gates passing
Regressions: None
```
***
### Handling Edge Cases
#### Case 1: Bug Can't Be Reproduced
```
🔍 Attempting to reproduce bug...
Following steps:
1. Go to /dashboard ✓
2. Click "Export" ✓
3. Wait for download...
Result: ✗ Bug NOT reproduced
Download worked correctly
Possible reasons:
- Environment-specific (browser, OS, device)
- Timing/race condition
- Already fixed in latest version
- Incomplete reproduction steps
Action:
Added to decisions.json for user input:
"Unable to reproduce bug. Please provide:
- Browser version
- Console errors
- Network tab errors
- Screenshots/video"
Run /agentful-decide to provide more information.
```
***
#### Case 2: Multiple Root Causes
```
🔬 Root cause analysis...
Multiple potential causes identified:
1. Race condition in data fetching (src/hooks/useData.ts:23)
2. Missing error boundary in component tree
3. API returning inconsistent data types
Recommended approach:
Fix most likely cause first (race condition)
Add regression tests
Validate
If bug persists, fix next cause
Delegating to @frontend to fix race condition...
```
***
#### Case 3: Fix Causes New Bugs
```
🔍 Validating fix...
❌ VALIDATION FAILED
New issues found:
1. Test: mobile-menu-spacing (FAILED)
Menu now closes too quickly, animation looks jerky
2. Test: rapid-navigation (FAILED)
Second navigation not working
Action: Reverting fix, using alternative approach
🔧 Implementing alternative fix...
Using isMountedRef pattern instead
Preserves animation while preventing setState error
✅ Validation passed
```
***
### Best Practices
#### 1. Create Detailed Bug Reports
Good bug reports speed up fixing:
**Good:**
```markdown
## Steps to Reproduce
1. Go to /dashboard
2. Click "Add Widget" button
3. Select "Weather" widget
4. Click "Add"
5. Widget not visible
## Expected
Weather widget appears on dashboard
## Actual
Widget not visible, console error:
"TypeError: widget.type is undefined"
## Environment
Chrome 121, macOS 14, screen size 1920x1080
```
**Bad:**
```markdown
## Bug
Dashboard not working
## What I did
Clicked some buttons
## What happened
Doesn't work
```
***
#### 2. Fix Root Cause, Not Symptoms
**Symptom fix (bad):**
```typescript
// Suppress the error
try {
setIsOpen(false);
} catch (e) {
// Ignore error
}
```
**Root cause fix (good):**
```typescript
// Fix the actual problem
setIsOpen(false); // Before navigation
router.push(item);
```
***
#### 3. Add Regression Tests
Always add tests that:
* Reproduce the bug
* Verify the fix
* Prevent recurrence
```typescript
it('should [description of bug]', () => {
// Arrange: Setup conditions that caused bug
// Act: Perform actions that triggered bug
// Assert: Verify bug is fixed
});
```
***
#### 4. Don't Refactor While Fixing
Fixing bugs ≠ Refactoring
**Fix bugs:**
* Minimal change
* Addresses specific issue
* No unrelated changes
**Refactor separately:**
* Use refactoring workflow
* Comprehensive changes
* Improves overall structure
***
#### 5. Document the Fix
Add clear comments:
```typescript
// Fix: Close menu before navigation to prevent setState on unmounted component
// Bug: Menu remained open after navigation, blocking content
// Solution: Synchronous menu close prior to router.push()
const handleItemClick = (item: string) => {
setIsOpen(false);
router.push(item);
};
```
***
### Monitoring Bug Fixes
#### Track Fixed Bugs
```bash
# See all resolved bugs
cat .agentful/completion.json | grep bugs_resolved
# Check recent commits
git log --oneline --grep="fix" -10
```
***
#### Bug Metrics
Track in completion.json:
```json
{
"bugs_resolved": {
"this_session": 3,
"this_week": 12,
"total": 47
},
"bug_severity_breakdown": {
"critical": 2,
"high": 15,
"medium": 20,
"low": 10
},
"average_fix_time": {
"critical": "45 minutes",
"high": "25 minutes",
"medium": "15 minutes",
"low": "8 minutes"
}
}
```
***
### Next Steps
#### Feature Development
After fixing bugs, continue building features
→ [Feature Development Guide](./feature-development)
***
### Quick Reference
**Start Testing:**
```bash
/agentful-start
# Specify testing goal
```
**Run All Tests:**
```bash
npm test
```
**Coverage Report:**
```bash
npm test -- --coverage
```
**Run Specific Tests:**
```bash
npm test -- auth
npm test -- --testNamePattern="login"
```
**Watch Mode:**
```bash
npm test -- --watch
```
## CLI Reference
Complete reference for all agentful CLI commands, options, and outputs.
### Installation
```bash
# Local installation
npx @itz4blitz/agentful init
# Global installation
npm install -g @itz4blitz/agentful
```
### Commands
#### `agentful init`
Initialize agentful in the current directory.
##### Usage
```bash
agentful init
agentful init --bare
```
##### Options
| Option | Type | Description |
| -------- | ---- | ----------------------------------------------------------------------------------------------------- |
| `--bare` | flag | Skip creating template files (CLAUDE.md, PRODUCT.md), only create .claude/ and .agentful/ directories |
##### What It Creates
1. **`.claude/`** directory (if not exists)
* All agent configurations
* Command definitions
* Settings and permissions
* Skills and capabilities
2. **`.agentful/`** directory (gitignored)
* `state.json` - Current work state
* `completion.json` - Feature progress tracking
* `decisions.json` - Pending/resolved decisions
* `architecture.json` - Detected tech stack
3. **Template files** (skipped with `--bare`)
* `PRODUCT.md` - Product specification template
* `CLAUDE.md` - Quick start guide
4. **`.gitignore`** update
* Adds `.agentful/` to gitignore
##### Behavior
If `.claude/` already exists, prompts for confirmation:
```
⚠️ .claude/ directory already exists!
Overwrite? (y/N)
```
* `y` - Removes existing directory and recreates
* `N` or any other input - Aborts initialization
##### Output Example
```
___ __ ____________ ____ ___ ____________
/ | / / / /_ __/ __ \/ __ \/ _ | / ____/ _/ /
/ /| | / / / / / / /_/ / /_/ / __ |/ / / // /
/ ___ |/ /_/ / / / / _, _/ _, _/ /_/ / /___/ // /
/_/ |_|_____/ /_/_/ /_/ |_/_/ |_|\____/\____/___/
v1.0.0
Creating .claude/ directory structure...
Initializing state files...
✓ Created CLAUDE.md
✓ Created PRODUCT.md
Added .agentful/ to .gitignore
✅ agentful initialized successfully!
Next steps:
1. Edit PRODUCT.md with your product specification
2. Run: claude
3. Type: /agentful-start
For autonomous 24/7 development:
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
```
##### Exit Codes
* `0` - Successfully initialized
* `1` - Initialization failed (directory permissions, user aborted)
***
#### `agentful status`
Display current development progress and state.
##### Usage
```bash
agentful status
```
##### Prerequisites
* Must be run in a directory with `.agentful/` folder
* `state.json` must exist
##### Output Sections
##### 1. Current Work
Shows active development task:
```
Current Status:
🔧 Working on: Authentication - JWT implementation
Phase: backend-implementation
Iterations: 3
```
Or if idle:
```
💤 Idle - no active task
```
##### 2. Progress Bar
Visual completion percentage:
```
Progress:
████████████░░░░░░░░ 48%
```
##### 3. Quality Gates
Status of all quality gates:
```
Quality Gates:
✅ Tests Passing
❌ No Type Errors
✅ No Dead Code
❌ Coverage 80
⚠️ Security Clean
```
##### 4. Pending Decisions
If decisions are blocking development:
```
⚠️ 2 pending decisions:
1. Should auth use JWT or session cookies?
2. Which database provider?
Run: /agentful-decide
```
##### 5. Next Actions
Always shows available commands:
```
Next Actions:
• /agentful-start - Continue development
• /agentful-decide - Answer pending decisions
• /agentful-validate- Run quality checks
```
##### Error Cases
```
❌ agentful not initialized in this directory!
Run: npx @itz4blitz/agentful init
```
```
❌ State file missing!
Run: npx @itz4blitz/agentful init
```
##### Complete Output Example
```
___ __ ____________ ____ ___ ____________
/ | / / / /_ __/ __ \/ __ \/ _ | / ____/ _/ /
/ /| | / / / / / / /_/ / /_/ / __ |/ / / // /
/ ___ |/ /_/ / / / / _, _/ _, _/ /_/ / /___/ // /
/_/ |_|_____/ /_/_/ /_/ |_/_/ |_|\\____/\\____/___/
v1.0.0
Current Status:
🔧 Working on: User authentication system
Phase: backend-implementation
Iterations: 7
Progress:
████████░░░░░░░░░░░░ 35%
Quality Gates:
❌ Tests Passing
❌ No Type Errors
✅ No Dead Code
❌ Coverage 80
✅ Security Clean
Next Actions:
• /agentful-start - Continue development
• /agentful-decide - Answer pending decisions
• /agentful-validate- Run quality checks
```
***
#### `agentful --help`
Display help information.
##### Usage
```bash
agentful --help
agentful -h
agentful help
```
##### Output
```
___ __ ____________ ____ ___ ____________
/ | / / / /_ __/ __ \/ __ \/ _ | / ____/ _/ /
/ /| | / / / / / / /_/ / /_/ / __ |/ / / // /
/ ___ |/ /_/ / / / / _, _/ _, _/ /_/ / /___/ // /
/_/ |_|_____/ /_/_/ /_/ |_/_/ |_|\\____/\\____/___/
v1.0.0
USAGE:
agentful
COMMANDS:
init Initialize agentful in current directory
init --bare Skip creating templates (just .claude/)
status Show current development progress
--help Show this help message
--version Show version
AFTER INIT:
1. Edit PRODUCT.md with your product spec
2. Run claude to start Claude Code
3. Type /agentful-start to begin autonomous development
FOR 24/7 DEVELOPMENT:
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
```
***
#### `agentful --version`
Display agentful version.
##### Usage
```bash
agentful --version
agentful -v
```
##### Output
```
agentful v1.0.0
```
***
### Exit Codes Summary
| Code | Meaning |
| ---- | ------------------------------------------------------------- |
| 0 | Success |
| 1 | Error (unknown command, initialization failed, missing state) |
***
### Environment
#### Required Files
| File | Purpose | Created By |
| ----------------------------- | ---------------------- | --------------------- |
| `.claude/` | agentful configuration | `agentful init` |
| `.agentful/state.json` | Current state | `agentful init` |
| `.agentful/completion.json` | Progress tracking | `agentful init` |
| `.agentful/decisions.json` | Decision tracking | `agentful init` |
| `.agentful/architecture.json` | Tech stack detection | Agent (automatically) |
#### Optional Files
| File | Purpose | Created By |
| ------------ | --------------------- | ------------------------------------ |
| `PRODUCT.md` | Product specification | `agentful init` (skip with `--bare`) |
| `CLAUDE.md` | Quick start guide | `agentful init` (skip with `--bare`) |
#### Directory Permissions
agentful requires:
* Read access to current directory
* Write access to create `.claude/` and `.agentful/`
* Write access to update `.gitignore`
***
### Color Scheme
The CLI uses ANSI colors for better readability:
| Color | Usage |
| ---------- | --------------------------------- |
| Cyan | Banner, branding |
| Green | Success messages, completed items |
| Yellow | Warnings, pending items |
| Red | Errors, failures |
| Blue | Active work, information |
| Magenta | Not currently used |
| Dim/Bright | Text emphasis |
***
### Version Compatibility
#### agentful Version
Current version: **1.0.0**
Check compatibility:
```bash
agentful --version
```
#### Node.js Requirements
Minimum Node.js version: **18.0.0**
Check your version:
```bash
node --version
```
***
### Quick Reference
| Command | Purpose | Common Use Case |
| ---------------------- | ----------------- | ----------------------------- |
| `agentful init` | Start new project | Creating new agentful project |
| `agentful init --bare` | Config only | Adding to existing project |
| `agentful status` | Check progress | See what's done/in progress |
| `agentful --help` | Get help | Remember command syntax |
| `agentful --version` | Check version | Debug version issues |
***
### Troubleshooting
#### "Command not found"
```bash
# Use npx instead
npx @itz4blitz/agentful init
# Or install globally
npm install -g @itz4blitz/agentful
```
#### "Permission denied"
```bash
# Check directory permissions
ls -la .
# Ensure write access
chmod u+w .
```
#### "Already initialized"
```bash
# Remove existing .claude/ first
rm -rf .claude .agentful
# Then reinitialize
agentful init
```
#### State file corruption
```bash
# Remove corrupted state
rm .agentful/state.json
# Reinitialize (preserves other state)
agentful init --bare
```
***
### Integration Examples
#### With npm scripts
```json
{
"scripts": {
"agentful:init": "agentful init",
"agentful:status": "agentful status",
"start": "claude"
}
}
```
#### With CI/CD
```bash
# Check agentful status in CI
- run: agentful status
# Validate completion percentage
- run: |
PERCENT=$(jq -r '.overall' .agentful/completion.json)
if [ "$PERCENT" -lt 100 ]; then
echo "Project not complete: $PERCENT%"
exit 1
fi
```
#### With Git hooks
```bash
# .git/hooks/pre-commit
#!/bin/bash
agentful status
echo "Check progress before committing"
```
***
### See Also
* [State Files Reference](./state-files.mdx) - Details on state file formats
* [Settings Reference](./settings-reference.mdx) - Configuration options
* [Commands](../commands) - Claude Code slash commands
* [Agents](../agents) - Agent specifications
## Settings Reference
Complete reference for `.claude/settings.json` configuration including hooks, permissions, and all available options.
### Overview
The `settings.json` file controls Claude Code's behavior during agentful development sessions. It configures:
* **Hooks** - Automatic triggers for commands and validation
* **Permissions** - Allowed and denied operations
* **Security** - Safety limits on file operations
### Location
`.claude/settings.json`
### Schema
```json
{
"type": "object",
"required": ["hooks", "permissions"],
"properties": {
"hooks": {
"type": "object",
"description": "Event-driven command triggers"
},
"permissions": {
"type": "object",
"description": "Allow/deny rules for operations"
}
}
}
```
### Complete Example
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "if [ -f .agentful/state.json ]; then jq -r '.current_phase // \"idle\"' .agentful/state.json 2>/dev/null || echo 'idle'; else echo 'idle'; fi"
}
]
}
]
},
"permissions": {
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(node:*)",
"Bash(git:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(jq:*)"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~/.*)",
"Bash(rm -rf /.*)",
"Bash(dd:*)",
"Bash(mkfs:*)"
]
}
}
```
***
### Hooks
Hooks are event-driven commands that run automatically during development.
#### Hook Types
##### PostToolUse
Runs after any tool operation (Read, Write, Edit, Bash, etc.).
**Use Cases**:
* Type checking after code changes
* Linting after edits
* Test running after implementations
* Validation after file operations
**Schema**:
```json
{
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
]
}
]
}
```
**Matcher Values**:
| Matcher | Triggers On | Example Tools | |
| ------- | ----------------- | ------------------ | ----------- |
| \`Edit | Write\` | File modifications | Edit, Write |
| `Edit` | File edits only | Edit | |
| `Write` | File writes only | Write | |
| `Read` | File reads | Read | |
| `Bash` | Command execution | Bash | |
| `.*` | All tools | Any tool | |
**Best Practices**:
1. **Limit output**: Use `| head -N` to prevent spam
```json
{
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
```
2. **Always succeed**: Use `|| true` to avoid blocking
```json
{
"command": "npm test -- --silent 2>&1 || true"
}
```
3. **Quick checks**: Favor fast validation
```json
{
"command": "npx tsc --noEmit --incremental false 2>&1 | head -3 || true"
}
```
##### UserPromptSubmit
Runs when user submits a new prompt.
**Use Cases**:
* Display current state context
* Show pending decisions
* Indicate active phase
* Provide progress updates
**Schema**:
```json
{
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "if [ -f .agentful/state.json ]; then jq -r '.current_phase // \"idle\"' .agentful/state.json 2>/dev/null || echo 'idle'; else echo 'idle'; fi"
}
]
}
]
}
```
**Best Practices**:
1. **Handle missing files**: Check file existence first
```bash
if [ -f .agentful/state.json ]; then
jq -r '.current_phase // "idle"' .agentful/state.json
else
echo "idle"
fi
```
2. **Provide defaults**: Use `||` for fallback values
```bash
jq -r '.current_phase // "idle"' .agentful/state.json || echo "idle"
```
3. **Suppress errors**: Use `2>/dev/null` for cleaner output
```bash
jq -r '.current_phase' .agentful/state.json 2>/dev/null || echo "idle"
```
#### Hook Command Examples
##### TypeScript Check
```json
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
```
**Output**:
```
src/auth.ts:45:12 - error TS2322: Type 'string' is not assignable to type 'number'
```
##### Test Runner
```json
{
"type": "command",
"command": "npm test -- --silent --reporter=json 2>&1 | jq -r '.stats.failures' || echo '0'"
}
```
**Output**:
```
3
```
##### Lint Check
```json
{
"type": "command",
"command": "npx eslint src/ --format json 2>&1 | jq '.length // 0' || echo '0'"
}
```
**Output**:
```
7
```
##### Progress Display
```json
{
"type": "command",
"command": "jq -r '\"Progress: \\(.overall)%\"' .agentful/completion.json 2>/dev/null || echo 'Progress: 0%'"
}
```
**Output**:
```
Progress: 48%
```
##### Pending Decisions
```json
{
"type": "command",
"command": "jq -r 'if .pending | length > 0 then \"\\(.pending | length) decisions pending\" else empty end' .agentful/decisions.json 2>/dev/null || ''"
}
```
**Output**:
```
2 decisions pending
```
#### Advanced Hook Patterns
##### Conditional Hooks
Run different commands based on conditions:
```json
{
"type": "command",
"command": "if git diff --name-only | grep -q '\\.tsx?$'; then npx tsc --noEmit 2>&1 | head -3 || true; fi"
}
```
##### Chain Multiple Commands
```json
{
"type": "command",
"command": "npx tsc --noEmit && npm test -- --silent || true"
}
```
##### File-Specific Hooks
Only run for certain file types:
```json
{
"matcher": ".*\\.(ts|tsx)$",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -3 || true"
}
]
}
```
***
### Permissions
Permissions control which operations Claude Code can perform.
#### Permission Syntax
```
()
```
#### Allow Rules
Operations that are explicitly permitted.
##### Package Managers
```json
{
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(yarn:*)",
"Bash(pnpm:*)",
"Bash(bun:*)"
]
}
```
**Allows**:
* `npm install`
* `npm run build`
* `npx tsc --noEmit`
* `yarn add lodash`
* `pnpm test`
##### Version Control
```json
{
"allow": [
"Bash(git:*)"
]
}
```
**Allows**:
* `git status`
* `git add .`
* `git commit -m "message"`
* `git push`
##### File Operations
```json
{
"allow": [
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(grep:*)"
]
}
```
**Allows**:
* `cat package.json`
* `echo "debug" >> log.txt`
* `head -n 10 file.log`
##### Build Tools
```json
{
"allow": [
"Bash(node:*)",
"Bash(ts-node:*)",
"Bash(vite:*)",
"Bash(next:*)"
]
}
```
**Allows**:
* `node script.js`
* `ts-node src/index.ts`
* `vite build`
* `next dev`
##### JSON Processing
```json
{
"allow": [
"Bash(jq:*)"
]
}
```
**Allows**:
* `jq '.version' package.json`
* `jq '.overall' .agentful/completion.json`
##### Testing
```json
{
"allow": [
"Bash(npm test:*)",
"Bash(npm run test:*)",
"Bash(vitest:*)",
"Bash(jest:*)",
"Bash(playwright:*)",
"Bash(cypress:*)"
]
}
```
**Allows**:
* `npm test`
* `npm run test:unit`
* `vitest run`
* `jest --coverage`
* `playwright test`
##### Database
```json
{
"allow": [
"Bash(prisma:*)",
"Bash(diesel:*)",
"Bash(sequelize:*)"
]
}
```
**Allows**:
* `prisma migrate dev`
* `prisma generate`
* `diesel migration run`
#### Deny Rules
Operations that are explicitly forbidden, regardless of allow rules.
##### System Safety
```json
{
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~/.*)",
"Bash(rm -rf /.*)",
"Bash(dd:*)",
"Bash(mkfs:*)",
"Bash(fdisk:*)",
"Bash(format:*)"
]
}
```
**Blocks**:
* Deleting root directory
* Deleting home directory
* Disk formatting
* Partition table manipulation
##### Data Destruction
```json
{
"deny": [
"Bash(git clean -fdx)",
"Bash(git reset --hard)",
"Bash(git push --force)",
"Bash(rm -rf node_modules)",
"Bash(rm -rf .git)"
]
}
```
**Blocks**:
* Removing untracked files
* Hard resetting git history
* Force pushing to remote
* Deleting node\_modules
* Deleting git history
##### Sensitive Commands
```json
{
"deny": [
"Bash(curl -X POST *",
"Bash(wget *",
"Bash(ssh *)",
"Bash(scp *)",
"Bash(rsync *)"
]
}
```
**Blocks**:
* Arbitrary POST requests
* File downloads
* Remote shell access
* Remote file copy
#### Permission Evaluation Order
1. **Check deny rules first** - If match, deny
2. **Check allow rules** - If match, allow
3. **Default deny** - If no match, deny
**Example**:
```json
{
"permissions": {
"allow": [
"Bash(git:*)"
],
"deny": [
"Bash(git push --force)"
]
}
}
```
**Result**:
* `git status` ✅ Allowed (matches allow)
* `git push` ✅ Allowed (matches allow)
* `git push --force` ❌ Denied (matches deny, deny takes precedence)
* `rm -rf node_modules` ❌ Denied (no allow match)
#### Pattern Matching
##### Wildcard (\*)
Matches any characters:
```json
{
"allow": [
"Bash(npm test:*)" // npm test, npm test:unit, npm test:integration
]
}
```
##### Exact Match
No wildcards for exact command:
```json
{
"allow": [
"Bash(npm test)" // Only "npm test", not "npm test:unit"
]
}
```
##### Prefix Match
Pattern at start matches prefix:
```json
{
"allow": [
"Bash(npm:*)" // npm install, npm test, npm run build
]
}
```
##### Multiple Patterns
Use array for multiple patterns:
```json
{
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(yarn:*)"
]
}
```
***
### Complete Settings Example
#### Development Mode
Permissive settings for active development:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"Phase: \" + (.current_phase // \"idle\")' .agentful/state.json 2>/dev/null || echo 'Phase: idle'"
}
]
}
]
},
"permissions": {
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(node:*)",
"Bash(git:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(jq:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(grep:*)",
"Bash(vitest:*)",
"Bash(playwright:*)"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~/.*)",
"Bash(rm -rf /.*)",
"Bash(dd:*)",
"Bash(mkfs:*)",
"Bash(git push --force)",
"Bash(git clean -fdx)"
]
}
}
```
#### Production Mode
Strict settings for production builds:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit && npm test -- --silent 2>&1 || true"
}
]
}
]
},
"permissions": {
"allow": [
"Bash(npm test:*)",
"Bash(npm run build:*)",
"Bash(git status)",
"Bash(git diff)",
"Bash(cat:*)",
"Bash(jq:*)"
],
"deny": [
"Bash(npm install *)",
"Bash(git add *)",
"Bash(git commit *)",
"Bash(git push *)",
"Bash(rm -rf *)"
]
}
}
```
#### Autonomous Mode
Settings for 24/7 autonomous development:
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -3 || true"
},
{
"type": "command",
"command": "npm test -- --silent --reporter=json 2>&1 | jq -r '.stats.failures // 0' || echo '0'"
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.overall' .agentful/completion.json 2>/dev/null || echo '0'"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "if [ -f .agentful/decisions.json ]; then COUNT=$(jq '.pending | length' .agentful/decisions.json 2>/dev/null || echo '0'); if [ \"$COUNT\" -gt 0 ]; then echo \"⚠️ $COUNT pending decisions - run /agentful-decide\"; fi; fi"
}
]
}
]
},
"permissions": {
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(node:*)",
"Bash(git:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(jq:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(grep:*)",
"Bash(mkdir:*)",
"Bash(cp:*)",
"Bash(mv:*)"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~/.*)",
"Bash(rm -rf /.*)",
"Bash(dd:*)",
"Bash(mkfs:*)",
"Bash(git push --force)",
"Bash(git clean -fdx)",
"Bash(rm -rf node_modules)",
"Bash(rm -rf .git)"
]
}
}
```
***
### Hook and Permission Patterns
#### Common Hook Combinations
##### TypeScript + Tests
```json
{
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -3 || true"
},
{
"type": "command",
"command": "npm test -- --silent 2>&1 | tail -3 || true"
}
]
}
]
}
```
##### Lint + Format Check
```json
{
"PostToolUse": [
{
"matcher": "Edit|Write.*\\.(ts|tsx|js|jsx)$",
"hooks": [
{
"type": "command",
"command": "npx eslint --fix 2>&1 | head -5 || true"
}
]
}
]
}
```
##### Progress Tracking
```json
{
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"Progress: \\(.overall)% | Phase: \\(.current_phase)\"' .agentful/state.json 2>/dev/null || echo 'Progress: 0% | Phase: idle'"
}
]
}
]
}
```
#### Permission Patterns by Use Case
##### Frontend Development
```json
{
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(vite:*)",
"Bash(next:*)",
"Bash(tailwindcss:*)"
]
}
```
##### Backend Development
```json
{
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(prisma:*)",
"Bash(node:*)",
"Bash(ts-node:*)"
]
}
```
##### Testing
```json
{
"allow": [
"Bash(npm test:*)",
"Bash(npm run test:*)",
"Bash(vitest:*)",
"Bash(jest:*)",
"Bash(playwright:*)",
"Bash(cypress:*)"
]
}
```
##### Database Operations
```json
{
"allow": [
"Bash(prisma migrate:*)",
"Bash(prisma generate:*)",
"Bash(prisma db:*)",
"Bash(prisma studio:*)"
]
}
```
***
### Validation and Testing
#### Testing Hooks
Test hook commands manually:
```bash
# Test TypeScript hook
npx tsc --noEmit 2>&1 | head -5 || true
# Test state reading
jq -r '.current_phase // "idle"' .agentful/state.json 2>/dev/null || echo "idle"
# Test progress display
jq -r '"Progress: \(.overall)%"' .agentful/completion.json 2>/dev/null || echo "Progress: 0%"
```
#### Testing Permissions
Verify permission rules:
```bash
# Check if command is allowed (should work)
npm test
# Check if command is denied (should be blocked)
rm -rf /
```
#### Validating JSON
```bash
# Validate JSON syntax
jq empty .claude/settings.json
# Pretty print for inspection
jq '.' .claude/settings.json
```
***
### Security Best Practices
#### 1. Principle of Least Privilege
Only allow what's necessary:
```json
{
"allow": [
"Bash(npm test)" // ✅ Specific command
]
// NOT: "Bash(npm:*)" // ❌ Too broad
}
```
#### 2. Explicit Deny for Dangerous Operations
Always deny destructive commands:
```json
{
"deny": [
"Bash(rm -rf *)",
"Bash(dd *)",
"Bash(mkfs *)"
]
}
```
#### 3. Limit Hook Output
Prevent terminal spam:
```json
{
"command": "npx tsc --noEmit 2>&1 | head -5 || true" // ✅ Limited
// NOT: "npx tsc --noEmit" // ❌ Unlimited output
}
```
#### 4. Use Non-Blocking Hooks
Always append `|| true`:
```json
{
"command": "npm test -- --silent || true" // ✅ Continues on failure
// NOT: "npm test -- --silent" // ❌ Blocks on failure
}
```
#### 5. Sanitize External Input
When processing user input:
```json
{
"command": "jq -r '.current_phase' .agentful/state.json 2>/dev/null || echo 'idle'" // ✅ Safe
// NOT: direct string interpolation // ❌ Injection risk
}
```
***
### Troubleshooting
#### Hooks Not Running
**Problem**: Hook commands don't execute.
**Solutions**:
1. Check JSON syntax:
```bash
jq empty .claude/settings.json
```
2. Verify hook type is valid:
```json
"PostToolUse" // ✅ Valid
// "PostTool" // ❌ Invalid
```
3. Ensure matcher pattern is correct:
```json
"matcher": "Edit|Write" // ✅ Valid
// "matcher": "Edit;Write" // ❌ Invalid separator
```
#### Commands Blocked
**Problem**: "Permission denied" error.
**Solutions**:
1. Check if command matches deny rule:
```bash
# Review deny list
jq '.permissions.deny' .claude/settings.json
```
2. Verify allow pattern matches:
```bash
# Test pattern matching
echo "npm test" | grep -q "^npm:" && echo "Matches" || echo "No match"
```
3. Add explicit allow rule:
```json
{
"allow": [
"Bash(your-command:*)"
]
}
```
#### Hook Output Spam
**Problem**: Too much output from hooks.
**Solutions**:
1. Limit output lines:
```json
{
"command": "npm test 2>&1 | head -10 || true"
}
```
2. Use silent mode:
```json
{
"command": "npm test -- --silent 2>&1 | tail -3 || true"
}
```
3. Filter with jq:
```json
{
"command": "jq '.errors[0:3]' test-report.json 2>/dev/null || echo '[]'"
}
```
***
### Migration Notes
#### Version History
| Version | Changes | Migration |
| ------- | ----------------------- | --------- |
| 1.0.0 | Initial settings format | N/A |
#### Future Changes
Potential additions:
1. **Rate limiting**: Limit command frequency
2. **Resource limits**: CPU/memory constraints
3. **Timeouts**: Maximum command duration
4. **Logging**: Audit trail of operations
***
### Quick Reference
#### Hook Types
| Hook Type | When It Runs | Common Use |
| ------------------ | ------------------------ | ----------------------- |
| `PostToolUse` | After any tool operation | Type checking, linting |
| `UserPromptSubmit` | After user input | Display state, progress |
#### Permission Categories
| Category | Example Commands | Risk Level |
| ---------------- | -------------------------- | ------------------ |
| Package managers | `npm install`, `npx tsc` | Low |
| Build tools | `vite build`, `next build` | Low |
| Testing | `npm test`, `vitest` | Low |
| Version control | `git status`, `git push` | Medium |
| File operations | `cat`, `echo`, `jq` | Low |
| System | `rm`, `dd`, `mkfs` | High (always deny) |
#### Common Patterns
| Pattern | Description | Example |
| ------------- | ------------------ | -------------------------- |
| `Bash(npm:*)` | All npm commands | `npm test`, `npm install` |
| `Bash(npx:*)` | All npx commands | `npx tsc`, `npx prettier` |
| `Bash(git:*)` | All git commands | `git status`, `git commit` |
| `Edit\|Write` | File modifications | Any edit or write |
| `.*\.tsx?$` | TypeScript files | Match `.ts`, `.tsx` |
***
### See Also
* [CLI Reference](./cli-reference.mdx) - Command-line interface
* [State Files Reference](./state-files.mdx) - State file formats
* [Commands](../commands) - Available slash commands
* [Configuration](../configuration) - Setup and customization
## State Files Reference
Complete reference for all agentful state file formats, schemas, and validation rules.
### Overview
agentful maintains runtime state in `.agentful/` directory (gitignored). These files track:
* **Current work progress** - What's being built
* **Feature completion** - How much is done
* **Decisions** - Pending and resolved user input
* **Architecture** - Detected tech stack and agents
### File Structure
```
.agentful/
├── state.json # Current work state and phase
├── completion.json # Feature completion percentages
├── decisions.json # Pending and resolved decisions
├── architecture.json # Detected tech stack
└── last-validation.json # Most recent validation report
```
### state.json
Tracks the current development state and active work.
#### Location
`.agentful/state.json`
#### Schema
```json
{
"type": "object",
"required": ["version", "current_task", "current_phase", "iterations", "last_updated", "blocked_on"],
"properties": {
"version": {
"type": "string",
"description": "State format version",
"pattern": "^\\d+\\.\\d+\\.\\d+$"
},
"current_task": {
"type": ["string", "null"],
"description": "Currently active task description"
},
"current_phase": {
"type": "string",
"enum": [
"idle",
"planning",
"architecture",
"backend-implementation",
"frontend-implementation",
"testing",
"validation",
"fixing",
"blocked"
],
"description": "Current development phase"
},
"iterations": {
"type": "number",
"minimum": 0,
"description": "Number of development loop iterations"
},
"last_updated": {
"type": "string",
"format": "date-time",
"description": "ISO 8601 timestamp of last update"
},
"blocked_on": {
"type": "array",
"items": {
"type": "string"
},
"description": "List of decision IDs blocking progress"
}
}
}
```
#### Example
```json
{
"version": "1.0.0",
"current_task": "Implementing JWT authentication service",
"current_phase": "backend-implementation",
"iterations": 7,
"last_updated": "2026-01-18T12:30:45Z",
"blocked_on": []
}
```
#### Field Descriptions
| Field | Type | Description | Valid Values |
| --------------- | -------------- | -------------------------- | -------------------------------------------- |
| `version` | string | State format version | Semantic version (e.g., `"1.0.0"`) |
| `current_task` | string\|null | Description of active task | Any string or null if idle |
| `current_phase` | string | Current development phase | See Phase Values below |
| `iterations` | number | Loop iteration count | Non-negative integer |
| `last_updated` | string | Last update timestamp | ISO 8601 format |
| `blocked_on` | array\ | Decision IDs blocking work | Array of decision ID strings |
#### Phase Values
| Phase | Description | When Used |
| ------------------------- | ---------------------- | ------------------------------------- |
| `idle` | No active work | Initial state, between tasks |
| `planning` | Analyzing requirements | Reading PRODUCT.md, planning features |
| `architecture` | Detecting tech stack | Generating specialized agents |
| `backend-implementation` | Building backend | Services, APIs, repositories |
| `frontend-implementation` | Building frontend | Components, pages, UI |
| `testing` | Writing tests | Unit, integration, E2E tests |
| `validation` | Running quality checks | Type checking, linting, coverage |
| `fixing` | Resolving issues | Fixing validation failures |
| `blocked` | Waiting on user input | Pending decisions |
#### Validation Rules
1. **Version format**: Must be valid semver (e.g., "1.0.0", "2.1.3")
2. **Timestamp**: Must be ISO 8601 format (e.g., "2026-01-18T12:30:45Z")
3. **Iterations**: Cannot be negative
4. **Blocked\_on**: Must reference valid decision IDs from decisions.json
#### Migration Notes
##### Version 1.0.0 → 1.1.0 (Future)
Add `error_count` field for tracking validation failures:
```json
{
"error_count": 0
}
```
Migration: Add field with default value `0`.
***
### completion.json
Tracks feature completion progress and quality gate status.
#### Location
`.agentful/completion.json`
#### Schema
```json
{
"type": "object",
"required": ["features", "gates", "overall", "last_updated"],
"properties": {
"features": {
"type": "object",
"patternProperties": {
".*": {
"type": "object",
"required": ["status", "score"],
"properties": {
"status": {
"type": "string",
"enum": ["pending", "in_progress", "complete", "blocked"]
},
"score": {
"type": "number",
"minimum": 0,
"maximum": 100
},
"started_at": {
"type": "string",
"format": "date-time"
},
"completed_at": {
"type": "string",
"format": "date-time"
},
"notes": {
"type": "string"
},
"acceptance": {
"type": "object",
"additionalProperties": {
"type": "boolean"
}
}
}
}
}
},
"gates": {
"type": "object",
"required": ["tests_passing", "no_type_errors", "no_dead_code", "coverage_80", "security_clean"],
"properties": {
"tests_passing": { "type": "boolean" },
"no_type_errors": { "type": "boolean" },
"no_dead_code": { "type": "boolean" },
"coverage_80": { "type": "boolean" },
"security_clean": { "type": "boolean" }
}
},
"overall": {
"type": "number",
"minimum": 0,
"maximum": 100,
"description": "Overall completion percentage"
},
"last_updated": {
"type": "string",
"format": "date-time"
}
}
}
```
#### Example
```json
{
"features": {
"authentication": {
"status": "complete",
"score": 100,
"started_at": "2026-01-18T00:00:00Z",
"completed_at": "2026-01-18T02:30:00Z",
"notes": "JWT authentication fully implemented with tests",
"acceptance": {
"login_endpoint": true,
"registration_endpoint": true,
"jwt_generation": true,
"refresh_token": true
}
},
"user-profile": {
"status": "in_progress",
"score": 45,
"started_at": "2026-01-18T02:30:00Z",
"notes": "Backend service complete, frontend pending"
},
"dashboard": {
"status": "pending",
"score": 0
}
},
"gates": {
"tests_passing": true,
"no_type_errors": true,
"no_dead_code": true,
"coverage_80": false,
"security_clean": true
},
"overall": 48,
"last_updated": "2026-01-18T12:30:45Z"
}
```
#### Field Descriptions
##### Features Object
| Field | Type | Description | Valid Values |
| -------------- | ------ | -------------------------- | ---------------------------------------- |
| `status` | string | Feature status | pending, in\_progress, complete, blocked |
| `score` | number | Completion percentage | 0-100 |
| `started_at` | string | Work start timestamp | ISO 8601 (optional) |
| `completed_at` | string | Completion timestamp | ISO 8601 (optional) |
| `notes` | string | Progress notes | Any string (optional) |
| `acceptance` | object | Acceptance criteria status | Map of criterion → boolean |
##### Gates Object
| Gate | Type | Description | Validation |
| ---------------- | ------- | -------------------------------- | ------------------------ |
| `tests_passing` | boolean | All tests pass | `npm test` |
| `no_type_errors` | boolean | No type errors (adapts to stack) | `npx tsc --noEmit` |
| `no_dead_code` | boolean | No unused code | `npx knip` |
| `coverage_80` | boolean | Coverage ≥ 80% | `npm test -- --coverage` |
| `security_clean` | boolean | No security issues | `npm audit` |
##### Overall Field
| Field | Type | Description | Calculation |
| --------- | ------ | ------------------------- | ------------------------------------------ |
| `overall` | number | Weighted completion score | Average of feature scores - gate penalties |
**Calculation Method**:
```javascript
// Average of all feature scores
const featureScores = Object.values(features).map(f => f.score);
const featureAverage = featureScores.reduce((a, b) => a + b, 0) / featureScores.length;
// Subtract gate penalties (5% per failed gate)
const failedGates = Object.values(gates).filter(g => !g).length;
const gatePenalty = failedGates * 5;
// Final score (minimum 0)
const overall = Math.max(0, Math.round(featureAverage - gatePenalty));
```
#### Status Values
| Status | Score Range | Meaning |
| ------------- | ----------- | ------------------------------ |
| `pending` | 0 | Not started |
| `in_progress` | 1-99 | Work in progress |
| `complete` | 100 | Fully done and validated |
| `blocked` | any | Waiting on decision/dependency |
#### Validation Rules
1. **Score range**: Must be 0-100 for all features
2. **Timestamps**: ISO 8601 format if present
3. **Acceptance criteria**: Optional, but if present must be boolean values
4. **Gates**: All 5 gates must be present and boolean
5. **Overall**: Must be 0-100, calculated automatically
#### Integration with PRODUCT.md
Parse PRODUCT.md features section:
```markdown
## Features
### 1. Authentication - CRITICAL
**Acceptance Criteria**:
- [x] Login endpoint
- [x] Registration endpoint
- [x] JWT token generation
- [ ] Refresh token flow
```
Maps to completion.json:
```json
{
"features": {
"authentication": {
"status": "in_progress",
"score": 75,
"acceptance": {
"login_endpoint": true,
"registration_endpoint": true,
"jwt_generation": true,
"refresh_token": false
}
}
}
}
```
***
### decisions.json
Tracks pending and resolved user decisions.
#### Location
`.agentful/decisions.json`
#### Schema
```json
{
"type": "object",
"required": ["pending", "resolved"],
"properties": {
"pending": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "question", "timestamp"],
"properties": {
"id": {
"type": "string",
"pattern": "^decision-\\d+$"
},
"question": {
"type": "string",
"minLength": 1
},
"options": {
"type": "array",
"items": {
"type": "string"
}
},
"context": {
"type": "string"
},
"blocking": {
"type": "array",
"items": {
"type": "string"
}
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
}
},
"resolved": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "question", "answer", "timestamp", "timestamp_resolved"],
"properties": {
"id": {
"type": "string"
},
"question": {
"type": "string"
},
"answer": {
"type": "string"
},
"timestamp": {
"type": "string",
"format": "date-time"
},
"timestamp_resolved": {
"type": "string",
"format": "date-time"
}
}
}
}
}
}
```
#### Example
```json
{
"pending": [
{
"id": "decision-001",
"question": "Should auth use JWT or session cookies?",
"options": [
"JWT (stateless, scalable)",
"Sessions (simpler, built-in)",
"Clerk (managed service)"
],
"context": "Building authentication system for PRODUCT.md",
"blocking": ["auth-feature", "user-profile-feature"],
"timestamp": "2026-01-18T00:00:00Z"
}
],
"resolved": [
{
"id": "decision-000",
"question": "Which database provider?",
"answer": "PostgreSQL (Supabase)",
"timestamp": "2026-01-17T23:00:00Z",
"timestamp_resolved": "2026-01-17T23:05:00Z"
}
]
}
```
#### Field Descriptions
##### Pending Decision
| Field | Type | Required | Description |
| ----------- | -------------- | -------- | -------------------------------------------- |
| `id` | string | Yes | Unique decision ID (pattern: `decision-NNN`) |
| `question` | string | Yes | Question text to present to user |
| `options` | array\ | No | Suggested answers (optional) |
| `context` | string | No | Background information |
| `blocking` | array\ | No | Feature IDs blocked by this decision |
| `timestamp` | string | Yes | When decision was created |
##### Resolved Decision
| Field | Type | Required | Description |
| -------------------- | ------ | -------- | ----------------------------- |
| `id` | string | Yes | Decision ID (matches pending) |
| `question` | string | Yes | Original question text |
| `answer` | string | Yes | User's chosen answer |
| `timestamp` | string | Yes | When decision was created |
| `timestamp_resolved` | string | Yes | When decision was resolved |
#### Validation Rules
1. **ID format**: Must match pattern `decision-\d+` (e.g., `decision-001`, `decision-42`)
2. **Timestamps**: ISO 8601 format
3. **Blocking**: Feature IDs should reference actual features in PRODUCT.md
4. **Unique IDs**: No duplicate IDs across pending and resolved
#### Decision Lifecycle
```
1. Agent needs input
↓
2. Add to pending array
↓
3. Update state.json blocked_on
↓
4. User runs /agentful-decide
↓
5. User selects answer
↓
6. Move from pending to resolved
↓
7. Update state.json (remove from blocked_on)
↓
8. Resume work on blocked features
```
***
### architecture.json
Tracks detected tech stack and generated agents.
#### Location
`.agentful/architecture.json`
#### Schema
```json
{
"type": "object",
"required": ["detected_stack", "generated_agents", "decisions", "timestamp"],
"properties": {
"detected_stack": {
"type": "object",
"properties": {
"frontend": {
"type": "object",
"properties": {
"framework": { "type": "string" },
"language": { "type": "string" },
"styling": { "type": "string" },
"state_management": { "type": "string" }
}
},
"backend": {
"type": "object",
"properties": {
"runtime": { "type": "string" },
"framework": { "type": "string" },
"language": { "type": "string" }
}
},
"database": {
"type": "object",
"properties": {
"type": { "type": "string" },
"orm": { "type": "string" }
}
},
"testing": {
"type": "object",
"properties": {
"unit": { "type": "string" },
"e2e": { "type": "string" }
}
}
}
},
"generated_agents": {
"type": "array",
"items": {
"type": "string"
}
},
"decisions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"decision": { "type": "string" },
"rationale": { "type": "string" },
"timestamp": { "type": "string", "format": "date-time" }
}
}
},
"timestamp": {
"type": "string",
"format": "date-time"
}
}
}
```
#### Example
```json
{
"detected_stack": {
"frontend": {
"framework": "Next.js 14",
"language": "TypeScript",
"styling": "Tailwind CSS",
"state_management": "Zustand"
},
"backend": {
"runtime": "Node.js",
"framework": "Next.js API Routes",
"language": "TypeScript"
},
"database": {
"type": "PostgreSQL",
"orm": "Prisma"
},
"testing": {
"unit": "Vitest",
"e2e": "Playwright"
}
},
"generated_agents": [
"nextjs-backend-agent.md",
"prisma-agent.md",
"tailwind-agent.md",
"typescript-agent.md"
],
"decisions": [
{
"decision": "Generate Prisma-specific agent for database operations",
"rationale": "Detected Prisma ORM in package.json and schema.prisma",
"timestamp": "2026-01-18T00:00:00Z"
}
],
"timestamp": "2026-01-18T00:00:00Z"
}
```
#### Detection Sources
Architecture detection uses multiple sources:
| Source | What It Detects | Priority |
| ------------------- | --------------------------- | -------- |
| PRODUCT.md | Explicit tech stack section | High |
| package.json | Dependencies and frameworks | High |
| Existing code | File patterns, imports | Medium |
| Configuration files | tsconfig, next.config, etc. | Medium |
#### Generated Agents
Common agent types generated:
| Agent | When Generated | Purpose |
| ------------------------- | -------------------- | ----------------------------- |
| `nextjs-backend-agent.md` | Next.js detected | API Routes, server components |
| `prisma-agent.md` | Prisma detected | Database queries, migrations |
| `tailwind-agent.md` | Tailwind detected | Styling, components |
| `react-query-agent.md` | React Query detected | Data fetching, caching |
| `vitest-agent.md` | Vitest detected | Unit test patterns |
***
### last-validation.json (Optional)
Most recent validation report.
#### Location
`.agentful/last-validation.json`
#### Schema
```json
{
"type": "object",
"required": ["timestamp", "results"],
"properties": {
"timestamp": {
"type": "string",
"format": "date-time"
},
"results": {
"type": "object",
"properties": {
"typescript": {
"type": "object",
"properties": {
"passed": { "type": "boolean" },
"errors": { "type": "array", "items": { "type": "string" } }
}
},
"tests": {
"type": "object",
"properties": {
"passed": { "type": "boolean" },
"total": { "type": "number" },
"failed": { "type": "number" }
}
},
"coverage": {
"type": "object",
"properties": {
"percentage": { "type": "number" },
"passes_threshold": { "type": "boolean" }
}
},
"dead_code": {
"type": "object",
"properties": {
"passed": { "type": "boolean" },
"issues": { "type": "array", "items": { "type": "string" } }
}
},
"security": {
"type": "object",
"properties": {
"passed": { "type": "boolean" },
"issues": { "type": "array", "items": { "type": "string" } }
}
}
}
}
}
}
```
#### Example
```json
{
"timestamp": "2026-01-18T12:30:45Z",
"results": {
"typescript": {
"passed": true,
"errors": []
},
"tests": {
"passed": true,
"total": 47,
"failed": 0
},
"coverage": {
"percentage": 82.5,
"passes_threshold": true
},
"dead_code": {
"passed": true,
"issues": []
},
"security": {
"passed": false,
"issues": [
"console.log in src/auth/login.ts:45",
"Hardcoded API key in .env.example"
]
}
}
}
```
***
### Quick Reference Tables
#### State Files Summary
| File | Purpose | Updated By | Required |
| ---------------------- | ------------------ | ---------------------- | -------- |
| `state.json` | Current work state | Orchestrator | Yes |
| `completion.json` | Feature progress | Orchestrator, Reviewer | Yes |
| `decisions.json` | User decisions | Orchestrator, User | Yes |
| `architecture.json` | Tech stack | Architect | Yes |
| `last-validation.json` | Validation report | Reviewer | No |
#### Common Fields
| Field | Found In | Type | Format |
| -------------- | --------------------------- | ------ | -------------- |
| `timestamp` | All except state.json | string | ISO 8601 |
| `last_updated` | state.json, completion.json | string | ISO 8601 |
| `version` | state.json | string | semver |
| `id` | decisions.json | string | `decision-NNN` |
| `status` | completion.json features | string | enum |
| `score` | completion.json features | number | 0-100 |
***
### Validation Tools
#### Using jq
```bash
# Validate JSON syntax
jq empty .agentful/state.json
# Check overall completion
jq '.overall' .agentful/completion.json
# Count pending decisions
jq '.pending | length' .agentful/decisions.json
# List failed gates
jq '.gates | to_entries[] | select(.value == false) | .key' \
.agentful/completion.json
```
#### Using Node.js
```javascript
// Load and validate state
const state = JSON.parse(
fs.readFileSync('.agentful/state.json', 'utf8')
);
// Check if blocked
if (state.blocked_on.length > 0) {
console.log('Blocked on decisions:', state.blocked_on);
}
// Calculate progress
const completion = JSON.parse(
fs.readFileSync('.agentful/completion.json', 'utf8')
);
console.log(`Progress: ${completion.overall}%`);
```
***
### Best Practices
#### 1. Atomic Updates
Always read, modify, and write in one operation:
```bash
# BAD: Separate read/write
STATE=$(cat .agentful/state.json)
echo "$STATE" | jq '.iterations += 1' > .agentful/state.json
# GOOD: Atomic operation
jq '.iterations += 1' .agentful/state.json > .agentful/state.tmp
mv .agentful/state.tmp .agentful/state.json
```
#### 2. Timestamps
Always use UTC ISO 8601:
```javascript
const timestamp = new Date().toISOString(); // ✅ Good
const timestamp = Date.now(); // ❌ Bad (not ISO format)
```
#### 3. Backups
Before major changes:
```bash
cp .agentful/state.json .agentful/state.backup.json
```
#### 4. Validation
Validate after updates:
```bash
jq empty .agentful/state.json && echo "Valid JSON"
```
***
### Troubleshooting
#### "Invalid JSON"
```bash
# Find syntax error
jq . .agentful/state.json
# Fix with jq (auto-formats)
jq '.' .agentful/state.json > .agentful/state.tmp
mv .agentful/state.tmp .agentful/state.json
```
#### "Missing required field"
```bash
# Check schema compliance
cat .agentful/completion.json | \
jq 'has("features") and has("gates") and has("overall")'
```
#### "Stale state"
```bash
# Check timestamp
jq '.last_updated' .agentful/state.json
# Force update
jq '.last_updated = now | todate' .agentful/state.json
```
***
### Migration Guide
#### Version Upgrades
When state.json version changes:
1. **Backup current state**
```bash
cp .agentful/state.json .agentful/state.v1.0.0.json
```
2. **Read old version**
```javascript
const oldState = JSON.parse(readFileSync('.agentful/state.json'));
```
3. **Migrate to new format**
```javascript
const newState = {
...oldState,
version: '1.1.0',
new_field: oldState.old_field || defaultValue
};
```
4. **Write new state**
```javascript
writeFileSync('.agentful/state.json', JSON.stringify(newState, null, 2));
```
5. **Validate**
```bash
jq empty .agentful/state.json
```
***
### See Also
* [CLI Reference](./cli-reference.mdx) - Command-line usage
* [Settings Reference](./settings-reference.mdx) - Configuration options
* [Commands](../commands/agentful-status.mdx) - Status command details
* [Agents](../agents/orchestrator.mdx) - State management by agents
## Best Practices
Learn from real agentful development experience. These patterns, anti-patterns, and optimizations will help you get the most out of autonomous development.
***
### Core Philosophy
**The 80/20 Rule of agentful**
agentful excels at:
* ✅ Building features from clear specs
* ✅ Writing boilerplate and infrastructure
* ✅ Writing tests for implementation
* ✅ Fixing validation failures
* ✅ Following established patterns
agentful struggles with:
* ❌ Ambiguous or vague requirements
* ❌ Creative design decisions
* ❌ Complex architectural refactors
* ❌ Human judgment calls
* ❌ Breaking new ground without patterns
**Best practice**: Let agentful do the 80% (implementation, tests, boilerplate), you handle the 20% (decisions, design, architecture).
***
### Section 1: Writing Better Features
#### Pattern 1.1: Progressive Feature Elaboration
**Start simple, add detail iteratively.**
**Iteration 1 (Core functionality)**:
```markdown
### 1. Todo List - CRITICAL
**Description**: Users can see their todos
**Acceptance Criteria**:
- [ ] Display list of todos
- [ ] Each todo shows text
```
**Iteration 2 (Add essential details)**:
```markdown
### 1. Todo List - CRITICAL
**Description**: Users can see and manage their todos
**Acceptance Criteria**:
- [ ] Display list of todos
- [ ] Each todo shows text and completion status
- [ ] Toggle completion with click
- [ ] Delete todo with button
- [ ] Empty state illustration
- [ ] Loading state while fetching
```
**Iteration 3 (Add polish)**:
```markdown
### 1. Todo List - CRITICAL
**Description**: Users can see and manage their todos
**Acceptance Criteria**:
- [ ] Display list of todos with text and status
- [ ] Toggle completion with click
- [ ] Delete button with confirmation
- [ ] Empty state with illustration and "Create your first todo" message
- [ ] Loading skeleton (not spinner) while fetching
- [ ] Error state with retry button
- [ ] Filter: all / active / completed
- [ ] Sort by date (newest first)
- [ ] Keyboard shortcuts: 't' to toggle, 'd' to delete
```
**Why**: agentful builds in layers. Start with core, add polish in later iterations.
***
#### Pattern 1.2: Acceptance Criteria as Given-When-Then
**Use behavior-driven development format.**
**Vague**:
```markdown
- [ ] User can login
```
**Specific (Given-When-Then)**:
```markdown
- [ ] GIVEN user is on login page
WHEN they enter valid email and password
AND click "Login" button
THEN they are redirected to /dashboard
AND JWT token is stored in httpOnly cookie
AND success toast appears
```
**Why**: Maps directly to tests and implementation.
***
#### Pattern 1.3: Include Edge Cases in Acceptance Criteria
**Don't let agentful discover edge cases late.**
**Basic acceptance criteria**:
```markdown
- [ ] Login form accepts email and password
- [ ] On success, redirect to dashboard
```
**With edge cases**:
```markdown
- [ ] Login form accepts email and password
- [ ] On success, redirect to dashboard
- [ ] Edge case - Empty fields: Show "Email and password required"
- [ ] Edge case - Invalid email format: Show "Invalid email format"
- [ ] Edge case - Wrong password: Show "Invalid credentials" (don't reveal which)
- [ ] Edge case - Unverified email: Show "Please verify your email first"
- [ ] Edge case - Account locked: Show "Account locked, contact support"
- [ ] Edge case - Network error: Show "Connection failed, try again"
- [ ] Edge case - Rate limit exceeded: Show "Too many attempts, try again in 15 minutes"
```
**Why**: agentful builds error handling from the start, not as an afterthought.
***
#### Pattern 1.4: Non-Functional Requirements
**Include performance, security, accessibility requirements.**
**Functional only**:
```markdown
### 1. Product Listing - CRITICAL
- [ ] Display products in grid
- [ ] Each card shows name, price, image
```
**With non-functional requirements**:
```markdown
### 1. Product Listing - CRITICAL
**Description**: Display products in grid layout
**Acceptance Criteria**:
- [ ] Display products in responsive grid (1/2/3/4 columns)
- [ ] Each card shows name, price, image
**Performance Requirements**:
- [ ] Initial render in < 1.5 seconds on 3G
- [ ] Images lazy load below fold
- [ ] List virtualizes for 100+ items (react-window)
- [ ] API response < 500ms p95
**Security Requirements**:
- [ ] Sanitize all user inputs (prevent XSS)
- [ ] Image URLs validated (prevent XXE)
- [ ] Rate limit API endpoint (100 req/min per IP)
**Accessibility Requirements**:
- [ ] WCAG 2.1 AA compliant
- [ ] Keyboard navigation works (Tab, Enter, Escape)
- [ ] Screen reader announces product info
- [ ] Focus indicators visible on all interactive elements
- [ ] Color contrast ratio ≥ 4.5:1
```
**Why**: agentful considers these from the start, not as refactors.
***
#### Anti-Pattern 1.1: Over-Specifying Implementation
**Don't tell agentful HOW to build, tell it WHAT to build.**
**Bad (over-specified)**:
```markdown
**Acceptance Criteria**:
- [ ] Use React Hook Form's useForm hook
- [ ] Use Zod schema with .string().email().min(5)
- [ ] Use useState for form data
- [ ] Use useEffect to fetch user on mount
- [ ] Store token in document.cookie
- [ ] Use axios for API calls with baseURL
- [ ] Use Tailwind classes: flex, flex-col, gap-4
```
**Good (outcome-focused)**:
```markdown
**Acceptance Criteria**:
- [ ] Login form with email/password fields
- [ ] Client-side validation (email format, password length)
- [ ] Form submits to /api/auth/login
- [ ] On success: store auth token, redirect to /dashboard
- [ ] On failure: show inline error message
- [ ] Form uses existing validation library (Zod or Yup)
- [ ] Styling matches design system (Tailwind CSS)
```
**Why**: Let agentful choose the best implementation approach within your constraints.
***
#### Anti-Pattern 1.2: Feature Bloat
**One feature doing too many things.**
**Bad**:
```markdown
### 1. User Management - CRITICAL
**Description**: Users can manage their accounts
**Acceptance Criteria**:
- [ ] Register new account
- [ ] Login with email/password
- [ ] Logout
- [ ] Edit profile
- [ ] Upload avatar
- [ ] Change password
- [ ] Reset password via email
- [ ] Delete account
- [ ] View account history
- [ ] Manage notifications
- [ ] Connect social accounts
```
**Good (split into focused features)**:
```markdown
### 1. Authentication - CRITICAL
**Description**: Users can login and logout
**Acceptance Criteria**:
- [ ] Login form with email/password
- [ ] JWT token generation
- [ ] Logout functionality
- [ ] Protected routes
### 2. Registration - HIGH
**Description**: New users can create accounts
**Acceptance Criteria**:
- [ ] Registration form
- [ ] Email verification
- [ ] Welcome email
### 3. Profile Management - HIGH
**Description**: Users can edit their profile
**Acceptance Criteria**:
- [ ] Edit name and avatar
- [ ] Change password
- [ ] Manage notifications
### 4. Password Reset - MEDIUM
...
### 5. Account Deletion - LOW
...
```
**Why**: Smaller, focused features complete faster. agentful can parallelize.
***
### Section 2: Tech Stack Specifications
#### Pattern 2.1: Specify Versions and Variants
**Be explicit about versions.**
**Vague**:
```markdown
## Tech Stack
- Next.js
- TypeScript
- Tailwind
```
**Specific**:
```markdown
## Tech Stack
### Frontend
- **Framework**: Next.js 14 (App Router, NOT Pages Router)
- **Language**: TypeScript 5.3+ (strict mode enabled)
- **Styling**: Tailwind CSS 3.4+ with CSS variables for theming
- **State**: Zustand 4.4+ (NOT Redux)
- **Forms**: React Hook Form 7.48+ with Zod 3.22+ validation
- **Tables**: TanStack Table 8.11+ (NOT react-table)
```
**Why**: Different versions have different patterns. Explicitness prevents wrong implementation.
***
#### Pattern 2.2: Include Constraint Rationale
**Explain WHY you chose a tool.**
**Basic**:
```markdown
- **Database**: PostgreSQL
- **ORM**: Prisma
```
**With rationale**:
```markdown
- **Database**: PostgreSQL (chosen for ACID compliance, JSON support, and existing team expertise)
- **ORM**: Prisma (type-safe, team standard, good migration system)
**Constraints**:
- Must use Prisma for all DB queries (no raw SQL)
- Follow existing schema in prisma/schema.prisma
- All schema changes require migration files
- Use Prisma Client for queries, no raw queries without approval
```
**Why**: Helps agentful make decisions when facing ambiguity.
***
#### Pattern 2.3: Specify Integration Patterns
**How tools work together.**
**Example**:
```markdown
## Tech Stack Integration Patterns
### API + State Management
- Use TanStack Query for all data fetching (caching, revalidation)
- Use Zustand for UI state (modals, forms, theme)
- Don't fetch in components, use custom hooks in src/hooks/
### Styling + Components
- Use shadcn/ui as base component library
- Extend components in src/components/ui/ for customization
- Use Tailwind for layout and styling
- Follow existing design tokens in src/tokens/
### Testing + Mocking
- Use Vitest for unit tests (fast, integrates with Vite)
- Use MSW for API mocking (NOT nock)
- Use Testing Library for component tests (NOT Enzyme)
- Mock external dependencies (Stripe API, email service)
```
**Why**: Ensures consistent patterns across entire codebase.
***
#### Anti-Pattern 2.1: Conflicting Tech Choices
**Incompatible tools.**
**Bad**:
```markdown
### Frontend
- **Framework**: Next.js 14
- **State**: Redux Toolkit
- **Forms**: React Hook Form
- **Validation**: Zod
### BUT ALSO
- Use Zustand for state
- Use Formik for forms
- Use Yup for validation
```
**Good**:
```markdown
### Frontend
- **Framework**: Next.js 14
- **State**: Zustand (primary), Redux (only for complex state if needed)
- **Forms**: React Hook Form
- **Validation**: Zod
**When to use Redux**:
- Only for complex global state (user session, cart with 50+ items)
- Default to Zustand for simpler state
```
**Why**: agentful needs clear direction on which tool to use.
***
### Section 3: Progress Monitoring
#### Pattern 3.1: Checkpoint-Based Monitoring
**Don't micromanage every file.**
**Obsessive (bad)**:
```bash
# After every file
/agentful-status
# After every test
/agentful-status
# After every validation
/agentful-status
```
**Strategic (good)**:
```bash
# Checkpoints:
# 1. When starting new feature
/agentful-status
# 2. When agentful seems stuck (10+ iterations without progress)
/agentful-status
# 3. When feature should be complete
/agentful-status
# 4. Before making manual changes
/agentful-status
```
**Why**: agentful works best uninterrupted. Check at natural breaks.
***
#### Pattern 3.2: Milestone-Based Validation
**Validate at milestones, not continuously.**
**Continuous validation (slow)**:
```markdown
**Technical Notes**:
- Run /agentful-validate after every file change
```
**Milestone validation (fast)**:
```markdown
**Technical Notes**:
- Run validation only when:
* Feature implementation complete
* Tests written
* Before marking feature complete
```
**Why**: Validation is expensive. Run it at checkpoints, not every iteration.
***
#### Pattern 3.3: Progress Tracking for Teams
**Visual dashboards for team visibility.**
**Simple**:
```bash
# Add to team dashboard script
cat .agentful/completion.json | jq '
{
project: "Product A",
overall: .overall,
current_task: .current_task,
gates: .gates,
pending_decisions: (.decisions.pending | length)
}
'
```
**Advanced**:
```bash
# Generate team dashboard
./scripts/generate-dashboard.sh > dashboard.html
# Shows all projects, progress, blockers
```
**Why**: Teams need visibility without interrupting agentful.
***
### Section 4: Intervention vs. Autonomy
#### Pattern 4.1: The 15-Minute Rule
**Let agentful work for 15 minutes before intervening.**
**Scenario**: agentful seems stuck on something
**Impatient (bad)**:
```bash
# 2 minutes in
"agentful is slow, let me just do it myself"
# Manually write code
# Break agentful's flow
```
**Patient (good)**:
```bash
# 15 minutes later
/agentful-status
# If still stuck:
# - Check state files
# - Check validation
# - Check for decisions
# - Intervene if truly stuck
```
**Why**: agentful might be exploring solutions. Interrupting breaks the loop.
***
#### Pattern 4.2: Selective Intervention
**Intervene only where agentful struggles.**
**agentful struggles with**:
* Complex type definitions
* Creative UX decisions
* Architectural refactors
* Performance optimizations
* Security-critical code
**Let agentful handle**:
* CRUD operations
* Form handling
* Basic routing
* Standard components
* Test writing
* Boilerplate
**Example hybrid approach**:
```typescript
// You write the complex types (agentful struggles)
interface AuthState {
user: User | null;
token: string | null;
permissions: Permission[];
sessionExpiry: number;
}
// agentful writes the basic store (agentful excels)
const useAuthStore = create((set) => ({
user: null,
token: null,
permissions: [],
sessionExpiry: 0,
login: (user, token) => set({ user, token }),
logout: () => set({ user: null, token: null, permissions: [] }),
}));
```
***
#### Pattern 4.3: Guidance Over Control
**Guide agentful, don't control it.**
**Controlling (bad)**:
```markdown
**Technical Notes**:
- Line 5: Must be exactly "const foo = ..."
- Line 6: Must be exactly "const bar = ..."
- Function name must be "processData"
- Use for loop, not forEach
- Use template literals, not string concat
```
**Guiding (good)**:
```markdown
**Technical Notes**:
- Follow existing pattern in src/lib/processor.ts
- Must handle empty input gracefully
- Must return array of processed items
- Performance: O(n) complexity is acceptable
```
**Why**: agentful needs flexibility to implement. Constrain by outcome, not method.
***
### Section 5: Quality and Code Review
#### Pattern 5.1: Acceptance Criteria Review Checklist
**Review acceptance criteria before running agentful.**
**Checklist**:
```markdown
For each feature, verify:
Clarity:
- [ ] Can I visualize what this will look like?
- [ ] Would a new developer understand this?
- [ ] Is there any ambiguity?
Completeness:
- [ ] Are all user flows covered?
- [ ] Are edge cases addressed?
- [ ] Is error handling specified?
Testability:
- [ ] Can I write a test for each criterion?
- [ ] Is success measurable?
- [ ] Is failure defined?
Feasibility:
- [ ] Is this realistic to build?
- [ ] Are dependencies available?
- [ ] Is timeline reasonable?
If any checklist item fails, refine acceptance criteria.
```
***
#### Pattern 5.2: Post-Development Review
**Review agentful's work like human code.**
**Review checklist**:
```markdown
After agentful completes feature:
Functionality:
- [ ] All acceptance criteria pass
- [ ] Edge cases handled
- [ ] Error handling complete
- [ ] User flows work end-to-end
Code Quality:
- [ ] Follows team patterns
- [ ] No code duplication
- [ ] Functions are focused and small
- [ ] Names are clear and descriptive
Testing:
- [ ] Tests cover all acceptance criteria
- [ ] Tests cover edge cases
- [ ] Tests are readable
- [ ] Mocks are appropriate
Performance:
- [ ] No obvious performance issues
- [ ] Database queries are optimized
- [ ] No unnecessary re-renders
- [ ] Bundle size reasonable
Security:
- [ ] Input validation present
- [ ] No hardcoded secrets
- [ ] Proper auth checks
- [ ] No SQL/ XSS vulnerabilities
Documentation:
- [ ] Complex functions have JSDoc
- [ ] API endpoints documented
- [ ] Setup instructions clear
```
**Why**: agentful can miss things. Human review catches them.
***
#### Pattern 5.3: Iterative Refinement
**Don't expect perfection on first try.**
**Iteration 1**: Focus on functionality
```markdown
### 1. User Login - CRITICAL
**Acceptance Criteria**:
- [ ] Login form with email/password
- [ ] On success, redirect to dashboard
- [ ] On failure, show error
```
**agentful builds it** → **You review**
**Iteration 2**: Add refinement based on review
```markdown
### 1. User Login - CRITICAL
**Acceptance Criteria**:
- [ ] Login form with email/password
- [ ] Client-side validation (email format, password length)
- [ ] On success, redirect to dashboard
- [ ] On failure, show specific error message
- [ ] Loading state during submission
- [ ] Disable submit button while submitting
- [ ] Enter key submits form
```
**Why**: First iteration establishes baseline. Refinements add polish.
***
### Section 6: Scaling to Large Projects
#### Pattern 6.1: Feature Modularization
**Break large features into smaller, independent ones.**
**Monolithic (bad)**:
```markdown
### 1. E-commerce Platform - CRITICAL
**Description**: Complete e-commerce functionality
**Acceptance Criteria**:
- [ ] Products, categories, search
- [ ] Cart, checkout, payment
- [ ] User accounts, orders, history
- [ ] Admin panel, inventory
- [ ] Reviews, ratings, recommendations
```
**Modular (good)**:
```markdown
### Phase 1: Core Shopping
### 1. Product Catalog - CRITICAL
### 2. Shopping Cart - CRITICAL
### 3. Checkout - CRITICAL
### Phase 2: User Features
### 4. User Authentication - HIGH
### 5. Order Management - HIGH
### Phase 3: Admin
### 6. Admin Product Management - MEDIUM
### 7. Order Processing - MEDIUM
### Phase 4: Enhancements
### 8. Product Reviews - LOW
### 9. Recommendations - LOW
```
**Why**: Smaller features complete faster. Can ship in phases.
***
#### Pattern 6.2: Progressive Enhancement
**Build MVP, then enhance.**
**MVP**:
```markdown
### 1. User Authentication - CRITICAL
- [ ] Email/password login
- [ ] JWT token
- [ ] Basic session management
```
**Enhancement 1** (after MVP complete):
```markdown
### 8. Social Login - MEDIUM
- [ ] Google OAuth
- [ ] GitHub OAuth
```
**Enhancement 2**:
```markdown
### 9. Multi-Factor Auth - LOW
- [ ] TOTP support
- [ ] SMS backup codes
```
**Why**: Ship faster. Add complexity after core works.
***
#### Pattern 6.3: Dependency Management
**Order features to minimize dependencies.**
**Bad order** (features blocked on dependencies):
```markdown
### 1. User Reviews - CRITICAL (blocked on users, products, orders)
### 2. Order Processing - CRITICAL (blocked on users, products, checkout)
### 3. Checkout - CRITICAL (blocked on users, products, cart)
### 4. Shopping Cart - CRITICAL (blocked on products)
### 5. Product Catalog - CRITICAL (no dependencies)
```
**Good order** (unblock as you go):
```markdown
### 1. Product Catalog - CRITICAL (foundation)
### 2. Shopping Cart - CRITICAL (depends on #1)
### 3. Checkout - CRITICAL (depends on #1, #2)
### 4. User Authentication - HIGH (parallel to #2, #3)
### 5. Order Processing - HIGH (depends on #3, #4)
### 6. User Reviews - MEDIUM (depends on #1, #4, #5)
```
**Why**: Features can be built in parallel. Less blocking.
***
### Section 7: Performance Optimization
#### Pattern 7.1: Performance Requirements in Specs
**Include performance from the start.**
**Afterthought (bad)**:
```markdown
### 1. Product Listing - CRITICAL
- [ ] Display products in grid
# Later: "This is slow, need to optimize"
```
**Built-in (good)**:
```markdown
### 1. Product Listing - CRITICAL
**Acceptance Criteria**:
- [ ] Display products in responsive grid
**Performance Requirements**:
- [ ] Initial render < 1.5s on 3G connection
- [ ] Time to interactive < 3s
- [ ] Database query < 500ms p95
- [ ] API response < 200ms p95
- [ ] Images lazy load, prioritize above-fold
- [ ] Virtualize list for 100+ items
- [ ] Cache API responses for 5 minutes
```
**Why**: agentful builds with performance in mind, not as refactor.
***
#### Pattern 7.2: Database Optimization
**Specify query patterns early.**
**Basic**:
```markdown
### 1. User Dashboard - CRITICAL
- [ ] Display user's recent orders
```
**With optimization**:
```markdown
### 1. User Dashboard - CRITICAL
- [ ] Display user's recent orders (last 10)
**Performance Notes**:
- [ ] Use indexed query on user_id
- [ ] Select only needed fields (avoid SELECT *)
- [ ] Pagination: 10 per page
- [ ] Cache for 2 minutes
- [ ] Use JOIN instead of N+1 queries
```
**Why**: agentful writes optimized queries from the start.
***
#### Pattern 7.3: Frontend Optimization
**Specify optimization techniques.**
**Example**:
```markdown
### 1. Product Feed - CRITICAL
**Acceptance Criteria**:
- [ ] Infinite scroll product feed
**Performance Requirements**:
- [ ] Use react-window for virtualization
- [ ] Lazy load images (use Intersection Observer)
- [ ] De-bounce search input by 300ms
- [ ] Use React.memo for product cards
- [ ] Pagination: 20 items per page
- [ ] Prefetch next page when user reaches 80% scroll
```
**Why**: agentful uses best practices, not naive implementations.
***
### Section 8: Security Best Practices
#### Pattern 8.1: Security Requirements in Specs
**Don't leave security to chance.**
**Example**:
```markdown
### 1. User Authentication - CRITICAL
**Acceptance Criteria**:
- [ ] Login form with email/password
**Security Requirements**:
- [ ] Rate limiting: 5 attempts per 15 min per IP
- [ ] Password requirements: min 8 chars, 1 uppercase, 1 number
- [ ] Hash passwords with bcrypt (cost factor 12)
- [ ] JWT token expires in 7 days
- [ ] Store JWT in httpOnly cookie (NOT localStorage)
- [ ] CSRF protection on all mutation endpoints
- [ ] Input sanitization (prevent XSS)
- [ ] SQL injection prevention (use parameterized queries)
- [ ] Don't reveal if email exists (use generic error messages)
```
**Why**: agentful implements security from the start, not as patch.
***
#### Pattern 8.2: Data Validation
**Validate at multiple layers.**
**Client-side**:
```markdown
**Acceptance Criteria**:
- [ ] Email validation: required, valid format
- [ ] Password validation: required, min 8 chars
- [ ] Show inline errors
```
**Server-side**:
```markdown
**Security Requirements**:
- [ ] Validate all inputs with Zod schema
- [ ] Sanitize HTML (prevent XSS)
- [ ] Validate JWT on every protected route
- [ ] Check user permissions for resources
```
**Database**:
```markdown
**Security Requirements**:
- [ ] Use parameterized queries (Prisma handles this)
- [ ] Validate data types at schema level
- [ ] Add CHECK constraints for business rules
```
**Why**: Defense in depth. If one layer fails, others protect.
***
#### Pattern 8.3: Secrets Management
**Never hardcode secrets.**
**Bad** (agentful might do this if not told):
```typescript
const API_KEY = "sk-1234567890abcdef";
```
**Good** (specify in PRODUCT.md):
```markdown
**Security Requirements**:
- [ ] All secrets in environment variables (.env.local)
- [ ] Add secrets to .env.example (with placeholder values)
- [ ] Never commit .env.local to Git
- [ ] Document required environment variables
- [ ] Validate required env vars on startup
```
**Example**:
```typescript
// agentful generates this instead:
const API_KEY = process.env.STRIPE_SECRET_KEY;
if (!API_KEY) {
throw new Error("STRIPE_SECRET_KEY environment variable is required");
}
```
***
### Section 9: Testing Best Practices
#### Pattern 9.1: Test Requirements in Specs
**Specify what to test.**
**Minimal**:
```markdown
**Acceptance Criteria**:
- [ ] Login form works
```
**With testing**:
```markdown
**Acceptance Criteria**:
- [ ] Login form works
**Testing Requirements**:
- [ ] Unit tests for:
- Email validation function
- Password validation function
- JWT generation function
- Token verification function
- [ ] Integration tests for:
- POST /api/auth/login (success case)
- POST /api/auth/login (wrong password)
- POST /api/auth/login (non-existent user)
- [ ] E2E tests for:
- Complete login flow
- Redirect after successful login
- Error message display
```
**Why**: Tester agent knows exactly what tests to write.
***
#### Pattern 9.2: Test Data Management
**Specify test data strategy.**
**Example**:
```markdown
**Testing Notes**:
- Use factory pattern for test data (see src/__tests__/factories/)
- Each test should create fresh data (don't share between tests)
- Clean up test data after each test (use afterEach)
- Use deterministic data (not random) for reproducibility
- Mock external dependencies (Stripe API, email service)
```
**Why**: Tests are reliable, maintainable, and fast.
***
#### Pattern 9.3: Coverage Targets
**Be realistic about coverage.**
**Unrealistic**:
```markdown
**Success Criteria**:
- 100% test coverage
```
**Realistic**:
```markdown
**Success Criteria**:
- 80% overall test coverage
- 90% for business logic (services, utils)
- 70% for components (UI has lower priority)
- 100% for authentication and security code
```
**Why**: 100% is rarely worth the effort. Focus on critical code.
***
### Section 10: Documentation Patterns
#### Pattern 10.1: Document as You Build
**Don't leave documentation for later.**
**Add to PRODUCT.md**:
```markdown
### 1. User Authentication - CRITICAL
...
**Documentation Requirements**:
- [ ] JSDoc on all exported functions
- [ ] API endpoint documentation (OpenAPI/Swagger)
- [ ] Setup instructions in README
- [ ] Environment variables documented in .env.example
- [ ] Architecture diagram for auth flow
```
**Why**: Documentation decays if written later. Write it while building.
***
#### Pattern 10.2: Architecture Documentation
**Document decisions and rationale.**
**Example**:
```markdown
## Architecture Decisions
### Authentication Strategy
**Decision**: JWT with httpOnly cookies
**Rationale**:
- Stateless, scales horizontally
- httpOnly cookies prevent XSS
- No token storage in localStorage
- 7-day expiry balances security and UX
**Alternatives Considered**:
- Sessions: Rejected (requires session store, doesn't scale)
- localStorage: Rejected (vulnerable to XSS)
- Clerk: Rejected (vendor lock-in, cost)
**Trade-offs**:
- Pros: Scalable, secure, simple
- Cons: Can't revoke tokens without blacklist (future enhancement)
**Decision Date**: 2026-01-18
**Decision Maker**: Team
```
**Why**: Future you (and teammates) understand why.
***
### Summary: agentful Best Practices Mindset
**Think of agentful as a junior developer** who:
* ✅ Follows instructions precisely
* ✅ Works tirelessly
* ✅ Writes tests diligently
* ✅ Needs clear requirements
* ✅ Struggles with ambiguity
* ✅ Needs guidance on complex decisions
* ✅ Benefits from code review
**Your role as senior developer**:
* Provide clear specs (PRODUCT.md)
* Guide at decision points (decisions.json)
* Review and refine (code review)
* Handle complex cases (manual intervention)
* Teach patterns (technical notes)
* Ensure quality (validation)
**The sweet spot**:
```
You: 20% (decisions, architecture, design, complex cases)
agentful: 80% (implementation, tests, boilerplate, refactoring)
```
**Result**: 10x productivity with quality maintained.
***
### Next Steps
Apply these best practices to your project:
1. **[Write Better PRODUCT.md](./writing-product-md)** - Clear specs
2. **[Set Up Team Config](./team-adoption)** - Encode patterns
3. **[Troubleshoot Issues](./troubleshooting)** - Fix problems quickly
***
**Related Guides:**
* [Writing PRODUCT.md](./writing-product-md) - Spec best practices
* [Team Adoption](./team-adoption) - Team patterns
* [Troubleshooting](./troubleshooting) - Problem prevention
## Guides Overview
Practical guides to help you succeed with agentful in real-world development scenarios.
### What You'll Learn
These guides go beyond the basics and teach you how to:
* Write effective PRODUCT.md specifications that agentful understands perfectly
* Set up agentful for team collaboration with shared configs
* Troubleshoot common issues and resolve blockers quickly
* Apply best practices learned from real agentful development
* Avoid anti-patterns that slow down autonomous development
### Guide Categories
#### Product Specification
**[Writing Effective PRODUCT.md](./writing-product-md)**
The foundation of successful autonomous development. Learn how to write clear, actionable specifications that guide agentful to build exactly what you want.
* Structure and sections explained
* Real examples from successful projects
* Templates you can copy and adapt
* Common dos and don'ts
* How to handle ambiguity
* Acceptance criteria best practices
#### Team Collaboration
**[Team Adoption Guide](./team-adoption)**
Using agentful effectively in a team environment. Setup patterns, collaboration strategies, and configuration sharing.
* Setting up team-wide agentful configs
* Managing shared PRODUCT.md files
* Collaboration workflows
* Code review with agentful
* Handling conflicting decisions
* Onboarding team members
#### Problem Solving
**[Troubleshooting Guide](./troubleshooting)**
Common issues, their symptoms, and step-by-step solutions. Get unstuck fast when agentful doesn't behave as expected.
* agentful seems stuck or spinning
* Validation loops that never complete
* Decision handling problems
* State file corruption
* Quality gate failures
* Performance issues
* Recovery strategies
#### Expert Tips
**[Best Practices](./best-practices)**
Learn from real agentful development experience. Proven patterns, anti-patterns to avoid, and optimization techniques.
* Writing better features and requirements
* Effective tech stack specifications
* Progress tracking and monitoring
* Iteration optimization
* Code quality patterns
* When to intervene vs. let agentful work
* Scaling to large projects
### How to Use These Guides
#### For Beginners
Start here if you're new to agentful:
1. **[Quick Start](../getting-started/quick-start)** - Get your first project running
2. **[Writing Effective PRODUCT.md](./writing-product-md)** - Learn to write great specs
3. **[Best Practices](./best-practices)** - Understand what works well
#### For Teams
Adopting agentful across a team? Read these:
1. **[Team Adoption Guide](./team-adoption)** - Setup and workflows
2. **[Writing Effective PRODUCT.md](./writing-product-md)** - Standardize specs
3. **[Troubleshooting Guide](./troubleshooting)** - Handle team issues
#### For Experienced Users
Already comfortable with agentful? Dive deeper:
1. **[Best Practices](./best-practices)** - Advanced patterns
2. **[Troubleshooting Guide](./troubleshooting)** - Debug complex issues
3. **[Team Adoption Guide](./team-adoption)** - Scale to teams
### Real Examples Throughout
All guides include:
* **Real code examples** from actual agentful projects
* **Before/after comparisons** showing improvements
* **Templates** you can copy and adapt
* **Checklists** for common tasks
* **Cross-references** to related documentation
### Contributing
Found a pattern that works well? Have a troubleshooting story to share?
Contributions to these guides are welcome! See the [Contributing Guide](https://github.com/blitz/agentful/blob/main/CONTRIBUTING.md) for details.
***
### Quick Reference
**Essential Guides:**
| You want to... | Read this guide |
| -------------------- | ---------------------------------------------------- |
| Write better specs | [Writing Effective PRODUCT.md](./writing-product-md) |
| Set up for your team | [Team Adoption](./team-adoption) |
| Fix a problem | [Troubleshooting](./troubleshooting) |
| Improve results | [Best Practices](./best-practices) |
**Key Concepts:**
* [Agents](../core-concepts/agents) - Specialized AI workers
* [Orchestrator](../core-concepts/orchestrator) - Development coordination
* [State Management](../core-concepts/state-management) - Progress tracking
* [Quality Gates](../core-concepts/agents#reviewer-agent) - Validation standards
**Common Tasks:**
* [Installation](../getting-started/installation) - Set up agentful
* [First Project](../getting-started/first-project) - Build your first autonomous project
* [Configuration](../getting-started/configuration) - Customize agents and commands
***
**Next:** [Learn to write effective PRODUCT.md files](./writing-product-md)
## Team Adoption Guide
Using agentful in a team environment requires coordination, shared standards, and clear workflows. This guide shows you how to adopt agentful across your team effectively.
***
### Challenges of Team Adoption
When using agentful solo, you can make decisions on the fly. In a team, you need:
* **Consistent PRODUCT.md standards** - Everyone writes specs the same way
* **Shared configuration** - Same agents, commands, and settings across team
* **Collaboration workflows** - How to work together without conflicts
* **Decision handling** - How to resolve team decisions agentful needs
* **Code review integration** - agentful + human review process
***
### Setup Phase: Team Configuration
#### Step 1: Initialize Team Repo
Create a shared repository with agentful:
```bash
# Team repo initialization
mkdir myteam-agentful-config
cd myteam-agentful-config
npx @itz4blitz/agentful init
# Customize for your team's standards
# Edit .claude/agents/ to match your patterns
# Edit .claude/commands/ to add team-specific workflows
```
**Commit to version control**:
```bash
git add .claude/
git commit -m "Add team agentful configuration"
git push origin main
```
#### Step 2: Customize Agents for Team Patterns
**Example: Backend agent with team patterns**
Edit `.claude/agents/backend.md`:
````markdown
# Team Backend Agent
You are the Backend Agent for [Company Name].
## Team Patterns
### API Response Format
All API routes must return:
```typescript
{
data: T | null,
error: {
code: string,
message: string,
details?: any
} | null
}
````
#### Error Handling
* Use `AppError` class from `src/lib/errors.ts`
* Log all errors to `src/lib/logger.ts`
* Never expose stack traces to clients
#### Database Queries
* Use Prisma transactions for multi-step operations
* Always use `try/finally` to ensure connections close
* Add `@prisma/client` types for all query results
### Team-Specific Rules
* Follow existing folder structure in `src/app/api/`
* Match existing route patterns: `/api/v1/resource/[id]/action`
* Use Zod schemas from `src/lib/schemas/` for validation
* Add JSDoc comments to all exported functions
````
**Why this matters**: agentful follows your team's established patterns instead of guessing.
---
### Step 3: Create Team PRODUCT.md Template
Create `.claude/templates/PRODUCT.md`:
```markdown
# [Company Name] Product Specification Template
## Overview
[2-3 sentence description]
## Tech Stack
### Frontend
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript (strict mode)
- **Styling**: Tailwind CSS
- **State**: Zustand
- **Forms**: React Hook Form + Zod
### Backend
- **Runtime**: Node.js
- **Framework**: Next.js API Routes
- **Language**: TypeScript (strict mode)
### Database
- **Database**: PostgreSQL
- **ORM**: Prisma
### Authentication
- **Method**: JWT with httpOnly cookies
- **Implementation**: `src/lib/auth.ts`
### Testing
- **Unit**: Vitest
- **E2E**: Playwright
### Deployment
- **Hosting**: Vercel
- **CI/CD**: GitHub Actions
## Features
### 1. [Feature Name] - [PRIORITY]
**Description**: [One sentence]
**Acceptance Criteria**:
- [ ] [Specific requirement]
- [ ] [Specific requirement]
**Technical Notes**:
- [Follow existing pattern in src/features/...]
````
**Teams can copy this template** for each new project, ensuring consistency.
***
#### Step 4: Add Team-Specific Commands
Create `.claude/commands/team-deploy.md`:
````markdown
---
name: team-deploy
description: Deploy with team approval process
---
# Team Deploy Command
## Pre-Deploy Checklist
Run these checks before deploying:
1. **Validation**:
```bash
/agentful-validate
````
2. **Team Review**:
* Create PR with `agent-deploy` label
* Get approval from Tech Lead
* Ensure all CI checks pass
3. **Staging Test**:
* Deploy to staging environment
* Run E2E tests on staging
* Manual smoke test
### Deploy Process
If all checks pass:
```bash
# Deploy to production
npm run deploy:prod
```
### Post-Deploy
* [ ] Monitor error logs for 15 minutes
* [ ] Verify key user flows work
* [ ] Update team in #deployments channel
````
**Benefit**: Standardizes deployment process across team.
---
### Step 5: Document Team Conventions
Create `CONVENTIONS.md` in your repo:
```markdown
# agentful Team Conventions
## PRODUCT.md Standards
### Priority Levels
- **CRITICAL**: Launch blockers, security, data integrity
- **HIGH**: Important features, can ship 1-2 days later
- **MEDIUM**: Nice to have, Polish
- **LOW**: Future improvements, optimizations
### Acceptance Criteria Format
All acceptance criteria must:
- Start with a verb ("Display", "Validate", "Handle")
- Be testable (can write a test for it)
- Be specific (no "good performance", use "< 200ms")
### Required Sections
Every feature must have:
- Description (one sentence)
- Acceptance criteria (checkbox list)
- User stories (for complex features)
- Technical notes (if integrating with existing systems)
## Code Standards
### File Naming
- Components: PascalCase (UserProfile.tsx)
- Utilities: camelCase (formatDate.ts)
- Hooks: camelCase with 'use' prefix (useAuth.ts)
- Types: PascalCase with 'Type' suffix (UserType)
### Import Order
```typescript
// 1. React
import { useState } from 'react';
// 2. Third-party
import { z } from 'zod';
// 3. Internal
import { Button } from '@/components/ui/button';
import { useAuth } from '@/hooks/useAuth';
````
### Git Workflow
#### Branch Naming
* `feature/agentful-[feature-name]` - Features agentful builds
* `fix/agentful-[issue]` - agentful fixes
* `refactor/agentful-[area]` - agentful refactors
#### Commit Messages
When agentful makes commits:
```
feat(agentful): implement user authentication
agentful-built feature:
- Login form with email/password
- JWT token generation
- Protected routes
- Unit tests (82% coverage)
Generated by agentful orchestrator
```
### Review Process
#### agentful-Generated PRs
1. **Auto-label**: Add `agent-generated` label
2. **Auto-assign**: Assign to team lead for review
3. **Checklist**:
* [ ] Tests pass locally
* [ ] No type errors (adapts to stack)
* [ ] Security review (if auth/data)
* [ ] Performance review (if API/DB)
* [ ] UX review (if frontend)
4. **Approval**: Requires 1 approval + CI pass
#### Human Edits to agentful Code
If you modify agentful-generated code:
1. Add comment: `// Human-modified: [reason]`
2. Update tests to match
3. Run `/agentful-validate` to ensure gates pass
### Decision Handling
#### Team Decisions
When agentful needs input, team decides in #agentful channel:
```markdown
@team agentful needs decision:
Feature: User notifications
Question: Should we use WebSocket or polling?
Options:
1. WebSocket (real-time, more complex)
2. Polling every 30s (simpler, slight delay)
3. Server-Sent Events (middle ground)
Context: Building notification system for PRODUCT.md
React with :one: :two: or :three:
```
#### Decision Documentation
After deciding, add to `.agentful/decisions.json`:
```json
{
"id": "decision-001",
"question": "WebSocket vs polling for notifications?",
"answer": "Option 1: WebSocket",
"reason": "Real-time is critical for collaboration features",
"decidedBy": "team",
"timestamp": "2026-01-18T10:00:00Z"
}
```
### Collaboration Rules
#### Working on Same Project
1. **Coordinate in #agentful channel** before running `/agentful-start`
2. **Feature ownership**: Claim features before agentful starts
3. **Staggered runs**: Don't run agentful simultaneously on same project
4. **Sync frequently**: Push state changes regularly
#### Code Conflicts
If you edit code agentful is working on:
1. **Stop agentful**: Let current task complete
2. **Resolve manually**: Fix conflicts yourself
3. **Validate**: Run `/agentful-validate`
4. **Resume**: `/agentful-start` continues
#### State File Sharing
```bash
# Always pull latest state before starting agentful
git pull origin main
# Push state after agentful completes features
git add .agentful/
git commit -m "Update agentful state"
git push origin main
```
### Quality Standards
#### Before Marking Feature Complete
* [ ] All acceptance criteria pass
* [ ] Tests written and passing
* [ ] No type errors (adapts to stack)
* [ ] No console.log or debug statements
* [ ] Code follows team conventions
* [ ] Documentation updated (if needed)
#### Code Review for agentful Code
Review like human-written code:
* Is it maintainable?
* Is it performant?
* Is it secure?
* Does it follow patterns?
* Are tests sufficient?
### Onboarding New Team Members
#### Learning Path
**Step 1: Observe**
* Watch agentful build a simple feature
* Review generated code with mentor
* Understand PRODUCT.md format
**Step 2: Practice**
* Write PRODUCT.md for small feature with mentor
* Run `/agentful-start` with guidance
* Review code together
**Step 3: Independent**
* Write PRODUCT.md independently
* Run agentful solo
* Team review of first solo project
**Step 4: Proficient**
* Handle complex features
* Mentor new team members
* Contribute to team config improvements
#### Example: First Feature
**Junior developer's first agentful feature:**
```bash
# 1. Clone project and setup
git clone team-repo
cd team-repo
npx @itz4blitz/agentful init # If not already initialized
# 2. Study existing code
cat PRODUCT.md
/agentful-status # See what's being worked on
# 3. Ask for a simple feature
"Mentor: What simple feature should I start with?"
"Try adding user profile editing"
# 4. Write PRODUCT.md addition
## Features
### 4. User Profile Editing - MEDIUM
**Description**: Users can edit their profile
**Acceptance Criteria**:
- [ ] Edit display name
- [ ] Upload avatar
- [ ] Save changes
# 5. Run agentful
/agentful-start
# 6. Watch it build
# agentful generates tests, implements feature, validates
# 7. Review with mentor
# Get feedback, learn patterns
```
**Benefit**: New team members learn by doing, with gradual responsibility.
***
### Collaboration Workflows
#### Workflow 1: Feature Branch Development
**Pattern**: Each feature in its own branch
```bash
# 1. Create feature branch
git checkout -b feature/agentful-user-auth
# 2. Write/update PRODUCT.md
# Add authentication feature details
# 3. Run agentful
claude
/agentful-start
# 4. agentful builds feature, commits to branch
# 5. Human review
git push origin feature/agentful-user-auth
# Create PR, team reviews
# 6. Merge to main
git checkout main
git merge feature/agentful-user-auth
```
**Pros**:
* Isolated development
* Easy to review
* Can run multiple features in parallel
**Cons**:
* Merge conflicts if branches touch same files
* More Git overhead
***
#### Workflow 2: Main Branch Development
**Pattern**: Direct development on main branch
```bash
# 1. Pull latest
git checkout main
git pull origin main
# 2. Update PRODUCT.md
# Add next feature to build
# 3. Run agentful
claude
/agentful-start
# 4. agentful builds, commits directly to main
# 5. Team reviews via PR after completion
git push origin main
# Create PR from main to main (for review)
# Merge after approval
```
**Pros**:
* Simpler Git workflow
* Fewer merge conflicts
* Continuous delivery style
**Cons**:
* Harder to work in parallel
* Main branch can be unstable
**Best for**: Small teams, rapid prototyping
***
#### Workflow 3: Distributed Feature Development
**Pattern**: Team members claim features, develop in parallel
```markdown
In #agentful channel:
@alice Claiming "user authentication" feature
@bob Claiming "project management" feature
@carol Claiming "task CRUD" feature
[Each creates their branch]
alice: git checkout -b feature/auth
bob: git checkout -b feature/projects
carol: git checkout -b feature/tasks
[Each runs agentful on their feature branch]
[Each creates PR when done]
[Team reviews and merges in priority order]
```
**Pros**:
* Parallel development
* Clear ownership
* Faster overall completion
**Cons**:
* Coordination overhead
* Possible overlapping work
**Best for**: Large teams, many features
***
### Decision Making at Scale
#### Async Decision Process
**When agentful needs input:**
1. **agentful adds to decisions.json**:
```json
{
"id": "decision-007",
"question": "Should email notifications use queue or send immediately?",
"context": "Building notification system, expect 1000 emails/hour at peak",
"blocking": ["email-notifications"],
"options": [
"Queue with Redis (reliable, more complex)",
"Send immediately (simpler, may block)",
"Third-party service (SendGrid, reliable, cost)"
]
}
```
2. **Automated Slack notification**:
```javascript
// .claude/skills/slack-notifier/SKILL.md
// When decision.json changes, post to #agentful
{
"text": "Decision needed from agentful",
"attachments": [{
"title": "Email notification strategy",
"text": "Context: Building notification system...",
"actions": [
{ "text": "Queue", "value": "option-1" },
{ "text": "Immediate", "value": "option-2" },
{ "text": "SendGrid", "value": "option-3" }
]
}]
}
```
3. **Team votes in thread**
4. **Majority wins**, update decisions.json:
```bash
/agentful-decide
# agentful reads updated decisions.json, resumes work
```
**Benefit**: Team doesn't block agentful. Decisions happen async.
***
#### Decision Escalation Path
**Level 1: Individual Developer**
* Developer decides immediately
* Document in decisions.json
* No team review needed
**Level 2: Team Consensus**
* Post in #agentful channel
* 15-minute discussion
* Majority vote wins
**Level 3: Tech Lead**
* Controversial or high-impact decisions
* Tech lead makes final call
* Document reasoning
**Level 4: Product Manager**
* Product strategy decisions
* PM decides with tech input
* Affects roadmap and priorities
**Level 5: CTO/Architecture**
* Fundamental architecture changes
* Security-critical decisions
* Long-term tech stack implications
***
### Code Review Integration
#### Hybrid Review Process
**agentful generates code** → **Automated checks** → **Human review** → **Merge**
```mermaid
graph LR
A[agentful Builds] --> B[agentful Reviewer]
B --> C{Gates Pass?}
C -->|No| D[agentful Fixer]
D --> B
C -->|Yes| E[Create PR]
E --> F[Human Review]
F --> G{Approved?}
G -->|No| H[Human Edits]
H --> E
G -->|Yes| I[Merge]
```
#### Review Checklist for agentful Code
**Automated (agentful Reviewer)**:
* ✅ All tests passing
* ✅ No type errors (adapts to stack)
* ✅ 80%+ coverage
* ✅ No dead code
* ✅ No security issues
**Human (Team Reviewer)**:
* ✅ Follows team conventions
* ✅ Maintainable and readable
* ✅ Performance acceptable
* ✅ Error handling complete
* ✅ Accessibility considered
* ✅ Documentation adequate
#### Review Acceleration Tips
**For faster reviews:**
1. **Small PRs**: agentful should complete features before creating PRs, not mid-feature
2. **Clear descriptions**: PR description should link to PRODUCT.md feature
3. **Automated labels**: Apply labels based on feature type (`auth`, `ui`, `api`)
4. **Assign reviewers**: Auto-assign based on file ownership
5. **Template PR descriptions**:
```markdown
## agentful-Generated PR
**Feature**: User Authentication (PRODUCT.md #1)
**Agent**: orchestrator + backend + frontend + tester
**Commit Hash**: abc123
### What was built
- Login form with email/password
- JWT authentication service
- Protected API routes
- Unit and integration tests
### Validation Results
- ✅ Tests: 47 passing
- ✅ TypeScript: 0 errors
- ✅ Coverage: 84%
- ✅ Dead code: 0 issues
- ✅ Security: 0 vulnerabilities
### Files changed
- `src/app/api/auth/login/route.ts` (new)
- `src/components/auth/LoginForm.tsx` (new)
- `src/lib/auth/jwt.ts` (new)
- `src/lib/auth/__tests__/jwt.test.ts` (new)
### Checklist
- [ ] Follows team conventions
- [ ] Performance acceptable
- [ ] Error handling complete
- [ ] Ready to merge
**Link to acceptance criteria**: [PRODUCT.md#1](../../PRODUCT.md#L50)
```
***
### Conflict Resolution
#### Scenario 1: Human Edits Conflict with agentful
**Situation**: You manually edit code, agentful changes same file later.
**Resolution**:
```bash
# 1. Stop agentful
# Let current task complete
# 2. Review conflicts
git diff
# Identify what agentful changed vs your changes
# 3. Decide which to keep
# Usually: Keep human edits, let agentful adapt
# 4. Document human override
// Human-modified: [reason] - [date] - [author]
// Original agentful logic was: [description]
# 5. Re-validate
/agentful-validate
# 6. Resume agentful
/agentful-start
# agentful will adapt to your changes
```
**Prevention**:
* Coordinate in #agentful before editing agentful code
* Edit different files than agentful is working on
* Use branches to isolate changes
***
#### Scenario 2: Multiple Team Members Running agentful
**Situation**: Two team members run `/agentful-start` on same project simultaneously.
**Symptoms**:
* Conflicting commits
* Race conditions in state.json
* Overwriting each other's work
**Resolution**:
**Short term**:
```bash
# 1. Both stop agentful
# 2. Decide who continues based on:
# - Who started first
# - Who has more critical feature
# - Rock-paper-scissors if tied
# 3. Other person pulls changes:
git pull origin main
git checkout -b feature/their-feature
# Move their PRODUCT.md edits to this branch
# 4. Winner continues:
/agentful-start
```
**Long term**: Create coordination system:
```bash
# .claude/skills/coord-lock/SKILL.md
# Before starting, check if locked
if [ -f .agentful/.lock ]; then
echo "agentful already running by $(cat .agentful/.lock)"
echo "Contact them to coordinate"
exit 1
fi
# Create lock
echo "$(whoami)@$(hostname) on $(date)" > .agentful/.lock
# Release lock when done
trap "rm -f .agentful/.lock" EXIT
```
***
#### Scenario 3: Disagreement on Implementation
**Situation**: agentful builds feature one way, team thinks it should be different.
**Example**: agentful uses React Query, team prefers Redux.
**Resolution**:
**Option 1: Let agentful decide**
* If no strong preference, let agentful continue
* Document team learns new pattern
* Evaluate after feature complete
**Option 2: Override via Technical Notes**
```markdown
**Technical Notes**:
- Use Redux Toolkit for state management (team standard)
- Follow existing pattern in src/store/
- Do NOT use React Query
```
**Option 3: Build and refactor**
* Let agentful complete with its approach
* Team reviews and decides
* If refactor needed, add to next sprint
* Update technical notes for future
**Key**: Decide **before** agentful builds, not after.
***
### Monitoring and Observability
agentful provides built-in progress tracking and monitoring:
#### Check Progress Anytime
Each team member can check project status:
```bash
/agentful-status
```
Output shows:
* Current task being worked on
* Overall progress percentage
* Quality gate status
* Pending decisions that need attention
#### Example Output
```
🔧 Working on: User authentication feature
Phase: implementation
Iterations: 12
Progress:
████████░░░░░░░░░░░ 40%
Quality Gates:
✅ Tests Passing
✅ No Type Errors
✅ Coverage 80%
✅ No Dead Code
✅ Security Clean
⚠️ 2 pending decisions:
1. Which auth library to use?
2. Session duration?
```
#### What Gets Tracked Automatically
* **Progress**: `.agentful/completion.json` - feature completion % per feature
* **State**: `.agentful/state.json` - current task, phase, iterations
* **Decisions**: `.agentful/decisions.json` - pending/resolved decisions
* **Architecture**: `.agentful/architecture.json` - detected tech stack
All tracking happens automatically - no manual setup needed.
***
### Training and Onboarding
#### New Team Member Checklist
**Getting Started**
* [ ] Read team CONVENTIONS.md
* [ ] Study existing PRODUCT.md files
* [ ] Review agentful-generated code
* [ ] Run `/agentful-status` on active projects
* [ ] Attend team agentful standup
**First Feature**
* [ ] Write PRODUCT.md for simple feature
* [ ] Get review from mentor
* [ ] Run `/agentful-start` with supervision
* [ ] Review generated code together
* [ ] Fix validation issues with guidance
**Working Independently**
* [ ] Write PRODUCT.md independently
* [ ] Run agentful solo
* [ ] Handle first decision
* [ ] Create and merge PR
* [ ] Present work to team
**Full Contributor**
* [ ] Handle complex feature
* [ ] Mentor another new member
* [ ] Contribute improvement to team config
* [ ] Lead decision discussion
#### Team Workshop Agenda
**2-Hour Workshop: agentful for Teams**
**Hour 1: Concepts and Setup**
* Demo: agentful building a feature (20 min)
* Team config tour (.claude/) (15 min)
* PRODUCT.md writing exercise (25 min)
**Hour 2: Hands-On**
* Pairs write PRODUCT.md for feature (20 min)
* Run agentful, observe results (20 min)
* Group retrospective (20 min)
**Outcomes**: Team aligned on standards, confident using agentful
***
### Summary: Successful Team Adoption
#### Keys to Success
1. **Start with standards** - Define conventions before adopting
2. **Customize agents** - Encode team patterns in agent instructions
3. **Document everything** - Conventions, workflows, decisions
4. **Coordinate early** - Don't let conflicts happen
5. **Review hybrid** - agentful auto-review + human review
6. **Decide async** - Don't block on decisions
7. **Train continuously** - Onboarding, workshops, pair programming
#### Common Pitfalls to Avoid
* ❌ Skipping conventions documentation
* ❌ Letting multiple members run agentful simultaneously
* ❌ Not coordinating PRODUCT.md changes
* ❌ Ignoring team decisions in decisions.json
* ❌ Skipping human review of agentful code
* ❌ Not training new team members
#### When Teams Struggle
**Symptom**: Constant conflicts, confusion, rework
**Solution**: Pause and standardize
1. Host team workshop to align
2. Update CONVENTIONS.md based on learnings
3. Reset project with clear standards
4. Require review of all PRODUCT.md before agentful runs
**Symptom**: agentful generates code team won't accept
**Solution**: Improve technical notes in PRODUCT.md
1. Review rejected PRs
2. Identify patterns agentful missed
3. Add to team agent instructions
4. Update PRODUCT.md template with examples
***
### Next Steps
Ready to adopt agentful as a team?
1. **[Read Best Practices](./best-practices)** - Learn from experienced teams
2. **[Set Up Team Config](../getting-started/configuration)** - Customize agents
3. **[Write Team PRODUCT.md Template](./writing-product-md)** - Standardize specs
4. **[Handle Troubleshooting](./troubleshooting)** - Fix team issues
***
**Related Guides:**
* [Writing Effective PRODUCT.md](./writing-product-md) - Spec standards
* [Best Practices](./best-practices) - Proven patterns
* [Troubleshooting](./troubleshooting) - Resolve conflicts
## Troubleshooting Guide
agentful usually runs smoothly, but when issues arise, this guide helps you diagnose and resolve them quickly.
***
### Quick Diagnostic Steps
Before diving into specific issues, run these checks:
```bash
# 1. Check agentful state
/agentful-status
# 2. Check validation status
/agentful-validate
# 3. Check for decisions
cat .agentful/decisions.json
# 4. Check for TypeScript errors
npx tsc --noEmit
# 5. Check tests
npm test
```
**This tells you**:
* Where agentful is stuck
* What's failing validation
* If decisions are blocking progress
* If there are basic code issues
***
### Common Issues by Category
### Category 1: agentful Seems Stuck
#### Symptom 1.1: No Progress After Many Iterations
**What you see**:
```
Running iteration 25...
Working on: User authentication
No changes in last 10 iterations
```
**Diagnosis**:
```bash
# Check what's happening
/agentful-status
# Check state file
cat .agentful/state.json
# Check if decisions are blocking
cat .agentful/decisions.json | jq '.pending'
```
**Common causes**:
1. **Pending decision blocking work**
2. **Validation loop (can't pass gates)**
3. **Agent doesn't know what to do next**
4. **PRODUCT.md unclear**
***
#### Solution 1.1: Check for Decisions
**If pending decisions exist**:
```json
{
"pending": [
{
"id": "decision-003",
"question": "Should auth use JWT or sessions?",
"blocking": ["authentication", "user-profile"]
}
]
}
```
**Fix**: Run decision handler
```bash
/agentful-decide
# Provide your answer:
Option 1: JWT (stateless, scalable)
```
agentful will resume immediately.
***
#### Solution 1.2: Check for Validation Loops
**If status shows validation passing and failing repeatedly**:
```bash
# Check last validation
cat .agentful/last-validation.json
# Check what's failing
jq '.checks | to_entries[] | select(.value.passed == false)'
```
**Common validation loop causes**:
##### Cause A: Dead Code Can't Be Fixed
**Symptom**: Reviewer finds dead code, Fixer can't remove it
**Example**:
```typescript
// Export is marked unused, but it IS used
export function utilityFunction() { ... }
// ts-prune says unused, but dynamic import uses it:
const module = await import('./utils');
module.utilityFunction();
```
**Fix**: Add technical note to PRODUCT.md
```markdown
**Technical Notes**:
- utilityFunction in src/utils/index.ts is dynamically imported
- Ignore dead code warnings for this function
```
Or whitelist in reviewer agent:
```markdown
## Dead Code Whitelist
- src/utils/index.ts:utilityFunction (dynamically imported)
```
***
##### Cause B: Test Coverage Stuck Below 80%
**Symptom**:
```
Coverage at 72%, needs 80%
Coverage at 75%, needs 80%
Coverage at 77%, needs 80%
[Stuck here]
```
**Why**: agentful adding tests but not enough
**Fix**: Identify uncovered code
```bash
npm test -- --coverage --reporters=json
# Check coverage report for uncovered files
```
**Manual intervention**: Add critical tests yourself
```bash
# Let agentful handle easy tests, you write complex ones
# Then re-run:
/agentful-validate
```
**Or temporarily lower threshold** (for MVP):
Edit `.claude/agents/reviewer.md`:
```markdown
### 6. Coverage Check
**FAIL if:** Coverage < 70% # Temporarily lowered
```
***
##### Cause C: Type Errors agentful Can't Resolve
**Symptom**: Same type error appears repeatedly
**Example**:
```typescript
// Error: Property 'userId' does not exist on type 'Session'
const userId = session.userId;
```
**Fix**: Run type check manually to see full error
```bash
npx tsc --noEmit
# Output:
src/app/api/auth/route.ts:15:25 - error TS2339:
Property 'userId' does not exist on type 'Session'.
```
**Fix the type definition yourself**:
```typescript
// Add missing property
interface Session {
userId: string;
token: string;
}
```
**Then resume**:
```bash
/agentful-start
```
***
#### Solution 1.3: Unclear PRODUCT.md
**If agentful keeps reading PRODUCT.md but not building**:
**Check**:
```bash
# See what agentful is trying to understand
# Look in conversation history for:
# "Reading PRODUCT.md..."
# "Analyzing feature X..."
# "Need clarification on..."
```
**Fix**: Add detail to unclear features
```markdown
# Before (vague)
### 3. User Profile - HIGH
Users can see their profile.
# After (specific)
### 3. User Profile - HIGH
**Description**: Users can view and edit their profile information
**Acceptance Criteria**:
- [ ] Display user name, email, avatar
- [ ] Edit form for name and avatar URL
- [ ] Email is read-only (can't change)
- [ ] Save button updates user in database
- [ ] Cancel button reverts changes
```
***
#### Symptom 1.4: agentful Stops Without Completing
**What you see**:
```
Feature complete: User authentication (100%)
[agentful exits]
```
**But**: More features remain in PRODUCT.md
**Diagnosis**:
```bash
# Check completion
cat .agentful/completion.json
# Check state
cat .agentful/state.json
```
**Possible causes**:
##### Cause A: Ralph Loop Reached Max Iterations
**If using Ralph loop**:
```bash
/ralph-loop "/agentful-start" --max-iterations 50
```
agentful stops after 50 iterations even if incomplete.
**Fix**: Increase limit or remove it
```bash
/ralph-loop "/agentful-start" --max-iterations 100
```
Or run without limit (use caution):
```bash
/ralph-loop "/agentful-start"
```
##### Cause B: All Remaining Features Blocked
**Decisions blocking all remaining work**
**Fix**: Run `/agentful-decide` to unblock
##### Cause C: Completion.json Marked Complete Incorrectly
**Manual correction needed**:
```bash
# Edit .agentful/completion.json
# Change feature status from "complete" to "in_progress"
# Then resume:
/agentful-start
```
***
### Category 2: Validation Failures
#### Symptom 2.1: Tests Keep Failing
**What you see**:
```
Test: User login
Expected: 200 status
Received: 401 status
❌ FAIL
```
**Diagnosis**:
```bash
# Run tests manually to see full output
npm test
# Check test file
cat src/__tests__/auth.test.ts
```
**Common causes**:
##### Cause A: Test Out of Sync with Implementation
**Code changed, test didn't update**
**Example**:
```typescript
// Test expects:
expect(response.status).toBe(200);
// But code returns:
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
```
**Fix**: Update test to match implementation (or vice versa)
**Prevention**: Tell agentful to regenerate tests
```markdown
**Technical Notes**:
- Regenerate all tests for this feature to match current implementation
```
***
##### Cause B: Missing Test Setup
**Test uses data that doesn't exist**
**Example**:
```typescript
// Test expects:
const user = await createUser({ email: "test@example.com" });
// But createUser not mocked or doesn't exist
```
**Fix**: Add setup/teardown to test
```typescript
beforeEach(async () => {
await setupTestData();
});
afterEach(async () => {
await cleanupTestData();
});
```
***
##### Cause C: Async/ Await Issues
**Test doesn't wait for async code**
**Example**:
```typescript
// Wrong (missing await):
act(() => {
render();
});
expect(screen.getByText("Welcome")).toBeInTheDocument();
// Correct:
await act(async () => {
render();
});
expect(await screen.findByText("Welcome")).toBeInTheDocument();
```
**Fix**: Add `await` and `async` properly
***
#### Symptom 2.2: TypeScript Errors Won't Go Away
**What you see**:
```
error TS2322: Type 'string' is not assignable to type 'number'
```
**Diagnosis**:
```bash
npx tsc --noEmit
```
**Common causes**:
##### Cause A: Type Mismatch
```typescript
// Function expects number, receives string
function setId(id: number) { ... }
setId("123"); // Error: string not assignable to number
```
**Fix**: Convert type
```typescript
setId(parseInt("123"));
// OR update function to accept string
function setId(id: string | number) { ... }
```
##### Cause B: Missing Type Definition
```typescript
// Using library without types
import { someLibrary } from 'untyped-library';
// Error: Could not find namespace for someLibrary
```
**Fix**: Install types
```bash
npm install --save-dev @types/untyped-library
```
Or add declaration:
```typescript
declare module 'untyped-library';
```
##### Cause C: Strict null Checks
```typescript
// Might be undefined
const user = users.find(id);
// Error: Object is possibly 'undefined'
console.log(user.name);
```
**Fix**: Add check
```typescript
const user = users.find(id);
if (!user) {
throw new Error("User not found");
}
console.log(user.name);
```
***
#### Symptom 2.3: Dead Code Detection Issues
**What you see**:
```
Unused export: validateEmail in src/utils/auth.ts
But export IS used!
```
**Diagnosis**:
```bash
# Check where it's used
grep -r "validateEmail" src/
# Might be dynamically imported
# Or used in way tool can't detect
```
**Common causes**:
##### Cause A: Dynamic Import
```typescript
// Export seems unused
export function validateEmail() { ... }
// But imported dynamically
const module = await import('./auth');
module.validateEmail();
```
**Fix**: Add to whitelist or comment
```typescript
// Used dynamically - don't remove
export function validateEmail() { ... }
```
##### Cause B: Exported for Side Effects
```typescript
// Function not called, but has side effects when imported
export function setupLogging() {
configureGlobalLogger();
}
// Import triggers side effects
import './utils/logging';
```
**Fix**: Rename to show side effect
```typescript
// Side effect - don't remove
export function _setupLogging() { ... }
```
***
### Category 3: Performance Issues
#### Symptom 3.1: agentful Runs Very Slowly
**What you see**: One feature takes hours instead of minutes
**Diagnosis**:
```bash
# Check what's taking time
# Look for repeated operations:
# - Running tests many times
# - Reading same files repeatedly
# - Checking dead code over and over
```
**Common causes**:
##### Cause A: Large Codebase
**1000+ files, agentful scans everything each iteration**
**Fix**: Exclude directories from agent searches
```markdown
# In .claude/agents/orchestrator.md
## Search Scope
Only search these directories:
- src/
- tests/
Ignore:
- node_modules/
- .next/
- build/
- dist/
- public/
```
##### Cause B: Expensive Validation
**Running all tests takes 10+ minutes**
**Fix**: Run faster subset during development
```bash
# Quick test mode during agentful runs
npm test -- --passWithNoTests --maxWorkers=4
# Full test suite only on final validation
npm test -- --coverage
```
##### Cause C: Dead Code Detection on Large Projects
**knip or ts-prune takes forever**
**Fix**: Disable or reduce scope
```bash
# Skip dead code check during iteration
# Only run on final validation
# In reviewer.md, comment out:
# ### 3. Dead Code Detection
```
***
#### Symptom 3.2: High Memory Usage
**What you see**: Claude Code using 2GB+ RAM, system slows down
**Diagnosis**: agentful reading too much into context
**Fix**: Reduce file reading
```markdown
# In agent instructions:
## File Reading Limits
- Only read files directly related to current task
- Don't read entire directories at once
- Use Glob to find files, Read only what's needed
- Limit file size: skip files > 10KB unless necessary
```
**Or restart Claude periodically**:
```bash
# Let context flush
# Exit and restart every 20-30 iterations
```
***
### Category 4: State File Issues
#### Symptom 4.1: State.json Corrupted
**What you see**:
```bash
cat .agentful/state.json
# Parse error: Invalid JSON
```
**Diagnosis**: File was edited manually or write interrupted
**Fix**: Restore from backup or reset
```bash
# Check git history
git log .agentful/state.json
# Restore last good version
git checkout abc123 -- .agentful/state.json
# OR reset to initial state
rm .agentful/state.json
/agentful-start # Will recreate file
```
**Prevention**: Don't edit state files manually
***
#### Symptom 4.2: State Not Updating
**What you see**:
```
Feature complete, but state.json still shows "in_progress"
```
**Fix**: Manual update
```bash
# Edit .agentful/completion.json
{
"features": {
"authentication": {
"status": "complete", # Change from "in_progress"
"score": 100
}
}
}
```
***
### Category 5: Integration Issues
#### Symptom 5.1: Git Conflicts with agentful
**What you see**:
```
git pull
CONFLICT (content): Merge conflict in .agentful/state.json
```
**Diagnosis**: Multiple sources updating state files
**Fix**:
```bash
# Decide which state to keep
# Usually: Keep local (your work takes precedence)
git checkout --ours .agentful/state.json
git add .agentful/state.json
git commit
# Or for remote changes
git checkout --theirs .agentful/state.json
git add .agentful/state.json
git commit
```
**Prevention**: Don't push state files frequently. Only on milestones.
***
#### Symptom 5.2: Environment Variables Missing
**What you see**:
```
Error: process.env.DATABASE_URL is undefined
```
**Diagnosis**: agentful trying to use env var that's not set
**Fix**: Add to `.env.local`:
```bash
DATABASE_URL="postgresql://..."
NEXT_PUBLIC_API_URL="https://..."
```
**And document in PRODUCT.md**:
```markdown
## Environment Variables Required
- `DATABASE_URL` - PostgreSQL connection string
- `NEXT_PUBLIC_API_URL` - API base URL
- `JWT_SECRET` - Secret for token signing
```
***
### Category 6: Agent Behavior Issues
#### Symptom 6.1: Agent Builds Wrong Thing
**What you see**: agentful builds X when you asked for Y
**Diagnosis**: PRODUCT.md unclear or ambiguous
**Example from PRODUCT.md**:
```markdown
### 1. User Management - CRITICAL
Users can manage their accounts.
# agentful might build:
# - Account creation
# - Profile editing
# - Account deletion
# But you wanted:
# - Login/Logout only
```
**Fix**: Be explicit about what NOT to build
```markdown
### 1. User Authentication - CRITICAL
**Description**: Users can login and logout
**Acceptance Criteria**:
- [ ] Login form with email/password
- [ ] JWT token generation
- [ ] Logout functionality
- [ ] Protected routes
**Out of Scope**:
- User registration (use admin panel)
- Profile editing (feature #2)
- Account deletion (feature #3)
```
***
#### Symptom 6.2: Agent Overwrites Manual Edits
**What you see**: You edit code, agentful changes it back
**Diagnosis**: agentful doesn't know you edited it
**Fix**: Document your edits
```typescript
// Human-modified: Added custom error handling for edge case
// Date: 2026-01-18
// Reason: Needed to handle malformed responses from API
// Do not modify without consulting team
function handleApiResponse(response: Response) {
// Custom logic here...
}
```
**Or tell agentful in technical notes**:
```markdown
**Technical Notes**:
- src/app/api/handler.ts has custom error handling
- Do NOT modify the try/catch block (lines 25-40)
- Build around it
```
***
#### Symptom 6.3: Agent Won't Stop
**What you see**: agentful keeps working past completion
**Diagnosis**: Completion criteria not met
**Fix**: Check what's incomplete
```bash
cat .agentful/completion.json
```
**Might be**:
* One gate not passing (e.g., coverage at 79%)
* One checkbox not checked in PRODUCT.md
* Quality gate failing
**Manual override** (if truly done):
```bash
# Mark complete manually
# Edit .agentful/completion.json:
{
"overall": 100,
"features": {
"all": "complete"
}
}
# Then stop agentful
# Don't let it continue looping
```
***
### Emergency Recovery Procedures
#### Recovery 1: Complete Reset
**When everything is broken and you need to start over**
```bash
# 1. Backup current work
cp -r .agentful .agentful.backup
git add .
git commit -m "Backup before reset"
# 2. Remove agentful state
rm -rf .agentful/
# 3. Start fresh
/agentful-start
# agentful will re-analyze PRODUCT.md and start over
```
**Warning**: You lose all progress tracking, but code remains.
***
#### Recovery 2: Rollback to Working State
**When agentful broke something that worked**
```bash
# 1. Find last good commit
git log --oneline
# 2. Reset to that commit
git reset abc123 --hard
# 3. Remove bad state
rm -rf .agentful/
# 4. Restart from good point
/agentful-start
```
***
#### Recovery 3: Manual Feature Completion
**When agentful can't complete a feature, you need to**
```bash
# 1. Stop agentful
# Let it finish current task, then exit
# 2. Complete feature yourself
# Write remaining code, tests, etc.
# 3. Update completion.json
{
"features": {
"your-feature": {
"status": "complete",
"score": 100,
"completedManually": true
}
}
}
# 4. Validate
/agentful-validate
# 5. Resume agentful for next feature
/agentful-start
```
***
### Getting Help
#### When to Ask for Help
**Self-solvable** (use this guide):
* Validation loops
* Type errors
* Test failures
* State issues
**Ask for help**:
* agentful crashes Claude Code
* Data loss or corruption
* Can't diagnose after 30 minutes
* Same issue repeats after fix
#### How to Report Issues
**Good issue report**:
```markdown
## agentful Issue Report
### What I was doing
Running `/agentful-start` on authentication feature
### What happened
agentful entered validation loop, stuck at 78% coverage
### Steps to reproduce
1. Run `/agentful-start`
2. Wait for authentication feature
3. Coverage stuck at 78%
### Environment
- Node.js: v20
- Framework: Next.js 14
- Database: PostgreSQL + Prisma
- Testing: Vitest
### State files
[Attach .agentful/state.json, completion.json, last-validation.json]
### PRODUCT.md
[Attach relevant feature section]
### Error logs
[Paste relevant errors]
```
**Where to report**:
* GitHub Issues: [https://github.com/blitz/agentful/issues](https://github.com/blitz/agentful/issues)
* Discord: \[agentful Discord channel]
***
### Prevention Checklist
**Before starting agentful**:
* [ ] PRODUCT.md is complete and specific
* [ ] Tech stack fully specified
* [ ] All features prioritized
* [ ] Acceptance criteria are testable
* [ ] Environment variables set
* [ ] Dependencies installed
* [ ] Git repository initialized
**During agentful run**:
* [ ] Check status every 5-10 iterations
* [ ] Monitor for decisions needing answers
* [ ] Don't interrupt mid-task
* [ ] Let validation loops run a few times
* [ ] Push code to Git periodically
**When issues arise**:
* [ ] Run diagnostics first
* [ ] Check state files
* [ ] Review validation output
* [ ] Try solutions from this guide
* [ ] Ask for help if stuck > 30 minutes
***
### Summary: Troubleshooting Mindset
**Effective troubleshooting**:
1. **Diagnose first** - Use quick diagnostic steps
2. **Find root cause** - Don't just treat symptoms
3. **Apply targeted fix** - Use the right solution
4. **Verify it worked** - Run `/agentful-validate`
5. **Prevent recurrence** - Update PRODUCT.md or config
**Most common fixes**:
* Run `/agentful-decide` for decisions
* Add detail to PRODUCT.md for unclear requirements
* Update tests manually if they're out of sync
* Fix type errors manually (agentful struggles with complex types)
* Reset state if corrupted
**When in doubt**:
1. Check state files
2. Run validation
3. Ask for help
***
### Next Steps
Fixed your issue? Great! Now:
1. **[Write Better PRODUCT.md](./writing-product-md)** - Prevent future issues
2. **[Follow Best Practices](./best-practices)** - Avoid common pitfalls
3. **[Review Team Adoption](./team-adoption)** - If working with others
***
**Related Guides:**
* [Best Practices](./best-practices) - Prevention strategies
* [Team Adoption](./team-adoption) - Team troubleshooting
* [Writing PRODUCT.md](./writing-product-md) - Clearer specs
## Writing Product Specifications
The quality of your product specification directly determines how well agentful can build your product. A well-written spec leads to autonomous development success. A vague spec leads to confusion, decisions, and delays.
***
### Why Product Specifications Matter
Product specifications are the **single source of truth** for agentful. It's where you define:
* **What** you're building (overview and features)
* **How** it should work (acceptance criteria)
* **With what** technologies (tech stack)
* **When** it's done (success criteria)
agentful reads your specification on every iteration. The clearer and more specific it is, the less it needs to ask you for decisions.
### The Golden Rule
> **Be specific. Be explicit. Use checklists.**
Vague requirements force agentful to stop and ask. Specific requirements let agentful work autonomously.
***
### Specification Structures: Flat vs Hierarchical
agentful supports **two organizational structures** for your product specifications. Both are valid - choose based on your project's complexity and team needs.
#### Structure Overview
| Aspect | Flat Structure | Hierarchical Structure |
| ------------------- | ------------------------------------------ | ------------------------------------ |
| **File Location** | `PRODUCT.md` or `.claude/product/index.md` | `.claude/product/domains/*/index.md` |
| **Best For** | Small to medium projects (3-15 features) | Large projects (15+ features) |
| **Domain Concept** | Sections within one file | Separate directories per domain |
| **Maintainability** | Easy for single author | Better for team collaboration |
| **Scalability** | Can get unwieldy past \~20 features | Scales to 50+ features |
| **Navigation** | Scroll through one file | Separate files per domain |
#### Visual Comparison
**Flat Structure** (Single File):
```
.claude/product/index.md
├── Overview
├── Tech Stack
└── Features (by domain section)
├── Domain 1: Authentication
│ ├── Feature 1.1
│ └── Feature 1.2
├── Domain 2: Content Management
│ ├── Feature 2.1
│ └── Feature 2.2
└── Domain 3: Analytics
├── Feature 3.1
└── Feature 3.2
```
**Hierarchical Structure** (Directory Tree):
```
.claude/product/
├── index.md (overview + tech stack)
└── domains/
├── authentication/
│ └── index.md (features 1.1, 1.2)
├── content-management/
│ └── index.md (features 2.1, 2.2)
└── analytics/
└── index.md (features 3.1, 3.2)
```
#### Decision Matrix
Choose **Flat Structure** if:
* ✓ Your project has 15 or fewer features
* ✓ You're a solo developer or small team
* ✓ All features fit in 3-6 logical domains
* ✓ You want simpler file management
* ✓ You prefer everything in one place
Choose **Hierarchical Structure** if:
* ✓ Your project has 15+ features
* ✓ Multiple team members own different domains
* ✓ You have 6+ distinct business domains
* ✓ Domains have complex interdependencies
* ✓ You want parallel domain development
* ✓ You need granular progress tracking
#### Key Terminology Difference
**Important**: "Domain" means different things in each structure:
* **Flat**: Domains are **section headers** in your single file (organizational tool)
* **Hierarchical**: Domains are **actual directories** in your filesystem (architectural tool)
Both structures let you organize features by business domain - the difference is physical vs logical organization.
#### Migration Path
You can always start flat and migrate to hierarchical:
1. **Start**: Flat structure for rapid iteration
2. **Grow**: Hit \~15 features or multiple contributors?
3. **Migrate**: Split into domain directories (see migration guide below)
***
### Organizing Features by Domain
Both flat and hierarchical structures use **domain-based organization**. This approach helps agentful better understand feature relationships, dependencies, and implementation order.
#### What Are Domains?
**Domains** are high-level business areas that group related features together. Think of them as logical containers for functionality that belongs together.
**Examples of domains**:
* **Authentication & User Management** - User accounts, profiles, permissions
* **Content & Data Management** - CRUD operations, search, categorization
* **Communication & Collaboration** - Messaging, notifications, sharing
* **Commerce & Transactions** - Orders, payments, inventory
* **Analytics & Reporting** - Dashboards, charts, exports
#### Why Use Domains?
1. **Better Organization**: Related features stay together, making the spec easier to navigate
2. **Clearer Dependencies**: Domains show what functionality depends on what
3. **Focused Development**: agentful can complete one domain before moving to the next
4. **Parallelizable Work**: Different domains can often be developed in parallel
5. **Easier Maintenance**: Future features have a clear place to belong
#### How to Structure Domains
Use a three-level hierarchy:
```
Domain 1: [Domain Name]
├─ Feature 1.1 - [Priority]
├─ Feature 1.2 - [Priority]
└─ Feature 1.3 - [Priority]
Domain 2: [Domain Name]
├─ Feature 2.1 - [Priority]
└─ Feature 2.2 - [Priority]
```
In **flat structure**, these domains become section headers in one file.
In **hierarchical structure**, these domains become separate directories with their own files.
#### Example: Task Management App
**Instead of a flat list**:
```markdown
## Features
1. User Authentication - CRITICAL
2. Task Management - HIGH
3. Real-time Updates - MEDIUM
4. User Profile - LOW
5. Team Collaboration - MEDIUM
```
**Use domains**:
```markdown
## Features
### Domain 1: Authentication & User Management
#### 1.1 User Authentication - CRITICAL
[Details...]
#### 1.2 User Profile - LOW
[Details...]
### Domain 2: Task & Project Management
#### 2.1 Task Management - HIGH
[Details...]
#### 2.2 Real-time Updates - MEDIUM
[Details...]
### Domain 3: Team Collaboration
#### 3.1 Team Features - MEDIUM
[Details...]
```
#### Domain Best Practices
1. **Start with Critical Domains**: Begin with domains that contain CRITICAL priority features
2. **Limit Domain Count**: 3-6 domains is optimal for most projects
3. **Balance Features**: Each domain should have 2-5 features
4. **Clear Boundaries**: Features should clearly belong to one domain (no overlap)
5. **Logical Flow**: Order domains by dependency (authentication → content → analytics)
#### Identifying Your Domains
Ask yourself:
1. **What are the main business areas?**
* E-commerce: Products, Orders, Customers, Marketing
* SaaS: Users, Billing, Content, Analytics
* Social: Profiles, Connections, Content, Messaging
2. **What features belong together?**
* Group features that share data models
* Group features used by the same users
* Group features with similar technical requirements
3. **What depends on what?**
* Authentication usually comes first
* Core content before analytics
* Basic CRUD before advanced features
***
### Product Specification Templates
#### Template 1: Flat Structure (Single File)
**Best for**: Projects with 3-15 features, solo developers, small teams
**File locations**:
* `PRODUCT.md` (root directory)
* OR `.claude/product/index.md` (recommended)
```markdown
# Product Specification
## Overview
[2-3 sentences describing what you're building and who it's for]
## Goals
- [ ] [Primary goal 1]
- [ ] [Primary goal 2]
- [ ] [Primary goal 3]
## Tech Stack
### Frontend
- **Framework**: [Next.js 14 / React + Vite / Vue + Nuxt / SvelteKit]
- **Language**: [TypeScript / JavaScript]
- **Styling**: [Tailwind CSS / CSS Modules / styled-components / shadcn/ui]
- **State Management**: [Zustand / Context API / Redux / Jotai]
### Backend
- **Runtime**: [Node.js / Bun / Deno]
- **Framework**: [Next.js API Routes / Express / Fastify / NestJS / Hono]
- **Language**: [TypeScript / JavaScript]
### Database
- **Database**: [PostgreSQL / MySQL / SQLite / MongoDB / PlanetScale]
- **ORM**: [Prisma / Drizzle / TypeORM / Mongoose]
### Authentication
- **Method**: [JWT / NextAuth / Clerk / Auth0 / Lucia]
### Testing
- **Unit**: [Vitest / Jest]
- **E2E**: [Playwright / Cypress]
### Deployment
- **Hosting**: [Vercel / Netlify / Railway / Fly.io]
## Features (Domain-Based Organization)
Organize features into domains as sections, then prioritize within each domain:
### Domain 1: [Domain Name]
#### 1.1 [Feature Name] - CRITICAL
**Description**: [What this feature does in one sentence]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific, testable requirement 1]
- [ ] [Specific, testable requirement 2]
- [ ] [Specific, testable requirement 3]
**Technical Notes** (Optional):
- [API endpoints, components, libraries, etc.]
---
#### 1.2 [Feature Name] - HIGH
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
**Technical Notes** (Optional):
- [Relevant implementation details]
---
### Domain 2: [Domain Name]
#### 2.1 [Feature Name] - HIGH
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
---
#### 2.2 [Feature Name] - MEDIUM
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
---
### Domain 3: [Domain Name]
#### 3.1 [Feature Name] - MEDIUM
**Description**: [What this feature does]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
---
#### 3.2 [Feature Name] - LOW
**Description**: [What this feature does]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
---
**Note**: Repeat for as many domains and features as needed. Aim for 3-6 domains with 2-5 features each.
## Architecture Notes (Optional)
### Folder Structure
If you have a preferred structure:
src/
├── app/ # Next.js app router
├── components/ # React components
├── lib/ # Utilities
├── hooks/ # Custom hooks
└── styles/ # Global styles
Or:
src/
├── app/ # Next.js app router
├── components/ # React components
│ ├── ui/ # Reusable UI components
│ └── features/ # Feature-specific components
├── lib/ # Utilities and helpers
├── hooks/ # Custom React hooks
├── services/ # API services
└── types/ # TypeScript types
### Design Patterns
- [Any specific patterns to use]
- [Any patterns to avoid]
### Constraints
- [Performance requirements]
- [Accessibility requirements]
- [Browser support requirements]
## Third-Party Integrations (Optional)
- [API 1]: [Purpose and usage notes]
- [API 2]: [Purpose and usage notes]
## Out of Scope (for MVP)
List what you're explicitly NOT building:
- [Feature X] - Will add in v2
- [Feature Y] - Out of scope
- [Feature Z] - Not needed
## Success Criteria
The product is complete when:
1. [All critical features implemented and tested]
2. [All tests passing with 80%+ coverage]
3. [No type errors (adapts to stack)]
4. [No security vulnerabilities]
5. [Deployed to production]
## Notes
[Any additional context, links, or documentation]
```
***
#### Template 2: Hierarchical Structure (Directory Tree)
**Best for**: Projects with 15+ features, multiple team members, complex domains
**File structure**:
```
.claude/product/
├── index.md # Overview + Tech Stack
└── domains/
├── authentication/
│ └── index.md # Auth features
├── content-management/
│ └── index.md # Content features
└── analytics/
└── index.md # Analytics features
```
**Main file**: `.claude/product/index.md`
```markdown
# Product Specification
## Overview
[2-3 sentences describing what you're building and who it's for]
## Goals
- [ ] [Primary goal 1]
- [ ] [Primary goal 2]
- [ ] [Primary goal 3]
## Tech Stack
### Frontend
- **Framework**: [Next.js 14 / React + Vite / Vue + Nuxt / SvelteKit]
- **Language**: [TypeScript / JavaScript]
- **Styling**: [Tailwind CSS / CSS Modules / styled-components / shadcn/ui]
- **State Management**: [Zustand / Context API / Redux / Jotai]
### Backend
- **Runtime**: [Node.js / Bun / Deno]
- **Framework**: [Next.js API Routes / Express / Fastify / NestJS / Hono]
- **Language**: [TypeScript / JavaScript]
### Database
- **Database**: [PostgreSQL / MySQL / SQLite / MongoDB / PlanetScale]
- **ORM**: [Prisma / Drizzle / TypeORM / Mongoose]
### Authentication
- **Method**: [JWT / NextAuth / Clerk / Auth0 / Lucia]
### Testing
- **Unit**: [Vitest / Jest]
- **E2E**: [Playwright / Cypress]
### Deployment
- **Hosting**: [Vercel / Netlify / Railway / Fly.io]
## Domains
This product is organized into the following domains:
1. **Authentication & User Management** - User accounts, profiles, permissions
→ See `.claude/product/domains/authentication/index.md`
2. **Content Management** - CRUD operations, search, categorization
→ See `.claude/product/domains/content-management/index.md`
3. **Analytics & Reporting** - Dashboards, charts, exports
→ See `.claude/product/domains/analytics/index.md`
## Architecture Notes (Optional)
### Folder Structure
[Your preferred structure]
### Design Patterns
[Patterns to use/avoid]
### Constraints
[Performance, accessibility, browser support]
## Third-Party Integrations (Optional)
- [API 1]: [Purpose and usage notes]
- [API 2]: [Purpose and usage notes]
## Out of Scope (for MVP)
List what you're explicitly NOT building:
- [Feature X] - Will add in v2
- [Feature Y] - Out of scope
- [Feature Z] - Not needed
## Success Criteria
The product is complete when:
1. [All critical features implemented and tested]
2. [All tests passing with 80%+ coverage]
3. [No type errors (adapts to stack)]
4. [No security vulnerabilities]
5. [Deployed to production]
## Notes
[Any additional context, links, or documentation]
```
**Domain file**: `.claude/product/domains/authentication/index.md`
```markdown
# Domain: Authentication & User Management
## Domain Overview
This domain handles all user identity and access management functionality including registration, login, profile management, and permissions.
## Dependencies
- Depends on: Database setup
- Required by: All other domains (content, analytics, etc.)
## Features
### 1.1 User Registration - CRITICAL
**Description**: New users can create accounts with email verification
**User Stories**:
- As a new user, I want to register with email so that I can access the platform
- As a security-conscious user, I want email verification so that my account is secure
**Acceptance Criteria**:
- [ ] Registration form with: email, password, confirm password fields
- [ ] Email validation: required, valid format, not already registered
- [ ] Password validation: required, min 8 chars, uppercase + lowercase + number
- [ ] Password confirmation must match
- [ ] On success: create user, send verification email, show "check your email" message
- [ ] On failure: inline error with specific reason (email taken, weak password, etc.)
- [ ] Verification link expires in 24 hours
- [ ] Verification link can be resent from login page
**Technical Notes**:
- Use bcrypt for password hashing (cost factor 12)
- Use JWT for verification token (expires in 24h)
- Rate limit registration: max 3 attempts per hour per IP
---
### 1.2 User Login - CRITICAL
**Description**: Registered users can authenticate with credentials
**User Stories**:
- As a registered user, I want to login so that I can access my account
- As a user, I want secure sessions so that my account isn't compromised
**Acceptance Criteria**:
- [ ] Login form with email and password fields
- [ ] Email validation: required, valid format
- [ ] Password validation: required, min 8 characters
- [ ] On success: verify email is verified, store JWT in httpOnly cookie, redirect to /dashboard
- [ ] On failure: inline error with specific reason (not found, wrong password, not verified)
- [ ] Show "resend verification" link if email not verified
- [ ] Rate limiting: max 5 attempts per 15 minutes per IP
- [ ] JWT valid for 7 days
**Technical Notes**:
- JWT includes: userId, email, role, issuedAt, expiresAt
- httpOnly cookie: secure=true, sameSite=strict, httpOnly=true
- Use existing auth pattern in src/lib/auth.ts
---
### 1.3 User Profile - HIGH
**Description**: Users can view and edit their profile information
**User Stories**:
- As a user, I want to update my profile so that my information is current
- As a user, I want to see my profile data so that I know what's stored
**Acceptance Criteria**:
- [ ] Profile page at /profile
- [ ] Display: name, email, registration date, last login
- [ ] Edit form: name (optional), email (optional, requires verification if changed)
- [ ] Profile picture upload (max 2MB, jpg/png)
- [ ] "Save Changes" button with loading state
- [ ] Success toast: "Profile updated"
- [ ] Error handling with specific messages
---
### 1.4 Password Reset - MEDIUM
**Description**: Users can reset forgotten passwords via email
**User Stories**:
- As a user, I want to reset my password so that I can regain access
**Acceptance Criteria**:
- [ ] "Forgot password" link on login page
- [ ] Request form: email field
- [ ] On submit: send reset link if email exists (always show success message to prevent email enumeration)
- [ ] Reset email contains link to /reset-password?token=xxx
- [ ] Reset link expires in 1 hour
- [ ] Reset form: new password, confirm password
- [ ] On success: show success message, redirect to login
- [ ] Invalid/expired tokens show clear error message
**Technical Notes**:
- Use separate reset token (different from auth JWT)
- Invalidate all user sessions after password reset
- Rate limit: max 3 reset requests per hour per email
---
## Domain Success Criteria
This domain is complete when:
1. All CRITICAL and HIGH features implemented and tested
2. Unit tests for auth utilities (hashing, token generation)
3. Integration tests for all auth flows
4. E2E tests for critical user journeys (register → verify → login → profile)
5. Security audit passes (no SQL injection, XSS, CSRF vulnerabilities)
```
**Domain file**: `.claude/product/domains/content-management/index.md`
```markdown
# Domain: Content Management
## Domain Overview
This domain handles all content creation, editing, organization, and retrieval functionality.
## Dependencies
- Depends on: Authentication & User Management domain
- Required by: Analytics domain
## Features
### 2.1 Create Content - CRITICAL
**Description**: Authenticated users can create new content items
**User Stories**:
- As a user, I want to create content so that I can share information
**Acceptance Criteria**:
- [ ] Create page at /content/new
- [ ] Form fields: title (required), body (required, rich text), tags (optional), category (dropdown)
- [ ] Title validation: required, 5-100 chars
- [ ] Body validation: required, 20-10000 chars
- [ ] Rich text editor: bold, italic, links, lists, headings
- [ ] "Publish" button (saves immediately)
- [ ] "Save Draft" button (saves as draft status)
- [ ] Success toast: "Content published" or "Draft saved"
- [ ] Redirect to content detail page after publish
---
### 2.2 View Content List - CRITICAL
**Description**: Users can browse all published content
**User Stories**:
- As a user, I want to see all content so that I can find what interests me
**Acceptance Criteria**:
- [ ] Content list page at /content
- [ ] Grid layout showing content cards
- [ ] Each card shows: title, excerpt (150 chars), author name, date, category tag
- [ ] Responsive grid: 1 col mobile, 2 tablet, 3 desktop
- [ ] Pagination: 12 items per page
- [ ] Filter by category (dropdown)
- [ ] Search by title (debounced 300ms)
- [ ] Loading skeleton while fetching
- [ ] Empty state: "No content found"
---
### 2.3 View Content Detail - CRITICAL
**Description**: Users can read full content items
**User Stories**:
- As a user, I want to read full content so that I can get detailed information
**Acceptance Criteria**:
- [ ] Detail page at /content/[id]
- [ ] Display: title, author, date, category, body (rich text rendered)
- [ ] Show author info: name, avatar, bio
- [ ] "Edit" button (only for content author)
- [ ] Loading state while fetching
- [ ] 404 page if content not found or deleted
- [ ] SEO metadata: title, description, OG tags
---
### 2.4 Edit Content - HIGH
**Description**: Content authors can edit their own content
**User Stories**:
- As a content author, I want to edit my content so that I can correct mistakes
**Acceptance Criteria**:
- [ ] Edit page at /content/[id]/edit (only for author)
- [ ] Pre-fill form with existing content
- [ ] Same validation as create
- [ ] "Update" button with loading state
- [ ] "Cancel" button returns to detail view
- [ ] Success toast: "Content updated"
- [ ] 403 error if user tries to edit others' content
---
### 2.5 Delete Content - MEDIUM
**Description**: Content authors can delete their own content
**User Stories**:
- As a content author, I want to delete content so that I can remove outdated info
**Acceptance Criteria**:
- [ ] Delete button on detail page (only for author)
- [ ] Confirmation dialog: "Delete this content? This cannot be undone."
- [ ] On confirm: soft delete (set deletedAt timestamp)
- [ ] Success toast: "Content deleted"
- [ ] Redirect to /content
- [ ] Deleted content doesn't appear in lists
---
## Domain Success Criteria
This domain is complete when:
1. All CRITICAL and HIGH features implemented and tested
2. Rich text editor properly sanitizes HTML (XSS prevention)
3. Soft delete works correctly (content hidden but recoverable)
4. Authorization checks prevent editing/deleting others' content
5. Pagination and search perform well with 1000+ items
```
**Domain file**: `.claude/product/domains/analytics/index.md`
```markdown
# Domain: Analytics & Reporting
## Domain Overview
This domain provides insights into content performance, user engagement, and platform metrics.
## Dependencies
- Depends on: Content Management domain
- Required by: None (leaf domain)
## Features
### 3.1 Content Analytics Dashboard - HIGH
**Description**: Content creators can view performance metrics for their content
**User Stories**:
- As a content creator, I want to see analytics so that I can understand engagement
**Acceptance Criteria**:
- [ ] Dashboard page at /analytics
- [ ] Only accessible to authenticated users
- [ ] Summary cards: total views, total likes, avg engagement rate
- [ ] Date range filter: last 7 days, 30 days, 90 days, custom
- [ ] Line chart: views over time (Chart.js or similar)
- [ ] Top 5 content table: title, views, likes, comments
- [ ] Loading states for all data
- [ ] Empty state if no analytics data
**Technical Notes**:
- Use aggregation queries for performance
- Cache analytics data for 5 minutes
- Store view events in separate analytics collection
---
### 3.2 Content Performance Detail - MEDIUM
**Description**: View detailed analytics for a single content item
**User Stories**:
- As a content creator, I want to see per-content analytics so that I can optimize
**Acceptance Criteria**:
- [ ] Analytics tab on content detail page (only for author)
- [ ] Show: total views, unique views, likes, comments, shares
- [ ] Views over time chart
- [ ] Referrer breakdown: direct, search, social, external
- [ ] Device breakdown: mobile, tablet, desktop
- [ ] Date range filter (same as dashboard)
---
### 3.3 Export Analytics Report - LOW
**Description**: Users can export analytics data as CSV
**User Stories**:
- As a content creator, I want to export analytics so that I can analyze in Excel
**Acceptance Criteria**:
- [ ] "Export CSV" button on dashboard
- [ ] Button shows loading state while generating
- [ ] CSV includes: content id, title, views, likes, comments, date range
- [ ] File download triggers automatically
- [ ] Filename format: analytics-YYYY-MM-DD.csv
---
## Domain Success Criteria
This domain is complete when:
1. All HIGH priority features implemented and tested
2. Analytics queries are optimized (don't slow down content loading)
3. Charts render correctly on all screen sizes
4. CSV export handles special characters properly
5. Date range filtering works across all features
```
***
#### Migrating from Flat to Hierarchical
When your flat file becomes unwieldy (15+ features or multiple contributors):
**Step 1: Create domain directories**
```bash
mkdir -p .claude/product/domains/authentication
mkdir -p .claude/product/domains/content-management
mkdir -p .claude/product/domains/analytics
```
**Step 2: Split your flat file**
* Move overview + tech stack to `.claude/product/index.md`
* Create `index.md` in each domain directory
* Move feature sections to appropriate domain files
* Add domain overview and dependencies to each file
**Step 3: Update the main index**
* Add "## Domains" section listing all domains
* Include file paths for each domain
* Maintain same numbering scheme (1.1, 1.2, 2.1, etc.)
**Step 4: Test the structure**
```bash
# agentful will read the hierarchical structure automatically
agentful status
```
**Key**: Feature numbering stays consistent (1.1, 2.1, etc.) regardless of structure.
```markdown
# Product Specification
## Overview
[2-3 sentences describing what you're building and who it's for]
## Goals
- [ ] [Primary goal 1]
- [ ] [Primary goal 2]
- [ ] [Primary goal 3]
## Tech Stack
### Frontend
- **Framework**: [Next.js 14 / React + Vite / Vue + Nuxt / SvelteKit]
- **Language**: [TypeScript / JavaScript]
- **Styling**: [Tailwind CSS / CSS Modules / styled-components / shadcn/ui]
- **State Management**: [Zustand / Context API / Redux / Jotai]
### Backend
- **Runtime**: [Node.js / Bun / Deno]
- **Framework**: [Next.js API Routes / Express / Fastify / NestJS / Hono]
- **Language**: [TypeScript / JavaScript]
### Database
- **Database**: [PostgreSQL / MySQL / SQLite / MongoDB / PlanetScale]
- **ORM**: [Prisma / Drizzle / TypeORM / Mongoose]
### Authentication
- **Method**: [JWT / NextAuth / Clerk / Auth0 / Lucia]
### Testing
- **Unit**: [Vitest / Jest]
- **E2E**: [Playwright / Cypress]
### Deployment
- **Hosting**: [Vercel / Netlify / Railway / Fly.io]
## Features (Hierarchical Domain-Based Structure)
Organize features into domains, then prioritize within each domain:
### Domain 1: [Domain Name]
#### 1.1 [Feature Name] - CRITICAL
**Description**: [What this feature does in one sentence]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific, testable requirement 1]
- [ ] [Specific, testable requirement 2]
- [ ] [Specific, testable requirement 3]
**Technical Notes** (Optional):
- [API endpoints, components, libraries, etc.]
---
#### 1.2 [Feature Name] - HIGH
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
**Technical Notes** (Optional):
- [Relevant implementation details]
---
### Domain 2: [Domain Name]
#### 2.1 [Feature Name] - HIGH
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
---
#### 2.2 [Feature Name] - MEDIUM
**Description**: [What this feature does]
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
- [ ] [Specific requirement 2]
---
### Domain 3: [Domain Name]
#### 3.1 [Feature Name] - MEDIUM
**Description**: [What this feature does]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
---
#### 3.2 [Feature Name] - LOW
**Description**: [What this feature does]
**Acceptance Criteria**:
- [ ] [Specific requirement 1]
---
**Note**: Repeat for as many domains and features as needed. Aim for 3-6 domains with 2-5 features each.
## Architecture Notes (Optional)
### Folder Structure
If you have a preferred structure:
src/
├── app/ # Next.js app router
├── components/ # React components
├── lib/ # Utilities
├── hooks/ # Custom hooks
└── styles/ # Global styles
Or:
src/
├── app/ # Next.js app router
├── components/ # React components
│ ├── ui/ # Reusable UI components
│ └── features/ # Feature-specific components
├── lib/ # Utilities and helpers
├── hooks/ # Custom React hooks
├── services/ # API services
└── types/ # TypeScript types
### Design Patterns
- [Any specific patterns to use]
- [Any patterns to avoid]
### Constraints
- [Performance requirements]
- [Accessibility requirements]
- [Browser support requirements]
## Third-Party Integrations (Optional)
- [API 1]: [Purpose and usage notes]
- [API 2]: [Purpose and usage notes]
## Out of Scope (for MVP)
List what you're explicitly NOT building:
- [Feature X] - Will add in v2
- [Feature Y] - Out of scope
- [Feature Z] - Not needed
## Success Criteria
The product is complete when:
1. [All critical features implemented and tested]
2. [All tests passing with 80%+ coverage]
3. [No type errors (adapts to stack)]
4. [No security vulnerabilities]
5. [Deployed to production]
## Notes
[Any additional context, links, or documentation]
```
***
### Section by Section Guide
#### Overview
**Purpose**: Quick understanding of what you're building.
**Length**: 2-3 sentences.
**Include**:
* What the product is
* Who it's for
* Key value proposition
**Good Example**:
```markdown
## Overview
A task management application for remote teams. Users can create projects, add tasks with deadlines, assign team members, and track progress with real-time updates.
```
**Bad Example**:
```markdown
## Overview
A task app. # Too vague - agentful doesn't know what features to include
```
***
#### Goals
**Purpose**: Define success metrics.
**Format**: Checkbox list (so you can track progress).
**Good Example**:
```markdown
## Goals
- [ ] Users can register and login
- [ ] Users can create projects and tasks
- [ ] Users can assign tasks to team members
- [ ] Real-time updates when tasks change
- [ ] Mobile-responsive design
```
**Tip**: Keep goals high-level. Features are where you get specific.
***
#### Tech Stack
**Purpose**: Tell agentful what technologies to use.
**Critical**: Be explicit. Don't make agentful guess.
##### Frontend
```markdown
### Frontend
- **Framework**: Next.js 14
- **Language**: TypeScript
- **Styling**: Tailwind CSS
- **State Management**: Zustand
```
**Why this matters**:
* agentful generates specialized agents based on your stack
* Different frameworks have different patterns (Next.js app router vs pages)
* Testing setup depends on the framework
##### Backend
```markdown
### Backend
- **Runtime**: Node.js
- **Framework**: Next.js API Routes
- **Language**: TypeScript
```
**Tip**: If using Next.js, backend is often integrated. Specify if using a separate backend server.
##### Database
```markdown
### Database
- **Database**: PostgreSQL
- **ORM**: Prisma
```
**Common choices**:
* **PostgreSQL + Prisma** - Most common, production-ready
* **SQLite + Prisma** - Good for local development, simple apps
* **MongoDB + Mongoose** - Flexible schema, document-based
* **None** - In-memory state for simple apps
**Be specific** about the ORM. Prisma != Drizzle != TypeORM.
##### Authentication
```markdown
### Authentication
- **Method**: JWT with httpOnly cookies
```
**Options**:
* **JWT** - Stateless, scalable, common
* **Sessions** - Simple, built-in to many frameworks
* **Clerk/Auth0** - Managed services, faster setup
* **None** - If no auth needed for MVP
##### Testing
```markdown
### Testing
- **Unit**: Vitest
- **E2E**: Playwright
```
**Common pairs**:
* **Vitest + Playwright** - Modern, fast
* **Jest + Cypress** - Traditional, widely-used
##### Deployment
```markdown
### Deployment
- **Hosting**: Vercel
```
**agentful uses this to**:
* Set build configurations
* Configure environment variables
* Add deployment scripts
***
#### Features (The Most Important Section)
**This is where most PRODUCT.md files fail.** Follow these patterns carefully.
##### Structure
Every feature needs:
```markdown
### [Priority Number]. [Feature Name] - [PRIORITY LEVEL]
**Description**: [One sentence explaining what this feature does]
**Acceptance Criteria**:
- [ ] [Specific, testable requirement]
- [ ] [Specific, testable requirement]
- [ ] [Specific, testable requirement]
**User Stories** (optional):
- As a [user type], I want [feature] so that [benefit]
**Technical Notes** (optional):
- [Implementation hints or constraints]
```
##### Priority Levels
Use these consistently:
* **CRITICAL** - Must have for MVP. agentful works on these first.
* **HIGH** - Important, but can wait slightly.
* **MEDIUM** - Nice to have.
* **LOW** - Future improvements.
##### Acceptance Criteria (The Secret Sauce)
**Good acceptance criteria are:**
1. **Specific** - Clear what "done" looks like
2. **Testable** - Can write a test for it
3. **Complete** - Cover all key aspects
4. **Checkable** - Can verify with a checkbox
##### Examples
**❌ Vague (Bad)**:
```markdown
**Acceptance Criteria**:
- [ ] User can login
- [ ] Authentication works
- [ ] Security is good
```
**Why this fails**: agentful doesn't know:
* What fields to include (email? username?)
* What validation to apply
* How to handle errors
* What "good security" means
**✅ Specific (Good)**:
```markdown
**Acceptance Criteria**:
- [ ] Login form with email and password fields
- [ ] Email validation: required, valid format
- [ ] Password validation: required, min 8 characters
- [ ] On success: store JWT token in httpOnly cookie, redirect to /dashboard
- [ ] On failure: show inline error message with specific reason
- [ ] Prevent login for unverified emails (show "check your email" message)
- [ ] Rate limiting: max 5 attempts per 15 minutes per IP
```
**Why this works**: agentful knows exactly what to build. No decisions needed.
***
##### Writing Great Acceptance Criteria
##### Pattern 1: User Input
```markdown
**Acceptance Criteria**:
- [ ] Input field for [field name]
- [ ] Validation: [required, format, min/max length]
- [ ] Placeholder text: "[example]"
- [ ] Error messages for invalid input
- [ ] Submit button that validates before submitting
```
##### Pattern 2: API Endpoints
```markdown
**Acceptance Criteria**:
- [ ] POST /api/auth/login endpoint
- [ ] Request body: { email: string, password: string }
- [ ] Response success: { user: {...}, token: "..." } with 200 status
- [ ] Response error: { error: "specific message" } with 401 status
- [ ] Hash passwords with bcrypt before comparing
- [ ] Return JWT token valid for 7 days
```
##### Pattern 3: Data Display
```markdown
**Acceptance Criteria**:
- [ ] Display list of [items]
- [ ] Show [field 1], [field 2], [field 3] for each item
- [ ] Loading state while fetching data
- [ ] Empty state with message when no items exist
- [ ] Error state with retry button when fetch fails
```
##### Pattern 4: User Actions
```markdown
**Acceptance Criteria**:
- [ ] [Button/Action] triggers [action]
- [ ] Confirmation prompt: "[message]"
- [ ] On confirm: [what happens]
- [ ] On cancel: [what happens]
- [ ] Success notification: "[message]"
- [ ] Error handling with specific message
```
***
##### User Stories (Optional but Helpful)
**Format**:
```markdown
**User Stories**:
- As a [user type], I want [feature] so that [benefit]
```
**Example**:
```markdown
**User Stories**:
- As a registered user, I want to login with my email and password so that I can access my projects
- As a security-conscious user, I want rate limiting on login attempts so that my account can't be brute-forced
```
**Why include these**: Helps agentful understand context and make better decisions when ambiguity exists.
***
##### Technical Notes (When Needed)
Use this section to guide implementation when you have specific requirements:
```markdown
**Technical Notes**:
- Use React Hook Form for form validation
- Store session in httpOnly cookie for security
- Implement rate limiting using Redis (or in-memory if Redis unavailable)
- Follow existing auth pattern in src/lib/auth.ts
```
**When to include**:
* You have existing code agentful should follow
* You need a specific library or pattern
* There are performance constraints
* There are security requirements
**When to skip**:
* Let agentful decide the implementation
* You don't have a strong preference
* The "how" doesn't matter, only the "what"
***
#### Architecture Notes (Optional)
**Purpose**: Guide structural decisions without micromanaging.
**Use when**:
* You have an existing codebase to match
* You have strong architectural preferences
* You're working with a team that needs consistency
**Example**:
```markdown
### Folder Structure
```
src/
├── app/ # Next.js app router
├── components/ # React components
│ ├── ui/ # Reusable UI components
│ └── features/ # Feature-specific components
├── lib/ # Utilities and helpers
├── hooks/ # Custom React hooks
├── services/ # API services
└── types/ # TypeScript types
```
### Design Patterns
- Use React Hook Form for all forms
- Use TanStack Query for data fetching
- Use Zod for runtime validation
- Follow atomic design for components
### Constraints
- All API routes must return { data, error } format
- All components must be TypeScript strict
- Mobile-first responsive design
- WCAG 2.1 AA accessibility compliance
```
***
#### Out of Scope (for MVP)
**Purpose**: Explicitly state what you're NOT building.
**Why this matters**: Prevents agentful from wasting time on features you don't want.
**Example**:
```markdown
## Out of Scope (for MVP)
- **User profiles** - Will add in v2, focus on core functionality first
- **Email notifications** - Out of scope for now, users check dashboard
- **Real-time collaboration** - Too complex for MVP, will use polling
- **Mobile apps** - Web-only for MVP
- **Payment processing** - Free tier only for launch
```
**Tip**: Be explicit. If you don't list it here, agentful might add it if it seems related to your features.
***
#### Success Criteria
**Purpose**: Define when agentful is "done".
**Example**:
```markdown
## Success Criteria
The product is complete when:
1. All CRITICAL and HIGH priority features are implemented and tested
2. All tests passing with 80%+ coverage
3. No type errors (adapts to stack)
4. No security vulnerabilities (npm audit passes)
5. Manual testing confirms all user stories work
6. Deployed to production and accessible
```
**agentful uses this to**:
* Know when to stop working
* Prioritize validation checks
* Determine if a feature is truly complete
***
### Real Examples
#### Example 1: Simple Todo App (Flat Structure)
**Structure**: Single file (`PRODUCT.md`)
**Best for**: Simple projects with few features
```markdown
# Product Specification
## Overview
A simple todo list application for personal task management.
## Tech Stack
### Frontend
- **Framework**: Next.js 14
- **Language**: TypeScript
- **Styling**: Tailwind CSS
- **State Management**: React Context API
### Backend
- **Framework**: Next.js API Routes
- **Language**: TypeScript
### Database
- **Database**: None (in-memory for MVP)
### Testing
- **Unit**: Vitest
## Features
### 1. Add Todo - CRITICAL
**Description**: Users can add new todo items to their list
**Acceptance Criteria**:
- [ ] Input field for todo text
- [ ] Text validation: required, max 200 characters
- [ ] "Add" button that creates todo
- [ ] New todo appears at top of list
- [ ] Input clears after adding
- [ ] Enter key also submits todo
### 2. Toggle Todo - HIGH
**Description**: Users can mark todos as complete or incomplete
**Acceptance Criteria**:
- [ ] Click todo to toggle completion status
- [ ] Completed todos show strikethrough text
- [ ] Completed todos have gray opacity
- [ ] Toggle persists across page reloads
### 3. Delete Todo - MEDIUM
**Description**: Users can delete todos they no longer need
**Acceptance Criteria**:
- [ ] Delete button on each todo (trash icon)
- [ ] Confirmation dialog before delete
- [ ] Todo immediately removed on confirm
- [ ] Delete cancels if user clicks outside dialog
### 4. Filter Todos - LOW
**Description**: Users can view all, active, or completed todos
**Acceptance Criteria**:
- [ ] Filter tabs: All, Active, Completed
- [ ] Active filter shows only incomplete todos
- [ ] Completed filter shows only completed todos
- [ ] All filter shows everything
## Success Criteria
1. All CRITICAL and HIGH features implemented
2. All tests passing with 80%+ coverage
3. No type errors (adapts to stack)
4. Manual testing confirms all features work
```
**Why this works**:
* Clear, specific acceptance criteria
* Tech stack fully specified
* Priorities clearly marked
* Success criteria defined
***
#### Example 2: E-commerce Platform (Flat Structure)
**Structure**: Single file (`PRODUCT.md`) with domain-based sections
**Best for**: Medium-complexity projects with multiple domains
```markdown
# Product Specification
## Overview
A modern e-commerce platform for selling digital products. Customers can browse products, add to cart, and checkout with Stripe payment.
## Tech Stack
### Frontend
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript
- **Styling**: Tailwind CSS + shadcn/ui
- **State Management**: Zustand
### Backend
- **Runtime**: Node.js
- **Framework**: Next.js API Routes
- **Language**: TypeScript
### Database
- **Database**: PostgreSQL (Supabase)
- **ORM**: Prisma
### Authentication
- **Method**: JWT with httpOnly cookies
### Payment
- **Provider**: Stripe
- **Mode**: Checkout Session (redirect-based)
### Testing
- **Unit**: Vitest
- **E2E**: Playwright
### Deployment
- **Hosting**: Vercel
## Features
### 1. Product Listing - CRITICAL
**Description**: Customers can browse all available digital products
**Acceptance Criteria**:
- [ ] Grid layout showing product cards
- [ ] Each card shows: product image, name, price, description (truncated)
- [ ] Responsive grid: 1 column mobile, 2 tablet, 3 desktop, 4 large screens
- [ ] Loading skeleton while fetching products
- [ ] Empty state with "No products available" message
- [ ] Hover effect on cards (slight elevation)
- [ ] Click card to navigate to product detail page
### 2. Product Detail - CRITICAL
**Description**: Customers can view detailed information about a product
**Acceptance Criteria**:
- [ ] Large product image (800x600)
- [ ] Product name, price, full description
- [ ] "Add to Cart" button
- [ ] "Back to Products" link
- [ ] Loading state while fetching
- [ ] Error state if product not found (404)
- [ ] Metadata for SEO (title, description, OG tags)
### 3. Shopping Cart - CRITICAL
**Description**: Customers can manage items in their cart
**Acceptance Criteria**:
- [ ] Cart icon in header showing item count badge
- [ ] Click cart icon to open cart drawer/slide-over
- [ ] Cart shows list of items with:
- Product thumbnail
- Product name
- Price
- Quantity selector (+/- buttons)
- Remove button
- [ ] Subtotal calculation
- [ ] "Checkout" button (disabled if cart empty)
- [ ] Cart persists in localStorage
- [ ] Close button on cart drawer
### 4. Add to Cart - HIGH
**Description**: Customers can add products to their cart
**Acceptance Criteria**:
- [ ] "Add to Cart" button on product detail page
- [ ] Button shows loading state while adding
- [ ] Success toast notification: "Added [Product] to cart"
- [ ] Error toast if add fails
- [ ] Cart count badge updates immediately
- [ ] If item already in cart, increment quantity instead of duplicate
### 5. Stripe Checkout - HIGH
**Description**: Customers can pay for their cart items using Stripe
**Acceptance Criteria**:
- [ ] Checkout button creates Stripe Checkout Session
- [ ] Request includes: line_items, success_url, cancel_url
- [ ] User redirects to Stripe-hosted checkout page
- [ ] Success URL: /checkout/success?session_id=xxx
- [ ] Cancel URL: /checkout/cancel
- [ ] Environment variable STRIPE_SECRET_KEY for API calls
- [ ] Environment variable NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY for client
- [ ] Webhook endpoint at /api/webhooks/stripe
- [ ] Webhook verifies signature using Stripe SDK
- [ ] Webhook handles checkout.session.completed event
- [ ] On success: clear cart, show order confirmation
- [ ] On cancel: return to cart, show "Payment cancelled" message
### 6. Order Confirmation - HIGH
**Description**: Customers see confirmation after successful payment
**Acceptance Criteria**:
- [ ] Page at /checkout/success
- [ ] Show order ID from Stripe session
- [ ] Show list of purchased items
- [ ] Show total amount paid
- [ ] "Continue Shopping" button to /products
- [ ] Email notification with order details (optional for MVP)
**Technical Notes**:
- Store order in database on webhook receipt
- Order schema: id, stripeSessionId, items, total, createdAt
### 7. Product Search - MEDIUM
**Description**: Customers can search products by name or description
**Acceptance Criteria**:
- [ ] Search input in header
- [ ] Debounced search (300ms delay)
- [ ] Search filters by product name and description
- [ ] Search results update product listing grid
- [ ] Clear search button (X icon in input)
- [ ] "No results found" message for empty searches
- [ ] URL query param ?search=query for shareable links
### 8. Admin Product Management - LOW
**Description**: Admin users can add, edit, and delete products
**Acceptance Criteria**:
- [ ] Admin route: /admin/products
- [ ] Protected: only accessible if ADMIN_EMAIL env var matches user email
- [ ] List all products with edit/delete buttons
- [ ] Add product form: name, price, description, image URL
- [ ] Edit product pre-fills form
- [ ] Delete product requires confirmation
- [ ] All changes update database immediately
**Out of Scope (for MVP)**:
- User authentication (simple email check for admin)
- Product image upload (use URL for now)
- Order history for customers
- Inventory management
- Product categories
- Product reviews/ratings
- Discount codes
- Shipping (digital products only)
## Success Criteria
1. All CRITICAL and HIGH features implemented and tested
2. All tests passing with 80%+ coverage
3. No type errors (adapts to stack)
4. Stripe test mode checkout works end-to-end
5. Webhook successfully processes test payments
6. Deployed to Vercel with environment variables configured
7. Manual testing confirms complete purchase flow
```
**Why this works**:
* Extremely detailed acceptance criteria
* Technical notes guide implementation
* Out of scope prevents feature creep
* Real-world constraints included (webhook, Stripe flow)
* Testing considerations mentioned
***
#### Example 3: SaaS Platform (Hierarchical Structure)
**Structure**: Directory tree (`.claude/product/domains/*/index.md`)
**Best for**: Large projects with multiple team members
**Main file**: `.claude/product/index.md`
```markdown
# Product Specification
## Overview
A project management SaaS platform for software teams. Teams can create projects, manage tasks, track time, and collaborate in real-time.
## Goals
- [ ] Users can register and create teams
- [ ] Teams can manage multiple projects
- [ ] Real-time task collaboration
- [ ] Time tracking and reporting
- [ ] Team analytics and insights
## Tech Stack
### Frontend
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript
- **Styling**: Tailwind CSS + shadcn/ui
- **State Management**: Zustand
- **Real-time**: Socket.io client
### Backend
- **Runtime**: Node.js
- **Framework**: Express
- **Language**: TypeScript
- **Real-time**: Socket.io
### Database
- **Database**: PostgreSQL (Supabase)
- **ORM**: Prisma
### Authentication
- **Method**: JWT with httpOnly cookies
### Testing
- **Unit**: Vitest
- **E2E**: Playwright
### Deployment
- **Hosting**: Vercel (frontend) + Railway (backend)
## Domains
This product is organized into the following domains:
1. **Authentication & Team Management** - User accounts, team creation, invitations
→ See `.claude/product/domains/authentication/index.md`
2. **Project & Task Management** - Projects, tasks, subtasks, dependencies
→ See `.claude/product/domains/projects/index.md`
3. **Time Tracking** - Time entries, reports, exports
→ See `.claude/product/domains/time-tracking/index.md`
4. **Analytics & Reporting** - Team performance, burndown charts
→ See `.claude/product/domains/analytics/index.md`
## Out of Scope (for MVP)
- File attachments and document management
- Video calls and screen sharing
- Mobile apps (web-only for MVP)
- Custom workflows and automations
- API for third-party integrations
## Success Criteria
1. All CRITICAL and HIGH features implemented and tested
2. Real-time collaboration works smoothly (WebSocket tests passing)
3. All tests passing with 80%+ coverage
4. No type errors
5. No security vulnerabilities
6. Deployed to production with monitoring setup
## Notes
- Each domain has a dedicated team member
- Use WebSocket for real-time updates (tasks, comments)
- Implement optimistic UI for better UX
- Focus on core collaboration features first
```
**Domain file**: `.claude/product/domains/authentication/index.md`
```markdown
# Domain: Authentication & Team Management
## Domain Overview
Handles user registration, login, team creation, and team member management.
## Dependencies
- Depends on: Database setup
- Required by: All other domains
## Features
### 1.1 User Registration - CRITICAL
**Acceptance Criteria**:
- [ ] Registration form: name, email, password, company name
- [ ] Email verification required before access
- [ ] On registration: create user, create team (user is owner), send verification email
- [ ] JWT token in httpOnly cookie (7 day expiry)
- [ ] Rate limit: 3 attempts per hour per IP
### 1.2 Team Invitations - CRITICAL
**Acceptance Criteria**:
- [ ] Invite form: email address, role (admin/member/viewer)
- [ ] Invitation email with signup link
- [ ] Invitation link expires in 7 days
- [ ] Team owners/admins can send invitations
- [ ] Accepting invite adds user to team
- [ ] Revoke invitation button
### 1.3 Team Management - HIGH
**Acceptance Criteria**:
- [ ] Team settings page: name, description, avatar
- [ ] Team members list with roles
- [ ] Change member role (owner/admin only)
- [ ] Remove member from team
- [ ] Delete team (owner only, requires confirmation)
## Domain Success Criteria
1. All CRITICAL and HIGH features implemented
2. Email verification flow works end-to-end
3. Team permissions enforced (members can't invite, etc.)
4. Security audit passes
```
**Why this works**:
* Clear separation of concerns
* Multiple team members can work on different domains simultaneously
* Each domain file is focused and manageable
* Dependencies are explicit
* Easy to track progress per domain
***
### Common Product Specification Mistakes
#### Mistake 1: Vague Requirements
**❌ Bad**:
```markdown
### 1. User Authentication - CRITICAL
**Description**: Users can login
**Acceptance Criteria**:
- [ ] Login works
- [ ] Security is good
```
**✅ Good**:
```markdown
### 1. User Authentication - CRITICAL
**Description**: Users can login with email and password
**Acceptance Criteria**:
- [ ] Login form with email and password fields
- [ ] Email validation: required, valid format
- [ ] Password validation: required, min 8 chars
- [ ] On success: JWT in httpOnly cookie, redirect to /dashboard
- [ ] On failure: inline error with specific reason
- [ ] Rate limiting: max 5 attempts per 15 min per IP
```
***
#### Mistake 2: Missing Tech Stack Details
**❌ Bad**:
```markdown
## Tech Stack
- Next.js
- TypeScript
- Database
```
**✅ Good**:
```markdown
## Tech Stack
### Frontend
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript
- **Styling**: Tailwind CSS
### Backend
- **Framework**: Next.js API Routes
- **Language**: TypeScript
### Database
- **Database**: PostgreSQL
- **ORM**: Prisma
```
***
#### Mistake 3: No Priorities
**❌ Bad**:
```markdown
## Features
1. Authentication
2. User profiles
3. Email notifications
4. Dark mode
5. Admin panel
```
**✅ Good**:
```markdown
## Features
### 1. Authentication - CRITICAL
...
### 2. User profiles - HIGH
...
### 3. Email notifications - MEDIUM
...
### 4. Dark mode - LOW
...
### 5. Admin panel - LOW
...
```
**Why priorities matter**: agentful works CRITICAL → HIGH → MEDIUM → LOW. Without priorities, it might work on dark mode before authentication.
***
#### Mistake 4: No Acceptance Criteria
**❌ Bad**:
```markdown
### 1. Shopping Cart - CRITICAL
Users can add items to cart and checkout.
```
**✅ Good**:
```markdown
### 1. Shopping Cart - CRITICAL
**Description**: Users can add items to cart and checkout
**Acceptance Criteria**:
- [ ] Cart icon shows item count badge
- [ ] Add to cart button on product page
- [ ] Cart drawer shows items with quantities
- [ ] Update quantity with +/- buttons
- [ ] Remove items from cart
- [ ] Subtotal calculation
- [ ] Checkout button (disabled if empty)
- [ ] Cart persists in localStorage
```
***
#### Mistake 5: Acceptance Criteria That Aren't Testable
**❌ Bad**:
```markdown
**Acceptance Criteria**:
- [ ] UI looks good
- [ ] Code is clean
- [ ] Performance is fast
```
**✅ Good**:
```markdown
**Acceptance Criteria**:
- [ ] Components follow design system spacing (4px grid)
- [ ] All functions have single responsibility
- [ ] Page load time < 2 seconds on 3G
```
***
#### Mistake 6: Too Much Implementation Detail
**❌ Bad** (over-specifying):
```markdown
**Acceptance Criteria**:
- [ ] Use React Hook Form with useForm hook
- [ ] Validate with Zod schema on line 15
- [ ] Call API endpoint /api/auth/login exactly
- [ ] Store token in cookie named 'auth_token'
- [ ] Use useEffect to fetch user data on mount
- [ ] Use useState for form state
```
**✅ Good** (focus on what, not how):
```markdown
**Acceptance Criteria**:
- [ ] Login form with email/password fields
- [ ] Client-side validation before submission
- [ ] POST to /api/auth/login with credentials
- [ ] Store auth token securely
- [ ] Fetch and display user data on successful login
```
**Let agentful figure out the "how"**. You specify the "what".
***
### Product Specification Checklist
Use this checklist before starting agentful:
#### Structure
* [ ] Chosen appropriate structure (flat for 3-15 features, hierarchical for 15+)
* [ ] Flat: Single file with domain sections OR
* [ ] Hierarchical: Main index + domain directories with index.md files
#### Content
* [ ] Overview is clear and concise (2-3 sentences)
* [ ] Goals are listed with checkboxes
* [ ] Tech stack is fully specified (frontend, backend, database, auth, testing, deployment)
* [ ] All features have priorities (CRITICAL/HIGH/MEDIUM/LOW)
* [ ] Each feature has a description
* [ ] Each feature has specific acceptance criteria
* [ ] Acceptance criteria are testable and verifiable
* [ ] Out of scope section lists what NOT to build
* [ ] Success criteria define when agentful is done
* [ ] Hierarchical: Domain dependencies are documented
#### Quality
* [ ] No vague requirements ("works well", "good performance")
* [ ] No missing tech stack details
* [ ] Acceptance criteria use checkboxes
* [ ] Features are organized by domain
* [ ] Features are prioritized
* [ ] Implementation details only when necessary
* [ ] User stories included for complex features
* [ ] Technical notes for specific constraints
#### Review
* [ ] Had a teammate review (if working in team)
* [ ] Tested clarity by asking: "Could I build this without questions?"
* [ ] Removed ambiguity
* [ ] Added examples where helpful
***
### Tips for Success
#### 1. Start Simple, Then Expand
**First version**:
```markdown
### 1. Todo List - CRITICAL
**Description**: Users can see their todos
**Acceptance Criteria**:
- [ ] Display list of todos
- [ ] Each todo shows text
```
**Then expand**:
```markdown
### 1. Todo List - CRITICAL
**Description**: Users can see and manage their todos
**Acceptance Criteria**:
- [ ] Display list of todos
- [ ] Each todo shows text and completion status
- [ ] Filter: all / active / completed
- [ ] Sort by date added (newest first)
- [ ] Empty state with illustration
- [ ] Loading state while fetching
- [ ] Error state with retry button
```
**Why**: Start with core functionality, then add polish after agentful completes the basics.
***
#### 2. Use Examples in Acceptance Criteria
```markdown
**Acceptance Criteria**:
- [ ] Email validation accepts formats like:
- user@example.com
- first.last@example.co.uk
- user+tag@example.com
- [ ] Email validation rejects formats like:
- user@ (no domain)
- @example.com (no user)
- user.example (no @)
```
**Why**: Examples make requirements concrete and testable.
***
#### 3. Be Explicit About Edge Cases
```markdown
**Acceptance Criteria**:
- [ ] Handle empty input gracefully
- [ ] Handle network errors with retry button
- [ ] Handle duplicate submissions (disable button on submit)
- [ ] Handle malicious input (sanitize user input)
- [ ] Handle expired auth tokens (auto-refresh or re-login)
```
**Why**: agentful will handle edge cases if you specify them. Otherwise, it might miss them.
***
#### 4. Reference Existing Patterns
If you have existing code:
```markdown
**Technical Notes**:
- Follow existing auth pattern in src/lib/auth.ts
- Match component structure in src/components/ui/
- Use same error handling pattern as src/app/api/products/route.ts
```
**Why**: Ensures consistency with your existing codebase.
***
#### 5. Think About User Experience
```markdown
**Acceptance Criteria**:
- [ ] Show loading state within 100ms of action (optimistic UI)
- [ ] Display success message for 3 seconds before auto-dismissing
- [ ] Confirm destructive actions with dialog
- [ ] Provide undo for non-destructive actions (like delete)
- [ ] Keyboard shortcuts: Enter to submit, Escape to cancel
```
**Why**: Great products are about UX, not just functionality.
***
#### 6. Consider Performance Early
```markdown
**Acceptance Criteria**:
- [ ] List items render with virtualization for 100+ items
- [ ] Images lazy load below the fold
- [ ] API responses include pagination (max 50 items per page)
- [ ] Cache GET requests for 5 minutes
- [ ] Debounce search input by 300ms
```
**Why**: Performance is easier to build in than retrofit later.
***
#### 7. Plan for Testing
```markdown
**Acceptance Criteria**:
- [ ] Unit tests for all business logic functions
- [ ] Integration tests for API endpoints
- [ ] E2E tests for critical user flows (login, checkout)
- [ ] Mock external dependencies (Stripe API, email service)
```
**Why**: agentful's tester agent needs to know what to test.
***
#### 8. Use "Don't" Sections
```markdown
**What NOT to do**:
- Don't use alerts for errors (use toast notifications)
- Don't hardcode strings (use i18n keys for future localization)
- Don't store sensitive data in localStorage
- Don't use any for types (be specific)
```
**Why**: Explicitly preventing bad patterns saves time.
***
### Updating PRODUCT.md Mid-Development
#### When to Update
**Safe to update**:
* Adding new LOW priority features
* Clarifying ambiguous acceptance criteria
* Adding technical notes for current work
* Updating success criteria
**Risky to update**:
* Changing priorities of in-progress features
* Removing features agentful is working on
* Completely changing tech stack mid-development
* Modifying acceptance criteria of completed features
#### How to Update Safely
1. **Run /agentful-status** to see what's in progress
2. **Only update features not yet started**
3. **Check .agentful/state.json** for current phase
4. **If changing priorities**, explain why in "Notes" section
**Example safe update**:
```markdown
## Notes
**[2026-01-18]** - Adding feature #8 (Dark mode) as LOW priority.
All CRITICAL and HIGH features complete, so this is safe to add.
```
***
### Tools for Better PRODUCT.md
#### PRODUCT.md Validators
```bash
# Check for common issues
npx agentful validate-product
# Output:
✓ Overview present
✓ Tech stack specified
✓ Features prioritized
⚠ Feature 3 has no acceptance criteria
⚠ Feature 5 is vague: "Make it fast"
```
#### PRODUCT.md Templates
```bash
# Generate a template for your stack
npx agentful template --stack nextjs,prisma,tailwind
# Outputs a ready-to-fill PRODUCT.md with your stack pre-configured
```
***
### Summary: The Perfect Product Specification
The perfect product specification is:
1. **Specific** - No vague requirements
2. **Complete** - Covers all critical aspects
3. **Organized** - Features grouped by domain
4. **Prioritized** - Clear order of work
5. **Testable** - Every requirement can be verified
6. **Explicit** - Tech stack fully specified
7. **Scoped** - Out of scope section prevents creep
8. **Achievable** - Success criteria are realistic
9. **Well-Structured** - Flat or hierarchical based on project size
**Choosing the Right Structure**:
* **Flat (PRODUCT.md or .claude/product/index.md)**: Start here for most projects
* **Hierarchical (.claude/product/domains/\*/index.md)**: Migrate when you hit 15+ features or multiple team members
**Remember**: You can always start flat and migrate to hierarchical later. Feature numbering stays consistent (1.1, 2.1, etc.) regardless of structure.
**Invest time in your product specification upfront, and agentful will reward you with autonomous development success.**
***
### Next Steps
Now that you have a great PRODUCT.md:
1. **[Start agentful](../getting-started/quick-start)** - Begin autonomous development
2. **[Monitor Progress](../commands/agentful-status)** - Track completion
3. **[Handle Decisions](../commands/agentful-decide)** - Answer when agentful asks
4. **[Validate Quality](../commands/agentful-validate)** - Ensure all gates pass
***
**Related Guides:**
* [Team Adoption](./team-adoption) - Standardize PRODUCT.md across your team
* [Best Practices](./best-practices) - More patterns for great specs
* [Troubleshooting](./troubleshooting) - Fix PRODUCT.md related issues
## Configuration
Customize agentful to match your workflow, tech stack, and preferences.
***
### Overview
agentful is highly customizable. You can modify:
* **Agents** - Add, remove, or specialize agents
* **Commands** - Create custom slash commands
* **Skills** - Add domain-specific capabilities
* **Settings** - Configure hooks and permissions
* **Templates** - Customize PRODUCT.md and CLAUDE.md
**Configuration files location:**
```
.claude/
├── product/ # Product structure (choose one)
│ ├── index.md # Option 1: Flat - all features
│ ├── domains/ # Option 2: Hierarchical - by domain
│ │ └── auth/
│ │ ├── index.md
│ │ └── features/
│ │ ├── login.md
│ │ └── register.md
│ ├── EXAMPLES.md # Feature writing examples
│ └── README.md # Structure guide
├── agents/ # Agent definitions
├── commands/ # Slash commands
├── skills/ # Domain skills
└── settings.json # Hooks and permissions
```
***
### Product Structure
agentful supports **both** flat and hierarchical product structures with **automatic detection**. Choose the format that best fits your project size and complexity.
#### Flat Structure
**Best for:** Quick prototypes, MVPs, small projects with 5-10 features
**Option A: Root file (legacy)**
```bash
your-project/
├── PRODUCT.md # All features in one file
├── src/
└── package.json
```
**Option B: .claude directory**
```bash
your-project/
├── .claude/
│ └── product/
│ └── index.md # All features in one file
├── src/
└── package.json
```
**Example `PRODUCT.md` or `.claude/product/index.md`:**
```markdown
# My App
## Features
### 1. User Authentication - CRITICAL
- Login with email/password
- JWT token handling
- Password reset
### 2. User Profile - HIGH
- Edit profile information
- Upload avatar
### 3. Dashboard - MEDIUM
- Display user stats
- Recent activity
```
#### Hierarchical Structure
**Best for:** Large projects with 20+ features, team collaboration, complex dependencies
```bash
your-project/
├── .claude/
│ └── product/
│ ├── index.md # Product overview
│ └── domains/
│ ├── authentication/
│ │ ├── index.md # Domain overview
│ │ └── features/
│ │ ├── login.md
│ │ └── register.md
│ └── user-management/
│ ├── index.md
│ └── features/
│ └── profile.md
```
**Example structure:**
**`.claude/product/index.md`** - Product overview:
```markdown
# My App
A full-stack application for user management.
## Domains
- Authentication (CRITICAL)
- User Management (HIGH)
- Dashboard (MEDIUM)
```
**`.claude/product/domains/authentication/index.md`** - Domain overview:
```markdown
# Authentication Domain
Handles user identity and access control.
## Features
- Login
- Register
- Password Reset
```
**`.claude/product/domains/authentication/features/login.md`** - Feature details:
```markdown
# Feature: Login
Priority: CRITICAL
## Subtasks
1. Create login UI
2. Implement login API
3. Add JWT handling
4. Write tests
```
#### Auto-Detection
The system automatically detects which format you're using:
1. **Hierarchical**: If `.claude/product/domains/*/index.md` exists
→ Tracks at subtask → feature → domain levels
2. **Flat (legacy)**: If `PRODUCT.md` exists at root
→ Tracks at feature level
3. **Flat (new)**: If `.claude/product/index.md` exists (without domains)
→ Tracks at feature level
**No configuration needed** - just create your files and agentful adapts automatically.
#### Migration Path
Start flat, migrate to hierarchical as your project grows:
```bash
# Phase 1: Quick Start
PRODUCT.md (all features in one file)
# Phase 2: Organize (optional)
.claude/product/index.md (move to .claude directory)
# Phase 3: Scale Up (when needed)
.claude/product/domains/ (split by domain)
```
#### When to Use Each Format
| Format | Use When | Benefits |
| ------------------------------- | ------------------------------------ | --------------------------------------- |
| Flat (PRODUCT.md) | MVP, prototype, small project | Simplest, fastest setup |
| Flat (.claude/product/index.md) | Want organization, but small project | Keeps root clean, still simple |
| Hierarchical | 20+ features, team collaboration | Domain-driven, parallel work, organized |
**Recommendation:** Start with `PRODUCT.md` for speed. Migrate to `.claude/product/domains/` when you have 20+ features or multiple developers.
For detailed examples and best practices, see [Project Structure Guide](/configuration/project-structure).
***
### Basic Configuration
#### 1. Settings (settings.json)
The main configuration file for agentful.
**Location:** `.claude/settings.json`
**Current defaults:**
```json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
]
}
],
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "if [ -f .agentful/state.json ]; then jq -r '.current_phase // \"idle\"' .agentful/state.json 2>/dev/null || echo 'idle'; else echo 'idle'; fi"
}
]
}
]
},
"permissions": {
"allow": [
"Bash(npm:*)",
"Bash(npx:*)",
"Bash(node:*)",
"Bash(git:*)",
"Bash(cat:*)",
"Bash(echo:*)",
"Bash(jq:*)"
],
"deny": [
"Bash(rm -rf /)",
"Bash(rm -rf ~/.*)",
"Bash(rm -rf /.*)",
"Bash(dd:*)",
"Bash(mkfs:*)"
]
}
}
```
##### Understanding Hooks
**PostToolUse Hook**
Runs after every file edit/write. Currently checks for TypeScript errors:
```json
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | head -5 || true"
}
]
}
```
**Customize for other languages:**
```json
// For Python
{
"command": "python -m mypy . 2>&1 | head -5 || true"
}
// For Go
{
"command": "go build ./... 2>&1 | head -5 || true"
}
// Disable TypeScript checking
{
"command": "echo 'TypeScript checking disabled'"
}
```
**UserPromptSubmit Hook**
Runs before showing Claude's response. Currently shows current development phase.
##### Understanding Permissions
**Allow List** - Commands agents can run:
```json
"allow": [
"Bash(npm:*)", // Run npm commands
"Bash(npx:*)", // Run npx commands
"Bash(git:*)", // Run git commands
"Bash(cat:*)", // Read files
"Bash(jq:*)", // Process JSON
"Bash(pnpm:*)" // Add pnpm support
]
```
**Deny List** - Dangerous commands to block:
```json
"deny": [
"Bash(rm -rf /)", // Prevent deleting root
"Bash(rm -rf ~/.*)", // Prevent deleting home dir
"Bash(dd:*)", // Prevent disk destruction
"Bash(mkfs:*)" // Prevent filesystem formatting
]
```
**Add custom permissions:**
```json
"allow": [
"Bash(npm:*)",
"Bash(yarn:*)", // Add Yarn support
"Bash(python:*)", // Add Python support
"Bash(ruby:*)", // Add Ruby support
"Bash(docker:*)", // Add Docker support
"Bash(make:*)" // Add make support
]
```
***
### Agent Configuration
#### 2. Customizing Existing Agents
All agents are Markdown files in `.claude/agents/`:
```
.claude/agents/
├── orchestrator.md # Main coordinator
├── architect.md # Tech stack analyzer
├── backend.md # Backend specialist
├── frontend.md # Frontend specialist
├── tester.md # Test writer
├── reviewer.md # Quality validator
└── fixer.md # Issue fixer
```
##### Example: Customize Frontend Agent
**Location:** `.claude/agents/frontend.md`
**Current scope:**
* UI Components
* Pages
* Hooks
* State Management
* Forms
* Styling
* Client-side Logic
**Add to scope:**
```markdown
## Your Scope
- **UI Components** - Reusable component library
- **Pages** - Route pages and views
- **Hooks** - Custom React hooks
- **State Management** - Context, Zustand, Redux, etc.
- **Forms** - Form handling and validation
- **Styling** - Tailwind, CSS Modules, styled-components, etc.
- **Client-side Logic** - User interactions, animations
- **Animation** - Framer Motion, GSAP, CSS animations ← NEW
```
**Remove from scope:**
```markdown
## NOT Your Scope (delegate or skip)
- Backend API routes → @backend
- Database operations → @backend
- Tests → @tester
- Code review → @reviewer
- State Management → @state-manager ← DELEGATE INSTEAD
```
##### Example: Customize Quality Gates
**Location:** `.claude/agents/reviewer.md`
**Add custom gate:**
```markdown
## Quality Gates
Code must pass ALL gates before completion:
- ✅ All tests passing
- ✅ No type errors (adapts to stack)
- ✅ No lint errors
- ✅ No dead code (unused exports, files, dependencies)
- ✅ Test coverage ≥ 80%
- ✅ No security issues
- ✅ Bundle size < 200KB (gzip) ← NEW
- ✅ Lighthouse score ≥ 90 ← NEW
```
#### 3. Creating New Agents
Create a new agent for specialized work:
**Example: Database Agent**
**Location:** `.claude/agents/database.md`
````markdown
---
name: database
version: 1.0.0
---
# Database Agent
You are the **Database Agent**. You handle all database-related operations.
## Your Scope
- **Schema Design** - Database models and relationships
- **Migrations** - Database migrations and rollbacks
- **Queries** - Complex queries and optimization
- **Seeding** - Database seeding and test data
- **Backups** - Database backup strategies
## NOT Your Scope (delegate or skip)
- API routes → @backend
- Business logic → @backend
- Tests → @tester
## Implementation Pattern
### Schema Design (Prisma)
```prisma
// prisma/schema.prisma
model User {
id String @id @default(cuid())
email String @unique
name String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
posts Post[]
}
````
#### Migration
```bash
npx prisma migrate dev --name add_users_table
```
#### Query Optimization
```typescript
// Efficient query with select
const users = await prisma.user.findMany({
select: {
id: true,
name: true,
_count: {
select: { posts: true }
}
}
});
```
### Rules
1. **ALWAYS** use TypeScript for schema definitions
2. **ALWAYS** create migrations for schema changes
3. **ALWAYS** use transactions for multi-step operations
4. **NEVER** expose raw database queries to API
5. **NEVER** delete columns without migration
6. **ALWAYS** add indexes for frequently queried fields
### After Implementation
When done, report:
* Schemas created/modified
* Migrations run
* Query optimizations made
* What needs testing (delegate to @tester)
````
**Use the new agent:**
In commands, reference with `@database`:
```markdown
The database schema is missing. @database, please create the User model.
````
***
### Command Configuration
#### 4. Customizing Commands
Commands are Markdown files in `.claude/commands/`:
```
.claude/commands/
├── agentful-start.md # Begin development
├── agentful-status.md # Check progress
├── agentful-decide.md # Answer decisions
└── agentful-validate.md # Run quality checks
```
##### Example: Add Deploy Command
**Location:** `.claude/commands/agentful-deploy.md`
```markdown
---
name: agentful-deploy
description: Deploy project to production
---
# Deploy Command
Deploys the project to production after validation.
## Usage
```
/agentful-deploy
```
## What It Does
1. Runs full validation (`/agentful-validate`)
2. Checks if all gates pass
3. Runs build command
4. Deploys to configured platform
5. Runs smoke tests
6. Reports deployment URL
## Requirements
- All quality gates must pass
- Build must succeed
- No uncommitted changes
## Platforms
Detects platform from configuration:
- **Vercel**: Runs `vercel deploy --prod`
- **Netlify**: Runs `netlify deploy --prod`
- **Railway**: Runs `railway up`
- **Custom**: Runs `npm run deploy`
## Example Output
```
🚀 Deploying to production...
Step 1: Validation
✅ All tests passing
✅ No type errors (adapts to stack)
✅ Coverage 87%
Step 2: Build
✅ Build successful (124ms)
Step 3: Deploy
✅ Deployed to Vercel
Step 4: Smoke tests
✅ Homepage loads
✅ API responding
Deployment complete!
🔗 [https://your-app.vercel.app](https://your-app.vercel.app)
````
## Configuration
Add to `PRODUCT.md`:
```markdown
## Deployment
- **Platform**: Vercel
- **Build Command**: npm run build
- **Output Directory**: .next
````
````
**Use the command:**
```bash
/agentful-deploy
````
***
### Skills Configuration
#### 5. Adding Skills
Skills are reusable capabilities in `.claude/skills/`:
```
.claude/skills/
├── product-tracking/
│ └── SKILL.md
└── validation/
└── SKILL.md
```
##### Example: Add Testing Skill
**Location:** `.claude/skills/testing/SKILL.md`
```markdown
---
name: testing
version: 1.0.0
---
# Testing Skill
Provides testing capabilities for agentful agents.
## What This Skill Does
- Writes unit tests
- Writes integration tests
- Writes E2E tests
- Generates test data
- Creates test fixtures
- Measures coverage
## Usage
Agents can invoke this skill:
```
@tester use testing skill to write tests for UserService
````
## Test Templates
### Unit Test (Vitest)
```typescript
import { describe, it, expect } from 'vitest';
import { UserService } from '../UserService';
describe('UserService', () => {
it('should create a user', async () => {
const user = await UserService.create({
email: 'test@example.com',
name: 'Test User'
});
expect(user).toHaveProperty('id');
expect(user.email).toBe('test@example.com');
});
});
````
#### Integration Test
```typescript
import { describe, it, expect, beforeAll, afterAll } from 'vitest';
import { prisma } from '@/lib/prisma';
describe('User API', () => {
beforeAll(async () => {
// Setup test database
});
afterAll(async () => {
// Cleanup
await prisma.user.deleteMany();
});
it('should create user via API', async () => {
const response = await fetch('/api/users', {
method: 'POST',
body: JSON.stringify({
email: 'test@example.com',
name: 'Test User'
})
});
expect(response.status).toBe(201);
});
});
```
### Coverage Targets
* Unit tests: 90%+ coverage
* Integration tests: Critical paths covered
* E2E tests: User journeys covered
### Best Practices
1. Test behavior, not implementation
2. Use descriptive test names
3. Follow AAA pattern (Arrange, Act, Assert)
4. Mock external dependencies
5. Keep tests fast and isolated
````
---
## Template Configuration
### 6. PRODUCT.md Template
Customize the default product template.
**Location:** `template/PRODUCT.md`
**Add custom sections:**
```markdown
## Custom Section
### Performance Requirements
- Page load < 2s
- Time to Interactive < 3s
- Lighthouse score > 90
### Accessibility Requirements
- WCAG 2.1 AA compliant
- Keyboard navigation
- Screen reader support
- Color contrast > 4.5:1
### Internationalization
- Support multiple languages
- Date/time localization
- Currency formatting
- RTL support for Arabic/Hebrew
````
#### 7. CLAUDE.md Template
Customize project instructions.
**Location:** `template/CLAUDE.md`
**Add custom guidelines:**
```markdown
## Coding Standards
### Naming Conventions
- Components: PascalCase (UserProfile.tsx)
- Utilities: camelCase (formatDate.ts)
- Constants: UPPER_SNAKE_CASE (API_BASE_URL)
- Hooks: use prefix (useAuth.ts)
### File Organization
```
src/
├── components/
│ ├── ui/ # Reusable components
│ └── features/ # Feature components
├── lib/ # Utilities
├── hooks/ # Custom hooks
└── types/ # TypeScript types
```
### Git Conventions
- Commit messages: conventional commits
- Branch naming: feature/, fix/, chore/
- PR templates required
```
***
### Environment Configuration
#### 8. Environment Variables
Create `.env.example` for your project:
```bash
# Database
DATABASE_URL="postgresql://..."
# API Keys
NEXT_PUBLIC_API_URL="https://api.example.com"
API_SECRET_KEY="..."
# Auth
NEXTAUTH_SECRET="..."
NEXTAUTH_URL="http://localhost:3000"
# Features
NEXT_PUBLIC_FEATURE_FLAGS="new-ui,dark-mode"
```
**Reference in PRODUCT.md:**
```markdown
## Environment Variables
Required environment variables:
- `DATABASE_URL` - PostgreSQL connection string
- `NEXTAUTH_SECRET` - Auth secret (generate with openssl)
- `API_SECRET_KEY` - API key for external services
```
***
### Platform-Specific Configuration
#### 9. Next.js Configuration
**next.config.js:**
```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
swcMinify: true,
images: {
domains: ['example.com'],
},
experimental: {
serverActions: true,
},
}
module.exports = nextConfig
```
#### 10. TypeScript Configuration
**tsconfig.json:**
```json
{
"compilerOptions": {
"target": "ES2020",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
```
***
### Quality Gate Configuration
#### 11. Coverage Thresholds
**Update in `.claude/agents/reviewer.md`:**
```markdown
## Coverage Thresholds
- Overall: ≥ 80%
- Critical paths: ≥ 90%
- UI components: ≥ 70%
- Utilities: ≥ 95%
```
**Vitest configuration:**
```typescript
// vitest.config.ts
export default defineConfig({
test: {
coverage: {
provider: 'v8',
reporter: ['text', 'json', 'html'],
thresholds: {
lines: 80,
functions: 80,
branches: 80,
statements: 80,
},
},
},
})
```
***
### Workflow Configuration
#### 12. Custom Workflow Steps
**Create custom workflow in `.claude/commands/agentful-custom.md`:**
```markdown
---
name: agentful-custom
description: Custom workflow for specific needs
---
# Custom Workflow
## Usage
```
/agentful-custom
```
## Workflow Steps
1. **Analysis Phase**
- Review current state
- Identify blockers
- Prioritize tasks
2. **Implementation Phase**
- Build features
- Write tests
- Document code
3. **Validation Phase**
- Run quality gates
- Security scan
- Performance check
4. **Deployment Phase**
- Build artifacts
- Deploy to staging
- Run smoke tests
## Custom Logic
Add your project-specific workflow here.
```
***
### Troubleshooting Configuration
#### Issue: Configuration Not Loading
**Symptoms:** Changes to `.claude/` not taking effect
**Solutions:**
1. **Restart Claude Code:**
```bash
# Exit and restart
exit
claude
```
2. **Check File Format:**
* Must be valid Markdown (`.md`)
* Must have valid frontmatter (for commands)
* No syntax errors in JSON
3. **Verify File Paths:**
```bash
# Should exist
ls -la .claude/agents/
ls -la .claude/commands/
ls -la .claude/settings.json
```
#### Issue: Agent Not Responding
**Symptoms:** `@agent-name` not working
**Solutions:**
1. **Check Agent File:**
* File must exist in `.claude/agents/`
* File must be valid Markdown
* Agent name must match filename
2. **Verify Agent Name:**
```bash
# List agents
ls .claude/agents/
# Reference without .md extension
@database # NOT @database.md
```
3. **Check Agent Definition:**
* Must have proper sections
* Must have clear scope definition
***
### Best Practices
#### 1. Version Control Your Config
**Commit `.claude/` to git:**
```bash
git add .claude/
git commit -m "Configure agentful agents and commands"
```
**Ignore `.agentful/` (runtime state):**
```bash
# Already in .gitignore
.agentful/
```
#### 2. Document Custom Changes
**Create CONFIG.md:**
```markdown
# agentful Configuration
## Custom Agents
- `@database` - Handles database operations
- `@analytics` - Analytics and tracking
## Custom Commands
- `/agentful-deploy` - Custom deployment workflow
## Modified Agents
- `@frontend` - Added animation support
- `@reviewer` - Added bundle size checks
## Quality Gates
- Coverage: 80% (was 75%)
- Bundle size: < 200KB
- Lighthouse: ≥ 90
```
#### 3. Test Configuration Gradually
**Start with defaults:**
```bash
# Use default config first
npx @itz4blitz/agentful init
```
**Make small changes:**
* Modify one agent at a time
* Test after each change
* Revert if issues arise
**Document what works:**
* Keep notes on successful changes
* Share with team
* Contribute back to agentful
***
### Next Steps
#### Agent Reference
Learn about each agent in detail
→ [Agents Guide](/agents/)
#### Command Reference
Learn about all commands
→ [Commands Guide](/commands/)
#### Advanced Configuration
Deep customization techniques
→ [Advanced Guide](/configuration)
#### Examples
See configuration examples
→ [Examples](/examples/)
## Your First Project
Build your first complete autonomous project with agentful. We'll create a **Task Management App** together.
***
### Project Overview
**What we're building:**
A simple task management application where users can:
* Add tasks
* Mark tasks as complete
* Delete tasks
* Filter by status
**Tech Stack:**
* Next.js 14 + TypeScript
* Tailwind CSS
* Local state (no database)
* Vitest for testing
**Time:** 30-45 minutes
**Difficulty:** Beginner
***
### Step 1: Initialize Project (5 minutes)
#### Create Project Directory
```bash
mkdir task-manager
cd task-manager
```
#### Initialize Next.js App
```bash
npx create-next-app@latest . --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
```
Follow prompts (press Enter for defaults).
#### Initialize agentful
```bash
npx @itz4blitz/agentful init
```
**Expected output:**
```
___ __ ____________ ____ ___ ____________
/ | / / / /_ __/ __ \/ __ \/ _ | / ____/ _/ /
/ /| | / / / / / / /_/ / /_/ / __ |/ / / // /
/ ___ |/ /_/ / / / / _, _/ _, _/ /_/ / /___/ // /
/_/ |_|_____/ /_/_/ /_/ |_/_/ |_|\____/\____/___/
v1.0.0
Creating .claude/ directory structure...
Initializing state files...
Creating template files...
✓ Created CLAUDE.md
✓ Created .claude/product/index.md (hierarchical structure)
Added .agentful/ to .gitignore
✅ agentful initialized successfully!
Next steps:
1. Edit your product specification (see options below)
2. Run: claude
3. Type: /agentful-start
```
> **Choose Your Structure**
>
> agentful supports two ways to define your product:
>
> **Simple Projects** (recommended for first-time users):
>
> * Use a flat `PRODUCT.md` file in your project root
> * Everything in one place
> * Easier to get started
>
> **Complex Projects** (for larger applications):
>
> * Use `.claude/product/` directory with multiple files
> * Organize by domains/features
> * Scales better for big projects
>
> Both work identically - agentful auto-detects which you're using. For this tutorial, we'll use the simple `PRODUCT.md` approach.
***
### Step 2: Define Product (10 minutes)
Since we're building a simple task manager, we'll use the **flat `PRODUCT.md`** structure.
Create a file called `PRODUCT.md` in your project root and add:
> **Note**: If you prefer the hierarchical structure, you can edit `.claude/product/index.md` instead - the content is identical. agentful will auto-detect either approach.
```markdown
# Product Specification
## Overview
A simple task management application for personal productivity. Users can add, complete, and delete tasks with a clean, intuitive interface.
## Goals
- [ ] Users can add tasks with descriptions
- [ ] Users can mark tasks as complete
- [ ] Users can delete tasks
- [ ] Users can filter tasks by status
- [ ] 80%+ test coverage
- [ ] No type errors (adapts to stack)
## Tech Stack
### Frontend
- **Framework**: Next.js 14
- **Language**: TypeScript
- **Styling**: Tailwind CSS
- **State Management**: React useState/useReducer
### Backend
- **Runtime**: Node.js
- **Framework**: Next.js API Routes (not needed for this project)
### Database
- **Database**: None (local state only)
### Testing
- **Unit**: Vitest
- **E2E**: None (skip for this project)
### Deployment
- **Hosting**: Vercel (future)
## Features (Priority Order)
### 1. Add Task - CRITICAL
**Description**: Users can add new tasks to their list
**Acceptance Criteria**:
- [ ] Input field for task description
- [ ] Add button
- [ ] Task appears in list after adding
- [ ] Input clears after adding
- [ ] Validation: empty tasks not allowed
- [ ] Validation: max 200 characters
**User Stories**:
- As a user, I want to add tasks so that I can remember what I need to do
- As a user, I want the input to clear after adding so I can quickly add multiple tasks
**Technical Notes**:
- Use input with text type
- Show error message for invalid input
- Focus input after adding
---
### 2. Toggle Task Completion - CRITICAL
**Description**: Users can mark tasks as complete/incomplete
**Acceptance Criteria**:
- [ ] Checkbox or click to toggle
- [ ] Visual indicator for completed tasks (strikethrough)
- [ ] Completion status persists in local state
**User Stories**:
- As a user, I want to mark tasks complete so I can see my progress
**Technical Notes**:
- Use checkbox or clickable element
- Add line-through style for completed tasks
- Gray out completed task text
---
### 3. Delete Task - HIGH
**Description**: Users can delete tasks they no longer need
**Acceptance Criteria**:
- [ ] Delete button on each task
- [ ] Confirmation before deleting (optional, skip for MVP)
- [ ] Task removes from list after deletion
**User Stories**:
- As a user, I want to delete tasks so I can keep my list clean
**Technical Notes**:
- Use trash icon or "Delete" text button
- Red color for delete action
- Smooth removal animation (optional)
---
### 4. Filter Tasks - MEDIUM
**Description**: Users can filter tasks by completion status
**Acceptance Criteria**:
- [ ] Filter buttons: All, Active, Completed
- [ ] Only show tasks matching selected filter
- [ ] Active filter highlighted
- [ ] Task count updates per filter
**User Stories**:
- As a user, I want to see only active tasks so I can focus on what's left
**Technical Notes**:
- Use button group for filters
- Update task count when filter changes
- Persist filter selection in state
---
### 5. Task Counter - LOW
**Description**: Display count of remaining active tasks
**Acceptance Criteria**:
- [ ] Show "X tasks left" text
- [ ] Updates in real-time
- [ ] Only counts active (incomplete) tasks
**User Stories**:
- As a user, I want to see how many tasks are left so I know my progress
**Technical Notes**:
- Display near filter buttons
- Update whenever tasks change
---
## Architecture Notes
### Folder Structure
```
src/
├── app/
│ ├── page.tsx # Main task manager page
│ ├── layout.tsx # Root layout
│ └── globals.css # Global styles
├── components/
│ ├── TaskList.tsx # Task list component
│ ├── TaskItem.tsx # Individual task component
│ ├── TaskInput.tsx # Add task input
│ └── TaskFilters.tsx # Filter buttons
└── lib/
└── types.ts # TypeScript types
```
### Design Patterns
- Use TypeScript for all components
- Functional components with hooks
- Props interfaces explicitly defined
- Separation of concerns (UI, state, logic)
### Constraints
- Mobile-first responsive design
- Accessible (keyboard navigation, ARIA labels)
- Client-side only (no API routes needed)
- Use Tailwind utility classes
## Out of Scope (for MVP)
- User authentication
- Task editing
- Task priorities
- Due dates
- Persistent storage (localStorage is fine)
- Cloud sync
## Success Criteria
The product is complete when:
1. All critical and high features implemented and tested
2. All tests passing with 80%+ coverage
3. No type errors (adapts to stack)
4. No lint errors
5. Responsive on mobile (375px+)
6. Accessible with keyboard
## Notes
- Keep it simple - this is a learning project
- Focus on clean code and tests
- Use TypeScript strictly (no any types)
- Follow Tailwind best practices
- Write tests as you go (via agentful)
```
***
### Step 3: Start Development (2 minutes)
#### Start Claude Code
```bash
claude
```
#### Begin Autonomous Development
In the Claude prompt, type:
```
/agentful-start
```
***
### Step 4: Watch agentful Work (20-30 minutes)
#### What You'll See
**Phase 1: Architecture Analysis (first 30 seconds)**
```
🏗️ Architect Agent analyzing...
Detected tech stack:
- Next.js 14
- TypeScript
- Tailwind CSS
- Vitest
Generated specialized agents:
✓ nextjs-agent
✓ typescript-agent
✓ tailwind-agent
✓ vitest-agent
✓ react-agent
Architecture analysis complete.
```
**Phase 2: Planning (next 30 seconds)**
```
📋 Orchestrator planning work...
Feature queue:
1. Add Task (CRITICAL)
2. Toggle Task Completion (CRITICAL)
3. Delete Task (HIGH)
4. Filter Tasks (MEDIUM)
5. Task Counter (LOW)
Starting: Add Task feature
```
**Phase 3: Implementation (5-10 minutes)**
```
🔧 Frontend Agent implementing...
Created files:
✓ src/lib/types.ts (Task interface)
✓ src/components/TaskInput.tsx
✓ src/components/TaskList.tsx
✓ src/components/TaskItem.tsx
✓ src/app/page.tsx (main page)
Updated files:
✓ src/app/globals.css (Tailwind imports)
```
**Phase 4: Testing (5-10 minutes)**
```
🧪 Tester Agent writing tests...
Created test files:
✓ src/components/__tests__/TaskInput.test.tsx
✓ src/components/__tests__/TaskList.test.tsx
✓ src/components/__tests__/TaskItem.test.tsx
Running tests...
✓ TaskInput renders correctly
✓ TaskInput validates empty input
✓ TaskInput validates max length
✓ TaskList displays tasks
✓ TaskItem toggles completion
✓ TaskItem deletes task
14 tests passing
```
**Phase 5: Validation (2 minutes)**
```
🔍 Reviewer Agent validating...
Running quality checks...
TypeScript: ✅ No errors
ESLint: ✅ No errors
Tests: ✅ All passing
Coverage: ✅ 87%
Dead Code: ✅ None found
Security: ✅ No issues
Feature complete: Add Task (100%)
```
**Phase 6: Next Feature (continues)**
```
Next: Toggle Task Completion
→ @frontend implementing toggle functionality
→ @tester writing toggle tests
→ @reviewer validating quality
Feature complete: Toggle Task Completion (100%)
Next: Delete Task
→ @frontend implementing delete functionality
...
```
This continues until all features are complete.
***
### Step 5: Monitor Progress (ongoing)
While agentful works, check progress anytime:
```
/agentful-status
```
**Example output during development:**
```
🔧 Working on: Filter Tasks feature
Phase: implementation
Iterations: 15
Progress:
████████████░░░░░░░ 60%
Features:
✅ Add Task (100%)
✅ Toggle Task Completion (100%)
✅ Delete Task (100%)
🔄 Filter Tasks (40%)
⏳ Task Counter (0%)
Quality Gates:
✅ Tests Passing (42/42)
✅ No Type Errors
✅ Coverage 87%
✅ No Dead Code
✅ No Security Issues
No pending decisions.
Next Actions:
• /agentful-start - Continue development
• /agentful-validate - Run quality checks
```
***
### Step 6: Handle Decisions (if needed)
agentful may ask for clarification:
```
⚠️ Decision needed:
For the "Delete Task" feature, should we:
1. Show confirmation dialog before deleting
2. Delete immediately without confirmation
Context: This affects user experience. Confirmation is safer but
adds friction. Immediate delete is faster but riskier.
```
**To answer:**
```
/agentful-decide
```
Then provide your preference:
```
Option 2: Delete immediately without confirmation
We can add undo functionality in v2 if needed.
```
agentful will immediately resume with your decision.
***
### Step 7: Review Results (5 minutes)
When agentful completes (100%), review what was built:
#### Check Generated Files
```bash
# View component structure
tree src/components
# View test coverage
npm run test -- --coverage
# Run TypeScript check
npx tsc --noEmit
# Run linting
npm run lint
```
#### Test the App
```bash
# Start development server
npm run dev
```
Open [http://localhost:3000](http://localhost:3000) and test:
1. Add a task
2. Mark it complete
3. Delete it
4. Try filters
#### Review Code Quality
```bash
# Final validation
/agentful-validate
```
**Expected output:**
```
✅ All tests passing (48/48)
✅ No type errors (adapts to stack)
✅ No ESLint errors
✅ Test coverage: 87%
✅ No dead code detected
✅ No security issues
Project complete! 🎉
```
***
### What agentful Built
#### File Structure Created
```
src/
├── app/
│ ├── page.tsx # Main page with task manager
│ ├── layout.tsx # Root layout
│ └── globals.css # Tailwind styles
├── components/
│ ├── TaskInput.tsx # Add task input component
│ ├── TaskList.tsx # Task list container
│ ├── TaskItem.tsx # Individual task display
│ └── TaskFilters.tsx # Filter button group
├── lib/
│ └── types.ts # TypeScript interfaces
└── components/
└── __tests__/
├── TaskInput.test.tsx # 8 tests
├── TaskList.test.tsx # 12 tests
├── TaskItem.test.tsx # 14 tests
└── TaskFilters.test.tsx # 14 tests
```
#### Key Features Implemented
✅ **Add Task** - Input with validation, auto-clear, focus management
✅ **Toggle Completion** - Checkbox with visual strikethrough
✅ **Delete Task** - Remove button with smooth UX
✅ **Filter Tasks** - All/Active/Completed with counts
✅ **Task Counter** - "X tasks left" display
✅ **Responsive Design** - Mobile-first Tailwind styling
✅ **Accessibility** - Keyboard navigation, ARIA labels
✅ **Tests** - 48 tests with 87% coverage
***
### Common Issues and Solutions
#### Issue: agentful stops mid-development
**Symptom:** No progress after 5+ minutes
**Solution:**
```bash
# Check status
/agentful-status
# Look for:
# - Pending decisions? → /agentful-decide
# - High iteration count? → /agentful-start to resume
# - Errors? → /agentful-validate
```
#### Issue: Tests failing
**Symptom:** Red test output
**Solution:**
Let agentful handle it. The Fixer agent will:
1. Identify failing tests
2. Fix implementation
3. Re-run tests
4. Continue when passing
#### Issue: Low test coverage
**Symptom:** Coverage \< 80%
**Solution:**
agentful will automatically add more tests. Watch for:
```
🧪 Tester Agent: Adding edge case tests...
Coverage now: 82% ✅
```
#### Issue: TypeScript errors
**Symptom:** Type errors in output
**Solution:**
The Fixer agent will resolve these. If persistent:
```bash
# Check specific errors
npx tsc --noEmit
# Manually fix if needed
# Then /agentful-start to continue
```
***
### Customizing Your Project
After agentful completes, you can:
#### Add New Features
**If using PRODUCT.md** (flat structure):
Edit `PRODUCT.md`:
```markdown
### 6. Task Due Dates - MEDIUM
**Description**: Add due dates to tasks
...
```
**If using hierarchical structure** (.claude/product/):
Edit `.claude/product/index.md` or add a new domain file like `.claude/product/domains/tasks.md`:
```markdown
### 6. Task Due Dates - MEDIUM
**Description**: Add due dates to tasks
...
```
Then:
```bash
/agentful-start
```
#### Modify Existing Features
**If using PRODUCT.md**:
Update acceptance criteria in `PRODUCT.md`:
```markdown
### 1. Add Task - CRITICAL
**Acceptance Criteria**:
- [ ] Input field for task description
- [ ] Add button
- [ ] Priority selector (Low/Medium/High) ← NEW
...
```
**If using hierarchical structure**:
Update the relevant domain file in `.claude/product/domains/`
Then:
```bash
/agentful-start
```
#### Switch Between Structures
You can switch between flat and hierarchical anytime:
* **Flat → Hierarchical**: Move `PRODUCT.md` → `.claude/product/index.md` and split into domain files
* **Hierarchical → Flat**: Merge all `.claude/product/**/*.md` into single `PRODUCT.md`
agentful auto-detects the change on next run.
#### Change Styling
Edit components directly:
```tsx
// src/components/TaskItem.tsx
// Change color
```
agentful won't overwrite manual edits unless you run `/agentful-start` again.
***
### Next Steps
#### Deploy Your Project
Deploy to Vercel, Netlify, or your preferred host
→ Follow your hosting platform's guides
#### Build More Projects
Try building different applications
→ [Examples Guide](/examples/)
#### Customize agentful
Modify agents and commands for your workflow
→ [Configuration Guide](/getting-started/configuration)
***
### Recap
You just built a complete task management application with:
✅ 5 features fully implemented
✅ 48 tests passing
✅ 87% test coverage
✅ No type errors (adapts to stack)
✅ Responsive design
✅ Accessibility features
✅ All in 30-45 minutes
**What you learned:**
* How to initialize agentful
* How to choose between flat (`PRODUCT.md`) or hierarchical (`.claude/product/`) structure
* How to write a clear product specification
* How agentful's agents work together
* How to monitor and guide development
* How to handle decisions
* How to review and validate results
**You're now ready to:**
* Build more complex projects with hierarchical structure
* Customize agentful for your stack
* Use 24/7 development mode
* Create your own agents and commands
Happy building! 🚀
## Installation
Get agentful up and running in your project in under a minute.
***
### Prerequisites
Before installing agentful, ensure you have:
* **Claude Code** installed - [Get it here](https://code.anthropic.com)
* **Node.js 18+** installed - [Download here](https://nodejs.org/)
* A project directory to work in
**Optional (for 24/7 development):**
* Ralph Wiggum plugin for Claude Code
```bash
/plugin install ralph-wiggum@anthropics
```
***
### Installation Methods
#### Method 1: Initialize in Existing Project (Recommended)
If you have an existing project:
```bash
cd your-project
npx @itz4blitz/agentful init
```
This creates:
* `.claude/` - Pre-configured agents, commands, skills
* `.agentful/` - Runtime state tracking (gitignored)
* `PRODUCT.md` - Your product spec template
* `CLAUDE.md` - Project instructions for Claude
#### Method 2: Initialize New Project
Starting from scratch? Create a new project first:
```bash
mkdir my-app
cd my-app
npm init -y
npx @itz4blitz/agentful init
```
#### Method 3: Bare Initialization
If you already have `PRODUCT.md` and `CLAUDE.md`:
```bash
npx @itz4blitz/agentful init --bare
```
This skips creating template files and only sets up `.claude/` and `.agentful/`.
***
### What Gets Created
After running `npx @itz4blitz/agentful init`, you'll see:
```
✅ agentful initialized successfully!
Next steps:
1. Edit PRODUCT.md with your product specification
2. Run: claude
3. Type: /agentful-start
For autonomous 24/7 development:
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
```
#### Directory Structure
```
your-project/
├── PRODUCT.md # ← Edit this: your product spec
├── CLAUDE.md # Project instructions
├── .claude/ # agentful configuration
│ ├── agents/ # 7 specialized agents
│ ├── commands/ # 4 slash commands
│ ├── skills/ # Domain skills
│ └── settings.json # Hooks and permissions
├── .agentful/ # Runtime state (gitignored)
│ ├── state.json
│ ├── completion.json
│ ├── decisions.json
│ └── architecture.json
└── package.json
```
***
### Verification
Verify agentful is installed:
```bash
# Check that .claude directory exists
ls -la .claude/
# Check that .agentful directory exists
ls -la .agentful/
# Verify state files
cat .agentful/state.json
```
You should see:
* `.claude/` directory with agents, commands, skills
* `.agentful/` directory with state files
* Initial state set to `idle`
***
### Updating .gitignore
agentful automatically adds `.agentful/` to your `.gitignore`:
```bash
# agentful runtime state
.agentful/
```
The `.agentful/` directory contains runtime state that shouldn't be committed:
* `state.json` - Current work state
* `completion.json` - Progress tracking
* `decisions.json` - Pending decisions
* `architecture.json` - Detected tech stack
**Note**: The `.claude/` directory **should** be committed to version control.
***
### Troubleshooting
#### Issue: "Command not found: npx"
**Solution:** Install Node.js 18+ from [nodejs.org](https://nodejs.org/)
```bash
# Verify Node.js is installed
node --version # Should be v18+
# Verify npx is available
npx --version
```
#### Issue: ".claude directory already exists"
If you already have a `.claude/` directory, agentful will ask:
```bash
⚠️ .claude/ directory already exists!
Overwrite? (y/N)
```
* Type `y` to overwrite (your existing config will be replaced)
* Type `N` or press Enter to abort
**Recommendation:** Back up your existing `.claude/` before overwriting:
```bash
mv .claude .claude.backup
npx @itz4blitz/agentful init
```
#### Issue: Permission denied
**Solution:** Make sure you have write permissions in the directory:
```bash
# Check permissions
ls -la
# If needed, change ownership (macOS/Linux)
sudo chown -R $USER:$USER .claude .agentful
```
#### Issue: "Cannot read properties of undefined"
**Solution:** Ensure you're running in a valid Node.js project:
```bash
# Initialize package.json if missing
npm init -y
# Then try again
npx @itz4blitz/agentful init
```
***
### Next Steps
Now that agentful is installed:
1. **Edit your product spec** → [Quick Start Guide](/getting-started/quick-start)
2. **Start Claude Code** → `claude`
3. **Begin development** → `/agentful-start`
***
### Uninstallation
To remove agentful from your project:
```bash
# Remove agentful directories
rm -rf .claude .agentful
# Remove template files (optional)
rm PRODUCT.md CLAUDE.md
# Remove .gitignore entry (optional)
# Edit .gitignore and remove the .agentful/ line
```
***
### Advanced Options
#### Custom Install Location
By default, agentful installs in the current directory. To install elsewhere:
```bash
npx @itz4blitz/agentful init --path /path/to/project
```
#### Silent Installation
For automation scripts:
```bash
npx @itz4blitz/agentful init --silent
```
Skips the confirmation prompt and creates a backup if `.claude/` exists.
#### Version Check
Check which version of agentful you installed:
```bash
npx agentful --version
```
***
### What's Next?
#### Quick Start
Learn how to use agentful in 5 minutes
→ [Quick Start Guide](/getting-started/quick-start)
#### First Project
Build your first autonomous project
→ [First Project Guide](/getting-started/first-project)
## Quick Start
Get agentful building your project autonomously in 5 minutes.
***
### Overview
This quick start will walk you through:
1. ✅ Initializing agentful
2. ✅ Defining your product
3. ✅ Starting autonomous development
4. ✅ Monitoring progress
5. ✅ Understanding the workflow
**Time:** 5 minutes
**Prerequisites:** [agentful installed](/getting-started/installation)
***
### Step 1: Initialize agentful (30 seconds)
```bash
# In your project directory
npx @itz4blitz/agentful init
```
**What happens:**
* Creates `.claude/` with 7 specialized agents
* Creates `.agentful/` for state tracking
* Creates `.claude/product/index.md` (hierarchical structure template)
* Creates `CLAUDE.md` project instructions
**Output:**
```
✅ agentful initialized successfully!
Next steps:
1. Edit your product specification (see below)
2. Run: claude
3. Type: /agentful-start
```
***
### Step 2: Define Your Product (2 minutes)
agentful supports two ways to define your product. Choose the one that fits your project.
***
#### Choose Your Adventure
**Simple Projects** (recommended for beginners and small apps):
* Use a flat `PRODUCT.md` file in your project root
* Everything in one place
* Easier to get started
* Best for: Learning projects, MVPs, single-purpose apps
**Complex Projects** (for larger applications):
* Use `.claude/product/` directory with multiple files
* Organize by domains/features
* Scales better for big projects
* Best for: Multi-domain apps, large teams, long-term projects
> **Both work identically** - agentful auto-detects which you're using. You can switch anytime.
***
#### Option A: Simple Structure (Flat PRODUCT.md)
Create `PRODUCT.md` in your project root:
```markdown
# Product Specification
## Overview
A simple todo list application.
## Tech Stack
- **Frontend**: Next.js 14, TypeScript, Tailwind CSS
- **Backend**: Next.js API Routes
- **Database**: None (in-memory for now)
- **Testing**: Vitest
## Features
### 1. Add Todo - CRITICAL
**Description**: Users can add new todo items
**Acceptance Criteria**:
- [ ] Input field for new todos
- [ ] Add button
- [ ] Todo appears in list
### 2. Toggle Todo - HIGH
**Description**: Users can mark todos as complete
**Acceptance Criteria**:
- [ ] Click todo to toggle completion
- [ ] Visual indicator for completed todos
### 3. Delete Todo - MEDIUM
**Description**: Users can delete todos
**Acceptance Criteria**:
- [ ] Delete button on each todo
- [ ] Confirmation prompt
```
**That's it!** Skip to Step 3.
***
#### Option B: Hierarchical Structure (.claude/product/)
Edit `.claude/product/index.md` (created during init):
```markdown
# Product Specification
## Overview
A simple todo list application.
## Domains
- Tasks
- UI
- Storage
## Tech Stack
- **Frontend**: Next.js 14, TypeScript, Tailwind CSS
- **Backend**: Next.js API Routes
- **Database**: None (in-memory for now)
- **Testing**: Vitest
```
Then create `.claude/product/domains/tasks.md`:
```markdown
# Tasks Domain
## Features
### 1. Add Todo - CRITICAL
**Description**: Users can add new todo items
**Acceptance Criteria**:
- [ ] Input field for new todos
- [ ] Add button
- [ ] Todo appears in list
### 2. Toggle Todo - HIGH
**Description**: Users can mark todos as complete
**Acceptance Criteria**:
- [ ] Click todo to toggle completion
- [ ] Visual indicator for completed todos
### 3. Delete Todo - MEDIUM
**Description**: Users can delete todos
**Acceptance Criteria**:
- [ ] Delete button on each todo
- [ ] Confirmation prompt
```
**More domains?** Create additional files like `ui.md`, `storage.md`, etc.
***
#### Key Sections Explained
```markdown
# Product Specification
## Overview
A simple todo list application.
## Tech Stack
- **Frontend**: Next.js 14, TypeScript, Tailwind CSS
- **Backend**: Next.js API Routes
- **Database**: None (in-memory for now)
- **Testing**: Vitest
## Features
### 1. Add Todo - CRITICAL
**Description**: Users can add new todo items
**Acceptance Criteria**:
- [ ] Input field for new todos
- [ ] Add button
- [ ] Todo appears in list
### 2. Toggle Todo - HIGH
**Description**: Users can mark todos as complete
**Acceptance Criteria**:
- [ ] Click todo to toggle completion
- [ ] Visual indicator for completed todos
### 3. Delete Todo - MEDIUM
**Description**: Users can delete todos
**Acceptance Criteria**:
- [ ] Delete button on each todo
- [ ] Confirmation prompt
```
#### Key Sections Explained
**Overview** - 2-3 sentences describing what you're building
**Tech Stack** - Your technology choices
* Frontend framework
* Backend framework
* Database
* Testing tools
* Styling approach
**Features** - What you want built, ordered by priority
* **CRITICAL** - Must have for MVP
* **HIGH** - Important but can wait
* **MEDIUM** - Nice to have
* **LOW** - Future improvements
For each feature, include:
* **Description** - What it does
* **Acceptance Criteria** - Specific requirements (checkboxes)
* **User Stories** (optional) - Who wants what and why
***
### Step 3: Start Claude Code (10 seconds)
```bash
claude
```
This starts the Claude Code CLI with agentful's specialized agents loaded.
***
### Step 4: Begin Autonomous Development (30 seconds)
In the Claude Code prompt, type:
```
/agentful-start
```
**What happens next:**
#### Phase 1: Architecture Analysis (10 seconds)
```
🏗️ Architect Agent analyzing...
Detected tech stack:
- Next.js 14
- TypeScript
- Tailwind CSS
Generated specialized agents:
✓ nextjs-agent
✓ typescript-agent
✓ tailwind-agent
✓ vitest-agent
```
#### Phase 2: Planning (10 seconds)
```
📋 Orchestrator planning work...
Priority queue:
1. Add Todo feature (CRITICAL)
2. Toggle Todo feature (HIGH)
3. Delete Todo feature (MEDIUM)
Starting: Add Todo feature
```
#### Phase 3: Implementation (varies)
```
🔧 Frontend Agent implementing...
Created:
- src/app/page.tsx (main page)
- src/components/TodoList.tsx
- src/components/TodoInput.tsx
- src/hooks/useTodos.ts
```
#### Phase 4: Testing (varies)
```
🧪 Tester Agent writing tests...
Created:
- src/components/__tests__/TodoList.test.tsx
- src/hooks/__tests__/useTodos.test.ts
Running tests...
✓ All tests passing
```
#### Phase 5: Validation (20 seconds)
```
🔍 Reviewer Agent validating...
Quality Gates:
✅ All tests passing
✅ No type errors (adapts to stack)
⚠️ Test coverage: 65% (target: 80%)
✅ No dead code
✅ No security issues
Coverage below 80%, continuing...
```
#### Phase 6: Iteration (continues)
```
🔄 Fixer Agent improving coverage...
Added tests for edge cases...
Coverage now: 82% ✅
Feature complete: Add Todo (100%)
Next: Toggle Todo feature...
```
***
### Step 5: Monitor Progress (ongoing)
Check progress anytime:
```
/agentful-status
```
**Output:**
```
🔧 Working on: Toggle Todo feature
Phase: implementation
Iterations: 8
Progress:
████████░░░░░░░░░░░ 40%
Quality Gates:
✅ Tests Passing
✅ No Type Errors
✅ Coverage 82%
✅ No Dead Code
⚠️ 1 pending decision:
1. Should completed todos move to bottom?
Next Actions:
• /agentful-start - Continue development
• /agentful-decide - Answer pending decision
• /agentful-validate- Run quality checks
```
***
### Step 6: Handle Decisions (if needed)
Sometimes agentful needs your input:
```
⚠️ Decision needed:
Should completed todos move to the bottom of the list?
Options:
1. Yes, move to bottom
2. No, keep in place
3. Sort by completion date
```
**To answer:**
```
/agentful-decide
```
Then provide your answer:
```
Option 1: Yes, move to bottom
```
agentful will immediately resume with your decision.
***
### Understanding the Workflow
#### The Development Loop
```
┌─────────────────────────────────────────┐
│ 1. Architect: Analyze tech stack │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 2. Orchestrator: Plan next task │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 3. Specialist: Implement feature │
│ (@frontend, @backend, @tester) │
└─────────────────────────────────────────┘
↓
┌─────────────────────────────────────────┐
│ 4. Reviewer: Validate quality │
└─────────────────────────────────────────┘
↓
Issues found?
↓
┌──────┴──────┐
↓ ↓
┌─────────────┐ ┌─────────────┐
│ 5. Fixer │ │ 6. Complete │
│ Fix issues│ │ Update │
└─────────────┘ │ Progress │
│ └─────────────┘
└─────────────────┘
↓
┌─────────────────────────────────────────┐
│ 7. Loop again until 100% complete │
└─────────────────────────────────────────┘
```
#### Agent Roles
| Agent | When it activates | What it does |
| ----------------- | -------------------- | ------------------------------------------------- |
| **@architect** | Once at start | Analyzes tech stack, generates specialized agents |
| **@orchestrator** | Every iteration | Plans work, delegates to specialists |
| **@frontend** | Building UI | Components, pages, hooks, styling |
| **@backend** | Building APIs | Services, repositories, controllers |
| **@tester** | After implementation | Writes unit, integration, E2E tests |
| **@reviewer** | After testing | Validates quality gates, finds issues |
| **@fixer** | When issues found | Auto-fixes validation failures |
***
### Common Commands
#### Start/Resume Development
```
/agentful-start
```
#### Check Progress
```
/agentful-status
```
#### Answer Pending Decisions
```
/agentful-decide
```
#### Run Quality Checks
```
/agentful-validate
```
***
### Tips for Success
#### 1. Start Small
Your first time? Build something simple:
✅ **Good first projects:**
* Todo app
* Blog with markdown
* Contact form
* Weather widget
❌ **Avoid for first time:**
* Real-time collaboration
* Payment processing
* Complex authentication
#### 2. Be Specific in Your Product Spec
The more specific your requirements, the better agentful understands:
**For simple projects (PRODUCT.md):**
**Vague:**
```markdown
## Features
1. User management
```
**Specific:**
```markdown
### 1. User Registration - CRITICAL
**Description**: Users can register with email/password
**Acceptance Criteria**:
- [ ] Email validation (required, valid format)
- [ ] Password min 8 characters, 1 uppercase, 1 number
- [ ] Unique email check
- [ ] Success: redirect to dashboard
- [ ] Error: show inline error message
```
**For complex projects (.claude/product/):**
**Vague:**
```markdown
# .claude/product/domains/users.md
## Features
1. Registration
```
**Specific:**
```markdown
# .claude/product/domains/users.md
## Features
### 1. User Registration - CRITICAL
**Description**: Users can register with email/password
**Acceptance Criteria**:
- [ ] Email validation (required, valid format)
- [ ] Password min 8 characters, 1 uppercase, 1 number
- [ ] Unique email check
- [ ] Success: redirect to dashboard
- [ ] Error: show inline error message
```
#### 3. Use Priority Levels
Order features by priority:
```markdown
### 1. Core feature - CRITICAL
### 2. Important feature - HIGH
### 3. Nice to have - MEDIUM
### 4. Future enhancement - LOW
```
agentful works CRITICAL → HIGH → MEDIUM → LOW
#### 4. Let It Run
Don't micromanage. agentful works best when you:
✅ **Do:**
* Start it and let it run
* Check in periodically with `/agentful-status`
* Answer decisions when prompted
* Review code at milestones
❌ **Don't:**
* Interrupt after every file
* Change your product spec mid-development
* Manually edit files agentful created
* Stop and start repeatedly
> **Switching structures?** You can change between flat (`PRODUCT.md`) and hierarchical (`.claude/product/`) anytime. agentful auto-detects the change.
#### 5. Use 24/7 Mode for Big Projects
For complex projects, use Ralph Wiggum loops:
```bash
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
```
Let it run overnight, wake up to progress.
***
### What to Expect
#### Timeline Examples
**Simple Project (Todo App)**
* 5-10 minutes
* 3-5 iterations
* 1-2 features
**Medium Project (Blog)**
* 30-60 minutes
* 10-20 iterations
* 5-10 features
**Complex Project (SaaS MVP)**
* 2-4 hours (or overnight with Ralph)
* 50-100 iterations
* 10-20 features
#### Quality Expectations
agentful aims for:
* ✅ All tests passing
* ✅ No type errors (adapts to stack)
* ✅ 80%+ test coverage
* ✅ No dead code
* ✅ No security issues
**Note:** Code may need refactoring for production. agentful builds working MVPs, not production-optimized code.
***
### Troubleshooting
#### Issue: agentful seems stuck
**Solution:** Check status
```
/agentful-status
```
If iterations > 20 without progress:
1. Check for pending decisions
2. Run `/agentful-decide`
3. Or restart: `/agentful-start`
#### Issue: Not making progress on features
**Solution:** Review PRODUCT.md
* Are acceptance criteria clear?
* Is tech stack specified?
* Try breaking features into smaller chunks
#### Issue: Too many validation errors
**Solution:** Let Fixer work
* agentful will auto-fix most issues
* If stuck, run `/agentful-validate` to see specific errors
* Some errors may require manual intervention
***
### Next Steps
#### Build Your First Project
Create a complete autonomous project
→ [First Project Guide](/getting-started/first-project)
#### Configuration
Customize agentful for your needs
→ [Configuration Guide](/getting-started/configuration)
***
### Quick Reference
**Essential Commands:**
* `/agentful-start` - Begin autonomous development
* `/agentful-status` - Check progress
* `/agentful-decide` - Answer decisions
* `/agentful-validate` - Run quality checks
**Key Files:**
* `PRODUCT.md` - Your product spec (simple structure)
* `.claude/product/index.md` - Main product spec (hierarchical structure)
* `.claude/product/domains/*.md` - Domain-specific specs (hierarchical structure)
* `CLAUDE.md` - Project instructions
* `.agentful/state.json` - Current state
* `.agentful/completion.json` - Progress tracking
**Choose Your Structure:**
* **Simple**: Create `PRODUCT.md` in project root
* **Complex**: Use `.claude/product/` with domain files
* **Switch anytime**: agentful auto-detects both
**24/7 Development:**
```bash
/ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE"
```
## REST API Service
A production-ready REST API for an e-commerce platform with user management, product catalog, order processing, and comprehensive testing.
***
### Overview
**ShopAPI** is a backend-only REST API service that powers e-commerce applications. Built with Node.js, Express, and TypeScript, following clean architecture principles with comprehensive testing and documentation.
#### Business Value
* **Target Users**: E-commerce platforms, marketplaces, online stores
* **Key Problem**: Need a scalable, well-tested backend for online sales
* **Solution**: RESTful API with clean architecture and 90%+ test coverage
#### Key Features
* ✅ Clean architecture (Repository → Service → Controller)
* ✅ JWT authentication with role-based access
* ✅ Product catalog with categories and search
* ✅ Order processing with status tracking
* ✅ Input validation with Zod schemas
* ✅ API documentation with Swagger
* ✅ Comprehensive error handling
* ✅ 90% test coverage
* ✅ Rate limiting and security
***
### Complete PRODUCT.md
````markdown
# ShopAPI - E-commerce REST API
## Overview
A production-ready REST API for e-commerce platforms. Provides endpoints for user management, product catalog, order processing, and payment integration. Built with clean architecture patterns and comprehensive testing.
## Tech Stack
- **Runtime**: Node.js 20 LTS
- **Framework**: Express.js 4.x
- **Language**: TypeScript 5.x (strict mode)
- **Database**: PostgreSQL 15
- **ORM**: Prisma 5.x
- **Authentication**: JWT (jsonwebtoken)
- **Validation**: Zod 3.x
- **Testing**: Jest 29.x, Supertest
- **Documentation**: Swagger/OpenAPI 3.0
- **Security**: Helmet, CORS, express-rate-limit
- **Code Quality**: ESLint, Prettier
## Features
This API demonstrates HIERARCHICAL structure optimized for REST services.
Features organized by API resource domain:
- .claude/product/domains/users/
- .claude/product/domains/products/
- .claude/product/domains/orders/
This mirrors REST resource organization and scales for large APIs.
### Domain: Users
#### User Registration - CRITICAL
**Priority**: CRITICAL
**Description**: Register new customer accounts
**User Stories**:
- As a new user, I can register an account with email and password
**Acceptance Criteria**:
- Passwords hashed with bcrypt (10 rounds)
- Email must be unique
- Default role: Customer
- Returns JWT token on successful registration
**API Endpoint**:
- POST /api/auth/register
**Implementation**:
- Repository: UserRepository
- Service: AuthService.register()
- Controller: AuthController.register()
- Validation: registerSchema
- Middleware: None (public endpoint)
#### User Login - CRITICAL
**Priority**: CRITICAL
**Description**: Authenticate users and issue JWT tokens
**User Stories**:
- As a registered user, I can login to receive a JWT token
- As an authenticated user, I can access protected endpoints
- As an admin, I have elevated permissions
**Acceptance Criteria**:
- JWT tokens expire after 24 hours
- Refresh tokens available (7 days)
- Roles: Customer, Admin, SuperAdmin
- Protected routes require valid JWT in Authorization header
**API Endpoints**:
- POST /api/auth/login
- POST /api/auth/refresh
**Implementation**:
- Repository: UserRepository
- Service: AuthService.login()
- Controller: AuthController.login()
- Validation: loginSchema
- Middleware: authMiddleware (for protected routes)
#### User Logout - MEDIUM
**Priority**: MEDIUM
**Description**: Invalidate user tokens
**User Stories**:
- As a logged-in user, I can logout securely
**Acceptance Criteria**:
- Add token to blacklist (or use short-lived tokens)
- Clear client-side token storage
**API Endpoint**:
- POST /api/auth/logout
**Implementation**:
- Service: AuthService.logout()
- Controller: AuthController.logout()
#### View Profile - MEDIUM
**Priority**: MEDIUM
**Description**: Users can view their profile information
**User Stories**:
- As a user, I can view my profile information
**Acceptance Criteria**:
- Returns user's name, email, role
- Requires authentication
**API Endpoint**:
- GET /api/users/me
**Implementation**:
- Repository: UserRepository
- Service: UserService.getProfile()
- Controller: UserController.getProfile()
- Middleware: authMiddleware
#### Update Profile - LOW
**Priority**: LOW
**Description**: Users can update their account details
**User Stories**:
- As a user, I can update my name and email
**Acceptance Criteria**:
- Users can update name and email
- Email changes require verification
- Email must remain unique
**API Endpoint**:
- PUT /api/users/me
**Implementation**:
- Repository: UserRepository
- Service: UserService.updateProfile()
- Controller: UserController.updateProfile()
- Validation: updateProfileSchema
- Middleware: authMiddleware
#### Admin: List All Users - LOW
**Priority**: LOW
**Description**: Admin can view all user accounts
**User Stories**:
- As an admin, I can view all user accounts with pagination
**Acceptance Criteria**:
- Admin can list all users with pagination
- Shows email, name, role, created date
- Requires Admin or SuperAdmin role
**API Endpoint**:
- GET /api/admin/users
**Implementation**:
- Repository: UserRepository
- Service: UserService.listUsers()
- Controller: UserController.listUsers()
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Delete User - LOW
**Priority**: LOW
**Description**: Admin can delete user accounts
**User Stories**:
- As an admin, I can delete user accounts
**Acceptance Criteria**:
- Soft delete for user accounts
- Requires Admin or SuperAdmin role
**API Endpoint**:
- DELETE /api/admin/users/:id
**Implementation**:
- Repository: UserRepository
- Service: UserService.deleteUser()
- Controller: UserController.deleteUser()
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
### Domain: Products
#### List Products - HIGH
**Priority**: HIGH
**Description**: Browse and filter product catalog
**User Stories**:
- As a customer, I can browse all products
- As a customer, I can search products by name
- As a customer, I can filter products by category and price
**Acceptance Criteria**:
- Products have name, description, price, stock, category
- Pagination support (default 20 per page, max 100)
- Full-text search on name and description
- Category filtering
- Price range filtering (minPrice, maxPrice)
- Sorting by price, name, createdAt
**API Endpoints**:
- GET /api/products (list with filters)
- GET /api/products/search/:query
**Implementation**:
- Repository: ProductRepository
- Service: ProductService.getProducts()
- Controller: ProductController.getProducts()
- Validation: productQuerySchema
- Performance: Indexed database queries
#### Get Product Details - HIGH
**Priority**: HIGH
**Description**: View detailed information for a single product
**User Stories**:
- As a customer, I can view detailed product information
**Acceptance Criteria**:
- Returns product with category details
- 404 if product not found
**API Endpoint**:
- GET /api/products/:id
**Implementation**:
- Repository: ProductRepository
- Service: ProductService.getProductById()
- Controller: ProductController.getProductById()
#### Admin: Create Product - HIGH
**Priority**: HIGH
**Description**: Admin can add new products to catalog
**User Stories**:
- As an admin, I can create new products
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Stock validation (cannot be negative)
- Price must be positive
- Category must exist
**API Endpoint**:
- POST /api/products
**Implementation**:
- Repository: ProductRepository, CategoryRepository
- Service: ProductService.createProduct()
- Controller: ProductController.createProduct()
- Validation: productSchema
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Update Product - HIGH
**Priority**: HIGH
**Description**: Admin can modify product information
**User Stories**:
- As an admin, I can update product details
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Same validation as create
**API Endpoint**:
- PUT /api/products/:id
**Implementation**:
- Repository: ProductRepository, CategoryRepository
- Service: ProductService.updateProduct()
- Controller: ProductController.updateProduct()
- Validation: productSchema
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Delete Product - MEDIUM
**Priority**: MEDIUM
**Description**: Admin can remove products from catalog
**User Stories**:
- As an admin, I can delete products
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Check if product is referenced in orders (optionally prevent)
**API Endpoint**:
- DELETE /api/products/:id
**Implementation**:
- Repository: ProductRepository
- Service: ProductService.deleteProduct()
- Controller: ProductController.deleteProduct()
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### List Categories - MEDIUM
**Priority**: MEDIUM
**Description**: View all product categories
**User Stories**:
- As a customer, I can browse products by category
**Acceptance Criteria**:
- Returns flat list or nested structure
- Includes product count per category
**API Endpoint**:
- GET /api/categories
**Implementation**:
- Repository: CategoryRepository
- Service: CategoryService.getCategories()
- Controller: CategoryController.getCategories()
#### Admin: Create Category - MEDIUM
**Priority**: MEDIUM
**Description**: Admin can create product categories
**User Stories**:
- As an admin, I can create product categories
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Categories have name, description, parent category (optional)
- Support nested categories (max 2 levels)
- Soft delete for categories
**API Endpoint**:
- POST /api/categories
**Implementation**:
- Repository: CategoryRepository
- Service: CategoryService.createCategory()
- Controller: CategoryController.createCategory()
- Validation: categorySchema
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Update Category - MEDIUM
**Priority**: MEDIUM
**Description**: Admin can modify category details
**User Stories**:
- As an admin, I can update category details
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
**Cannot create circular references in parent category
**API Endpoint**:
- PUT /api/categories/:id
**Implementation**:
- Repository: CategoryRepository
- Service: CategoryService.updateCategory()
- Controller: CategoryController.updateCategory()
- Validation: categorySchema
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Delete Category - LOW
**Priority**: LOW
**Description**: Admin can remove categories
**User Stories**:
- As an admin, I can delete categories
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Soft delete
- Cannot delete if products reference it
**API Endpoint**:
- DELETE /api/categories/:id
**Implementation**:
- Repository: CategoryRepository
- Service: CategoryService.deleteCategory()
- Controller: CategoryController.deleteCategory()
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
### Domain: Orders
#### Create Order - HIGH
**Priority**: HIGH
**Description**: Customers can create orders with multiple items
**User Stories**:
- As a customer, I can create an order with multiple items
**Acceptance Criteria**:
- Orders have multiple items (quantity, price at purchase)
- Stock validation before order creation
- Order total calculation
- Atomic transaction (all items succeed or all fail)
**API Endpoint**:
- POST /api/orders
**Implementation**:
- Repository: OrderRepository, OrderItemRepository, ProductRepository
- Service: OrderService.createOrder()
- Controller: OrderController.createOrder()
- Validation: createOrderSchema
- Business Logic: Transaction handling for stock updates
- Middleware: authMiddleware
#### View My Orders - HIGH
**Priority**: HIGH
**Description**: Customers can view their order history
**User Stories**:
- As a customer, I can view my order history
**Acceptance Criteria**:
- Customer can only see their own orders
- Pagination support
- Ordered by date descending
**API Endpoint**:
- GET /api/orders
**Implementation**:
- Repository: OrderRepository
- Service: OrderService.getCustomerOrders()
- Controller: OrderController.getCustomerOrders()
- Middleware: authMiddleware
#### View Order Details - HIGH
**Priority**: HIGH
**Description**: View detailed information for a specific order
**User Stories**:
- As a customer, I can view detailed order information
**Acceptance Criteria**:
- Customer can only view their own orders
- Includes all order items with product details
**API Endpoint**:
- GET /api/orders/:id
**Implementation**:
- Repository: OrderRepository
- Service: OrderService.getOrderById()
- Controller: OrderController.getOrderById()
- Middleware: authMiddleware
#### Admin: List All Orders - MEDIUM
**Priority**: MEDIUM
**Description**: Admin can view all orders
**User Stories**:
- As an admin, I can view all orders
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Filter by status, customer, date range
- Pagination support
**API Endpoint**:
- GET /api/admin/orders
**Implementation**:
- Repository: OrderRepository
- Service: OrderService.getAllOrders()
- Controller: OrderController.getAllOrders()
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Admin: Update Order Status - MEDIUM
**Priority**: MEDIUM
**Description**: Admin can update order status
**User Stories**:
- As an admin, I can update order status
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Order status: Pending, Processing, Shipped, Delivered, Cancelled
- Status transition validation
**API Endpoint**:
- PATCH /api/admin/orders/:id/status
**Implementation**:
- Repository: OrderRepository
- Service: OrderService.updateOrderStatus()
- Controller: OrderController.updateOrderStatus()
- Validation: updateOrderStatusSchema
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
#### Process Payment - LOW
**Priority**: LOW
**Description**: Integrate payment processing (placeholder)
**User Stories**:
- As a customer, I can add payment info to orders
**Acceptance Criteria**:
- Support for Stripe/PayPal integration
- Payment status tracking
- Webhook handling for payment updates
**API Endpoints**:
- POST /api/orders/:id/payment
- POST /api/webhooks/payments
**Implementation**:
- Service: PaymentService (adapter pattern)
- Controller: PaymentController
- Validation: paymentSchema
#### Process Refund - LOW
**Priority**: LOW
**Description**: Admin can process refunds
**User Stories**:
- As an admin, I can process refunds
**Acceptance Criteria**:
- Requires Admin or SuperAdmin role
- Restores stock if applicable
**API Endpoint**:
- POST /api/orders/:id/refund
**Implementation**:
- Service: PaymentService
- Controller: PaymentController
- Middleware: authMiddleware, roleMiddleware(['ADMIN', 'SUPERADMIN'])
### Domain: Developer Experience
#### API Documentation - MEDIUM
**Priority**: MEDIUM
**Description**: Self-documenting API with Swagger
**User Stories**:
- As a developer, I can view API documentation at /api-docs
- As a developer, I can try endpoints directly from docs
**Acceptance Criteria**:
- All endpoints documented with OpenAPI 3.0
- Request/response schemas shown
- Authentication examples provided
- Error responses documented
**Implementation**:
- Swagger UI middleware
- JSDoc comments for routes
- YAML/OpenAPI spec file
## Non-Functional Requirements
### Performance
- API response time < 100ms (p95) for simple queries
- Support 1000+ concurrent requests
- Database connection pooling (max 10 connections)
- Redis caching for product listings (optional)
### Security
- Helmet middleware for security headers
- CORS configured for specific origins
- Rate limiting: 100 requests per 15 minutes per IP
- Input sanitization (Zod validation)
- SQL injection prevention (Prisma)
- XSS prevention
- File upload limits (1MB max)
- Environment variable validation
### Reliability
- Graceful error handling
- Proper HTTP status codes
- Request logging (morgan)
- Health check endpoint
- Database transaction rollback on errors
- No sensitive data in logs
### Maintainability
- Clean architecture (layers separation)
- Dependency injection pattern
- Interface-based repositories
- Comprehensive test coverage (≥80%)
- ESLint and Prettier configured
- Meaningful error messages
## Database Schema
```prisma
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}
model User {
id String @id @default(cuid())
email String @unique
password String
name String
role UserRole @default(CUSTOMER)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
orders Order[]
}
model Category {
id String @id @default(cuid())
name String @unique
description String?
parentId String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
parent Category? @relation("CategoryHierarchy", fields: [parentId], references: [id], onDelete: SetNull)
children Category[] @relation("CategoryHierarchy")
products Product[]
}
model Product {
id String @id @default(cuid())
name String
description String?
price Decimal @db.Decimal(10, 2)
stock Int @default(0)
categoryId String
images String[] @default([])
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
category Category @relation(fields: [categoryId], references: [id], onDelete: Restrict)
orderItems OrderItem[]
}
model Order {
id String @id @default(cuid())
userId String
status OrderStatus @default(PENDING)
total Decimal @db.Decimal(10, 2)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
items OrderItem[]
}
model OrderItem {
id String @id @default(cuid())
orderId String
productId String
quantity Int
price Decimal @db.Decimal(10, 2)
order Order @relation(fields: [orderId], references: [id], onDelete: Cascade)
product Product @relation(fields: [productId], references: [id], onDelete: Restrict)
@@unique([orderId, productId])
}
enum UserRole {
CUSTOMER
ADMIN
SUPERADMIN
}
enum OrderStatus {
PENDING
PROCESSING
SHIPPED
DELIVERED
CANCELLED
}
````
### API Documentation Structure
#### Base URL
```
Development: http://localhost:3000/api
Production: https://api.shopapi.com/v1
```
#### Authentication
Most endpoints require JWT token in Authorization header:
```
Authorization: Bearer
```
#### Response Format
Success:
```json
{
"success": true,
"data": { ... }
}
```
Error:
```json
{
"success": false,
"error": {
"message": "Error description",
"code": "ERROR_CODE"
}
}
```
### Success Criteria
1. All CRITICAL and HIGH priority features implemented
2. All endpoints documented with Swagger
3. Test coverage ≥ 80%
4. All endpoints return proper HTTP status codes
5. Rate limiting configured and tested
6. Security audit passed (no vulnerabilities)
7. API response time \< 100ms (p95)
8. Health check endpoint functional
### Notes
* Follow repository → service → controller pattern strictly
* All async errors must be handled
* Use Prisma transactions for multi-step operations
* Log all API requests with morgan
* Validate all inputs with Zod schemas
* Write tests before implementation (TDD preferred)
* Document complex business logic with comments
```
---
## Project Structure
### Initial State
```
shopapi/
├── package.json
└── tsconfig.json
```
### Final State
**Hierarchical PRODUCT.md Structure**:
```
shopapi/
├── .claude/
│ ├── agents/
│ ├── commands/
│ ├── skills/
│ └── product/
│ ├── overview\.md # Project overview, tech stack
│ ├── domains/ # HIERARCHICAL: Organized by API resource
│ │ ├── users/
│ │ │ ├── index.md # Users domain overview
│ │ │ ├── registration.md
│ │ │ ├── login.md
│ │ │ ├── logout.md
│ │ │ ├── view-profile.md
│ │ │ ├── update-profile.md
│ │ │ ├── list-users.md
│ │ │ └── delete-user.md
│ │ ├── products/
│ │ │ ├── index.md # Products domain overview
│ │ │ ├── list-products.md
│ │ │ ├── get-product.md
│ │ │ ├── create-product.md
│ │ │ ├── update-product.md
│ │ │ ├── delete-product.md
│ │ │ ├── list-categories.md
│ │ │ ├── create-category.md
│ │ │ ├── update-category.md
│ │ │ └── delete-category.md
│ │ ├── orders/
│ │ │ ├── index.md # Orders domain overview
│ │ │ ├── create-order.md
│ │ │ ├── view-orders.md
│ │ │ ├── view-order-details.md
│ │ │ ├── list-all-orders.md
│ │ │ ├── update-status.md
│ │ │ ├── process-payment.md
│ │ │ └── process-refund.md
│ │ └── developer-experience/
│ │ └── api-documentation.md
│ ├── non-functional.md # Performance, security, etc.
│ └── database-schema.md # Prisma schema
├── .agentful/
│ ├── state.json
│ ├── completion.json
│ └── decisions.json
├── CLAUDE.md
├── prisma/
│ ├── schema.prisma
│ └── migrations/
│ └── 20240118\_init/
│ └── migration.sql
├── src/
│ ├── index.ts # App entry point
│ ├── app.ts # Express app setup
│ ├── config/
│ │ ├── database.ts # Prisma client
│ │ ├── jwt.ts # JWT config
│ │ └── rate-limit.ts # Rate limiting config
│ ├── controllers/ # Request handlers
│ │ ├── auth.controller.ts
│ │ ├── user.controller.ts
│ │ ├── product.controller.ts
│ │ ├── category.controller.ts
│ │ ├── order.controller.ts
│ │ └── payment.controller.ts
│ ├── services/ # Business logic
│ │ ├── auth.service.ts
│ │ ├── user.service.ts
│ │ ├── product.service.ts
│ │ ├── category.service.ts
│ │ ├── order.service.ts
│ │ └── payment.service.ts
│ ├── repositories/ # Data access
│ │ ├── user.repository.ts
│ │ ├── product.repository.ts
│ │ ├── category.repository.ts
│ │ ├── order.repository.ts
│ │ └── order-item.repository.ts
│ ├── middleware/ # Express middleware
│ │ ├── auth.middleware.ts
│ │ ├── role.middleware.ts
│ │ ├── error.middleware.ts
│ │ └── validation.middleware.ts
│ ├── routes/ # Route definitions
│ │ ├── index.ts
│ │ ├── auth.routes.ts
│ │ ├── user.routes.ts
│ │ ├── product.routes.ts
│ │ ├── category.routes.ts
│ │ ├── order.routes.ts
│ │ └── payment.routes.ts
│ ├── schemas/ # Zod validation schemas
│ │ ├── auth.schema.ts
│ │ ├── user.schema.ts
│ │ ├── product.schema.ts
│ │ ├── category.schema.ts
│ │ ├── order.schema.ts
│ │ └── payment.schema.ts
│ ├── types/ # TypeScript types
│ │ ├── auth.types.ts
│ │ ├── user.types.ts
│ │ ├── product.types.ts
│ │ ├── order.types.ts
│ │ └── express.d.ts # Extended Express types
│ ├── utils/ # Utility functions
│ │ ├── logger.ts
│ │ ├── error.ts # Custom error classes
│ │ └── async-handler.ts # Async error wrapper
│ └── constants/
│ ├── http-status.ts # HTTP status codes
│ └── error-codes.ts # Error code constants
├── tests/
│ ├── unit/
│ │ ├── services/
│ │ │ ├── auth.service.test.ts
│ │ │ ├── user.service.test.ts
│ │ │ ├── product.service.test.ts
│ │ │ ├── order.service.test.ts
│ │ │ └── payment.service.test.ts
│ │ └── repositories/
│ │ └── product.repository.test.ts
│ ├── integration/
│ │ ├── api/
│ │ │ ├── auth.test.ts
│ │ │ ├── users.test.ts
│ │ │ ├── products.test.ts
│ │ │ ├── orders.test.ts
│ │ │ └── payments.test.ts
│ │ └── database/
│ │ └── transactions.test.ts
│ └── fixtures/
│ ├── test-data.ts # Test data factories
│ └── setup.ts # Test setup/teardown
├── docs/
│ └── swagger.json # OpenAPI specification
├── .env.example
├── .env.test
├── .eslintrc.js
├── .prettierrc
├── jest.config.js
├── package.json
└── tsconfig.json
````
**Why Hierarchical for APIs?**
For REST APIs, organizing features by resource domain (users, products, orders) is ideal:
- Mirrors REST resource organization
- Each domain = logical API resource group
- Easy to assign different teams to different resources
- Scales to dozens of endpoints without confusion
- Clear separation of concerns (e.g., user domain handles all /api/users/* endpoints)
**File Count**: 87 files
**Lines of Code**: ~6,200 lines
**Test Coverage**: 91%
---
## Implementation Details
## Phase 1: Project Setup
### Phase 1: Project Setup (20 minutes)
#### Initialize Project
```bash
mkdir shopapi && cd shopapi
npm init -y
# Install core dependencies
npm install express cors helmet morgan dotenv
npm install prisma @prisma/client
npm install jsonwebtoken bcryptjs zod
# Install dev dependencies
npm install -D typescript @types/node @types/express
npm install -D @types/cors @types/jsonwebtoken @types/bcryptjs
npm install -D ts-node nodemon jest ts-jest
npm install -D @types/jest supertest
npm install -D eslint prettier
# Initialize TypeScript
npx tsc --init
# Initialize agentful
npx @itz4blitz/agentful init
````
##### Configure TypeScript
**tsconfig.json**:
```json
{
"compilerOptions": {
"target": "ES2022",
"module": "commonjs",
"lib": ["ES2022"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node",
"types": ["node", "jest"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests"]
}
```
##### Configure Package Scripts
**package.json**:
```json
{
"scripts": {
"dev": "nodemon src/index.ts",
"build": "tsc",
"start": "node dist/index.js",
"test": "jest --coverage",
"test:watch": "jest --watch",
"prisma:generate": "prisma generate",
"prisma:migrate": "prisma migrate dev",
"prisma:studio": "prisma studio",
"lint": "eslint src --ext .ts",
"lint:fix": "eslint src --ext .ts --fix",
"format": "prettier --write \"src/**/*.ts\""
}
}
```
***
### Phase 2: Clean Architecture
#### Phase 2: Clean Architecture Implementation
agentful strictly follows the layered architecture pattern. Here's how it implements each layer:
##### Layer 1: Repository Layer (Data Access)
**src/repositories/product.repository.ts**:
```typescript
import { PrismaClient, Product, Prisma } from '@prisma/client';
import { prisma } from '../config/database';
export class ProductRepository {
/**
* Find product by ID
*/
async findById(id: string): Promise {
return prisma.product.findUnique({
where: { id },
include: { category: true },
});
}
/**
* Find all products with filters
*/
async findAll(params: {
skip?: number;
take?: number;
where?: Prisma.ProductWhereInput;
orderBy?: Prisma.ProductOrderByWithRelationInput;
}): Promise {
const { skip = 0, take = 20, where, orderBy } = params;
return prisma.product.findMany({
skip,
take,
where,
orderBy: orderBy || { createdAt: 'desc' },
include: { category: true },
});
}
/**
* Count products matching criteria
*/
async count(where?: Prisma.ProductWhereInput): Promise {
return prisma.product.count({ where });
}
/**
* Create new product
*/
async create(data: Prisma.ProductCreateInput): Promise {
return prisma.product.create({
data,
include: { category: true },
});
}
/**
* Update product
*/
async update(id: string, data: Prisma.ProductUpdateInput): Promise {
return prisma.product.update({
where: { id },
data,
include: { category: true },
});
}
/**
* Delete product
*/
async delete(id: string): Promise {
return prisma.product.delete({
where: { id },
});
}
/**
* Check if product exists
*/
async exists(id: string): Promise {
const count = await prisma.product.count({ where: { id } });
return count > 0;
}
/**
* Update product stock
*/
async updateStock(id: string, quantity: number): Promise {
return prisma.product.update({
where: { id },
data: { stock: { increment: quantity } },
});
}
/**
* Search products by name or description
*/
async search(query: string, limit: number = 20): Promise {
return prisma.product.findMany({
where: {
OR: [
{ name: { contains: query, mode: 'insensitive' } },
{ description: { contains: query, mode: 'insensitive' } },
],
},
take: limit,
include: { category: true },
});
}
}
```
##### Layer 2: Service Layer (Business Logic)
**src/services/product.service.ts**:
```typescript
import { ProductRepository } from '../repositories/product.repository';
import { CategoryRepository } from '../repositories/category.repository';
import { ConflictError, NotFoundError, ValidationError } from '../utils/error';
import { Decimal } from '@prisma/client/runtime/library';
export interface CreateProductInput {
name: string;
description?: string;
price: number;
stock: number;
categoryId: string;
images?: string[];
}
export interface UpdateProductInput {
name?: string;
description?: string;
price?: number;
stock?: number;
categoryId?: string;
images?: string[];
}
export interface ProductQueryParams {
page?: number;
limit?: number;
categoryId?: string;
minPrice?: number;
maxPrice?: number;
search?: string;
sortBy?: 'price' | 'name' | 'createdAt';
sortOrder?: 'asc' | 'desc';
}
export class ProductService {
private productRepo: ProductRepository;
private categoryRepo: CategoryRepository;
constructor() {
this.productRepo = new ProductRepository();
this.categoryRepo = new CategoryRepository();
}
/**
* Get paginated list of products
*/
async getProducts(query: ProductQueryParams) {
const page = query.page || 1;
const limit = Math.min(query.limit || 20, 100); // Max 100 per page
const skip = (page - 1) * limit;
// Build where clause
const where: any = {};
if (query.categoryId) {
where.categoryId = query.categoryId;
}
if (query.minPrice !== undefined || query.maxPrice !== undefined) {
where.price = {};
if (query.minPrice !== undefined) where.price.gte = query.minPrice;
if (query.maxPrice !== undefined) where.price.lte = query.maxPrice;
}
if (query.search) {
where.OR = [
{ name: { contains: query.search, mode: 'insensitive' } },
{ description: { contains: query.search, mode: 'insensitive' } },
];
}
// Build order by
const orderBy: any = {};
if (query.sortBy) {
orderBy[query.sortBy] = query.sortOrder || 'asc';
} else {
orderBy.createdAt = 'desc';
}
// Fetch products and total count
const [products, total] = await Promise.all([
this.productRepo.findAll({ skip, take: limit, where, orderBy }),
this.productRepo.count(where),
]);
return {
data: products,
pagination: {
page,
limit,
total,
totalPages: Math.ceil(total / limit),
},
};
}
/**
* Get single product by ID
*/
async getProductById(id: string) {
const product = await this.productRepo.findById(id);
if (!product) {
throw new NotFoundError('Product not found');
}
return product;
}
/**
* Create new product
*/
async createProduct(input: CreateProductInput) {
// Validate category exists
const category = await this.categoryRepo.findById(input.categoryId);
if (!category) {
throw new NotFoundError('Category not found');
}
// Validate price
if (input.price <= 0) {
throw new ValidationError('Price must be greater than 0');
}
// Validate stock
if (input.stock < 0) {
throw new ValidationError('Stock cannot be negative');
}
// Create product
const product = await this.productRepo.create({
name: input.name,
description: input.description,
price: input.price,
stock: input.stock,
categoryId: input.categoryId,
images: input.images || [],
});
return product;
}
/**
* Update product
*/
async updateProduct(id: string, input: UpdateProductInput) {
// Check if product exists
const existing = await this.productRepo.findById(id);
if (!existing) {
throw new NotFoundError('Product not found');
}
// Validate category if provided
if (input.categoryId) {
const category = await this.categoryRepo.findById(input.categoryId);
if (!category) {
throw new NotFoundError('Category not found');
}
}
// Validate price if provided
if (input.price !== undefined && input.price <= 0) {
throw new ValidationError('Price must be greater than 0');
}
// Validate stock if provided
if (input.stock !== undefined && input.stock < 0) {
throw new ValidationError('Stock cannot be negative');
}
// Update product
const product = await this.productRepo.update(id, input);
return product;
}
/**
* Delete product
*/
async deleteProduct(id: string) {
// Check if product exists
const existing = await this.productRepo.findById(id);
if (!existing) {
throw new NotFoundError('Product not found');
}
// TODO: Check if product is referenced in any orders
// For now, we'll allow deletion
await this.productRepo.delete(id);
return { message: 'Product deleted successfully' };
}
/**
* Search products
*/
async searchProducts(query: string, limit: number = 20) {
if (!query || query.trim().length < 2) {
throw new ValidationError('Search query must be at least 2 characters');
}
const products = await this.productRepo.search(query.trim(), limit);
return {
query,
count: products.length,
data: products,
};
}
}
```
##### Layer 3: Controller Layer (HTTP Handlers)
**src/controllers/product.controller.ts**:
```typescript
import { Request, Response, NextFunction } from 'express';
import { ProductService } from '../services/product.service';
import { asyncHandler } from '../utils/async-handler';
import { ProductQueryParams } from '../types/product.types';
export class ProductController {
private productService: ProductService;
constructor() {
this.productService = new ProductService();
}
/**
* GET /api/products
* Get list of products with pagination and filters
*/
getProducts = asyncHandler(async (req: Request, res: Response) => {
const query: ProductQueryParams = {
page: req.query.page ? parseInt(req.query.page as string) : undefined,
limit: req.query.limit ? parseInt(req.query.limit as string) : undefined,
categoryId: req.query.categoryId as string,
minPrice: req.query.minPrice ? parseFloat(req.query.minPrice as string) : undefined,
maxPrice: req.query.maxPrice ? parseFloat(req.query.maxPrice as string) : undefined,
search: req.query.search as string,
sortBy: req.query.sortBy as any,
sortOrder: req.query.sortOrder as any,
};
const result = await this.productService.getProducts(query);
res.json({
success: true,
...result,
});
});
/**
* GET /api/products/:id
* Get single product by ID
*/
getProductById = asyncHandler(async (req: Request, res: Response) => {
const { id } = req.params;
const product = await this.productService.getProductById(id);
res.json({
success: true,
data: product,
});
});
/**
* POST /api/products
* Create new product (admin only)
*/
createProduct = asyncHandler(async (req: Request, res: Response) => {
const input = {
name: req.body.name,
description: req.body.description,
price: req.body.price,
stock: req.body.stock,
categoryId: req.body.categoryId,
images: req.body.images,
};
const product = await this.productService.createProduct(input);
res.status(201).json({
success: true,
data: product,
});
});
/**
* PUT /api/products/:id
* Update product (admin only)
*/
updateProduct = asyncHandler(async (req: Request, res: Response) => {
const { id } = req.params;
const input = {
name: req.body.name,
description: req.body.description,
price: req.body.price,
stock: req.body.stock,
categoryId: req.body.categoryId,
images: req.body.images,
};
const product = await this.productService.updateProduct(id, input);
res.json({
success: true,
data: product,
});
});
/**
* DELETE /api/products/:id
* Delete product (admin only)
*/
deleteProduct = asyncHandler(async (req: Request, res: Response) => {
const { id } = req.params;
await this.productService.deleteProduct(id);
res.json({
success: true,
message: 'Product deleted successfully',
});
});
/**
* GET /api/products/search/:query
* Search products
*/
searchProducts = asyncHandler(async (req: Request, res: Response) => {
const { query } = req.params;
const limit = req.query.limit ? parseInt(req.query.limit as string) : 20;
const result = await this.productService.searchProducts(query, limit);
res.json({
success: true,
...result,
});
});
}
```
##### Layer 4: Routes (Endpoint Definition)
**src/routes/product.routes.ts**:
```typescript
import { Router } from 'express';
import { ProductController } from '../controllers/product.controller';
import { authenticate, authorize } from '../middleware/auth.middleware';
import { validate } from '../middleware/validation.middleware';
import { productSchema, productQuerySchema } from '../schemas/product.schema';
const router = Router();
const controller = new ProductController();
// Public routes
router.get('/', validate(productQuerySchema, 'query'), controller.getProducts);
router.get('/search/:query', controller.searchProducts);
router.get('/:id', controller.getProductById);
// Admin routes
router.post(
'/',
authenticate,
authorize('ADMIN', 'SUPERADMIN'),
validate(productSchema),
controller.createProduct
);
router.put(
'/:id',
authenticate,
authorize('ADMIN', 'SUPERADMIN'),
validate(productSchema),
controller.updateProduct
);
router.delete(
'/:id',
authenticate,
authorize('ADMIN', 'SUPERADMIN'),
controller.deleteProduct
);
export default router;
```
***
### Phase 3: Testing
#### Phase 3: Comprehensive Testing
agentful achieves 91% test coverage through unit and integration tests.
##### Unit Tests
**tests/unit/services/product.service.test.ts**:
```typescript
import { describe, it, expect, beforeEach, vi } from '@jest/globals';
import { ProductService } from '../../../src/services/product.service';
import { ProductRepository } from '../../../src/repositories/product.repository';
import { CategoryRepository } from '../../../src/repositories/category.repository';
import { NotFoundError, ValidationError } from '../../../src/utils/error';
// Mock repositories
vi.mock('../../../src/repositories/product.repository');
vi.mock('../../../src/repositories/category.repository');
describe('ProductService', () => {
let productService: ProductService;
let mockProductRepo: any;
let mockCategoryRepo: any;
beforeEach(() => {
// Clear all mocks before each test
vi.clearAllMocks();
// Create service instance
productService = new ProductService();
// Get mock instances
mockProductRepo = ProductRepository.prototype;
mockCategoryRepo = CategoryRepository.prototype;
});
describe('getProducts', () => {
it('should return paginated products', async () => {
const mockProducts = [
{ id: '1', name: 'Product 1', price: 10 },
{ id: '2', name: 'Product 2', price: 20 },
];
vi.spyOn(mockProductRepo, 'findAll').mockResolvedValue(mockProducts);
vi.spyOn(mockProductRepo, 'count').mockResolvedValue(2);
const result = await productService.getProducts({ page: 1, limit: 10 });
expect(result.data).toEqual(mockProducts);
expect(result.pagination).toEqual({
page: 1,
limit: 10,
total: 2,
totalPages: 1,
});
});
it('should filter by category', async () => {
vi.spyOn(mockProductRepo, 'findAll').mockResolvedValue([]);
vi.spyOn(mockProductRepo, 'count').mockResolvedValue(0);
await productService.getProducts({ categoryId: 'cat-123' });
expect(mockProductRepo.findAll).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({
categoryId: 'cat-123',
}),
})
);
});
it('should filter by price range', async () => {
vi.spyOn(mockProductRepo, 'findAll').mockResolvedValue([]);
vi.spyOn(mockProductRepo, 'count').mockResolvedValue(0);
await productService.getProducts({ minPrice: 10, maxPrice: 100 });
expect(mockProductRepo.findAll).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({
price: { gte: 10, lte: 100 },
}),
})
);
});
it('should search by name or description', async () => {
vi.spyOn(mockProductRepo, 'findAll').mockResolvedValue([]);
vi.spyOn(mockProductRepo, 'count').mockResolvedValue(0);
await productService.getProducts({ search: 'laptop' });
expect(mockProductRepo.findAll).toHaveBeenCalledWith(
expect.objectContaining({
where: expect.objectContaining({
OR: [
{ name: { contains: 'laptop', mode: 'insensitive' } },
{ description: { contains: 'laptop', mode: 'insensitive' } },
],
}),
})
);
});
});
describe('getProductById', () => {
it('should return product if found', async () => {
const mockProduct = { id: '1', name: 'Product 1', price: 10 };
vi.spyOn(mockProductRepo, 'findById').mockResolvedValue(mockProduct);
const result = await productService.getProductById('1');
expect(result).toEqual(mockProduct);
});
it('should throw NotFoundError if product not found', async () => {
vi.spyOn(mockProductRepo, 'findById').mockResolvedValue(null);
await expect(productService.getProductById('999')).rejects.toThrow(
NotFoundError
);
await expect(productService.getProductById('999')).rejects.toThrow(
'Product not found'
);
});
});
describe('createProduct', () => {
it('should create product with valid input', async () => {
const input = {
name: 'New Product',
price: 99.99,
stock: 10,
categoryId: 'cat-123',
};
const mockCategory = { id: 'cat-123', name: 'Electronics' };
const mockProduct = { id: '1', ...input };
vi.spyOn(mockCategoryRepo, 'findById').mockResolvedValue(mockCategory);
vi.spyOn(mockProductRepo, 'create').mockResolvedValue(mockProduct);
const result = await productService.createProduct(input);
expect(result).toEqual(mockProduct);
expect(mockCategoryRepo.findById).toHaveBeenCalledWith('cat-123');
expect(mockProductRepo.create).toHaveBeenCalled();
});
it('should throw error if category not found', async () => {
const input = {
name: 'New Product',
price: 99.99,
stock: 10,
categoryId: 'invalid-cat',
};
vi.spyOn(mockCategoryRepo, 'findById').mockResolvedValue(null);
await expect(productService.createProduct(input)).rejects.toThrow(
NotFoundError
);
await expect(productService.createProduct(input)).rejects.toThrow(
'Category not found'
);
});
it('should throw error if price is invalid', async () => {
const input = {
name: 'New Product',
price: -10,
stock: 10,
categoryId: 'cat-123',
};
vi.spyOn(mockCategoryRepo, 'findById').mockResolvedValue({ id: 'cat-123' });
await expect(productService.createProduct(input)).rejects.toThrow(
ValidationError
);
await expect(productService.createProduct(input)).rejects.toThrow(
'Price must be greater than 0'
);
});
it('should throw error if stock is negative', async () => {
const input = {
name: 'New Product',
price: 99.99,
stock: -5,
categoryId: 'cat-123',
};
vi.spyOn(mockCategoryRepo, 'findById').mockResolvedValue({ id: 'cat-123' });
await expect(productService.createProduct(input)).rejects.toThrow(
ValidationError
);
await expect(productService.createProduct(input)).rejects.toThrow(
'Stock cannot be negative'
);
});
});
describe('searchProducts', () => {
it('should search products with valid query', async () => {
const mockProducts = [
{ id: '1', name: 'Laptop Pro', description: 'High-end laptop' },
];
vi.spyOn(mockProductRepo, 'search').mockResolvedValue(mockProducts);
const result = await productService.searchProducts('laptop', 20);
expect(result.query).toBe('laptop');
expect(result.count).toBe(1);
expect(result.data).toEqual(mockProducts);
});
it('should throw error if query is too short', async () => {
await expect(productService.searchProducts('a', 20)).rejects.toThrow(
ValidationError
);
await expect(productService.searchProducts('a', 20)).rejects.toThrow(
'Search query must be at least 2 characters'
);
});
it('should trim query string', async () => {
vi.spyOn(mockProductRepo, 'search').mockResolvedValue([]);
await productService.searchProducts(' laptop ', 20);
expect(mockProductRepo.search).toHaveBeenCalledWith('laptop', 20);
});
});
});
```
##### Integration Tests
**tests/integration/api/products.test.ts**:
```typescript
import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
import request from 'supertest';
import { app } from '../../../src/app';
import { prisma } from '../../../src/config/database';
import { generateToken } from '../../../src/config/jwt';
describe('POST /api/products', () => {
let adminToken: string;
let categoryId: string;
beforeAll(async () => {
// Create test category
const category = await prisma.category.create({
data: { name: 'Test Category' },
});
categoryId = category.id;
// Create admin user and get token
const admin = await prisma.user.create({
data: {
email: 'admin@test.com',
password: 'hashed_password',
name: 'Admin',
role: 'ADMIN',
},
});
adminToken = generateToken(admin.id, admin.role);
});
afterAll(async () => {
// Cleanup
await prisma.product.deleteMany({});
await prisma.category.deleteMany({});
await prisma.user.deleteMany({});
});
it('should create product as admin', async () => {
const response = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${adminToken}`)
.send({
name: 'Test Product',
description: 'Test description',
price: 99.99,
stock: 10,
categoryId,
});
expect(response.status).toBe(201);
expect(response.body.success).toBe(true);
expect(response.body.data).toHaveProperty('id');
expect(response.body.data.name).toBe('Test Product');
expect(response.body.data.price).toBe('99.99');
});
it('should require authentication', async () => {
const response = await request(app).post('/api/products').send({
name: 'Test Product',
price: 99.99,
categoryId,
});
expect(response.status).toBe(401);
});
it('should require admin role', async () => {
// Create customer user
const customer = await prisma.user.create({
data: {
email: 'customer@test.com',
password: 'hashed_password',
name: 'Customer',
role: 'CUSTOMER',
},
});
const customerToken = generateToken(customer.id, customer.role);
const response = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${customerToken}`)
.send({
name: 'Test Product',
price: 99.99,
categoryId,
});
expect(response.status).toBe(403);
});
it('should validate required fields', async () => {
const response = await request(app)
.post('/api/products')
.set('Authorization', `Bearer ${adminToken}`)
.send({
name: 'Test Product',
// Missing price, stock, categoryId
});
expect(response.status).toBe(400);
expect(response.body.success).toBe(false);
expect(response.body.error).toHaveProperty('details');
});
});
describe('GET /api/products', () => {
let products: any[];
beforeAll(async () => {
// Create test data
const category = await prisma.category.create({
data: { name: 'Electronics' },
});
products = await Promise.all([
prisma.product.create({
data: {
name: 'Laptop',
price: 999.99,
stock: 10,
categoryId: category.id,
},
}),
prisma.product.create({
data: {
name: 'Mouse',
price: 29.99,
stock: 50,
categoryId: category.id,
},
}),
]);
});
afterAll(async () => {
await prisma.product.deleteMany({});
await prisma.category.deleteMany({});
});
it('should return list of products', async () => {
const response = await request(app).get('/api/products');
expect(response.status).toBe(200);
expect(response.body.success).toBe(true);
expect(response.body.data).toHaveLength(2);
expect(response.body.pagination).toHaveProperty('total');
});
it('should support pagination', async () => {
const response = await request(app).get('/api/products?page=1&limit=1');
expect(response.status).toBe(200);
expect(response.body.data).toHaveLength(1);
expect(response.body.pagination.page).toBe(1);
expect(response.body.pagination.limit).toBe(1);
});
it('should filter by category', async () => {
const response = await request(app)
.get('/api/products')
.query({ categoryId: products[0].categoryId });
expect(response.status).toBe(200);
expect(response.body.data.length).toBeGreaterThan(0);
});
it('should filter by price range', async () => {
const response = await request(app)
.get('/api/products')
.query({ minPrice: 50, maxPrice: 1000 });
expect(response.status).toBe(200);
response.body.data.forEach((product: any) => {
const price = parseFloat(product.price);
expect(price).toBeGreaterThanOrEqual(50);
expect(price).toBeLessThanOrEqual(1000);
});
});
});
```
***
***
### Results
#### Development Time
| Phase | Duration | Agent |
| --------------------- | ----------- | ------------------ |
| Project Setup | 20 min | @orchestrator |
| Database Schema | 25 min | @backend |
| Authentication System | 1 hour | @backend + @tester |
| Product Catalog | 1.5 hours | @backend + @tester |
| Order Management | 1 hour | @backend + @tester |
| Category Management | 45 min | @backend + @tester |
| API Documentation | 40 min | @backend |
| **Total** | **5 hours** | |
#### Code Metrics
```
Files Created: 87 files
- Repository layer: 5 files
- Service layer: 5 files
- Controller layer: 4 files
- Routes: 5 files
- Middleware: 4 files
- Schemas: 4 files
- Tests: 38 files
- Configuration: 12 files
Total Lines of Code: ~6,200 lines
- Application code: ~4,100 lines
- Test code: ~2,100 lines
Test Coverage: 91%
- Unit tests: 94% coverage
- Integration tests: 89% coverage
Quality Gates Status:
✅ All tests passing (312 tests)
✅ No type errors (adapts to stack)
✅ No ESLint errors
✅ Coverage threshold met (91% ≥ 80%)
✅ No dead code
✅ No security vulnerabilities
✅ API documentation complete
```
#### API Performance
```
Endpoint Performance (p95):
- GET /api/products: 45ms
- GET /api/products/:id: 12ms
- POST /api/products: 67ms
- PUT /api/products/:id: 58ms
- DELETE /api/products/:id: 34ms
- POST /api/auth/login: 23ms
- POST /api/orders: 89ms
Load Testing:
- 1000 concurrent requests: All successful
- Average response time: 38ms
- Throughput: 26,316 requests/sec
- Error rate: 0%
```
***
### API Documentation
#### Swagger UI Integration
The API includes self-documenting Swagger UI available at `/api-docs`.
**Example Swagger Spec**:
```yaml
openapi: 3.0.0
info:
title: ShopAPI
version: 1.0.0
description: E-commerce REST API
paths:
/api/products:
get:
summary: Get list of products
tags: [Products]
parameters:
- name: page
in: query
schema:
type: integer
default: 1
- name: limit
in: query
schema:
type: integer
default: 20
- name: categoryId
in: query
schema:
type: string
- name: search
in: query
schema:
type: string
responses:
'200':
description: List of products
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
data:
type: array
items:
$ref: '#/components/schemas/Product'
pagination:
$ref: '#/components/schemas/Pagination'
post:
summary: Create new product
tags: [Products]
security:
- bearerAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateProductInput'
responses:
'201':
description: Product created
'401':
description: Unauthorized
'403':
description: Forbidden - Admin only
components:
schemas:
Product:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
price:
type: number
format: decimal
stock:
type: integer
categoryId:
type: string
Pagination:
type: object
properties:
page:
type: integer
limit:
type: integer
total:
type: integer
totalPages:
type: integer
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
```
***
### Key Decisions
#### Decision 1: Database Choice
**Question**: PostgreSQL vs MongoDB?
**Decision**: PostgreSQL
**Reasoning**:
* Relational data fits the domain (users, products, orders)
* ACID transactions critical for orders
* Strong typing with Prisma
* Better for complex queries
#### Decision 2: Architecture Pattern
**Question**: MVC vs Clean Architecture?
**Decision**: Clean Architecture (Repository → Service → Controller)
**Reasoning**:
* Better separation of concerns
* Easier to test (mock repositories)
* More maintainable as codebase grows
* Business logic independent of frameworks
#### Decision 3: Authentication Strategy
**Question**: Session vs JWT?
**Decision**: JWT
**Reasoning**:
* Stateless - no server-side session storage
* Works well for microservices (future scaling)
* Mobile app friendly
* Simple implementation
#### Decision 4: Validation Library
**Question**: Joi vs Zod vs Yup?
**Decision**: Zod
**Reasoning**:
* TypeScript-first (infers types from schemas)
* Zero dependencies
* Better performance
* Excellent error messages
***
### Best Practices Demonstrated
#### 1. Layer Separation
Each layer has a single responsibility:
* **Repository**: Data access only
* **Service**: Business logic only
* **Controller**: HTTP handling only
#### 2. Dependency Injection
Services receive repositories as constructor parameters:
```typescript
constructor(productRepo: ProductRepository) {
this.productRepo = productRepo;
}
```
#### 3. Error Handling
Custom error classes with proper HTTP status codes:
```typescript
export class NotFoundError extends AppError {
constructor(message: string) {
super(message, 404, 'NOT_FOUND');
}
}
```
#### 4. Input Validation
All inputs validated before processing:
```typescript
const validated = productSchema.parse(req.body);
```
#### 5. Transaction Management
Database operations wrapped in transactions:
```typescript
await prisma.$transaction(async (tx) => {
// Multiple operations
// All or nothing
});
```
***
### Conclusion
This API service demonstrates agentful's ability to:
* Build production-grade backends
* Follow clean architecture principles
* Achieve exceptional test coverage (91%)
* Implement comprehensive security
* Create self-documenting APIs
* Deliver in 5 hours (vs 2+ weeks traditionally)
**Perfect for**: Backend-focused projects, microservices, API-first applications
**Previous**: [Full-Stack App Example](/examples/full-stack-app)
**Next**: [Frontend Project Example](/examples/frontend-project)
## Modern Web Application
A stunning frontend-only project built with Next.js 14, featuring a reusable component library, sophisticated state management, and seamless API integration.
***
### Overview
**WeatherDashboard** is a beautiful weather application that provides real-time weather data, forecasts, and historical trends. Built entirely as a frontend project consuming third-party APIs.
#### Business Value
* **Target Users**: General public, weather enthusiasts, travelers
* **Key Problem**: Need a beautiful, fast weather app
* **Solution**: Modern frontend with excellent UX and performance
#### Key Features
* ✅ Component library with 15+ reusable components
* ✅ Zustand state management
* ✅ React Query for server state
* ✅ Beautiful UI with Tailwind CSS
* ✅ Responsive design (mobile-first)
* ✅ Dark mode support
* ✅ Search with debouncing
* ✅ Location-based weather
* ✅ Animated weather icons
* ✅ 7-day forecast
* ✅ Historical weather charts
***
### Complete PRODUCT.md
````markdown
# WeatherDashboard - Modern Weather App
## Overview
A beautiful, responsive weather dashboard that provides current conditions, forecasts, and historical data. Consumes the OpenWeatherMap API for real-time weather data.
## Tech Stack
- **Framework**: Next.js 14 (App Router)
- **Language**: TypeScript 5.x (strict mode)
- **Styling**: Tailwind CSS 3.x
- **State Management**: Zustand
- **Server State**: TanStack Query (React Query)
- **Components**: Custom component library (shadcn/ui style)
- **Icons**: Lucide React
- **Charts**: Recharts
- **Animations**: Framer Motion
- **Forms**: React Hook Form + Zod
- **API**: OpenWeatherMap API
## Features
### Domain 1: Core Weather Data
#### 1.1 Current Weather Display - CRITICAL
**Priority**: CRITICAL
**Description**: Display current weather conditions for a location
**User Stories**:
- As a user, I can see current temperature
- As a user, I can see weather conditions (sunny, rainy, etc.)
- As a user, I can see humidity, wind speed, and pressure
- As a user, I can see a beautiful weather icon
**Acceptance Criteria**:
- Large, readable temperature display
- Animated weather icons
- Metric and imperial unit toggle
- Loading and error states
- Last updated timestamp
**Components**:
- components/weather/CurrentWeather.tsx
- components/weather/WeatherIcon.tsx
- components/weather/WeatherDetails.tsx
**API Integration**:
- GET /weather/current?q={city}
- Response: temp, condition, humidity, wind, pressure
#### 1.2 Weather Forecast - HIGH
**Priority**: HIGH
**Description**: Display weather forecast for the next 7 days
**User Stories**:
- As a user, I can see the weather for the next 7 days
- As a user, I can see high/low temperatures
- As a user, I can see weather conditions for each day
**Acceptance Criteria**:
- Horizontal scrollable list
- Daily high/low temps
- Weather icons for each day
- Day of week labels
- Click on day for detailed view
**Components**:
- components/forecast/ForecastList.tsx
- components/forecast/ForecastDay.tsx
- components/forecast/ForecastDetail.tsx
#### 1.3 Historical Data & Analytics - MEDIUM
**Priority**: MEDIUM
**Description**: Display historical weather data with interactive charts
**User Stories**:
- As a user, I can see temperature trends over time
- As a user, I can compare different metrics
**Acceptance Criteria**:
- Line chart for temperature
- Bar chart for precipitation
- Toggle between time ranges (week, month, year)
- Interactive tooltips
- Responsive chart sizing
**Components**:
- components/charts/TemperatureChart.tsx
- components/charts/PrecipitationChart.tsx
**Library**: Recharts
### Domain 2: Location & Search
#### 2.1 Location Search - HIGH
**Priority**: HIGH
**Description**: Search for weather by city name or zip code
**User Stories**:
- As a user, I can search for a city
- As a user, I see search suggestions as I type
- As a user, I can use my current location
- As a user, I see recent searches
**Acceptance Criteria**:
- Debounced search (300ms delay)
- Autocomplete with suggestions
- Geolocation support
- Recent search history (localStorage)
- Loading state during search
**Components**:
- components/search/SearchBar.tsx
- components/search/SearchSuggestions.tsx
- components/search/RecentSearches.tsx
**Hooks**:
- hooks/useSearch.ts
- hooks/useDebounce.ts
- hooks/useGeolocation.ts
#### 2.2 Favorites Management - LOW
**Priority**: LOW
**Description**: Save favorite locations for quick access
**User Stories**:
- As a user, I can add a location to favorites
- As a user, I can quickly access favorite locations
**Acceptance Criteria**:
- Heart icon to add/remove favorites
- Favorites stored in localStorage
- Quick access from sidebar or header
- Maximum 10 favorites
**Components**:
- components/favorites/FavoriteButton.tsx
- components/favorites/FavoritesList.tsx
**Hooks**:
- hooks/useFavorites.ts
### Domain 3: User Experience & Interface
#### 3.1 Theme System - MEDIUM
**Priority**: MEDIUM
**Description**: Toggle between light and dark themes
**User Stories**:
- As a user, I can switch between light and dark mode
- As a user, the app remembers my preference
**Acceptance Criteria**:
- Toggle button in header
- Smooth transition between themes
- Persists to localStorage
- Respects system preference on first visit
**Implementation**:
- next-themes for theme management
- Tailwind dark: variants
- All components support both themes
#### 3.2 Responsive Design - MEDIUM
**Priority**: MEDIUM
**Description**: Ensure great experience on all devices
**Acceptance Criteria**:
- Mobile-first approach
- Breakpoints: 640px, 768px, 1024px, 1280px
- Touch-friendly targets (44px minimum)
- Optimized for phones, tablets, desktops
**Implementation**:
- Tailwind responsive utilities
- Fluid typography
- Adaptive layouts
## Component Library
### Base Components
- Button (variants: primary, secondary, ghost, danger)
- Input (text, number, search)
- Card (base layout)
- Badge (status indicators)
- Skeleton (loading states)
### Layout Components
- Container (max-width wrapper)
- Grid (responsive grid)
- Flex (flexbox wrapper)
- Separator (divider)
### Feedback Components
- Toast (notifications)
- Alert (inline messages)
- Spinner (loading indicator)
- Empty State (no data)
### Navigation Components
- Tabs (switch between views)
- Pagination (navigate pages)
- Breadcrumbs (navigation path)
## Non-Functional Requirements
### Performance
- Initial page load < 1.5 seconds
- Time to interactive < 2 seconds
- Lighthouse score ≥ 90
- Optimize images (WebP, lazy loading)
- Code splitting by route
### Accessibility
- WCAG 2.1 AA compliant
- Keyboard navigation
- Screen reader support
- ARIA labels
- Focus indicators
- Color contrast ratio ≥ 4.5:1
### Responsive Design
- Mobile-first approach
- Breakpoints: 640px, 768px, 1024px, 1280px
- Touch-friendly targets (44px minimum)
- Optimized for phones, tablets, desktops
### SEO
- Meta tags for each page
- Structured data (JSON-LD)
- Semantic HTML
- Open Graph tags
- Sitemap.xml
## Pages Structure
```text
/ - Home page with current weather
/search?q={city} - Search results page
/favorites - Saved locations
/settings - App settings
/about - About page
````
### API Integration
#### OpenWeatherMap API
**Current Weather**:
```text
GET https://api.openweathermap.org/data/2.5/weather
?q={city name}&appid={API key}&units=metric
```
**Forecast**:
```text
GET https://api.openweathermap.org/data/2.5/forecast
?q={city name}&appid={API key}&units=metric
```
**Geocoding**:
```text
GET https://api.openweathermap.org/geo/1.0/direct
?q={city name}&limit=5&appid={API key}
```
**Response Caching**:
* Current weather: 10 minutes
* Forecast: 30 minutes
* Geocoding: 24 hours
### State Management
#### Zustand Store (Client State)
* Current theme (light/dark)
* User preferences (units, location)
* Search history
* Favorites
#### React Query (Server State)
* Current weather data
* Forecast data
* Historical data
* Automatic refetching
* Caching strategy
### Success Criteria
1. All CRITICAL and HIGH priority features implemented
2. Component library fully documented with Storybook
3. All components support dark mode
4. Responsive on all device sizes
5. Lighthouse performance score ≥ 90
6. Accessibility audit passed
7. TypeScript strict mode (no any types)
8. 80%+ test coverage for components
### Notes
* Build component library first, then features
* Use Storybook for component development
* Implement dark mode from the start (easier than retroactive)
* Focus on micro-interactions and animations
* Use optimistic UI updates where possible
* Implement proper error boundaries
* Add loading states for all async operations
```
---
## Project Structure
### Initial State
```
weather-dashboard/
├── package.json
└── tsconfig.json
```
### Final State
```
weather-dashboard/
├── .claude/
│ ├── agents/
│ └── commands/
├── .agentful/
│ └── state.json
├── PRODUCT.md
├── CLAUDE.md
├── public/
│ ├── images/
│ └── icons/
├── src/
│ ├── app/
│ │ ├── layout.tsx
│ │ ├── page.tsx
│ │ ├── globals.css
│ │ ├── search/
│ │ │ └── page.tsx
│ │ ├── favorites/
│ │ │ └── page.tsx
│ │ └── settings/
│ │ └── page.tsx
│ ├── components/
│ │ ├── ui/ # Reusable component library
│ │ │ ├── button.tsx
│ │ │ ├── input.tsx
│ │ │ ├── card.tsx
│ │ │ ├── badge.tsx
│ │ │ ├── skeleton.tsx
│ │ │ ├── spinner.tsx
│ │ │ ├── toast.tsx
│ │ │ ├── alert.tsx
│ │ │ ├── tabs.tsx
│ │ │ └── index.ts
│ │ ├── layout/
│ │ │ ├── header.tsx
│ │ │ ├── sidebar.tsx
│ │ │ ├── footer.tsx
│ │ │ └── container.tsx
│ │ ├── weather/
│ │ │ ├── current-weather.tsx
│ │ │ ├── weather-icon.tsx
│ │ │ ├── weather-details.tsx
│ │ │ └── temperature-display.tsx
│ │ ├── search/
│ │ │ ├── search-bar.tsx
│ │ │ ├── search-suggestions.tsx
│ │ │ └── recent-searches.tsx
│ │ ├── forecast/
│ │ │ ├── forecast-list.tsx
│ │ │ ├── forecast-day.tsx
│ │ │ └── forecast-detail.tsx
│ │ ├── charts/
│ │ │ ├── temperature-chart.tsx
│ │ │ └── precipitation-chart.tsx
│ │ └── favorites/
│ │ ├── favorite-button.tsx
│ │ └── favorites-list.tsx
│ ├── hooks/
│ │ ├── use-search.ts
│ │ ├── use-debounce.ts
│ │ ├── use-geolocation.ts
│ │ ├── use-favorites.ts
│ │ ├── use-weather.ts
│ │ └── use-units.ts
│ ├── store/
│ │ ├── use-store.ts # Zustand store
│ │ └── slices/
│ │ ├── ui.ts
│ │ ├── weather.ts
│ │ └── favorites.ts
│ ├── lib/
│ │ ├── api.ts # API client
│ │ ├── query-client.ts # React Query setup
│ │ └── utils.ts # Utility functions
│ ├── types/
│ │ ├── weather.ts
│ │ ├── forecast.ts
│ │ └── index.ts
│ └── styles/
│ └── animations.css # Custom animations
├── .env.local
├── next.config.js
├── tailwind.config.js
└── package.json
````
**File Count**: 73 files
**Lines of Code**: ~4,800 lines
**Components**: 27 components
---
## Implementation Details
### Phase 1: Component Library (1 hour)
agentful builds a reusable component library first, following atomic design principles.
#### Base Button Component
**src/components/ui/button.tsx**:
```typescript
import { ButtonHTMLAttributes, forwardRef } from 'react';
import { cn } from '@/lib/utils';
export interface ButtonProps extends ButtonHTMLAttributes {
variant?: 'primary' | 'secondary' | 'ghost' | 'danger';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
fullWidth?: boolean;
}
export const Button = forwardRef(
(
{
children,
variant = 'primary',
size = 'md',
isLoading = false,
fullWidth = false,
disabled,
className,
...props
},
ref
) => {
const baseStyles = 'inline-flex items-center justify-center rounded-lg font-medium transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-offset-2 disabled:opacity-50 disabled:cursor-not-allowed';
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700 focus:ring-blue-500 dark:bg-blue-500 dark:hover:bg-blue-600',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300 focus:ring-gray-500 dark:bg-gray-700 dark:text-gray-100 dark:hover:bg-gray-600',
ghost: 'bg-transparent text-gray-700 hover:bg-gray-100 focus:ring-gray-500 dark:text-gray-300 dark:hover:bg-gray-800',
danger: 'bg-red-600 text-white hover:bg-red-700 focus:ring-red-500 dark:bg-red-500 dark:hover:bg-red-600',
};
const sizes = {
sm: 'px-3 py-1.5 text-sm',
md: 'px-4 py-2 text-base',
lg: 'px-6 py-3 text-lg',
};
const widthClass = fullWidth ? 'w-full' : '';
return (
);
}
);
Button.displayName = 'Button';
````
##### Card Component
**src/components/ui/card.tsx**:
```typescript
import { HTMLAttributes, forwardRef } from 'react';
import { cn } from '@/lib/utils';
export const Card = forwardRef>(
({ className, ...props }, ref) => (
)
);
Card.displayName = 'Card';
export const CardHeader = forwardRef>(
({ className, ...props }, ref) => (
)
);
CardHeader.displayName = 'CardHeader';
export const CardTitle = forwardRef>(
({ className, ...props }, ref) => (
)
);
CardTitle.displayName = 'CardTitle';
export const CardContent = forwardRef>(
({ className, ...props }, ref) => (
)
);
CardContent.displayName = 'CardContent';
```
##### Input Component
**src/components/ui/input.tsx**:
```typescript
import { InputHTMLAttributes, forwardRef } from 'react';
import { cn } from '@/lib/utils';
export interface InputProps extends InputHTMLAttributes {
error?: string;
label?: string;
}
export const Input = forwardRef(
({ className, error, label, type = 'text', ...props }, ref) => {
return (
);
}
if (error || !forecast) {
return null;
}
// Process forecast data to get one reading per day
const dailyForecast = forecast.list.filter((reading, index) => index % 8 === 0).slice(0, 7);
return (
7-Day Forecast
{dailyForecast.map((day) => (
))}
);
}
```
#### Phase 4: Charts & Visualization (45 minutes)
##### Temperature Chart with Recharts
**src/components/charts/temperature-chart.tsx**:
```typescript
'use client';
import {
LineChart,
Line,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
} from 'recharts';
interface TemperatureChartProps {
data: Array<{
time: string;
temp: number;
}>;
}
export function TemperatureChart({ data }: TemperatureChartProps) {
return (
Temperature Trend
);
}
```
***
### Results
#### Development Time
| Phase | Duration | Agent |
| ------------------------ | ------------- | ------------- |
| Project Setup | 15 min | @orchestrator |
| Component Library | 1 hour | @frontend |
| State Management | 45 min | @frontend |
| Weather Features | 1.5 hours | @frontend |
| Charts & Visualization | 45 min | @frontend |
| Dark Mode Implementation | 30 min | @frontend |
| Responsive Polish | 30 min | @frontend |
| **Total** | **4.5 hours** | |
#### Code Metrics
```
Files Created: 73 files
- UI Components: 12 files
- Feature Components: 15 files
- Layout Components: 4 files
- Hooks: 8 files
- Store: 1 file
- Pages: 5 files
- Lib/Utils: 6 files
- Types: 4 files
- Styles: 3 files
Total Lines of Code: ~4,800 lines
- Component code: ~3,200 lines
- Hook code: ~680 lines
- Store/state: ~420 lines
- Utils/lib: ~500 lines
Components: 27 total
- Reusable UI components: 12
- Feature-specific: 15
Quality Gates Status:
✅ All TypeScript strict checks passing
✅ No any types used
✅ All components have TypeScript interfaces
✅ Responsive design verified
✅ Dark mode working on all components
✅ Accessibility attributes present
✅ No console errors
```
#### Performance Metrics
```
Lighthouse Scores:
- Performance: 96
- Accessibility: 98
- Best Practices: 95
- SEO: 100
Core Web Vitals:
- LCP (Largest Contentful Paint): 1.2s ✅
- FID (First Input Delay): 45ms ✅
- CLS (Cumulative Layout Shift): 0.02 ✅
Bundle Size:
- Initial JS: 142 KB
- CSS: 12 KB
- Total: 154 KB (gzipped)
Load Times (3G):
- First Contentful Paint: 1.1s
- Time to Interactive: 2.3s
- Speed Index: 1.8s
```
***
### Component Library Documentation
#### Usage Examples
##### Button
```typescript
```
##### Card
```typescript
Title
Content goes here
```
##### Input
```typescript
setEmail(e.target.value)}
/>
```
***
### Responsive Design Strategy
#### Breakpoints
```css
/* Tailwind defaults */
sm: 640px /* Mobile landscape */
md: 768px /* Tablet */
lg: 1024px /* Desktop */
xl: 1280px /* Large desktop */
```
#### Mobile-First Example
```typescript
// Stacked on mobile, side-by-side on desktop
// Full width on mobile, constrained on desktop
{/* content */}
```
***
### Dark Mode Implementation
#### Theme Provider Setup
**src/app/providers.tsx**:
```typescript
'use client';
import { ThemeProvider } from 'next-themes';
import { useUIStore } from '@/store/use-store';
export function Providers({ children }: { children: React.ReactNode }) {
const theme = useUIStore((state) => state.theme);
return (
{children}
);
}
```
#### Dark Mode Styles
```typescript
// Example component with dark mode
Dark mode supported
```
***
### Key Decisions
#### Decision 1: Component Library Choice
**Question**: Build custom or use existing library?
**Decision**: Build custom components inspired by shadcn/ui
**Reasoning**:
* Full control over components
* No unnecessary dependencies
* Easy to customize
* Learn component patterns
#### Decision 2: State Management
**Question**: Redux, Context, or Zustand?
**Decision**: Zustand
**Reasoning**:
* Simpler than Redux
* More powerful than Context
* Great TypeScript support
* Built-in persistence
#### Decision 3: Data Fetching
**Question**: SWR or React Query?
**Decision**: TanStack Query (React Query)
**Reasoning**:
* Better caching strategy
* More features
* Excellent TypeScript support
* DevTools for debugging
#### Decision 4: Styling Approach
**Question**: CSS Modules, Styled Components, or Tailwind?
**Decision**: Tailwind CSS
**Reasoning**:
* Rapid development
* Consistent design system
* Dark mode support built-in
* Responsive utilities
* Small bundle size
***
### Best Practices Demonstrated
#### 1. Component Composition
```typescript
// Small, focused components
```
#### 2. Custom Hooks for Reusability
```typescript
// Hook abstracts away complexity
const weather = useWeather(city);
const { data, isLoading, error } = weather;
```
#### 3. Type Safety
```typescript
// All components have explicit prop types
interface ButtonProps extends ButtonHTMLAttributes {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
}
```
#### 4. Accessibility
```typescript
// Semantic HTML, ARIA labels, keyboard support
```
#### 5. Performance Optimization
```typescript
// Debounced search
const debouncedQuery = useDebounce(query, 300);
// Memoized values
const sortedData = useMemo(() => data.sort(...), [data]);
```
***
### Conclusion
This frontend project demonstrates agentful's ability to:
* Build beautiful, modern UIs
* Create reusable component libraries
* Implement sophisticated state management
* Achieve exceptional performance (96 Lighthouse score)
* Deliver responsive, accessible designs
* Complete in 4.5 hours (vs 1+ week traditionally)
**Perfect for**: Frontend-focused projects, SPAs, dashboards, marketing sites
**Previous**: [API Development Example](/examples/api-development)
**Next**: [Examples Index](/examples/index)
## Full-Stack SaaS Application
A complete task management system for remote teams with authentication, real-time updates, and role-based access control.
***
### Overview
**TaskFlow** is a collaborative task management application similar to Trello or Asana, built from scratch using agentful in 6-8 hours.
#### Business Value
* **Target Users**: Remote teams, startups, agencies
* **Key Problem**: Managing tasks across distributed teams
* **Solution**: Centralized task management with real-time collaboration
#### Key Features
* ✅ JWT-based authentication
* ✅ Team workspace management
* ✅ Task CRUD operations
* ✅ Real-time task updates
* ✅ Role-based permissions (Admin, Member, Viewer)
* ✅ Task assignments and due dates
* ✅ Activity feed
***
### Complete PRODUCT.md
Here's the complete `PRODUCT.md` that powered this project, organized in a **hierarchical structure** perfect for production applications:
````markdown
# TaskFlow - Team Task Management
## Overview
A collaborative task management application for remote teams. Users can create workspaces, invite team members, create and assign tasks, and track progress with real-time updates.
## Tech Stack
- **Frontend**: Next.js 14 (App Router), TypeScript, Tailwind CSS
- **Backend**: Next.js API Routes, Prisma ORM
- **Database**: PostgreSQL (local Docker or Supabase)
- **Auth**: JWT with httpOnly cookies
- **State**: Zustand for client state, React Query for server state
- **Testing**: Vitest, Playwright, Testing Library
- **Validation**: Zod
- **Styling**: Tailwind CSS + shadcn/ui components
## Features
This example demonstrates HIERARCHICAL structure for production apps.
Instead of one massive PRODUCT.md, features are organized by domain:
- .claude/product/domains/authentication/
- .claude/product/domains/workspaces/
- .claude/product/domains/tasks/
This scales better for large applications with multiple teams.
### Domain: Authentication
#### User Registration - CRITICAL
**Priority**: CRITICAL - Must be completed first
**User Stories**:
- As a new user, I can register with email and password
**Acceptance Criteria**:
- Passwords must be hashed (bcrypt, 10 rounds)
- Email validation required
- User automatically logged in after registration
- JWT token stored in httpOnly cookie
**API Endpoints**:
- POST /api/auth/register
**Components**:
- app/(auth)/register/page.tsx
- components/auth/RegisterForm.tsx
#### User Login - CRITICAL
**Priority**: CRITICAL
**User Stories**:
- As a registered user, I can login to access my workspace
**Acceptance Criteria**:
- JWT tokens stored in httpOnly cookies
- Session expires after 7 days
- Protected routes redirect to login
- Login form shows clear error messages
**API Endpoints**:
- POST /api/auth/login
- GET /api/auth/me
**Components**:
- app/(auth)/login/page.tsx
- components/auth/LoginForm.tsx
#### User Logout - CRITICAL
**Priority**: CRITICAL
**User Stories**:
- As a logged-in user, I can logout securely
**Acceptance Criteria**:
- Clears httpOnly cookie
- Redirects to login page
- Clears client-side state
**API Endpoints**:
- POST /api/auth/logout
**Components**:
- components/auth/LogoutButton.tsx
#### User Profile - LOW
**Priority**: LOW - Nice to have
**User Stories**:
- As a user, I can view my profile
- As a user, I can update my name and avatar
**Acceptance Criteria**:
- Profile shows name, email, avatar
- Avatar upload to cloud storage (or use Gravatar)
- Email changes require verification
**API Endpoints**:
- GET /api/users/me
- PUT /api/users/me
**Components**:
- app/profile/page.tsx
- components/users/ProfileForm.tsx
### Domain: Workspaces
#### Create Workspace - HIGH
**Priority**: HIGH - Core feature for organizing work
**User Stories**:
- As a user, I can create a new workspace
**Acceptance Criteria**:
- User can create unlimited workspaces
- Workspace requires name and description
- Creator becomes workspace owner
**API Endpoints**:
- POST /api/workspaces
**Components**:
- components/workspaces/CreateWorkspaceDialog.tsx
#### View Workspaces - HIGH
**Priority**: HIGH
**User Stories**:
- As a workspace member, I can view all workspaces I'm part of
**Acceptance Criteria**:
- Show list of all user's workspaces
- Display workspace name and member count
- Click to enter workspace
**API Endpoints**:
- GET /api/workspaces
**Components**:
- components/workspaces/WorkspaceList.tsx
- components/workspaces/WorkspaceCard.tsx
#### Manage Workspace Members - MEDIUM
**Priority**: MEDIUM
**User Stories**:
- As a workspace owner, I can invite team members
- As a workspace owner, I can remove members
**Acceptance Criteria**:
- Members invited via email
- Members have roles: Owner, Admin, Member, Viewer
- Email invitation sent with workspace link
**API Endpoints**:
- POST /api/workspaces/:id/members
- DELETE /api/workspaces/:id/members/:userId
**Components**:
- components/workspaces/MemberList.tsx
- components/workspaces/InviteMemberDialog.tsx
#### Real-time Presence - MEDIUM
**Priority**: MEDIUM - Enhances collaboration
**User Stories**:
- As a user, I see when team members come online
**Acceptance Criteria**:
- Display online/offline status
- Show active users in workspace
- Update status in real-time
**Implementation**:
- /api/workspaces/:id/events (SSE endpoint)
- Hook: hooks/useWorkspacePresence.ts
- Component: components/workspaces/OnlineUsers.tsx
### Domain: Tasks
#### Create Task - HIGH
**Priority**: HIGH - Core feature
**User Stories**:
- As a user, I can create tasks in a workspace
**Acceptance Criteria**:
- Tasks require title and workspace
- Optional: description, assignee, due date, priority
- Default status: Todo
**API Endpoints**:
- POST /api/workspaces/:workspaceId/tasks
**Components**:
- components/tasks/CreateTaskDialog.tsx
#### View Tasks - HIGH
**Priority**: HIGH
**User Stories**:
- As a user, I can view all tasks in a workspace
**Acceptance Criteria**:
- Tasks organized by status (Todo, In Progress, Done)
- Kanban-style board layout
- Drag-and-drop to move tasks
**API Endpoints**:
- GET /api/workspaces/:workspaceId/tasks
**Components**:
- components/tasks/TaskBoard.tsx
- components/tasks/TaskCard.tsx
#### Update Task Status - HIGH
**Priority**: HIGH
**User Stories**:
- As a user, I can move tasks through statuses
**Acceptance Criteria**:
- Drag and drop to change status
- Optimistic UI update
- Activity feed tracks changes
**API Endpoints**:
- PATCH /api/tasks/:id/status
**Components**:
- components/tasks/TaskCard.tsx (with drag handlers)
#### Assign Tasks - MEDIUM
**Priority**: MEDIUM
**User Stories**:
- As a user, I can assign tasks to team members
- As a user, I can set due dates and priorities
**Acceptance Criteria**:
- Assign from workspace member list
- Set priority: Low, Medium, High, Urgent
- Due date picker
**API Endpoints**:
- PUT /api/tasks/:id
**Components**:
- components/tasks/TaskAssignee.tsx
- components/tasks/TaskDueDate.tsx
#### Task Filtering - MEDIUM
**Priority**: MEDIUM
**User Stories**:
- As a user, I can filter tasks by assignee
- As a user, I can filter tasks by priority
**Acceptance Criteria**:
- Filter by assignee (including "unassigned")
- Filter by priority level
- Clear filters button
**API Endpoints**:
- GET /api/workspaces/:workspaceId/tasks (with query params)
**Components**:
- components/tasks/TaskFilters.tsx
#### Real-time Task Updates - MEDIUM
**Priority**: MEDIUM - Enhances collaboration
**User Stories**:
- As a user, I see task updates immediately when others make changes
**Acceptance Criteria**:
- Task updates sync across all connected clients
- Activity feed shows recent changes
- Notifications for task assignments
**Implementation Notes**:
- Leverage SSE infrastructure from Workspaces domain
- Add activity tracking to task operations
- Broadcast changes on task mutations
**Components**:
- components/tasks/RealtimeBadge.tsx
- hooks/useTaskUpdates.ts
## Non-Functional Requirements
### Performance
- Initial page load < 2 seconds
- API response time < 200ms (p95)
- Support 100+ concurrent users
### Security
- All API routes protected except /api/auth/*
- SQL injection prevention (Prisma handles this)
- XSS prevention (React handles this)
- CSRF protection (Next.js built-in)
- Rate limiting on auth endpoints
### Accessibility
- WCAG 2.1 AA compliant
- Keyboard navigation support
- Screen reader support
- High contrast mode support
### Code Quality
- TypeScript strict mode
- 80%+ test coverage
- No console.log in production
- All components have TypeScript interfaces
## Database Schema
```prisma
model User {
id String @id @default(cuid())
email String @unique
password String
name String
avatar String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ownedWorkspaces Workspace[] @relation("WorkspaceOwner")
workspaceMembers WorkspaceMember[]
assignedTasks Task[] @relation("TaskAssignee")
createdTasks Task[] @relation("TaskCreator")
activities Activity[]
}
model Workspace {
id String @id @default(cuid())
name String
description String?
ownerId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
owner User @relation("WorkspaceOwner", fields: [ownerId], references: [id], onDelete: Cascade)
members WorkspaceMember[]
tasks Task[]
activities Activity[]
}
model WorkspaceMember {
id String @id @default(cuid())
workspaceId String
userId String
role Role @default(MEMBER)
joinedAt DateTime @default(now())
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([workspaceId, userId])
}
model Task {
id String @id @default(cuid())
title String
description String?
status TaskStatus @default(TODO)
priority Priority @default(MEDIUM)
dueDate DateTime?
workspaceId String
assigneeId String?
creatorId String
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
assignee User? @relation("TaskAssignee", fields: [assigneeId], references: [id])
creator User @relation("TaskCreator", fields: [creatorId], references: [id])
activities Activity[]
}
model Activity {
id String @id @default(cuid())
type ActivityType
message String
taskId String?
workspaceId String
userId String
createdAt DateTime @default(now())
task Task? @relation(fields: [taskId], references: [id], onDelete: Cascade)
workspace Workspace @relation(fields: [workspaceId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id])
}
enum Role {
OWNER
ADMIN
MEMBER
VIEWER
}
enum TaskStatus {
TODO
IN_PROGRESS
DONE
}
enum Priority {
LOW
MEDIUM
HIGH
URGENT
}
enum ActivityType {
TASK_CREATED
TASK_UPDATED
TASK_DELETED
TASK_ASSIGNED
STATUS_CHANGED
MEMBER_JOINED
MEMBER_LEFT
}
````
### Success Criteria
1. All CRITICAL and HIGH priority features implemented
2. All quality gates passing (TypeScript, tests, coverage, lint, security)
3. Test coverage ≥ 80%
4. E2E tests for critical user flows
5. Responsive design (mobile, tablet, desktop)
6. Accessibility audit passed
### Notes
* Start with authentication - it's the foundation
* Build workspace management before tasks (tasks need workspaces)
* Real-time updates can be added after core features work
* Use shadcn/ui for consistent, accessible components
* Focus on getting one feature fully done before starting the next
```
---
## Project Structure
### Initial State (Before agentful)
```
taskflow/
├── node\_modules/
├── package.json
├── tsconfig.json
└── next.config.js
```
### Final State (After agentful)
**Hierarchical PRODUCT.md Structure**:
```
taskflow/
├── .claude/
│ ├── agents/
│ ├── commands/
│ ├── skills/
│ └── product/
│ ├── overview\.md # Project overview, tech stack
│ ├── domains/ # HIERARCHICAL: Organized by domain
│ │ ├── authentication/
│ │ │ ├── index.md # Auth domain overview
│ │ │ ├── registration.md
│ │ │ ├── login.md
│ │ │ ├── logout.md
│ │ │ └── profile.md
│ │ ├── workspaces/
│ │ │ ├── index.md # Workspaces domain overview
│ │ │ ├── create-workspace.md
│ │ │ ├── view-workspaces.md
│ │ │ ├── manage-members.md
│ │ │ └── real-time-presence.md
│ │ └── tasks/
│ │ ├── index.md # Tasks domain overview
│ │ ├── create-task.md
│ │ ├── view-tasks.md
│ │ ├── update-status.md
│ │ ├── assign-tasks.md
│ │ ├── filter-tasks.md
│ │ └── real-time-updates.md
│ ├── non-functional.md # Performance, security, etc.
│ └── database-schema.md # Prisma schema
├── .agentful/
│ ├── state.json
│ ├── completion.json
│ └── decisions.json
├── CLAUDE.md
├── prisma/
│ ├── schema.prisma
│ └── migrations/
│ └── 20240118\_init/
│ └── migration.sql
├── src/
│ ├── app/
│ │ ├── (auth)/
│ │ │ ├── login/
│ │ │ │ └── page.tsx
│ │ │ └── register/
│ │ │ └── page.tsx
│ │ ├── (dashboard)/
│ │ │ ├── workspace/
│ │ │ │ └── \[id]/
│ │ │ │ └── page.tsx
│ │ │ └── layout.tsx
│ │ ├── api/
│ │ │ ├── auth/
│ │ │ │ ├── login/route.ts
│ │ │ │ ├── register/route.ts
│ │ │ │ ├── logout/route.ts
│ │ │ │ └── me/route.ts
│ │ │ ├── workspaces/
│ │ │ │ ├── route.ts
│ │ │ │ ├── \[id]/
│ │ │ │ │ ├── route.ts
│ │ │ │ │ ├── tasks/
│ │ │ │ │ │ ├── route.ts
│ │ │ │ │ │ └── \[taskId]/route.ts
│ │ │ │ │ └── members/
│ │ │ │ │ └── route.ts
│ │ │ │ └── events/
│ │ │ │ └── route.ts
│ │ │ └── users/
│ │ │ └── me/
│ │ │ └── route.ts
│ │ ├── layout.tsx
│ │ └── page.tsx
│ ├── components/
│ │ ├── ui/
│ │ │ ├── button.tsx
│ │ │ ├── input.tsx
│ │ │ ├── dialog.tsx
│ │ │ ├── form.tsx
│ │ │ └── ...
│ │ ├── auth/
│ │ │ ├── RegisterForm.tsx
│ │ │ ├── LoginForm.tsx
│ │ │ └── LogoutButton.tsx
│ │ ├── workspaces/
│ │ │ ├── WorkspaceList.tsx
│ │ │ ├── WorkspaceCard.tsx
│ │ │ ├── CreateWorkspaceDialog.tsx
│ │ │ ├── MemberList.tsx
│ │ │ ├── InviteMemberDialog.tsx
│ │ │ └── OnlineUsers.tsx
│ │ ├── tasks/
│ │ │ ├── TaskBoard.tsx
│ │ │ ├── TaskCard.tsx
│ │ │ ├── CreateTaskDialog.tsx
│ │ │ ├── TaskFilters.tsx
│ │ │ ├── TaskAssignee.tsx
│ │ │ ├── TaskDueDate.tsx
│ │ │ └── RealtimeBadge.tsx
│ │ └── layout/
│ │ ├── Header.tsx
│ │ └── Sidebar.tsx
│ ├── lib/
│ │ ├── auth.ts
│ │ ├── prisma.ts
│ │ └── utils.ts
│ ├── hooks/
│ │ ├── useAuth.ts
│ │ ├── useWorkspaces.ts
│ │ ├── useTasks.ts
│ │ ├── useTaskUpdates.ts
│ │ └── useWorkspacePresence.ts
│ ├── store/
│ │ └── authStore.ts
│ ├── types/
│ │ └── index.ts
│ └── styles/
│ └── globals.css
├── **tests**/
│ ├── unit/
│ │ ├── services/
│ │ │ └── auth.service.test.ts
│ │ └── hooks/
│ │ └── useAuth.test.ts
│ ├── integration/
│ │ └── api/
│ │ └── auth.test.ts
│ └── e2e/
│ ├── auth.spec.ts
│ └── tasks.spec.ts
├── .env.example
├── .env.local
└── package.json
````
**Why Hierarchical?**
For production apps, organizing features by domain (authentication, workspaces, tasks) is more realistic than a flat PRODUCT.md. This structure:
- Scales to dozens of features without becoming overwhelming
- Allows teams to work on different domains in parallel
- Makes it easier to find and update specific features
- Mirrors real-world project organization
**File Count**: 127 files created
**Lines of Code**: ~8,500 lines
**Test Coverage**: 84%
---
## Implementation Walkthrough
### Phase 1: Project Setup (15 minutes)
#### 1. Initialize Project
```bash
mkdir taskflow && cd taskflow
npm init -y
npm install next@14 react react-dom typescript @types/react @types/node
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
````
##### 2. Initialize agentful
```bash
npx @itz4blitz/agentful init
```
##### 3. Edit PRODUCT.md
Copy the complete PRODUCT.md from above into your project.
##### 4. Start Development
```bash
claude
/agentful-start
```
**agentful Output**:
```
✅ Detected: Next.js 14 + TypeScript + Prisma + Tailwind
✅ Generated specialized agents
🎯 Starting Phase 1: Authentication (CRITICAL)
Delegating to @backend...
```
***
#### Phase 2: Database Schema (20 minutes)
**Agent**: `@backend` → `@architect`
**agentful Sequence**:
```
@orchestrator: Creating database schema
→ @backend: Writing Prisma schema
→ @tester: Writing database tests
→ @reviewer: Validating schema
```
**Generated Files**:
##### prisma/schema.prisma
```prisma
// This is your Prisma schema file
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
model User {
id String @id @default(cuid())
email String @unique
password String
name String
avatar String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
ownedWorkspaces Workspace[] @relation("WorkspaceOwner")
workspaceMembers WorkspaceMember[]
assignedTasks Task[] @relation("TaskAssignee")
createdTasks Task[] @relation("TaskCreator")
activities Activity[]
}
// ... (rest of schema from PRODUCT.md)
```
##### prisma/migrations/20240118\_init/migration.sql
```sql
-- CreateEnum
CREATE TYPE "Role" AS ENUM ('OWNER', 'ADMIN', 'MEMBER', 'VIEWER');
-- CreateEnum
CREATE TYPE "TaskStatus" AS ENUM ('TODO', 'IN_PROGRESS', 'DONE');
-- CreateEnum
CREATE TYPE "Priority" AS ENUM ('LOW', 'MEDIUM', 'HIGH', 'URGENT');
-- CreateEnum
CREATE TYPE "ActivityType" AS ENUM ('TASK_CREATED', 'TASK_UPDATED', 'TASK_DELETED', 'TASK_ASSIGNED', 'STATUS_CHANGED', 'MEMBER_JOINED', 'MEMBER_LEFT');
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"email" TEXT NOT NULL,
"password" TEXT NOT NULL,
"name" TEXT NOT NULL,
"avatar" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("User")
);
-- CreateTable
CREATE TABLE "Workspace" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"description" TEXT,
"ownerId" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Workspace_pkey" PRIMARY KEY ("Workspace")
);
-- ... (rest of migrations)
```
**Commands Run**:
```bash
npx prisma migrate dev --name init
npx prisma generate
```
**Validation**: ✅ Schema matches PRODUCT.md requirements
***
#### Phase 3: Authentication System (1.5 hours)
**Agent**: `@backend` → `@frontend` → `@tester`
##### 3.1 Backend Implementation
**agentful Sequence**:
```
@orchestrator: Building authentication feature
→ @backend: Creating auth service
→ @backend: Creating auth repositories
→ @backend: Creating auth API routes
→ @tester: Writing unit tests
→ @tester: Writing integration tests
→ @reviewer: Code review
```
**Generated Files**:
##### src/lib/auth.ts
```typescript
import { SignJWT, jwtVerify } from 'jose';
import { cookies } from 'next/headers';
import { prisma } from './prisma';
const secret = new TextEncoder().encode(process.env.JWT_SECRET);
export async function createToken(payload: any) {
return new SignJWT(payload)
.setProtectedHeader({ alg: 'HS256' })
.setExpirationTime('7d')
.sign(secret);
}
export async function verifyToken(token: string) {
try {
const { payload } = await jwtVerify(token, secret);
return payload;
} catch (error) {
return null;
}
}
export async function getSession() {
const cookieStore = await cookies();
const token = cookieStore.get('token')?.value;
if (!token) return null;
const payload = await verifyToken(token);
if (!payload) return null;
const user = await prisma.user.findUnique({
where: { id: payload.userId as string },
select: {
id: true,
email: true,
name: true,
avatar: true,
},
});
return user;
}
export async function hashPassword(password: string): Promise {
const bcrypt = require('bcrypt');
return bcrypt.hash(password, 10);
}
export async function comparePassword(
password: string,
hashedPassword: string
): Promise {
const bcrypt = require('bcrypt');
return bcrypt.compare(password, hashedPassword);
}
```
##### src/app/api/auth/register/route.ts
```typescript
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { hashPassword, createToken } from '@/lib/auth';
import { z } from 'zod';
const registerSchema = z.object({
email: z.string().email(),
password: z.string().min(8),
name: z.string().min(2),
});
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const validated = registerSchema.parse(body);
// Check if user exists
const existing = await prisma.user.findUnique({
where: { email: validated.email },
});
if (existing) {
return NextResponse.json(
{ error: 'User already exists' },
{ status: 409 }
);
}
// Create user
const hashedPassword = await hashPassword(validated.password);
const user = await prisma.user.create({
data: {
email: validated.email,
password: hashedPassword,
name: validated.name,
},
select: {
id: true,
email: true,
name: true,
avatar: true,
},
});
// Create token
const token = await createToken({ userId: user.id });
// Set cookie
const response = NextResponse.json(user, { status: 201 });
response.cookies.set('token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7, // 7 days
});
return response;
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ error: 'Validation failed', details: error.errors },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
```
##### src/app/api/auth/login/route.ts
```typescript
import { NextRequest, NextResponse } from 'next/server';
import { prisma } from '@/lib/prisma';
import { comparePassword, createToken } from '@/lib/auth';
import { z } from 'zod';
const loginSchema = z.object({
email: z.string().email(),
password: z.string(),
});
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const validated = loginSchema.parse(body);
// Find user
const user = await prisma.user.findUnique({
where: { email: validated.email },
});
if (!user) {
return NextResponse.json(
{ error: 'Invalid credentials' },
{ status: 401 }
);
}
// Verify password
const isValid = await comparePassword(validated.password, user.password);
if (!isValid) {
return NextResponse.json(
{ error: 'Invalid credentials' },
{ status: 401 }
);
}
// Create token
const token = await createToken({ userId: user.id });
// Set cookie
const response = NextResponse.json({
id: user.id,
email: user.email,
name: user.name,
avatar: user.avatar,
});
response.cookies.set('token', token, {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7, // 7 days
});
return response;
} catch (error) {
if (error instanceof z.ZodError) {
return NextResponse.json(
{ error: 'Validation failed', details: error.errors },
{ status: 400 }
);
}
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
```
##### 3.2 Frontend Implementation
**Agent**: `@frontend`
##### src/hooks/useAuth.ts
```typescript
'use client';
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
interface User {
id: string;
email: string;
name: string;
avatar?: string;
}
interface AuthState {
user: User | null;
isLoading: boolean;
isAuthenticated: boolean;
login: (email: string, password: string) => Promise;
register: (email: string, password: string, name: string) => Promise;
logout: () => Promise;
fetchSession: () => Promise;
}
export const useAuth = create()(
persist(
(set) => ({
user: null,
isLoading: true,
isAuthenticated: false,
login: async (email: string, password: string) => {
const res = await fetch('/api/auth/login', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password }),
});
if (!res.ok) {
const error = await res.json();
throw new Error(error.error || 'Login failed');
}
const user = await res.json();
set({ user, isAuthenticated: true, isLoading: false });
},
register: async (email: string, password: string, name: string) => {
const res = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email, password, name }),
});
if (!res.ok) {
const error = await res.json();
throw new Error(error.error || 'Registration failed');
}
const user = await res.json();
set({ user, isAuthenticated: true, isLoading: false });
},
logout: async () => {
await fetch('/api/auth/logout', { method: 'POST' });
set({ user: null, isAuthenticated: false, isLoading: false });
},
fetchSession: async () => {
try {
const res = await fetch('/api/auth/me');
if (res.ok) {
const user = await res.json();
set({ user, isAuthenticated: true, isLoading: false });
} else {
set({ user: null, isAuthenticated: false, isLoading: false });
}
} catch (error) {
set({ user: null, isAuthenticated: false, isLoading: false });
}
},
}),
{
name: 'auth-storage',
}
)
);
```
##### src/app/(auth)/login/page.tsx
```typescript
'use client';
import { useState } from 'react';
import { useRouter } from 'next/navigation';
import { useAuth } from '@/hooks/useAuth';
export default function LoginPage() {
const router = useRouter();
const { login } = useAuth();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [error, setError] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError('');
setIsLoading(true);
try {
await login(email, password);
router.push('/workspace');
} catch (err: any) {
setError(err.message);
} finally {
setIsLoading(false);
}
};
return (