# 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 ( {items.map(item => ( handleItemClick(item.path)}> {item.label} ))} ); } ``` **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)
#### Refactoring Improve code quality with refactoring workflow → [Refactoring Guide](./refactoring)
*** ### Quick Reference **Report Bug:** ```bash # Create bug report cat > .agentful/bugs/bug-name.md << 'EOF' [Paste bug report template] EOF ``` **Start Bug Fix:** ```bash /agentful-start # Automatically picks up bug from bugs/ directory ``` **Check Bug Status:** ```bash /agentful-status # Shows active and resolved bugs ``` **Validate Fix:** ```bash /agentful-validate # Ensures no regressions ``` ## Feature Development Workflow Complete guide to building features from requirements to production-ready code using agentful's autonomous development workflow. *** ### Overview The Feature Development workflow takes a feature requirement from `PRODUCT.md` and transforms it into fully implemented, tested, and validated code through autonomous agent collaboration. #### What This Workflow Delivers * ✅ Complete feature implementation (frontend + backend) * ✅ Comprehensive test coverage (≥80%) * ✅ All validation gates passing * ✅ No type errors (adapts to stack) * ✅ No dead code * ✅ Security-clean code #### Typical Timeline | Feature Complexity | Time | Iterations | | ------------------------------------- | ------------- | ---------- | | **Simple** (CRUD, forms) | 5-30 minutes | 2-5 | | **Medium** (auth, APIs) | 30-90 minutes | 5-15 | | **Complex** (real-time, integrations) | 1-4 hours | 15-40 | *** ### Prerequisites Before starting feature development, ensure: #### 1. Product Specification Complete Your `PRODUCT.md` should have: ```markdown ### 1. Feature Name - PRIORITY **Description**: Clear description of what the feature does **Acceptance Criteria**: - [ ] Specific requirement 1 - [ ] Specific requirement 2 - [ ] Specific requirement 3 **User Stories** (optional): - As a [user type] - I want [action] - So that [benefit] **Technical Notes** (optional): - API endpoints needed - Database schema changes - Third-party integrations ``` #### 2. Tech Stack Defined ```markdown ## Tech Stack - **Frontend**: Next.js 14, TypeScript, Tailwind CSS - **Backend**: Next.js API Routes - **Database**: PostgreSQL + Prisma - **Testing**: Vitest + Playwright - **Styling**: Tailwind CSS ``` #### 3. agentful Initialized ```bash # Already initialized? ls .claude/agents/ ls .agentful/ # If not, initialize: npx @itz4blitz/agentful init ``` *** ### The Feature Development Loop #### Complete Workflow Diagram ``` ┌─────────────────────────────────────────────────────────────┐ │ START: /agentful-start │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 1. ARCHITECT ANALYSIS (once per session) │ │ • Read PRODUCT.md tech stack │ │ • Generate tech-specific agents │ │ • Create architecture.json │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. ORCHESTRATOR PLANNING │ │ • Read state.json (current progress) │ │ • Read completion.json (what's done) │ │ • Read PRODUCT.md (requirements) │ │ • Select next feature to implement │ │ • Check for blockers │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. FEATURE BREAKDOWN │ │ • Analyze feature requirements │ │ • Identify backend tasks (APIs, services, DB) │ │ • Identify frontend tasks (UI, hooks, pages) │ │ • Identify testing tasks (unit, integration, E2E) │ │ • Create implementation plan │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 4. BACKEND IMPLEMENTATION │ │ • Delegate to @backend agent │ │ • Implement repositories │ │ • Implement services │ │ • Implement API routes/controllers │ │ • Database schema changes │ │ • Input validation schemas │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 5. FRONTEND IMPLEMENTATION │ │ • Delegate to @frontend agent │ │ • Create UI components │ │ • Create pages/views │ │ • Create custom hooks │ │ • Implement state management │ │ • Style with chosen framework │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 6. TESTING │ │ • Delegate to @tester agent │ │ • Write unit tests for services │ │ • Write unit tests for components │ │ • Write integration tests for APIs │ │ • Write E2E tests for user flows │ │ • Ensure ≥80% coverage │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 7. VALIDATION │ │ • Delegate to @reviewer agent │ │ • Run TypeScript check (tsc --noEmit) │ │ • Run lint check │ │ • Run dead code detection │ │ • Run all tests │ │ • Check coverage ≥80% │ │ • Run security scan │ └─────────────────────────────────────────────────────────────┘ ↓ Issues found? │ ┌──────────┴──────────┐ ↓ ↓ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 8a. FIX ITERATION(S) │ │ 8b. FEATURE COMPLETE │ │ • @fixer resolves │ │ • All checks pass │ │ • Re-validate │ │ • Update progress │ │ • Loop until pass │ │ • Mark feature done │ └─────────────────────────┘ └─────────────────────────┘ │ │ └──────────┬──────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 9. UPDATE COMPLETION │ │ • Update completion.json │ │ feature.status = "complete" │ │ feature.score = 100 │ │ • Update state.json │ │ increment iterations │ │ clear current_task │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 10. NEXT FEATURE │ │ • Loop back to step 2 │ │ • Select next priority feature │ │ • Continue until 100% complete │ └─────────────────────────────────────────────────────────────┘ ``` *** ### Step-by-Step Guide #### Step 1: Start the Workflow ```bash # In Claude Code CLI /agentful-start ``` **What happens:** 1. Orchestrator reads all state files 2. Checks for pending decisions 3. Selects next feature to work on 4. Begins implementation **Expected output:** ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Session ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Loaded state: 5 features, 32% complete Pending decisions: 0 Blocked tasks: 0 Starting development loop... 🏗️ Architect analyzing tech stack... Detected: Next.js 14, TypeScript, Tailwind, Prisma Generated: nextjs-agent, prisma-agent, tailwind-agent 📋 Next feature: User Authentication (CRITICAL) Priority: #1 Status: Not started → Delegating to specialists... ``` *** #### Step 2: Backend Implementation **Agent:** @backend **Time:** 5-30 minutes **What gets built:** ```typescript // 1. Repository Layer (data access) // src/repositories/user.repository.ts export class UserRepository { async findById(id: string): Promise { return db.user.findUnique({ where: { id } }); } async findByEmail(email: string): Promise { return db.user.findUnique({ where: { email } }); } async create(data: CreateUserInput): Promise { return db.user.create({ data }); } } // 2. Service Layer (business logic) // src/services/auth.service.ts export class AuthService { async register(input: RegisterInput): Promise { const existing = await this.userRepo.findByEmail(input.email); if (existing) throw new ConflictError('User exists'); const hashed = await hashPassword(input.password); return this.userRepo.create({ ...input, password: hashed }); } async login(email: string, password: string): Promise { const user = await this.userRepo.findByEmail(email); if (!user) throw new UnauthorizedError('Invalid credentials'); const valid = await comparePassword(password, user.password); if (!valid) throw new UnauthorizedError('Invalid credentials'); const token = generateJWT(user); return { user, token }; } } // 3. API Routes (HTTP endpoints) // src/app/api/auth/login/route.ts export async function POST(req: NextRequest) { const body = await req.json(); const service = new AuthService(); try { const result = await service.login(body.email, body.password); return NextResponse.json(result); } catch (error) { if (error instanceof UnauthorizedError) { return NextResponse.json( { error: error.message }, { status: 401 } ); } throw error; } } // 4. Validation Schemas // src/schemas/auth.schema.ts export const loginSchema = z.object({ email: z.string().email('Invalid email'), password: z.string().min(8, 'Password min 8 chars'), }); ``` **Backend agent follows this order:** 1. ✅ Repository layer (database access) 2. ✅ Service layer (business logic) 3. ✅ Controller/routes (HTTP endpoints) 4. ✅ Validation schemas (input validation) 5. ✅ Error handling (proper HTTP status codes) **Output:** ``` 🔧 Backend Agent implementing User Authentication... Created repositories: ✓ src/repositories/user.repository.ts Created services: ✓ src/services/auth.service.ts Created API routes: ✓ src/app/api/auth/login/route.ts ✓ src/app/api/auth/register/route.ts ✓ src/app/api/auth/logout/route.ts Created schemas: ✓ src/schemas/auth.schema.ts Backend implementation complete! Time: 8 minutes Files: 6 created ``` *** #### Step 3: Frontend Implementation **Agent:** @frontend **Time:** 5-30 minutes **What gets built:** ```tsx // 1. Custom Hooks (state management) // src/hooks/useAuth.ts export function useAuth() { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const 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 }), }); const data = await res.json(); setUser(data.user); return data; }; const logout = async () => { await fetch('/api/auth/logout', { method: 'POST' }); setUser(null); }; return { user, isLoading, login, logout }; } // 2. UI Components // src/components/ui/Button.tsx export const Button = forwardRef( ({ variant = 'primary', size = 'md', isLoading, children, ...props }, ref) => { const baseStyles = 'rounded-lg font-medium transition-colors'; const variants = { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-900', }; return ( ); } ); // 3. Feature Components // src/components/auth/LoginForm.tsx export function LoginForm() { const { login, isLoading } = useAuth(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { await login(email, password); // Redirect on success } catch (error) { // Show error } }; return (
setEmail(e.target.value)} placeholder="Email" required /> setPassword(e.target.value)} placeholder="Password" required />
); } // 4. Pages // src/app/login/page.tsx export default function LoginPage() { return (
); } ``` **Frontend agent follows this order:** 1. ✅ Custom hooks (business logic hooks) 2. ✅ UI primitives (Button, Input, Modal) 3. ✅ Feature components (LoginForm, UserProfile) 4. ✅ Pages/views (route pages) 5. ✅ Styling (Tailwind classes or chosen framework) **Output:** ``` 🎨 Frontend Agent implementing User Authentication... Created hooks: ✓ src/hooks/useAuth.ts ✓ src/hooks/useForm.ts Created UI components: ✓ src/components/ui/Button.tsx ✓ src/components/ui/Input.tsx ✓ src/components/ui/Modal.tsx Created feature components: ✓ src/components/auth/LoginForm.tsx ✓ src/components/auth/RegisterForm.tsx Created pages: ✓ src/app/login/page.tsx ✓ src/app/register/page.tsx Frontend implementation complete! Time: 12 minutes Files: 9 created ``` *** #### Step 4: Testing **Agent:** @tester **Time:** 10-30 minutes **What gets built:** ```typescript // 1. Unit Tests (Services) // src/services/__tests__/auth.service.test.ts describe('AuthService', () => { it('should register new user with hashed password', async () => { const service = new AuthService(); const result = await service.register({ email: 'test@example.com', password: 'password123', }); expect(result.email).toBe('test@example.com'); expect(result.password).not.toBe('password123'); // Hashed }); it('should reject duplicate email', async () => { const service = new AuthService(); await service.register({ email: 'test@example.com', password: 'password123', }); await expect( service.register({ email: 'test@example.com', password: 'password456', }) ).rejects.toThrow('User already exists'); }); }); // 2. Unit Tests (Components) // src/components/__tests__/LoginForm.test.tsx describe('LoginForm', () => { it('should render login form', () => { render(); expect(screen.getByPlaceholderText('Email')).toBeInTheDocument(); expect(screen.getByPlaceholderText('Password')).toBeInTheDocument(); }); it('should call login on submit', async () => { const { login } = useAuth(); render(); await fireEvent.change(screen.getByPlaceholderText('Email'), { target: { value: 'test@example.com' }, }); await fireEvent.click(screen.getByText('Sign In')); expect(login).toHaveBeenCalledWith('test@example.com', 'password123'); }); }); // 3. Integration Tests (API) // src/app/api/auth/__tests__/login.test.ts describe('POST /api/auth/login', () => { it('should login with valid credentials', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'password123', }); expect(res.status).toBe(200); expect(res.body).toHaveProperty('token'); expect(res.body.user).toHaveProperty('email', 'test@example.com'); }); it('should reject invalid credentials', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'wrongpassword', }); expect(res.status).toBe(401); }); }); // 4. E2E Tests (User Flows) // e2e/auth.spec.ts test.describe('Authentication Flow', () => { test('should register and login user', async ({ page }) => { await page.goto('/register'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'password123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard'); await expect(page.locator('text=Welcome')).toBeVisible(); }); }); ``` **Tester agent ensures:** * ✅ All services have unit tests * ✅ All components have unit tests * ✅ All API endpoints have integration tests * ✅ Critical flows have E2E tests * ✅ Coverage ≥ 80% **Output:** ``` 🧪 Tester Agent writing tests... Created unit tests: ✓ src/services/__tests__/auth.service.test.ts (8 tests) ✓ src/components/__tests__/LoginForm.test.tsx (5 tests) ✓ src/hooks/__tests__/useAuth.test.ts (4 tests) Created integration tests: ✓ src/app/api/auth/__tests__/login.test.ts (3 tests) ✓ src/app/api/auth/__tests__/register.test.ts (3 tests) Created E2E tests: ✓ e2e/auth.spec.ts (2 tests) Running tests... ✓ 23 tests passed ✓ Coverage: 87% Testing complete! Time: 15 minutes Tests: 23 created Coverage: 87% (target: 80%) ``` *** #### Step 5: Validation **Agent:** @reviewer **Time:** 1-2 minutes **What gets checked:** ```bash # 1. TypeScript npx tsc --noEmit ✓ No type errors # 2. Lint npm run lint ✓ No lint errors # 3. Dead Code npx knip ✓ No unused exports, files, or dependencies # 4. Tests npm test ✓ 23 tests passed # 5. Coverage npm test -- --coverage ✓ 87% coverage (≥80% threshold) # 6. Security npm audit --production ✓ No vulnerabilities grep -r "console.log" src/ ✓ No debug logs grep -rE "password.*=" src/ ✓ No hardcoded secrets ``` **Reviewer agent runs all checks:** **Output:** ``` 🔍 Reviewer Agent validating... Quality Gates: ✅ TypeScript: No errors (0 issues) ✅ Lint: No errors (0 issues) ✅ Dead Code: None found (0 issues) ✅ Tests: All passing (23/23) ✅ Coverage: 87% (≥80% threshold) ✅ Security: No issues (0 vulnerabilities) Overall: ✅ PASSED Feature validation complete! Time: 45 seconds ``` *** #### Step 6: Handle Validation Issues If validation finds issues: ``` ❌ VALIDATION FAILED Issues found: 1. Coverage at 72% (needs 80%) 2. console.log in src/auth/login.ts:45 3. Unused export: formatDate in src/utils/date.ts Delegating to @fixer... ``` **Agent:** @fixer **Time:** 2-5 minutes **What gets fixed:** ```typescript // 1. Add tests to reach 80% coverage // src/services/__tests__/auth.service.test.ts describe('AuthService edge cases', () => { it('should handle empty password', async () => { await expect( service.login('test@example.com', '') ).rejects.toThrow('Invalid credentials'); }); it('should handle malformed email', async () => { await expect( service.register({ email: 'invalid', password: 'pass123' }) ).rejects.toThrow(); }); }); // 2. Remove console.log // Before: async function login(email: string, password: string) { console.log('Login attempt:', email); // ❌ Remove // ... } // After: async function login(email: string, password: string) { // ... } // 3. Remove unused export // Before: export function formatDate(date: Date): string { ... } // ❌ Unused export function parseDate(str: string): Date { ... } // After: export function parseDate(str: string): Date { ... } ``` **Output:** ``` 🔧 Fixer Agent resolving issues... Fixed: ✓ Added 5 edge case tests (coverage 72% → 84%) ✓ Removed console.log from src/auth/login.ts:45 ✓ Removed unused export formatDate from src/utils/date.ts Delegating to @reviewer for re-validation... 🔍 Reviewer Agent re-validating... ✅ All checks passed! Feature complete after fixes. Time: 3 minutes ``` *** #### Step 7: Completion Update **Agent:** @orchestrator **Time:** Instant **What gets updated:** ```json // .agentful/completion.json { "features": { "authentication": { "status": "complete", "score": 100, "started_at": "2026-01-18T00:00:00Z", "completed_at": "2026-01-18T00:45:00Z", "notes": "JWT authentication fully implemented with tests" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": true, "coverage_80": true }, "overall": 25 } // .agentful/state.json { "version": "1.0", "current_task": null, "current_phase": "idle", "iterations": 12, "last_updated": "2026-01-18T00:45:00Z", "blocked_on": [] } ``` **Output:** ``` ✅ Feature Complete: User Authentication Files created: 18 Tests added: 23 Coverage: 87% Quality gates: All passing Progress updated: Authentication: 0% → 100% Overall: 0% → 25% Next feature: User Profile Priority: #2 ``` *** #### Step 8: Next Feature Workflow automatically loops back to Step 2 for the next feature. *** ### Real Example: Building a Todo App Let's see the complete workflow for a simple Todo app feature. #### PRODUCT.md Specification ```markdown ## 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 - [ ] Validation: non-empty text - [ ] Success feedback ### 2. Toggle Todo - HIGH **Description**: Users can mark todos as complete **Acceptance Criteria**: - [ ] Click todo to toggle completion - [ ] Visual indicator for completed todos - [ ] Strike-through text ### 3. Delete Todo - MEDIUM **Description**: Users can delete todos **Acceptance Criteria**: - [ ] Delete button on each todo - [ ] Confirmation prompt - [ ] Removes from list ``` *** #### Execution Timeline ##### Iteration 1: Add Todo Feature (8 minutes) ``` 🔧 Frontend Agent implementing Add Todo... Created: ✓ src/hooks/useTodos.ts (todo state management) ✓ src/components/TodoInput.tsx (input form) ✓ src/components/TodoList.tsx (todo list display) ✓ src/app/page.tsx (main page) 🧪 Tester Agent writing tests... Created: ✓ src/hooks/__tests__/useTodos.test.ts (6 tests) ✓ src/components/__tests__/TodoInput.test.tsx (4 tests) ✓ src/components/__tests__/TodoList.test.tsx (5 tests) Coverage: 89% 🔍 Reviewer Agent validating... ✅ All checks passed ✅ Feature Complete: Add Todo (100%) ``` **Files created:** 7 **Tests added:** 15 **Coverage:** 89% *** ##### Iteration 2: Toggle Todo Feature (5 minutes) ``` 🔧 Frontend Agent implementing Toggle Todo... Modified: ✓ src/hooks/useTodos.ts (added toggleTodo function) ✓ src/components/TodoList.tsx (click to toggle) 🧪 Tester Agent writing tests... Added: ✓ 3 tests for toggleTodo in useTodos.test.ts ✓ 2 tests for click interaction in TodoList.test.tsx Coverage: 91% 🔍 Reviewer Agent validating... ✅ All checks passed ✅ Feature Complete: Toggle Todo (100%) ``` **Files modified:** 2 **Tests added:** 5 **Coverage:** 91% *** ##### Iteration 3: Delete Todo Feature (6 minutes) ``` 🔧 Frontend Agent implementing Delete Todo... Modified: ✓ src/hooks/useTodos.ts (added deleteTodo function) ✓ src/components/TodoList.tsx (added delete button with confirmation) 🧪 Tester Agent writing tests... Added: ✓ 3 tests for deleteTodo in useTodos.test.ts ✓ 2 tests for delete interaction in TodoList.test.tsx Coverage: 92% 🔍 Reviewer Agent validating... ⚠️ Found 1 issue: - Missing test for cancel on confirmation dialog 🔧 Fixer Agent resolving issue... Added test for cancel case Coverage: 93% 🔍 Reviewer Agent re-validating... ✅ All checks passed ✅ Feature Complete: Delete Todo (100%) ``` **Files modified:** 2 **Tests added:** 6 (including fix) **Coverage:** 93% *** #### Final Results ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Development Session Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Project: Todo App Duration: 19 minutes Iterations: 3 Features Delivered: ✅ Add Todo (100%) ✅ Toggle Todo (100%) ✅ Delete Todo (100%) Files Created: 7 Files Modified: 4 Tests Added: 26 Test Coverage: 93% Quality Gates: ✅ Tests: 26/26 passing ✅ TypeScript: No errors ✅ Lint: No issues ✅ Dead Code: None ✅ Coverage: 93% (≥80%) ✅ Security: Clean 🎉 Todo app complete! Ready for deployment. ``` *** ### Manual vs Autonomous Execution #### Manual Mode (Step-by-Step) **Best for:** Learning, debugging, complex decisions ```bash # Run one iteration at a time /agentful-start # Review output # Check files created # Run tests manually # Run next iteration /agentful-start ``` **Pros:** * Full control * Learn how agents work * Debug issues easily * Make decisions at each step **Cons:** * Slower overall * Requires constant attention * Interrupt-driven *** #### Autonomous Mode (24/7) **Best for:** Fast delivery, well-defined features ```bash # Ralph loop - runs continuously /ralph-loop "/agentful-start" \ --max-iterations 50 \ --completion-promise "AGENTFUL_COMPLETE" # Let it run overnight # Wake up to completed features ``` **Pros:** * Fastest delivery * No manual intervention * 24/7 development * Optimal for batches of features **Cons:** * Less control * Can't see progress in real-time * May need decision interrupts *** #### Hybrid Mode (Recommended) **Best of both worlds:** ```bash # Start autonomous /agentful-start # [Let it run 30-60 minutes] # Check progress /agentful-status # If decisions needed: /agentful-decide # Resume autonomous /agentful-start # Check after major milestone /agentful-validate # Continue if good, stop if issues /agentful-start ``` *** ### Monitoring Progress #### Real-time Status ```bash /agentful-status ``` **Output:** ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Product: Todo App Overall Progress: ████████░░░░░░░░░░░ 40% Phase: implementation Iterations: 8 ┌─────────────────────┬──────────┬─────────┬────────────────┐ │ Feature │ Status │ Score │ Notes │ ├─────────────────────┼──────────┼─────────┼────────────────┤ │ Add Todo │ ✅ Done │ 100% │ │ │ Toggle Todo │ 🔄 Active│ 60% │ Testing │ │ Delete Todo │ ⏸ Pending│ 0% │ │ └─────────────────────┴──────────┴─────────┴────────────────┘ Quality Gates: ✅ Tests Passing ✅ No Type Errors ✅ Coverage 91% ✅ No Dead Code ✅ Security Clean 🔧 Currently Working On: Task: toggle-todo-testing Agent: tester Started: 2 minutes ago Last output: "Writing interaction tests for toggle..." ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Next Actions: • /agentful-start - Continue development • /agentful-decide - Answer pending decisions • /agentful-validate- Run quality checks ``` *** #### Inspect State Files ```bash # See what's done cat .agentful/completion.json # See current work cat .agentful/state.json # Check validation results cat .agentful/last-review.json ``` *** ### Best Practices #### 1. Write Clear Requirements **Good:** ```markdown ### 1. User Login - CRITICAL **Description**: Users can log in with email/password **Acceptance Criteria**: - [ ] Email input (validation: valid email format) - [ ] Password input (validation: min 8 chars) - [ ] Login button (disabled while loading) - [ ] Success: redirect to dashboard - [ ] Error: show inline message - [ ] API: POST /api/auth/login ``` **Bad:** ```markdown ### 1. Login Users can log in ``` *** #### 2. Prioritize Features Use priority levels: ```markdown ### 1. Core feature - CRITICAL ### 2. Important feature - HIGH ### 3. Nice to have - MEDIUM ``` agentful works in priority order. *** #### 3. Be Specific About Tech Stack ```markdown ## Tech Stack - Frontend: Next.js 14 (App Router) - Styling: Tailwind CSS - State: React Context + hooks - Testing: Vitest + Testing Library ``` Specific stack = better code generation. *** #### 4. Let It Complete Features Don't interrupt mid-feature: ```bash # Good: Let feature finish /agentful-start # [Wait for "Feature Complete" message] # Bad: Stop early /agentful-start # [Interrupt after 5 minutes] # Feature left incomplete ``` *** #### 5. Use Quality Gates Always validate after features: ```bash /agentful-start # Complete feature /agentful-validate # Verify quality /agentful-start # Next feature ``` *** ### Troubleshooting #### Issue: Feature Not Starting **Symptoms:** `/agentful-start` picks wrong feature **Solution:** ```bash # Check completion.json cat .agentful/completion.json # Manually update priority # Set score of desired feature to 0 # Set others to higher values /agentful-start ``` *** #### Issue: Tests Failing **Symptoms:** Reviewer keeps failing on tests **Solution:** ```bash # Run tests manually to see output npm test # Check specific test failures npm test -- --reporter=verbose # Let Fixer handle it /agentful-start ``` *** #### Issue: Coverage Below 80% **Symptoms:** Reviewer fails coverage gate **Solution:** ```bash # See coverage report npm test -- --coverage # Let Fixer add tests /agentful-start # Or add tests manually # Then run /agentful-start ``` *** #### Issue: Stuck in Validation Loop **Symptoms:** Fixer → Reviewer → Fixer → Reviewer... **Solution:** ```bash # Check last-review.json cat .agentful/last-review.json # Identify recurring issue # Fix manually if Fixer can't resolve # Reset state echo '{"current_task":null}' > .agentful/state.json # Resume /agentful-start ``` *** ### Next Steps
#### Bug Fixing Workflow When features have issues, use the bug fixing workflow → [Bug Fixing Guide](./bug-fixing)
#### Refactoring Workflow Improve existing feature code → [Refactoring Guide](./refactoring)
#### Testing Workflow Deep dive on testing strategies → [Testing Guide](./testing)
*** ### Quick Reference **Start Feature Development:** ```bash /agentful-start ``` **Check Progress:** ```bash /agentful-status ``` **Resolve Blockers:** ```bash /agentful-decide ``` **Validate Quality:** ```bash /agentful-validate ``` **24/7 Mode:** ```bash /ralph-loop "/agentful-start" \ --max-iterations 50 \ --completion-promise "AGENTFUL_COMPLETE" ``` ## Workflows Complete end-to-end workflows for autonomous product development with agentful. *** ### Overview agentful provides specialized workflows for different development scenarios. Each workflow orchestrates the appropriate agents, commands, and validation steps to achieve specific goals efficiently. ### Available Workflows
#### [Feature Development](./feature-development) **End-to-end feature implementation** Build new features from requirements to production-ready code. * Requirements analysis * Architecture design * Implementation (frontend + backend) * Testing and validation * Quality gates **Time:** 30 min - 4 hours per feature **Agents:** Orchestrator → Architect → Specialists → Tester → Reviewer [Learn More →](./feature-development) *** #### [Bug Fixing](./bug-fixing) **Systematic bug resolution** Identify, isolate, fix, and validate bug fixes with proper testing. * Bug reproduction * Root cause analysis * Fix implementation * Regression testing * Validation **Time:** 10 min - 2 hours per bug **Agents:** Orchestrator → Specialists → Tester → Reviewer → Fixer [Learn More →](./bug-fixing) *** #### [Refactoring](./refactoring) **Code quality improvement** Improve code structure, maintainability, and performance while preserving functionality. * Code analysis * Refactoring plan * Incremental changes * Validation after each step * Documentation updates **Time:** 1 - 6 hours per module **Agents:** Orchestrator → Specialists → Reviewer → Fixer [Learn More →](./refactoring) *** #### [Testing](./testing) **Comprehensive test coverage** Achieve 80%+ test coverage with unit, integration, and E2E tests. * Test strategy design * Unit test implementation * Integration tests * E2E test scenarios * Coverage optimization **Time:** 1 - 4 hours per feature suite **Agents:** Tester → Reviewer → Fixer [Learn More →](./testing) *** #### \[Manual vs Autonomous] **Choose your approach** Interactive step-by-step or hands-off autonomous development. * Manual: Full control, step-by-step * Autonomous: 24/7 continuous development * Hybrid: Start autonomous, intervene when needed [Learn More →](#manual-vs-autonomous)
*** ### Workflow Components Every agentful workflow consists of these core components: #### 1. Agents Specialized AI agents that handle specific aspects of development: | Agent | Role | Workflow Stage | | ----------------- | ------------------------------------- | ----------------------- | | **@orchestrator** | Coordinates work, delegates tasks | Planning & Coordination | | **@architect** | Analyzes tech stack, generates agents | Initialization | | **@frontend** | Builds UI components, pages, hooks | Implementation | | **@backend** | Implements APIs, services, databases | Implementation | | **@tester** | Writes comprehensive tests | Testing | | **@reviewer** | Validates quality gates | Validation | | **@fixer** | Auto-fixes validation issues | Remediation | #### 2. Commands Slash commands that control workflows: | Command | Purpose | When to Use | | -------------------- | ----------------------------------- | --------------------- | | `/agentful-start` | Start/resume autonomous development | Main workflow trigger | | `/agentful-status` | Check progress and state | Monitoring | | `/agentful-decide` | Resolve pending decisions | Unblocking work | | `/agentful-validate` | Run quality checks | Validation gates | #### 3. State Files Track progress and decisions: | File | Purpose | Updated By | | ---------------------------- | ------------------------------- | ------------ | | `.agentful/state.json` | Current work, phase, iterations | Orchestrator | | `.agentful/completion.json` | Feature completion percentages | Orchestrator | | `.agentful/decisions.json` | Pending user decisions | Orchestrator | | `.agentful/last-review.json` | Latest validation results | Reviewer | #### 4. Quality Gates Validation checkpoints that must pass: * **Tests Passing** - All tests must pass * **No Type Errors** - TypeScript validation * **No Dead Code** - Unused code elimination * **Coverage ≥ 80%** - Test coverage threshold * **Security Clean** - No secrets or vulnerabilities *** ### The Universal Development Loop All agentful workflows follow this core pattern: ``` ┌──────────────────────────────────────────────────────────┐ │ 1. PLAN │ │ • Read state (state.json, completion.json) │ │ • Read requirements (PRODUCT.md) │ │ • Identify next task │ │ • Check for blockers │ └──────────────────────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────────────────────┐ │ 2. DELEGATE │ │ • Select appropriate specialist agent │ │ • Provide clear task description │ │ • Wait for completion │ └──────────────────────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────────────────────┐ │ 3. IMPLEMENT │ │ • Specialist agent executes task │ │ • Creates/modifies files │ │ • Follows best practices │ │ • Reports completion │ └──────────────────────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────────────────────┐ │ 4. VALIDATE │ │ • Reviewer runs all checks │ │ • TypeScript, lint, tests, coverage, security │ │ • Generates report │ └──────────────────────────────────────────────────────────┘ ↓ Issues found? │ ┌──────────┴──────────┐ ↓ ↓ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 5a. FIX │ │ 5b. COMPLETE │ │ • Fixer resolves │ │ • Update completion │ │ • Re-validate │ │ • Mark feature done │ │ • Loop until pass │ │ • Prepare next task │ └─────────────────────────┘ └─────────────────────────┘ │ │ └──────────┬──────────┘ ↓ ┌──────────────────────────────────────────────────────────┐ │ 6. UPDATE STATE │ │ • Update completion.json │ │ • Update state.json │ │ • Log progress │ └──────────────────────────────────────────────────────────┘ ↓ ┌──────────────────────────────────────────────────────────┐ │ 7. LOOP │ │ • Return to step 1 │ │ • Continue until all features complete │ │ • Or until max iterations reached │ └──────────────────────────────────────────────────────────┘ ``` *** ### Workflow Examples #### Example 1: Simple Feature (5-10 minutes) **Task:** Add a "Contact Us" form ``` 1. /agentful-start 2. Orchestrator reads PRODUCT.md → "Contact form" feature 3. Delegates to @frontend → Creates contact form component 4. Delegates to @backend → Creates submission endpoint 5. Delegates to @tester → Writes form validation tests 6. Delegates to @reviewer → Validates all checks pass 7. Updates completion.json → contact-form: 100% 8. Reports success ``` **Output:** * 3 files created (form component, API route, tests) * 100% test coverage * All validation gates passing * Ready for production *** #### Example 2: Complex Feature (1-3 hours) **Task:** User authentication system ``` Iteration 1: Backend auth service @backend → Auth service, JWT tokens → @reviewer → Pass Iteration 2: Frontend login page @frontend → Login form, useAuth hook → @reviewer → Pass Iteration 3: Registration flow @backend → Register endpoint → @frontend → Register form → @tester → Integration tests → @reviewer → Fail (coverage 72%) Iteration 4: Fix coverage @fixer → Add edge case tests → @reviewer → Pass (coverage 84%) Iteration 5: Password reset @backend → Reset flow → @tester → E2E tests → @reviewer → Pass Final: Auth feature 100% complete ``` **Output:** * 15 files created * 47 tests passing * 84% coverage * All quality gates passing *** #### Example 3: Bug Fix (15-30 minutes) **Task:** Fix navigation bug on mobile ``` 1. Report bug to orchestrator 2. Orchestrator delegates to @frontend 3. Frontend agent reproduces bug 4. Identifies root cause: z-index conflict 5. Implements fix 6. Delegates to @tester → Regression tests 7. Delegates to @reviewer → Validates 8. Updates completion.json → bugs-resolved++ 9. Reports fix complete ``` *** ### Manual vs Autonomous #### Manual Workflows **Characteristics:** * Step-by-step control * Review each change * Make decisions at each step * Learn how agentful works * Debug and understand issues **When to use:** * First time using agentful * Complex architectural decisions * Learning the codebase * Small, quick tasks * When you want full control **How to use:** ```bash /agentful-start # Run one task # Review the output /agentful-start # Run next task # Review the output ``` *** #### Autonomous Workflows **Characteristics:** * Hands-off continuous development * agentful makes most decisions * Only interrupt for major decisions * Fastest path to completion * 24/7 development capability **When to use:** * Large feature sets * Overnight development * Well-defined requirements * Clear tech stack * When you want speed **How to use:** ```bash # Ralph loop mode - runs 24/7 until complete /ralph-loop "/agentful-start" \ --max-iterations 50 \ --completion-promise "AGENTFUL_COMPLETE" ``` *** #### Hybrid Workflow (Recommended) **Best of both worlds:** 1. **Start autonomous** for straightforward tasks 2. **Monitor periodically** with `/agentful-status` 3. **Intervene** when agentful asks for decisions 4. **Let it run** again after resolving blockers 5. **Review milestones** at feature boundaries **Example:** ```bash # Start autonomous development /agentful-start # [Let it run 30-60 minutes] # Check progress /agentful-status # If decisions needed: /agentful-decide # Resume autonomous mode /agentful-start ``` *** ### Choosing the Right Workflow #### Decision Tree ``` Start │ ├─ What do you need to build? │ ├─ New feature │ │ → Feature Development Workflow │ │ │ ├─ Fix broken code │ │ → Bug Fixing Workflow │ │ │ ├─ Improve existing code │ │ → Refactoring Workflow │ │ │ └─ Add/improve tests │ → Testing Workflow │ └─ How do you want to work? ├─ Full control, learn system │ → Manual mode │ ├─ Fast, hands-off │ → Autonomous mode │ └─ Balance of both → Hybrid mode (recommended) ``` *** ### Timeline Expectations #### By Project Size | Project Type | Features | Time | Iterations | | ------------ | -------- | ---------------- | ---------- | | **Small** | 3-5 | 30 min - 2 hours | 10-20 | | **Medium** | 6-12 | 2-6 hours | 30-60 | | **Large** | 13-25 | 6-12 hours | 70-150 | #### By Feature Complexity | Complexity | Description | Time per Feature | | ----------- | --------------------------------- | ---------------- | | **Simple** | CRUD, forms, basic UI | 5-15 min | | **Medium** | Auth, APIs, state management | 30-60 min | | **Complex** | Real-time, payments, integrations | 1-3 hours | #### By Workflow Type | Workflow | Avg Time | Variables | | ------------------- | ---------------- | --------------------- | | Feature Development | 30 min - 4 hours | Feature complexity | | Bug Fixing | 10 min - 2 hours | Bug severity | | Refactoring | 1-6 hours | Codebase size | | Testing | 1-4 hours | Coverage requirements | *** ### Monitoring Workflows #### Real-time Monitoring Track progress as agentful works: ```bash # Check current status /agentful-status # Typical output: 🔧 Working on: User Authentication Backend Phase: implementation Iterations: 8 Progress: ████████░░░░░░░░░░░ 40% Quality Gates: ✅ Tests Passing ✅ No Type Errors ⚠️ Coverage 76% (needs 80%) ✅ No Dead Code Next Actions: • /agentful-start - Continue development • /agentful-decide - Answer pending decision ``` #### Progress Indicators Watch these metrics: 1. **Completion Percentage** - Overall progress 2. **Iterations** - Tasks completed 3. **Quality Gates** - Validation status 4. **Pending Decisions** - Blockers to resolve #### State File Inspection Inspect raw state files: ```bash # Current work cat .agentful/state.json # Completion status cat .agentful/completion.json # Pending decisions cat .agentful/decisions.json # Last validation cat .agentful/last-review.json ``` *** ### Troubleshooting Workflows #### Issue: Workflow Not Starting **Symptoms:** `/agentful-start` doesn't begin work **Solutions:** ```bash # Check for pending decisions /agentful-decide # Verify state files exist ls -la .agentful/ # Check PRODUCT.md exists cat PRODUCT.md # Try running orchestrator directly Task("orchestrator", "Test orchestrator") ``` *** #### Issue: Stuck in Loop **Symptoms:** High iterations, no progress **Solutions:** ```bash # Check status /agentful-status # Run validation to see issues /agentful-validate # If validation keeps failing: # 1. Review last-review.json # 2. Fix manually if needed # 3. Restart: /agentful-start ``` *** #### Issue: Quality Gates Failing **Symptoms:** Reviewer keeps finding issues **Solutions:** ```bash # See specific failures /agentful-validate # Let Fixer auto-fix /agentful-start # If Fixer can't resolve: # Manual intervention needed # Review .agentful/last-review.json ``` *** #### Issue: Slow Progress **Symptoms:** Taking too long per feature **Solutions:** 1. **Check feature complexity** - Break into smaller chunks 2. **Review tech stack** - Ensure clear in PRODUCT.md 3. **Reduce scope** - Focus on MVP features 4. **Use autonomous mode** - Faster than manual *** ### Best Practices #### 1. Clear Requirements **Good PRODUCT.md:** ```markdown ### 1. User Authentication - CRITICAL **Description**: Email/password authentication with JWT **Acceptance Criteria**: - [ ] Login endpoint: POST /api/auth/login - [ ] Register endpoint: POST /api/auth/register - [ ] JWT token generation - [ ] Token refresh flow - [ ] Secure password hashing (bcrypt) **Tech Stack**: - Frontend: Next.js 14 - Backend: Next.js API Routes - Auth: JWT (jsonwebtoken) - Database: PostgreSQL + Prisma ``` **Bad PRODUCT.md:** ```markdown ## Features 1. Authentication 2. User management 3. Dashboard ``` *** #### 2. Let Agents Work **Do:** * Start the workflow and let it run * Check in periodically * Answer decisions when prompted * Review completed features **Don't:** * Interrupt after every file * Micromanage agent decisions * Change PRODUCT.md mid-workflow * Edit files while agents work *** #### 3. Use Quality Gates Quality gates are your friend: * ✅ **Prevent bad code** from entering codebase * ✅ **Ensure test coverage** before marking complete * ✅ **Catch security issues** early * ✅ **Maintain code quality** over time **Don't skip validation:** ```bash # Good: Always validate after major features /agentful-start # Complete feature /agentful-validate # Verify quality # Bad: Skip validation /agentful-start # Complete feature # Move on immediately without checking ``` *** #### 4. Monitor Progress Check status regularly: ```bash # Every 30-60 minutes during active development /agentful-status # After each completed feature /agentful-status ``` Look for: * ✅ Increasing completion percentage * ✅ Features moving to "complete" * ✅ Quality gates passing * ⚠️ Pending decisions (resolve quickly) * ⚠️ Stuck iterations (investigate) *** #### 5. Resolve Decisions Quickly Pending decisions block progress: ```bash # When warned about decisions: ⚠️ Pending decisions need your input # Resolve immediately: /agentful-decide # Then resume: /agentful-start ``` **Why:** Each decision can block multiple features. Fast resolution = faster development. *** ### Advanced Workflow Patterns #### Parallel Feature Development ```bash # Work on 2 features simultaneously # .agentful/state.json { "parallel_tasks": 2, "active_tasks": [ "auth-backend", "user-profile-frontend" ] } /agentful-start ``` *** #### Feature Branching ```bash # Create branch for feature git checkout -b feature/authentication # Run autonomous workflow /agentful-start # When complete, commit and merge git add . git commit -m "feat: authentication system" git checkout main git merge feature/authentication ``` *** #### Incremental Delivery ```bash # Deliver features in batches # PRODUCT.md ## Phase 1 - MVP - Authentication - User profile - Basic dashboard ## Phase 2 - Enhancement - Advanced search - Notifications - Settings # Run for Phase 1 only /agentful-start # Deliver Phase 1, then run for Phase 2 /agentful-start ``` *** #### Rollback Workflow ```bash # If something goes wrong: # 1. Stop agentful # 2. Review changes git diff # 3. Rollback if needed git reset --hard HEAD # 4. Reset state echo '{"version":"1.0","current_task":null,"current_phase":"idle","iterations":0}' > .agentful/state.json # 5. Start fresh /agentful-start ``` *** ### Next Steps
#### Start Building Learn the feature development workflow end-to-end → [Feature Development Guide](./feature-development)
#### Fix Bugs Fast Master systematic bug resolution → [Bug Fixing Workflow](./bug-fixing)
#### Improve Code Quality Learn refactoring workflows → [Refactoring Workflow](./refactoring)
#### Achieve Test Coverage Comprehensive testing strategies → [Testing Workflow](./testing)
*** ### Quick Reference **Essential Commands:** * `/agentful-start` - Start autonomous development * `/agentful-status` - Check progress * `/agentful-decide` - Resolve decisions * `/agentful-validate` - Run quality checks **State Files:** * `.agentful/state.json` - Current work state * `.agentful/completion.json` - Feature progress * `.agentful/decisions.json` - Pending decisions * `.agentful/last-review.json` - Validation results **24/7 Development:** ```bash /ralph-loop "/agentful-start" \ --max-iterations 50 \ --completion-promise "AGENTFUL_COMPLETE" ``` ## Refactoring Workflow Complete guide to improving code structure, maintainability, and performance using agentful's systematic refactoring workflow. *** ### Overview The Refactoring workflow improves existing code quality without changing its external behavior. It focuses on code health, maintainability, and performance optimization. #### What This Workflow Delivers * ✅ Improved code structure and organization * ✅ Enhanced maintainability and readability * ✅ Performance optimizations * ✅ Eliminated code duplication * ✅ Better separation of concerns * ✅ Updated tests and documentation #### Typical Timeline | Refactoring Scope | Time | Iterations | | ------------------------------------------- | ---------------- | ---------- | | **Function-level** (single function) | 5-15 minutes | 2-5 | | **Module-level** (related components) | 15-45 minutes | 5-10 | | **Feature-level** (entire feature) | 45 min - 2 hours | 10-20 | | **Codebase-level** (cross-cutting concerns) | 2-6 hours | 20-50 | *** ### Prerequisites Before starting refactoring, ensure: #### 1. Existing Code is Working ```bash # All tests pass npm test ✓ All tests passing # Application runs without errors npm run dev ✓ Dev server running # No validation errors /agentful-validate ✓ All quality gates passing ``` #### 2. Refactoring Goal Defined ```markdown ## Refactoring Goal **What**: Improve user authentication code structure **Why**: - Hard to test (tightly coupled) - Code duplication in auth methods - Difficult to add new auth providers **Success Criteria**: - [ ] Clear separation of concerns - [ ] No code duplication - [ ] Easy to add new auth providers - [ ] All tests still pass - [ ] No behavior changes ``` #### 3. Baseline Metrics Recorded ```bash # Record current state npm test -- --coverage --json > .agentful/baseline-coverage.json npx tsc --noEmit > .agentful/baseline-types.txt npm run lint > .agentful/baseline-lint.txt # Record performance (if applicable) # Bundle size, load time, etc. ``` *** ### The Refactoring Loop #### Complete Workflow Diagram ``` ┌─────────────────────────────────────────────────────────────┐ │ START: Refactoring Goal Defined │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 1. CODE ANALYSIS │ │ • Read existing code │ │ • Identify code smells │ │ • Measure metrics (complexity, duplication) │ │ • Find opportunities for improvement │ │ • Prioritize refactoring targets │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. REFACTORING PLAN │ │ • Define refactoring scope │ │ • Identify specific improvements │ │ • Plan incremental changes │ │ • Ensure test coverage │ │ • Document refactoring strategy │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. INCREMENTAL REFACTORING │ │ • Make small, isolated changes │ │ • Run tests after each change │ │ • Preserve behavior at each step │ │ • Commit after verified step │ │ • Continue to next improvement │ └─────────────────────────────────────────────────────────────┘ ↓ Tests failing? │ ┌──────────┴──────────┐ ↓ ↓ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 4a. ROLLBACK │ │ 4b. CONTINUE │ │ • Revert change │ │ • Tests pass │ │ • Fix tests first │ │ • Verify behavior │ │ • Try again │ │ • Next improvement │ └─────────────────────────┘ └─────────────────────────┘ │ │ └──────────┬──────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 5. VALIDATION │ │ • All tests pass │ │ • No behavior changes │ │ • Quality gates pass │ │ • Performance improved or maintained │ │ • Documentation updated │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 6. COMPARISON │ │ • Compare with baseline metrics │ │ • Verify improvements │ │ • Check for regressions │ │ • Document what changed │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 7. COMPLETION │ │ • Update completion.json │ │ • Document refactoring │ │ • Update related docs │ │ • Mark refactoring complete │ └─────────────────────────────────────────────────────────────┘ ``` *** ### Step-by-Step Guide #### Step 1: Code Analysis **Agent:** Orchestrator (delegates to specialist agents) **Time:** 5-15 minutes **Analysis checklist:** ```typescript // Code analysis example: AuthService // 1. Identify code smells // src/services/auth.service.ts export class AuthService { // ❌ CODE SMELL: God class (too many responsibilities) async login(email: string, password: string) { /* 50 lines */ } async register(data: RegisterData) { /* 50 lines */ } async resetToken(email: string) { /* 30 lines */ } async validateToken(token: string) { /* 30 lines */ } async refreshAccessToken(token: string) { /* 40 lines */ } async logout(token: string) { /* 20 lines */ } async OAuthLogin(provider: string, code: string) { /* 60 lines */ } async verifyEmail(token: string) { /* 30 lines */ } async sendPasswordReset(email: string) { /* 30 lines */ } // ❌ CODE SMELL: Long method async login(email: string, password: string) { // 1. Validate input if (!email || !password) { throw new Error('Email and password required'); } if (!this.isValidEmail(email)) { throw new Error('Invalid email format'); } if (password.length < 8) { throw new Error('Password too short'); } // 2. Find user const user = await this.userRepo.findByEmail(email); if (!user) { throw new Error('User not found'); } // 3. Check password const isValid = await this.comparePassword(password, user.password); if (!isValid) { throw new Error('Invalid password'); } // 4. Check if user is locked if (user.lockedUntil && user.lockedUntil > new Date()) { throw new Error('Account locked'); } // 5. Generate tokens const accessToken = this.generateAccessToken(user); const refreshToken = this.generateRefreshToken(user); // 6. Save refresh token await this.tokenRepo.save(refreshToken); // 7. Update last login await this.userRepo.update(user.id, { lastLoginAt: new Date() }); // 8. Clear failed login attempts await this.userRepo.clearFailedAttempts(user.id); // 9. Return result return { user, accessToken, refreshToken }; } // ❌ CODE SMELL: Duplicate validation isValidEmail(email: string) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } // ❌ CODE SMELL: Duplicate validation in register async register(data: RegisterData) { if (!data.email || !data.password) { throw new Error('Email and password required'); } if (!this.isValidEmail(data.email)) { throw new Error('Invalid email format'); } if (data.password.length < 8) { throw new Error('Password too short'); } // ... more duplicate validation } } // 2. Metrics // - Cyclomatic complexity: 15 (should be < 10) // - Lines per function: 50+ (should be < 20) // - Responsibilities: 9 (should be 1) // - Code duplication: 35% (should be < 5%) ``` **Output:** ``` 🔍 Code Analysis Complete Module: AuthService Location: src/services/auth.service.ts Issues Found: 1. God Class • 9 methods, too many responsibilities • 350+ lines total • Handles auth, tokens, validation, locking 2. Long Methods • login(): 50 lines • OAuthLogin(): 60 lines • register(): 45 lines 3. Code Duplication (35%) • Email validation duplicated in 4 places • Password validation duplicated in 3 places • Token generation duplicated in 2 places 4. Low Testability • Tight coupling to repositories • Hard to mock dependencies • No dependency injection 5. Violates SRP (Single Responsibility Principle) • Should separate: - Authentication logic - Token management - Validation - User locking Refactoring Priority: HIGH Estimated Time: 1-2 hours ``` *** #### Step 2: Refactoring Plan **Agent:** @architect **Time:** 5-10 minutes **Plan creation:** ```markdown ## Refactoring Plan: AuthService ### Phase 1: Extract Validation (15 minutes) **Goal**: Create separate validation module **Actions**: 1. Create `src/lib/validation.ts` 2. Extract email validation 3. Extract password validation 4. Add validation schemas **Benefits**: - Remove 35% of code duplication - Reusable across codebase - Easier to test --- ### Phase 2: Extract Token Management (20 minutes) **Goal**: Create TokenService **Actions**: 1. Create `src/services/token.service.ts` 2. Move token generation to TokenService 3. Move token validation to TokenService 4. Move token storage to TokenService **Benefits**: - Single responsibility for tokens - Easier to swap token libraries - Better testability --- ### Phase 3: Simplify AuthService (25 minutes) **Goal**: Focus only on authentication flow **Actions**: 1. Remove token logic (delegates to TokenService) 2. Remove validation logic (delegates to Validation) 3. Extract login steps into smaller functions 4. Add dependency injection **Benefits**: - AuthService focuses on auth flow - Each method < 20 lines - Complexity < 10 --- ### Phase 4: Add Tests (20 minutes) **Goal**: Comprehensive test coverage **Actions**: 1. Unit tests for Validation 2. Unit tests for TokenService 3. Unit tests for AuthService 4. Integration tests for auth flow **Benefits**: - Confidence in refactored code - Prevent regressions --- ### Success Metrics **Before**: - Cyclomatic complexity: 15 - Lines per function: 50+ - Code duplication: 35% - Test coverage: 45% **After** (target): - Cyclomatic complexity: < 10 - Lines per function: < 20 - Code duplication: < 5% - Test coverage: > 80% ### Risk Mitigation 1. **Incremental changes**: One phase at a time 2. **Test after each phase**: No behavior changes 3. **Commit after each phase**: Easy rollback 4. **Baseline tests**: Ensure no regressions ``` *** #### Step 3: Incremental Refactoring **Agent:** @backend **Time:** 60-90 minutes (total) ##### Phase 1: Extract Validation ```typescript // BEFORE: Validation scattered everywhere // src/services/auth.service.ts export class AuthService { isValidEmail(email: string) { return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email); } isValidPassword(password: string) { return password.length >= 8; } async login(email: string, password: string) { if (!this.isValidEmail(email)) { throw new Error('Invalid email'); } if (!this.isValidPassword(password)) { throw new Error('Invalid password'); } // ... } async register(data: RegisterData) { if (!this.isValidEmail(data.email)) { throw new Error('Invalid email'); } if (!this.isValidPassword(data.password)) { throw new Error('Invalid password'); } // ... } } // AFTER: Centralized validation // src/lib/validation.ts import { z } from 'zod'; // Reusable validation schemas export const emailSchema = z.string().email('Invalid email format'); export const passwordSchema = z.string().min(8, 'Password must be at least 8 characters'); export const loginSchema = z.object({ email: emailSchema, password: passwordSchema, }); export const registerSchema = z.object({ email: emailSchema, password: passwordSchema, name: z.string().min(2, 'Name must be at least 2 characters'), }); // Validation functions export function validateEmail(email: string): boolean { return emailSchema.safeParse(email).success; } export function validatePassword(password: string): boolean { return passwordSchema.safeParse(password).success; } // Usage in AuthService // src/services/auth.service.ts import { loginSchema, registerSchema } from '@/lib/validation'; export class AuthService { async login(input: LoginInput) { // Validate using schema const validated = loginSchema.parse(input); // Proceed with validated data const user = await this.userRepo.findByEmail(validated.email); // ... } async register(input: RegisterInput) { // Validate using schema const validated = registerSchema.parse(input); // Proceed with validated data return this.userRepo.create(validated); } } ``` **Run tests after phase 1:** ```bash npm test ✓ All tests passing ✓ No behavior changes ✓ Code duplication reduced from 35% to 15% Commit: "refactor: extract validation to separate module" ``` *** ##### Phase 2: Extract Token Management ```typescript // BEFORE: Token logic mixed with auth // src/services/auth.service.ts export class AuthService { async login(email: string, password: string) { // ... auth logic ... // Token generation mixed in const accessToken = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '15m' }); const refreshToken = jwt.sign({ userId: user.id }, process.env.JWT_SECRET, { expiresIn: '7d' }); await this.tokenRepo.save(refreshToken); return { user, accessToken, refreshToken }; } async verifyToken(token: string) { return jwt.verify(token, process.env.JWT_SECRET); } } // AFTER: Separate TokenService // src/services/token.service.ts export class TokenService { constructor(private tokenRepo: TokenRepository) {} generateAccessToken(user: User): string { return jwt.sign( { userId: user.id, email: user.email }, process.env.JWT_SECRET!, { expiresIn: '15m' } ); } generateRefreshToken(user: User): string { return jwt.sign( { userId: user.id }, process.env.JWT_SECRET!, { expiresIn: '7d' } ); } async createTokenPair(user: User): Promise { const accessToken = this.generateAccessToken(user); const refreshToken = this.generateRefreshToken(user); await this.tokenRepo.save(refreshToken); return { accessToken, refreshToken }; } verifyAccessToken(token: string): TokenPayload { return jwt.verify(token, process.env.JWT_SECRET!) as TokenPayload; } verifyRefreshToken(token: string): TokenPayload { return jwt.verify(token, process.env.JWT_SECRET!) as TokenPayload; } } // Updated AuthService // src/services/auth.service.ts export class AuthService { constructor( private userRepo: UserRepository, private tokenService: TokenService // ✅ Dependency injection ) {} async login(email: string, password: string) { // ... auth logic ... // Delegate token creation to TokenService const tokens = await this.tokenService.createTokenPair(user); return { user, ...tokens }; } async verifyToken(token: string) { return this.tokenService.verifyAccessToken(token); } } ``` **Run tests after phase 2:** ```bash npm test ✓ All tests passing ✓ No behavior changes ✓ Single responsibility: AuthService focuses on auth, TokenService on tokens Commit: "refactor: extract token management to TokenService" ``` *** ##### Phase 3: Simplify AuthService ```typescript // BEFORE: Long, complex methods // src/services/auth.service.ts export class AuthService { async login(email: string, password: string) { // 50 lines of mixed concerns } } // AFTER: Small, focused methods // src/services/auth.service.ts export class AuthService { constructor( private userRepo: UserRepository, private tokenService: TokenService, private lockoutService: LockoutService ) {} async login(email: string, password: string): Promise { // Validate input const validated = loginSchema.parse({ email, password }); // Find user (delegated) const user = await this.findUserByEmail(validated.email); // Check credentials (delegated) await this.verifyCredentials(user, validated.password); // Check lockout (delegated) await this.lockoutService.checkLockout(user); // Generate tokens (delegated) const tokens = await this.tokenService.createTokenPair(user); // Update last login (delegated) await this.userRepo.updateLastLogin(user.id); return { user, ...tokens }; } // Small, focused helper methods private async findUserByEmail(email: string): Promise { const user = await this.userRepo.findByEmail(email); if (!user) { throw new UnauthorizedError('Invalid credentials'); } return user; } private async verifyCredentials(user: User, password: string): Promise { const isValid = await bcrypt.compare(password, user.password); if (!isValid) { await this.lockoutService.recordFailedAttempt(user); throw new UnauthorizedError('Invalid credentials'); } } } ``` **Metrics after phase 3:** ```bash # Before refactoring Cyclomatic complexity: 15 Lines per function: 50+ Test coverage: 45% # After refactoring Cyclomatic complexity: 5 ✅ (reduced 67%) Lines per function: 12 ✅ (reduced 76%) Test coverage: 65% ✅ (improved 20%) Commit: "refactor: simplify AuthService with focused methods" ``` *** ##### Phase 4: Add Comprehensive Tests ```typescript // src/services/__tests__/auth.service.test.ts describe('AuthService', () => { let service: AuthService; let mockUserRepo: UserRepository; let mockTokenService: TokenService; let mockLockoutService: LockoutService; beforeEach(() => { mockUserRepo = createMockUserRepository(); mockTokenService = createMockTokenService(); mockLockoutService = createMockLockoutService(); service = new AuthService( mockUserRepo, mockTokenService, mockLockoutService ); }); describe('login', () => { it('should authenticate user with valid credentials', async () => { // Arrange const user = createTestUser(); mockUserRepo.findByEmail.mockResolvedValue(user); mockTokenService.createTokenPair.mockResolvedValue({ accessToken: 'access-token', refreshToken: 'refresh-token' }); // Act const result = await service.login('test@example.com', 'password123'); // Assert expect(result.user).toEqual(user); expect(result.accessToken).toBe('access-token'); expect(result.refreshToken).toBe('refresh-token'); }); it('should throw error for non-existent user', async () => { // Arrange mockUserRepo.findByEmail.mockResolvedValue(null); // Act & Assert await expect( service.login('missing@example.com', 'password123') ).rejects.toThrow('Invalid credentials'); }); it('should throw error for invalid password', async () => { // Arrange const user = createTestUser(); mockUserRepo.findByEmail.mockResolvedValue(user); mockLockoutService.recordFailedAttempt.mockResolvedValue(undefined); // Act & Assert await expect( service.login('test@example.com', 'wrongpassword') ).rejects.toThrow('Invalid credentials'); expect(mockLockoutService.recordFailedAttempt).toHaveBeenCalledWith(user); }); it('should check lockout before authenticating', async () => { // Arrange const user = createTestUser(); mockUserRepo.findByEmail.mockResolvedValue(user); mockLockoutService.checkLockout.mockImplementation(() => { throw new LockedError('Account locked'); }); // Act & Assert await expect( service.login('test@example.com', 'password123') ).rejects.toThrow('Account locked'); }); }); describe('register', () => { it('should create new user with hashed password', async () => { // Arrange const data = { email: 'new@example.com', password: 'password123', name: 'New User' }; mockUserRepo.create.mockResolvedValue({ id: '123', email: data.email, name: data.name }); // Act const result = await service.register(data); // Assert expect(result).toHaveProperty('id'); expect(result.email).toBe(data.email); expect(mockUserRepo.create).toHaveBeenCalled(); }); }); }); // src/services/__tests__/token.service.test.ts describe('TokenService', () => { it('should generate valid access token', () => { const user = createTestUser(); const service = new TokenService(mockTokenRepo); const token = service.generateAccessToken(user); expect(token).toBeTruthy(); expect(typeof token).toBe('string'); }); it('should verify valid access token', () => { const user = createTestUser(); const service = new TokenService(mockTokenRepo); const token = service.generateAccessToken(user); const payload = service.verifyAccessToken(token); expect(payload.userId).toBe(user.id); }); it('should throw error for invalid token', () => { const service = new TokenService(mockTokenRepo); expect(() => { service.verifyAccessToken('invalid-token'); }).toThrow(); }); }); ``` **Final metrics:** ```bash npm test -- --coverage Coverage Summary: AuthService: 92% ✅ (was 45%) TokenService: 89% ✅ (new) Validation: 95% ✅ (new) Overall coverage: 87% ✅ (target: 80%) Commit: "test: add comprehensive tests for refactored auth" ``` *** #### Step 4: Validation **Agent:** @reviewer **Time:** 2-3 minutes **Validation checks:** ```bash # 1. All tests pass npm test ✓ 65 tests passed (was 25) # 2. No behavior changes # Run E2E tests npm run test:e2e ✓ All user flows work correctly # 3. Quality gates /agentful-validate Quality Gates: ✅ TypeScript: No errors ✅ Lint: No errors ✅ Dead Code: None ✅ Tests: All passing ✅ Coverage: 87% (target 80%) ✅ Security: No issues # 4. Performance comparison # Before: 850ms for login flow # After: 720ms for login flow # ✅ 15% performance improvement # 5. Code metrics comparison # Cyclomatic complexity: 15 → 5 ✅ # Lines per function: 50 → 12 ✅ # Code duplication: 35% → 3% ✅ ``` **Output:** ``` ✅ Refactoring Complete: AuthService Time: 1 hour 45 minutes Commits: 4 (one per phase) Improvements: • Cyclomatic complexity: 15 → 5 (67% reduction) • Lines per function: 50 → 12 (76% reduction) • Code duplication: 35% → 3% (91% reduction) • Test coverage: 45% → 87% (93% increase) • Performance: 15% faster login flow Quality Gates: ✅ All tests passing (65/65) ✅ No behavior changes ✅ No regressions detected ✅ Documentation updated Modules Created: ✓ src/lib/validation.ts ✓ src/services/token.service.ts ✓ src/services/lockout.service.ts Modules Refactored: ✓ src/services/auth.service.ts (simplified) Tests Added: ✓ 40 new tests ✓ All refactored modules covered Ready to ship! ``` *** ### Real Example: Refactoring Todo List #### Before: Tightly Coupled ```typescript // src/components/TodoList.tsx export function TodoList() { const [todos, setTodos] = useState([]); const [filter, setFilter] = useState<'all' | 'active' | 'completed'>('all'); // ❌ Mixed concerns: fetching, filtering, state management useEffect(() => { fetch('/api/todos') .then(res => res.json()) .then(data => setTodos(data)); }, []); // ❌ Complex filtering logic inside component const filteredTodos = useMemo(() => { switch (filter) { case 'active': return todos.filter(t => !t.completed); case 'completed': return todos.filter(t => t.completed); default: return todos; } }, [todos, filter]); // ❌ Business logic in component const addTodo = async (text: string) => { const newTodo = await fetch('/api/todos', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text, completed: false }) }).then(res => res.json()); setTodos([...todos, newTodo]); }; const toggleTodo = async (id: string) => { const todo = todos.find(t => t.id === id); const updated = await fetch(`/api/todos/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ completed: !todo.completed }) }).then(res => res.json()); setTodos(todos.map(t => t.id === id ? updated : t)); }; const deleteTodo = async (id: string) => { await fetch(`/api/todos/${id}`, { method: 'DELETE' }); setTodos(todos.filter(t => t.id !== id)); }; // ❌ 120+ lines in single component return (
{/* UI code mixed with business logic */}
); } ``` **Issues:** * 120+ lines * Mixed concerns (data fetching, business logic, UI) * Hard to test * Duplicated API calls * No separation of concerns *** #### After: Separated Concerns ```typescript // 1. Custom hook for data management // src/hooks/useTodos.ts export function useTodos() { const [todos, setTodos] = useState([]); const [filter, setFilter] = useState('all'); // ✅ Data fetching separated useEffect(() => { todoApi.getAll().then(setTodos); }, []); // ✅ API calls delegated to service const addTodo = async (text: string) => { const newTodo = await todoApi.create({ text, completed: false }); setTodos(prev => [...prev, newTodo]); }; const toggleTodo = async (id: string) => { const todo = todos.find(t => t.id === id); const updated = await todoApi.update(id, { completed: !todo.completed }); setTodos(prev => prev.map(t => t.id === id ? updated : t)); }; const deleteTodo = async (id: string) => { await todoApi.delete(id); setTodos(prev => prev.filter(t => t.id !== id)); }; // ✅ Filtering logic in hook const filteredTodos = useMemo(() => { return filterTodos(todos, filter); }, [todos, filter]); return { todos: filteredTodos, filter, setFilter, addTodo, toggleTodo, deleteTodo }; } // 2. API service // src/lib/todoApi.ts export const todoApi = { getAll: () => fetch('/api/todos').then(res => res.json()), create: (data: CreateTodoDto) => fetch('/api/todos', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }).then(res => res.json()), update: (id: string, data: UpdateTodoDto) => fetch(`/api/todos/${id}`, { method: 'PATCH', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }).then(res => res.json()), delete: (id: string) => fetch(`/api/todos/${id}`, { method: 'DELETE' }), }; // 3. Utility functions // src/lib/todoUtils.ts export function filterTodos(todos: Todo[], filter: Filter): Todo[] { switch (filter) { case 'active': return todos.filter(t => !t.completed); case 'completed': return todos.filter(t => t.completed); default: return todos; } } // 4. Simplified component (only UI) // src/components/TodoList.tsx export function TodoList() { // ✅ All business logic in hook const { todos, filter, setFilter, addTodo, toggleTodo, deleteTodo } = useTodos(); // ✅ Component only handles UI return (
); } ``` **Improvements:** * Component: 120 lines → 15 lines (87% reduction) * Separation of concerns * Easy to test * Reusable logic * Clear responsibilities *** ### Refactoring Patterns #### 1. Extract Method **When:** Method is too long or does multiple things **Before:** ```typescript function processOrder(order: Order) { // 50 lines of validation, processing, saving } ``` **After:** ```typescript function processOrder(order: Order) { validateOrder(order); const processed = calculateOrder(order); saveOrder(processed); } ``` *** #### 2. Extract Class **When:** Class has too many responsibilities **Before:** ```typescript class UserService { async create() { /* ... */ } async authenticate() { /* ... */ } async sendEmail() { /* ... */ } async generateReport() { /* ... */ } } ``` **After:** ```typescript class UserService { async create() { /* ... */ } async authenticate() { /* ... */ } } class EmailService { async sendEmail() { /* ... */ } } class ReportService { async generateReport() { /* ... */ } } ``` *** #### 3. Replace Conditional with Polymorphism **When:** Complex switch/if-else chains **Before:** ```typescript function calculateDiscount(order: Order) { if (order.type === 'regular') { return order.total * 0.05; } else if (order.type === 'premium') { return order.total * 0.10; } else if (order.type === 'vip') { return order.total * 0.15; } } ``` **After:** ```typescript interface DiscountStrategy { calculate(order: Order): number; } class RegularDiscount implements DiscountStrategy { calculate(order: Order) { return order.total * 0.05; } } class PremiumDiscount implements DiscountStrategy { calculate(order: Order) { return order.total * 0.10; } } class VipDiscount implements DiscountStrategy { calculate(order: Order) { return order.total * 0.15; } } ``` *** #### 4. Extract Module **When:** Related functionality scattered across files **Before:** ```typescript // Auth duplicated across multiple files // auth.service.ts, user.service.ts, session.service.ts ``` **After:** ```typescript // src/features/auth/ // - services/ // - components/ // - hooks/ // - types/ ``` *** ### Best Practices #### 1. Refactor in Small Steps ```bash # Good: One small change at a time 1. Extract validation 2. Run tests 3. Commit 4. Extract tokens 5. Run tests 6. Commit # Bad: Big bang refactor 1. Rewrite entire module 2. Tests fail everywhere 3. Can't debug 4. Hard to rollback ``` *** #### 2. Test Continuously ```bash # After every change npm test # If tests fail: # 1. Fix tests # 2. Or revert change # 3. Try different approach # Never proceed with failing tests ``` *** #### 3. Preserve Behavior ```bash # Refactoring ≠ Adding features Before: User can login After: User can login (same behavior) Only implementation changes, external behavior stays the same ``` *** #### 4. Document Changes ```bash # Good commit messages refactor: extract validation to separate module - Created src/lib/validation.ts - Moved email/password validation - Replaced with reusable schemas - Reduced code duplication by 35% No behavior changes. All tests passing. ``` *** #### 5. Measure Improvement ```bash # Before refactoring - Code complexity: 15 - Test coverage: 45% - Duplication: 35% # After refactoring - Code complexity: 5 ✅ - Test coverage: 87% ✅ - Duplication: 3% ✅ # Verify improvements before considering complete ``` *** ### Next Steps
#### Feature Development After refactoring, build new features confidently → [Feature Development Guide](./feature-development)
#### Testing Workflow Improve test coverage with testing workflow → [Testing Guide](./testing)
*** ### Quick Reference **Start Refactoring:** ```bash /agentful-start # Specify refactoring goal in prompt ``` **Validate Refactoring:** ```bash /agentful-validate # Ensure no regressions ``` **Compare Metrics:** ```bash # Before npm test -- --coverage > baseline.json # After npm test -- --coverage > current.json diff baseline.json current.json ``` ## Testing Workflow Complete guide to achieving comprehensive test coverage (80%+) using agentful's systematic testing workflow. *** ### Overview The Testing workflow ensures code quality through comprehensive testing including unit tests, integration tests, and E2E tests. It achieves and maintains ≥80% coverage across the codebase. #### What This Workflow Delivers * ✅ Unit tests for all services and components * ✅ Integration tests for API endpoints * ✅ E2E tests for critical user flows * ✅ Test coverage ≥ 80% * ✅ Fast, reliable test suites * ✅ Regression prevention #### Typical Timeline | Testing Scope | Time | Test Count | | -------------------------------- | ------------- | ------------ | | **Component** (single component) | 5-15 minutes | 3-8 tests | | **Service** (single service) | 10-20 minutes | 8-15 tests | | **Feature** (complete feature) | 30-60 minutes | 20-40 tests | | **Suite** (multiple features) | 1-4 hours | 50-150 tests | *** ### Prerequisites Before starting testing, ensure: #### 1. Code to Test is Available ```bash # Code exists ls src/ # Dependencies installed npm install # Can run tests npm test -- --passWithNoTests ``` #### 2. Testing Framework Configured ```javascript // vitest.config.ts import { defineConfig } from 'vitest/config'; export default defineConfig({ test: { globals: true, environment: 'jsdom', // For component tests setupFiles: './src/test/setup.ts', coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], exclude: [ 'node_modules/', 'src/test/', '**/*.d.ts', ], }, }, }); ``` #### 3. Test Utilities Available ```typescript // src/test/setup.ts import { vi } from 'vitest'; import '@testing-library/jest-dom'; // Global mocks vi.mock('next/navigation', () => ({ useRouter: () => ({ push: vi.fn(), replace: vi.fn(), }), useSearchParams: () => new URLSearchParams(), })); // Test utilities export function createMockUser(overrides = {}) { return { id: '123', email: 'test@example.com', name: 'Test User', ...overrides, }; } ``` *** ### The Testing Loop #### Complete Workflow Diagram ``` ┌─────────────────────────────────────────────────────────────┐ │ START: Testing Goal Defined │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 1. TEST STRATEGY │ │ • Identify what needs testing │ │ • Categorize by type (unit/integration/E2E) │ │ • Determine coverage gaps │ │ • Prioritize critical paths │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 2. UNIT TESTS │ │ • Test individual functions │ │ • Test component rendering │ │ • Test hooks behavior │ │ • Mock external dependencies │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 3. INTEGRATION TESTS │ │ • Test API endpoints │ │ • Test module interactions │ │ • Test database operations │ │ • Test data flow │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 4. E2E TESTS │ │ • Test complete user flows │ │ • Test cross-feature scenarios │ │ • Test real browser interactions │ │ • Test critical paths │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 5. COVERAGE ANALYSIS │ │ • Run coverage report │ │ • Identify uncovered code │ │ • Add tests for gaps │ │ • Reach 80% threshold │ └─────────────────────────────────────────────────────────────┘ ↓ Coverage < 80%? │ ┌──────────┴──────────┐ ↓ ↓ ┌─────────────────────────┐ ┌─────────────────────────┐ │ 6a. ADD MORE TESTS │ │ 6b. COVERAGE MET │ │ • Identify gaps │ │ • All critical paths │ │ • Test edge cases │ │ • ≥80% coverage │ │ • Re-measure │ │ • All tests passing │ └─────────────────────────┘ └─────────────────────────┘ │ │ └──────────┬──────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 7. VALIDATION │ │ • All tests pass │ │ • Coverage threshold met │ │ • Tests are deterministic │ │ • Tests run fast (<5 seconds for unit) │ └─────────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ 8. COMPLETION │ │ • Update completion.json │ │ • Document test suite │ │ • Set up CI/CD integration │ │ • Mark testing complete │ └─────────────────────────────────────────────────────────────┘ ``` *** ### Step-by-Step Guide #### Step 1: Test Strategy **Agent:** @orchestrator **Time:** 5-10 minutes **Strategy creation:** ```markdown ## Test Strategy: User Authentication ### Testing Scope **Modules to Test:** 1. AuthService (src/services/auth.service.ts) 2. TokenService (src/services/token.service.ts) 3. LoginForm (src/components/auth/LoginForm.tsx) 4. Login API (src/app/api/auth/login/route.ts) 5. Registration flow (E2E) **Test Categories:** #### 1. Unit Tests (40 tests) - AuthService: 15 tests - login() with valid credentials - login() with invalid credentials - login() with non-existent user - register() with valid data - register() with duplicate email - register() with weak password - password validation - email validation - token generation - token verification - account locking - failed login tracking - logout functionality - session management - error handling - TokenService: 10 tests - generateAccessToken() - generateRefreshToken() - verifyAccessToken() - verifyRefreshToken() - token expiration - invalid token handling - token payload encoding - token signature validation - token refresh flow - token revocation - LoginForm Component: 10 tests - renders email input - renders password input - renders submit button - shows validation errors - disables button while loading - calls login on submit - redirects on success - shows error message - handles network errors - accessible form labels - useAuth Hook: 5 tests - returns user state - returns login function - returns logout function - updates user on login - clears user on logout #### 2. Integration Tests (8 tests) - POST /api/auth/login - success with valid credentials - 401 with invalid credentials - 400 with missing fields - returns token on success - returns user data - rate limiting - account lockout - session creation #### 3. E2E Tests (3 tests) - Registration flow - navigate to register - fill form - submit - verify redirect - verify login - Login flow - navigate to login - fill credentials - submit - verify redirect to dashboard - verify user displayed - Logout flow - login - click logout - verify redirect to login - verify session cleared ### Coverage Goals **Target:** 87% coverage **Current:** 45% coverage **Gap:** +42 percentage points **Priority Areas:** 1. Critical paths (login, register) - 100% coverage 2. Error handling - 95% coverage 3. Edge cases - 80% coverage 4. UI components - 85% coverage ### Success Criteria - ✅ All 51 tests passing - ✅ 87% coverage (≥80% threshold) - ✅ No flaky tests - ✅ Unit tests run in <3 seconds - ✅ Integration tests run in <10 seconds - ✅ E2E tests run in <30 seconds ``` *** #### Step 2: Unit Tests **Agent:** @tester **Time:** 30-45 minutes ##### Service Tests ```typescript // src/services/__tests__/auth.service.test.ts import { describe, it, expect, vi, beforeEach } from 'vitest'; import { AuthService } from '../auth.service'; import { UserRepository } from '../../repositories/user.repository'; import { TokenService } from '../token.service'; describe('AuthService', () => { let service: AuthService; let mockUserRepo: UserRepository; let mockTokenService: TokenService; beforeEach(() => { // Create mocks mockUserRepo = { findByEmail: vi.fn(), create: vi.fn(), update: vi.fn(), } as any; mockTokenService = { createTokenPair: vi.fn(), verifyAccessToken: vi.fn(), } as any; service = new AuthService(mockUserRepo, mockTokenService); }); describe('login', () => { it('should authenticate user with valid credentials', async () => { // Arrange const user = createMockUser({ id: '123', email: 'test@example.com', password: 'hashed-password', }); mockUserRepo.findByEmail.mockResolvedValue(user); mockTokenService.createTokenPair.mockResolvedValue({ accessToken: 'access-token', refreshToken: 'refresh-token', }); // Act const result = await service.login('test@example.com', 'password123'); // Assert expect(result.user).toEqual(user); expect(result.accessToken).toBe('access-token'); expect(result.refreshToken).toBe('refresh-token'); expect(mockUserRepo.findByEmail).toHaveBeenCalledWith('test@example.com'); expect(mockTokenService.createTokenPair).toHaveBeenCalledWith(user); }); it('should throw error for non-existent user', async () => { // Arrange mockUserRepo.findByEmail.mockResolvedValue(null); // Act & Assert await expect( service.login('missing@example.com', 'password123') ).rejects.toThrow('Invalid credentials'); expect(mockUserRepo.findByEmail).toHaveBeenCalledWith('missing@example.com'); expect(mockTokenService.createTokenPair).not.toHaveBeenCalled(); }); it('should throw error for invalid password', async () => { // Arrange const user = createMockUser({ password: 'hashed-password', }); mockUserRepo.findByEmail.mockResolvedValue(user); mockUserRepo.findByEmail.mockImplementation(async (email: string) => { if (email === 'test@example.com') { // Simulate password verification failure const userWithWrongPassword = { ...user }; (userWithWrongPassword as any).verifyPassword = vi.fn().mockResolvedValue(false); return userWithWrongPassword; } return null; }); // Act & Assert await expect( service.login('test@example.com', 'wrongpassword') ).rejects.toThrow('Invalid credentials'); }); it('should handle account lockout', async () => { // Arrange const lockedUser = createMockUser({ lockedUntil: new Date(Date.now() + 3600000), // Locked for 1 hour }); mockUserRepo.findByEmail.mockResolvedValue(lockedUser); // Act & Assert await expect( service.login('locked@example.com', 'password123') ).rejects.toThrow('Account locked'); expect(mockTokenService.createTokenPair).not.toHaveBeenCalled(); }); it('should update last login on success', async () => { // Arrange const user = createMockUser(); mockUserRepo.findByEmail.mockResolvedValue(user); mockTokenService.createTokenPair.mockResolvedValue({ accessToken: 'token', refreshToken: 'refresh', }); mockUserRepo.update.mockResolvedValue(user); // Act await service.login('test@example.com', 'password123'); // Assert expect(mockUserRepo.update).toHaveBeenCalledWith(user.id, { lastLoginAt: expect.any(Date), }); }); }); describe('register', () => { it('should create new user with hashed password', async () => { // Arrange const userData = { email: 'new@example.com', password: 'password123', name: 'New User', }; const createdUser = createMockUser(userData); mockUserRepo.findByEmail.mockResolvedValue(null); // No existing user mockUserRepo.create.mockResolvedValue(createdUser); // Act const result = await service.register(userData); // Assert expect(result).toEqual(createdUser); expect(mockUserRepo.findByEmail).toHaveBeenCalledWith(userData.email); expect(mockUserRepo.create).toHaveBeenCalledWith({ email: userData.email, password: expect.any(String), // Hashed password name: userData.name, }); expect(mockUserRepo.create).toHaveBeenCalledWith( expect.objectContaining({ password: expect.not.toBe(userData.password), // Password was hashed }) ); }); it('should throw error for duplicate email', async () => { // Arrange const existingUser = createMockUser({ email: 'existing@example.com', }); mockUserRepo.findByEmail.mockResolvedValue(existingUser); // Act & Assert await expect( service.register({ email: 'existing@example.com', password: 'password123', name: 'User', }) ).rejects.toThrow('User already exists'); expect(mockUserRepo.create).not.toHaveBeenCalled(); }); it('should validate password strength', async () => { // Arrange mockUserRepo.findByEmail.mockResolvedValue(null); // Act & Assert await expect( service.register({ email: 'test@example.com', password: 'weak', // Too short name: 'Test User', }) ).rejects.toThrow('Password must be at least 8 characters'); }); }); describe('verifyToken', () => { it('should verify valid access token', async () => { // Arrange const payload = { userId: '123', email: 'test@example.com' }; mockTokenService.verifyAccessToken.mockReturnValue(payload); // Act const result = service.verifyToken('valid-token'); // Assert expect(result).toEqual(payload); expect(mockTokenService.verifyAccessToken).toHaveBeenCalledWith('valid-token'); }); it('should throw error for invalid token', async () => { // Arrange mockTokenService.verifyAccessToken.mockImplementation(() => { throw new Error('Invalid token'); }); // Act & Assert expect(() => { service.verifyToken('invalid-token'); }).toThrow('Invalid token'); }); }); }); // Helper function function createMockUser(overrides = {}) { return { id: '123', email: 'test@example.com', password: 'hashed-password', name: 'Test User', createdAt: new Date(), updatedAt: new Date(), lastLoginAt: null, lockedUntil: null, failedLoginAttempts: 0, verifyPassword: vi.fn().mockResolvedValue(true), ...overrides, }; } ``` ##### Component Tests ```typescript // src/components/__tests__/LoginForm.test.tsx import { describe, it, expect, vi } from 'vitest'; import { render, screen, fireEvent, waitFor } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { LoginForm } from '../LoginForm'; describe('LoginForm', () => { it('should render email and password inputs', () => { render(); expect(screen.getByLabelText(/email/i)).toBeInTheDocument(); expect(screen.getByLabelText(/password/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument(); }); it('should show validation errors for empty fields', async () => { const user = userEvent.setup(); render(); // Submit without filling fields const submitButton = screen.getByRole('button', { name: /sign in/i }); await user.click(submitButton); // Wait for validation errors await waitFor(() => { expect(screen.getByText(/email is required/i)).toBeInTheDocument(); expect(screen.getByText(/password is required/i)).toBeInTheDocument(); }); }); it('should show validation error for invalid email', async () => { const user = userEvent.setup(); render(); const emailInput = screen.getByLabelText(/email/i); await user.type(emailInput, 'invalid-email'); const submitButton = screen.getByRole('button', { name: /sign in/i }); await user.click(submitButton); await waitFor(() => { expect(screen.getByText(/invalid email format/i)).toBeInTheDocument(); }); }); it('should call login with correct credentials', async () => { const mockLogin = vi.fn().mockResolvedValue({ user: { id: '123', email: 'test@example.com' }, }); const user = userEvent.setup(); render(); // Fill form await user.type(screen.getByLabelText(/email/i), 'test@example.com'); await user.type(screen.getByLabelText(/password/i), 'password123'); // Submit await user.click(screen.getByRole('button', { name: /sign in/i })); // Assert await waitFor(() => { expect(mockLogin).toHaveBeenCalledWith({ email: 'test@example.com', password: 'password123', }); }); }); it('should disable submit button while loading', async () => { const mockLogin = vi.fn(() => new Promise(resolve => setTimeout(resolve, 1000))); const user = userEvent.setup(); render(); // Fill and submit await user.type(screen.getByLabelText(/email/i), 'test@example.com'); await user.type(screen.getByLabelText(/password/i), 'password123'); const submitButton = screen.getByRole('button', { name: /sign in/i }); await user.click(submitButton); // Button should be disabled and show loading await waitFor(() => { expect(submitButton).toBeDisabled(); expect(screen.getByText(/loading/i)).toBeInTheDocument(); }); }); it('should display error message on login failure', async () => { const mockLogin = vi.fn().mockRejectedValue(new Error('Invalid credentials')); const user = userEvent.setup(); render(); await user.type(screen.getByLabelText(/email/i), 'test@example.com'); await user.type(screen.getByLabelText(/password/i), 'wrongpassword'); await user.click(screen.getByRole('button', { name: /sign in/i })); await waitFor(() => { expect(screen.getByText(/invalid credentials/i)).toBeInTheDocument(); }); }); it('should be accessible with proper labels', () => { render(); expect(screen.getByLabelText(/email/i)).toHaveAttribute('type', 'email'); expect(screen.getByLabelText(/password/i)).toHaveAttribute('type', 'password'); expect(screen.getByRole('button', { name: /sign in/i })).toBeInTheDocument(); }); }); ``` ##### Hook Tests ```typescript // src/hooks/__tests__/useAuth.test.ts import { describe, it, expect, vi, beforeEach } from 'vitest'; import { renderHook, act, waitFor } from '@testing-library/react'; import { useAuth } from '../useAuth'; // Mock fetch global.fetch = vi.fn(); describe('useAuth', () => { beforeEach(() => { vi.clearAllMocks(); localStorage.clear(); }); it('should return initial state', () => { const { result } = renderHook(() => useAuth()); expect(result.current.user).toBeNull(); expect(result.current.isLoading).toBe(true); expect(result.current.isAuthenticated).toBe(false); }); it('should login user and update state', async () => { const mockUser = { id: '123', email: 'test@example.com' }; (global.fetch as any).mockResolvedValueOnce({ ok: true, json: async () => ({ user: mockUser, token: 'access-token' }), }); const { result } = renderHook(() => useAuth()); // Wait for initial check await waitFor(() => { expect(result.current.isLoading).toBe(false); }); // Login await act(async () => { await result.current.login('test@example.com', 'password123'); }); // Assert expect(result.current.user).toEqual(mockUser); expect(result.current.isAuthenticated).toBe(true); expect(global.fetch).toHaveBeenCalledWith('/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@example.com', password: 'password123', }), }); }); it('should logout user and clear state', async () => { const { result } = renderHook(() => useAuth()); // Set initial user await act(async () => { await result.current.login('test@example.com', 'password123'); }); expect(result.current.isAuthenticated).toBe(true); // Logout await act(async () => { await result.current.logout(); }); // Assert expect(result.current.user).toBeNull(); expect(result.current.isAuthenticated).toBe(false); }); it('should handle login errors', async () => { (global.fetch as any).mockRejectedValueOnce(new Error('Network error')); const { result } = renderHook(() => useAuth()); await waitFor(() => { expect(result.current.isLoading).toBe(false); }); await expect( act(async () => { await result.current.login('test@example.com', 'password123'); }) ).rejects.toThrow('Network error'); expect(result.current.user).toBeNull(); expect(result.current.isAuthenticated).toBe(false); }); }); ``` **Output:** ``` 🧪 Tester Agent writing unit tests... Created unit tests: ✓ src/services/__tests__/auth.service.test.ts (18 tests) ✓ src/services/__tests__/token.service.test.ts (10 tests) ✓ src/components/__tests__/LoginForm.test.tsx (8 tests) ✓ src/hooks/__tests__/useAuth.test.ts (5 tests) Running unit tests... ✓ 41 tests passed ✓ Coverage: 73% Time: 18 minutes ``` *** #### Step 3: Integration Tests **Agent:** @tester **Time:** 15-25 minutes ```typescript // src/app/api/auth/__tests__/login.test.ts import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import request from 'supertest'; import { app } from '../../../app'; describe('POST /api/auth/login', () => { let testUserId: string; // Setup: Create test user beforeAll(async () => { const res = await request(app) .post('/api/auth/register') .send({ email: 'test@example.com', password: 'password123', name: 'Test User', }); testUserId = res.body.id; }); // Cleanup: Delete test user afterAll(async () => { await request(app).delete(`/api/users/${testUserId}`); }); it('should login with valid credentials', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'password123', }); expect(res.status).toBe(200); expect(res.body).toHaveProperty('user'); expect(res.body).toHaveProperty('accessToken'); expect(res.body).toHaveProperty('refreshToken'); expect(res.body.user).toHaveProperty('email', 'test@example.com'); expect(res.body.user).not.toHaveProperty('password'); }); it('should reject invalid credentials', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'wrongpassword', }); expect(res.status).toBe(401); expect(res.body).toHaveProperty('error', 'Invalid credentials'); expect(res.body).not.toHaveProperty('accessToken'); }); it('should reject non-existent user', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'nonexistent@example.com', password: 'password123', }); expect(res.status).toBe(401); expect(res.body).toHaveProperty('error'); }); it('should validate required fields', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', // Missing password }); expect(res.status).toBe(400); expect(res.body).toHaveProperty('error'); }); it('should validate email format', async () => { const res = await request(app) .post('/api/auth/login') .send({ email: 'invalid-email', password: 'password123', }); expect(res.status).toBe(400); expect(res.body).toHaveProperty('error'); }); it('should handle rate limiting', async () => { // Attempt 5 failed logins rapidly const promises = Array(5).fill(null).map(() => request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'wrongpassword', }) ); const results = await Promise.all(promises); // Last attempt should be rate limited expect(results[4].status).toBe(429); expect(results[4].body).toHaveProperty('error', 'Too many attempts'); }); it('should lock account after multiple failed attempts', async () => { // Attempt 10 failed logins for (let i = 0; i < 10; i++) { await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'wrongpassword', }); } // Account should be locked const res = await request(app) .post('/api/auth/login') .send({ email: 'test@example.com', password: 'password123', // Correct password }); expect(res.status).toBe(423); // Locked expect(res.body).toHaveProperty('error', 'Account locked'); }); }); ``` **Output:** ``` 🧪 Tester Agent writing integration tests... Created integration tests: ✓ src/app/api/auth/__tests__/login.test.ts (7 tests) ✓ src/app/api/auth/__tests__/register.test.ts (5 tests) Running integration tests... ✓ 12 tests passed ✓ Coverage: 81% Time: 12 minutes ``` *** #### Step 4: E2E Tests **Agent:** @tester **Time:** 15-20 minutes ```typescript // e2e/auth.spec.ts import { test, expect } from '@playwright/test'; test.describe('Authentication Flow', () => { test.beforeEach(async ({ page }) => { // Clear storage before each test await page.context().clearCookies(); await page.evaluate(() => localStorage.clear()); }); test('should register new user', async ({ page }) => { await page.goto('/register'); // Fill registration form await page.fill('[name="email"]', `test-${Date.now()}@example.com`); await page.fill('[name="password"]', 'password123'); await page.fill('[name="name"]', 'Test User'); await page.fill('[name="confirmPassword"]', 'password123'); // Submit await page.click('button[type="submit"]'); // Should redirect to dashboard await expect(page).toHaveURL('/dashboard'); // Should show welcome message await expect(page.locator('text=Welcome')).toBeVisible(); }); test('should login with valid credentials', async ({ page }) => { await page.goto('/login'); // Fill login form await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'password123'); // Submit await page.click('button[type="submit"]'); // Should redirect to dashboard await expect(page).toHaveURL('/dashboard', { timeout: 5000 }); // Should show user menu await expect(page.locator('[aria-label="User menu"]')).toBeVisible(); }); test('should show error for invalid credentials', async ({ page }) => { await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'wrongpassword'); await page.click('button[type="submit"]'); // Should stay on login page await expect(page).toHaveURL('/login'); // Should show error message await expect(page.locator('text=Invalid credentials')).toBeVisible(); }); test('should logout and redirect to login', async ({ page }) => { // Login first await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'password123'); await page.click('button[type="submit"]'); // Wait for dashboard await expect(page).toHaveURL('/dashboard'); // Logout await page.click('[aria-label="User menu"]'); await page.click('text=Logout'); // Should redirect to login await expect(page).toHaveURL('/login'); // Should not show user menu await expect(page.locator('[aria-label="User menu"]')).not.toBeVisible(); }); test('should persist session across page reloads', async ({ page }) => { // Login await page.goto('/login'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'password123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard'); // Reload page await page.reload(); // Should still be logged in await expect(page).toHaveURL('/dashboard'); await expect(page.locator('[aria-label="User menu"]')).toBeVisible(); }); test('should validate email format', async ({ page }) => { await page.goto('/register'); await page.fill('[name="email"]', 'invalid-email'); await page.fill('[name="password"]', 'password123'); await page.fill('[name="name"]', 'Test User'); await page.click('button[type="submit"]'); // Should show validation error await expect(page.locator('text=Invalid email format')).toBeVisible(); // Should not submit await expect(page).toHaveURL('/register'); }); test('should require password confirmation', async ({ page }) => { await page.goto('/register'); await page.fill('[name="email"]', 'test@example.com'); await page.fill('[name="password"]', 'password123'); await page.fill('[name="confirmPassword"]', 'different'); await page.click('button[type="submit"]'); // Should show error await expect(page.locator('text=Passwords do not match')).toBeVisible(); }); }); ``` **Output:** ``` 🧪 Tester Agent writing E2E tests... Created E2E tests: ✓ e2e/auth.spec.ts (7 tests) Running E2E tests... ✓ 7 tests passed ✓ All user flows working Time: 15 minutes ``` *** #### Step 5: Coverage Analysis **Agent:** @reviewer **Time:** 2-3 minutes ```bash npm test -- --coverage ``` **Coverage report:** ``` ----------|---------|----------|---------|---------|------------------- File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s ----------|---------|----------|---------|---------|------------------- All files | 87.3 | 84.2 | 89.1 | 87.3 | auth.service.ts | 94.2 | 92.5 | 100 | 94.5 | 45,78 token.service.ts | 91.8 | 88.3 | 100 | 91.2 | 23 useAuth.ts | 85.7 | 80.0 | 85.7 | 85.7 | 12-15 LoginForm.tsx | 82.1 | 75.0 | 83.3 | 82.1 | 28-32 ----------|---------|----------|---------|---------|------------------- Coverage threshold: 80% Actual coverage: 87.3% ✅ Gaps identified: 1. auth.service.ts:45 - Account lockout edge case 2. auth.service.ts:78 - Token refresh error handling 3. useAuth.ts:12-15 - Session initialization error 4. LoginForm.tsx:28-32 - Accessibility edge case ``` **Fill gaps:** ```typescript // Add tests for uncovered lines // auth.service.ts:45 - Account lockout edge case it('should unlock account after lockout period expires', async () => { const user = createMockUser({ lockedUntil: new Date(Date.now() - 1000), // Expired 1 second ago }); mockUserRepo.findByEmail.mockResolvedValue(user); const result = await service.login('test@example.com', 'password123'); expect(result.user).toEqual(user); expect(mockUserRepo.update).toHaveBeenCalledWith(user.id, { lockedUntil: null, failedLoginAttempts: 0, }); }); ``` **Final coverage:** ``` ----------|---------|----------|---------|---------| File | % Stmts | % Branch | % Funcs | % Lines | ----------|---------|----------|---------|---------| All files | 91.5 | 88.7 | 92.3 | 91.5 | ----------|---------|----------|---------|---------| ✅ Coverage goal achieved: 91.5% (target: 80%) ``` *** #### Step 6: Validation **Agent:** @reviewer **Time:** 1-2 minutes ```bash # All tests pass npm test ✓ 60 tests passed # Coverage met npm test -- --coverage ✓ Coverage: 91.5% (≥80% threshold) # Tests are fast npm test -- --reporter=verbose ✓ Unit tests: 2.8s ✓ Integration tests: 8.2s ✓ E2E tests: 24.1s # No flaky tests npm test -- --repeat=10 ✓ All tests passed on all 10 runs ``` *** #### Final Results ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Testing Workflow Complete ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Module: User Authentication Time: 1 hour 12 minutes Tests Created: • Unit tests: 41 ( AuthService: 18, TokenService: 10, Components: 13) • Integration tests: 12 (Login: 7, Register: 5) • E2E tests: 7 (Complete flows) Total Tests: 60 All Passing: ✅ Coverage: 91.5% (target: 80%) Improvement: +46.5 percentage points Quality Metrics: • Unit test speed: 2.8s ✅ (<3s target) • Integration test speed: 8.2s ✅ (<10s target) • E2E test speed: 24.1s ✅ (<30s target) • Flaky tests: 0 ✅ • Deterministic: ✅ Test Files Created: ✓ src/services/__tests__/auth.service.test.ts ✓ src/services/__tests__/token.service.test.ts ✓ src/components/__tests__/LoginForm.test.tsx ✓ src/hooks/__tests__/useAuth.test.ts ✓ src/app/api/auth/__tests__/login.test.ts ✓ src/app/api/auth/__tests__/register.test.ts ✓ e2e/auth.spec.ts Ready for CI/CD integration! ``` *** ### Test Organization #### File Structure ``` src/ ├── services/ │ ├── auth.service.ts │ └── __tests__/ │ └── auth.service.test.ts ├── components/ │ ├── auth/ │ │ └── LoginForm.tsx │ └── __tests__/ │ └── LoginForm.test.tsx ├── hooks/ │ ├── useAuth.ts │ └── __tests__/ │ └── useAuth.test.ts ├── app/ │ └── api/ │ └── auth/ │ ├── login/ │ │ └── route.ts │ └── __tests__/ │ └── login.test.ts └── test/ ├── setup.ts └── utilities.ts e2e/ └── auth.spec.ts ``` *** ### Best Practices #### 1. Test Behavior, Not Implementation **Good:** ```typescript it('should login user with valid credentials', async () => { const result = await service.login('test@example.com', 'password123'); expect(result).toHaveProperty('user'); expect(result).toHaveProperty('accessToken'); }); ``` **Bad:** ```typescript it('should call userRepository.findByEmail', async () => { await service.login('test@example.com', 'password123'); expect(mockUserRepo.findByEmail).toHaveBeenCalled(); // Testing implementation, not behavior }); ``` *** #### 2. Use Descriptive Test Names **Good:** ```typescript it('should throw error for duplicate email registration', async () => { // Clear what it tests }); ``` **Bad:** ```typescript it('should work', async () => { // Vague, unclear }); ``` *** #### 3. One Assertion Per Test (Mostly) **Good:** ```typescript it('should validate email format', async () => { const result = validateEmail('invalid-email'); expect(result).toBe(false); }); it('should require @ symbol', async () => { const result = validateEmail('invalidemail.com'); expect(result).toBe(false); }); ``` **Acceptable:** ```typescript it('should return user data and tokens on successful login', async () => { const result = await service.login('test@example.com', 'password123'); expect(result).toHaveProperty('user'); expect(result).toHaveProperty('accessToken'); expect(result).toHaveProperty('refreshToken'); // Related assertions OK in one test }); ``` *** #### 4. Mock External Dependencies ```typescript // Good: Mock database const mockDb = { user: { findUnique: vi.fn(), create: vi.fn(), }, }; // Bad: Real database in tests const result = await db.user.findUnique(); // Slow, unreliable, requires test DB ``` *** #### 5. Keep Tests Fast ```typescript // Good: Unit tests run in milliseconds it('should validate email', () => { expect(validateEmail('test@example.com')).toBe(true); }); // Bad: Slow operations in unit tests it('should send email', async () => { await sendEmail('test@example.com'); // Actually sends email! // Very slow, side effects }); // Better: Mock it it('should call email service', async () => { await sendEmail('test@example.com'); expect(mockEmailService.send).toHaveBeenCalled(); }); ``` *** ### Next Steps
#### Feature Development After testing, continue building features with confidence → [Feature Development Guide](./feature-development)
#### Bug Fixing Workflow Fix bugs with regression tests → [Bug Fixing Guide](./bug-fixing)
*** ### 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)
#### Learn Advanced Features 24/7 development, custom agents, workflows → [Advanced Guide](/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 (
{label && ( )} {error && (

{error}

)}
); } ); Input.displayName = 'Input'; ``` ##### Skeleton Loading Component **src/components/ui/skeleton.tsx**: ```typescript import { cn } from '@/lib/utils'; interface SkeletonProps extends React.HTMLAttributes { variant?: 'text' | 'circular' | 'rectangular'; } export function Skeleton({ className, variant = 'rectangular', ...props }: SkeletonProps) { const variants = { text: 'h-4 w-full rounded', circular: 'h-12 w-12 rounded-full', rectangular: 'h-24 w-full rounded-lg', }; return (
); } ``` #### Phase 2: State Management (45 minutes) ##### Zustand Store Setup **src/store/use-store.ts**: ```typescript import { create } from 'zustand'; import { persist } from 'zustand/middleware'; interface UIState { theme: 'light' | 'dark' | 'system'; setTheme: (theme: 'light' | 'dark' | 'system') => void; sidebarOpen: boolean; toggleSidebar: () => void; } interface WeatherState { units: 'metric' | 'imperial'; toggleUnits: () => void; recentSearches: string[]; addRecentSearch: (city: string) => void; clearRecentSearches: () => void; } interface FavoritesState { favorites: string[]; addFavorite: (city: string) => void; removeFavorite: (city: string) => void; isFavorite: (city: string) => boolean; } export const useUIStore = create()( persist( (set) => ({ theme: 'system', setTheme: (theme) => set({ theme }), sidebarOpen: false, toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })), }), { name: 'ui-storage', } ) ); export const useWeatherStore = create()( persist( (set) => ({ units: 'metric', toggleUnits: () => set((state) => ({ units: state.units === 'metric' ? 'imperial' : 'metric' })), recentSearches: [], addRecentSearch: (city) => set((state) => ({ recentSearches: [city, ...state.recentSearches.filter((c) => c !== city)].slice(0, 5), })), clearRecentSearches: () => set({ recentSearches: [] }), }), { name: 'weather-storage', } ) ); export const useFavoritesStore = create()( persist( (set, get) => ({ favorites: [], addFavorite: (city) => set((state) => { if (state.favorites.includes(city)) return state; if (state.favorites.length >= 10) return state; return { favorites: [...state.favorites, city] }; }), removeFavorite: (city) => set((state) => ({ favorites: state.favorites.filter((c) => c !== city), })), isFavorite: (city) => get().favorites.includes(city), }), { name: 'favorites-storage', } ) ); ``` ##### React Query Setup **src/lib/query-client.ts**: ```typescript import { QueryClient } from '@tanstack/react-query'; export const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 10 * 60 * 1000, // 10 minutes cacheTime: 30 * 60 * 1000, // 30 minutes refetchOnWindowFocus: false, retry: 1, }, }, }); ``` **src/app/layout.tsx**: ```typescript 'use client'; import { QueryClientProvider } from '@tanstack/react-query'; import { queryClient } from '@/lib/query-client'; import { ThemeProvider } from 'next-themes'; export default function RootLayout({ children, }: { children: React.ReactNode; }) { return ( {children} ); } ``` #### Phase 3: Weather Features (1.5 hours) ##### Custom Hooks **src/hooks/use-weather.ts**: ```typescript import { useQuery } from '@tanstack/react-query'; import { useWeatherStore } from '@/store/use-store'; import { fetchWeather, fetchForecast } from '@/lib/api'; export function useWeather(city: string) { const units = useWeatherStore((state) => state.units); const weather = useQuery({ queryKey: ['weather', city, units], queryFn: () => fetchWeather(city, units), enabled: !!city, staleTime: 10 * 60 * 1000, // 10 minutes }); return weather; } export function useForecast(city: string) { const units = useWeatherStore((state) => state.units); const forecast = useQuery({ queryKey: ['forecast', city, units], queryFn: () => fetchForecast(city, units), enabled: !!city, staleTime: 30 * 60 * 1000, // 30 minutes }); return forecast; } ``` **src/hooks/use-debounce.ts**: ```typescript import { useState, useEffect } from 'react'; export function useDebounce(value: T, delay: number = 300): T { const [debouncedValue, setDebouncedValue] = useState(value); useEffect(() => { const handler = setTimeout(() => { setDebouncedValue(value); }, delay); return () => { clearTimeout(handler); }; }, [value, delay]); return debouncedValue; } ``` ##### Search Component with Debouncing **src/components/search/search-bar.tsx**: ```typescript 'use client'; import { useState, useEffect } from 'react'; import { Search, X } from 'lucide-react'; import { useDebounce } from '@/hooks/use-debounce'; import { useWeatherStore } from '@/store/use-store'; export function SearchBar() { const [query, setQuery] = useState(''); const debouncedQuery = useDebounce(query, 300); const addRecentSearch = useWeatherStore((state) => state.addRecentSearch); useEffect(() => { if (debouncedQuery.length >= 2) { // Trigger search addRecentSearch(debouncedQuery); } }, [debouncedQuery, addRecentSearch]); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (query.trim()) { // Navigate to search results window.location.href = `/search?q=${encodeURIComponent(query)}`; } }; return (
setQuery(e.target.value)} placeholder="Search city..." className="pl-10 pr-10" /> {query && ( )}
); } ``` ##### Current Weather Component **src/components/weather/current-weather.tsx**: ```typescript 'use client'; import { useWeather } from '@/hooks/use-weather'; import { WeatherIcon } from './weather-icon'; import { TemperatureDisplay } from './temperature-display'; import { WeatherDetails } from './weather-details'; interface CurrentWeatherProps { city: string; } export function CurrentWeather({ city }: CurrentWeatherProps) { const { data: weather, isLoading, error } = useWeather(city); if (isLoading) { return (
); } if (error || !weather) { return (

Failed to load weather data. Please try again.

); } return ( {weather.name} {new Date().toLocaleDateString()}
); } ``` ##### Animated Weather Icon **src/components/weather/weather-icon.tsx**: ```typescript 'use client'; import { motion } from 'framer-motion'; import { Cloud, Sun, CloudRain, CloudSnow, CloudLightning } from 'lucide-react'; import { cn } from '@/lib/utils'; interface WeatherIconProps { condition: string; size?: 'sm' | 'md' | 'lg'; className?: string; } const iconMap = { Clear: Sun, Clouds: Cloud, Rain: CloudRain, Drizzle: CloudRain, Thunderstorm: CloudLightning, Snow: CloudSnow, Mist: Cloud, Fog: Cloud, }; const sizeMap = { sm: 'h-8 w-8', md: 'h-16 w-16', lg: 'h-32 w-32', }; export function WeatherIcon({ condition, size = 'md', className }: WeatherIconProps) { const Icon = iconMap[condition as keyof typeof iconMap] || Sun; return ( ); } ``` ##### Forecast List Component **src/components/forecast/forecast-list.tsx**: ```typescript 'use client'; import { useForecast } from '@/hooks/use-weather'; import { ForecastDay } from './forecast-day'; interface ForecastListProps { city: string; } export function ForecastList({ city }: ForecastListProps) { const { data: forecast, isLoading, error } = useForecast(city); if (isLoading) { return (
{[...Array(7)].map((_, i) => ( ))}
); } 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 (
Welcome Back Sign in to your TaskFlow account
{error && (
{error}
)}
setEmail(e.target.value)} placeholder="you@example.com" required />
setPassword(e.target.value)} placeholder="••••••••" required />

Don't have an account?{' '} Sign up

); } ``` ##### 3.3 Tests **Agent**: `@tester` ##### **tests**/integration/api/auth/login.test.ts ```typescript import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { prisma } from '@/lib/prisma'; import { hashPassword } from '@/lib/auth'; describe('POST /api/auth/login', () => { let testUserId: string; beforeAll(async () => { // Create test user const hashedPassword = await hashPassword('password123'); const user = await prisma.user.create({ data: { email: 'test@example.com', password: hashedPassword, name: 'Test User', }, }); testUserId = user.id; }); afterAll(async () => { // Cleanup await prisma.user.delete({ where: { id: testUserId } }); }); it('should login with valid credentials', async () => { const res = await fetch('http://localhost:3000/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@example.com', password: 'password123', }), }); expect(res.status).toBe(200); const data = await res.json(); expect(data).toHaveProperty('email', 'test@example.com'); expect(data).toHaveProperty('name', 'Test User'); expect(res.headers.get('set-cookie')).toContain('token='); }); it('should reject invalid credentials', async () => { const res = await fetch('http://localhost:3000/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@example.com', password: 'wrongpassword', }), }); expect(res.status).toBe(401); const data = await res.json(); expect(data).toHaveProperty('error'); }); it('should validate required fields', async () => { const res = await fetch('http://localhost:3000/api/auth/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: 'test@example.com' }), }); expect(res.status).toBe(400); }); }); ``` *** #### Phase 4: Workspace Management (1.5 hours) **Agent**: `@backend` → `@frontend` → `@tester` Similar authentication flow applied to workspaces. Key files created: ##### Backend Files * `src/app/api/workspaces/route.ts` - List/create workspaces * `src/app/api/workspaces/[id]/route.ts` - Get/update/delete workspace * `src/app/api/workspaces/[id]/members/route.ts` - Manage members ##### Frontend Files * `src/components/workspaces/WorkspaceList.tsx` * `src/components/workspaces/CreateWorkspaceDialog.tsx` * `src/hooks/useWorkspaces.ts` ##### Tests * `__tests__/unit/services/workspace.service.test.ts` * `__tests__/integration/api/workspaces.test.ts` *** #### Phase 5: Task Management (2 hours) **Agent**: `@backend` → `@frontend` → `@tester` ##### Key Implementation: Task Board with Drag-and-Drop ##### src/components/tasks/TaskBoard.tsx ```typescript 'use client'; import { useState } from 'react'; import { useTasks } from '@/hooks/useTasks'; import { TaskCard } from './TaskCard'; import { CreateTaskDialog } from './CreateTaskDialog'; interface TaskBoardProps { workspaceId: string; } type TaskStatus = 'TODO' | 'IN_PROGRESS' | 'DONE'; export function TaskBoard({ workspaceId }: TaskBoardProps) { const { tasks, isLoading, updateTaskStatus } = useTasks(workspaceId); const [isCreateDialogOpen, setIsCreateDialogOpen] = useState(false); const columns = [ { id: 'TODO', title: 'To Do', color: 'bg-gray-100' }, { id: 'IN_PROGRESS', title: 'In Progress', color: 'bg-blue-50' }, { id: 'DONE', title: 'Done', color: 'bg-green-50' }, ] as const; const handleDrop = async (taskId: string, newStatus: TaskStatus) => { await updateTaskStatus(taskId, newStatus); }; if (isLoading) { return
Loading tasks...
; } return (

Task Board

{columns.map((column) => (

{column.title}

{tasks .filter((task) => task.status === column.id) .map((task) => ( handleDrop(task.id, newStatus)} /> ))}
))}
{isCreateDialogOpen && ( setIsCreateDialogOpen(false)} /> )}
); } ``` *** #### Phase 6: Real-time Updates (1 hour) **Agent**: `@backend` → `@frontend` ##### Implementation: Server-Sent Events ##### src/app/api/workspaces/\[id]/events/route.ts ```typescript import { NextRequest } from 'next/server'; import { prisma } from '@/lib/prisma'; export async function GET( req: NextRequest, { params }: { params: { id: string } } ) { const workspaceId = params.id; const encoder = new TextEncoder(); const stream = new ReadableStream({ async start(controller) { // Send initial connection message controller.enqueue( encoder.encode(`data: ${JSON.stringify({ type: 'connected' })}\n\n`) ); // Poll for updates (every 2 seconds) const interval = setInterval(async () => { const recentTasks = await prisma.task.findMany({ where: { workspaceId, updatedAt: { gte: new Date(Date.now() - 2000), }, }, }); if (recentTasks.length > 0) { controller.enqueue( encoder.encode( `data: ${JSON.stringify({ type: 'tasks_updated', data: recentTasks })}\n\n` ) ); } }, 2000); // Cleanup on close req.signal.addEventListener('abort', () => { clearInterval(interval); controller.close(); }); }, }); return new Response(stream, { headers: { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', Connection: 'keep-alive', }, }); } ``` ##### src/hooks/useTaskUpdates.ts ```typescript 'use client'; import { useEffect, useState } from 'react'; interface TaskUpdate { type: string; data?: any; } export function useTaskUpdates(workspaceId: string) { const [updates, setUpdates] = useState([]); useEffect(() => { const eventSource = new EventSource( `/api/workspaces/${workspaceId}/events` ); eventSource.onmessage = (event) => { const update = JSON.parse(event.data); setUpdates((prev) => [...prev, update]); }; return () => { eventSource.close(); }; }, [workspaceId]); return updates; } ``` *** ### Results #### Time Breakdown | Phase | Duration | Agent | | -------------------- | ------------- | ------------------------------ | | Project Setup | 15 min | @orchestrator | | Database Schema | 20 min | @backend + @architect | | Authentication | 1.5 hours | @backend + @frontend + @tester | | Workspace Management | 1.5 hours | @backend + @frontend + @tester | | Task Management | 2 hours | @backend + @frontend + @tester | | Real-time Updates | 1 hour | @backend + @frontend | | **Total** | **6.5 hours** | | #### Code Metrics ``` File Count: 127 files - Backend files: 42 - Frontend files: 58 - Test files: 27 Lines of Code: ~8,500 lines - Application code: ~6,200 - Test code: ~2,300 Test Coverage: 84% - Unit tests: 89% coverage - Integration tests: 82% coverage - E2E tests: 5 critical flows covered Quality Gates Status: ✅ All tests passing (245 tests) ✅ No type errors (adapts to stack) ✅ No lint errors ✅ Coverage threshold met (84% ≥ 80%) ✅ No dead code ✅ No security vulnerabilities ``` #### Before vs After ##### Before (Empty Project) ``` taskflow/ ├── package.json └── tsconfig.json ``` **Capabilities**: None **Features**: 0/5 implemented **Tests**: 0 ##### After (Completed Application) ``` taskflow/ ├── 127 files ├── 8,500+ lines of code ├── 245 passing tests └── 84% coverage ``` **Capabilities**: * ✅ User registration & login * ✅ Team workspace creation * ✅ Task management with drag-and-drop * ✅ Real-time collaboration * ✅ Role-based permissions **Features**: 5/5 implemented (100%) **Tests**: 245 tests passing *** ### Agent Delegation Sequence #### High-Level Flow ``` User: /agentful-start @orchestrator ├─ Analyze PRODUCT.md ├─ Detect tech stack ├─ Prioritize features └─ Start Phase 1: Authentication @backend ├─ Create Prisma schema ├─ Implement auth service ├─ Create API routes └─ Report completion @frontend ├─ Create useAuth hook ├─ Build login page ├─ Build register page └─ Report completion @tester ├─ Write unit tests ├─ Write integration tests ├─ Run tests └─ Verify 80% coverage @reviewer ├─ Check code quality ├─ Check for dead code ├─ Run security scan └─ Approve phase @orchestrator ├─ Mark authentication complete ├─ Update progress └─ Start Phase 2: Workspaces [Repeat pattern for each feature] @orchestrator ├─ All features complete ├─ Run final validation └─ Report success @fixer (if validation fails) ├─ Identify issues ├─ Fix errors └─ Re-validate ``` *** ### Key Decisions Made During development, agentful encountered these decisions and resolved them: #### Decision 1: Auth Library **Question**: Which auth library to use? **Options**: NextAuth.js, Lucia, Custom JWT **Decision**: Custom JWT implementation **Reasoning**: More control, simpler for this use case, fewer dependencies #### Decision 2: Real-time Approach **Question**: SSE vs WebSockets vs Polling? **Options**: Pusher, WebSockets, SSE, Polling **Decision**: Server-Sent Events **Reasoning**: Built into Next.js, simpler than WebSockets, unidirectional flow sufficient #### Decision 3: State Management **Question**: Which state management library? **Options**: Redux, Zustand, Context API **Decision**: Zustand **Reasoning**: Simpler than Redux, more powerful than Context, great TypeScript support #### Decision 4: Component Library **Question**: Build from scratch or use library? **Options**: Material UI, Chakra UI, shadcn/ui, Custom **Decision**: shadcn/ui **Reasoning**: Copy-paste components, full ownership, Tailwind-based, accessible *** ### Validation Results #### Quality Gates Run 1 (After Phase 3) ``` Running validation... ✅ TypeScript: No errors ✅ Tests: 78/78 passing ✅ Coverage: 82% (threshold: 80%) ⚠️ Lint: 3 warnings - Unused import in AuthForm.tsx - Missing return type in auth.ts - Unused variable in login/page.tsx ✅ Dead Code: None found ✅ Security: No vulnerabilities Status: PASSED (with warnings) ``` #### Quality Gates Run 2 (Final) ``` Running final validation... ✅ TypeScript: No errors ✅ Tests: 245/245 passing ✅ Coverage: 84% (threshold: 80%) ✅ Lint: No errors or warnings ✅ Dead Code: None found ✅ Security: No vulnerabilities ✅ E2E Tests: 5/5 flows passing Status: ALL GATES PASSED 🎉 ``` *** ### Lessons Learned #### What Went Well 1. **Feature Prioritization** - Starting with authentication was the right choice 2. **Incremental Development** - One feature at a time prevented overwhelm 3. **Test-Driven Approach** - Writing tests alongside code caught issues early 4. **Type Safety** - TypeScript prevented many runtime errors #### Challenges Encountered 1. **SSE Implementation** - Required experimentation with Next.js streaming 2. **Drag-and-Drop** - Initial implementation had performance issues, refactored to use simpler approach 3. **Real-time Testing** - Required test setup adjustments for SSE #### Improvements Made 1. Added request validation after discovering missing input sanitization 2. Refactored auth service to separate concerns better 3. Optimized database queries after noticing N+1 issues 4. Added error boundaries after catching React errors *** ### Next Steps for This Project #### Potential Enhancements 1. **Email Notifications** - Notify users of task assignments 2. **File Attachments** - Attach files to tasks 3. **Comments** - Comment threads on tasks 4. **Search & Filters** - Advanced task search 5. **Analytics Dashboard** - Team productivity insights #### Scaling Considerations 1. **Caching** - Add Redis for session and data caching 2. **CDN** - Serve static assets via CDN 3. **Database Optimization** - Add indexes for common queries 4. **Rate Limiting** - Implement stricter rate limiting 5. **Monitoring** - Add error tracking (Sentry) and monitoring *** ### Conclusion This full-stack SaaS application demonstrates agentful's ability to: * Build complex features autonomously * Maintain high code quality standards * Coordinate multiple specialized agents * Deliver working software in hours, not weeks The 6.5-hour development time includes: * Complete authentication system * Team collaboration features * Real-time updates * Comprehensive test suite * Production-ready code **Compare to traditional development**: 2-3 weeks **Time saved**: \~85% *** ### Try It Yourself Want to build this yourself? ```bash # 1. Create project mkdir taskflow && cd taskflow npm init -y # 2. Initialize agentful npx @itz4blitz/agentful init # 3. Copy PRODUCT.md (from this example) # 4. Start building claude /agentful-start # That's it! Come back in 6-8 hours to a working app. ``` *** **Previous**: [Examples Index](/examples/index) **Next**: [API Development Example](/examples/api-development) import { Badge } from '../../components/Badge' import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '../../components/Card' ## Examples Learn from complete, real-world examples of projects built with agentful. Each example shows you: * Complete `PRODUCT.md` specifications * Expected directory structure * Actual code from the implementation * Agent delegation sequences * Before/after comparisons * Time estimates and validation results *** ### Available Examples
Full-Stack SaaS App Comprehensive
Complete task management system with authentication, real-time updates, and team collaboration
Stack:
Next.js 14 TypeScript Prisma PostgreSQL Tailwind Vitest
Features:
  • JWT authentication
  • Team workspaces
  • Task CRUD operations
  • Real-time updates
  • Role-based access
Time Estimate: 6-8 hours with agentful
View Example →
REST API Service Backend-Focused
Express API with comprehensive testing, documentation, and clean architecture
Stack:
Node.js Express TypeScript PostgreSQL Jest Swagger
Features:
  • RESTful API design
  • Repository pattern
  • Request validation
  • Error handling
  • API documentation
Time Estimate: 4-5 hours with agentful
View Example →
Modern Web App Frontend-Focused
Next.js frontend with component library, state management, and responsive design
Stack:
Next.js 14 TypeScript Tailwind Zustand React Query
Features:
  • Component library
  • Custom hooks
  • State management
  • API integration
  • Responsive layouts
Time Estimate: 3-4 hours with agentful
View Example →
Microservices Architecture Coming Soon
Distributed system with multiple services, message queues, and service mesh
Stack:
NestJS Docker RabbitMQ Redis
Features:
  • Service orchestration
  • Event-driven architecture
  • Distributed tracing
  • API Gateway
Coming in future release
*** ### How to Use These Examples #### 1. Learn the Patterns Each example demonstrates: * How to write effective `PRODUCT.md` specs * How agents collaborate and delegate * How to structure your codebase * How to achieve quality gates #### 2. Adapt to Your Needs Use these as starting points: * Copy the `PRODUCT.md` structure * Adjust features for your requirements * Modify tech stack as needed * Scale up or down #### 3. Follow Along Reproduce the examples step-by-step: ```bash # Create new project mkdir my-task-manager && cd my-task-manager npm init -y # Initialize agentful npx @itz4blitz/agentful init # Copy PRODUCT.md from example # Then start building claude /agentful-start ``` *** ### What Makes a Good Example? Each example in this section is: ✅ **Complete** - Full implementation, not snippets ✅ **Working** - Tested and validated code ✅ **Realistic** - Practical features you'd actually build ✅ **Educational** - Shows patterns you can apply ✅ **Reproducible** - Can be built from scratch *** ### Example Structure Each example page includes: #### Product Specification Complete `PRODUCT.md` with: * Overview and goals * Tech stack * Feature list with priorities * User stories * Acceptance criteria #### Implementation Guide Step-by-step walkthrough: * Directory structure * Key files and code * Agent delegation sequence * Common decisions and solutions #### Before & After Visual comparisons: * Empty project → Working application * File count growth * Code metrics * Test coverage #### Results Actual outcomes: * Time to completion * Lines of code generated * Test coverage achieved * Quality gates status *** ### Contributing Examples Have you built something great with agentful? We'd love to see it! Consider contributing: * Unique tech stacks * Different use cases * Performance benchmarks * Best practices learned Join our community and share your experience. *** ### Next Steps Pick an example that matches your project type and dive in: * Building a SaaS product? → **[Full-Stack SaaS App](/examples/full-stack-app)** * Creating an API? → **[REST API Service](/examples/api-development)** * Frontend-only project? → **[Modern Web App](/examples/frontend-project)** Each example is designed to teach you patterns you can apply immediately to your own projects. ## Agents Agents are the **building blocks of agentful** - specialized AI workers, each with a specific domain of expertise, well-defined responsibilities, and clear boundaries. They don't just "write code" - they follow patterns, enforce standards, and collaborate through the orchestrator. ### What Are Agents? An agent is defined by: 1. **Name** - Unique identifier (e.g., `backend`, `frontend`, `tester`) 2. **Description** - What it does, what it doesn't do 3. **Model** - Which AI model powers it (Sonnet for specialists, Opus for coordinators) 4. **Tools** - What it can access (Read, Write, Edit, Bash, Task, etc.) 5. **Scope** - What it's responsible for 6. **Patterns** - How it implements features Here's a typical agent definition: ```markdown --- name: backend description: Implements backend services, repositories, controllers, APIs. Never modifies frontend code. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Backend Agent You are the **Backend Agent**. You implement server-side code using clean architecture patterns. ## Your Scope - API Routes & Controllers - Service Layer - Repository Layer - Database schemas - Authentication ## NOT Your Scope - UI components → @frontend - Tests → @tester - Code review → @reviewer ``` ### Why Multiple Agents? #### The Problem with "Do Everything" AI A single AI agent that tries to do everything suffers from: * **Context confusion** - Frontend patterns mixed with backend patterns * **Quality inconsistency** - Different standards for different domains * **Validation complexity** - Hard to enforce domain-specific rules * **Scalability limits** - Can't specialize in every framework #### The agentful Solution **Specialization = Quality** Each agent: * Knows its domain deeply * Follows consistent patterns * Enforces domain-specific rules * Stays within its boundaries ### The Seven Core Agents #### 1. Orchestrator Agent **The conductor that never plays an instrument** ``` Role: Coordinate all work Model: Opus (most capable) Tools: Read, Write, Edit, Glob, Grep, Task, AskUserQuestion, TodoWrite ``` **Responsibilities:** * Read `PRODUCT.md` to understand what we're building * Track progress in `.agentful/completion.json` * Read state from `.agentful/state.json` * Delegate ALL implementation to specialist agents * Ensure validation happens after every change * Block on user decisions when needed **What it NEVER does:** * Write code directly * Skip validation * Make assumptions about user preferences **Example delegation:** ```javascript Task("backend", "Implement JWT authentication service per PRODUCT.md section 3") Task("reviewer", "Review all authentication changes") Task("tester", "Write tests for authentication module") ``` #### 2. Architect Agent **The tech stack analyst** ``` Role: Analyze tech stack and generate specialized agents Model: Opus Tools: Read, Write, Edit, Glob, Grep, Task ``` **Responsibilities:** * Read `PRODUCT.md` to identify the tech stack * Generate specialized agents for languages/frameworks * Update existing agents with tech-specific patterns * Create `.agentful/architecture.json` documenting decisions **Example output:** ```json { "detected_stack": { "frontend": { "framework": "Next.js", "version": "14", "language": "TypeScript" }, "database": { "provider": "PostgreSQL", "orm": "Prisma" } }, "generated_agents": [ "nextjs-agent", "prisma-agent" ] } ``` #### 3. Backend Agent **Server-side specialist** ``` Role: Implement services, repositories, APIs, databases Model: Sonnet Tools: Read, Write, Edit, Glob, Grep, Bash ``` **Scope:** * API Routes & Controllers * Service Layer (business logic) * Repository Layer (data access) * Database schemas and migrations * Authentication (JWT, sessions, OAuth) * Input validation with Zod * Error handling **NOT its scope:** * UI components → `@frontend` * Tests → `@tester` * Code review → `@reviewer` **Implementation pattern:** ```typescript // Repository Layer export class UserRepository { async findById(id: string): Promise { return db.user.findUnique({ where: { id } }); } } // Service Layer export class UserService { constructor(private repo: UserRepository) {} async registerUser(input: RegisterInput): Promise { const existing = await this.repo.findByEmail(input.email); if (existing) throw new ConflictError('User already exists'); return this.repo.create(input); } } // Controller/Route export async function POST(req: Request) { const body = await req.json(); const service = new UserService(new UserRepository()); const user = await service.registerUser(body); return Response.json(user, { status: 201 }); } ``` #### 4. Frontend Agent **UI and client-side specialist** ``` Role: Implement components, pages, hooks, styling Model: Sonnet Tools: Read, Write, Edit, Glob, Grep, Bash ``` **Scope:** * UI Components (reusable component library) * Pages (route pages and views) * Custom React hooks * State management (Context, Zustand, Redux) * Form handling and validation * Styling (Tailwind, CSS Modules, styled-components) * Client-side logic and interactions **NOT its scope:** * Backend API routes → `@backend` * Database operations → `@backend` * Tests → `@tester` **Implementation pattern:** ```tsx // Component export interface ButtonProps { variant?: 'primary' | 'secondary' | 'danger'; size?: 'sm' | 'md' | 'lg'; isLoading?: boolean; } export const Button = forwardRef( ({ children, variant = 'primary', size = 'md', isLoading, ...props }, ref) => { const baseStyles = 'rounded-lg font-medium transition-colors'; const variants = { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300', }; return ( ); } ); // Custom Hook export function useAuth() { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); useEffect(() => { fetch('/api/auth/me') .then(res => res.json()) .then(data => setUser(data.user)) .finally(() => setIsLoading(false)); }, []); return { user, isLoading }; } ``` #### 5. Tester Agent **Quality assurance specialist** ``` Role: Write comprehensive unit, integration, and E2E tests Model: Sonnet Tools: Read, Write, Edit, Glob, Grep, Bash ``` **Scope:** * Unit Tests (functions, components, services) * Integration Tests (module interactions) * E2E Tests (full user flows) * Test fixtures (setup, teardown, mocks) * Coverage reports and improvement **Target:** 80% coverage threshold **Implementation pattern:** ```typescript describe('UserService', () => { let service: UserService; let mockRepo: UserRepository; beforeEach(() => { mockRepo = { findByEmail: vi.fn(), create: vi.fn(), } as any; service = new UserService(mockRepo); }); it('should create a new user with hashed password', async () => { const input = { email: 'test@example.com', password: 'password123', }; mockRepo.findByEmail = vi.fn().mockResolvedValue(null); mockRepo.create = vi.fn().mockResolvedValue({ id: '1', email: input.email, }); const result = await service.registerUser(input); expect(mockRepo.findByEmail).toHaveBeenCalledWith(input.email); expect(result.email).toBe(input.email); }); it('should throw error if user already exists', async () => { mockRepo.findByEmail = vi.fn().mockResolvedValue({ id: '1' }); await expect(service.registerUser(input)).rejects.toThrow('User already exists'); }); }); ``` #### 6. Reviewer Agent **Code quality enforcer** ``` Role: Review code, find dead code, validate production readiness Model: Sonnet Tools: Read, Glob, Grep, Bash, Write, Edit ``` **Checks (runs all 8):** 1. **TypeScript Check** - `npx tsc --noEmit` 2. **Lint Check** - `npm run lint` 3. **Dead Code Detection** - Find unused exports, files, imports 4. **Test Check** - `npm test` 5. **Coverage Check** - Verify ≥ 80% coverage 6. **Security Check** - Scan for secrets, vulnerabilities, debug logs 7. **Manual Code Review** - Error handling, patterns, best practices 8. **Console Log Check** - Find debug statements **Output format:** ```json { "passed": false, "checks": { "typescript": { "passed": true }, "lint": { "passed": true }, "deadCode": { "passed": false, "issues": [ "Unused export: formatDate in src/utils/date.ts", "Unused file: src/components/OldWidget.tsx" ] }, "tests": { "passed": true }, "coverage": { "passed": false, "actual": 72, "required": 80 }, "security": { "passed": false, "issues": [ "console.log in src/auth/login.ts:45" ] } }, "mustFix": [ "Remove unused export formatDate from src/utils/date.ts", "Delete unused file src/components/OldWidget.tsx", "Add tests to reach 80% coverage (currently at 72%)", "Remove console.log from src/auth/login.ts:45" ] } ``` #### 7. Fixer Agent **Auto-fixer for validation failures** ``` Role: Automatically fix validation failures identified by reviewer Model: Sonnet Tools: Read, Write, Edit, Glob, Grep, Bash ``` **What it fixes:** * Dead code (unused exports, files, imports) * Missing tests (adds tests to reach 80%) * Console.log statements * Hardcoded secrets * Type errors * Lint errors **What it NEVER does:** * Comment out code (removes it) * Add `@ts-ignore` to silence errors * Leave `// TODO: fix this` comments * Make partial fixes **Fix strategy:** ```typescript // Before (dead code) export function formatDate(date: Date): string { // ❌ Unused return date.toISOString(); } export function parseDate(str: string): Date { // ✅ Used return new Date(str); } // After - Fixer deletes unused function entirely export function parseDate(str: string): Date { return new Date(str); } ``` ### Agent Collaboration #### How Agents Work Together ``` ┌─────────────────────────────────────────────────────────────┐ │ User │ │ "Build auth" │ └────────────────────────┬────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────┐ │ Orchestrator │ │ "I'll coordinate, not implement" │ └─────────┬───────────────────────────────────────────────────┘ │ ├──► Architect: "Analyze tech stack" │ └──► Generates nextjs-agent, prisma-agent │ ├──► Backend: "Implement JWT service" │ └──► Creates auth.service.ts │ ├──► Frontend: "Create login page" │ └──► Creates login-form.tsx │ ├──► Tester: "Write auth tests" │ └──► Creates auth.test.ts (target: 80%) │ ├──► Reviewer: "Check everything" │ └──► Finds: console.log, unused import │ └──► Fixer: "Fix the issues" └──► Removes console.log, unused import └──► Reviewer: "All checks passed ✅" └──► Orchestrator: "Update completion.json" ``` #### Communication Protocol Agents **never communicate directly**. All communication flows through: 1. **State files** - `.agentful/state.json`, `.agentful/completion.json` 2. **The orchestrator** - Delegates via Task tool 3. **Artifacts** - Code, tests, documentation Example: ```javascript // Orchestrator delegates to backend Task("backend", "Implement JWT authentication per PRODUCT.md") // Backend completes and reports // "Created auth.service.ts, login route, user repository" // Orchestrator then delegates to reviewer Task("reviewer", "Review all authentication changes") // Reviewer reports issues to state file // .agentful/last-review.json // Orchestrator delegates to fixer Task("fixer", "Fix issues from last-review.json") ``` ### Agent Boundaries #### Clear Scope Separation Each agent has explicit boundaries: ```typescript // Backend Agent - What it DOES export class UserService { // ✅ Service layer logic async registerUser(input: RegisterInput): Promise { const existing = await this.repo.findByEmail(input.email); if (existing) throw new ConflictError('User already exists'); return this.repo.create(input); } } // Backend Agent - What it NEVER does // ❌ Don't create UI components // export function LoginForm() { ... } // ❌ Don't write tests // describe('UserService', () => { ... }); // ❌ Don't review code // npx tsc --noEmit ``` #### Boundary Enforcement Boundaries are enforced by: 1. **Agent instructions** - Explicitly stated in agent definition 2. **Orchestrator delegation** - Right agent for right task 3. **Reviewer validation** - Checks for scope violations 4. **Tool limitations** - Frontend agent doesn't get Bash for API routes ### Why This Architecture Works #### 1. Focus = Quality Each agent focuses on one domain: * Backend agent knows backend patterns deeply * Frontend agent knows UI patterns deeply * Tester agent knows testing strategies deeply #### 2. Parallel Work Multiple agents can work simultaneously: ``` Orchestrator → Backend: "Build user API" → Frontend: "Build user profile UI" → Tester: "Write tests for previous feature" ``` #### 3. Easy Debugging When something goes wrong: * Know exactly which agent was responsible * Check agent's specific rules and patterns * Fix that agent without affecting others #### 4. Scalability Need support for a new framework? * Architect generates a new specialized agent * Existing agents continue unchanged * Orchestrator can delegate to new agent ### Creating Custom Agents You can add your own agents in `.claude/agents/`: ```markdown --- name: mobile description: Implements React Native mobile components and navigation model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Mobile Agent You are the **Mobile Agent**. You implement React Native applications. ## Your Scope - React Native components - Navigation (React Navigation) - Native modules - Mobile-specific patterns ## NOT Your Scope - Web UI → @frontend - Backend APIs → @backend ``` The orchestrator will automatically discover and use your custom agent. ### Summary Agents are agentful's fundamental building blocks: * **Specialized** - Each has a specific domain * **Collaborative** - Work together through orchestrator * **Boundaried** - Clear scopes and responsibilities * **Scalable** - Easy to add new agents * **Quality-focused** - Enforce patterns and standards **Next:** [See how agents are coordinated](./orchestrator) ## Core Concepts Overview agentful represents a paradigm shift in software development - **autonomous product development powered by specialized AI agents**. Instead of writing code yourself, you coordinate a team of AI agents that build your product for you. ### The Core Philosophy **agentful is not a code generator.** It's an autonomous development system that: * **Thinks before it acts** - Analyzes requirements, plans architecture, makes technical decisions * **Works iteratively** - Builds, validates, fixes, and improves in continuous loops * **Maintains quality** - Enforces type safety, testing, code review standards * **Scales efficiently** - Uses the right agent for each task (backend, frontend, testing) * **Respects your decisions** - Asks for input when needed, never guesses critical choices ### Why agentful Exists Traditional development has pain points: | Pain Point | Traditional Approach | agentful Approach | | --------------------- | --------------------------- | -------------------------------------- | | **Boilerplate** | Write it yourself | Agents generate it automatically | | **Testing** | Often skipped or incomplete | 80% coverage enforced | | **Code Review** | Manual, inconsistent | Automated on every change | | **Dead Code** | Accumulates over time | Detected and removed automatically | | **Type Errors** | Found at runtime | Caught before validation passes | | **Context Switching** | You do everything | Specialist agents handle their domains | | **Progress Tracking** | Manual updates | Automatic state tracking | ### The Big Picture agentful orchestrates **seven specialized agents** that work together: ``` ┌─────────────────────────────────────────────────────────────┐ │ Orchestrator │ │ (Coordinates but never codes) │ └────────────┬────────────────────────────────────────────────┘ │ ├──► Architect ──► Analyzes tech stack, generates specialists │ ├──► Backend ────► Services, repositories, APIs │ ├──► Frontend ───► Components, pages, hooks, styling │ ├──► Tester ─────► Unit, integration, E2E tests │ ├──► Reviewer ───► Code quality, dead code detection │ └──► Fixer ──────► Auto-fixes validation issues ``` ### Core Concepts Deep Dive Each core concept builds on this foundation: #### [Agents](./agents) **Specialized AI workers** with distinct responsibilities, scopes, and patterns. The orchestrator delegates work to the right agent based on what needs to be done. #### [Orchestrator](./orchestrator) The **conductor of the symphony** - reads state, picks tasks, delegates to specialists, validates work, and tracks progress. Never writes code directly. #### [Slash Commands](./slash-commands) Your **control interface** for starting, monitoring, and steering autonomous development. Simple commands that trigger complex workflows. #### [Skills](./skills) **Domain-specific capabilities** that can be added to agents to extend their functionality with specialized knowledge. #### [State Management](./state-management) **Progress tracking** through JSON files that capture what's done, what's blocked, what's pending, and what decisions have been made. ### How These Concepts Connect ```mermaid graph TD A[You run /agentful-start] --> B[Orchestrator reads state] B --> C{Need decision?} C -->|Yes| D[Add to decisions.json] C -->|No| E[Pick next task] E --> F[Delegate to Agent] F --> G[Agent uses Skills] G --> H[Implement feature] H --> I[Delegate to Reviewer] I --> J{Checks pass?} J -->|No| K[Delegate to Fixer] K --> I J -->|Yes| L[Update state.json] L --> M{All done?} M -->|No| E M -->|Yes| N[Complete!] ``` ### The Development Loop At its core, agentful follows this loop: 1. **Read State** - Check what's done, what's blocked, what's next 2. **Pick Task** - Choose highest priority unblocked work 3. **Delegate** - Assign to specialist agent with clear instructions 4. **Validate** - Run all quality checks 5. **Fix** - Resolve any issues found 6. **Update** - Record progress in state files 7. **Repeat** - Until 100% complete ### Why This Architecture Matters #### Separation of Concerns Each agent has a **single, well-defined responsibility**: * Backend agent never touches UI code * Frontend agent never modifies API routes * Orchestrator never writes code directly This prevents confusion and ensures expertise is applied where it matters most. #### Continuous Validation Every change is **automatically validated** before being considered complete: * Type errors caught immediately * Tests required for coverage * Dead code removed automatically * Security scans on every change #### Human-in-the-Loop When agentful needs your input: * Development continues on unblocked features * Decisions are recorded with context * You provide guidance, not implementation #### State as Truth Source All progress tracked in **simple JSON files**: * Easy to inspect * Easy to version control * Easy to debug when stuck ### What Makes agentful Different | Aspect | Code Generators | agentful | | -------------- | --------------- | ---------------------- | | **Output** | One-time code | Continuous development | | **Quality** | Variable | Enforced gates | | **Testing** | Maybe | 80% coverage required | | **Iteration** | Manual | Automatic loops | | **Context** | Single prompt | Full product spec | | **Validation** | User checks | Automated | | **Dead Code** | Accumulates | Auto-removed | ### Getting Started with Core Concepts We recommend exploring these concepts in this order: 1. **[Agents](./agents)** - Understand your AI team 2. **[Orchestrator](./orchestrator)** - See how they're coordinated 3. **[Slash Commands](./slash-commands)** - Learn to control the system 4. **[State Management](./state-management)** - Track progress 5. **[Skills](./skills)** - Extend capabilities (optional) Each concept page includes: * **WHY** it exists before **HOW** it works * Real examples from agentful's codebase * Cross-links to related concepts * Practical use cases ### The agentful Promise When you use agentful, you're not just getting code. You're getting: * **Autonomous Development** - Build products while you sleep * **Quality Assurance** - Multiple validation gates * **Progress Tracking** - Always know what's done * **Flexibility** - Intervene when needed, automate when possible * **Scalability** - Add agents for new tech stacks * **Transparency** - See what's happening and why *** **Next:** [Learn about the Agent System](./agents) ## Orchestrator The orchestrator is the **brain of agentful** - the conductor that leads a symphony of specialized agents without ever playing an instrument itself. It doesn't write code. It thinks, plans, delegates, validates, and tracks progress. ### What is the Orchestrator? The orchestrator is an AI agent with a unique constraint: ```markdown --- name: orchestrator description: Coordinates autonomous product development. Reads state, delegates to specialists, tracks progress. NEVER writes code directly. model: opus tools: Read, Write, Edit, Glob, Grep, Task, AskUserQuestion, TodoWrite --- ``` **Key characteristics:** * Uses **Opus model** (most capable for reasoning) * Has **Task tool** (can spawn other agents) * Has **AskUserQuestion tool** (can request input) * **Cannot write code directly** (by design) * Coordinates through **state files** ### Why "Never Code Directly"? #### The Anti-Pattern An orchestrator that writes code leads to: * **Scope confusion** - Mixing frontend and backend concerns * **Quality inconsistency** - Not following domain-specific patterns * **Bypassing specialists** - Underutilizing expert agents * **Bottlenecks** - Everything depends on one agent's knowledge #### The agentful Pattern The orchestrator that **only delegates** ensures: * **Clear separation** - Backend agent handles backend, frontend handles frontend * **Pattern consistency** - Each agent follows its domain's best practices * **Parallel execution** - Multiple agents can work simultaneously * **Expert utilization** - Right tool for the right job ``` ❌ Bad Orchestrator: "I'll implement authentication myself" → Writes auth service → Writes login page → Writes tests → Everything looks the same, no domain expertise ✅ Good Orchestrator: "Backend agent, implement JWT service" "Frontend agent, create login page" "Tester agent, write auth tests" → Each uses domain-specific patterns → Quality is higher → Work can be parallelized ``` ### The Orchestrator's Responsibilities #### 1. State Management The orchestrator is the **steward of state**. It always reads these files first: ```bash # Read in this order 1. PRODUCT.md # What we're building 2. .agentful/state.json # Current work state 3. .agentful/completion.json # What's done/not done 4. .agentful/decisions.json # Pending user decisions ``` **State JSON structure:** `.agentful/state.json` ```json { "version": "1.0", "current_task": "user-profile-backend", "current_phase": "implementing", "iterations": 7, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": [] } ``` `.agentful/completion.json` ```json { "features": { "authentication": { "status": "complete", "score": 100, "completed_at": "2026-01-18T01:00:00Z" }, "user-profile": { "status": "in_progress", "score": 45, "notes": "Backend done, frontend pending" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": true, "coverage_80": false }, "overall": 48 } ``` #### 2. Delegation The orchestrator's primary job is **picking the right agent for each task**: ```javascript // Backend work Task("backend", "Implement user authentication with JWT per PRODUCT.md") // Frontend work Task("frontend", "Create login page with email/password form") // Tests Task("tester", "Write unit tests for auth service") // After ANY work, ALWAYS run reviewer Task("reviewer", "Review all changes in src/auth/") ``` **Delegation rules:** * Always use Task tool (never implement directly) * Be specific about what needs to be done * Reference PRODUCT.md for context * Follow with reviewer for validation #### 3. Decision Handling When user input is needed, the orchestrator: 1. **Adds to decisions.json:** ```json { "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" } ``` 2. **STOPS work** on blocked features 3. **MOVES to next non-blocked work** 4. **TELLS user** to run `/agentful-decide` #### 4. Completion Tracking After validated work, the orchestrator updates completion.json: ```json { "features": { "authentication": { "status": "complete", "score": 100, "completed_at": "2026-01-18T01:00:00Z" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": true, "coverage_80": true }, "overall": 100 } ``` #### 5. Work Selection Priority When selecting next work, the orchestrator uses this order: ``` 1. Critical failures → Broken tests, type errors, blocked PRs 2. Unblock work → Things waiting on a single small decision 3. High priority features → As defined in PRODUCT.md 4. Medium priority features 5. Tests for completed features 6. Polish/Optimization → Only when everything else is done ``` ### The Orchestrator Loop #### Continuous Iteration The orchestrator loops until complete: ``` ┌─────────────────────────────────────────────────────────────┐ │ Orchestrator Loop │ └─────────────────────────────────────────────────────────────┘ 1. Read state files - state.json (current work) - completion.json (progress) - decisions.json (blockers) 2. Check for blockers - If pending decisions exist → Move to unblocked work → Tell user to run /agentful-decide 3. Pick next task - Use priority order - Select highest value unblocked work 4. Delegate to specialist - Task("@backend", "Implement user profile API") - Wait for completion 5. Validate results - Task("@reviewer", "Review profile changes") - If issues found → Task("@fixer", "Fix issues") - Loop validation until clean 6. Update state - completion.json: feature = complete, score = 100 - state.json: current_task = null 7. Check completion - overall == 100? - All gates passing? - All features complete? YES → Output: AGENTFUL_COMPLETE NO → Loop to step 1 ``` #### Example Flow ``` [Read state] → completion.json: auth = 30% (backend done) → state.json: current_task = null [Delegate] → Task("@frontend", "Create login page component") [Wait] → Frontend agent completes: - Created login-form.tsx - Added useAuth hook - Styled with Tailwind [Validate] → Task("@reviewer", "Review login form") [Reviewer finds] - Missing error handling - Unused import - No tests yet [Fix] → Task("@fixer", "Fix reviewer issues") → Fixer removes unused import → Fixer adds error handling → Note: Tests will be added by tester agent [Re-validate] → Task("@reviewer", "Re-review login form") → Reviewer: All checks passed ✅ [Update] → completion.json: auth = 60% (frontend done) [Loop] → What's next? Read state... → Pick next task: "Write auth tests" ``` ### Orchestrator Decision Making #### How It Picks Tasks The orchestrator uses **multi-factor decision making**: ```javascript // Pseudocode of orchestrator logic function pickNextTask(state, completion, decisions) { // Factor 1: Critical failures (highest priority) const failures = getCriticalFailures(completion.gates); if (failures.length > 0) { return fixCriticalFailure(failures[0]); } // Factor 2: Unblock work (high value, low effort) const blocked = getBlockedFeatures(decisions); const unblockable = blocked.filter(f => f.unblockEffort === 'low'); if (unblockable.length > 0) { return unblockFeature(unblockable[0]); } // Factor 3: High priority features const highPriority = getFeaturesByPriority(completion, 'HIGH'); const incomplete = highPriority.filter(f => f.status !== 'complete'); if (incomplete.length > 0) { return continueFeature(incomplete[0]); } // Factor 4: Tests for completed features const untested = getCompletedButUntested(completion); if (untested.length > 0) { return testFeature(untested[0]); } // Factor 5: Polish (only when everything else done) if (completion.overall === 100 && allGatesPassing(completion)) { return null; // Done! } return continueNextFeature(); } ``` #### Intelligent Task Batching The orchestrator can batch related work: ```javascript // Instead of: Task("backend", "Create user repository") Task("backend", "Create user service") Task("backend", "Create user routes") // It batches: Task("backend", "Implement complete user module: - UserRepository with CRUD operations - UserService with business logic - User routes (GET /api/users, POST /api/users) Per PRODUCT.md section 4") ``` This reduces: * Context switching * Validation overhead * State update frequency ### Orchestrator Communication #### With Specialist Agents The orchestrator communicates via **Task tool delegation**: ```javascript // Clear, specific delegation Task("backend", ` Implement JWT authentication per PRODUCT.md section 3: - Create Auth service with login/register methods - Add JWT token generation and validation - Create /api/auth/login and /api/auth/register routes - Use bcrypt for password hashing - Return appropriate error responses `) // Specialist agent completes and reports back // Orchestrator reads output and validates ``` #### With User The orchestrator uses **state files and slash commands**: ```javascript // When decision needed: // 1. Add to decisions.json { "id": "decision-001", "question": "Should auth use JWT or session cookies?", "blocking": ["auth-feature"] } // 2. Update state.json { "blocked_on": ["auth-feature"] } // 3. Tell user "⚠️ Pending decision needed. Run /agentful-decide" // 4. User runs /agentful-decide // 5. Orchestrator reads resolved decision // 6. Removes from blocked_on // 7. Continues work ``` #### With State Files The orchestrator **continuously updates state**: ```javascript // Before work { "current_task": "user-profile-backend", "current_phase": "implementing", "iterations": 7 } // After work { "current_task": null, "current_phase": "idle", "iterations": 8 } // After validation { "features": { "user-profile": { "status": "complete", "score": 100 } }, "overall": 72 } ``` ### Orchestrator in Ralph Loop #### Ralph Wiggum Integration When running in continuous mode (`/ralph-loop`), the orchestrator: 1. **Outputs completion promise** ONLY when truly complete: ``` AGENTFUL_COMPLETE ``` 2. **Loops continuously** until complete: ``` Each iteration: 1. Re-read state files (they may have changed) 2. Pick next work item 3. Delegate to specialist agent 4. Wait for agent to complete 5. Run reviewer 6. Fix any issues found 7. Update completion state 8. Loop (don't output AGENTFUL_COMPLETE yet) ``` 3. **Never outputs AGENTFUL\_COMPLETE prematurely**: ```javascript // ❌ WRONG - Outputs too early if (featureComplete) { output("AGENTFUL_COMPLETE"); } // ✅ RIGHT - Only when truly done if (allFeaturesComplete && allGatesPassing) { output("AGENTFUL_COMPLETE"); } ``` #### Continuous Mode Example ```bash # User starts continuous mode /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" # Orchestrator runs 24/7: Iteration 1: → Implement auth backend (backend agent) → Review finds: 3 issues → Fix issues (fixer agent) → Re-review: ✅ Clean Iteration 2: → Implement auth frontend (frontend agent) → Review: ✅ Clean → Write tests (tester agent) → Coverage: 85% ✅ Iteration 3: → Implement user profile backend → Need decision: "Which fields to include?" → Add to decisions.json → Move to unblocked feature: settings page [... continues for hours ...] Iteration 47: → All features complete (100%) → All gates passing ✅ → Output: AGENTFUL_COMPLETE # Loop exits, work complete! ``` ### Orchestrator Best Practices #### DO ✅ * **Always read state first** - Before any action * **Always delegate** - Never implement directly * **Always validate** - Reviewer after every change * **Always update state** - Track progress accurately * **Move on when blocked** - Don't wait for decisions * **Batch related work** - Reduce overhead * **Be specific** - Clear delegation instructions #### DON'T ❌ * **Never write code** - Delegate to specialists * **Never skip validation** - Always run reviewer * **Never guess decisions** - Ask user via decisions.json * **Never block on single item** - Work on unblocked features * **Never ignore state** - It's the source of truth * **Never promise complete early** - Only when truly done ### Orchestrator vs. Traditional Project Manager | Aspect | Traditional PM | agentful Orchestrator | | --------------------- | ------------------------- | ---------------------- | | **Task assignment** | Manual to team members | Automatic to agents | | **Progress tracking** | Updates, spreadsheets | state.json files | | **Quality control** | Manual code review | Automated reviewer | | **Blocker handling** | Meetings, emails | decisions.json | | **Work selection** | Intuition, priority lists | Algorithmic + priority | | **Availability** | Business hours | 24/7 | | **Speed** | Days/weeks | Minutes/hours | ### Summary The orchestrator is agentful's coordination layer: * **Thinks, doesn't code** - Delegates to specialists * **State-driven** - All decisions based on state files * **Continuous** - Loops until 100% complete * **Blocker-aware** - Works around decisions needed * **Quality-focused** - Validates everything * **Intelligent** - Picks highest value work It's the difference between a **micro-manager** (doing everything yourself) and a **conductor** (coordinating experts to create a symphony). **Next:** [Learn about slash commands](./slash-commands) ## Skills Skills are **domain-specific capabilities** that can be added to agents to extend their functionality with specialized knowledge. Think of skills as "plugins" that give agents superpowers in specific domains. ### What Are Skills? While agents define **roles and responsibilities**, skills define **capabilities and knowledge**. #### Analogy: Agents vs. Skills ``` Agent = Role (e.g., "Backend Developer") → Knows: Architecture patterns, clean code principles → Responsible for: Services, repositories, APIs Skill = Capability (e.g., "Prisma ORM") → Knows: Prisma schema syntax, migration commands → Provides: Database modeling patterns, query patterns Backend Agent + Prisma Skill → Can do: Design schemas, write migrations, optimize queries ``` #### Skill Definition Skills are defined in `.claude/skills/` as markdown files: ````markdown --- name: prisma-orm applies_to: [backend, architect] description: Prisma ORM expertise for database modeling and queries --- # Prisma ORM Skill You have expertise in Prisma ORM. ## Schema Design ```prisma model User { id String @id @default(cuid()) email String @unique password String posts Post[] } ```` ### Common Patterns #### Relations ```prisma // One-to-many model User { posts Post[] } model Post { author User @relation(fields: [authorId], references: [id]) authorId String } ``` #### Migrations ```bash npx prisma migrate dev --name init npx prisma migrate deploy ``` ### Best Practices * Always use `@default(cuid())` for IDs * Use `@unique` for email fields * Add indexes for frequently queried fields ``` ## Why Skills Exist ### Problem: Agents Are Generalists Base agents have **broad knowledge** but **shallow domain-specific expertise**: ``` Backend Agent: ✅ Knows clean architecture ✅ Knows REST API patterns ✅ Knows service/repository pattern ❌ Doesn't know Prisma-specific patterns ❌ Doesn't know Next.js 14 specific API routes ❌ Doesn't know Tailwind utility patterns ``` ### Solution: Skills Add Specialization Skills inject **deep domain knowledge** into agents: ``` Backend Agent + Prisma Skill: ✅ Knows clean architecture ✅ Knows REST API patterns ✅ Knows Prisma schema syntax ✅ Knows Prisma query patterns ✅ Knows migration workflow ✅ Knows relation modeling ```` ## Skill Types ### 1. Technology Skills Specific technologies and frameworks: ```markdown --- name: nextjs-14 applies_to: [frontend, backend, architect] description: Next.js 14 App Router expertise --- # Next.js 14 Skill ## App Router Patterns ### Server Components (Default) ```tsx // src/app/dashboard/page.tsx async function getData() { const res = await fetch('https://api.example.com/data', { cache: 'no-store', }); return res.json(); } export default async function DashboardPage() { const data = await getData(); return
{data.title}
; } ```` #### Client Components (When Needed) ```tsx 'use client'; export function InteractiveButton() { const [count, setCount] = useState(0); return ; } ``` ### Route Handlers ```tsx // src/app/api/users/route.ts import { NextRequest, NextResponse } from 'next/server'; export async function GET(req: NextRequest) { const users = await db.user.findMany(); return NextResponse.json(users); } ``` ```` ### 2. Database Skills ORM and database expertise: ```markdown --- name: postgresql applies_to: [backend, architect] description: PostgreSQL database expertise --- # PostgreSQL Skill ## Query Patterns ### Indexes ```sql CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_post_author ON posts(author_id); ```` #### Full-Text Search ```sql SELECT * FROM posts WHERE to_tsvector(title || ' ' || content) @@ to_tsquery('react'); ``` ### Best Practices * Use `TEXT` instead of `VARCHAR` (no performance penalty) * Use `TIMESTAMPTZ` for timestamps (with timezone) * Add foreign keys for data integrity * Use `EXPLAIN ANALYZE` to optimize queries ```` ### 3. Styling Skills CSS and styling frameworks: ```markdown --- name: tailwind-css applies_to: [frontend] description: Tailwind CSS utility-first styling --- # Tailwind CSS Skill ## Utility Patterns ### Responsive Design ```tsx
{items.map(item => )}
```` #### Dark Mode ```tsx

Adaptive to theme

``` ### Component Patterns #### Card Component ```tsx export function Card({ children, className }) { return (
{children}
); } ``` ```` ### 4. Testing Skills Testing frameworks and strategies: ```markdown --- name: vitest applies_to: [tester] description: Vitest testing framework expertise --- # Vitest Skill ## Test Patterns ### Unit Tests ```typescript import { describe, it, expect, vi } from 'vitest'; describe('UserService', () => { it('should create user with hashed password', async () => { const user = await service.register({ email: 'test@example.com', password: 'password123' }); expect(user.password).not.toBe('password123'); expect(user.password).toMatch(/^\$2[ayb]\$.{56}$/); }); }); ```` #### Mocking ```typescript const mockRepo = { findByEmail: vi.fn().mockResolvedValue(null), create: vi.fn().mockResolvedValue({ id: '1' }) }; ``` ### Coverage Configuration ```javascript // vitest.config.ts export default defineConfig({ test: { coverage: { provider: 'v8', reporter: ['text', 'json', 'html'], thresholds: { lines: 80, functions: 80, branches: 80, statements: 80 } } } }); ``` ```` ### 5. Domain Skills Industry-specific knowledge: ```markdown --- name: ecommerce applies_to: [backend, frontend, architect] description: E-commerce domain expertise --- # E-commerce Domain Skill ## Common Patterns ### Shopping Cart ```typescript interface CartItem { productId: string; quantity: number; variant?: string; } interface Cart { items: CartItem[]; subtotal: number; tax: number; total: number; } ```` #### Inventory Management ```typescript async function checkInventory(productId: string, quantity: number) { const product = await db.product.findUnique({ where: { id: productId } }); if (product.stock < quantity) { throw new InsufficientStockError(product.stock, quantity); } return product; } ``` ### Best Practices * Always use transactions for order creation * Implement optimistic locking for inventory * Cache product data but invalidate on updates * Use webhooks for payment status updates ```` ## How Skills Work ### Skill Loading When an agent is invoked, agentful: 1. **Detects applicable skills** ```bash # Reads skill frontmatter applies_to: [backend, architect] # Checks current agent current_agent = "backend" # → Load this skill ```` 2. **Injects skill knowledge** * Agent definition + skill content = enhanced capabilities * Agent can now use skill-specific patterns * Agent knows best practices from skill 3. **Applies to implementation** * Backend agent using Prisma skill: ```typescript // Knows to use Prisma patterns export class UserRepository { async findById(id: string) { return db.user.findUnique({ where: { id } }); } } ``` #### Skill Composition Multiple skills can be combined: ```javascript Backend Agent + Prisma Skill (database) + JWT Skill (authentication) + Zod Skill (validation) → Can build complete auth system ``` ### Creating Custom Skills You can add your own skills in `.claude/skills/`: ````markdown --- name: your-skill-name applies_to: [agent1, agent2] description: What this skill provides --- # Skill Name Brief description of what this skill does. ## Patterns ### Pattern Name ```language // Code example ```` ### Best Practices * Best practice 1 * Best practice 2 ```` ### Example: Custom API Skill ```markdown --- name: stripe-api applies_to: [backend] description: Stripe payment integration expertise --- # Stripe API Skill ## Payment Patterns ### Create Payment Intent ```typescript import Stripe from 'stripe'; const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!); async function createPaymentIntent(amount: number, currency: string) { const paymentIntent = await stripe.paymentIntents.create({ amount: amount * 100, // Convert to cents currency, automatic_payment_methods: { enabled: true }, }); return paymentIntent; } ```` #### Webhook Handler ```typescript import { headers } from 'next/headers'; export async function POST(req: Request) { const body = await req.text(); const sig = headers().get('stripe-signature')!; let event: Stripe.Event; try { event = stripe.webhooks.constructEvent( body, sig, process.env.STRIPE_WEBHOOK_SECRET! ); } catch (err) { return NextResponse.json({ error: 'Invalid signature' }, { status: 400 }); } switch (event.type) { case 'payment_intent.succeeded': // Handle successful payment break; } return NextResponse.json({ received: true }); } ``` ### Best Practices * Always verify webhook signatures * Store payment intent IDs in your database * Handle idempotency keys for retries * Use Stripe CLI for local testing ``` ## Skill Discovery ### Automatic Skill Loading agentful automatically discovers and loads skills: ``` .claude/ ├── agents/ │ ├── backend.md │ └── frontend.md └── skills/ ├── prisma-orm.md (applies\_to: \[backend]) ├── nextjs-14.md (applies\_to: \[frontend, backend]) ├── tailwind-css.md (applies\_to: \[frontend]) └── vitest.md (applies\_to: \[tester]) When @backend agent invoked: → Loads: prisma-orm.md → Loads: nextjs-14.md (if applicable) → Combines with backend.md ```` ### Skill Priority When skills conflict, **most specific wins**: ```javascript Generic skill: "database" (applies_to: [backend]) Specific skill: "prisma-orm" (applies_to: [backend]) → Use prisma-orm (more specific) ```` ### Skills vs. Agent Specialization #### When to Use Skills Use skills when: * **Multiple agents** need the same capability * Example: Both backend and architect need PostgreSQL knowledge * **Capability is optional** or tech-specific * Example: Not all backend agents use Prisma * **Capability can be composed** * Example: Backend + Prisma + JWT = complete auth system #### When to Use Agents Use agents when: * **Role is fundamentally different** * Example: Backend vs. Frontend (different domains) * **Responsibilities don't overlap** * Example: Tester never reviews code * **Scope needs strict boundaries** * Example: Backend never touches UI ### Skill Examples #### Example 1: Adding React Query Skill ````markdown --- name: react-query applies_to: [frontend] description: React Query for server state management --- # React Query Skill ## Query Patterns ### Fetching Data ```tsx import { useQuery } from '@tanstack/react-query'; function UserProfile({ userId }) { const { data: user, isLoading, error } = useQuery({ queryKey: ['user', userId], queryFn: () => fetch(`/api/users/${userId}`).then(r => r.json()), }); if (isLoading) return
Loading...
; if (error) return
Error loading user
; return
{user.name}
; } ```` #### Mutations ```tsx import { useMutation, useQueryClient } from '@tanstack/react-query'; function UpdateProfile() { const queryClient = useQueryClient(); const mutation = useMutation({ mutationFn: (data) => fetch('/api/users', { method: 'PUT', body: JSON.stringify(data), }), onSuccess: () => { queryClient.invalidateQueries({ queryKey: ['user'] }); }, }); } ``` ```` ### Example 2: Adding Docker Skill ```markdown --- name: docker applies_to: [backend, architect] description: Docker containerization expertise --- # Docker Skill ## Dockerfile Patterns ### Node.js App ```dockerfile FROM node:20-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:20-alpine AS runner WORKDIR /app COPY --from=builder /app/dist ./dist COPY --from=builder /app/node_modules ./node_modules EXPOSE 3000 CMD ["npm", "start"] ```` ### Docker Compose ```yaml version: '3.8' services: app: build: . ports: - "3000:3000" environment: - DATABASE_URL=postgres://db:5432/myapp depends_on: - db db: image: postgres:16 volumes: - postgres_data:/var/lib/postgresql/data volumes: postgres_data: ``` ``` ## Best Practices for Skills ### DO ✅ - **Keep skills focused** - One capability per skill - **Provide examples** - Show common patterns - **Specify applies_to** - Clear which agents use it - **Document best practices** - Share domain knowledge - **Keep updated** - Match current framework versions ### DON'T ❌ - **Don't duplicate agent logic** - Skills add, don't replace - **Don't make skills too broad** - "web-development" is too broad, "nextjs-14" is good - **Don't assume tech stack** - Make skills optional - **Don't hardcode paths** - Use generic patterns ## Summary Skills are agentful's extensibility mechanism: - **Domain-specific** - Deep knowledge in specific areas - **Composable** - Combine multiple skills - **Optional** - Load only what's needed - **Extensible** - Add your own skills - **Specialized** - Give agents superpowers They transform generalist agents into **specialized experts** while keeping the agent system simple and maintainable. **Next:** [Learn about state management](./state-management) ``` ## Slash Commands Slash commands are your **control interface for agentful** - simple, human-readable commands that trigger complex autonomous workflows. Think of them as the steering wheel, accelerator, and dashboard for autonomous development. ### What Are Slash Commands? Slash commands are defined in `.claude/commands/` as markdown files with frontmatter: ```markdown --- name: agentful-start description: Start or resume autonomous product development loop --- # agentful Start This command initiates the autonomous product development loop. ``` When you type `/agentful-start`, Claude Code reads the command definition and executes the workflow described within it. ### Why Slash Commands? #### The Problem with "Just Talk to AI" Without structured commands: ``` You: "Start working on my project" AI: "What should I build?" You: "It's in PRODUCT.md" AI: "Ok, what should I do first?" You: "I don't know, you decide" AI: "Should I build the frontend or backend?" You: "I don't care, just start" [...conversation continues for 10 minutes...] ``` #### The agentful Solution With slash commands: ``` You: /agentful-start agentful: [Immediately reads state, picks task, delegates, validates] → No questions → No ambiguity → Immediate action ``` #### Benefits | Benefit | Description | | ------------------- | --------------------------------------- | | **Consistency** | Same command, same behavior, every time | | **Speed** | No conversational overhead | | **Discoverable** | Tab-completion shows all commands | | **Composable** | Commands can call other commands | | **Traceable** | Clear audit trail of what was run | | **Parameterizable** | Pass flags and options | ### The Four Core Commands agentful has four primary commands for autonomous development: #### 1. `/agentful-start` - The Engine Starter **Purpose:** Start or resume autonomous product development loop **What it does:** ```bash 1. Load State - Read PRODUCT.md (what we're building) - Read .agentful/state.json (current work state) - Read .agentful/completion.json (progress) - Read .agentful/decisions.json (pending decisions) 2. Check Blockers - If decisions pending → Warn user - Continue with unblocked work 3. Initialize State (if needed) - Create .agentful/state.json if missing - Set current_phase = "idle" 4. Delegate to Orchestrator - Task("orchestrator", "Run autonomous development loop") - Orchestrator picks next task - Delegates to specialists - Validates results - Updates progress - Loops until complete ``` **Usage:** ```bash # Manual mode (one task at a time) /agentful-start # Continuous mode (24/7 development) /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` **When to use:** * First time starting development * After resolving decisions * After manual intervention * To check progress while continuing **Output:** ``` agentful: Starting autonomous development loop... → Detected Next.js + TypeScript + Prisma + Tailwind → Reading state: auth = 30% complete → Next task: Complete auth frontend → Delegating to @frontend agent... [Agent completes work] → Validating changes... TypeScript: ✅ Lint: ✅ Tests: ✅ Coverage: 85% ✅ → Auth = 100% complete → Next: User profile feature ``` #### 2. `/agentful-status` - The Dashboard **Purpose:** Show current progress, completion percentage, and what's being worked on **What it does:** ```bash 1. Read state files - state.json (current work, phase, iterations) - completion.json (features, gates) - decisions.json (pending decisions) - PRODUCT.md (product name) 2. Format output beautifully - ASCII art tables - Progress bars - Status indicators - Quick action suggestions 3. Display: - Overall completion percentage - Feature-by-feature status - Quality gate status - Pending decisions - Current work ``` **Usage:** ```bash /agentful-status ``` **Output:** ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Product: Task Management App Overall Progress: ████████░░░░░░░░░░░░ 48% Phase: implementing Iterations: 12 ┌─────────────────────┬──────────┬─────────┬────────────────┐ │ Feature │ Status │ Score │ Notes │ ├─────────────────────┼──────────┼─────────┼────────────────┤ │ Authentication │ ✅ Done │ 100% │ │ │ User Profile │ 🔄 Active│ 45% │ Backend done │ │ Dashboard │ ⏸ Pending│ 0% │ Blocked on UX │ │ Settings │ ⏸ Pending│ 0% │ │ └─────────────────────┴──────────┴─────────┴────────────────┘ ┌─────────────────────┬────────┐ │ Quality Gate │ Status │ ├─────────────────────┼────────┤ │ Tests Passing │ ✅ │ │ No Type Errors │ ✅ │ │ No Dead Code │ ❌ │ │ Coverage ≥ 80% │ ⚠️ 72% │ └─────────────────────┴────────┘ ⚠️ Decisions Needed: 1. "Should dashboard use grid or list layout?" Blocking: dashboard-feature → Run /agentful-decide to resolve ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Next Actions: • /agentful-start - Continue development • /agentful-decide - Answer pending decisions • /agentful-validate- Run quality checks ``` **When to use:** * Check progress without continuing work * See what's blocking development * Get a quick overview * Before making decisions #### 3. `/agentful-decide` - The Decision Resolver **Purpose:** Answer pending decisions that are blocking development progress **What it does:** ```bash 1. Read decisions.json - Get list of pending decisions - Each has: question, options, context, blocking 2. Present to user interactively - Use AskUserQuestion tool - Show question, options, context - Accept user selection 3. Record decision - Move from pending to resolved - Store answer with timestamp 4. Update state - Remove from state.json blocked_on array - Allow blocked features to proceed 5. Show summary - What was resolved - What's now unblocked ``` **Usage:** ```bash /agentful-decide ``` **Output:** ``` ⚠️ You have 2 pending decisions: [1/2] Should auth use JWT or session cookies? Context: Building authentication system Blocking: auth-feature, user-profile-feature Options: [1] JWT (stateless, scalable) [2] Sessions (simpler, built-in) [3] Clerk (managed service) Your choice: > 1 [2/2] Which database provider? Context: Need database for user data Blocking: database-setup Options: [1] PostgreSQL (robust, scalable) [2] MySQL (widely supported) [3] SQLite (simple, file-based) [4] MongoDB (NoSQL, flexible) Your choice: > 1 ✅ All decisions resolved! Unblocked features: - auth-feature (can now proceed) - user-profile-feature (can now proceed) - database-setup (can now proceed) Run /agentful-start to continue development. ``` **When to use:** * When status shows pending decisions * Before continuing development * To unblock features * To provide technical direction #### 4. `/agentful-validate` - The Quality Check **Purpose:** Run all quality checks and validation gates **What it does:** ```bash 1. Delegate to reviewer agent - Task("reviewer", "Run all validation checks") 2. Reviewer runs 8 checks: - TypeScript (npx tsc --noEmit) - Lint (npm run lint) - Dead code detection - Tests (npm test) - Coverage (≥ 80%) - Security (secrets, vulnerabilities, logs) - Manual code review - Console log check 3. Display results - Pass/fail for each check - List of issues found - Suggestions for fixing 4. Update completion.json - Set gate statuses - Track what's passing/failing 5. Offer auto-fix - Ask if user wants to run fixer ``` **Usage:** ```bash # Full validation /agentful-validate # Quick checks (with flags) /agentful-validate --type-check /agentful-validate --tests /agentful-validate --security ``` **Output:** ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Validation Results ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TypeScript ✅ PASS - No type errors Lint ✅ PASS - No lint errors Dead Code ❌ FAIL - 3 issues found Tests ✅ PASS - 47 tests passed Coverage ⚠️ WARN - 72% (needs 80%) Security ⚠️ WARN - 2 issues found Overall: ❌ FAILED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Issues that must be fixed: 1. [Dead Code] Unused export: formatDate in src/utils/date.ts 2. [Dead Code] Unused file: src/components/OldWidget.tsx 3. [Dead Code] Unused dependency: lodash in package.json 4. [Coverage] 8 percentage points below threshold (72% vs 80%) 5. [Security] console.log in src/auth/login.ts:45 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Would you like to auto-fix these issues? [y/N]: > y Delegating to @fixer agent... [Fixer removes dead code, adds tests, removes console.log] Re-validating... TypeScript ✅ PASS Lint ✅ PASS Dead Code ✅ PASS Tests ✅ PASS Coverage ✅ PASS - 82% Security ✅ PASS Overall: ✅ ALL CHECKS PASSED ``` **When to use:** * After manual code changes * Before committing * To check code quality * To see what needs fixing * In CI/CD pipelines ### Command Architecture #### Command Structure Each command is a markdown file with: ```markdown --- name: command-name description: Human-readable description --- # Command Name This command does X, Y, Z. ## Process Step-by-step instructions... ## Implementation Detailed steps... ## Example Flow Example usage... ``` #### Command Communication Commands communicate through: 1. **State files** - Read `.agentful/*.json` 2. **Agent delegation** - Use Task tool to spawn agents 3. **Tool execution** - Run Bash, Read, Write, etc. Example command that delegates: ```markdown ## Process ### 1. Run Reviewer ``` Task("reviewer", "Run all validation checks on the current codebase and report results.") ``` ### 2. Display Results After reviewer completes, display formatted output... ``` ### Command Composition Commands can call other commands: ```markdown # In agentful-start.md ## Process ### If pending decisions found ``` User needs to resolve decisions first. → Run: /agentful-decide ``` ``` ### Command Best Practices #### DO ✅ * **Be specific** - Clear descriptions of what command does * **Check state** - Always read state files first * **Delegate appropriately** - Use Task tool for agents * **Format output** - Make it readable (tables, progress bars) * **Handle errors** - Graceful failure with helpful messages * **Suggest next actions** - Guide user on what to do next #### DON'T ❌ * **Don't implement directly** - Delegate to agents * **Don't skip state checks** - Always read state files * **Don't hardcode paths** - Use relative or detected paths * **Don't assume** - Check files exist before reading * **Don't be silent** - Always provide feedback ### Creating Custom Commands You can add your own commands in `.claude/commands/`: ````markdown --- name: agentful-deploy description: Deploy to production after all validations pass --- # agentful Deploy This command deploys your application to production. ## Preconditions Check all gates first: ```bash # Delegate to validate Task("reviewer", "Run all validation checks") ```` If any checks fail: ``` ❌ Cannot deploy: Quality gates not passing Run /agentful-validate to see issues ``` ### Deployment Process 1. Run tests 2. Build application 3. Deploy to production (Vercel/Netlify/etc.) 4. Verify deployment 5. Tag release ```` Then use it: ```bash /agentful-deploy ```` ### Command Reference Summary | Command | Purpose | When to Use | | -------------------- | ----------------------------------- | ------------------------ | | `/agentful-start` | Start/resume autonomous development | Always (primary command) | | `/agentful-status` | Show progress and state | Checking progress | | `/agentful-decide` | Resolve pending decisions | When blocked | | `/agentful-validate` | Run quality checks | After manual changes | ### Command Flow Examples #### Typical Development Session ```bash # Start development /agentful-start [Works for 30 minutes, completes 3 features] # Check progress /agentful-status # See a decision is needed, resolve it /agentful-decide # Continue development /agentful-start [Works for 20 minutes, then blocked by decision] [You make some manual code changes] # Validate your changes /agentful-validate # Continue autonomous development /agentful-start ``` #### 24/7 Development ```bash # Start continuous mode /ralph-loop "/agentful-start" --max-iterations 50 # Check in anytime /agentful-status # If stuck on decisions /agentful-decide # Loop resumes automatically ``` ### Summary Slash commands are your interface to agentful: * **Simple** - One command triggers complex workflows * **Consistent** - Same behavior every time * **Composable** - Commands can call other commands * **Traceable** - Clear audit trail * **Extensible** - Add your own commands They transform autonomous development from a conversation into a **controlled, observable process**. **Next:** [Learn about skills](./skills) ## State Management State management is **agentful's memory and truth source** - the system of record that tracks what's done, what's blocked, what's pending, and what decisions have been made. All coordination happens through simple JSON files that serve as the single source of truth. ### What Is State Management in agentful? State management in agentful means: * **Progress tracking** - What features are complete, partial, or pending * **Work coordination** - What's currently being worked on * **Decision tracking** - What user input is needed * **Quality gates** - What validation checks are passing/failing * **Blocker management** - What's waiting on what All stored in **simple, human-readable JSON files** in `.agentful/`: ``` .agentful/ ├── state.json # Current work state ├── completion.json # Feature progress ├── decisions.json # Pending and resolved decisions ├── last-review.json # Most recent validation └── architecture.json # Detected tech stack ``` ### Why JSON State Files? #### The Problem Traditional state management approaches have issues: | Approach | Problems | | -------------------------- | ---------------------------------------- | | **In-memory only** | Lost on restart, not inspectable | | **Database** | Overhead, dependency, not human-readable | | **Proprietary format** | Hard to debug, requires tools | | **Scattered across files** | No single source of truth | #### The agentful Solution **JSON state files** provide: * **Human-readable** - Open in any text editor * **Git-friendly** - Track changes over time * **Inspectable** - See exactly what's happening * **Simple** - No special tools needed * **Explicit** - Clear structure, no ambiguity * **Recoverable** - Easy to fix if corrupted ```json { "features": { "authentication": { "status": "complete", "score": 100 } }, "overall": 48 } ``` You can **literally see** your progress at a glance. ### The Four Core State Files #### 1. state.json - Current Work State **Purpose:** Track what's happening right now **Location:** `.agentful/state.json` **Structure:** ```json { "version": "1.0", "current_task": "user-profile-backend", "current_phase": "implementing", "iterations": 12, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": [] } ``` **Field meanings:** | Field | Type | Purpose | | --------------- | ------------------ | -------------------------------------------------------- | | `version` | string | State schema version (for migrations) | | `current_task` | string \| null | ID of task currently being worked on | | `current_phase` | string | Phase: idle, planning, implementing, validating, blocked | | `iterations` | number | How many loop iterations have run | | `last_updated` | ISO 8601 timestamp | When state was last modified | | `blocked_on` | string\[] | List of feature IDs blocked on decisions | **Phases explained:** ``` idle → Not working, waiting for /agentful-start planning → Analyzing PRODUCT.md, picking next task implementing → Specialist agent is working validating → Reviewer is checking quality blocked → Waiting on user decision ``` **Usage:** ```bash # Orchestrator always reads this first cat .agentful/state.json # Check if blocked if [ $(jq '.blocked_on | length' .agentful/state.json) -gt 0 ]; then echo "Blocked on decisions, run /agentful-decide" fi ``` #### 2. completion.json - Progress Tracking **Purpose:** Track feature completion and quality gates **Location:** `.agentful/completion.json` **Structure:** ```json { "features": { "authentication": { "status": "complete", "score": 100, "completed_at": "2026-01-18T01:00:00Z", "notes": "JWT auth with login/register/logout" }, "user-profile": { "status": "in_progress", "score": 45, "notes": "Backend done, frontend pending" }, "dashboard": { "status": "pending", "score": 0, "notes": "Blocked on UX decision" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": false, "coverage_80": false }, "overall": 48, "last_updated": "2026-01-18T00:00:00Z" } ``` **Feature statuses:** | Status | Score Range | Meaning | | ------------- | ----------- | ------------------------ | | `pending` | 0 | Not started | | `in_progress` | 1-99 | Partially complete | | `complete` | 100 | Fully done and validated | **Quality gates:** ```json { "gates": { "tests_passing": true, // All tests pass "no_type_errors": true, // TypeScript clean "no_dead_code": false, // Has unused code "coverage_80": false // Coverage below 80% } } ``` **Overall calculation:** ```javascript // Pseudocode overall = average( ...Object.values(features).map(f => f.score), gates.tests_passing ? 100 : 0, gates.no_type_errors ? 100 : 0, gates.no_dead_code ? 100 : 0, gates.coverage_80 ? 100 : 0 ) / (features.length + 4) ``` **Usage:** ```bash # Check if project is complete if [ $(jq '.overall' .agentful/completion.json) -eq 100 ]; then echo "Project complete!" fi # See what's in progress jq '.features | to_entries[] | select(.value.status == "in_progress")' ``` #### 3. decisions.json - Decision Tracking **Purpose:** Track pending and resolved user decisions **Location:** `.agentful/decisions.json` **Structure:** ```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", "priority": "high" } ], "resolved": [ { "id": "decision-000", "question": "Which database provider?", "answer": "PostgreSQL (robust, scalable)", "timestamp_resolved": "2026-01-18T00:30:00Z", "resolution_time_minutes": 5 } ] } ``` **Decision lifecycle:** ``` 1. Orchestrator needs input ↓ 2. Add to pending array ↓ 3. Add to state.json blocked_on ↓ 4. User runs /agentful-decide ↓ 5. Move from pending to resolved ↓ 6. Remove from state.json blocked_on ↓ 7. Unblocked features can proceed ``` **Usage:** ```bash # Check if decisions needed pending_count=$(jq '.pending | length' .agentful/decisions.json) if [ $pending_count -gt 0 ]; then echo "⚠️ $pending_count decisions needed" echo "Run /agentful-decide to resolve" fi ``` #### 4. last-review\.json - Validation Results **Purpose:** Store most recent validation check results **Location:** `.agentful/last-review.json` **Structure:** ```json { "passed": false, "timestamp": "2026-01-18T00:00:00Z", "checks": { "typescript": { "passed": true, "summary": "No type errors found" }, "lint": { "passed": true, "summary": "No lint errors" }, "deadCode": { "passed": false, "issues": [ "Unused export: formatDate in src/utils/date.ts", "Unused file: src/components/OldWidget.tsx", "Unused dependency: lodash in package.json" ] }, "tests": { "passed": true, "summary": "47 tests passed" }, "coverage": { "passed": false, "actual": 72, "required": 80, "summary": "8 percentage points below threshold" }, "security": { "passed": false, "issues": [ "console.log in src/auth/login.ts:45", "Possible hardcoded secret in src/config/api.ts:12" ] } }, "mustFix": [ "Remove unused export formatDate from src/utils/date.ts", "Delete unused file src/components/OldWidget.tsx", "Add tests to reach 80% coverage (currently at 72%)", "Remove console.log from src/auth/login.ts:45", "Investigate possible hardcoded secret in src/config/api.ts:12" ], "canIgnore": [] } ``` **Usage:** ```bash # Check if last validation passed if jq -e '.passed' .agentful/last-review.json > /dev/null; then echo "✅ Last validation passed" else echo "❌ Last validation failed" echo "Issues:" jq -r '.mustFix[]' .agentful/last-review.json fi ``` ### State File Interactions #### How State Files Work Together ``` ┌─────────────────────────────────────────────────────────────┐ │ Orchestrator │ │ "What should I do?" │ └────────┬────────────────────────────────────────────────────┘ │ │ 1. Read all state files ▼ ┌─────────────────────────────────────────────────────────────┐ │ state.json → current_phase = "idle" │ │ completion.json → overall = 48% │ │ decisions.json → pending = ["decision-001"] │ └────────┬────────────────────────────────────────────────────┘ │ │ 2. Check for decisions ▼ Has decisions? │ ┌────┴────┐ │ │ Yes No │ │ │ ▼ │ Pick next task │ │ ▼ ▼ Work on Delegate unblocked to agent features │ │ ▼ │ 3. Update state.json │ current_phase = "implementing" │ │ │ ▼ │ Agent completes │ │ │ ▼ │ 4. Run reviewer │ │ │ ▼ │ Update last-review.json │ │ │ ▼ │ 5. If issues, fixer fixes │ │ │ ▼ │ 6. Update completion.json │ feature.score = 100 │ │ │ ▼ │ 7. Update state.json │ current_phase = "idle" │ current_task = null │ │ └─────────┤ ▼ Loop again ``` #### Example Flow **Initial state:** ```json // state.json { "current_task": null, "current_phase": "idle", "blocked_on": [] } // completion.json { "features": { "authentication": { "status": "pending", "score": 0 } }, "overall": 0 } ``` **Orchestrator picks task:** ```json // state.json { "current_task": "authentication", "current_phase": "implementing" } ``` **Backend agent completes:** ```json // state.json { "current_task": "authentication", "current_phase": "validating" } ``` **Reviewer passes:** ```json // completion.json { "features": { "authentication": { "status": "complete", "score": 100 } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": true, "coverage_80": true }, "overall": 100 } // state.json { "current_task": null, "current_phase": "idle" } ``` ### State File Operations #### Reading State **Bash (jq):** ```bash # Get current phase jq -r '.current_phase' .agentful/state.json # Get overall completion jq '.overall' .agentful/completion.json # Count pending decisions jq '.pending | length' .agentful/decisions.json # Check if validation passed jq '.passed' .agentful/last-review.json ``` **Node.js:** ```javascript import state from '../.agentful/state.json' assert { type: 'json' }; if (state.current_phase === 'blocked') { console.log('Blocked on:', state.blocked_on); } ``` **Python:** ```python import json with open('.agentful/completion.json') as f: completion = json.load(f) print(f"Progress: {completion['overall']}%") ``` #### Updating State **Direct (careful!):** ```bash # Update phase jq '.current_phase = "implementing"' .agentful/state.json > tmp.json mv tmp.json .agentful/state.json ``` **Through orchestrator (preferred):** ```javascript // Orchestrator updates state await fs.writeJSON('.agentful/state.json', { current_task: 'user-profile', current_phase: 'implementing', iterations: state.iterations + 1, last_updated: new Date().toISOString() }); ``` #### Resetting State ```bash # Start over (careful!) rm -rf .agentful/ # Or just reset completion echo '{ "features": {}, "gates": { "tests_passing": false, "no_type_errors": false, "no_dead_code": false, "coverage_80": false }, "overall": 0 }' > .agentful/completion.json ``` ### State File Best Practices #### DO ✅ * **Always read before writing** - Avoid race conditions * **Use atomic writes** - Write to temp, then move * **Validate JSON** - Ensure it's valid before saving * **Include timestamps** - Track when things changed * **Add context** - Use notes field for why something happened * **Gitignore appropriately** - Don't commit sensitive state #### DON'T ❌ * **Don't edit manually while running** - Let orchestrator manage * **Don't use complex nested structures** - Keep it flat and readable * **Don't store binary data** - Only JSON-serializable data * **Don't put secrets in state** - Use environment variables * **Don't ignore state files** - They're the source of truth ### State File in Git #### What to Commit ```gitignore # .gitignore # State files (generally don't commit) .agentful/state.json .agentful/last-review.json # But DO commit these !.agentful/completion.json # Track progress !.agentful/decisions.json # Track decisions !.agentful/architecture.json # Track tech stack ``` **Why:** * `state.json` - Changes constantly, not useful in history * `last-review.json` - Temporary validation output * `completion.json` - Useful to see progress over time * `decisions.json` - Useful audit trail * `architecture.json` - Useful for documentation #### Viewing State History ```bash # See how completion progressed git log --oneline -- .agentful/completion.json # Diff completion between commits git diff HEAD~5 HEAD -- .agentful/completion.json # See when decisions were made git log --oneline -- .agentful/decisions.json ``` ### Advanced State Patterns #### Checkpoint State ```bash # Save checkpoint cp .agentful/completion.json .agentful/checkpoints/before-auth.json # Restore if needed cp .agentful/checkpoints/before-auth.json .agentful/completion.json ``` #### State Migrations When state schema changes: ```javascript // migrate-state-v1-to-v2.js import fs from 'fs'; const state = JSON.parse(fs.readFileSync('.agentful/state.json', 'utf8')); // v1 had 'task', v2 renamed to 'current_task' if (state.task) { state.current_task = state.task; delete state.task; state.version = '2.0'; } fs.writeFileSync('.agentful/state.json', JSON.stringify(state, null, 2)); ``` #### State Validation ```javascript // validate-state.js import Ajv from 'ajv'; const stateSchema = { type: 'object', required: ['version', 'current_phase', 'iterations'], properties: { version: { type: 'string' }, current_phase: { enum: ['idle', 'planning', 'implementing', 'validating', 'blocked'] }, iterations: { type: 'number', minimum: 0 } } }; const ajv = new Ajv(); const validate = ajv.compile(stateSchema); const state = JSON.parse(fs.readFileSync('.agentful/state.json', 'utf8')); if (!validate(state)) { console.error('Invalid state:', validate.errors); process.exit(1); } ``` ### State vs. Database Why not use a database for state? | Aspect | JSON Files | Database | | ------------------- | ------------- | -------------------------- | | **Setup** | Zero | Need server | | **Inspectability** | Text editor | SQL client | | **Version control** | Git-friendly | Requires migrations | | **Debugging** | Open and read | Need queries | | **Dependencies** | None | Database driver | | **Complexity** | Simple | Overkill for this use case | JSON files are **perfect for agentful's needs** because state is: * Low volume (few KB, not GB) * Read/written by single process (no concurrent access) * Simple structure (flat JSON) * Human-inspectable (debugging is easier) ### Summary State management in agentful is **simple, explicit, and effective**: * **JSON files** - Human-readable, git-friendly * **Four core files** - State, completion, decisions, validation * **Source of truth** - All coordination goes through them * **Inspectable** - See exactly what's happening * **Trackable** - Progress over time in git * **Recoverable** - Easy to fix if something goes wrong They're the **memory that makes autonomous development possible** - without them, the orchestrator wouldn't know what to do next. **Next:** [Return to core concepts overview](./index) ## Agent Configuration agentful's agents are highly configurable. You can customize existing agents, create new specialized agents, or modify agent behavior for your specific tech stack. ### Agent File Structure Each agent is a Markdown file with YAML frontmatter: ```markdown --- name: agent-name description: What this agent does model: sonnet|opus tools: Read, Write, Edit, Glob, Grep, Bash, Task, AskUserQuestion, TodoWrite --- # Agent Name Detailed instructions for the agent... ``` #### Frontmatter Fields | Field | Type | Required | Description | | ------------- | ------ | -------- | -------------------------------------- | | `name` | string | Yes | Unique identifier (used for @mentions) | | `description` | string | Yes | One-line summary of agent's purpose | | `model` | string | No | Claude model (sonnet, opus, haiku) | | `tools` | array | Yes | Tools this agent can use | #### Available Tools | Tool | Description | Use Case | | ----------------- | --------------- | ----------------------- | | `Read` | Read files | Inspect code, configs | | `Write` | Write files | Create new files | | `Edit` | Edit files | Modify existing code | | `Glob` | Find files | Pattern matching | | `Grep` | Search content | Find code patterns | | `Bash` | Run commands | Execute scripts, tests | | `Task` | Delegate agents | Spawn specialist agents | | `AskUserQuestion` | Get input | Request user decisions | | `TodoWrite` | Track tasks | Manage todo lists | ### Core Agents #### Orchestrator Agent **File**: `.claude/agents/orchestrator.md` **Purpose**: Coordinates autonomous development, never writes code directly. **Key Responsibilities**: * Reads `PRODUCT.md` and state files * Delegates work to specialist agents * Tracks progress in `completion.json` * Handles user decisions * Coordinates validation workflow **Configuration Example**: ```markdown --- name: orchestrator description: Coordinates autonomous product development. Reads state, delegates to specialists, tracks progress. NEVER writes code directly. model: opus tools: Read, Write, Edit, Glob, Grep, Task, AskUserQuestion, TodoWrite --- # Orchestrator Agent You are the Orchestrator Agent for autonomous product development. ## Your Role - Read PRODUCT.md to understand what we're building - Track progress in .agentful/completion.json - Delegate ALL implementation to specialist agents - Ensure validation happens after every change ## Delegation Pattern NEVER implement yourself. Always use Task tool: Task("backend", "Implement user authentication per PRODUCT.md") Task("frontend", "Create login page") Task("reviewer", "Review all changes") ``` **Customization Options**: ```markdown ## Custom Work Priorities When selecting next work, use this order: 1. Security vulnerabilities 2. Broken tests 3. CRITICAL features 4. HIGH priority features 5. MEDIUM priority features 6. LOW priority features 7. Polish/optimization ``` #### Architect Agent **File**: `.claude/agents/architect.md` **Purpose**: Analyzes tech stack and generates specialized agents dynamically. **Key Responsibilities**: * Reads `PRODUCT.md` to detect tech stack * Generates tech-specific agents * Updates existing agents with framework patterns * Creates `architecture.json` documenting decisions **Configuration Example**: ```markdown --- name: architect description: Analyzes PRODUCT.md tech stack and generates specialized agents dynamically. model: opus tools: Read, Write, Edit, Glob, Grep, Task --- # Architect Agent You are the Architect Agent. ## Tech Stack Detection From PRODUCT.md, extract: - Frontend framework (Next.js, React, Vue, Svelte) - Backend framework (Express, NestJS, Fastify) - Database (PostgreSQL, MongoDB, SQLite) - ORM (Prisma, Drizzle, TypeORM) - Styling (Tailwind, CSS Modules, styled-components) - Testing (Vitest, Jest, Playwright) ## Agent Generation For each technology, create specialized agents: - nextjs-agent.md - prisma-agent.md - tailwind-agent.md - vitest-agent.md ``` **Custom Tech Stack**: ````markdown ## Custom Framework Support ### Adding support for your framework 1. Create template in `.claude/agents/templates/my-framework.md` 2. Add detection logic: ```markdown Detect from PRODUCT.md: - Framework: "MyFramework" - Pattern: "app/routes/*.js" - Component: "export default function Route()" ```` 3. Generate agent with framework-specific patterns ```` ### Backend Agent **File**: `.claude/agents/backend.md` **Purpose**: Implements server-side code using clean architecture. **Key Responsibilities**: - Repository layer (data access) - Service layer (business logic) - Controller layer (HTTP endpoints) - Database schemas and migrations - Authentication and authorization - Input validation **Technology-Specific Patterns**: ```markdown ## Next.js App Router Pattern ```typescript // src/app/api/users/route.ts import { NextRequest, NextResponse } from 'next/server'; import { UserService } from '@/services/user.service'; export async function GET(req: NextRequest) { const service = new UserService(); const users = await service.listUsers(); return NextResponse.json(users); } ```` ### Express.js Pattern ```typescript // src/routes/users.routes.ts import { Router } from 'express'; import { UserService } from '../services/user.service'; const router = Router(); router.get('/', async (req, res, next) => { try { const service = new UserService(); const users = await service.listUsers(); res.json(users); } catch (error) { next(error); } }); ``` ### NestJS Pattern ```typescript // src/users/users.controller.ts import { Controller, Get } from '@nestjs/common'; import { UsersService } from './users.service'; @Controller('users') export class UsersController { constructor(private usersService: UsersService) {} @Get() findAll() { return this.usersService.findAll(); } } ``` ```` **Customization Example**: ```markdown ## Custom Backend Rules 1. **ALWAYS** use Repository pattern 2. **ALWAYS** validate with Zod 3. **NEVER** use raw SQL (always use ORM) 4. **ALWAYS** handle errors with proper HTTP status 5. **Custom**: Use our custom Logger class 6. **Custom**: All routes must have rate limiting ```` #### Frontend Agent **File**: `.claude/agents/frontend.md` **Purpose**: Implements UI components, pages, hooks, and styling. **Key Responsibilities**: * React/Vue/Svelte components * Page layouts * Custom hooks * State management * Styling implementation * Client-side routing **Framework Patterns**: ````markdown ## React/Next.js Pattern ```tsx 'use client'; import { useState } from 'react'; export default function LoginForm() { const [email, setEmail] = useState(''); return (
setEmail(e.target.value)} />
); } ```` ### Vue 3 Pattern ```vue ``` ### Svelte Pattern ```svelte
``` ```` **Component Library Integration**: ```markdown ## Using shadcn/ui All components must use shadcn/ui: ```tsx import { Button } from '@/components/ui/button'; import { Input } from '@/components/ui/input'; export function LoginForm() { return (
); } ```` ### Using Chakra UI ```tsx import { Button, Input } from '@chakra-ui/react'; export function LoginForm() { return (
); } ``` ```` ### Tester Agent **File**: `.claude/agents/tester.md` **Purpose**: Writes comprehensive tests (unit, integration, E2E). **Key Responsibilities**: - Unit tests for services and utilities - Integration tests for API endpoints - E2E tests for user flows - Test fixtures and mocks - Coverage reporting **Test Framework Patterns**: ```markdown ## Vitest Pattern ```typescript import { describe, it, expect, vi } from 'vitest'; import { UserService } from './user.service'; describe('UserService', () => { it('should create a user', async () => { const service = new UserService(); const user = await service.createUser({ email: 'test@example.com', password: 'password123' }); expect(user).toHaveProperty('id'); expect(user.email).toBe('test@example.com'); }); }); ```` ### Playwright Pattern ```typescript import { test, expect } from '@playwright/test'; test('user can login', async ({ page }) => { await page.goto('/login'); await page.fill('input[name="email"]', 'test@example.com'); await page.fill('input[name="password"]', 'password123'); await page.click('button[type="submit"]'); await expect(page).toHaveURL('/dashboard'); }); ``` ```` ### Reviewer Agent **File**: `.claude/agents/reviewer.md` **Purpose**: Performs code review and quality checks. **Key Responsibilities**: - TypeScript type checking - Lint validation - Dead code detection - Test coverage analysis - Security scanning - Best practices enforcement **Custom Quality Gates**: ```markdown ## Custom Validation Rules ### Strict TypeScript ```bash npx tsc --noEmit --strict --noUnusedLocals --noUnusedParameters ```` #### Custom Lint Rules * No console.log in production code * All exports must be used * Max function complexity: 10 * Max file lines: 300 #### Security Rules * No hardcoded secrets * No eval() or Function() * All user input must be validated * SQL queries must use parameterized inputs ```` ### Fixer Agent **File**: `.claude/agents/fixer.md` **Purpose**: Automatically fixes validation failures. **Key Responsibilities**: - Removes unused imports and variables - Fixes TypeScript errors - Removes console.log and debug code - Adds missing tests - Fixes lint errors ## Creating Custom Agents ### Tech-Specific Agents Create `.claude/agents/nextjs-agent.md`: ```markdown --- name: nextjs description: Specializes in Next.js 14 development with App Router, Server Components, and Server Actions. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Next.js Specialist You are the Next.js Specialist Agent. ## Patterns ### Server Component (Default) ```tsx // app/dashboard/page.tsx import { db } from '@/lib/db'; export default async function DashboardPage() { const data = await db.user.findMany(); return (

Dashboard

); } ```` #### Client Component (When Needed) ```tsx 'use client'; import { useState } from 'react'; export function LoginForm() { const [email, setEmail] = useState(''); // Interactive state here } ``` #### Server Action ```typescript // app/actions.ts 'use server'; export async function createUser(formData: FormData) { const email = formData.get('email'); // Server-side validation and processing } ``` #### Route Handler ```typescript // app/api/users/route.ts import { NextRequest, NextResponse } from 'next/server'; export async function GET(req: NextRequest) { return NextResponse.json({ users: [] }); } ``` ### Rules 1. Use App Router (not Pages Router) 2. Server Components by default 3. Client Components only when needed (useState, useEffect) 4. Co-locate related files 5. Use TypeScript strict mode ```` ### Database-Specific Agents Create `.claude/agents/prisma-agent.md`: ```markdown --- name: prisma description: Specializes in Prisma ORM development including schema design, migrations, and queries. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Prisma Specialist ## Schema Design ```prisma // prisma/schema.prisma model User { id String @id @default(cuid()) email String @unique password String posts Post[] createdAt DateTime @default(now()) updatedAt DateTime @updatedAt } model Post { id String @id @default(cuid()) title String content String? author User @relation(fields: [authorId], references: [id]) authorId String } ```` ### Migration Pattern ```bash # Create migration npx prisma migrate dev --name add_user_table # Reset database (dev only) npx prisma migrate reset # Generate client npx prisma generate ``` ### Query Patterns ```typescript // Find unique const user = await db.user.findUnique({ where: { email: 'test@example.com' } }); // Find many const users = await db.user.findMany({ where: { active: true }, include: { posts: true } }); // Create const user = await db.user.create({ data: { email: 'test@example.com', password: hashed } }); // Update const user = await db.user.update({ where: { id }, data: { email: 'new@example.com' } }); // Delete await db.user.delete({ where: { id } }); ``` ```` ### Styling-Specific Agents Create `.claude/agents/tailwind-agent.md`: ```markdown --- name: tailwind description: Specializes in Tailwind CSS utility-first styling. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Tailwind CSS Specialist ## Component Pattern ```tsx export function Button({ variant = 'primary', children }) { const baseStyles = 'px-4 py-2 rounded font-medium transition-colors'; const variants = { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300', danger: 'bg-red-600 text-white hover:bg-red-700' }; return ( ); } ```` ### Responsive Design ```tsx
{/* Responsive grid layout */}
``` ### Custom Configuration ```javascript // tailwind.config.js module.exports = { theme: { extend: { colors: { primary: { 50: '#f0f9ff', // ... custom color scale } } } } } ``` ```` ## Agent Delegation ### From Orchestrator ```markdown # Delegating to specialist agents ## Backend Work Task("backend", "Implement authentication service with JWT") ## Frontend Work Task("frontend", "Create login page with form validation") ## Next.js-Specific Work Task("nextjs", "Create dashboard page with server components") ## Database Work Task("prisma", "Add user schema with email uniqueness") ## Styling Work Task("tailwind", "Style the login form with proper spacing") ## Testing Task("tester", "Write unit tests for auth service") ## Review Task("reviewer", "Review all authentication changes") ```` #### Between Agents Agents can delegate to other agents: ```markdown # Backend agent delegating to tester After implementing authentication: 1. Validate implementation works 2. Task("tester", "Write comprehensive tests for auth service") 3. Wait for test completion 4. If tests fail, fix them 5. Task("reviewer", "Review auth implementation and tests") ``` ### Agent Configuration Examples #### Full-Stack Web App ```markdown PRODUCT.md: - Frontend: Next.js 14 + TypeScript + Tailwind - Backend: Next.js API Routes - Database: PostgreSQL + Prisma - Auth: JWT - Testing: Vitest + Playwright Generated agents: - nextjs-agent (App Router patterns) - prisma-agent (ORM patterns) - tailwind-agent (Styling patterns) - vitest-agent (Testing patterns) ``` #### Express + React ```markdown PRODUCT.md: - Frontend: React + Vite + TypeScript - Backend: Express + TypeScript - Database: MongoDB + Mongoose - Testing: Jest + Cypress Generated agents: - react-agent (Hooks, components) - express-agent (Routes, middleware) - mongoose-agent (Schema, queries) - jest-agent (Unit tests) - cypress-agent (E2E tests) ``` #### Vue + Nuxt ```markdown PRODUCT.md: - Frontend: Nuxt 3 + TypeScript - Backend: Nuxt server routes - Database: SQLite + Drizzle - Testing: Vitest + Playwright Generated agents: - nuxt-agent (Nuxt patterns) - vue-agent (Composition API) - drizzle-agent (ORM patterns) ``` ### Next Steps * [Workflow Configuration](./workflow-configuration) - Create custom commands and workflows ## Configuration Overview agentful provides a flexible configuration system that lets you customize every aspect of autonomous product development. Configuration is split between project-level settings and agentful's internal configuration. ### Configuration Structure ``` .your-project/ ├── .claude/ # Claude Code + agentful config │ ├── settings.json # Global settings (hooks, permissions) │ ├── agents/ # Agent definitions │ ├── commands/ # Slash command definitions │ └── skills/ # Reusable skill modules ├── .agentful/ # Runtime state (gitignored) │ ├── state.json # Current work state │ ├── completion.json # Progress tracking │ ├── decisions.json # Pending/resolved decisions │ └── architecture.json # Tech stack detection ├── PRODUCT.md # Your product specification └── CLAUDE.md # agentful usage guide ``` ### Configuration Files #### Core Files | File | Purpose | Edit? | | ----------------------- | -------------------------------------- | -------------- | | `.claude/settings.json` | Hooks, permissions, global settings | Yes | | `PRODUCT.md` | Product requirements and tech stack | Yes (required) | | `CLAUDE.md` | Project-specific agentful instructions | Optional | | `.agentful/*.json` | Runtime state (auto-generated) | No | #### Generated Files | File | Purpose | Generated By | | -------------------------------- | ------------------ | --------------- | | `.agentful/state.json` | Current work state | CLI init | | `.agentful/completion.json` | Feature progress | Orchestrator | | `.agentful/decisions.json` | User decisions | Orchestrator | | `.agentful/architecture.json` | Tech stack info | Architect agent | | `.agentful/last-validation.json` | Validation results | Reviewer agent | ### Quick Start Configuration #### 1. Initialize agentful ```bash npx @itz4blitz/agentful init ``` This creates: * `.claude/` directory with all agents and commands * `.agentful/` directory for runtime state * `PRODUCT.md` template * `CLAUDE.md` usage guide * Updates `.gitignore` to exclude `.agentful/` #### 2. Configure Your Product Edit `PRODUCT.md` with your product details: ```markdown # Product Specification ## Overview A task management application for teams. ## Tech Stack ### Frontend - **Framework**: Next.js 14 - **Language**: TypeScript - **Styling**: Tailwind CSS ### Backend - **Framework**: Next.js API Routes - **Database**: PostgreSQL + Prisma - **Auth**: JWT ## Features ### 1. Authentication - CRITICAL - Login with email/password - JWT token generation - Session management ``` #### 3. Customize Agents (Optional) Edit agents in `.claude/agents/` to match your preferences: ```bash # Customize backend agent patterns edit .claude/agents/backend.md # Add custom validation rules edit .claude/skills/validation/SKILL.md ``` #### 4. Adjust Settings Edit `.claude/settings.json` for hooks and permissions: ```json { "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [ { "type": "command", "command": "npm run lint" } ] } ] }, "permissions": { "allow": [ "Bash(npm:*)", "Bash(npx:*)", "Bash(git:*)" ] } } ``` ### Configuration Layers agentful configuration applies in layers (highest priority first): 1. **Project-level** - `PRODUCT.md`, `CLAUDE.md` 2. **Agent-level** - Individual agent definitions in `.claude/agents/` 3. **Skill-level** - Reusable skills in `.claude/skills/` 4. **Global-level** - `.claude/settings.json` ### Environment-Specific Configuration #### Development ```bash # Use default settings npx @itz4blitz/agentful init # Edit PRODUCT.md for dev-specific features # - Enable debug mode # - Use mock services # - Add dev tools ``` #### Production ```bash # Update PRODUCT.md with production requirements # - Set production API endpoints # - Enable all security features # - Configure performance monitoring # Adjust permissions in settings.json { "permissions": { "deny": [ "Bash(npm:dev*)", "Bash(npm:test*)" ] } } ``` #### Staging Create environment-specific config: ```bash # Copy PRODUCT.md cp PRODUCT.md PRODUCT.staging.md # Use staging-specific config claude --config PRODUCT.staging.md ``` ### Next Steps * [Project Structure](./project-structure) - Required files and directory layout * [Agent Configuration](./agent-configuration) - Customizing agents for your stack * [Workflow Configuration](./workflow-configuration) - Custom commands and workflows ## Project Structure agentful requires a specific project structure to function correctly. Understanding the required and optional files helps you organize your project effectively. ### Required Directory Structure agentful supports two product specification structures: #### Option 1: Flat Structure (Single PRODUCT.md) Best for simple projects, MVPs, and single-developer workflows. ``` .your-project/ ├── .claude/ # REQUIRED - agentful configuration │ ├── settings.json # REQUIRED - Global settings │ ├── agents/ # REQUIRED - Agent definitions │ │ ├── orchestrator.md │ │ ├── architect.md │ │ ├── backend.md │ │ ├── frontend.md │ │ ├── tester.md │ │ ├── reviewer.md │ │ └── fixer.md │ ├── commands/ # REQUIRED - Slash commands │ │ ├── agentful-start.md │ │ ├── agentful-status.md │ │ ├── agentful-decide.md │ │ └── agentful-validate.md │ └── skills/ # REQUIRED - Reusable modules │ ├── validation/ │ │ └── SKILL.md │ └── product-tracking/ │ └── SKILL.md │ ├── .agentful/ # REQUIRED - Runtime state (gitignored) │ ├── state.json # Auto-created on init │ ├── completion.json # Auto-created on init │ ├── decisions.json # Auto-created on init │ ├── architecture.json # Auto-created by architect │ └── last-validation.json # Auto-created by reviewer │ ├── PRODUCT.md # REQUIRED - Your product spec (flat) └── CLAUDE.md # OPTIONAL - Project-specific guide ``` #### Option 2: Hierarchical Structure (`.claude/product/`) Best for large projects, team collaboration, and complex feature dependencies. ``` .your-project/ ├── .claude/ # REQUIRED - agentful configuration │ ├── settings.json # REQUIRED - Global settings │ ├── agents/ # REQUIRED - Agent definitions │ │ ├── orchestrator.md │ │ ├── architect.md │ │ ├── backend.md │ │ ├── frontend.md │ │ ├── tester.md │ │ ├── reviewer.md │ │ └── fixer.md │ ├── commands/ # REQUIRED - Slash commands │ │ ├── agentful-start.md │ │ ├── agentful-status.md │ │ ├── agentful-decide.md │ │ └── agentful-validate.md │ ├── skills/ # REQUIRED - Reusable modules │ │ ├── validation/ │ │ │ └── SKILL.md │ │ └── product-tracking/ │ │ └── SKILL.md │ └── product/ # REQUIRED - Product spec (hierarchical) │ ├── PRODUCT.md # Root product overview │ ├── domains/ # Functional domains │ │ ├── authentication/ │ │ │ ├── DOMAIN.md │ │ │ └── features/ │ │ │ ├── login.md │ │ │ ├── registration.md │ │ │ └── password-reset.md │ │ └── user-management/ │ │ ├── DOMAIN.md │ │ └── features/ │ │ ├── profile.md │ │ └── settings.md │ └── quality-gates/ # Quality standards │ ├── testing.md │ ├── security.md │ └── performance.md │ ├── .agentful/ # REQUIRED - Runtime state (gitignored) │ ├── state.json # Auto-created on init │ ├── completion.json # Auto-created on init │ ├── decisions.json # Auto-created on init │ ├── architecture.json # Auto-created by architect │ └── last-validation.json # Auto-created by reviewer │ └── CLAUDE.md # OPTIONAL - Project-specific guide ``` #### Choosing Your Structure :::tip **Flat Structure (PRODUCT.md)** - Start here for most projects. You can migrate to hierarchical later as your project grows. ::: | Factor | Flat (PRODUCT.md) | Hierarchical (`.claude/product/`) | | ---------------------- | --------------------------- | --------------------------------- | | **Team Size** | 1-2 developers | 3+ developers | | **Feature Count** | \< 20 features | 20+ features | | **Project Complexity** | Simple to moderate | Complex with dependencies | | **Domain Separation** | Not needed | Multiple business domains | | **Ease of Use** | ✅ Very simple | ⚠️ Requires setup | | **Scalability** | ⚠️ Limited | ✅ Highly scalable | | **Team Collaboration** | ⚠️ Possible conflicts | ✅ Clear ownership | | **Migration Path** | Can upgrade to hierarchical | N/A | **Recommendation**: Start with **flat structure** unless you know you need hierarchical from day one. ### File Requirements #### Absolutely Required | File | Purpose | Created By | | ------------------------------------------------ | ------------------ | ------------------------------ | | `.claude/settings.json` | Hooks, permissions | `npx @itz4blitz/agentful init` | | `.claude/agents/*.md` | Agent definitions | `npx @itz4blitz/agentful init` | | `.claude/commands/*.md` | Slash commands | `npx @itz4blitz/agentful init` | | `.claude/skills/*/SKILL.md` | Skill modules | `npx @itz4blitz/agentful init` | | `PRODUCT.md` **OR** `.claude/product/PRODUCT.md` | Product spec | You (edit template) | | `.agentful/state.json` | Work state | CLI on init | #### Recommended | File | Purpose | When to Create | | ------------ | ----------------------------- | ----------------------------- | | `CLAUDE.md` | Project-specific instructions | For custom workflows | | `.env` | Environment variables | When using external services | | `.gitignore` | Git exclusions | Always (auto-updated by init) | #### Auto-Generated (Don't Edit) | File | Purpose | Generated By | | -------------------------------- | ------------------ | ------------ | | `.agentful/completion.json` | Progress tracking | Orchestrator | | `.agentful/decisions.json` | User decisions | Orchestrator | | `.agentful/architecture.json` | Tech stack info | Architect | | `.agentful/last-validation.json` | Validation results | Reviewer | ### When to Use Each Structure #### Flat Structure (PRODUCT.md) Choose the flat structure when: * **Starting a new project** - Quick setup, minimal overhead * **Building an MVP** - Fast iteration, simple scope * **Solo developer or small team** (1-2 people) - Easy to coordinate * **\< 20 features planned** - Manageable in a single file * **Single domain focus** - One product area (e.g., just authentication) * **Learning agentful** - Simpler to understand and debug **Advantages:** * ✅ Quickest to get started * ✅ Easier to see the entire product at a glance * ✅ Simpler file management * ✅ Less cognitive overhead * ✅ Perfect for prototypes and MVPs **Limitations:** * ⚠️ Can become unwieldy with 20+ features * ⚠️ Harder for multiple developers to work simultaneously * ⚠️ No clear separation of concerns * ⚠️ Merge conflicts more likely on teams #### Hierarchical Structure (`.claude/product/`) Choose the hierarchical structure when: * **Large-scale project** - 20+ features with complex dependencies * **Team collaboration** (3+ developers) - Clear ownership boundaries * **Multiple domains** - Distinct business areas (e.g., auth, billing, content) * **Complex dependencies** - Features that rely on other features * **Long-term project** - Expected to grow and evolve over months * **Enterprise needs** - Requires organized structure and governance **Advantages:** * ✅ Scales to hundreds of features * ✅ Clear ownership (domains/features) * ✅ Reduced merge conflicts * ✅ Better for parallel development * ✅ Easier to navigate large specs * ✅ Supports domain-driven design **Trade-offs:** * ⚠️ More complex initial setup * ⚠️ Requires planning domain structure * ⚠️ More files to manage * ⚠️ Slightly higher learning curve #### Decision Matrix Use this flowchart to decide: ``` Start │ ├─ Do you have 3+ developers? │ ├─ Yes → Hierarchical │ └─ No → Continue │ ├─ Do you have 20+ features planned? │ ├─ Yes → Hierarchical │ └─ No → Continue │ ├─ Do you have multiple business domains? │ ├─ Yes → Hierarchical │ └─ No → Continue │ └─ Is this a long-term (6+ months) project? ├─ Yes → Consider Hierarchical └─ No → Flat Structure (PRODUCT.md) ``` **When in doubt, start with flat.** You can migrate to hierarchical later without losing progress. ### Initialization Process #### Full Initialization (with templates) ```bash npx @itz4blitz/agentful init ``` Creates: * All required `.claude/` configuration * All `.agentful/` state files * `PRODUCT.md` template (flat structure by default) * `CLAUDE.md` template * Updates `.gitignore` **Note**: This creates a flat structure. To use hierarchical structure, see [Hierarchical Setup](#hierarchical-setup) below. #### Bare Initialization (existing project) ```bash npx @itz4blitz/agentful init --bare ``` Creates: * All required `.claude/` configuration * All `.agentful/` state files * Updates `.gitignore` Skips: * `PRODUCT.md` (if exists) * `CLAUDE.md` (if exists) #### Hierarchical Setup To initialize with a hierarchical structure: ```bash # 1. Run normal init npx @itz4blitz/agentful init # 2. Create hierarchical structure mkdir -p .claude/product/domains .claude/product/quality-gates # 3. Move or delete the flat PRODUCT.md # Option A: Move it as the root overview mv PRODUCT.md .claude/product/PRODUCT.md # Option B: Delete it and start fresh rm PRODUCT.md # 4. Create your domain structure # See "Hierarchical Product Structure" section below ``` **Migration from Flat to Hierarchical:** You can migrate at any time without losing progress: ```bash # 1. Create hierarchical structure mkdir -p .claude/product/domains .claude/product/quality-gates # 2. Move existing PRODUCT.md as root mv PRODUCT.md .claude/product/PRODUCT.md # 3. Extract features into domains # Create DOMAIN.md and feature files based on your existing spec ``` ### .claude/settings.json This is the core configuration file that controls hooks and permissions. #### Structure ```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 Reference | Hook | Trigger | Use Case | | ------------------ | ------------------------- | -------------------------------- | | `PostToolUse` | After any tool use | Run type checks, linting | | `PreToolUse` | Before tool execution | Validate state, check locks | | `UserPromptSubmit` | When user submits message | Display context, check decisions | #### Permission Patterns Allow patterns support wildcards: ```json { "permissions": { "allow": [ "Bash(npm:*)", // All npm commands "Bash(npx:*)", // All npx commands "Bash(git:*)", // All git commands "Bash(node:*)", // All node scripts "Bash(cat:*.md)", // cat markdown files only "Bash(jq:.agentful/*)" // jq on agentful files only ], "deny": [ "Bash(rm -rf /)", // Never allow rm -rf / "Bash(rm -rf ~/.*)", // Never allow rm home "Bash(dd:*)", // Never allow dd command "Bash(mkfs:*)" // Never allow filesystem creation ] } } ``` ### Product Specification Structure The product specification is the most important configuration file. agentful supports two formats: #### Flat Structure (PRODUCT.md) Single file containing all product information. Best for simple projects. #### Hierarchical Structure (`.claude/product/`) Organized structure with domains, features, and quality gates. Best for complex projects. ##### Required Files ``` .claude/product/ ├── PRODUCT.md # Root product overview (required) ├── domains/ # Business domains (required if hierarchical) │ ├── {domain-name}/ │ │ ├── DOMAIN.md # Domain overview (required) │ │ └── features/ # Feature files (required) │ │ ├── {feature}.md │ │ └── {feature}.md └── quality-gates/ # Quality standards (optional) ├── testing.md ├── security.md └── performance.md ``` ### Flat Structure (PRODUCT.md) The single-file approach for simple projects. #### Required Sections (Flat) ```markdown # Product Specification ## Overview [2-3 sentence description of what you're building] ## Goals - [ ] Primary goal 1 - [ ] Primary goal 2 - [ ] Primary goal 3 ## Tech Stack ### Frontend - **Framework**: [Next.js / React / Vue / Svelte] - **Language**: [TypeScript / JavaScript] - **Styling**: [Tailwind / CSS Modules / styled-components] ### Backend - **Runtime**: [Node.js / Bun / Deno] - **Framework**: [Express / Fastify / NestJS / Next.js API] - **Language**: [TypeScript / JavaScript] ### Database - **Database**: [PostgreSQL / MySQL / MongoDB / SQLite] - **ORM**: [Prisma / Drizzle / TypeORM / Mongoose] ### Authentication - **Method**: [JWT / Sessions / NextAuth / Clerk] ### Testing - **Unit**: [Vitest / Jest] - **E2E**: [Playwright / Cypress] ## Features ### 1. [Feature Name] - CRITICAL **Description**: [What this feature does] **Acceptance Criteria**: - [ ] [Specific requirement 1] - [ ] [Specific requirement 2] - [ ] [Specific requirement 3] **User Stories**: - As a [user type], I want [feature] so that [benefit] ## 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] ``` #### Minimal Flat PRODUCT.md ```markdown # Product Specification ## Overview A simple TODO list application. ## Tech Stack - Next.js 14 - TypeScript - Tailwind CSS - Prisma + SQLite ## Features ### 1. Create TODO - CRITICAL - User can add a task - Task has title and description ### 2. List TODOs - CRITICAL - Display all tasks - Show completion status ## Success Criteria 1. All features working 2. Tests passing 3. No type errors (adapts to stack) ``` ### Hierarchical Structure (`.claude/product/`) The multi-file approach for complex projects. This structure separates concerns into domains, features, and quality gates. #### Root Product Overview (`.claude/product/PRODUCT.md`) High-level product description and tech stack: ```markdown # Product Specification ## Overview A comprehensive e-commerce platform with multi-vendor support, real-time inventory, and advanced analytics. ## Goals - [ ] Launch with 100+ products - [ ] Support 10+ vendors simultaneously - [ ] Process 1000+ orders/day - [ ] Provide real-time inventory updates ## Tech Stack ### Frontend - **Framework**: Next.js 14 - **Language**: TypeScript - **Styling**: Tailwind CSS - **State**: Zustand + React Query ### Backend - **Runtime**: Node.js - **Framework**: Next.js API Routes - **Language**: TypeScript ### Database - **Database**: PostgreSQL - **ORM**: Prisma - **Cache**: Redis ### Authentication - **Method**: NextAuth.js - **Providers**: Google, GitHub, Email ### Testing - **Unit**: Vitest - **E2E**: Playwright ## Domains - **Authentication**: User accounts, login, registration - **Product Catalog**: Product management, categories, search - **Order Management**: Cart, checkout, order processing - **Vendor Portal**: Vendor dashboard, inventory, analytics - **Admin Panel**: Platform administration, moderation ## Success Criteria The product is complete when: 1. All domains fully implemented and tested 2. All tests passing with 80%+ coverage 3. No type errors 4. No security vulnerabilities 5. Load tested to 1000 concurrent users 6. Deployed to production ``` #### Domain Structure (`.claude/product/domains/{domain}/DOMAIN.md`) Each domain has a DOMAIN.md file describing that business area: ```markdown # Authentication Domain ## Overview Handles all user authentication, authorization, and account management functionality. ## Scope - User registration and login - Password management - Profile management - Session handling - OAuth integrations ## Dependencies - None (foundational domain) ## Features - User Registration - User Login - Password Reset - Email Verification - OAuth (Google, GitHub) - Profile Management ## Quality Gates - All authentication flows tested - No security vulnerabilities - OWASP compliance verified ``` #### Feature Files (`.claude/product/domains/{domain}/features/{feature}.md`) Each feature has its own detailed specification: ```markdown # User Registration ## Description Allow new users to create accounts using email/password or OAuth providers. ## Priority CRITICAL ## Dependencies - None ## User Stories - As a new user, I want to register with email so that I can access the platform - As a new user, I want to sign up with Google so that I can quickly get started - As a user, I want to verify my email so that my account is secure ## Acceptance Criteria ### Email Registration - [ ] User can register with email and password - [ ] Password must be at least 8 characters with uppercase, lowercase, and number - [ ] Email must be valid format - [ ] Email must be unique - [ ] User receives verification email after registration - [ ] Account is inactive until email verified ### OAuth Registration - [ ] User can register with Google - [ ] User can register with GitHub - [ ] OAuth profile data is imported - [ ] Account is automatically verified ### Security - [ ] Passwords are hashed with bcrypt - [ ] Rate limiting on registration endpoint - [ ] CSRF protection enabled - [ ] Input validation on all fields ## Technical Requirements - Use NextAuth.js for authentication - Store users in PostgreSQL via Prisma - Send emails using Resend - Implement rate limiting with upstash ``` #### Quality Gates (`.claude/product/quality-gates/{gate}.md`) Define quality standards for different aspects: ```markdown # Testing Standards ## Unit Testing - Minimum 80% code coverage - All business logic tested - Mock external dependencies - Fast execution (< 5 seconds total) ## Integration Testing - All API endpoints tested - Database operations tested - Authentication flows tested - Third-party integrations mocked ## E2E Testing - Critical user paths covered - Cross-browser testing (Chrome, Firefox, Safari) - Mobile responsive testing - Performance benchmarks met ## Test Quality - Clear test names - Independent tests (no shared state) - Proper setup/teardown - Meaningful assertions ``` ```markdown # Security Standards ## Authentication - All endpoints authenticated except public ones - Session timeout after 1 hour - Secure cookie flags enabled - CSRF protection on all mutations ## Authorization - Role-based access control (RBAC) - Resource-level permissions - Admin actions require elevated privileges ## Data Protection - Passwords hashed (bcrypt, rounds >= 12) - PII encrypted at rest - API keys in environment variables - Secrets never committed to git ## API Security - Rate limiting on all endpoints - Input validation and sanitization - SQL injection prevention (parameterized queries) - XSS prevention (input encoding, CSP) ## Compliance - OWASP Top 10 addressed - GDPR compliance for user data - Regular security audits ``` ### CLAUDE.md Structure Optional project-specific instructions file. #### When to Use CLAUDE.md * Custom architectural patterns * Company coding standards * Special validation rules * Team-specific workflows #### Example CLAUDE.md ```markdown # agentful Product Development This project uses agentful with custom settings. ## Project-Specific Rules 1. All API routes must use Zod validation 2. All components must use TypeScript strict mode 3. Database queries must use prepared statements 4. All tests must use Vitest ## Custom Workflows ### Before committing - Run `/agentful-validate` - Fix any issues - Update completion status ### Code review process - Use @reviewer after every feature - Fix issues with @fixer - Re-validate before moving on ## Special Instructions - Use our company's component library - Follow our API design guidelines - All logs must go to our logging service - Use our custom error handler ``` ### .agentful/ State Files These files are auto-generated and should not be manually edited. #### state.json ```json { "version": "1.0.0", "current_task": "implementing-authentication", "current_phase": "implementation", "iterations": 5, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": [] } ``` #### completion.json The completion tracking file format differs based on your product structure: ##### Flat Structure Format When using `PRODUCT.md`, features are tracked at the top level: ```json { "features": { "authentication": { "status": "complete", "score": 100, "started_at": "2026-01-18T00:00:00Z", "completed_at": "2026-01-18T01:00:00Z" }, "user-profile": { "status": "in_progress", "score": 45, "started_at": "2026-01-18T01:00:00Z" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": false, "coverage_80": false, "security_clean": true }, "overall": 48, "last_updated": "2026-01-18T01:30:00Z" } ``` ##### Hierarchical Structure Format When using `.claude/product/`, features are organized by domain: ```json { "domains": { "authentication": { "status": "complete", "score": 100, "features": { "user-registration": { "status": "complete", "score": 100, "started_at": "2026-01-18T00:00:00Z", "completed_at": "2026-01-18T01:00:00Z" }, "user-login": { "status": "complete", "score": 100, "started_at": "2026-01-18T01:00:00Z", "completed_at": "2026-01-18T02:00:00Z" }, "password-reset": { "status": "complete", "score": 100, "started_at": "2026-01-18T02:00:00Z", "completed_at": "2026-01-18T03:00:00Z" } } }, "product-catalog": { "status": "in_progress", "score": 35, "features": { "product-listing": { "status": "complete", "score": 100, "started_at": "2026-01-18T03:00:00Z", "completed_at": "2026-01-18T05:00:00Z" }, "product-details": { "status": "in_progress", "score": 60, "started_at": "2026-01-18T05:00:00Z" }, "product-search": { "status": "pending", "score": 0 } } } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": false, "coverage_80": false, "security_clean": true }, "overall": 52, "last_updated": "2026-01-18T06:00:00Z" } ``` **Key Differences:** | Aspect | Flat Format | Hierarchical Format | | --------------- | --------------------- | ------------------------------ | | Structure | Single-level features | Nested domains → features | | Status Tracking | Per feature | Per domain AND per feature | | Scoring | Feature-level only | Domain-level + feature-level | | Best For | Simple projects | Complex, multi-domain projects | #### decisions.json ```json { "pending": [ { "id": "decision-001", "question": "Should auth use JWT or session cookies?", "options": [ "JWT (stateless, scalable)", "Sessions (simpler, built-in)" ], "context": "Building authentication system", "blocking": ["auth-feature"], "timestamp": "2026-01-18T00:00:00Z" } ], "resolved": [ { "id": "decision-000", "question": "Database provider?", "answer": "PostgreSQL", "timestamp": "2026-01-17T23:00:00Z" } ] } ``` ### Git Configuration #### .gitignore agentful automatically adds to `.gitignore`: ```gitignore # agentful runtime state .agentful/ ``` #### Recommended Full .gitignore ```gitignore # Dependencies node_modules/ # agentful runtime state .agentful/ # Environment variables .env .env.local .env.*.local # Build output .next/ out/ dist/ build/ # IDE .vscode/ .idea/ # OS .DS_Store Thumbs.db # Testing coverage/ # Logs *.log npm-debug.log* ``` ### Structure Comparison Summary #### Quick Reference | Aspect | Flat (PRODUCT.md) | Hierarchical (`.claude/product/`) | | --------------------- | ----------------- | --------------------------------- | | **Setup Time** | 2 minutes | 10-15 minutes | | **Learning Curve** | Low | Medium | | **Best Team Size** | 1-2 developers | 3+ developers | | **Feature Capacity** | \< 20 features | 100+ features | | **File Count** | 1 file | 10+ files | | **Merge Conflicts** | More likely | Less likely | | **Parallel Work** | Difficult | Easy | | **Scalability** | Limited | Excellent | | **Domain Separation** | Manual | Built-in | | **Migration** | Can upgrade | N/A | #### Structure Selection Guide ##### Start with Flat if: * ✅ Building an MVP or prototype * ✅ Working solo or with one other developer * ✅ Project has \< 20 features * ✅ Single business domain * ✅ Need to start quickly * ✅ Learning agentful ##### Start with Hierarchical if: * ✅ Building a large-scale application * ✅ Working with a team of 3+ * ✅ Project has 20+ features * ✅ Multiple business domains * ✅ Features have complex dependencies * ✅ Long-term project (6+ months) * ✅ Need clear ownership boundaries #### Real-World Examples **Flat Structure Examples:** * Personal blog with CMS * Simple SaaS MVP (billing + core feature) * Portfolio website * Internal tools for small team * Prototype or proof-of-concept **Hierarchical Structure Examples:** * E-commerce platform (auth, products, orders, vendor portal, admin) * Project management tool (auth, projects, tasks, teams, notifications, reporting) * Healthcare app (auth, patients, appointments, records, billing, telehealth) * Social platform (auth, users, posts, comments, messaging, notifications, analytics) #### Migration Path **You can always start flat and migrate to hierarchical later:** 1. **Start with flat** - Quick setup, immediate progress 2. **Hit a threshold** - 20+ features or team grows 3. **Migrate gradually** - Extract features into domains over time 4. **No progress lost** - All work transfers seamlessly **Migration Process:** ```bash # 1. Create hierarchical structure mkdir -p .claude/product/domains .claude/product/quality-gates # 2. Move PRODUCT.md as root overview mv PRODUCT.md .claude/product/PRODUCT.md # 3. Extract features into domains # Group related features into domain folders # Each feature gets its own .md file # 4. Create domain overviews # Add DOMAIN.md for each domain explaining scope # 5. Completion tracking auto-updates # agentful detects the new structure and adapts ``` ### Best Practices #### For Flat Structure: 1. **Use clear feature naming** - Prefix with domain (e.g., "auth-login", "user-profile") 2. **Group related features** - Use comments or sections to organize 3. **Keep it focused** - If it gets too long, consider migrating to hierarchical 4. **Use priorities** - Mark features as CRITICAL, HIGH, MEDIUM, LOW 5. **Document dependencies** - Note which features depend on others #### For Hierarchical Structure: 1. **Plan your domains first** - Think about business areas, not technical layers 2. **Keep domains focused** - Each domain should have a clear purpose 3. **Limit domain size** - Aim for 5-10 features per domain 4. **Use consistent naming** - Follow the same pattern across all domains 5. **Document dependencies** - Note both inter-domain and intra-domain dependencies 6. **Create quality gates** - Define clear standards for each domain 7. **Assign ownership** - Each domain should have a clear owner/team #### Common Pitfalls to Avoid **Flat Structure:** * ❌ Don't let the file grow beyond 500 lines * ❌ Don't merge unrelated features into one * ❌ Don't ignore domain boundaries * ❌ Don't prevent team collaboration **Hierarchical Structure:** * ❌ Don't create too many domains (5-10 is ideal) * ❌ Don't over-organize (keep it simple) * ❌ Don't create empty domains * ❌ Don't forget to link related features * ❌ Don't make domains too technical (focus on business) ### Next Steps * [Agent Configuration](./agent-configuration) - Customize agents for your tech stack * [Workflow Configuration](./workflow-configuration) - Create custom commands and workflows ## Workflow Configuration agentful workflows are defined as slash commands. You can customize existing commands, create new workflows, and integrate with your development processes. ### Command Structure Commands are Markdown files with YAML frontmatter in `.claude/commands/`: ```markdown --- name: command-name description: What this command does --- # Command Name Detailed instructions... ``` #### Built-in Commands | Command | File | Purpose | | -------------------- | ---------------------- | ---------------------------- | | `/agentful-start` | `agentful-start.md` | Start autonomous development | | `/agentful-status` | `agentful-status.md` | Check progress | | `/agentful-decide` | `agentful-decide.md` | Answer pending decisions | | `/agentful-validate` | `agentful-validate.md` | Run quality checks | ### Customizing Existing Commands #### Modifying /agentful-start Edit `.claude/commands/agentful-start.md`: ````markdown --- name: agentful-start description: Start or resume autonomous development with custom workflow --- # agentful Start ## Custom Startup Sequence ### 1. Pre-Flight Checks - [ ] Check if git working directory is clean - [ ] Verify all dependencies installed - [ ] Confirm database is running - [ ] Validate environment variables ### 2. Load State Read in order: 1. `PRODUCT.md` - Product requirements 2. `.agentful/state.json` - Current state 3. `.agentful/completion.json` - Progress 4. `.agentful/decisions.json` - Pending decisions ### 3. Custom Initialization If state.json doesn't exist: ```bash # Run custom setup npm run setup:dev # Seed database if needed npm run db:seed # Run initial validation npx tsc --noEmit ```` #### 4. Delegate to Orchestrator Task("orchestrator", "Run autonomous development loop with custom priorities") ```` ### Custom Status Display Edit `.claude/commands/agentful-status.md`: ```markdown --- name: agentful-status description: Display detailed project status with custom metrics --- # agentful Status ## Display Format ### Progress Overview ```` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Progress: \[████████████░░░░░░░░] 60% Features: ✅ Authentication (100%) 🔄 User Profile (75%) ⏳ Dashboard (0%) Quality Gates: ✅ Tests passing (47/47) ✅ No type errors ❌ Dead code (3 issues) ⚠️ Coverage (72%, needs 80%) Last Activity: Implementing user avatar upload Next Task: Complete dashboard layout ``` ### Custom Metrics Add project-specific metrics: ``` Database Migrations: ✅ Up to date API Documentation: ⏳ Not generated Deployment Status: ✅ Production v2.3.1 ``` ``` ### Creating Custom Commands #### Feature-Specific Commands Create `.claude/commands/deploy.md`: ````markdown --- name: deploy description: Deploy application to production with safety checks --- # Deploy Command ## Pre-Deployment Checklist 1. **Run all tests** ```bash npm test ```` 2. **Type check** ```bash npx tsc --noEmit ``` 3. **Build production bundle** ```bash npm run build ``` 4. **Check for security issues** ```bash npm audit --production ``` 5. **Run E2E tests** ```bash npm run test:e2e ``` ### Deployment Steps If all checks pass: 1. Create git tag 2. Push to main branch 3. Trigger deployment pipeline 4. Verify health checks 5. Run smoke tests ### Rollback Plan If deployment fails: 1. Identify failure point 2. Revert to previous version 3. Investigate logs 4. Fix issue 5. Retry deployment ```` Usage: `/deploy` ### Database Migration Command Create `.claude/commands/migrate.md`: ```markdown --- name: migrate description: Run database migrations with safety checks --- # Database Migration ## Safety Checks 1. **Backup database** ```bash npm run db:backup ```` 2. **Check current migration status** ```bash npm run db:status ``` 3. **Review migration files** ```bash # Read migration files to validate safety ``` ### Migration Process 1. Generate migration if needed: ```bash npx prisma migrate dev --name migration_name ``` 2. Review generated SQL 3. Test migration on staging 4. Apply to production: ```bash npx prisma migrate deploy ``` 5. Verify data integrity 6. Update application schema ### Rollback Plan If migration fails: 1. Restore from backup 2. Identify issue in migration 3. Fix migration 4. Retry process ```` Usage: `/migrate` ### Code Review Command Create `.claude/commands/review.md`: ```markdown --- name: review description: Perform comprehensive code review of changes --- # Code Review ## Review Scope 1. **Git Changes** ```bash git diff main...HEAD ```` 2. **Changed Files** Identify all modified, added, and deleted files 3. **Review Checklist** * [ ] Code follows project patterns * [ ] TypeScript strict mode passes * [ ] Tests added/updated * [ ] Documentation updated * [ ] No security vulnerabilities * [ ] Performance considered * [ ] Error handling proper * [ ] Logging added where needed ### Review Process 1. Delegate to reviewer agent: ``` Task("reviewer", "Perform comprehensive review of recent changes") ``` 2. If issues found: ``` Task("fixer", "Fix issues found during review") ``` 3. Re-review until clean ### Report Format ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Code Review Report ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Files Changed: 7 Lines Added: +342 Lines Removed: -89 Issues Found: 🔴 Critical: 0 🟡 Warning: 3 🔵 Info: 5 Recommendations: 1. Add error handling to AuthService.login 2. Extract magic strings to constants 3. Add JSDoc comments to public APIs Status: ✅ Approved (with minor suggestions) ``` ```` Usage: `/review` ### Documentation Generation Command Create `.claude/commands/docs.md`: ```markdown --- name: docs description: Generate API documentation from code --- # Generate Documentation ## API Documentation 1. **Scan for API routes** ```bash find src/app/api -name "route.ts" ```` 2. **Extract endpoints** * HTTP methods * Request/response schemas * Authentication requirements * Rate limits 3. **Generate OpenAPI spec** ```bash npm run docs:generate ``` ### Component Documentation 1. **Scan for components** ```bash find src/components -name "*.tsx" -o -name "*.jsx" ``` 2. **Extract component props** 3. **Generate usage examples** 4. **Create Storybook stories** ### Output Generate: * `docs/api/` - API reference * `docs/components/` - Component catalog * `OPENAPI.json` - OpenAPI specification ```` Usage: `/docs` ## Workflow Automation ### Pre-Commit Workflow Create `.claude/commands/pre-commit.md`: ```markdown --- name: pre-commit description: Run all checks before committing code --- # Pre-Commit Checks ## Sequence 1. **Type Check** ```bash npx tsc --noEmit ```` 2. **Lint** ```bash npm run lint ``` 3. **Tests** ```bash npm test ``` 4. **Coverage** ```bash npm test -- --coverage ``` 5. **Dead Code** ```bash npx knip ``` 6. **Security** ```bash npm audit --production ``` ### Results If all pass: ``` ✅ All checks passed - Ready to commit ``` If any fail: ``` ❌ Pre-commit checks failed: - TypeScript: 3 errors - Lint: 7 warnings - Coverage: 72% (needs 80%) Run /fix to auto-fix issues ``` ```` ### Integration with Git Hooks Add to `package.json`: ```json { "scripts": { "prepare": "husky install", "pre-commit": "echo 'Running agentful pre-commit checks' && claude /pre-commit || exit 1" } } ```` Or use `.husky/pre-commit`: ```bash #!/bin/sh . "$(dirname "$0")/_/husky.sh" # Run agentful pre-commit checks npx agentful pre-commit # Exit on failure if [ $? -ne 0 ]; then echo "❌ Pre-commit checks failed. Commit aborted." exit 1 fi ``` #### CI/CD Integration ##### GitHub Actions Create `.github/workflows/agentful.yml`: ```yaml name: agentful Validation on: pull_request: branches: [main] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' - name: Install dependencies run: npm ci - name: Run agentful validation run: | npx @itz4blitz/agentful init --bare npx agentful validate - name: Upload validation report uses: actions/upload-artifact@v3 with: name: validation-report path: .agentful/last-validation.json ``` ##### GitLab CI Create `.gitlab-ci.yml`: ```yaml stages: - validate agentful-validation: stage: validate image: node:18 script: - npm ci - npx @itz4blitz/agentful init --bare - npx agentful validate artifacts: paths: - .agentful/last-validation.json reports: junit: .agentful/validation-report.xml ``` ### Advanced Workflows #### Feature Development Workflow Create `.claude/commands/feature.md`: ```markdown --- name: feature description: Complete workflow for implementing a new feature --- # Feature Development ## Inputs Feature name from user input or PRODUCT.md ## Workflow ### 1. Planning Phase - Read PRODUCT.md for feature requirements - Create feature branch - Document implementation plan ### 2. Design Phase Task("architect", "Design database schema and API endpoints for feature") ### 3. Backend Phase Task("backend", "Implement backend services and API routes") ### 4. Frontend Phase Task("frontend", "Implement UI components and pages") ### 5. Testing Phase Task("tester", "Write comprehensive tests") ### 6. Review Phase Task("reviewer", "Review implementation") ### 7. Fix Phase (if needed) Task("fixer", "Fix any issues found in review") ### 8. Documentation Phase Task("docs", "Generate API documentation") ### 9. Validation Phase Run all quality checks ### 10. Completion - Update completion.json - Mark feature as complete - Report summary ## Example Usage User: `/feature user-profile` agentful: 1. Reads user-profile from PRODUCT.md 2. Creates feature branch feature/user-profile 3. Implements all requirements 4. Validates quality 5. Reports completion ``` #### Refactoring Workflow Create `.claude/commands/refactor.md`: ````markdown --- name: refactor description: Safe refactoring workflow with automated testing --- # Refactor Workflow ## Pre-Refactor 1. **Baseline tests** ```bash npm test ```` 2. **Create backup branch** ```bash git checkout -b refactor/backup-$(date +%s) ``` 3. **Document current state** * Capture test results * Document current behavior * Create rollback point ### Refactor Process 1. **Make changes** * Small, incremental changes * Run tests after each change * Commit working states 2. **Validate behavior** ```bash # All tests must pass npm test # No regressions npm run test:e2e # Performance maintained npm run benchmark ``` 3. **Code review** ``` Task("reviewer", "Review refactored code") ``` ### Post-Refactor 1. **Update tests** 2. **Update documentation** 3. **Remove deprecated code** 4. **Update CHANGELOG** ### Safety If tests fail at any point: 1. Stop immediately 2. Identify breaking change 3. Fix or revert 4. Re-validate ### Example User: `/refactor Extract user service logic` agentful: 1. Reads current user service code 2. Identifies extraction points 3. Creates new service modules 4. Updates all imports 5. Runs tests continuously 6. Completes when all tests pass ```` ### Hotfix Workflow Create `.claude/commands/hotfix.md`: ```markdown --- name: hotfix description: Emergency fix workflow for production issues --- # Hotfix Workflow ## Priority: CRITICAL This workflow bypasses normal process for urgent fixes. ## Process 1. **Create hotfix branch** ```bash git checkout -b hotfix/$(date +%s) ```` 2. **Minimal fix only** * Fix the specific issue * No refactoring * No new features * Minimal changes 3. **Quick validation** ```bash # Type check only npx tsc --noEmit # Critical tests only npm test -- --testNamePattern="critical" ``` 4. **Deploy to staging** ```bash npm run deploy:staging ``` 5. **Smoke test** ```bash npm run test:smoke ``` 6. **Deploy to production** ```bash npm run deploy:prod ``` 7. **Verify fix** * Check production logs * Verify issue resolved * Monitor metrics 8. **Follow-up** * Create regular issue for proper fix * Add tests for issue * Update documentation ### Example User: `/hotfix Users cannot login due to auth token error` agentful: 1. Identifies auth token bug 2. Creates minimal fix 3. Runs type check 4. Deploys to staging 5. Verifies fix works 6. Deploys to production 7. Creates follow-up ticket ```` ## Environment-Specific Workflows ### Development Workflow `.claude/commands/dev.md`: ```markdown --- name: dev description: Start development environment with watchers --- # Development Mode ## Start Services 1. **Database** ```bash npm run db:start ```` 2. **Backend** (if separate) ```bash npm run dev:api ``` 3. **Frontend** ```bash npm run dev ``` 4. **Watchers** ```bash # TypeScript watcher npx tsc --watch # Test watcher npm test -- --watch # Lint watcher npm run lint -- --watch ``` ### Development Features * Hot module replacement * Fast refresh * Source maps * Error overlay * Debug logging ### Integration Open browser to [http://localhost:3000](http://localhost:3000) with dev tools enabled. ```` ### Staging Workflow `.claude/commands/staging.md`: ```markdown --- name: staging description: Deploy to staging environment for testing --- # Staging Deployment ## Pre-Deploy 1. **Run full test suite** ```bash npm test npm run test:e2e ```` 2. **Build staging bundle** ```bash npm run build:staging ``` 3. **Security scan** ```bash npm audit --production ``` ### Deploy 1. **Deploy to staging** ```bash npm run deploy:staging ``` 2. **Run smoke tests** ```bash npm run test:smoke:staging ``` 3. **Verify deployment** * Check staging URL * Verify key features * Check error logs ### Report ``` ✅ Deployed to staging URL: https://staging.example.com Commit: abc123 Tests: ✅ All passing ``` ```` ### Production Workflow `.claude/commands/production.md`: ```markdown --- name: production description: Deploy to production with full validation --- # Production Deployment ## Pre-Deploy Checklist - [ ] All tests passing (100%) - [ ] Coverage ≥ 80% - [ ] No type errors (adapts to stack) - [ ] No lint errors - [ ] No dead code - [ ] No security vulnerabilities - [ ] Staging tests passed - [ ] Performance benchmarks met - [ ] Documentation updated - [ ] CHANGELOG updated - [ ] Migration plan tested - [ ] Rollback plan ready ## Deployment Steps 1. **Create release tag** ```bash git tag -a v1.0.0 -m "Release v1.0.0" git push origin v1.0.0 ```` 2. **Run database migrations** ```bash npm run db:migrate:prod ``` 3. **Deploy application** ```bash npm run deploy:prod ``` 4. **Smoke tests** ```bash npm run test:smoke:prod ``` 5. **Monitor** * Error rates * Response times * Resource usage * Business metrics ### Rollback Plan If deployment fails: ```bash npm run rollback:prod git revert HEAD npm run deploy:prod ``` ### Post-Deploy * Monitor for 1 hour * Check error logs * Verify key metrics * Notify team of success ``` ## Workflow Best Practices ### 1. Keep Workflows Simple - One purpose per workflow - Clear success criteria - Handle failures gracefully ### 2. Always Validate - Type check before committing - Test before deploying - Monitor after deploying ### 3. Provide Feedback - Show progress clearly - Report errors helpfully - Suggest next actions ### 4. Enable Automation - Integrate with CI/CD - Use git hooks - Automate repetitive tasks ### 5. Document Everything - Comment complex logic - Provide examples - Maintain CHANGELOG ## Workflow Examples Repository See `.claude/workflows/` for more examples: - `feature.mdx` - Feature development - `bugfix.mdx` - Bug fixing workflow - `release.mdx` - Release management - `performance.mdx` - Performance optimization - `security.mdx` - Security audit workflow ## Next Steps - [Configuration Overview](./index) - Back to configuration overview - [Project Structure](./project-structure) - File and directory requirements ``` ## /agentful-decide Answer pending decisions that are blocking development progress. ### Purpose The `/agentful-decide` command resolves architectural and product decisions that are blocking feature development. When the orchestrator encounters a choice that requires human input, it records a decision in `.agentful/decisions.json`. This command presents those decisions interactively, allows you to choose from options or provide custom input, and unblocks the affected features. ### Why Decisions Block Development Autonomous development requires clear direction. When you need to make choices like: * "Should auth use JWT or session cookies?" * "Which database provider for deployment?" * "UI framework for dashboard components?" The orchestrator **stops** and waits for your input because: 1. **Architectural impact** - These choices affect how code is written 2. **Avoiding rework** - Wrong choice = wasted development time 3. **Product direction** - Some decisions reflect product strategy 4. **Team coordination** - Decisions should be consistent across team Once you decide, the orchestrator resumes with clear direction. ### Usage #### Basic Usage ```bash /agentful-decide ``` This will: 1. Read pending decisions from `.agentful/decisions.json` 2. Present each decision with options 3. Accept your choice (number or custom input) 4. Record the decision 5. Remove from pending list 6. Unblock affected features #### After Warning from /agentful-start ```bash $ /agentful-start ⚠️ Pending decisions need your input: 1. "Should auth use JWT or session cookies?" Run: /agentful-decide $ /agentful-decide # Resolve decisions $ /agentful-start # Continue development ``` #### Interactive Mode When multiple decisions are pending: ```bash $ /agentful-decide You have 3 pending decisions to resolve: [1/3] Should auth use JWT or session cookies? Context: Building authentication system for PRODUCT.md Blocking: auth-feature, user-profile-feature Options: [1] JWT (stateless, scalable) [2] Sessions (simpler, built-in) [3] Clerk (managed service) [4] Custom input... Your choice: > 1 ✅ Recorded: JWT (stateless, scalable) [2/3] Which database provider for production? Context: Deployment infrastructure setup Blocking: deployment-feature Options: [1] PostgreSQL (standard, relational) [2] MongoDB (flexible, document) [3] SQLite (simple, embedded) [4] Custom input... Your choice: > 4 Enter custom option: > Supabase (PostgreSQL + Auth) ✅ Recorded: Supabase (PostgreSQL + Auth) [3/3] State management library? Context: Frontend state architecture Blocking: dashboard-feature Options: [1] Redux (standard, verbose) [2] Zustand (simple, modern) [3] Jotai (atomic, flexible) [4] Custom input... Your choice: > 2 ✅ Recorded: Zustand (simple, modern) ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ All 3 decisions resolved! Features Unblocked: • auth-feature • user-profile-feature • deployment-feature • dashboard-feature Run /agentful-start to continue development. ``` ### Decision Format #### Decision Structure Each decision in `.agentful/decisions.json` follows this structure: ```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", "priority": "high" } ], "resolved": [ { "id": "decision-002", "question": "Deployment platform?", "answer": "Vercel (serverless, edge)", "timestamp_resolved": "2026-01-18T00:30:00Z", "resolved_by": "user" } ] } ``` #### Decision Fields | Field | Type | Purpose | | -------------------- | -------------- | --------------------------------- | | `id` | string | Unique identifier (decision-XXX) | | `question` | string | What needs to be decided | | `options` | array\[string] | Predefined choices (can be empty) | | `context` | string | Why this decision matters | | `blocking` | array\[string] | Features/tasks blocked by this | | `timestamp` | string | When decision was created | | `priority` | string | high/medium/low urgency | | `answer` | string | What was chosen (resolved only) | | `timestamp_resolved` | string | When resolved (resolved only) | | `resolved_by` | string | Who resolved (user/agent) | ### How It Works #### 1. Read Pending Decisions ```javascript // .agentful/decisions.json { "pending": [ { "id": "decision-001", "question": "Should auth use JWT or session cookies?", "options": ["JWT", "Sessions", "Clerk"], "blocking": ["auth-feature"] } ] } ``` #### 2. Present to User ``` ┌────────────────────────────────────────────────────────────┐ │ Decision #1 │ ├────────────────────────────────────────────────────────────┤ │ Question: Should auth use JWT or session cookies? │ │ │ │ Context: Building authentication system for PRODUCT.md │ │ │ │ Options: │ │ [1] JWT (stateless, scalable) │ │ [2] Sessions (simpler, built-in) │ │ [3] Clerk (managed service) │ │ [4] Custom input... │ │ │ │ Blocking: auth-feature, user-profile-feature │ └────────────────────────────────────────────────────────────┘ Your choice: ``` #### 3. Record Decision After user selects option \[1]: ```javascript // Move from pending to resolved { "resolved": [ { "id": "decision-001", "question": "Should auth use JWT or session cookies?", "answer": "JWT (stateless, scalable)", "timestamp_resolved": "2026-01-18T00:30:00Z", "resolved_by": "user" } ], "pending": [] // Removed from pending } ``` #### 4. Update State Remove from `.agentful/state.json` blocked\_on array: ```javascript // Before { "blocked_on": ["auth-feature", "user-profile-feature"] } // After { "blocked_on": [] // Unblocked! } ``` #### 5. Notify Orchestrator The orchestrator can now proceed with auth implementation using JWT. ### When to Use #### After Warning ```bash $ /agentful-start ⚠️ Pending decisions need your input: 1. "Should auth use JWT or session cookies?" Run: /agentful-decide $ /agentful-decide # Required - can't proceed without this ``` #### Proactive Decision Making ```bash # Check if any decisions pending /agentful-status # If yes, resolve them before they block /agentful-decide ``` #### After Manual Changes ```bash # You implemented auth with JWT manually # Update decision log so orchestrator knows /agentful-decide # Select: JWT # Orchestrator now consistent with your choice ``` ### Examples by Scenario #### Scenario 1: First Decision ```bash $ /agentful-start ⚠️ CANNOT START - Pending decisions $ /agentful-decide You have 1 pending decision: [1/1] Authentication approach? Context: Starting auth implementation Blocking: auth-feature Options: [1] JWT (stateless) [2] Sessions (simple) [3] Clerk (managed) Your choice: > 1 ✅ Decision resolved: JWT Run /agentful-start to continue. ``` #### Scenario 2: Multiple Related Decisions ```bash $ /agentful-decide You have 4 pending decisions: [1/4] Auth strategy? > 1 (JWT) [2/4] Database provider? > 1 (PostgreSQL) [3/4] Deployment platform? > 2 (Vercel) [4/4] Monitoring setup? > 4 (Custom: Datadog) ✅ All 4 decisions resolved Features unblocked: auth, database, deployment, monitoring ``` #### Scenario 3: Custom Input ```bash $ /agentful-decide [1/1] UI component library? Options: [1] Material-UI [2] Chakra UI [3] Ant Design [4] Custom input... Your choice: > 4 Enter custom option: > Tailwind UI + Headless UI ✅ Decision resolved: Tailwind UI + Headless UI ``` #### Scenario 4: No Pending Decisions ```bash $ /agentful-decide ✅ No pending decisions! All features are unblocked. Run /agentful-start to continue development. ``` ### Tips #### Decision-Making Tips 1. **Read context carefully** * Context explains why the decision matters * Helps you understand architectural implications 2. **Consider what's blocking** * See which features are affected * High-impact decisions need more thought 3. **Custom input is okay** * Predefined options are suggestions * Your specific situation may require custom approach 4. **Decisions are recorded** * All decisions logged to decisions.json * Can review later for architectural history #### Best Practices 1. **Resolve decisions quickly** * Pending decisions immediately block progress * Don't let them accumulate 2. **Be consistent** * Similar decisions should have similar logic * Check previous decisions in resolved array 3. **Document tradeoffs** * If choosing custom, note why in answer * Example: "Vercel (team has experience)" 4. **Review periodically** ```bash # See all decisions (pending + resolved) cat .agentful/decisions.json | jq '.' ``` #### Team Collaboration 1. **Share decisions.json** ```bash # Commit decisions for team visibility git add .agentful/decisions.json git commit -m "decide: Choose JWT for auth" git push ``` 2. **Discuss blockers** * If unsure about decision, discuss with team first * Then run `/agentful-decide` to record 3. **Override if needed** ```bash # Edit decisions.json directly # Change pending decision options # Then run /agentful-decide ``` ### Troubleshooting #### Issue: Decisions.json is empty **Cause:** No decisions recorded yet **Solution:** ```bash # Initialize file echo '{"pending":[],"resolved":[]}' > .agentful/decisions.json # Decisions will be added by orchestrator as needed ``` #### Issue: Decision doesn't show in /agentful-decide **Cause:** Decision already resolved or not in pending array **Solution:** ```bash # Check current state cat .agentful/decisions.json | jq '.pending' # If in resolved, move back to pending if needed # Or create new decision with correct id ``` #### Issue: Features still blocked after deciding **Cause:** state.json blocked\_on not updated **Solution:** ```bash # Check blocked_on cat .agentful/state.json | jq '.blocked_on' # Manually clear if needed jq '.blocked_on = []' .agentful/state.json > temp.json mv temp.json .agentful/state.json ``` #### Issue: Want to change a decision **Cause:** Need to update previous choice **Solution:** ```bash # 1. Move from resolved to pending jq '.pending += [.resolved[0]] | .resolved = .resolved[1:]' \ .agentful/decisions.json > temp.json mv temp.json .agentful/decisions.json # 2. Re-run decide /agentful-decide ``` ### Advanced Usage #### Batch Decision Resolution ```bash # Pre-define all decisions at once cat > .agentful/decisions.json << 'EOF' { "pending": [ { "id": "decision-001", "question": "Auth strategy?", "options": ["JWT", "Sessions"], "blocking": ["auth"] }, { "id": "decision-002", "question": "Database?", "options": ["PostgreSQL", "MongoDB"], "blocking": ["database"] } ], "resolved": [] } EOF # Then resolve all at once /agentful-decide ``` #### Decision Templates Create reusable decision patterns: ```json // .agentful/decision-templates.json { "templates": { "auth-strategy": { "question": "Authentication approach?", "options": ["JWT", "Sessions", "OAuth", "Clerk"], "default": "JWT" }, "database": { "question": "Database provider?", "options": ["PostgreSQL", "MongoDB", "SQLite"], "default": "PostgreSQL" } } } ``` #### Priority-Based Decisions ```json { "pending": [ { "id": "decision-001", "question": "Critical architectural choice?", "priority": "high", "blocking": ["core-feature"] }, { "id": "decision-002", "question": "Nice-to-have feature option?", "priority": "low", "blocking": ["optional-feature"] } ] } # /agentful-decide will show high priority first ``` #### Decision History Analysis ```bash # See all past decisions jq '.resolved[] | {question, answer, timestamp}' \ .agentful/decisions.json # Count by type jq '.resolved[] | .question' .agentful/decisions.json | \ sort | uniq -c # Export to CSV for analysis jq -r '.resolved[] | [.question, .answer, .timestamp_resolved] | @csv' \ .agentful/decisions.json > decisions.csv ``` ### Integration Examples #### Pre-Development Checklist ```bash #!/bin/bash # check-decisions.sh PENDING=$(jq '.pending | length' .agentful/decisions.json) if [ "$PENDING" -gt 0 ]; then echo "⚠️ You have $PENDING pending decisions:" jq -r '.pending[] | " • \(.question)"' .agentful/decisions.json echo "" echo "Run /agentful-decide before starting development." exit 1 else echo "✅ No pending decisions. Ready to develop!" exit 0 fi ``` #### Decision Review Bot ```bash # Run daily to review recent decisions jq '.resolved[] | select(.timestamp_resolved >= now - 86400) | "Resolved: \(.question) → \(.answer)"' \ .agentful/decisions.json ``` #### Sync with Project Management ```bash # Create GitHub issues from decisions jq -r '.pending[] | "gh issue create --title \"Decision: \(.question)\" --body \"\(.context)\""' \ .agentful/decisions.json | bash ``` ### Common Decision Patterns #### Authentication ```json { "question": "Authentication strategy?", "options": [ "JWT (stateless, scalable)", "Sessions (simple, server-managed)", "Clerk/Auth0 (managed service)", "NextAuth (framework-specific)" ], "context": "Affects entire auth architecture", "blocking": ["auth-feature", "user-management"] } ``` #### Database ```json { "question": "Database provider?", "options": [ "PostgreSQL (relational, ACID)", "MongoDB (document, flexible)", "SQLite (embedded, simple)", "Supabase (PostgreSQL + services)" ], "context": "Affects data modeling and queries", "blocking": ["database-setup", "data-modeling"] } ``` #### Deployment ```json { "question": "Deployment platform?", "options": [ "Vercel (serverless, edge)", "Netlify (static, JAMstack)", "AWS (cloud, flexible)", "Railway/Render (simple PaaS)" ], "context": "Affects CI/CD and infrastructure", "blocking": ["deployment-feature"] } ``` ### See Also * [/agentful-start](./agentful-start) - Continue after resolving decisions * [/agentful-status](./agentful-status) - Check if decisions are pending * [Decision Templates](/commands/agentful-decide) - Creating reusable decision patterns * [State Management](/core-concepts/state-management) - How decisions affect state * [Orchestrator](/agents/orchestrator) - How orchestrator uses decisions ## /agentful-start Start or resume autonomous product development loop by delegating to the orchestrator agent. ### Purpose The `/agentful-start` command is the primary entry point for autonomous development. It: * Reads current project state from `.agentful/state.json` * Checks for pending decisions that might block progress * Delegates to the orchestrator agent to pick and execute tasks * Continues the development loop until interrupted or complete * Updates completion tracking in `.agentful/completion.json` ### Usage #### Basic Usage ```bash /agentful-start ``` This will: 1. Check for pending decisions (and warn if any exist) 2. Read current state and completion status 3. Pick the next task to work on 4. Delegate to specialist agents 5. Validate the completed work 6. Update state and completion tracking 7. Report progress #### Autonomous Loop Mode For continuous development, wrap in Ralph loop: ```bash /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` This runs 24/7 until: * All features reach 100% completion * All quality gates pass * Maximum iterations reached (safety limit) #### After Resolving Decisions ```bash # If /agentful-start reports pending decisions /agentful-decide # Then continue development /agentful-start ``` ### Startup Sequence #### 1. Load State The command reads these files in order: | File | Purpose | | --------------------------- | ---------------------------------- | | `PRODUCT.md` | What we're building (requirements) | | `.agentful/state.json` | Current work state and progress | | `.agentful/completion.json` | Feature completion percentages | | `.agentful/decisions.json` | Pending user decisions | #### 2. Check Decisions If pending decisions exist, the command warns you: ``` ⚠️ Pending decisions need your input: 1. "Should auth use JWT or session cookies?" Run: /agentful-decide Cannot proceed until decisions are resolved. ``` **Why this check?** Decisions often represent architectural choices that affect implementation. Proceeding without resolution could lead to wasted work. #### 3. Initialize State (if needed) If `.agentful/state.json` doesn't exist: ```json { "version": "1.0", "current_task": null, "current_phase": "idle", "iterations": 0, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": [] } ``` #### 4. Delegate to Orchestrator The command **does not** execute work directly. Instead, it delegates: ``` Task("orchestrator", "Run autonomous development loop. Read state, pick next task, delegate to specialist agents, validate, update state, continue until complete.") ``` ### How It Works #### Example Flow ``` 1. Orchestrator reads state.json → "backend-auth" in progress, 30% complete 2. Orchestrator reads completion.json → Auth feature at 30%, needs implementation 3. Orchestrator reads PRODUCT.md → Auth requirements: JWT tokens, refresh, logout 4. Orchestrator delegates to @backend → "Complete auth implementation: login, refresh, logout" 5. Backend agent implements auth system 6. Orchestrator delegates to @reviewer → "Review auth changes for quality and standards" 7. Reviewer finds issues (e.g., missing tests) 8. Orchestrator delegates to @fixer → "Add missing auth tests" 9. Orchestrator delegates to @reviewer again → "Re-review auth changes" 10. Reviewer approves 11. Orchestrator updates completion.json → Auth feature: 30% → 100% 12. Orchestrator loops back: What's next? → Picks "user-profile" feature ``` #### Task Selection Logic The orchestrator picks tasks based on: 1. **Blocking dependencies** - Unblocked tasks first 2. **Completion priority** - Lowest completion % first 3. **Feature dependencies** - Prerequisites before dependents 4. **Current state** - Resume in-progress tasks before starting new ones ### Output Examples #### Successful Task Completion ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Session ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Loaded state: 3 features, 48% complete Pending decisions: 0 Blocked tasks: 0 Starting development loop... 🔄 Task 1/5: User Authentication Backend Agent: backend Requirements: JWT tokens, refresh flow, logout → Implementing auth service layer... → Adding token refresh logic... → Creating logout endpoint... → Writing unit tests... ✅ Complete 📊 Validation: • TypeScript: ✅ PASS • Tests: ✅ PASS (12/12) • Coverage: ✅ 94% • Security: ✅ PASS → Updated completion: auth 30% → 100% 🔄 Task 2/5: User Profile API Agent: backend Requirements: CRUD operations, avatar upload → Implementing profile model... → Creating CRUD endpoints... ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Session Progress: Tasks Completed: 1/5 Overall Completion: 48% → 58% Quality Gates: All passing Run /agentful-status for details or /agentful-start to continue. ``` #### Blocked by Decisions ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Session ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ⚠️ CANNOT START - Pending Decisions Required You have 2 pending decisions that block progress: 1. "Should auth use JWT or session cookies?" Options: JWT (stateless), Sessions (simpler), Clerk (managed) Blocking: auth-feature, user-profile-feature 2. "Database provider for deployment?" Options: PostgreSQL (standard), MongoDB (flexible), SQLite (simple) Blocking: deployment-feature Run /agentful-decide to resolve these decisions before continuing. ``` #### Development Complete ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Session ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ ✅ ALL FEATURES COMPLETE! Product: My Awesome App Completion: 100% Quality Gates: All passing Features Delivered: ✅ Authentication (100%) ✅ User Profile (100%) ✅ Dashboard (100%) ✅ Settings (100%) Quality Status: ✅ Tests: 47/47 passing ✅ TypeScript: No errors ✅ Lint: No issues ✅ Coverage: 87% ✅ Security: No vulnerabilities Total Iterations: 23 Time Elapsed: 2 hours 14 minutes 🎉 Product development complete! Ready for deployment. ``` ### When to Use #### Ideal Times to Run /agentful-start | Situation | Command | Why | | ------------------------- | -------------------------------------------------- | ------------------------------------------- | | Starting a new session | `/agentful-start` | Begin autonomous work | | After resolving decisions | `/agentful-start` | Continue unblocked development | | After manual changes | `/agentful-start` | Integrate your changes with autonomous flow | | Checking progress | `/agentful-status` first, then `/agentful-start` | See state before continuing | | Quality issues found | `/agentful-validate` first, then `/agentful-start` | Validate before proceeding | #### When NOT to Use | Situation | Alternative | | ----------------------- | ----------------------------------------- | | Pending decisions exist | `/agentful-decide` first | | Want to see what's done | `/agentful-status` | | Quality check needed | `/agentful-validate` | | Manual development | Just code, then run commands to integrate | ### Tips #### Productivity Tips 1. **Run in parallel with other work** ```bash # Start autonomous development /agentful-start # While it runs, work on something else # Come back later to check progress ``` 2. **Use autonomous mode for long sessions** ```bash /ralph-loop "/agentful-start" --max-iterations 50 # Go get coffee, come back to completed features ``` 3. **Check status periodically** ```bash /agentful-status # Quick check without interrupting work ``` 4. **Let it iterate through small tasks** ```bash # Start once, let it run 5-10 iterations /agentful-start # Each iteration = one task completed ``` #### Best Practices 1. **Keep PRODUCT.md updated** * Clear requirements = better autonomous decisions * Update as requirements evolve 2. **Resolve decisions quickly** * Pending decisions immediately block progress * Use `/agentful-decide` as soon as warned 3. **Monitor iteration count** * High iterations without progress = possible issue * Check `/agentful-status` if stuck 4. **Run validation after major features** ```bash /agentful-start # Complete feature /agentful-validate # Verify quality /agentful-start # Continue ``` ### Troubleshooting #### Issue: "Cannot proceed until decisions are resolved" **Cause:** Pending decisions in `.agentful/decisions.json` **Solution:** ```bash /agentful-decide # Resolve all pending decisions /agentful-start ``` #### Issue: "No tasks available to work on" **Cause:** All features complete or everything blocked **Solution:** ```bash /agentful-status # Check if truly complete (100%) # Or identify what's blocking progress ``` #### Issue: Stuck in loop, not making progress **Cause:** Validation failing repeatedly **Solution:** ```bash /agentful-validate # See specific failures # Fix manually or let /agentful-start auto-fix ``` #### Issue: "state.json not found" **Cause:** First-time run or missing initialization **Solution:** ```bash mkdir -p .agentful cat > .agentful/state.json << 'EOF' { "version": "1.0", "current_task": null, "current_phase": "idle", "iterations": 0, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": [] } EOF /agentful-start ``` #### Issue: Orchestrator not starting **Cause:** Agent not configured or system error **Solution:** ```bash # Check agent configuration ls .claude/agents/ # Verify PRODUCT.md exists cat PRODUCT.md # Try running orchestrator directly Task("orchestrator", "Test orchestrator agent") ``` ### Advanced Usage #### Custom Task Selection Force specific task by updating state: ```json // .agentful/state.json { "current_task": "user-profile-backend", "current_phase": "implementing", "force_task": true } ``` Then run `/agentful-start` #### Iteration Control Limit work per session: ```bash # Run 3 tasks then stop /agentful-start --max-tasks 3 # Run for 30 minutes then stop /agentful-start --max-time 30m ``` #### Parallel Development Work on multiple features simultaneously: ```json // .agentful/state.json { "parallel_tasks": 2, "active_tasks": [ "auth-backend", "user-profile-frontend" ] } ``` #### State Restoration Restore from previous session: ```bash # Check last state cat .agentful/state.json # Resume from specific iteration echo '{"iteration": 15}' > .agentful/resume.json /agentful-start ``` ### Integration Examples #### CI/CD Pipeline ```yaml # .github/workflows/agentful-dev.yml name: Autonomous Development on: schedule: - cron: '0 */2 * * *' # Every 2 hours workflow_dispatch: jobs: develop: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 - name: Install dependencies run: npm install - name: Run autonomous development run: | echo "Starting autonomous development loop..." /agentful-start - name: Validate results run: /agentful-validate - name: Commit progress run: | git config user.name "agentful Bot" git add . git commit -m "feat: autonomous development progress" git push ``` #### Pre-commit Hook ```bash # .git/hooks/pre-commit #!/bin/bash echo "Running pre-commit validation..." /agentful-validate if [ $? -ne 0 ]; then echo "❌ Validation failed. Commit aborted." echo "Run /agentful-start to auto-fix issues." exit 1 fi ``` #### Monitoring Script ```bash #!/bin/bash # watch-agentful.sh while true; do clear /agentful-status echo "Refreshing in 30 seconds..." sleep 30 done ``` ### See Also * [/agentful-status](./agentful-status) - Check development progress * [/agentful-decide](./agentful-decide) - Resolve blocking decisions * [/agentful-validate](./agentful-validate) - Run quality checks * [Orchestrator Agent](/agents/orchestrator) - How task selection works * [State Management](/core-concepts/state-management) - Understanding state files ## /agentful-status Show current progress, completion percentage, phase, and what's being worked on. ### Purpose The `/agentful-status` command provides a comprehensive overview of your autonomous development session. It displays: * Overall product completion percentage * Individual feature status (Done/Active/Pending) * Quality gate results (tests, types, lint, coverage, security) * Pending decisions that need resolution * Current work being performed * Iteration count and session history Use this command to quickly understand where your project stands without interrupting development flow. ### Usage #### Basic Usage ```bash /agentful-status ``` This displays a formatted dashboard showing all aspects of development progress. #### Common Patterns ```bash # Before starting work /agentful-status # → See what's done, what's next # After autonomous run /agentful-status # → Check what was completed # When blocked /agentful-status # → Identify what's blocking progress # Before making decisions /agentful-status # → Review context for decisions ``` ### Output Format #### Complete Status Display ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ agentful Development Status ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Product: TaskMaster Pro Overall Progress: ████████░░░░░░░░░░ 48% Phase: backend-implementation Iterations: 12 Last Updated: 2026-01-18 14:32:15 UTC ┌─────────────────────┬──────────┬─────────┬────────────────┐ │ Feature │ Status │ Score │ Notes │ ├─────────────────────┼──────────┼─────────┼────────────────┤ │ Authentication │ ✅ Done │ 100% │ │ │ User Profile │ 🔄 Active│ 45% │ Backend done │ │ │ │ │ Frontend pending│ │ Dashboard │ ⏸ Pending│ 0% │ Blocked on UX │ │ Settings │ ⏸ Pending│ 0% │ │ │ Notifications │ ⏸ Pending│ 0% │ │ └─────────────────────┴──────────┴─────────┴────────────────┘ ┌─────────────────────┬────────┐ │ Quality Gate │ Status │ ├─────────────────────┼────────┤ │ Tests Passing │ ✅ │ 47/47 │ No Type Errors │ ✅ │ │ No Dead Code │ ❌ │ 3 issues │ Coverage ≥ 80% │ ⚠️ │ 72% │ Security Scan │ ✅ │ └─────────────────────┴────────┘ ⚠️ Decisions Needed: 1. "Dashboard UI framework?" Options: React (standard), Svelte (faster), Vue (simple) Context: Building dashboard component library Blocking: dashboard-feature → Run /agentful-decide to resolve 🔧 Currently Working On: Task: user-profile-frontend Agent: frontend Started: 8 minutes ago Phase: Implementing profile edit form Last output: "Creating form validation schema..." ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Next Actions: • /agentful-start - Continue development • /agentful-decide - Answer pending decisions • /agentful-validate- Run quality checks ``` ### Output Sections #### Header Section ``` Product: TaskMaster Pro Overall Progress: ████████░░░░░░░░░░ 48% Phase: backend-implementation Iterations: 12 Last Updated: 2026-01-18 14:32:15 UTC ``` **What it tells you:** * **Product**: Name from PRODUCT.md * **Progress**: Visual bar + percentage of all features * **Phase**: Current development phase (e.g., planning, implementing, validating) * **Iterations**: Number of development cycles completed * **Last Updated**: When state was last modified **How to use this info:** * Track progress over time * Identify if development is active (recent update) * See how many iterations have run #### Feature Table ``` ┌─────────────────────┬──────────┬─────────┬────────────────┐ │ Feature │ Status │ Score │ Notes │ ├─────────────────────┼──────────┼─────────┼────────────────┤ │ Authentication │ ✅ Done │ 100% │ │ │ User Profile │ 🔄 Active│ 45% │ Backend done │ │ │ │ │ Frontend pending│ │ Dashboard │ ⏸ Pending│ 0% │ Blocked on UX │ │ Settings │ ⏸ Pending│ 0% │ │ └─────────────────────┴──────────┴─────────┴────────────────┘ ``` **Status indicators:** * ✅ **Done** - Feature complete (100%), validated, ready * 🔄 **Active** - Currently being worked on (`> 0%`, `< 100%`) * ⏸ **Pending** - Not started (0%), may be blocked **Notes column explains:** * Why a feature is blocked * What's left to complete * Dependencies or prerequisites **How to use this info:** * See what features are done vs. pending * Identify what's blocking progress * Understand feature dependencies #### Quality Gates ``` ┌─────────────────────┬────────┐ │ Quality Gate │ Status │ ├─────────────────────┼────────┤ │ Tests Passing │ ✅ │ 47/47 │ No Type Errors │ ✅ │ │ No Dead Code │ ❌ │ 3 issues │ Coverage ≥ 80% │ ⚠️ │ 72% │ Security Scan │ ✅ │ └─────────────────────┴────────┘ ``` **Gate meanings:** * **Tests Passing** - All tests pass (shows count if available) * **No Type Errors** - TypeScript compilation succeeds * **No Dead Code** - No unused exports, files, or imports * **Coverage ≥ 80%** - Code coverage meets threshold * **Security Scan** - No vulnerabilities or secrets **Status indicators:** * ✅ **Pass** - Gate passed, no action needed * ⚠️ **Warning** - Gate soft-failed (e.g., coverage at 72%) * ❌ **Fail** - Gate failed, needs attention **How to use this info:** * Identify quality issues before proceeding * See what's preventing validation from passing * Prioritize what to fix #### Pending Decisions ``` ⚠️ Decisions Needed: 1. "Dashboard UI framework?" Options: React (standard), Svelte (faster), Vue (simple) Context: Building dashboard component library Blocking: dashboard-feature → Run /agentful-decide to resolve ``` **What it shows:** * Question that needs your input * Available options with descriptions * Context for why the decision is needed * What features/tasks are blocked by this decision **How to use this info:** * Understand what decisions are blocking progress * Prepare answers before running `/agentful-decide` * See architectural context for decisions #### Current Work ``` 🔧 Currently Working On: Task: user-profile-frontend Agent: frontend Started: 8 minutes ago Phase: Implementing profile edit form Last output: "Creating form validation schema..." ``` **What it tells you:** * Which task is currently executing * Which specialist agent is working * How long it's been running * What phase of the task * Most recent log/output **How to use this info:** * See if development is active or stuck * Understand what's happening right now * Identify if a task is taking too long ### When to Use #### Before Starting Work ```bash /agentful-status # → See what's been done # → Identify what's next # → Check if blocked by decisions ``` **Why:** Helps you understand current state before taking action. #### After Autonomous Session ```bash /agentful-start # [Let it run for a while] # Ctrl+C to stop /agentful-status # → See what was completed # → Check overall progress ``` **Why:** Validate that progress was made during the session. #### When Development Seems Stuck ```bash /agentful-status # → Check "Currently Working On" section # → See if task is taking too long # → Identify blocking decisions ``` **Why:** Diagnose why development isn't progressing. #### Before Making Decisions ```bash /agentful-status # → Review pending decisions in context # → See what features are blocked # → Understand architectural tradeoffs ``` **Why:** Provides context for making informed decisions. #### Quality Check ```bash /agentful-status # → Quick look at quality gates # → If issues found, run /agentful-validate for details ``` **Why:** Fast quality overview without running full validation. ### Examples by Scenario #### Scenario 1: New Session Check ```bash $ /agentful-status Product: MyApp Progress: ██░░░░░░░░░░░░░░░ 20% Phase: Initial development Iterations: 2 Features: ✅ Setup (100%) 🔄 Auth (60%) ⏸ Dashboard (0%) Quality: All gates passing Decisions: None pending Current Work: Implementing auth refresh tokens ``` **Interpretation:** Early development, auth in progress, no blockers. #### Scenario 2: Blocked Development ```bash $ /agentful-status Product: MyApp Progress: ████░░░░░░░░░░░░ 40% Phase: Blocked on decisions Iterations: 8 Features: ✅ Auth (100%) ⏸ Dashboard (0%) - Blocked on UI framework ⚠️ Decisions Needed: 1. "UI framework for dashboard?" Blocking: dashboard-feature ``` **Interpretation:** Development halted by pending decision. Need to run `/agentful-decide`. #### Scenario 3: Quality Issues ```bash $ /agentful-status Product: MyApp Progress: ████████░░░░░░░░ 60% Phase: Fixing quality issues Iterations: 15 Features: ✅ Auth (100%) ✅ Dashboard (100%) 🔄 Profile (90%) Quality Gates: Tests: ✅ TypeScript: ✅ Dead Code: ❌ 5 issues Coverage: ⚠️ 76% ``` **Interpretation:** Feature mostly done but quality gates failing. Run `/agentful-validate` for details, then `/agentful-start` to auto-fix. #### Scenario 4: Nearly Complete ```bash $ /agentful-status Product: MyApp Progress: ██████████░░░░░░ 90% Phase: Final validation Iterations: 28 Features: ✅ Auth (100%) ✅ Dashboard (100%) ✅ Profile (100%) ✅ Settings (95%) Quality: All gates passing Decisions: None pending Current Work: Finalizing settings UI ``` **Interpretation:** Almost done! One more feature at 95%, quality good. ### Tips #### Quick Progress Checks ```bash # One-liner to see just completion percentage /agentful-status | grep "Progress:" ``` #### Monitoring Active Development ```bash # Watch status update every 30 seconds watch -n 30 "/agentful-status" ``` #### Export Status ```bash # Save status to file for later comparison /agentful-status > status-backup.txt # Or JSON for programmatic use /agentful-status --json > status.json ``` #### Compare Progress Over Time ```bash # Save status snapshots /agentful-status > status-$(date +%Y%m%d-%H%M).txt # Compare later diff status-20260118-1000.txt status-20260118-1200.txt ``` ### Troubleshooting #### Issue: Status shows "No state found" **Cause:** `.agentful/state.json` missing or corrupted **Solution:** ```bash ls -la .agentful/ # If missing, initialize echo '{"version":"1.0","current_task":null}' > .agentful/state.json /agentful-status ``` #### Issue: Feature completion not updating **Cause:** Orchestrator not updating completion.json **Solution:** ```bash # Check completion.json cat .agentful/completion.json # Manually update if needed # Or run /agentful-start to trigger update ``` #### Issue: Quality gates outdated **Cause:** Gates not updated after recent changes **Solution:** ```bash # Force validation update /agentful-validate # Then check status /agentful-status ``` #### Issue: "Currently Working On" seems stuck **Cause:** Task hanging or agent error **Solution:** ```bash # Check how long it's been running /agentful-status # If >30 minutes, might be stuck # Try stopping and restarting /agentful-start ``` ### Advanced Usage #### Custom Status Format ```bash # Show only features /agentful-status --features # Show only quality gates /agentful-status --quality # Show only current work /agentful-status --current ``` #### Integration with Monitoring ```bash #!/bin/bash # monitor-status.sh while true; do STATUS=$(agentful-status) PROGRESS=$(echo "$STATUS" | grep "Progress:" | awk '{print $2}') echo "[$(date)] Progress: $PROGRESS" # Alert if stuck if echo "$STATUS" | grep -q "Blocked"; then echo "⚠️ Development blocked!" # Send notification fi sleep 300 # Check every 5 minutes done ``` #### Progress Tracking Dashboard ```bash # Generate simple HTML dashboard /agentful-status --html > status.html open status.html ``` #### Status History ```bash # Log status over time mkdir -p .agentful/history while true; do /agentful-status > .agentful/history/status-$(date +%s).txt sleep 300 done ``` ### Data Sources The `/agentful-status` command reads from: | File | Purpose | Format | | --------------------------- | --------------------------------- | -------- | | `.agentful/state.json` | Current task, phase, iterations | JSON | | `.agentful/completion.json` | Feature completion %, gate status | JSON | | `.agentful/decisions.json` | Pending decisions | JSON | | `PRODUCT.md` | Product name, feature list | Markdown | ### See Also * [/agentful-start](./agentful-start) - Continue development * [/agentful-decide](./agentful-decide) - Resolve pending decisions * [/agentful-validate](./agentful-validate) - Detailed quality check * [State Files](/core-concepts/state-management) - Understanding state.json structure * [Completion Tracking](/core-concepts/state-management) - How completion is calculated ## /agentful-validate Run all quality checks and validation gates by delegating to the reviewer agent. ### Purpose The `/agentful-validate` command ensures your codebase meets quality standards by running comprehensive checks: 1. **TypeScript Check** - Type safety validation 2. **Lint Check** - Code style and standards 3. **Dead Code Detection** - Find unused code 4. **Test Check** - Verify all tests pass 5. **Coverage Check** - Ensure ≥80% code coverage 6. **Security Check** - Scan for vulnerabilities and secrets This command is essential for maintaining code quality throughout autonomous development. The orchestrator runs it automatically after each feature completion, but you can also run it manually. ### Usage #### Basic Usage ```bash /agentful-validate ``` This runs all validation checks and displays results. #### Quick Mode - Specific Checks ```bash # Type check only (fastest) /agentful-validate --type-check # Test run only /agentful-validate --tests # Security scan only /agentful-validate --security # Lint only /agentful-validate --lint ``` #### After Feature Completion ```bash /agentful-start # [Feature completed] /agentful-validate # → Verify quality before continuing ``` #### Before Commit ```bash /agentful-validate # → If all passing, safe to commit # → If failing, fix issues first ``` #### CI/CD Integration ```yaml # .github/workflows/validate.yml - name: Run agentful validation run: /agentful-validate ``` Exit codes: * `0` - All checks passed * `1` - One or more checks failed * `2` - Unable to run checks (missing deps, etc.) ### Validation Checks #### 1. TypeScript Check **Command:** `npx tsc --noEmit` **What it checks:** * Type errors in TypeScript code * Missing type definitions * Incorrect type usage * Interface compatibility **Example output:** ``` TypeScript ✅ PASS - No type errors ``` **Or:** ``` TypeScript ❌ FAIL - 3 errors found src/auth/login.ts:45:12 - error TS2322: Type 'string' is not assignable to type 'number' src/utils/format.ts:18:5 - error TS7005: Module '"lodash"' has no default export ``` #### 2. Lint Check **Command:** `npm run lint` (or `eslint .`) **What it checks:** * Code style consistency * Best practices violations * Potential bugs * Unused variables **Example output:** ``` Lint ✅ PASS - No lint errors ``` **Or:** ``` Lint ❌ FAIL - 5 issues found src/components/UserProfile.tsx:23:8 - Unused variable 'tempData' src/utils/api.ts:56:15 - Missing semicolon src/hooks/useAuth.ts:12:3 - 'console.log' should be removed ``` #### 3. Dead Code Detection **Command:** Custom analysis of exports, imports, files **What it checks:** * Unused exports in modules * Imported but never used * Entire files that aren't imported * Unused dependencies in package.json **Example output:** ``` Dead Code ✅ PASS - No dead code found ``` **Or:** ``` Dead Code ❌ FAIL - 3 issues found 1. Unused export: formatDate in src/utils/date.ts Exported but never imported 2. Unused file: src/components/OldWidget.tsx Entire file not imported by any module 3. Unused dependency: lodash in package.json Installed but never imported in code ``` #### 4. Test Check **Command:** `npm test` (or `jest`, `vitest`, etc.) **What it checks:** * All tests pass * No test failures * No skipped tests (warning) * Test suite executes successfully **Example output:** ``` Tests ✅ PASS - 47 tests passed ``` **Or:** ``` Tests ❌ FAIL - 3 tests failed FAIL src/auth/login.test.ts ✕ should reject invalid credentials (45ms) ✕ should handle network errors (32ms) FAIL src/utils/format.test.ts ✕ should format dates correctly (18ms) ``` #### 5. Coverage Check **Command:** Coverage from test runner (jest/vitest) **What it checks:** * Line coverage ≥ 80% * Branch coverage ≥ 80% * Function coverage ≥ 80% * Statement coverage ≥ 80% **Example output:** ``` Coverage ✅ PASS - 87% coverage ``` **Or:** ``` Coverage ⚠️ WARN - 72% (needs 80%) Coverage by file: src/auth/login.ts 45% (missing: error handling) src/utils/api.ts 60% (missing: edge cases) src/components/UI.tsx 95% Need 8 more points to reach 80% threshold. ``` #### 6. Security Check **Command:** Security scan for secrets, vulnerabilities, debug logs **What it checks:** * Hardcoded secrets/API keys * Debug console.log statements * Known vulnerable dependencies * Insecure code patterns **Example output:** ``` Security ✅ PASS - No security issues ``` **Or:** ``` Security ⚠️ WARN - 2 issues found 1. console.log in src/auth/login.ts:45 Should be removed for production 2. Potential secret in .env.example:12 API_KEY placeholder looks like real key ``` ### Output Examples #### All Checks Passing ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Validation Results ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TypeScript ✅ PASS - No type errors Lint ✅ PASS - No lint errors Dead Code ✅ PASS - No dead code found Tests ✅ PASS - 47 tests passed Coverage ✅ PASS - 87% coverage Security ✅ PASS - No security issues Overall: ✅ ALL CHECKS PASSED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Quality gates passing. Safe to proceed with deployment. ``` #### Some Checks Failing ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Validation Results ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TypeScript ✅ PASS - No type errors Lint ✅ PASS - No lint errors Dead Code ❌ FAIL - 3 issues found Tests ✅ PASS - 47 tests passed Coverage ⚠️ WARN - 72% (needs 80%) Security ⚠️ WARN - 2 issues found Overall: ❌ FAILED ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Issues that must be fixed: Dead Code (3): 1. Unused export: formatDate in src/utils/date.ts 2. Unused file: src/components/OldWidget.tsx 3. Unused dependency: lodash in package.json Coverage (8 points needed): 4. src/auth/login.ts - 45% (missing: error handling) 5. src/utils/api.ts - 60% (missing: edge cases) Security (2): 6. console.log in src/auth/login.ts:45 7. Potential secret in .env.example:12 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Run /agentful-start to auto-fix these issues. ``` #### Detailed Failure Output ``` ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Validation Results ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ TypeScript ❌ FAIL - 5 errors Error Details: src/auth/login.ts:45:12 error TS2322: Type 'string' is not assignable to type 'number' src/components/UserForm.tsx:23:5 error TS2571: Object is of type 'unknown' src/api/client.ts:18:3 error TS2307: Cannot find module 'missing-package' src/utils/format.ts:56:8 error TS2339: Property 'toLocaleDateString' does not exist on type 'Date | null' src/hooks/useAuth.ts:89:12 error TS2322: Type 'null' is not assignable to type 'User' Lint ⚠️ WARN - 12 warnings Warning Details: src/components/Header.tsx:12:8 warning: 'tempData' is assigned a value but never used src/utils/api.ts:45:15 warning: Missing semicolon ... (10 more warnings) Tests ❌ FAIL - 3 tests failed Failure Details: FAIL src/auth/login.test.ts (52 ms) ✕ should reject invalid credentials (23 ms) Expected: error message Received: null ✕ should handle network errors (18 ms) Timeout: async callback not called FAIL src/utils/format.test.ts (12 ms) ✕ should format dates correctly (8 ms) Expected: "Jan 18, 2026" Received: "2026-01-18" Coverage ⚠️ WARN - 68% (needs 80%) File Coverage: src/auth/login.ts 45% ████████████░░░░░░░░ src/api/client.ts 52% ███████████████░░░░░ src/utils/format.ts 71% ███████████████████░ src/components/UI.tsx 95% ████████████████████ Security ✅ PASS Overall: ❌ FAILED - Critical issues must be fixed ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Run /agentful-start to auto-fix, or fix manually and re-run. ``` ### When to Use #### After Feature Completion ```bash /agentful-start # [Feature implementation completed] /agentful-validate # → Verify quality before moving to next feature ``` **Why:** Ensures each feature meets standards before proceeding. #### Before Committing ```bash git add . /agentful-validate # → If passing, commit # → If failing, fix first git commit -m "feat: new feature" ``` **Why:** Prevents low-quality code from entering repository. #### Before Deployment ```bash /agentful-validate # → Full validation before production npm run deploy ``` **Why:** Catches issues that would break production. #### CI/CD Pipeline ```yaml # .github/workflows/ci.yml on: [push, pull_request] jobs: validate: steps: - uses: actions/checkout@v2 - run: npm install - run: /agentful-validate # Exit code 0 = pass, 1 = fail ``` **Why:** Automated quality gate for all changes. #### After Manual Changes ```bash # You manually edited some files vim src/auth/login.ts # Validate your changes /agentful-validate ``` **Why:** Catches mistakes immediately after manual edits. ### Integration with Development Flow #### Standard Flow ```bash 1. /agentful-start → Implement feature 2. /agentful-validate → Verify quality 3. If passing: → /agentful-start (continue to next feature) 4. If failing: → /agentful-start (auto-fix) → /agentful-validate (verify fixes) ``` #### Quality-Focused Flow ```bash 1. /agentful-start → Implement feature 2. /agentful-validate --type-check → Quick type check 3. /agentful-validate --tests → Quick test run 4. /agentful-validate → Full validation 5. If all passing: → Commit and continue ``` #### Fix-and-Validate Loop ```bash # Validation fails /agentful-validate # Auto-fix issues /agentful-start # Verify fixes /agentful-validate # If still failing, manual fix needed vim src/fix-file.ts # Re-validate /agentful-validate ``` ### Tips #### Fast Validation ```bash # Quick type check during development /agentful-validate --type-check # Fast feedback loop # Takes ~2 seconds vs ~30 seconds for full validation ``` #### Fix Validation Failures ```bash # Let orchestrator auto-fix /agentful-validate # Shows failures /agentful-start # Orchestrator delegates to @fixer ``` #### Track Quality Over Time ```bash # Log validation results /agentful-validate > validation-$(date +%Y%m%d).log # Compare over time diff validation-20260117.log validation-20260118.log ``` #### Coverage Improvement ```bash # See what needs coverage /agentful-validate # Shows files below 80% # Focus testing on those files # Re-run to see improvement /agentful-validate ``` ### Troubleshooting #### Issue: "Cannot run validation - missing dependencies" **Cause:** Test framework not installed **Solution:** ```bash npm install --save-dev jest @types/jest # Or vitest, etc. /agentful-validate ``` #### Issue: TypeScript check fails but code runs fine **Cause:** Type definitions missing or incorrect **Solution:** ```bash # Install missing types npm install --save-dev @types/node @types/react # Or fix type errors manually vim src/file-with-error.ts # Re-validate /agentful-validate ``` #### Issue: Tests pass locally but fail in validation **Cause:** Different test configuration or environment **Solution:** ```bash # Check test command in package.json cat package.json | grep test # Ensure it matches what validation runs npm test # Should match ``` #### Issue: Coverage low but tests all pass **Cause:** Not all code paths tested **Solution:** ```bash # See coverage details npm test -- --coverage # Identify uncovered lines # Add tests for those paths /agentful-validate ``` #### Issue: Dead code false positives **Cause:** Code used in ways analyzer doesn't detect **Solution:** ```bash # Verify code is truly unused grep -r "exportName" src/ # If actually used, ignore warning or update analyzer # If truly unused, remove it rm src/unused-file.ts /agentful-validate ``` ### Advanced Usage #### Custom Validation Thresholds ```json // .agentful/validation-config.json { "coverage": { "threshold": 90, // Higher than default 80% "perFile": true // Require each file to meet threshold }, "security": { "allowDebugLogs": false, "allowConsoleLog": false }, "deadCode": { "ignorePatterns": ["*.test.ts", "*.spec.ts"] } } ``` #### Parallel Validation ```bash # Run checks in parallel for speed /agentful-validate --parallel # Or specific parallel checks /agentful-validate --type-check --tests --parallel ``` #### Validation Report ```bash # Generate detailed HTML report /agentful-validate --report > validation-report.html open validation-report.html ``` #### Watch Mode ```bash # Continuously validate on file changes /agentful-validate --watch # Re-runs validation when files change # Great for active development ``` #### CI/CD Exit Codes ```bash #!/bin/bash # ci-validate.sh /agentful-validate EXIT_CODE=$? if [ $EXIT_CODE -eq 0 ]; then echo "✅ Validation passed" exit 0 elif [ $EXIT_CODE -eq 1 ]; then echo "❌ Validation failed" # Notify team slack-send "Validation failed - PR blocked" exit 1 else echo "⚠️ Validation error (exit code: $EXIT_CODE)" exit 2 fi ``` ### Integration Examples #### Pre-commit Hook ```bash # .git/hooks/pre-commit #!/bin/bash echo "Running pre-commit validation..." /agentful-validate if [ $? -ne 0 ]; then echo "❌ Validation failed. Commit aborted." echo "Run /agentful-start to auto-fix issues." exit 1 fi echo "✅ Validation passed. Proceeding with commit." ``` #### GitHub Actions ```yaml # .github/workflows/validate.yml name: agentful Validation on: [push, pull_request] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 - name: Install dependencies run: npm ci - name: Run validation run: /agentful-validate - name: Upload results if: failure() uses: actions/upload-artifact@v2 with: name: validation-results path: validation-report.html ``` #### Slack Notifications ```bash #!/bin/bash # validate-and-notify.sh /agentful-validate > validation-results.txt 2>&1 EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then # Send failure to Slack curl -X POST $SLACK_WEBHOOK_URL \ -H 'Content-Type: application/json' \ -d "{ \"text\": \"❌ Validation Failed\", \"attachments\": [{ \"text\": \"$(cat validation-results.txt)\" }] }" fi exit $EXIT_CODE ``` #### Quality Metrics Dashboard ```bash #!/bin/bash # collect-metrics.sh # Run validation and extract metrics TYPESCRIPT_RESULT=$(/agentful-validate --type-check --json | jq '.pass') LINT_RESULT=$(/agentful-validate --lint --json | jq '.pass') COVERAGE_RESULT=$(/agentful-validate --coverage --json | jq '.coverage') # Store for dashboard echo "$(date),$TYPESCRIPT_RESULT,$LINT_RESULT,$COVERAGE_RESULT" \ >> .agentful/metrics.csv # Plot with gnuplot or send to Grafana ``` ### Quality Gates Reference #### Default Thresholds | Gate | Threshold | Can Customize? | | ---------- | ---------- | ------------------------------ | | TypeScript | 0 errors | No (must pass) | | Lint | 0 errors | No (must pass) | | Dead Code | 0 issues | No (must pass) | | Tests | 0 failures | No (must pass) | | Coverage | ≥80% | Yes | | Security | 0 critical | Yes (can downgrade to warning) | #### Adjusting Thresholds Edit `.agentful/validation-config.json`: ```json { "gates": { "coverage": { "threshold": 90, "enforce": true }, "security": { "level": "strict", // strict, moderate, lenient "allowConsoleLog": false } } } ``` ### See Also * [/agentful-start](./agentful-start) - Auto-fix validation failures * [/agentful-status](./agentful-status) - Check gate status overview * [Quality Gates](/autonomous-development/quality-gates) - Configuring validation thresholds * [Reviewer Agent](/agents/reviewer) - How validation runs * [CI/CD Integration](/guides/best-practices) - Pipeline examples ## /agentful The **main conversational interface** for agentful. Just talk naturally - no need to remember specific commands or syntax. ### Usage \`\`\`bash /agentful \[your request in plain English] \`\`\` ### Examples ```bash # Start development /agentful "Add user authentication" # Check progress /agentful "How's it going?" # Fix bugs /agentful "The login button isn't working" # Get status /agentful "What's left to build?" # Continue work /agentful "Keep going" ``` ### What It Understands #### Status & Progress * "How's it going?" * "What's the status?" * "What's left?" * "Progress check" * "What are you working on?" #### Feature Development * "Add \[feature]" * "Build \[feature]" * "Create \[feature]" * "Implement \[feature]" Example: "Add user authentication with JWT" #### Bug Fixes * "Fix \[issue]" * "The \[component] is broken" * "\[feature] isn't working" Example: "Fix the login redirect bug" #### Questions * "What are we building?" * "How does \[feature] work?" * "Tech stack?" * "Architecture?" #### Actions * "Continue" - Resume development * "Stop" - Pause development * "Run tests" - Execute validation ### How It Works 1. **Understands Intent** - Classifies what you want (status, feature, bugfix, etc.) 2. **Checks Context** - Reads product spec, state, and conversation history 3. **Routes to Specialist** - Delegates to appropriate agent (orchestrator, tester, etc.) 4. **Provides Updates** - Shows progress and asks questions when needed ### Example Conversations #### Feature Development ```bash You: /agentful "Add user profiles" Agent: Got it! Starting user profiles development... [Analyzing project structure...] [Delegating to architect agent...] Agent: User profiles feature plan created: • User profile data model • Profile CRUD API • Profile settings page Starting implementation... ``` #### Status Check ```bash You: /agentful "How's it going?" Agent: Overall Progress: ████████████░░░░ 45% Features: ✅ Authentication Backend 100% 🔄 Authentication Frontend 45% ⏸ User Profiles 0% Currently working on: Login page component Want to continue or check something else? ``` #### Bug Fix ```bash You: /agentful "The login button is broken" Agent: Investigating login button issue... [Analyzing LoginForm component...] Found: Missing onClick handler Fixing now... Agent: Fixed! Login button now triggers authentication. Tests passing. ✅ ``` ### Integration with Commands `/agentful` automatically routes to specialized commands: | Your Input | Routes To | | ----------------------- | -------------------- | | "How's it going?" | `/agentful-status` | | "Continue working" | `/agentful-start` | | "What needs decisions?" | `/agentful-decide` | | "Run tests" | `/agentful-validate` | | "Add \[feature]" | Orchestrator agent | ### Conversation History agentful remembers your conversation: * Last 100 messages * Context across sessions * Your preferences and project knowledge ### Tips * **Be specific** for features: "Add OAuth login with GitHub" * **Describe bugs** clearly: "Login redirects to wrong page after auth" * **Use natural language** - no need for technical jargon * **Ask questions** - agentful knows your project inside and out ### Related Commands * [`/agentful-start`](./agentful-start.mdx) - Start autonomous development * [`/agentful-status`](./agentful-status.mdx) - Check detailed progress * [`/agentful-decide`](./agentful-decide.mdx) - Answer pending decisions * [`/agentful-validate`](./agentful-validate.mdx) - Run quality checks ## agentful Commands Reference Complete reference guide for all agentful slash commands used in autonomous product development. ### Overview agentful provides a set of slash commands that automate the product development lifecycle. These commands work together to create an autonomous development loop that can build features, validate quality, and resolve decisions with minimal human intervention. ### Command Categories #### Core Development Commands * **[/agentful-start](./agentful-start)** - Start or resume autonomous product development * **[/agentful-status](./agentful-status)** - View current progress and state * **[/agentful-decide](./agentful-decide)** - Resolve pending decisions blocking progress * **[/agentful-validate](./agentful-validate)** - Run quality checks and validation gates ### Quick Start #### Basic Workflow The typical development workflow follows this sequence: ``` 1. /agentful-start → Begin autonomous development 2. /agentful-status → Check progress 3. /agentful-decide → Answer blocking decisions (if needed) 4. /agentful-validate → Verify quality (optional) 5. /agentful-start → Continue development ``` #### First Time Setup Before using agentful commands, ensure you have: 1. **PRODUCT.md** - Product requirements document 2. **.agentful/** directory - State management 3. **Git repository** - Version control ```bash # Initialize agentful mkdir -p .agentful echo '{}' > .agentful/state.json echo '{}' > .agentful/completion.json echo '{"pending":[],"resolved":[]}' > .agentful/decisions.json ``` ### Command Reference #### /agentful-start **Purpose:** Initiates the autonomous development loop **When to use:** * Starting a new product development session * Resuming development after a break * Continuing after resolving decisions * Running autonomous development cycles **Key features:** * Reads product state and picks next task * Delegates work to specialist agents * Validates completion before moving on * Updates completion tracking **See:** [Complete /agentful-start reference](./agentful-start) *** #### /agentful-status **Purpose:** Shows current progress and development state **When to use:** * Checking what's been completed * Seeing what's currently in progress * Identifying blocking issues * Getting an overview before making decisions **Key features:** * Visual progress display with percentages * Feature status table (Done/Active/Pending) * Quality gate status * Pending decisions overview * Current work context **See:** [Complete /agentful-status reference](./agentful-status) *** #### /agentful-decide **Purpose:** Resolves pending decisions blocking development **When to use:** * /agentful-start reports pending decisions * You need to make architectural choices * Blocking issues need resolution * Setting product direction **Key features:** * Interactive decision interface * Presents options with context * Records decisions for traceability * Unblocks features automatically **See:** [Complete /agentful-decide reference](./agentful-decide) *** #### /agentful-validate **Purpose:** Runs quality checks and validation gates **When to use:** * Before committing code * After completing features * Verifying quality standards * CI/CD integration **Key features:** * TypeScript type checking * Lint validation * Dead code detection * Test execution * Coverage reporting * Security scanning **See:** [Complete /agentful-validate reference](./agentful-validate) *** ### Common Workflows #### Workflow 1: Initial Development Session ```bash # Start building your product /agentful-start # Check progress after some time /agentful-status # If blocked by decisions /agentful-decide # Continue development /agentful-start ``` #### Workflow 2: Quality-Focused Development ```bash # Run development /agentful-start # Validate quality before proceeding /agentful-validate # If validation fails, run again to auto-fix /agentful-start # Verify fixes /agentful-validate ``` #### Workflow 3: Autonomous Loop (Advanced) For continuous autonomous development: ```bash /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` This runs the development loop continuously until: * All features complete (100%) * All quality gates passing * Maximum iterations reached #### Workflow 4: Decision-Heavy Session ```bash # Start development /agentful-start # If blocked, review all pending decisions /agentful-decide # Resolve multiple decisions in sequence # (Interactive mode walks through each) # Resume with clear path /agentful-start # Verify unblocked progress /agentful-status ``` ### Command Output Reference #### Status Indicators | Symbol | Meaning | | ------ | ----------------- | | ✅ | Completed/Passing | | 🔄 | In Progress | | ⏸ | Pending/Blocked | | ⚠️ | Warning | | ❌ | Failed/Error | #### Progress Bars ``` Overall Progress: ████░░░░░░░░░░ 48% 10% 50% 100% ``` * Solid blocks (█) = completed * Empty blocks (░) = remaining #### Quality Gates ``` ┌─────────────────────┬────────┐ │ Quality Gate │ Status │ ├─────────────────────┼────────┤ │ Tests Passing │ ✅ │ │ No Type Errors │ ✅ │ │ No Dead Code │ ❌ │ │ Coverage ≥ 80% │ ⚠️ 72% │ └─────────────────────┴────────┘ ``` ### Tips and Best Practices #### Development Tips 1. **Start with /agentful-status** - Always check current state before starting work 2. **Resolve decisions promptly** - Pending decisions block progress immediately 3. **Run validation regularly** - Catch quality issues early 4. **Monitor iterations** - High iteration counts may indicate problems #### Productivity Tips 1. **Use autonomous mode for long sessions** - Let the loop run while you focus on other tasks 2. **Check status between iterations** - Stay informed without interrupting flow 3. **Keep PRODUCT.md updated** - Better requirements = better autonomous development 4. **Review decisions log** - Learn from previous architectural choices #### Troubleshooting ##### Development Stuck? ```bash # Check what's happening /agentful-status # Look for pending decisions # If present, resolve them /agentful-decide ``` ##### Quality Gates Failing? ```bash # Run detailed validation /agentful-validate # Review specific failures # Run /agentful-start to auto-fix ``` ##### Can't Start Development? ```bash # Verify required files exist ls -la PRODUCT.md .agentful/ # Initialize if missing mkdir -p .agentful echo '{"version":"1.0","current_task":null}' > .agentful/state.json ``` ### Advanced Usage #### Integration with CI/CD ```yaml # .github/workflows/agentful.yml name: agentful Validation on: [push, pull_request] jobs: validate: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run agentful validation run: | npm install /agentful-validate ``` #### Custom Decision Templates Create reusable decision patterns: ```json // .agentful/decision-templates.json { "templates": [ { "name": "auth-strategy", "question": "Authentication approach?", "options": ["JWT", "Sessions", "OAuth", "Custom"] } ] } ``` #### Progress Tracking Integration ```bash # Sync with external project management /agentful-status | jq '.features' > project-status.json ``` ### See Also * [Installation Guide](/getting-started/installation) - Setting up agentful * [Product Spec Guide](/guides/writing-product-md) - Writing PRODUCT.md * [Agent Configuration](/agents) - Understanding specialist agents * [Quality Gates](/autonomous-development/quality-gates) - Configuring validation thresholds * [Troubleshooting](/guides/troubleshooting) - Common issues and solutions ## 24/7 Development with Ralph Wiggum Ralph Wiggum is a Claude Code plugin that enables continuous looping - perfect for autonomous development that runs while you sleep. This guide explains how to use Ralph Wiggum with agentful for true 24/7 productivity. ### What is Ralph Wiggum? Ralph Wiggum is a Claude Code plugin that: * Executes commands in a continuous loop * Stops only when completion promise is emitted * Tracks iteration count to prevent infinite loops * Handles errors gracefully and continues * Provides detailed logging of each iteration ### Installation Install Ralph Wiggum plugin: ```bash /plugin install ralph-wiggum@anthropics ``` Verify installation: ```bash /plugin list ``` ### Basic Usage #### Starting a 24/7 Loop ```bash /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` **Parameters explained**: * `/agentful-start` - Command to loop (agentful's autonomous mode) * `--max-iterations 50` - Maximum loops before stopping (safety limit) * `--completion-promise "AGENTFUL_COMPLETE"` - Stop when orchestrator emits this #### How It Works 1. **Start Loop** - Ralph executes `/agentful-start` 2. **Orchestrator Runs** - Plans work, delegates to agents 3. **Work Completes** - Agents build features 4. **Validation Runs** - Quality gates checked 5. **Issues Fixed** - Fixer resolves problems 6. **Progress Updated** - State files updated 7. **Check Promise** - If `AGENTFUL_COMPLETE` emitted, stop 8. **Otherwise Loop** - Continue from step 2 9. **Iteration Count** - Stop at max-iterations if not complete ### Orchestrator Integration The orchestrator agent outputs the completion promise when truly done: ```javascript // In orchestrator logic if (completion.overall === 100 && allGatesPass()) { console.log("AGENTFUL_COMPLETE"); } ``` Until then, Ralph keeps looping. ### Loop Configuration #### Iteration Limits Choose based on project size: ```bash # Small project (1-3 features) /ralph-loop "/agentful-start" --max-iterations 20 # Medium project (4-10 features) /ralph-loop "/agentful-start" --max-iterations 50 # Large project (10+ features) /ralph-loop "/agentful-start" --max-iterations 100 # Weekend warrior (let it run all weekend) /ralph-loop "/agentful-start" --max-iterations 200 ``` #### Time Estimates Approximate iterations per hour: 5-10 (depending on feature complexity and validation time) ```bash # Overnight (8 hours) = 40-80 iterations /ralph-loop "/agentful-start" --max-iterations 80 # Weekend (48 hours) = 240-480 iterations /ralph-loop "/agentful-start" --max-iterations 400 ``` #### Safety Limits Always set max-iterations, even for large projects: ```bash # Good: Has safety limit /ralph-loop "/agentful-start" --max-iterations 100 # Bad: Could run forever if bugs occur /ralph-loop "/agentful-start" # No limit! ``` ### Real-World Examples #### Example 1: Overnight Feature Build ```bash # Friday evening setup /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" # Wake up Saturday morning to: # - 3-5 features implemented # - All tests passing # - 80%+ coverage # - Ready for review ``` #### Example 2: Weekend Sprint ```bash # Friday night /ralph-loop "/agentful-start" --max-iterations 200 --completion-promise "AGENTFUL_COMPLETE" # Monday morning: # - Full MVP complete # - All features tested # - Quality gates passing # - Production ready ``` #### Example 3: Bug Fix Marathon ```bash # Create PRODUCT.md focused on bugs cat > PRODUCT.md << EOF ## Bug Sprint Fix all critical and high priority bugs from GitHub Issues. Critical: - [ ] Authentication timeout on slow networks - [ ] Database connection leaks - [ ] Memory leak in WebSocket handler High: - [ ] UI freeze on large datasets - [ ] File upload failures EOF # Start loop /ralph-loop "/agentful-start" --max-iterations 30 # Check back in a few hours - all bugs fixed and tested ``` ### Monitoring Ralph Loops #### Check Progress While Ralph is running, open a new terminal: ```bash # Check what agentful is working on cd /path/to/project claude /agentful-status # Exit without stopping Ralph # Ralph continues in original terminal ``` #### View Iteration Count Ralph displays current iteration: ``` [Iteration 12/50] Running: /agentful-start [Iteration 13/50] Running: /agentful-start ... ``` #### Check Git History Each validated feature is committed: ```bash # See what's been built git log --oneline --graph -20 # Example output: # * abc1234 feat: Implement user authentication # * def5678 test: Add auth service tests (95% coverage) # * ghi9012 fix: Remove dead code from auth module ``` #### Review Quality Gates ```bash # Check completion status cat .agentful/completion.json # Check last validation report cat .agentful/last-review.json ``` ### Decision Handling During Loops #### When Decisions Are Needed agentful encounters a decision: 1. **Creates decision** in `decisions.json` 2. **Moves to non-blocked work** (continues autonomously) 3. **Waits for you** to answer #### How to Answer Without Stopping Ralph **Option 1: Quick Answer** ```bash # In new terminal claude /agentful-decide # Select option # Exit - Ralph continues running ``` **Option 2: Edit Direct** ```bash # Edit decisions.json vim .agentful/decisions.json # Move decision from "pending" to "resolved" # Ralph will pick up on next loop ``` #### Example Decision Flow ```javascript // .agentful/decisions.json (during loop) { "pending": [ { "id": "auth-decision-001", "question": "Use JWT or sessions?", "blocking": ["authentication-feature"] } ] } // agentful continues with other features (dashboard, user-profile) // You answer when convenient // Next loop picks up auth again ``` ### Error Handling #### Ralph Handles Errors Gracefully If an iteration fails: 1. Logs error with iteration number 2. Continues to next iteration 3. No progress lost (previous commits intact) ```bash [Iteration 15/50] Running: /agentful-start Error: Network timeout [Iteration 16/50] Running: /agentful-start # Continues... ``` #### Common Errors **1. API Timeouts** * Cause: External service slow/down * Solution: Ralph retries next iteration **2. Test Failures** * Cause: Bug introduced * Solution: Fixer agent fixes automatically **3. Decision Blocks** * Cause: Needs user input * Solution: agentful works on other features **4. Git Conflicts** * Cause: Manual edits during loop * Solution: Stop Ralph, resolve, restart ### Stopping Ralph Loops #### Graceful Stop Press `Ctrl+C` in Ralph's terminal. Ralph finishes current iteration then stops: ``` [Iteration 27/50] Running: /agentful-start ^C Gracefully stopping... Iteration complete. Stopped at iteration 27/50. ``` #### Completion Promise Ralph stops automatically when promise emitted: ``` [Iteration 42/50] Running: /agentful-start AGENTFUL_COMPLETE Completion promise detected. Stopping. Final iteration: 42/50 Total time: 4h 23m ``` #### Restarting After Stop All progress saved in state files. Simply restart: ```bash /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` agentful resumes from where it left off. ### Best Practices #### 1. Test Before 24/7 ```bash # First run manually /agentful-start # Let it complete 2-3 features # Check code quality # Verify style matches expectations # Then enable Ralph /ralph-loop "/agentful-start" --max-iterations 50 ``` #### 2. Start with Conservative Limits ```bash # First time: small limit /ralph-loop "/agentful-start" --max-iterations 10 # Monitor, then increase /ralph-loop "/agentful-start" --max-iterations 50 ``` #### 3. Monitor First Few Loops ```bash # Watch first 3-5 iterations # Ensure decisions handled correctly # Check quality gates passing # Then leave it alone ``` #### 4. Use Screen/Tmux for Long Runs ```bash # Start in screen session screen -S agentful # Start Ralph /ralph-loop "/agentful-start" --max-iterations 100 # Detach: Ctrl+A, D # Reattach: screen -r agentful # survives SSH disconnects ``` #### 5. Commit Before Starting ```bash # Ensure clean state git add . git commit -m "Before Ralph loop" # Start Ralph /ralph-loop "/agentful-start" --max-iterations 50 ``` #### 6. Set Up Notifications (Optional) ```bash # Simple completion notification /ralph-loop "/agentful-start" \ --max-iterations 50 \ --completion-promise "AGENTFUL_COMPLETE" \ && osascript -e 'display notification "agentful complete!"' ``` ### Advanced Patterns #### Parallel Development Run multiple Ralph loops on separate branches: ```bash # Terminal 1: Feature branch A git checkout feature-a /ralph-loop "/agentful-start" --max-iterations 30 # Terminal 2: Feature branch B git checkout feature-b /ralph-loop "/agentful-start" --max-iterations 30 ``` #### Staged Development Build in phases: ```bash # Phase 1: Core features cat > PRODUCT.md << EOF ## Phase 1 - Core - Authentication - User profile - Database setup EOF /ralph-loop "/agentful-start" --max-iterations 30 # After complete, update PRODUCT.md for Phase 2 ``` #### Bug-Only Mode Create focused PRODUCT.md for bugs: ```bash cat > PRODUCT.md << EOF ## Bug Sprint Critical priority only. EOF /ralph-loop "/agentful-start" --max-iterations 20 ``` ### Troubleshooting Ralph #### Ralph Not Starting **Check plugin installed**: ```bash /plugin list | grep ralph ``` **Reinstall if needed**: ```bash /plugin install ralph-wiggum@anthropics --force ``` #### Loop Stops Prematurely **Check for errors**: ```bash # View Ralph's log # Usually in terminal output ``` **Common causes**: * agentful crashed (check PRODUCT.md valid) * Decision blocks everything (run `/agentful-decide`) * Max iterations too low (increase limit) #### Infinite Loop Without Progress **Check state files**: ```bash cat .agentful/state.json cat .agentful/completion.json ``` **If iteration count increasing but completion not**: 1. Stop Ralph (Ctrl+C) 2. Review `.agentful/last-review.json` 3. Fix blocking issues manually 4. Restart Ralph ### Production Considerations #### For Team Development ```bash # Use feature branches git checkout -k feature/autonomous-build # Run Ralph /ralph-loop "/agentful-start" --max-iterations 50 # Create PR when complete gh pr create --title "Autonomous build: Feature X" ``` #### For Critical Projects ```bash # Lower iteration limit /ralph-loop "/agentful-start" --max-iterations 20 # Monitor more frequently # Check every 2-3 hours ``` #### For Prototypes/MVPs ```bash # High iteration limit /ralph-loop "/agentful-start" --max-iterations 200 # Let it run all weekend # Check Monday morning ``` ### Next Steps * [Autonomous Development Overview](./index.mdx) - Back to overview * [Quality Gates](./quality-gates.mdx) - What gates must pass * [Monitoring](./monitoring.mdx) - Track progress effectively ## Autonomous Development agentful's autonomous development mode enables Claude Code to work independently, building your product 24/7 with minimal human intervention. This comprehensive guide explains how autonomous development works and how to use it safely. ### Overview Autonomous development in agentful follows a continuous cycle: 1. **Read State** - Check progress and what's left to build 2. **Select Work** - Choose next feature/task based on priority 3. **Delegate** - Assign to specialist agent (backend, frontend, tester) 4. **Validate** - Reviewer agent checks code quality 5. **Fix** - Fixer agent resolves any issues 6. **Update Progress** - Mark work as complete 7. **Repeat** - Loop until 100% complete ```mermaid graph TD A[Read State] --> B[Select Work] B --> C[Delegate to Agent] C --> D[Implement Feature] D --> E[Run Quality Checks] E --> F{All Pass?} F -->|Yes| G[Update Progress] F -->|No| H[Auto-Fix Issues] H --> E G --> I{100% Complete?} I -->|No| A I -->|Yes| J[Done!] ``` ### Key Components #### Orchestrator Agent The orchestrator is the brain of autonomous development: * **Never writes code** - only coordinates and delegates * **Reads state files** - understands current progress * **Selects work** - prioritizes features intelligently * **Handles decisions** - blocks when user input needed * **Tracks progress** - updates completion metrics Located in: `.claude/agents/orchestrator.md` #### Quality Gates All code must pass 6 quality gates before completion: 1. **Tests Passing** - All tests must pass 2. **TypeScript Clean** - No type errors 3. **Lint Clean** - No lint errors 4. **Dead Code Removed** - No unused exports, files, or dependencies 5. **Coverage ≥ 80%** - Test coverage threshold 6. **Security Clean** - No vulnerabilities, secrets, or debug logs #### Specialist Agents Autonomous development delegates to specialized agents: * **@backend** - Services, repositories, controllers, APIs * **@frontend** - Components, pages, hooks, styling * **@tester** - Unit, integration, and E2E tests * **@reviewer** - Code quality validation * **@fixer** - Automatic issue resolution ### State Management agentful tracks state in `.agentful/` directory: #### state.json Current work state and context: ```json { "version": "1.0", "current_task": "Implement user authentication", "current_phase": "implementing", "iterations": 12, "last_updated": "2026-01-18T00:00:00Z", "blocked_on": ["auth-decision-001"] } ``` #### completion.json Progress tracking for features and gates: ```json { "features": { "authentication": { "status": "complete", "score": 100, "completed_at": "2026-01-18T01:00:00Z" }, "user-profile": { "status": "in_progress", "score": 45, "notes": "Backend done, frontend pending" } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": false, "coverage_80": false, "security_clean": true }, "overall": 48 } ``` #### decisions.json Pending and resolved user decisions: ```json { "pending": [ { "id": "auth-decision-001", "question": "Should auth use JWT or session cookies?", "options": ["JWT (stateless, scalable)", "Sessions (simpler)"], "blocking": ["authentication"], "timestamp": "2026-01-18T00:00:00Z" } ], "resolved": [] } ``` ### Work Selection Priority The orchestrator selects work in this order: 1. **Critical failures** - Broken tests, type errors, blocked work 2. **Unblock work** - Features waiting on single small decision 3. **High priority features** - As defined in PRODUCT.md 4. **Medium priority features** 5. **Tests for completed features** 6. **Polish/Optimization** - Only when everything else done ### Decision Handling When agentful needs your input: 1. **Stops work** on blocked features 2. **Creates decision** in `decisions.json` 3. **Moves on** to non-blocked work 4. **Notifies you** to run `/agentful-decide` You respond by running: ``` /agentful-decide ``` Then choose from the provided options. agentful continues automatically. ### Completion Criteria Autonomous development completes when: * All features have `status: "complete"` * All quality gates are `true` * Overall completion is 100% * No pending decisions ### Running Autonomous Mode #### Manual Mode Start autonomous development: ``` /agentful-start ``` Check progress anytime: ``` /agentful-status ``` #### 24/7 Mode (Ralph Wiggum) For continuous overnight development: ```bash /ralph-loop "/agentful-start" --max-iterations 50 --completion-promise "AGENTFUL_COMPLETE" ``` Ralph will loop until: * All features complete (100%) * All quality gates pass * Max iterations reached See [24/7 Development](./24-7-development.mdx) for details. ### Monitoring Progress Monitor autonomous development through: 1. **State files** - Check `.agentful/completion.json` 2. **Status command** - Run `/agentful-status` anytime 3. **Git commits** - Each validated feature is committed 4. **Review reports** - Check `.agentful/last-review.json` ### Safety Features #### Validation Gates Every change must pass all quality gates before progressing. This ensures: * No broken code enters codebase * No type errors accumulate * No dead code remains * Coverage is maintained * Security issues caught early #### Automatic Recovery The fixer agent automatically resolves: * Dead code (unused exports, files, dependencies) * Test coverage gaps (adds tests to reach 80%) * Code quality issues (console.log, TODO comments) * Type errors and lint failures #### Decision Blocking agentful stops and asks when: * Multiple valid approaches exist * User preferences needed (UI design, naming) * External dependencies required * Trade-offs need evaluation ### Best Practices #### 1. Start with Clear PRODUCT.md The more detailed your product spec, the less agentful needs to ask: ```markdown ## Authentication - CRITICAL **Approach**: JWT with httpOnly cookies **Storage**: PostgreSQL with Prisma **Validation**: Zod schemas **Testing**: Vitest + Playwright **Acceptance Criteria**: - [ ] User registration with email/password - [ ] Email verification required - [ ] Password reset via email - [ ] Session management ``` #### 2. Run Manual First Before 24/7 mode: 1. Run `/agentful-start` manually 2. Monitor first few iterations 3. Check quality gates passing 4. Verify code style matches expectations 5. Then enable Ralph loop #### 3. Monitor Early Runs Check in regularly: ```bash # Every hour or so /agentful-status # Review recent changes git log --oneline -10 # Check quality gates cat .agentful/completion.json ``` #### 4. Handle Decisions Promptly Unanswered decisions block progress. When notified: 1. Run `/agentful-decide` 2. Review options 3. Make selection 4. agentful continues #### 5. Set Iteration Limits For Ralph loops, always set `--max-iterations`: ```bash # Safe: 50 iterations = overnight /ralph-loop "/agentful-start" --max-iterations 50 # Longer: weekend development /ralph-loop "/agentful-start" --max-iterations 200 ``` ### Troubleshooting #### agentful Not Starting **Check**: 1. PRODUCT.md exists and is valid 2. `.agentful/` directory exists 3. State files are valid JSON **Fix**: ```bash # Reinitialize npx @itz4blitz/agentful init ``` #### Quality Gates Failing Repeatedly **Check**: 1. `.agentful/last-review.json` for specific issues 2. If fixer can't resolve, may need manual intervention **Fix**: ```bash # Run validation manually /agentful-validate # Review specific issues cat .agentful/last-review.json ``` #### Loop Not Progressing **Check**: 1. `.agentful/decisions.json` for pending decisions 2. `.agentful/state.json` for blockers **Fix**: ```bash # Answer pending decisions /agentful-decide ``` ### Next Steps * [24/7 Development](./24-7-development.mdx) - Ralph Wiggum integration * [Quality Gates](./quality-gates.mdx) - Detailed gate explanations * [Recovery Strategies](./recovery-strategies.mdx) - Self-healing mechanisms * [Monitoring](./monitoring.mdx) - Progress tracking strategies ## Monitoring Effective monitoring is crucial for autonomous development. This guide explains how to track progress, understand what agentful is building, and ensure quality throughout the development process. ### Overview agentful provides multiple monitoring layers: 1. **Real-time Status** - Current work and progress 2. **State Files** - Detailed progress tracking 3. **Quality Reports** - Validation results 4. **Git History** - Commits and changes 5. **Custom Dashboards** - Build your own monitoring ### Quick Status Check #### agentful Status Command ```bash /agentful-status ``` **Output**: ``` === agentful Status === Current Task: Implementing user authentication Current Phase: implementing Iteration: 12 of ~50 estimated Overall Progress: 35% ├── Authentication: 100% ✓ ├── User Profile: 60% (backend done, frontend pending) └── Dashboard: 0% Quality Gates: ├── Tests: Passing ✓ ├── TypeScript: Clean ✓ ├── Lint: Clean ✓ ├── Dead Code: 3 issues ├── Coverage: 72% (target: 80%) └── Security: Clean ✓ Pending Decisions: 1 - [auth-decision-001] Should passwords include special characters? Recent Commits: • abc1234 feat: Implement user registration • def5678 test: Add auth service tests • ghi9012 fix: Remove unused imports ``` ### State File Monitoring #### completion.json Track overall progress: ```bash # View completion status cat .agentful/completion.json # Pretty print cat .agentful/completion.json | jq '.' # Check overall progress cat .agentful/completion.json | jq '.overall' # Check gate status cat .agentful/completion.json | jq '.gates' # Check feature status cat .agentful/completion.json | jq '.features' ``` **Example Output**: ```json { "features": { "authentication": { "status": "complete", "score": 100, "completed_at": "2026-01-18T01:00:00Z" }, "user-profile": { "status": "in_progress", "score": 60, "notes": "Backend complete, frontend in progress" }, "dashboard": { "status": "pending", "score": 0 } }, "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": false, "coverage_80": false, "security_clean": true }, "overall": 53, "last_updated": "2026-01-18T02:30:00Z" } ``` #### state.json Monitor current work: ```bash # Current task cat .agentful/state.json | jq '.current_task' # Current phase cat .agentful/state.json | jq '.current_phase' # Iteration count cat .agentful/state.json | jq '.iterations' # Blockers cat .agentful/state.json | jq '.blocked_on' ``` **Example Output**: ```json { "version": "1.0", "current_task": "Implementing user profile page", "current_phase": "implementing", "iterations": 15, "last_updated": "2026-01-18T02:30:00Z", "blocked_on": ["ui-decision-002"] } ``` #### decisions.json Track pending decisions: ```bash # Count pending decisions cat .agentful/decisions.json | jq '.pending | length' # View pending questions cat .agentful/decisions.json | jq '.pending[] | .question' # View what's blocked cat .agentful/decisions.json | jq '.pending[] | .blocking' ``` **Example Output**: ```json { "pending": [ { "id": "ui-decision-002", "question": "Which component library should we use?", "options": [ "Material-UI (MUI)", "Chakra UI", "Tailwind UI", "Custom components" ], "blocking": ["user-profile", "dashboard"], "timestamp": "2026-01-18T02:00:00Z" } ], "resolved": [ { "id": "auth-decision-001", "question": "JWT or sessions?", "answer": "JWT with httpOnly cookies", "resolved_at": "2026-01-18T01:00:00Z" } ] } ``` ### Quality Monitoring #### Validation Reports ```bash # Latest review cat .agentful/last-review.json # Check if passed cat .agentful/last-review.json | jq '.passed' # View failed checks cat .agentful/last-review.json | jq '.checks | to_entries[] | select(.value.passed == false)' # View must-fix items cat .agentful/last-review.json | jq '.mustFix[]' # View can-ignore items cat .agentful/last-review.json | jq '.canIgnore[]' ``` **Example Output**: ```json { "passed": false, "timestamp": "2026-01-18T02:30:00Z", "checks": { "typescript": { "passed": true, "summary": "No type errors" }, "lint": { "passed": true, "summary": "No lint errors" }, "deadCode": { "passed": false, "issues": [ "Unused export: formatDate in src/utils/date.ts", "Unused file: src/components/OldWidget.tsx" ] }, "tests": { "passed": true, "summary": "52 tests passed" }, "coverage": { "passed": false, "actual": 72, "required": 80, "summary": "8 percentage points below threshold" }, "security": { "passed": true, "summary": "No security issues" } }, "mustFix": [ "Remove unused export: formatDate in src/utils/date.ts", "Delete unused file: src/components/OldWidget.tsx", "Add tests to reach 80% coverage (currently at 72%)" ], "canIgnore": [] } ``` #### Fix Reports ```bash # What was fixed cat .agentful/last-fix.json | jq '.fixed[]' # What remains cat .agentful/last-fix.json | jq '.remaining[]' # What's blocked cat .agentful/last-fix.json | jq '.blocked[]' ``` **Example Output**: ```json { "timestamp": "2026-01-18T02:35:00Z", "fixed": [ "Removed unused export: formatDate in src/utils/date.ts", "Deleted unused file: src/components/OldWidget.tsx", "Added tests for string utility functions" ], "remaining": [ "Coverage at 76% (need 4 more percentage points)" ], "blocked": [] } ``` ### Git-Based Monitoring #### Commit History ```bash # View recent commits git log --oneline -20 # View by agent git log --author="orchestrator" --oneline git log --author="backend" --oneline git log --author="frontend" --oneline git log --author="fixer" --oneline # View commits since agentful started git log --since="1 hour ago" --oneline # View commit with diff git log -1 --stat ``` **Example Output**: ``` abc1234 feat: Implement user profile page def5678 test: Add profile service tests (92% coverage) ghi9012 fix: Remove unused imports from profile component jkl2345 refactor: Extract profile validation logic mno6789 feat: Implement user profile backend API pqr3456 test: Add API integration tests ``` #### Branch Tracking ```bash # Current branch git branch --show-current # List all branches git branch -a # Compare to main git log main..HEAD --oneline ``` #### Change Statistics ```bash # Lines changed by agent git log --author="backend" --since="1 day ago" --pretty=tformat: --numstat | \ awk '{add+=$1; del+=$2} END {print "Added:", add, "Deleted:", del}' # Files changed git diff --name-only HEAD~10 HEAD # Diff by feature git log --grep="authentication" --oneline ``` ### Real-Time Monitoring #### Watch Mode Monitor state files in real-time: ```bash # Watch completion progress watch -n 5 'cat .agentful/completion.json | jq .overall' # Watch current task watch -n 5 'cat .agentful/state.json | jq .current_task' # Watch quality gates watch -n 5 'cat .agentful/completion.json | jq .gates' ``` #### Tail Logs ```bash # If using logging tail -f .agentful/agentful.log # View last 100 lines tail -n 100 .agentful/agentful.log # Search for errors grep -i "error" .agentful/agentful.log ``` ### Progress Visualization #### Terminal Dashboard Create a monitoring script: ```bash #!/bin/bash # monitor.sh while true; do clear echo "=== agentful Monitor ===" echo "" echo "Progress: $(cat .agentful/completion.json | jq .overall)%" echo "Current: $(cat .agentful/state.json | jq .current_task)" echo "Phase: $(cat .agentful/state.json | jq .current_phase)" echo "Iteration: $(cat .agentful/state.json | jq .iterations)" echo "" echo "Quality Gates:" cat .agentful/completion.json | jq -r '.gates | to_entries[] | " \(.key): \(.value)"' echo "" echo "Pending Decisions: $(cat .agentful/decisions.json | jq '.pending | length')" echo "" echo "Recent Commits:" git log --oneline -5 echo "" sleep 5 done ``` Run with: ```bash chmod +x monitor.sh ./monitor.sh ``` #### ASCII Progress Bars ```bash #!/bin/bash # progress-bar.sh OVERALL=$(cat .agentful/completion.json | jq .overall) FILLED=$((OVERALL / 2)) EMPTY=$((50 - FILLED)) BAR="[" for ((i=0; i&1 | grep "error TS" | wc -l) echo "Type Errors: $TSC_ERRORS" # Lint errors LINT_ERRORS=$(npm run lint 2>&1 | grep "error" | wc -l) echo "Lint Errors: $LINT_ERRORS" # Test results TEST_RESULTS=$(npm test 2>&1 | grep -E "passing|failing") echo "$TEST_RESULTS" # Coverage COVERAGE=$(npm test -- --coverage --reporter=json 2>&1 | \ jq -r '.total.lines.pct // "N/A"') echo "Coverage: ${COVERAGE}%" # Dead code DEAD_CODE=$(npx knip --reporter json 2>/dev/null | \ jq '[.. | .issues? // empty] | add | length') echo "Dead Code Issues: $DEAD_CODE" ``` ### Alerting #### Notify on Completion ```bash #!/bin/bash # wait-for-complete.sh while true; do COMPLETE=$(cat .agentful/completion.json | jq '.overall == 100') if [ "$COMPLETE" = "true" ]; then echo "agentful development complete!" osascript -e 'display notification "agentful development complete!" with title "agentful"' break fi sleep 30 done ``` #### Notify on Failures ```bash #!/bin/bash # watch-failures.sh LAST_CHECK=$(cat .agentful/last-review.json | jq '.passed') while true; do CURRENT_CHECK=$(cat .agentful/last-review.json | jq '.passed') if [ "$LAST_CHECK" = "true" ] && [ "$CURRENT_CHECK" = "false" ]; then echo "Quality check failed!" osascript -e 'display notification "Quality check failed" with title "agentful"' fi LAST_CHECK=$CURRENT_CHECK sleep 30 done ``` #### Notify on Decisions ```bash #!/bin/bash # watch-decisions.sh LAST_COUNT=$(cat .agentful/decisions.json | jq '.pending | length') while true; do CURRENT_COUNT=$(cat .agentful/decisions.json | jq '.pending | length') if [ "$CURRENT_COUNT" -gt "$LAST_COUNT" ]; then echo "New decision pending!" osascript -e 'display notification "Decision needed" with title "agentful"' fi LAST_COUNT=$CURRENT_COUNT sleep 30 done ``` ### Web Dashboard (Optional) #### Simple HTTP Dashboard ```bash #!/bin/bash # dashboard-server.sh while true; do cat > /tmp/agentful-status.html << EOF agentful Monitor

agentful Status

$(/agentful-status)
  

Quality Gates

    $(cat .agentful/completion.json | jq -r '.gates | to_entries[] | "
  • \(.key): \(if .value then "✓" else "✗" end)
  • "')

Recent Activity

$(git log --oneline -10)
  
EOF # Serve with Python or npx serve sleep 5 done ``` Run with: ```bash python3 -m http.server 8000 # Open http://localhost:8000/agentful-status.html ``` ### Remote Monitoring #### SSH Monitoring ```bash # Monitor remote agentful ssh user@server 'cd /path/to/project && cat .agentful/completion.json | jq .overall' # Stream logs ssh user@server 'tail -f /path/to/project/.agentful/agentful.log' ``` #### Slack Integration ```bash # Post status to Slack WEBHOOK="https://hooks.slack.com/services/YOUR/WEBHOOK/URL" curl -X POST $WEBHOOK \ -H 'Content-Type: application/json' \ -d "{ \"text\": \"agentful Update\", \"attachments\": [{ \"text\": \"Progress: $(cat .agentful/completion.json | jq .overall)%\nCurrent: $(cat .agentful/state.json | jq .current_task)\" }] }" ``` ### Monitoring Best Practices #### 1. Check Regularly ```bash # Every hour during workday # Every 4-6 hours during overnight runs ``` #### 2. Monitor Key Metrics Focus on: * Overall progress percentage * Quality gate status * Pending decisions (answer promptly) * Recent commits (review direction) #### 3. Set Up Alerts For long runs: * Completion notification * Failure alerts * Decision notifications #### 4. Keep Historical Data ```bash # Daily snapshots cp .agentful/completion.json .agentful/history/completion-$(date +%Y%m%d).json # Analyze trends for file in .agentful/history/completion-*.json; do echo "$file: $(jq '.overall' $file)%" done ``` #### 5. Use Visual Dashboards * Terminal dashboards for local monitoring * Web dashboards for team visibility * Slack notifications for remote teams ### Troubleshooting Monitoring #### Status Not Updating **Check**: ```bash # State file permissions ls -la .agentful/*.json # File locked? lsof .agentful/completion.json ``` **Fix**: ```bash # Ensure writeable chmod 644 .agentful/*.json ``` #### Inaccurate Progress **Check**: ```bash # Review feature scores cat .agentful/completion.json | jq '.features' # Check if gates accurate cat .agentful/last-review.json ``` **Fix**: ```bash # Re-run validation /agentful-validate ``` #### Missing Commits **Check**: ```bash # Git config git config user.name git config user.email ``` **Fix**: ```bash # Set git config for agentful git config user.name "agentful" git config user.email "agentful@example.com" ``` ### Advanced Monitoring #### Time-Series Tracking ```bash #!/bin/bash # track-progress.sh LOG_FILE=".agentful/progress.log" while true; do TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ") OVERALL=$(cat .agentful/completion.json | jq .overall) TASK=$(cat .agentful/state.json | jq -r .current_task) echo "$TIMESTAMP,$OVERALL,$TASK" >> $LOG_FILE sleep 60 # Log every minute done ``` #### Performance Metrics ```bash #!/bin/bash # performance.sh # Track iteration time START_TIME=$(cat .agentful/state.json | jq -r '.last_updated') CURRENT_TIME=$(date -u +"%Y-%m-%dT%H:%M:%SZ") # Calculate iteration duration (if you have Python/node) # Or use GNU date ``` #### Predictive Completion ```bash #!/bin/bash # eta.sh # Calculate estimated completion CURRENT_PROGRESS=$(cat .agentful/completion.json | jq .overall) ITERATIONS=$(cat .agentful/state.json | jq .iterations) # Simple linear projection if [ "$CURRENT_PROGRESS" -gt 0 ]; then AVG_RATE=$(echo "scale=2; $CURRENT_PROGRESS / $ITERATIONS" | bc) REMAINING=$(echo "scale=0; (100 - $CURRENT_PROGRESS) / $AVG_RATE" | bc) echo "Estimated iterations remaining: $REMAINING" fi ``` ### Next Steps * [Autonomous Development Overview](./index.mdx) - Back to overview * [24/7 Development](./24-7-development.mdx) - Monitoring long-running loops * [Recovery Strategies](./recovery-strategies.mdx) - Monitor fixer effectiveness ## Quality Gates agentful's quality gates ensure that all code entering your codebase meets production-ready standards. This comprehensive guide explains each gate, passing criteria, and how to troubleshoot failures. ### Overview All code must pass **6 quality gates** before being marked complete: 1. **Tests Passing** - All tests must pass 2. **TypeScript Clean** - No type errors 3. **Lint Clean** - No lint errors 4. **Dead Code Removed** - No unused exports, files, or dependencies 5. **Coverage ≥ 80%** - Test coverage threshold 6. **Security Clean** - No vulnerabilities, secrets, or debug logs The reviewer agent runs all checks after every code change. The fixer agent automatically resolves failures when possible. ### Gate 1: Tests Passing #### Purpose Ensure all tests pass before accepting new code. #### Check Command ```bash npm test ``` #### Passing Criteria * Exit code: 0 (success) * Failed tests: 0 * No test timeouts or crashes #### Failure Scenarios ```typescript // ❌ Failing test test('should authenticate user', async () => { const result = await authenticate('user@example.com', 'wrong-password'); expect(result).toBeTruthy(); // Fails: result is null }); ``` #### Common Issues 1. **Test timeouts** - Increase timeout or fix async code 2. **Flaky tests** - Tests that pass sometimes, fail sometimes 3. **Broken fixtures** - Mock data not matching current code 4. **Missing setup** - Tests not initializing dependencies #### Auto-Fixable The fixer agent can: * Fix simple assertion errors * Update outdated test data * Increase timeouts for slow tests * Remove duplicate or redundant tests #### Manual Fixes Required * Complex test logic failures * Race conditions in tests * Environment-specific test issues ### Gate 2: TypeScript Clean #### Purpose Catch type errors at compile time, ensuring type safety. #### Check Command ```bash npx tsc --noEmit ``` #### Passing Criteria * Exit code: 0 * Type errors: 0 * No implicit any #### Failure Scenarios ```typescript // ❌ Type error: Property does not exist interface User { name: string; email: string; } const user: User = { name: 'John', email: 'john@example.com' }; console.log(user.age); // Error: Property 'age' does not exist // ❌ Type error: Wrong type function calculateTotal(price: number, quantity: number): number { return price * quantity; } calculateTotal('10', 5); // Error: Argument of type 'string' not assignable to 'number' // ❌ Type error: Missing return type async function fetchData() { // Should specify Promise return await db.user.findFirst(); } ``` #### Common Issues 1. **Missing type annotations** - Functions without return types 2. **Implicit any** - Parameters without types 3. **Wrong types** - Type mismatches 4. **Missing imports** - Types not imported 5. **Library types** - @types packages not installed #### Auto-Fixable The fixer agent can: * Add missing type annotations * Fix obvious type mismatches * Install missing @types packages * Remove unused type imports * Add proper interface definitions #### Manual Fixes Required * Complex type logic * Generic type constraints * Type assertion decisions * Architectural type design ### Gate 3: Lint Clean #### Purpose Enforce consistent code style and catch common errors. #### Check Command ```bash npm run lint ``` #### Passing Criteria * Exit code: 0 * Lint errors: 0 * Warnings: Allowed (not blocking) #### Failure Scenarios ```typescript // ❌ Lint error: Unused variable const unusedVar = 5; // Error: 'unusedVar' is assigned a value but never used // ❌ Lint error: Inconsistent spacing import{Component}from 'react'; // Missing spaces // ❌ Lint error: Missing semicolon (if configured) const value = 42 // Error: Missing semicolon // ❌ Lint error: Console statement console.log('Debug output'); // Error: Unexpected console statement ``` #### Common Issues 1. **Unused variables** - Variables declared but not used 2. **Console statements** - console.log left in code 3. **Formatting** - Inconsistent spacing, quotes, etc. 4. **Import order** - Imports not sorted correctly 5. **Naming conventions** - Variables not following conventions #### Auto-Fixable The fixer agent can: * Remove unused variables and imports * Delete console.log statements * Fix formatting issues (with --fix flag) * Reorder imports * Fix naming conventions #### Manual Fixes Required * Complex refactoring to fix issues * Architectural lint rule violations ### Gate 4: Dead Code Removed #### Purpose Eliminate unused code that bloats the codebase and creates maintenance burden. #### Check Commands ```bash # Try knip first (most comprehensive) npx knip --reporter json 2>/dev/null # Fall back to ts-prune npx ts-prune 2>/dev/null # Manual grep check grep -r "export.*function\|export.*class" src/ --include="*.ts" --include="*.tsx" ``` #### Passing Criteria * Unused exports: 0 * Unused files: 0 * Unused dependencies: 0 * Unused imports: 0 #### Failure Scenarios ```typescript // ❌ Unused export // src/utils/date.ts export function formatDate(date: Date): string { // Never imported anywhere return date.toISOString(); } export function parseDate(str: string): Date { // Used in other files return new Date(str); } // ❌ Unused file // src/components/OldWidget.tsx // Entire file never imported anywhere // ❌ Unused import import { unused, used } from './module'; // 'unused' never referenced // ❌ Unused dependency // package.json { "dependencies": { "lodash": "^4.17.21" // Never used in code } } ``` #### Common Issues 1. **Unused exports** - Functions/classes exported but never imported 2. **Unused files** - Files not imported by any other file 3. **Unused dependencies** - Packages in package.json but not used 4. **Unused imports** - Imports not referenced in file 5. **Commented code** - Old code commented out instead of deleted #### Auto-Fixable The fixer agent can: * Delete unused exports * Delete unused files * Remove unused imports * Uninstall unused dependencies * Remove commented-out code #### Manual Fixes Required * Determining if code is intentionally exported for library * Code used in conditional imports * Dynamic imports not detected by tools ### Gate 5: Coverage ≥ 80% #### Purpose Ensure code is adequately tested to prevent regressions. #### Check Command ```bash npm test -- --coverage --reporter=json ``` #### Passing Criteria * Overall coverage: ≥ 80% * File-level coverage: No individual file below 60% #### Failure Scenarios ```typescript // ❌ Untested function // src/utils/string.ts export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } // No test file exists: src/utils/__tests__/string.test.ts // ❌ Partially tested function // src/services/user.ts export async function createUser(email: string, password: string) { if (await userExists(email)) { throw new Error('User exists'); } const hashed = await hashPassword(password); return db.user.create({ data: { email, password: hashed } }); } // Test only covers success case, not error case ``` #### Coverage Metrics Track these metrics: ```json { "lines": 85, // Percentage of lines executed "functions": 90, // Percentage of functions called "branches": 75, // Percentage of if/else branches taken "statements": 85 // Percentage of statements executed } ``` All metrics should be ≥ 80%. #### Common Issues 1. **Missing tests** - New code without test coverage 2. **Untested branches** - if/else not fully covered 3. **Error paths** - try/catch error cases not tested 4. **Edge cases** - Boundary conditions not tested 5. **Async paths** - Promise rejections not tested #### Auto-Fixable The fixer agent can: * Generate basic unit tests for untested functions * Add test cases for missing branches * Create tests for error paths * Increase coverage by adding test scenarios #### Manual Fixes Required * Complex integration test setup * E2E test scenarios * Performance testing * Testing with external dependencies ### Gate 6: Security Clean #### Purpose Prevent security vulnerabilities and secrets in code. #### Check Commands ```bash # npm audit for vulnerabilities npm audit --production # Check for hardcoded secrets grep -rE "(password|secret|token|api_key|apikey)\s*[:=]\s*['\"][^'\"]{10,}['\"]" \ src/ --include="*.ts" --include="*.tsx" # Check for console.log grep -rn "console\.(log|debug|warn)" src/ --include="*.ts" --include="*.tsx" # Check for @ts-ignore grep -rn "@ts-ignore\|@ts-nocheck" src/ --include="*.ts" --include="*.tsx" ``` #### Passing Criteria * Critical vulnerabilities: 0 * High vulnerabilities: 0 * Hardcoded secrets: 0 * console.log statements: 0 * @ts-ignore: 0 #### Failure Scenarios ```typescript // ❌ Hardcoded secret const API_KEY = "sk-1234567890abcdef"; // NEVER commit this // ✅ Use environment variables const API_KEY = process.env.API_KEY; // ❌ console.log left in code async function login(email: string, password: string) { console.log('Login attempt:', email); // Remove this const user = await authenticate(email, password); return user; } // ❌ @ts-ignore silencing error // @ts-ignore const data = JSON.parse(maybeInvalidJSON); // Fix the type instead // ❌ npm audit vulnerability // package.json { "dependencies": { "lodash": "4.17.15" // Has known high-severity vulnerability } } ``` #### Common Issues 1. **Hardcoded secrets** - API keys, passwords in code 2. **Debug statements** - console.log, console.debug left in 3. **Type suppressions** - @ts-ignore hiding real issues 4. **Vulnerable dependencies** - Outdated packages with CVEs 5. **Insecure configs** - CORS settings, auth misconfigurations #### Auto-Fixable The fixer agent can: * Remove console.log statements * Replace hardcoded secrets with env vars * Remove @ts-ignore and fix underlying type issues * Update vulnerable dependencies * Add .env.example entries for required env vars #### Manual Fixes Required * Complex secret management setup (Vault, AWS Secrets) * Breaking dependency updates * Architecture-level security changes ### Quality Gate Workflow #### 1. Implementation Agent implements feature: ```typescript // Backend agent creates auth service export class AuthService { async login(email: string, password: string) { console.log('Login:', email); // Oops, left debug log const user = await db.user.findFirst({ where: { email } }); if (!user) throw new Error('Invalid credentials'); return generateToken(user); } } ``` #### 2. Review Reviewer agent runs all checks: ```json { "passed": false, "checks": { "tests": { "passed": false, "failed": 2 }, "typescript": { "passed": true }, "lint": { "passed": false }, "deadCode": { "passed": true }, "coverage": { "passed": false, "actual": 65 }, "security": { "passed": false, "issues": ["console.log in auth.service.ts:5"] } } } ``` #### 3. Fix Fixer agent resolves issues: ```typescript // Removed console.log export class AuthService { async login(email: string, password: string) { const user = await db.user.findFirst({ where: { email } }); if (!user) throw new Error('Invalid credentials'); return generateToken(user); } } // Added missing tests // Improved coverage to 82% ``` #### 4. Re-Review Reviewer runs checks again: ```json { "passed": true, "summary": "All quality gates passed" } ``` #### 5. Complete Orchestrator marks feature complete: ```json { "authentication": { "status": "complete", "score": 100 } } ``` ### Monitoring Quality Gates #### Check Status ```bash # View latest review cat .agentful/last-review.json # View gate status in completion cat .agentful/completion.json | jq '.gates' # Run validation manually /agentful-validate ``` #### Gate Status Output ```json { "gates": { "tests_passing": true, "no_type_errors": true, "no_dead_code": true, "coverage_80": false, "security_clean": true }, "overall": 83.3 } ``` ### Troubleshooting Gate Failures #### Gate Fails Repeatedly 1. **Check last-review\.json**: ```bash cat .agentful/last-review.json | jq '.mustFix' ``` 2. **Identify pattern** - Same file failing? 3. **Manual intervention** - If fixer can't resolve, fix manually 4. **Re-run validation**: ```bash /agentful-validate ``` #### Coverage Stuck Below 80% 1. **Check by-file coverage**: ```bash npm test -- --coverage --reporter=json # Look at coverage report for low files ``` 2. **Target lowest files** - Add tests to worst files first 3. **Test generation** - Fixer can generate basic tests 4. **Manual test writing** - Complex scenarios need manual tests #### Dead Code Keeps Returning 1. **Check imports** - Unused imports often reappear 2. **Check generated code** - Some tools generate unused code 3. **Check barrel exports** - index.ts files exporting unused items 4. **Regular cleanup** - Run knip periodically #### Security Issues Won't Auto-Fix 1. **Secrets in old commits** - Use git-secrets or BFG 2. **Breaking dependency updates** - Manual update and testing 3. **Architecture issues** - May require design changes ### Customizing Gates #### Adjust Coverage Threshold Edit `.claude/agents/reviewer.md`: ```markdown ### 6. Coverage Check **FAIL if:** Coverage < 90% # Changed from 80% ``` #### Add Custom Gates Add new check to reviewer: ````markdown ### 7. Performance Check ```bash npm run benchmark ```` **FAIL if:** Response time > 100ms ```` ### Disable Gates (Not Recommended) Only disable if truly not needed: ```markdown ### 6. Coverage Check **DISABLED:** Not applicable for this project ```` ### Best Practices 1. **Run locally before commit** - Catch issues early 2. **Watch gate trends** - Coverage going up or down? 3. **Address failures quickly** - Don't let debt accumulate 4. **Keep tests fast** - Slow tests discourage running them 5. **Review security regularly** - Run npm audit weekly 6. **Monitor dead code** - Run knip monthly cleanup ### Next Steps * [Autonomous Development Overview](./index.mdx) - Back to overview * [Recovery Strategies](./recovery-strategies.mdx) - How fixer resolves issues * [Monitoring](./monitoring.mdx) - Track gate status over time ## Recovery Strategies agentful's self-healing capabilities automatically resolve most validation failures through the fixer agent. This guide explains how recovery works, what can be auto-fixed, and how to handle issues requiring manual intervention. ### Overview The recovery cycle works as follows: ```mermaid graph TD A[Code Change] --> B[Reviewer Validates] B --> C{All Pass?} C -->|Yes| D[Mark Complete] C -->|No| E[Identify Issues] E --> F[Fixer Attempts Auto-Fix] F --> G{Fixed?} G -->|Yes| B G -->|No| H[Add to Decisions] H --> I[Manual Intervention] I --> J[User Resolves] J --> B ``` ### Fixer Agent Capabilities The fixer agent can automatically resolve: #### 1. Dead Code Removal **Unused Exports** ```typescript // Before export function formatDate(date: Date): string { // Unused return date.toISOString(); } export function parseDate(str: string): Date { // Used return new Date(str); } // After (fixer removes unused function) export function parseDate(str: string): Date { return new Date(str); } ``` **Unused Files** ```bash # Fixer deletes entire file rm src/components/OldWidget.tsx # Removes imports from other files # Updates barrel exports ``` **Unused Dependencies** ```bash # Detects with depcheck npx depcheck # Removes from package.json npm uninstall lodash ``` #### 2. Test Coverage Gaps **Generates Basic Tests** ```typescript // Original code (untested) export function capitalize(str: string): string { return str.charAt(0).toUpperCase() + str.slice(1); } // Fixer generates test describe('capitalize', () => { it('should capitalize first letter', () => { expect(capitalize('hello')).toBe('Hello'); }); it('should handle empty string', () => { expect(capitalize('')).toBe(''); }); it('should handle single character', () => { expect(capitalize('a')).toBe('A'); }); }); ``` **Adds Edge Case Tests** * Null/undefined inputs * Empty strings/arrays * Boundary values (0, -1, etc.) * Error conditions #### 3. Code Quality Issues **Removes Debug Statements** ```typescript // Before async function login(email: string, password: string) { console.log('Login attempt:', email); // Remove console.debug('Password:', password); // Remove const user = await authenticate(email, password); return user; } // After async function login(email: string, password: string) { const user = await authenticate(email, password); return user; } ``` **Removes Commented Code** ```typescript // Before // export function oldMethod() { ... } // Remove this export function newMethod() { ... } // After export function newMethod() { ... } ``` **Fixes TODO Comments** ```typescript // Before // TODO: Implement validation // Fixer implements or removes function process(input: string) { return input; } // After (fixer implements basic validation) function process(input: string): string { if (!input || input.trim().length === 0) { throw new Error('Invalid input'); } return input.trim(); } ``` #### 4. TypeScript Errors **Adds Type Annotations** ```typescript // Before function calculate(a, b) { // Implicit any return a + b; } // After function calculate(a: number, b: number): number { return a + b; } ``` **Fixes Type Mismatches** ```typescript // Before interface User { name: string; } const user: User = { name: 'John', age: 30 }; // Error: age not in interface // After interface User { name: string; age?: number; // Made optional } const user: User = { name: 'John', age: 30 }; ``` **Installs Type Definitions** ```bash # Detects missing types # import express from 'express' // No @types/express # Installs automatically npm install --save-dev @types/express ``` #### 5. Lint Errors **Removes Unused Variables** ```typescript // Before const unused = 5; const used = 10; console.log(used); // After const used = 10; console.log(used); ``` **Fixes Import Order** ```typescript // Before (wrong order) import { internal } from './internal'; import React from 'react'; import lodash from 'lodash'; // After (correct order) import React from 'react'; import lodash from 'lodash'; import { internal } from './internal'; ``` **Fixes Formatting** ```typescript // Before const obj ={key:'value'}; // Spacing issues // After const obj = { key: 'value' }; ``` #### 6. Security Issues **Removes Hardcoded Secrets** ```typescript // Before const API_KEY = "sk-1234567890abcdef"; // ❌ Never commit // After const API_KEY = process.env.API_KEY; // Fixer also updates .env.example echo "API_KEY=your_api_key_here" >> .env.example ``` **Updates Vulnerable Dependencies** ```bash # npm audit shows vulnerability # lodash@4.17.15 has high severity vulnerability # Fixer updates npm update lodash # If breaking changes, creates decision for manual review ``` **Removes @ts-ignore** ```typescript // Before // @ts-ignore const data = JSON.parse(maybeInvalid); // After (fixer adds proper validation) const data = JSON.parse(maybeInvalid) as unknown; if (isValidData(data)) { return data; } throw new Error('Invalid data'); ``` ### Recovery Workflow #### 1. Issue Detection Reviewer identifies issues: ```json { "passed": false, "mustFix": [ "Remove unused export: formatDate in src/utils/date.ts", "Add tests to reach 80% coverage (currently 72%)", "Remove console.log from src/auth/login.ts:45" ] } ``` #### 2. Fixer Attempts Resolution Fixer works through issues systematically: ```typescript // Priority 1: Quick fixes // - Remove console.log (line 45) // - Remove unused export // Priority 2: Medium effort // - Generate tests for coverage // Priority 3: Complex fixes // - Refactor if needed ``` #### 3. Re-Validation After fixes, reviewer runs again: ```json { "passed": true, "summary": "All issues resolved" } ``` #### 4. Progress Update Orchestrator marks complete: ```json { "current_task": null, "current_phase": "idle" } ``` ### Manual Intervention Required Some issues require human judgment: #### 1. Architectural Decisions ```typescript // Fixer detects circular dependency // src/a.ts imports from src/b.ts // src/b.ts imports from src/a.ts // Can't auto-fix - requires refactoring decision // Creates decision in decisions.json ``` **Example Decision**: ```json { "id": "arch-decision-001", "question": "How to resolve circular dependency between a.ts and b.ts?", "options": [ "Extract shared code to c.ts", "Combine into single module", "Use dependency injection pattern" ], "blocking": ["feature-x"], "timestamp": "2026-01-18T00:00:00Z" } ``` #### 2. Breaking Changes ```typescript // Fixer can't update major version // package.json: "package": "1.0.0" // Vulnerability fixed in "package": "2.0.0" // Creates decision for manual approval ``` #### 3. Complex Test Scenarios ```typescript // Fixer can generate basic tests // But complex integration tests need manual design describe('user authentication flow', () => { // Fixer creates simple test it('should authenticate valid user', async () => { // ... basic test }); // Manual test needed for: it('should handle rate limiting', async () => { // Complex scenario with timing }); it('should handle concurrent logins', async () => { // Race condition testing }); }); ``` #### 4. Business Logic ```typescript // Fixer can implement validation // But business rules need human input // Example: Discount calculation function calculateDiscount(total: number, customer: Customer): number { // Fixer can add basic validation if (total <= 0) throw new Error('Invalid total'); // But business rule needs human: // "VIP customers get 15% discount on orders over $100 // but only on Tuesdays, and not during sale periods" // Creates decision for business logic clarification } ``` #### 5. External Dependencies ```typescript // Fixer can't set up external services // Database connections, API keys, etc. // Creates decision with setup instructions { "question": "Database configuration needed", "context": "Add DATABASE_URL to .env", "instructions": "1. Create database at Supabase\n2. Add URL to .env\n3. Run migrations" } ``` ### Handling Manual Decisions #### When Decision Is Required 1. **Stop current work** on blocked feature 2. **Create decision** in `decisions.json` 3. **Continue** with non-blocked features 4. **Notify user** to run `/agentful-decide` #### Resolution Process ```bash # User runs decision command /agentful-decide # agentful presents options ❓ How to resolve circular dependency? [1] Extract shared code to c.ts [2] Combine into single module [3] Use dependency injection pattern Your choice: 1 ✅ Decision recorded. Continuing development... ``` #### After Resolution 1. **Decision moved** from pending to resolved 2. **Blocked feature** becomes active again 3. **Orchestrator resumes** work on feature 4. **Fixer implements** based on decision ### Recovery Patterns #### Pattern 1: Immediate Fix ```typescript // Issue found console.log in src/auth.ts:45 // Immediate fix // Fixer removes line // Re-validate // Pass ``` #### Pattern 2: Iterative Fix ```typescript // Issue found Coverage at 65%, need 80% // Iteration 1: Fixer adds tests for untested functions // Coverage: 72% // Iteration 2: Fixer adds edge case tests // Coverage: 78% // Iteration 3: Fixer adds integration tests // Coverage: 82% // Pass ``` #### Pattern 3: Manual Decision Loop ```typescript // Issue found Circular dependency detected // Can't fix // Create decision // User answers // Extract shared code // Fixer implements // Re-validate // Pass ``` #### Pattern 4: Cascading Fixes ```typescript // Issue 1 found Unused export in utils.ts // Fixer removes export // But now tests fail (they imported the export) // Issue 2 found Test failures // Fixer removes dead tests // But now coverage drops // Issue 3 found Coverage below 80% // Fixer adds new tests // Pass ``` ### Monitoring Recovery #### Track Fixer Activity ```bash # View what fixer is doing tail -f .agentful/fixer.log # Check recent fixes cat .agentful/last-fix.json # View fix history cat .agentful/completion.json | jq '.fix_history' ``` #### Fix Report Format ```json { "timestamp": "2026-01-18T00:00:00Z", "fixed": [ "Removed unused export: formatDate in src/utils/date.ts", "Deleted unused file: src/components/OldWidget.tsx", "Removed console.log from src/auth/login.ts:45" ], "remaining": [ "Coverage at 78% (added tests, need 2 more%)" ], "blocked": [] } ``` #### Recovery Metrics Track these metrics: ```json { "auto_fix_rate": 0.85, // 85% of issues auto-fixed "manual_decision_rate": 0.15, // 15% need human input "avg_fix_iterations": 2.3, // Average 2.3 loops to resolve "critical_fixes": 12, // Number of critical issues fixed "quality_fixes": 45 // Number of quality issues fixed } ``` ### Troubleshooting Recovery #### Fixer Can't Resolve Issue **Symptoms**: * Same issue appears in multiple reviews * `remaining` array never empties * Iteration count increases without progress **Diagnosis**: ```bash # Check what's blocking cat .agentful/last-review.json | jq '.mustFix' # Check fix attempts cat .agentful/last-fix.json | jq '.remaining' ``` **Solutions**: 1. Run `/agentful-validate` manually 2. Review specific issues 3. Fix manually if needed 4. Check if decision needed but not created #### Fixer Creates Breaking Changes **Symptoms**: * Tests pass after fix but functionality broken * Type errors fixed but logic wrong **Prevention**: ```bash # Always run tests after fixes npm test # Check git diff before commit git diff # If suspicious, reset and fix manually git reset --hard HEAD ``` #### Infinite Fix Loop **Symptoms**: * Fixer fixes issue * Reviewer finds it again * Loop never ends **Common Causes**: 1. **Tool configuration wrong** - Fixer and reviewer using different rules 2. **Generated code** - Fixer removes code that gets regenerated 3. **Conflicting rules** - One rule requires what another forbids **Solutions**: 1. Stop the loop (Ctrl+C or kill Ralph) 2. Review configuration files 3. Align tool settings 4. Consider excluding generated files from checks #### Recovery Deletes Useful Code **Symptoms**: * Fixer removes code you need * Exports deleted but used in tests **Prevention**: ```typescript // Mark intentionally unused exports // eslint-disable-next-line unused-imports/no-unused-vars export { experimentalFeature } from './experimental'; // Or use barrel exports selectively // public.ts - exports for external use // internal.ts - exports for internal use only ``` **Recovery**: ```bash # Restore from git git log --find-renames --name-status # Find deletion git checkout -- path/to/file ``` ### Best Practices #### 1. Review Auto-Fixes Regularly review what fixer is doing: ```bash # Daily review git log --author="fixer" --since="1 day ago" --patch ``` #### 2. Test Critical Paths After auto-fixes, manually test: * Authentication flows * Payment processing * Data mutations * External integrations #### 3. Monitor Fix Patterns If fixer keeps fixing same type of issue: * Update agent instructions to prevent issue * Adjust lint rules * Add pre-commit hooks #### 4. Keep Decisions Small Break complex decisions into smaller ones: ```json // Bad: Giant decision { "question": "How to refactor entire authentication system?" } // Good: Small decisions { "question": "Use JWT or sessions?" } { "question": "Store tokens in localStorage or cookies?" } ``` #### 5. Document Decisions Resolved decisions should inform future work: ```json { "resolved": [ { "id": "auth-001", "question": "JWT or sessions?", "answer": "JWT with httpOnly cookies", "reasoning": "Scalability for future microservices", "timestamp": "2026-01-18T00:00:00Z" } ] } ``` ### Advanced Recovery #### Custom Fix Strategies Define custom fix patterns in `.claude/agents/fixer.md`: ````markdown ## Custom Fix: Add Error Logging When adding try/catch, also add logging: ```typescript try { await operation(); } catch (error) { logger.error('Operation failed', { error }); throw error; } ```` ```` ### Recovery Hooks Add custom recovery steps: ```markdown ## After Database Connection Failure 1. Check DATABASE_URL in .env 2. Test connection: npm run db:test 3. Run migrations: npm run db:migrate 4. Retry operation ```` ### Next Steps * [Autonomous Development Overview](./index.mdx) - Back to overview * [Quality Gates](./quality-gates.mdx) - What triggers recovery * [Monitoring](./monitoring.mdx) - Track recovery effectiveness ## Architect Agent The Architect analyzes the tech stack and dynamically generates specialized agents for frameworks, databases, and tools used in the project. ### Overview The Architect ensures that agentful can work with any technology stack by: 1. Reading `PRODUCT.md` to identify the tech stack 2. Generating framework-specific agents (Next.js, Vue, NestJS, etc.) 3. Creating documentation for tech-specific patterns 4. Updating agents when the tech stack changes 5. Maintaining `.agentful/architecture.json` ### Configuration ```yaml name: architect description: Analyzes PRODUCT.md tech stack and generates specialized agents dynamically. Creates language/framework-specific agents on demand. model: opus tools: Read, Write, Edit, Glob, Grep, Task ``` **Why Opus?** Agent generation requires understanding framework patterns, best practices, and how to structure effective agents. ### Startup Process #### 1. Analyze Tech Stack Read `PRODUCT.md` and extract: ```markdown ## Tech Stack - Framework: Next.js 14 - Language: TypeScript - Database: PostgreSQL + Prisma - Auth: JWT - Styling: Tailwind CSS - Testing: Vitest + Playwright ``` **Extracted Information:** * **Frontend Framework** - Next.js, React, Vue, Svelte, Solid, etc. * **Backend Framework** - Next.js API Routes, Express, NestJS, Fastify, etc. * **Database** - PostgreSQL, MySQL, MongoDB, SQLite, etc. * **ORM** - Prisma, Drizzle, TypeORM, etc. * **Styling** - Tailwind, CSS Modules, styled-components, etc. * **Testing** - Jest, Vitest, Playwright, Cypress, etc. * **Language** - TypeScript, JavaScript, Python, Go, etc. #### 2. Generate Specialized Agents For each technology, create or update agents: ``` .claude/agents/generated/ ├── nextjs-agent.md # Next.js specific patterns ├── prisma-agent.md # Database/ORM patterns ├── tailwind-agent.md # Styling patterns └── vitest-agent.md # Testing patterns ``` #### 3. Create Architecture Documentation Generate `.agentful/architecture.json`: ```json { "detected_stack": { "frontend": { "framework": "Next.js", "version": "14", "language": "TypeScript" }, "backend": { "framework": "Next.js API Routes", "runtime": "Node.js" }, "database": { "provider": "PostgreSQL", "orm": "Prisma" }, "styling": { "framework": "Tailwind CSS" }, "testing": { "unit": "Vitest", "e2e": "Playwright" } }, "generated_agents": [ "nextjs-agent", "prisma-agent", "tailwind-agent", "vitest-agent" ], "decisions": [], "timestamp": "2026-01-18T00:00:00Z" } ``` ### Agent Template Generated agents follow this template: ````markdown --- name: {{tech}}-specialist description: Specializes in {{Tech Framework}} development. Uses {{specific patterns}}. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # {{Tech Framework}} Specialist You are the {{Tech Framework}} Specialist Agent. ## Patterns ### File Structure \``` src/ ├── app/ # App router ├── components/ # React components └── lib/ # Utilities \``` ### Component Pattern \`\`\`tsx 'use client'; export default function {{ComponentName}}() { return
{{Content}}
; } \`\`\` ### API Route Pattern \`\`\`ts import { NextRequest, NextResponse } from 'next/server'; export async function GET(req: NextRequest) { return NextResponse.json({ data }); } \`\`\` ## Rules - Use App Router (not Pages Router) - Server Components by default - Client Components only when needed (useState, useEffect) - Always use TypeScript ```` ### Supported Technologies #### JavaScript/TypeScript Ecosystem | Framework | Agent Name | Patterns | | --------- | ------------- | ------------------------------------------ | | Next.js | nextjs-agent | App Router, Server Actions, Route Handlers | | React | react-agent | Hooks, Components, Context | | Vue | vue-agent | Composition API, Script Setup | | Svelte | svelte-agent | Components, Stores, Actions | | Solid | solid-agent | Reactive primitives, Components | | Express | express-agent | Routes, Middleware, Controllers | | NestJS | nestjs-agent | Modules, Controllers, Services | | Fastify | fastify-agent | Routes, Plugins, Hooks | #### Backend/Databases | Database | Agent Name | Patterns | | ---------- | -------------- | ------------------------------------------ | | Prisma | prisma-agent | Schema, Client, Migrations | | Drizzle | drizzle-agent | Schema, Queries, Migrations | | TypeORM | typeorm-agent | Entities, Repositories, Migrations | | Mongoose | mongoose-agent | Models, Schemas, Middleware | | MongoDB | mongodb-agent | Collections, Aggregation, Indexes | | PostgreSQL | postgres-agent | Queries, Transactions, Functions | | MySQL | mysql-agent | Queries, Transactions, Stored Procedures | | SQLite | sqlite-agent | Queries, Transactions, Database management | #### Styling | Styling | Agent Name | Patterns | | ----------------- | ---------------- | -------------------------------- | | Tailwind | tailwind-agent | Utility classes, @apply, config | | CSS Modules | cssmodules-agent | .module.css, composition | | styled-components | styled-agent | Styled components, themes, props | | shadcn/ui | shadcn-agent | Components, cn(), variants | | Chakra UI | chakra-agent | Components, Props, Theming | | Mantine | mantine-agent | Components, Hooks, Theming | #### Testing | Framework | Agent Name | Patterns | | --------------- | --------------------- | ---------------------------- | | Vitest | vitest-agent | describe, it, expect, vi | | Jest | jest-agent | describe, test, expect, jest | | Playwright | playwright-agent | page, locator, expect | | Cypress | cypress-agent | cy, commands, custom queries | | Testing Library | testing-library-agent | render, screen, fireEvent | #### State Management | Library | Agent Name | Patterns | | -------------- | ------------- | ---------------------------------- | | Zustand | zustand-agent | create, useStore, slices | | Redux | redux-agent | actions, reducers, selectors | | Jotai | jotai-agent | atoms, useAtom | | Recoil | recoil-agent | atoms, selectors, useRecoilState | | TanStack Query | query-agent | useQuery, useMutation, QueryClient | ### Dynamic Agent Generation When a new technology is detected: #### 1. Check if Agent Exists ```bash if [ ! -f ".claude/agents/${tech}-agent.md" ]; then # Generate agent Task("architect", "Generate ${tech}-agent.md based on PRODUCT.md") fi ``` #### 2. Generate from Template The Architect: 1. Researches the technology's best practices 2. Creates patterns specific to that technology 3. Writes examples and common use cases 4. Documents rules and gotchas 5. Saves to `.claude/agents/generated/${tech}-agent.md` #### 3. Validate Generated Agent ```markdown Task("reviewer", "Validate generated ${tech}-agent.md follows best practices") ``` ### Handling Unknown Tech Stack If `PRODUCT.md` doesn't specify tech stack: #### Option 1: Analyze Existing Code ```bash # Detect project type grep -r "package.json" && echo "Node.js project" grep -r "go.mod" && echo "Go project" grep -r "requirements.txt" && echo "Python project" grep -r "Cargo.toml" && echo "Rust project" # Detect frameworks grep -r "next.config" && echo "Next.js" grep -r "vite.config" && echo "Vite" grep -r "@nestjs" && echo "NestJS" ``` #### Option 2: Ask User Add to `decisions.json`: ```json { "id": "tech-stack-001", "question": "What tech stack should we use?", "options": [ "Next.js + TypeScript + Prisma", "React + Vite + Node + Express", "Vue + Nuxt + Nitro", "SvelteKit + Prisma", "Custom (specify)" ], "context": "No tech stack specified in PRODUCT.md", "blocking": ["agent-generation"] } ``` #### Option 3: Use Defaults ```json { "detected_stack": { "frontend": { "framework": "Next.js", "version": "14" }, "backend": { "framework": "Next.js API Routes" }, "database": { "orm": "Prisma" }, "styling": { "framework": "Tailwind CSS" }, "testing": { "unit": "Vitest", "e2e": "Playwright" } } } ``` ### Self-Healing Updates When tech stack changes: #### 1. Detect Change ```bash # Monitor PRODUCT.md for changes # Monitor package.json for new dependencies ``` #### 2. Regenerate Affected Agents ```markdown [Detect] → New framework added (e.g., "tRPC") ↓ [Generate] → Create trpc-agent.md ↓ [Validate] → Test agent works ↓ [Update] → Update architecture.json ↓ [Notify] → Tell orchestrator about new capability ``` #### 3. Update Architecture JSON ```json { "generated_agents": [ "nextjs-agent", "prisma-agent", "trpc-agent" // Newly added ] } ``` ### Integration with Orchestrator After generating agents, the Orchestrator can delegate: ```markdown Task("nextjs-agent", "Create the dashboard page with server components") Task("prisma-agent", "Add user schema with email and password") Task("tailwind-agent", "Style the login form with proper spacing") Task("vitest-agent", "Write tests for auth service") ``` ### Example: Generating Next.js Agent #### Input ```markdown PRODUCT.md: - Framework: Next.js 14 - App Router (not Pages Router) - TypeScript - Server Components by default ``` #### Output ````markdown --- name: nextjs-specialist description: Specializes in Next.js 14 App Router development. Uses Server Components, Server Actions, and Route Handlers. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Next.js 14 Specialist ## File Structure \``` src/ ├── app/ │ ├── (auth)/ │ │ └── login/ │ │ └── page.tsx │ ├── api/ │ │ └── auth/ │ │ └── route.ts │ └── layout.tsx ├── components/ └── lib/ \``` ## Page Pattern \`\`\`tsx // Server Component (default) export default async function DashboardPage() { const data = await fetchData(); return
{data}
; } \`\`\` ## Client Component Pattern \`\`\`tsx 'use client'; export default function InteractiveButton() { const [count, setCount] = useState(0); return ; } \`\`\` ## Server Action Pattern \`\`\`tsx 'use server'; export async function createPost(formData: FormData) { // Server-side logic } \`\`\` ## Route Handler Pattern \`\`\`tsx import { NextRequest, NextResponse } from 'next/server'; export async function GET(req: NextRequest) { return NextResponse.json({ data }); } \`\`\` ## Rules - Use App Router (not Pages Router) - Server Components by default - Add 'use client' only for interactive components - Always use TypeScript - Use native fetch for data fetching - Prefer Server Actions over API routes for mutations ```` ### Best Practices #### DO * Always read PRODUCT.md first * Check if agent exists before generating * Validate generated agents * Use latest framework patterns * Update architecture.json after changes * Document framework-specific gotchas #### DON'T * Overwrite user-customized agents without asking * Generate agents for technologies not in use * Skip validation * Use outdated patterns (e.g., Next.js Pages Router) ### Troubleshooting #### Agent Not Generated **Symptom:** Expected agent not in `.claude/agents/generated/` **Solutions:** 1. Check PRODUCT.md has the tech stack specified 2. Run `/agentful-generate-agents` manually 3. Check architecture.json for detected technologies #### Agent Uses Wrong Patterns **Symptom:** Generated agent uses outdated or incorrect patterns **Solutions:** 1. Edit agent file directly: `.claude/agents/generated/${tech}-agent.md` 2. Update PRODUCT.md with correct framework version 3. Re-run architect to regenerate #### Missing Technology Detection **Symptom:** Technology in use but no agent generated **Solutions:** 1. Manually add to PRODUCT.md 2. Run architect to detect changes 3. Create agent manually as template ### Advanced Usage #### Custom Agent Templates Override default agent template by creating: ``` .agentful/templates/ ├── frontend-agent.md ├── backend-agent.md └── database-agent.md ``` #### Framework-Specific Overrides ```markdown .claude/agents/generated/nextjs-agent.md: # Override: Custom Next.js patterns for this project # Your custom patterns - Use our custom Button component - Follow our folder structure - Use our custom hooks ``` #### Multi-Language Support Generate agents for different languages: ```json { "detected_stack": { "frontend": { "language": "TypeScript" }, "backend": { "language": "Python", "framework": "FastAPI" } }, "generated_agents": [ "nextjs-agent", "fastapi-agent" ] } ``` ### Monitoring Check architect status: ```bash # View detected architecture cat .agentful/architecture.json # List generated agents ls -la .claude/agents/generated/ # Regenerate all agents /agentful-generate-agents ``` ## Backend Agent The Backend Agent implements server-side code following clean architecture patterns with proper separation of concerns. ### Overview The Backend Agent is responsible for all server-side development: * API routes and controllers * Service layer (business logic) * Repository layer (data access) * Database schemas and migrations * Authentication and authorization * Input validation * Error handling ### Configuration ```yaml name: backend description: Implements backend services, repositories, controllers, APIs, database schemas, authentication. Never modifies frontend code. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash ``` **Why Sonnet?** Backend implementation requires understanding patterns but not the highest reasoning level - Opus is better used for orchestration and architecture. ### Scope #### ✅ What the Backend Agent Does * **API Routes & Controllers** - HTTP endpoints, request handling * **Service Layer** - Business logic, use cases * **Repository Layer** - Data access, database queries * **Database** - Schemas, migrations, seeders * **Authentication** - JWT, sessions, OAuth, authorization * **Validation** - Input validation with Zod or similar * **Error Handling** - Proper error responses #### ❌ What the Backend Agent Delegates * UI components → `@frontend` * Tests → `@tester` * Code review → `@reviewer` * Frontend build tools → `@frontend` ### Implementation Pattern The Backend Agent follows **layered architecture** in this order: #### 1. Repository Layer First Data access logic: ```typescript // src/repositories/user.repository.ts export class UserRepository { async findById(id: string): Promise { return db.user.findUnique({ where: { id } }); } async findByEmail(email: string): Promise { return db.user.findUnique({ where: { email } }); } async create(data: CreateUserInput): Promise { return db.user.create({ data }); } async update(id: string, data: UpdateUserInput): Promise { return db.user.update({ where: { id }, data }); } async delete(id: string): Promise { return db.user.delete({ where: { id } }); } } ``` **Key Principles:** * Single responsibility (data access only) * Database-specific logic * No business rules * Returns domain entities #### 2. Service Layer Second Business logic: ```typescript // src/services/user.service.ts import { UserRepository } from '../repositories/user.repository'; import { hashPassword, comparePassword } from '../lib/crypto'; export class UserService { constructor(private repo: UserRepository) {} async registerUser(input: RegisterInput): Promise { // Check if user exists const existing = await this.repo.findByEmail(input.email); if (existing) { throw new ConflictError('User already exists'); } // Hash password const hashedPassword = await hashPassword(input.password); // Create user return this.repo.create({ ...input, password: hashedPassword, }); } async authenticateUser(email: string, password: string): Promise { const user = await this.repo.findByEmail(email); if (!user) { throw new UnauthorizedError('Invalid credentials'); } const isValid = await comparePassword(password, user.password); if (!isValid) { throw new UnauthorizedError('Invalid credentials'); } return user; } } ``` **Key Principles:** * Business rules and validation * Orchestrates repositories * Handles errors * Domain-specific logic #### 3. Controller/Route Last HTTP handlers: ```typescript // src/app/api/users/route.ts import { UserService } from '../../services/user.service'; import { UserRepository } from '../../repositories/user.repository'; import { registerSchema } from '../../schemas/user.schema'; export async function POST(req: Request) { try { // Validate input const body = await req.json(); const validated = registerSchema.parse(body); // Execute use case const service = new UserService(new UserRepository()); const user = await service.registerUser(validated); // Return response return Response.json(user, { status: 201 }); } catch (error) { if (error instanceof z.ZodError) { return Response.json( { error: 'Validation failed', details: error.errors }, { status: 400 } ); } if (error instanceof ConflictError) { return Response.json({ error: error.message }, { status: 409 }); } throw error; } } ``` **Key Principles:** * Thin layer (delegation only) * HTTP-specific concerns * Input/output handling * Status codes ### Technology-Specific Patterns #### Next.js App Router (Route Handlers) ```typescript // src/app/api/auth/login/route.ts import { NextRequest, NextResponse } from 'next/server'; import { AuthService } from '@/services/auth.service'; export async function POST(req: NextRequest) { const body = await req.json(); const authService = new AuthService(); const result = await authService.login(body); return NextResponse.json(result); } ``` #### Express.js ```typescript // src/routes/auth.routes.ts import { Router } from 'express'; import { AuthService } from '../services/auth.service'; import { authenticate } from '../middleware/auth'; const router = Router(); router.post('/register', async (req, res, next) => { try { const authService = new AuthService(); const user = await authService.register(req.body); res.status(201).json(user); } catch (error) { next(error); } }); router.post('/login', async (req, res, next) => { try { const authService = new AuthService(); const result = await authService.login(req.body); res.json(result); } catch (error) { next(error); } }); export default router; ``` #### NestJS ```typescript // src/auth/auth.controller.ts import { Controller, Post, Body } from '@nestjs/common'; import { AuthService } from './auth.service'; @Controller('auth') export class AuthController { constructor(private authService: AuthService) {} @Post('register') async register(@Body() registerDto: RegisterDto) { return this.authService.register(registerDto); } @Post('login') async login(@Body() loginDto: LoginDto) { return this.authService.login(loginDto); } } ``` ### Authentication Patterns #### JWT Authentication ```typescript // src/services/auth.service.ts import { sign, verify } from 'jsonwebtoken'; import { UserRepository } from '../repositories/user.repository'; export class AuthService { constructor(private repo: UserRepository) {} async login(email: string, password: string) { const user = await this.repo.findByEmail(email); if (!user) throw new UnauthorizedError('Invalid credentials'); const isValid = await comparePassword(password, user.password); if (!isValid) throw new UnauthorizedError('Invalid credentials'); const token = sign( { userId: user.id }, process.env.JWT_SECRET!, { expiresIn: '7d' } ); return { token, user }; } verifyToken(token: string) { return verify(token, process.env.JWT_SECRET!); } } ``` #### Middleware Protection ```typescript // src/middleware/auth.ts import { Request, Response, NextFunction } from 'express'; export function authenticate(req: Request, res: Response, next: NextFunction) { const token = req.headers.authorization?.replace('Bearer ', ''); if (!token) { return res.status(401).json({ error: 'No token provided' }); } try { const decoded = verifyToken(token); req.user = decoded; next(); } catch (error) { return res.status(401).json({ error: 'Invalid token' }); } } ``` ### Validation Patterns #### Zod Schema Validation ```typescript // src/schemas/user.schema.ts import { z } from 'zod'; export const registerSchema = z.object({ email: z.string().email('Invalid email format'), password: z.string().min(8, 'Password must be at least 8 characters'), name: z.string().min(2, 'Name must be at least 2 characters'), }); export type RegisterInput = z.infer; ``` #### Controller Validation ```typescript export async function POST(req: Request) { try { const body = await req.json(); const validated = registerSchema.parse(body); // Proceed with validated data } catch (error) { if (error instanceof z.ZodError) { return Response.json( { error: 'Validation failed', details: error.errors }, { status: 400 } ); } } } ``` ### Error Handling #### Custom Error Classes ```typescript // src/lib/errors.ts export class ConflictError extends Error { constructor(message: string) { super(message); this.name = 'ConflictError'; } } export class UnauthorizedError extends Error { constructor(message: string) { super(message); this.name = 'UnauthorizedError'; } } export class NotFoundError extends Error { constructor(message: string) { super(message); this.name = 'NotFoundError'; } } ``` #### Error Middleware ```typescript // src/middleware/error.ts import { Request, Response, NextFunction } from 'express'; export function errorHandler(err: Error, req: Request, res: Response, next: NextFunction) { if (err instanceof ConflictError) { return res.status(409).json({ error: err.message }); } if (err instanceof UnauthorizedError) { return res.status(401).json({ error: err.message }); } if (err instanceof NotFoundError) { return res.status(404).json({ error: err.message }); } console.error('Unexpected error:', err); res.status(500).json({ error: 'Internal server error' }); } ``` ### File Structure ``` src/ ├── repositories/ # Data access layer │ ├── user.repository.ts │ ├── base.repository.ts │ └── index.ts ├── services/ # Business logic │ ├── user.service.ts │ ├── auth.service.ts │ └── index.ts ├── controllers/ # HTTP handlers │ ├── user.controller.ts │ ├── auth.controller.ts │ └── index.ts ├── middleware/ # Express/Nest middleware │ ├── auth.ts │ ├── error.ts │ └── index.ts ├── schemas/ # Validation schemas │ ├── user.schema.ts │ └── index.ts ├── lib/ # Utilities │ ├── crypto.ts │ ├── errors.ts │ └── validation.ts └── types/ # TypeScript types ├── user.types.ts └── index.ts ``` ### Rules #### ALWAYS 1. Use TypeScript strict mode 2. Handle errors explicitly with proper HTTP status codes 3. Validate inputs with Zod or similar 4. Follow the Repository → Service → Controller pattern 5. Use environment variables for secrets 6. Return consistent response formats #### NEVER 1. Leave TODO comments - implement fully or document blocker 2. Modify frontend code (components, pages, styles) 3. Skip error handling 4. Hardcode secrets or configuration 5. Mix concerns (e.g., database queries in controllers) 6. Return different response formats inconsistently ### Best Practices #### Dependency Injection ```typescript // Good: DI allows testing export class UserService { constructor(private repo: UserRepository) {} async getUser(id: string) { return this.repo.findById(id); } } // Bad: Hard dependency export class UserService { async getUser(id: string) { const repo = new UserRepository(); // ❌ return repo.findById(id); } } ``` #### Error Messages ```typescript // Good: Specific, actionable errors throw new ConflictError('User with email "test@example.com" already exists'); // Bad: Generic errors throw new Error('Failed'); // ❌ ``` #### Response Consistency ```typescript // Good: Consistent structure return Response.json({ data: user, meta: { timestamp: new Date().toISOString() } }); // Bad: Inconsistent return Response.json(user); // ❌ Sometimes wrapped return Response.json({ user }); // ❌ Sometimes not ``` ### Common Tasks #### Creating a New Feature 1. **Repository** - Create data access methods 2. **Service** - Implement business logic 3. **Schema** - Define validation 4. **Controller** - Create HTTP endpoint 5. **Test** - Delegate to @tester #### Adding Authentication 1. Create auth service with JWT logic 2. Add authenticate middleware 3. Protect routes with middleware 4. Add login/register endpoints #### Database Migration 1. Update schema (Prisma, Drizzle, etc.) 2. Generate migration 3. Run migration 4. Update repository if needed ### After Implementation Report to orchestrator: ```json { "files_created": [ "src/repositories/user.repository.ts", "src/services/user.service.ts", "src/app/api/users/route.ts" ], "files_modified": [], "implementation": "User CRUD API with JWT authentication", "dependencies_added": ["jsonwebtoken", "bcryptjs", "zod"], "next_steps": [ "Write unit tests for UserService", "Write integration tests for API endpoints", "Add frontend components for user management" ] } ``` ### Troubleshooting #### Circular Dependencies **Symptom:** Import cycles between services **Solutions:** 1. Create a shared types file 2. Use dependency injection 3. Restructure to avoid bidirectional dependencies #### Type Errors **Symptom:** TypeScript compilation fails **Solutions:** 1. Run `npx tsc --noEmit` to see errors 2. Fix type mismatches 3. Ensure all imports are typed #### Database Connection Issues **Symptom:** Repository methods fail **Solutions:** 1. Check environment variables 2. Verify database is running 3. Test connection separately ### Integration #### With Orchestrator ``` [Orchestrator] → "Implement user authentication" ↓ [Backend] → Creates auth service, repository, routes ↓ [Orchestrator] → "Review authentication" ↓ [Reviewer] → Validates ``` #### With Frontend ``` [Backend] → Creates POST /api/auth/login ↓ [Frontend] → Creates login form that calls API ↓ [Backend] → Returns JWT token ``` #### With Tester ``` [Backend] → Implements UserService ↓ [Tester] → Writes unit tests ↓ [Backend] → Fixes any issues found ``` ## Creating Custom Agents Extend agentful by creating custom agents for specialized tasks, technologies, or workflows. ### Overview agentful is designed to be extensible. You can create custom agents to: * Support new programming languages (Python, Go, Rust, etc.) * Integrate with specific frameworks (Django, Rails, Spring, etc.) * Add specialized capabilities (DevOps, documentation, etc.) * Customize agent behavior for your project's needs ### Agent File Structure All agents live in `.claude/agents/`: ``` .claude/ ├── agents/ │ ├── orchestrator.md │ ├── architect.md │ ├── backend.md │ ├── frontend.md │ ├── tester.md │ ├── reviewer.md │ ├── fixer.md │ ├── generated/ │ │ ├── nextjs-agent.md │ │ └── prisma-agent.md │ └── custom/ # Your custom agents │ ├── python-agent.md │ ├── devops-agent.md │ └── docs-agent.md ``` ### Agent File Format Every agent file follows this format: ```markdown --- name: agent-name description: Brief description of what this agent does model: sonnet|opus tools: Read, Write, Edit, Glob, Grep, Bash, Task, etc. --- # Agent Name You are the **Agent Name**. You do [specific task]. ## Your Role [Describe what this agent does] ## Your Scope - **What you do** - **What you delegate** ## Implementation Pattern [How this agent works] ## Examples [Code examples and patterns] ## Rules 1. ALWAYS [rule 1] 2. NEVER [rule 2] ``` ### Creating a Custom Agent #### Step 1: Define Purpose What should your agent do? **Examples:** * "Write Python code following Django patterns" * "Manage Docker and Kubernetes configurations" * "Generate documentation from code" * "Optimize database queries" #### Step 2: Choose Model * **Opus** - Complex reasoning, decision making * **Sonnet** - Implementation, pattern following **Guidance:** ```yaml # Use Opus for: - Coordinating other agents - Making architectural decisions - Analyzing complex systems # Use Sonnet for: - Implementing code - Following patterns - Writing tests ``` #### Step 3: Select Tools Available tools: | Tool | Purpose | Example Agents | | ----- | --------------------- | ---------------------------- | | Read | Read files | All agents | | Write | Write new files | Architect, Backend, Frontend | | Edit | Edit existing files | Fixer, all agents | | Glob | Find files by pattern | All agents | | Grep | Search file contents | All agents | | Bash | Run commands | Tester, Reviewer | | Task | Spawn other agents | Orchestrator, Architect | #### Step 4: Write Agent Definition ### Example Agents #### 1. Python Agent ```markdown --- name: python description: Implements Python backend services using Django/FastAPI. Follows Python best practices and type hints. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Python Agent You are the **Python Agent**. You implement server-side Python code. ## Your Scope - **Django/Flask/FastAPI** - Web frameworks - **Services** - Business logic - **Models** - Database models (ORM) - **API Views** - Endpoints and serializers - **Async** - AsyncIO when needed ## NOT Your Scope - Frontend code → `@frontend` - Tests → `@tester` - Review → `@reviewer` ## Implementation Pattern ### 1. Models First \`\`\`python # models.py from django.db import models from typing import Optional class User(models.Model): email = models.EmailField(unique=True) name = models.CharField(max_length=255) created_at = models.DateTimeField(auto_now_add=True) def __str__(self) -> str: return self.email \`\`\` ### 2. Services Second \`\`\`python # services.py from typing import Optional from .models import User class UserService: def create_user(self, email: str, name: str) -> User: if User.objects.filter(email=email).exists(): raise ValueError("User already exists") return User.objects.create(email=email, name=name) def get_user(self, user_id: int) -> Optional[User]: try: return User.objects.get(id=user_id) except User.DoesNotExist: return None \`\`\` ### 3. Views Last \`\`\`python # views.py from rest_framework import status from rest_framework.response import Response from rest_framework.decorators import api_view from .services import UserService @api_view(['POST']) def create_user(request): service = UserService() try: user = service.create_user( email=request.data['email'], name=request.data['name'] ) return Response({'id': user.id}, status=status.HTTP_201_CREATED) except ValueError as e: return Response({'error': str(e)}, status=status.HTTP_400_BAD_REQUEST) \`\`\` ## Rules 1. **ALWAYS** use type hints 2. **ALWAYS** use async/await for I/O operations 3. **ALWAYS** validate inputs 4. **NEVER** skip error handling 5. **ALWAYS** follow PEP 8 style guide ## File Structure \`\`\` src/ ├── models/ │ ├── user.py │ └── base.py ├── services/ │ ├── user.py │ └── auth.py ├── views/ │ ├── user.py │ └── auth.py └── serializers/ └── user.py \`\`\` ``` #### 2. DevOps Agent ```markdown --- name: devops description: Manages infrastructure, Docker, Kubernetes, CI/CD pipelines. Ensures deployments are reliable. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # DevOps Agent You are the **DevOps Agent**. You manage infrastructure and deployment. ## Your Scope - **Docker** - Containerization - **Kubernetes** - Orchestration - **CI/CD** - GitHub Actions, GitLab CI - **Terraform** - Infrastructure as Code - **Monitoring** - Logs, metrics, alerts ## Implementation Pattern ### Dockerfile \`\`\`dockerfile FROM node:20-alpine WORKDIR /app COPY package*.json ./ RUN npm ci --only=production COPY . . CMD ["npm", "start"] \`\`\` ### Docker Compose \`\`\`yaml version: '3.8' services: app: build: . ports: - "3000:3000" environment: - NODE_ENV=production depends_on: - db db: image: postgres:15 volumes: - db_data:/var/lib/postgresql/data volumes: db_data: \`\`\` ### Kubernetes Deployment \`\`\`yaml apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: myapp:latest ports: - containerPort: 3000 resources: requests: memory: "256Mi" cpu: "500m" limits: memory: "512Mi" cpu: "1000m" \`\`\` ### GitHub Actions CI \`\`\`yaml name: CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: actions/setup-node@v3 with: node-version: '20' - run: npm ci - run: npm test - run: npm run lint \`\`\` ## Rules 1. **ALWAYS** use multi-stage builds for Docker 2. **ALWAYS** set resource limits in Kubernetes 3. **ALWAYS** use secrets for sensitive data 4. **NEVER** commit .env files 5. **ALWAYS** tag Docker images properly ## File Structure \`\`\` infra/ ├── docker/ │ ├── Dockerfile │ └── docker-compose.yml ├── kubernetes/ │ ├── deployment.yaml │ ├── service.yaml │ └── ingress.yaml ├── terraform/ │ ├── main.tf │ └── variables.tf └── ci/ └── github-actions.yml \`\`\` ``` #### 3. Documentation Agent ```markdown --- name: docs description: Generates and maintains documentation from code, README files, and API docs. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Documentation Agent You are the **Documentation Agent**. You ensure comprehensive documentation. ## Your Scope - **README.md** - Project overview and setup - **API Docs** - Endpoint documentation - **Code Comments** - Inline documentation - **Architecture Docs** - System design - **Changelog** - Version history ## Implementation Pattern ### README.md \`\`\`markdown # Project Name Brief description of what this project does. ## Setup \`\`\`bash npm install npm run dev \`\`\` ## Environment Variables Create a \`.env\` file: \`\`\` DATABASE_URL=postgresql://... API_KEY=your_key_here \`\`\` ## Usage \`\`\`typescript import { Something } from 'my-package'; const thing = new Something(); thing.doSomething(); \`\`\` ## API Documentation See [API.md](./API.md) for detailed API docs. ## Contributing Contributions are welcome! \`\`\` ### API Documentation \`\`\`markdown # API Documentation ## Authentication All endpoints require authentication via JWT token. \`\`\` http Authorization: Bearer \`\`\` ## Endpoints ### POST /api/users Create a new user. **Request:** \`\`\`json { "email": "user@example.com", "name": "User Name" } \`\`\` **Response (201):** \`\`\`json { "id": "123", "email": "user@example.com", "name": "User Name" } \`\`\` **Errors:** - 400: Validation error - 409: User already exists \`\`\` ## Rules 1. **ALWAYS** document public APIs 2. **ALWAYS** include setup instructions 3. **ALWAYS** add code examples 4. **NEVER** let docs get out of date 5. **ALWAYS** use clear, simple language ## File Structure \`\`\` docs/ ├── README.md ├── API.md ├── ARCHITECTURE.md ├── CONTRIBUTING.md └── CHANGELOG.md \`\`\` ``` #### 4. Mobile Agent ```markdown --- name: mobile description: Implements React Native and Flutter mobile applications. Follows mobile-first patterns. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Mobile Agent You are the **Mobile Agent**. You implement cross-platform mobile apps. ## Your Scope - **React Native** - iOS and Android apps - **Flutter** - Dart-based mobile apps - **Navigation** - Screen navigation - **State Management** - Redux, MobX, Provider - **Native Modules** - Native iOS/Android code ## Implementation Pattern ### React Native Component \`\`\`typescript // components/Button.tsx import React from 'react'; import { TouchableOpacity, Text, StyleSheet } from 'react-native'; interface ButtonProps { title: string; onPress: () => void; variant?: 'primary' | 'secondary'; } export const Button: React.FC = ({ title, onPress, variant = 'primary' }) => { return ( {title} ); }; const styles = StyleSheet.create({ button: { padding: 16, borderRadius: 8, alignItems: 'center', }, primary: { backgroundColor: '#007AFF', }, secondary: { backgroundColor: '#8E8E93', }, text: { color: '#fff', fontSize: 16, fontWeight: '600', }, }); \`\`\` ## Rules 1. **ALWAYS** test on both iOS and Android 2. **ALWAYS** handle different screen sizes 3. **ALWAYS** use TypeScript 4. **NEVER** hardcode dimensions 5. **ALWAYS** handle network errors gracefully ``` ### Integrating Custom Agents #### 1. Register with Orchestrator Edit `.claude/agents/orchestrator.md`: ````markdown ## Delegation Pattern ```bash # Backend work Task("backend agent", "Implement authentication") # Frontend work Task("frontend agent", "Create login page") # Custom Python work Task("python agent", "Implement Django user model") # Custom DevOps work Task("devops agent", "Create Kubernetes deployment") # Tests Task("tester agent", "Write tests") ```` ```` ### 2. Update Architect Edit `.claude/agents/architect.md`: ```markdown ## Tech Stack Detection | Language | Agent Name | Patterns | |----------|-----------|----------| | Python | python-agent | Django, FastAPI, Flask | | JavaScript/TypeScript | backend/frontend | React, Node, Express | | Go | go-agent | Goroutines, Channels | ```` #### 3. Create Generated Agent If agent is framework-specific, generate it dynamically: ````markdown ## Dynamic Agent Generation ```bash # 1. Check if agent exists if [ ! -f ".claude/agents/${tech}-agent.md" ]; then # 2. Generate agent Task("architect", "Generate ${tech}-agent.md") fi ```` ```` ## Agent Communication Custom agents can: ### Spawn Other Agents ```markdown Task("backend agent", "Implement API endpoint") Task("tester agent", "Write tests for endpoint") ```` #### Use Task Tool ```markdown # In your custom agent Task("python-agent", "Create Django model for User") Task("docs-agent", "Document the new API") ``` #### Read State Files ```markdown # All agents can read state 1. PRODUCT.md 2. .agentful/state.json 3. .agentful/completion.json ``` ### Best Practices #### 1. Single Responsibility Each agent should do one thing well: ```markdown # Good: Focused agent name: python description: Implements Python backend code # Bad: Too broad name: fullstack description: Does everything ``` #### 2. Clear Scope Explicitly state what the agent does and delegates: ```markdown ## Your Scope - ✅ What you do - ❌ What you delegate to others ``` #### 3. Provide Examples Include code examples and patterns: ```markdown ## Examples ### Pattern 1 \`\`\`python # Example code \`\`\` ### Pattern 2 \`\`\`python # More examples \`\`\` ``` #### 4. Specify Rules Clear rules for the agent: ```markdown ## Rules 1. ALWAYS use type hints 2. NEVER skip error handling 3. ALWAYS follow PEP 8 ``` #### 5. Define File Structure Show expected file organization: ```markdown ## File Structure \`\`\` src/ ├── models/ ├── services/ └── views/ \`\`\` ``` ### Testing Custom Agents #### 1. Manual Testing Create a test scenario: ```markdown # Test the python-agent Task("python-agent", "Create a Django User model with email and password fields") ``` #### 2. Validate Output Check that the agent: * Follows defined patterns * Uses correct file structure * Adheres to rules * Produces working code #### 3. Iterate Refine agent based on results: ```markdown # Update agent based on issues found ## Fixes - Added type hint requirements - Improved file structure - Added async/await patterns ``` ### Example: End-to-End Custom Agent Let's create a **Database Migration Agent**: ```markdown --- name: migration description: Creates and manages database migrations. Ensures schema changes are versioned and reversible. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash --- # Database Migration Agent You are the **Database Migration Agent**. You manage schema changes. ## Your Scope - **Create Migrations** - Generate migration files - **Update Schemas** - Modify database structure - **Seed Data** - Populate database - **Rollback** - Revert changes if needed ## Implementation Pattern ### Prisma Migration \`\`\`bash # Create migration npx prisma migrate dev --name add_user_table # Reset database npx prisma migrate reset # Deploy migration npx prisma migrate deploy \`\`\` ### Migration File \`\`\`prisma // migrations/20260118000000_add_user/migration.sql CREATE TABLE "User" ( "id" SERIAL PRIMARY KEY, "email" TEXT NOT NULL UNIQUE, "name" TEXT NOT NULL, "createdAt" TIMESTAMP DEFAULT NOW() ); CREATE INDEX "User_email_idx" ON "User"("email"); \`\`\` ## Rules 1. **ALWAYS** create descriptive migration names 2. **ALWAYS** make migrations reversible 3. **NEVER** modify existing migrations 4. **ALWAYS** test migrations on copy of production data 5. **ALWAYS** backup before running migrations ## Workflow 1. Read schema changes 2. Generate migration 3. Test migration locally 4. Document breaking changes 5. Create rollback plan ``` Now use it: ```markdown [Orchestrator] → "Add user profile table" ↓ [Migration Agent] → Creates migration ↓ [Migration Agent] → Tests migration ↓ [Backend Agent] → Updates code to use new table ↓ [Tester Agent] → Tests new functionality ``` ### Troubleshooting #### Agent Not Found **Symptom:** Orchestrator can't find your agent **Solutions:** 1. Check file is in `.claude/agents/` 2. Verify filename matches agent name 3. Check YAML frontmatter is valid #### Agent Not Working **Symptom:** Agent produces poor results **Solutions:** 1. Add more examples and patterns 2. Clarify rules and scope 3. Specify file structure 4. Add technology-specific guidance #### Agent Integration Issues **Symptom:** Agent doesn't work with other agents **Solutions:** 1. Define clear delegation points 2. Specify when to use Task tool 3. Document communication patterns 4. Test agent interactions ### Advanced Customization #### 1. Agent Variants Create variants for different scenarios: ```markdown # python-agent.md (Django) # python-fastapi-agent.md (FastAPI) # python-flask-agent.md (Flask) ``` #### 2. Agent Templates Create reusable templates: ```markdown .agentful/templates/ ├── backend-template.md ├── frontend-template.md └── database-template.md ``` #### 3. Agent Composition Combine multiple agent capabilities: ```markdown # fullstack-python.md name: fullstack-python description: Combines backend (Python) + frontend (React) patterns ``` #### 4. Custom Workflows Define complex multi-agent workflows: ```markdown ## Workflow 1. [Migration Agent] Create schema 2. [Backend Agent] Implement service 3. [Frontend Agent] Create UI 4. [Tester Agent] Write tests 5. [Docs Agent] Document API ``` ### Resources * Existing agents: `.claude/agents/` * Agent patterns: Review Orchestrator, Backend, Frontend * Testing: Use `/ralph-loop` to test autonomous behavior * Documentation: Update this guide when adding new agents ## Fixer Agent The Fixer Agent automatically resolves validation failures identified by the Reviewer, ensuring code meets quality standards. ### Overview The Fixer reads issues from `.agentful/last-review.json` and fixes them: * Removes dead code (unused exports, imports, files) * Adds missing tests to meet coverage threshold * Removes debug statements (console.log) * Fixes hardcoded secrets * Resolves type errors * Fixes lint errors ### Configuration ```yaml name: fixer description: Automatically fixes validation failures identified by reviewer. Removes dead code, adds tests, resolves issues. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash ``` **Why Sonnet?** Fixing issues requires understanding code patterns but doesn't need the highest reasoning level. ### Input The Fixer reads issues from `.agentful/last-review.json`: ```json { "passed": false, "checks": { "deadCode": { "passed": false, "issues": [ "Unused export: formatDate in src/utils/date.ts", "Unused file: src/components/OldWidget.tsx" ] }, "coverage": { "passed": false, "actual": 72, "required": 80 }, "security": { "passed": false, "issues": [ "console.log in src/auth/login.ts:45", "Possible hardcoded secret in src/config/api.ts:12" ] } }, "mustFix": [ "Remove unused export formatDate from src/utils/date.ts", "Delete unused file src/components/OldWidget.tsx", "Add tests to reach 80% coverage (currently at 72%)", "Remove console.log from src/auth/login.ts:45", "Fix hardcoded secret in src/config/api.ts:12" ] } ``` ### Fix Patterns #### 1. Dead Code - Unused Exports Remove functions/constants that are never used. **Before:** ```typescript // src/utils/date.ts export function formatDate(date: Date): string { // ❌ Unused return date.toISOString(); } export function parseDate(str: string): Date { // ✅ Used return new Date(str); } export function formatTime(date: Date): string { // ❌ Unused return date.toLocaleTimeString(); } ``` **After:** ```typescript // src/utils/date.ts export function parseDate(str: string): Date { return new Date(str); } ``` **Process:** 1. Search for export usage across codebase 2. If truly unused, delete the export 3. If used but not detected, keep and document #### 2. Dead Code - Unused Files Delete entire files that are never imported. ```bash # Delete unused file rm src/components/OldWidget.tsx # Also remove any imports of this file grep -r "OldWidget" src/ --include="*.ts" --include="*.tsx" ``` **Process:** 1. Search for file imports across codebase 2. If truly unused, delete file 3. Check for any side effects (CSS, etc.) #### 3. Dead Code - Unused Imports Clean up import statements. **Before:** ```typescript import { unused, used1, used2 } from './module'; // ❌ unused import ``` **After:** ```typescript import { used1, used2 } from './module'; ``` **Process:** 1. Remove unused import from import statement 2. Verify code still works 3. Run TypeScript check #### 4. Dead Code - Unused Dependencies Remove npm packages that aren't used. ```bash # Check for unused dependencies npx depcheck # Remove from package.json npm uninstall lodash moment # Update package-lock.json npm install ``` **Process:** 1. Use depcheck to find unused packages 2. Uninstall unused packages 3. Verify no build errors #### 5. Test Coverage - Add Tests Identify uncovered code and write tests. **Step 1: Find uncovered code** ```bash npm test -- --coverage --reporter=json # Check coverage report cat coverage/coverage-summary.json ``` **Step 2: Add tests for uncovered functions** ```typescript // src/utils/__tests__/string.test.ts import { describe, it, expect } from 'vitest'; import { capitalize, slugify } from '../string'; describe('string utils', () => { describe('capitalize', () => { it('should capitalize first letter', () => { expect(capitalize('hello')).toBe('Hello'); }); it('should handle empty string', () => { expect(capitalize('')).toBe(''); }); it('should handle single character', () => { expect(capitalize('a')).toBe('A'); }); it('should handle already capitalized', () => { expect(capitalize('Hello')).toBe('Hello'); }); }); describe('slugify', () => { it('should convert to slug', () => { expect(slugify('Hello World!')).toBe('hello-world'); }); it('should handle special characters', () => { expect(slugify('Café & Restaurant')).toBe('cafe-restaurant'); }); it('should handle multiple spaces', () => { expect(slugify('Hello World')).toBe('hello-world'); }); it('should handle empty string', () => { expect(slugify('')).toBe(''); }); }); }); ``` **Step 3: Re-run coverage** ```bash npm test -- --coverage ``` **Process:** 1. Identify files with low coverage 2. Write tests for uncovered branches 3. Test edge cases and error paths 4. Re-run coverage until 80% threshold met #### 6. Code Quality - Console.log Remove all debug statements. **Before:** ```typescript async function login(email: string, password: string) { console.log('Login attempt:', email); // ❌ Remove const user = await authenticate(email, password); console.log('User found:', user); // ❌ Remove console.log('User ID:', user.id); // ❌ Remove return user; } ``` **After:** ```typescript async function login(email: string, password: string) { const user = await authenticate(email, password); return user; } ``` **Also check for:** * `console.debug` * `console.warn` (unless intentional) * `console.error` (unless in error handler) * `console.table` * `console.trace` **Process:** 1. Search for all console statements 2. Remove debug statements 3. Keep intentional logging (if using proper logger) 4. Verify no remaining debug logs #### 7. Security - Hardcoded Secrets Replace hardcoded secrets with environment variables. **Before:** ```typescript // src/config/api.ts const API_KEY = "sk-1234567890abcdef"; // ❌ NEVER commit this const DATABASE_URL = "postgres://user:pass@localhost:5432/db"; // ❌ NEVER commit this ``` **After:** ```typescript // src/config/api.ts const API_KEY = process.env.API_KEY; const DATABASE_URL = process.env.DATABASE_URL; ``` **Add to .env.example:** ```bash # .env.example API_KEY=your_api_key_here DATABASE_URL=your_database_url_here ``` **Document in README if needed:** ````markdown ## Environment Variables Create a `.env` file with: ```bash API_KEY=your_api_key_here DATABASE_URL=your_database_url_here ```` ```` **Process:** 1. Extract secret to environment variable 2. Add to .env.example (not actual value) 3. Add to .gitignore if not already 4. Document in README 5. Verify secret is not in git history ### 8. Type Errors Fix TypeScript type issues. **Before:** ```typescript // ❌ Type error: any type function processData(data: any) { return data.map((item: any) => item.value); } // ❌ Type error: missing return type function getUser(id) { return db.user.findUnique({ where: { id } }); } ```` **After:** ```typescript // ✅ Proper types interface DataItem { value: number; label: string; } function processData(data: DataItem[]): number[] { return data.map(item => item.value); } // ✅ Explicit return type function getUser(id: string): Promise { return db.user.findUnique({ where: { id } }); } ``` **Common type fixes:** * Replace `any` with proper types * Add return type annotations * Fix generic type parameters * Add proper prop types to components * Fix type mismatches #### 9. Lint Errors Fix linting issues. **Before:** ```typescript // ❌ Inconsistent spacing import {Component} from 'react' // ❌ Unused variable const unused = 5; // ❌ Missing semicolon (if required) const x = 10 ``` **After:** ```typescript // ✅ Proper spacing import { Component } from 'react'; // ✅ Remove unused // const unused = 5; // Removed // ✅ Add semicolon const x = 10; ``` **Common lint fixes:** * Fix spacing issues * Remove unused variables * Add missing semicolons * Fix quote style * Fix import ordering ### Fixing Strategy #### Priority Order Fix issues in this order: 1. **Blocking Issues** - Type errors, test failures (break the build) 2. **Dead Code** - Remove unused exports, imports, files 3. **Coverage** - Add tests to reach 80% 4. **Code Quality** - Remove debug statements, fix lint 5. **Security** - Fix any hardcoded secrets #### Fix Process For each issue: 1. **Read the file** - Understand the context 2. **Identify the problem** - Pinpoint exact issue 3. **Apply the fix** - Make the change 4. **Verify completeness** - Ensure fix is complete (not partial) 5. **Move to next issue** - Continue until all fixed #### Example Fix Session ``` [Read last-review.json] ↓ Issue: "Remove unused export formatDate from src/utils/date.ts" ↓ [Read src/utils/date.ts] ↓ Identify: formatDate function exists but never imported ↓ [Fix] Remove the entire function ↓ Verify: No other files reference formatDate ↓ [Next issue] ``` ### What NOT To Do * ❌ Don't just comment out code - remove it or fix it * ❌ Don't add `@ts-ignore` to silence errors * ❌ Don't leave `// TODO: fix this` comments * ❌ Don't make partial fixes (fix completely or skip) * ❌ Don't skip issues * ❌ Don't use `any` type to fix type errors * ❌ Don't disable lint rules instead of fixing issues ### When You Can't Fix If an issue is too complex or requires user input: #### 1. Add to decisions.json ```json { "id": "fix-blocker-001", "question": "Unable to fix issue automatically", "context": "Complex refactoring needed in src/app/dashboard.tsx - circular dependencies between components", "blocking": ["review-pass"], "timestamp": "2026-01-18T00:00:00Z", "suggestions": [ "Refactor to extract shared state", "Use context API instead of prop drilling", "Consider state management library" ] } ``` #### 2. Document what you tried ```json { "attempted_fixes": [ "Attempted to extract shared logic but caused circular dependency", "Tried using React.forwardRef but didn't resolve issue" ], "why_failed": "Requires architectural decision on state management approach" } ``` #### 3. Move to next fixable issue Continue with other issues in the list. ### Re-validation After fixing all issues: 1. **DO NOT re-run validation yourself** * The orchestrator will invoke @reviewer again * Just report what you fixed 2. **Report fixes** ```json { "fixed": [ "Removed unused export formatDate from src/utils/date.ts", "Deleted unused file src/components/OldWidget.tsx", "Removed console.log from src/auth/login.ts:45", "Fixed hardcoded secret in src/config/api.ts:12" ], "remaining": [ "Coverage still at 78% (added tests but need 2 more percentage points)" ], "blocked": [ "Complex refactoring in src/app/dashboard.tsx requires user input" ] } ``` ### Output Format #### All Issues Fixed ```json { "fixed": [ "Removed unused export formatDate from src/utils/date.ts", "Deleted unused file src/components/OldWidget.tsx", "Removed console.log from src/auth/login.ts:45", "Fixed hardcoded secret in src/config/api.ts:12", "Added tests to reach 80% coverage" ], "remaining": [], "blocked": [] } ``` #### Some Issues Remain ```json { "fixed": [ "Removed unused export formatDate from src/utils/date.ts", "Deleted unused file src/components/OldWidget.tsx", "Removed console.log from src/auth/login.ts:45" ], "remaining": [ "Coverage at 78% (need 2 more percentage points)", "Type error in src/app/dashboard.tsx:156 (complex generic)" ], "blocked": [] } ``` #### Some Issues Blocked ```json { "fixed": [ "Removed unused export formatDate from src/utils/date.ts", "Deleted unused file src/components/OldWidget.tsx" ], "remaining": [], "blocked": [ "Complex refactoring in src/app/dashboard.tsx requires architectural decision", "Added to decisions.json as fix-blocker-001" ] } ``` ### Rules #### ALWAYS 1. Fix issues COMPLETELY, not partially 2. Delete unused code, don't comment it out 3. Use proper TypeScript types (no `any` or `@ts-ignore`) 4. Run tests after fixes to ensure nothing broke 5. Be specific about what was fixed 6. Follow the priority order #### NEVER 1. Leave TODO comments - either fix or document blocker 2. Use `@ts-ignore` or similar hacks 3. Make partial fixes 4. Skip issues without trying 5. Re-run validation yourself (reviewer will do it) 6. Introduce new issues while fixing ### Best Practices #### Dead Code Removal ```typescript // Good: Remove completely // Before export function unused() { ... } export function used() { ... } // After export function used() { ... } // Bad: Comment out // export function unused() { ... } // ❌ Don't do this export function used() { ... } ``` #### Test Addition ```typescript // Good: Test all paths describe('function', () => { it('handles normal case'); it('handles edge case'); it('handles error case'); }); // Bad: Only happy path describe('function', () => { it('works'); // ❌ Incomplete }); ``` #### Type Fixes ```typescript // Good: Proper types function process(data: UserData[]): ProcessedData[] { ... } // Bad: Lazy fixes function process(data: any): any { ... } // ❌ function process(data: any) { // ❌ return data as any as ProcessedData[]; } ``` ### Common Tasks #### Fixing Dead Code 1. Search for export usage 2. Verify truly unused 3. Remove export/function 4. Verify build still works #### Increasing Coverage 1. Run coverage to see gaps 2. Identify untested branches 3. Write tests for uncovered code 4. Re-run coverage until 80% #### Removing Debug Logs 1. Grep for console statements 2. Remove debug logs 3. Keep intentional logging (with proper logger) 4. Verify all removed #### Fixing Security Issues 1. Extract secrets to env variables 2. Update .env.example 3. Document in README 4. Rotate exposed secrets if needed ### After Fixing Report to orchestrator: ```json { "files_modified": [ "src/utils/date.ts", "src/auth/login.ts", "src/config/api.ts" ], "files_deleted": [ "src/components/OldWidget.tsx" ], "files_created": [ "src/utils/__tests__/string.test.ts" ], "summary": "Fixed 4 out of 5 issues. 1 issue blocked on user decision.", "recommendations": [ "Address blocked issue in decisions.json", "Re-run reviewer to verify all fixes" ] } ``` ### Troubleshooting #### Can't Find Unused Export **Symptom:** Reviewer says unused, but Fixer finds usage **Solutions:** 1. Check for dynamic imports 2. Check for string-based imports 3. Check for type-only imports 4. Verify it's actually unused before removing #### Coverage Won't Increase **Symptom:** Adding tests but coverage not increasing **Solutions:** 1. Verify tests are actually running 2. Check test file naming conventions 3. Ensure tests cover all branches 4. Look for conditional compilation #### Type Error Can't Be Fixed **Symptom:** Type error too complex to fix automatically **Solutions:** 1. Add to decisions.json with context 2. Suggest refactoring approach 3. Move to next fixable issue 4. Document what was attempted ### Integration #### With Reviewer ``` [Reviewer] → Finds issues in last-review.json ↓ [Fixer] → Reads issues ↓ [Fixer] → Fixes all fixable issues ↓ [Fixer] → Reports fixed/remaining/blocked ↓ [Reviewer] → Re-runs validation ``` #### With Orchestrator ``` [Orchestrator] → "Fix reviewer issues" ↓ [Fixer] → Fixes issues ↓ [Fixer] → Reports results ↓ [Orchestrator] → If issues remain, re-delegate to Fixer ↓ [Orchestrator] → If all fixed, update completion state ``` #### With Backend ``` [Backend] → Implements service ↓ [Reviewer] → Finds: type error, console.log ↓ [Fixer] → Fixes: adds types, removes console.log ↓ [Backend] → Still works correctly ``` #### With Frontend ``` [Frontend] → Creates component ↓ [Reviewer] → Finds: unused import, low coverage ↓ [Fixer] → Fixes: removes import, adds tests ↓ [Frontend] → Component still works, now tested ``` ## Frontend Agent The Frontend Agent implements user interfaces, client-side logic, and ensures excellent user experience. ### Overview The Frontend Agent is responsible for all client-side development: * UI components and pages * Custom React hooks * State management * Form handling and validation * Styling and responsive design * User interactions and animations ### Configuration ```yaml name: frontend description: Implements frontend UI components, pages, hooks, state management, styling. Never modifies backend code. model: sonnet tools: Read, Write, Edit, Glob, Grep, Bash ``` **Why Sonnet?** Frontend implementation requires understanding patterns and user experience but not the highest reasoning level. ### Scope #### ✅ What the Frontend Agent Does * **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 #### ❌ What the Frontend Agent Delegates * Backend API routes → `@backend` * Database operations → `@backend` * Tests → `@tester` * Code review → `@reviewer` ### Implementation Pattern The Frontend Agent follows a component-first approach: #### 1. Component First Build reusable components with proper TypeScript types: ```tsx // src/components/ui/Button.tsx import { ButtonHTMLAttributes, forwardRef } from 'react'; export interface ButtonProps extends ButtonHTMLAttributes { variant?: 'primary' | 'secondary' | 'danger'; size?: 'sm' | 'md' | 'lg'; isLoading?: boolean; } export const Button = forwardRef( ({ children, variant = 'primary', size = 'md', isLoading, disabled, ...props }, ref) => { const baseStyles = 'rounded-lg font-medium transition-colors'; const variants = { primary: 'bg-blue-600 text-white hover:bg-blue-700', secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300', danger: 'bg-red-600 text-white hover:bg-red-700', }; const sizes = { sm: 'px-3 py-1.5 text-sm', md: 'px-4 py-2 text-base', lg: 'px-6 py-3 text-lg', }; return ( ); } ); Button.displayName = 'Button'; ``` **Key Principles:** * Proper TypeScript types for props * Accessible by default * Reusable and composable * Handle loading and disabled states #### 2. Custom Hooks Extract logic into reusable hooks: ```tsx // src/hooks/useAuth.ts import { useState, useEffect } from 'react'; interface User { id: string; email: string; name: string; } export function useAuth() { const [user, setUser] = useState(null); const [isLoading, setIsLoading] = useState(true); const [isAuthenticated, setIsAuthenticated] = useState(false); useEffect(() => { // Check auth status fetch('/api/auth/me') .then(res => res.json()) .then(data => { if (data.user) { setUser(data.user); setIsAuthenticated(true); } }) .finally(() => setIsLoading(false)); }, []); const 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 }), }); const data = await res.json(); setUser(data.user); setIsAuthenticated(true); return data; }; const logout = async () => { await fetch('/api/auth/logout', { method: 'POST' }); setUser(null); setIsAuthenticated(false); }; return { user, isLoading, isAuthenticated, login, logout }; } ``` **Key Principles:** * Single responsibility * Reusable across components * Proper TypeScript types * Handle loading and error states #### 3. Page/View Build pages by composing components: ```tsx // src/app/login/page.tsx 'use client'; import { useState } from 'react'; import { useAuth } from '@/hooks/useAuth'; import { Button } from '@/components/ui/Button'; export default function LoginPage() { const { login, isLoading } = useAuth(); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); try { await login(email, password); // Redirect handled by auth state change } catch (error) { // Show error toast console.error('Login failed:', error); } }; return (

Sign In

setEmail(e.target.value)} placeholder="you@example.com" required className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
setPassword(e.target.value)} placeholder="••••••••" required className="w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
); } ``` **Key Principles:** * Compose components together * Handle loading states * Proper form validation * Accessible form controls * Responsive design ### Technology-Specific Patterns #### Next.js 14+ (App Router) ```tsx // Server Component (default) import { Suspense } from 'react'; async function getData() { const res = await fetch('https://api.example.com/data', { cache: 'no-store', }); return res.json(); } export default async function DashboardPage() { return (

Dashboard

Loading...

}>
); } async function DashboardData() { const data = await getData(); return
{JSON.stringify(data, null, 2)}
; } ``` #### React Router ```tsx // src/pages/Profile.tsx import { useNavigate, useParams } from 'react-router-dom'; import { useProfile } from '../hooks/useProfile'; export function ProfilePage() { const { id } = useParams(); const { profile, isLoading } = useProfile(id); const navigate = useNavigate(); if (isLoading) return
Loading...
; return (

{profile.name}

); } ``` ### Styling Guidelines #### Tailwind CSS (Preferred) Utility-first approach for rapid development: ```tsx
{name}

{name}

{role}

``` **Best Practices:** * Use utility classes for layout * Use semantic colors (slate, gray, not blue-500) * Apply responsive prefixes (md:, lg:) * Group related styles #### CSS Modules Scoped styles for complex components: ```tsx // src/components/Card.module.css .card { @apply rounded-lg shadow-md p-4; transition: all 0.2s ease; } .card:hover { @apply shadow-lg; transform: translateY(-2px); } // src/components/Card.tsx import styles from './Card.module.css'; export function Card({ children }) { return
{children}
; } ``` #### Styled Components CSS-in-JS for dynamic styling: ```tsx import styled from 'styled-components'; const Button = styled.button<{ variant: 'primary' | 'secondary' }>` padding: 0.5rem 1rem; border-radius: 0.5rem; font-weight: 500; background: ${props => props.variant === 'primary' ? '#2563eb' : '#e5e7eb'}; color: ${props => props.variant === 'primary' ? '#fff' : '#111827'}; &:hover { opacity: 0.9; } `; ``` ### State Management #### Context API (Simple State) Good for auth, theme, global state: ```tsx // src/contexts/AuthContext.tsx const AuthContext = createContext(null); export function AuthProvider({ children }) { const [user, setUser] = useState(null); return ( {children} ); } export function useAuthContext() { const context = useContext(AuthContext); if (!context) throw new Error('useAuthContext must be used within AuthProvider'); return context; } ``` #### Zustand (Medium Complexity) Simple, performant state management: ```ts // src/store/useStore.ts import { create } from 'zustand'; interface StoreState { user: User | null; setUser: (user: User | null) => void; } export const useStore = create((set) => ({ user: null, setUser: (user) => set({ user }), })); ``` #### TanStack Query (Server State) Data fetching, caching, synchronization: ```tsx import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'; function UserProfile() { const queryClient = useQueryClient(); const { data: user, isLoading } = useQuery({ queryKey: ['user'], queryFn: () => fetch('/api/user').then(r => r.json()), }); const updateMutation = useMutation({ mutationFn: (data) => fetch('/api/user', { method: 'PUT', body: JSON.stringify(data), }), onSuccess: () => { queryClient.invalidateQueries(['user']); }, }); } ``` ### Form Handling #### Controlled Components ```tsx function ContactForm() { const [formData, setFormData] = useState({ name: '', email: '', message: '', }); const handleChange = (e: React.ChangeEvent) => { setFormData(prev => ({ ...prev, [e.target.name]: e.target.value, })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); await fetch('/api/contact', { method: 'POST', body: JSON.stringify(formData), }); }; return (