├── .carrot-test └── compliance │ ├── audit │ └── hznwtt.json │ └── results │ └── ui-ihdpro-2025-05-28T19-41-25-221Z.json ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── SUMMARY.md ├── Support └── Claude │ └── claude_desktop_config.json ├── carrot-spec.json ├── docs ├── compliance-storage-and-ast.md ├── quick-start.md ├── spec-compliance-checking.md ├── spec-compliance-expansion-plan.md ├── technical-approach.md └── troubleshooting.md ├── examples ├── api-compliance-demo.md ├── cli-tool-development.md ├── db-schema-evolution.md ├── full-stack-demo.md ├── spec-compliance-demo.md ├── ui-compliance-demo.md └── ui-component-workflow.md ├── package-lock.json ├── package.json ├── src ├── prompts │ ├── draft_pr.ts │ ├── explain_file.ts │ ├── index.ts │ └── review_diff.ts ├── resources │ ├── docs.ts │ ├── file.ts │ ├── index.ts │ ├── spec.ts │ └── todo.ts ├── server.ts ├── tools │ ├── add_route.ts │ ├── check_spec_compliance.ts │ ├── check_spec_compliance_universal.ts │ ├── commit_changes.ts │ ├── compliance │ │ ├── ast-analyzer.ts │ │ ├── base.ts │ │ ├── cli-checker.ts │ │ ├── db-checker.ts │ │ ├── index.ts │ │ ├── storage.ts │ │ └── ui-checker.ts │ ├── format_code.ts │ ├── grow_cli_spec.ts │ ├── grow_db_spec.ts │ ├── grow_spec.ts │ ├── grow_ui_spec.ts │ ├── index.ts │ ├── run_tests.ts │ ├── search_code.ts │ └── setup_carrot.ts └── utils │ ├── path.ts │ └── rate_limiter.ts ├── tests └── development │ ├── debug-mcp.js │ ├── direct-spec.js │ ├── reset-specs.js │ ├── restart-cursor.sh │ ├── simpleStreamableHttp.js │ ├── test-cli-implementation.js │ ├── test-cli-tools.js │ ├── test-cli-universal.js │ └── test-enhanced-tools.md └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | node_modules/ 3 | jspm_packages/ 4 | 5 | # Build outputs 6 | dist/ 7 | build/ 8 | *.tgz 9 | 10 | # Environment files 11 | .env 12 | .env.local 13 | .env.development.local 14 | .env.test.local 15 | .env.production.local 16 | .env.development 17 | .env.test 18 | .env.production 19 | 20 | # Logs 21 | logs/ 22 | *.log 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | lerna-debug.log* 27 | .pnpm-debug.log* 28 | 29 | # Runtime data 30 | pids 31 | *.pid 32 | *.seed 33 | *.pid.lock 34 | 35 | # Test coverage 36 | coverage/ 37 | *.lcov 38 | .nyc_output/ 39 | 40 | # IDE and editor files 41 | .vscode/ 42 | .idea/ 43 | *.swp 44 | *.swo 45 | *~ 46 | 47 | # OS files 48 | .DS_Store 49 | Thumbs.db 50 | 51 | # Cache files 52 | .cache/ 53 | .parcel-cache/ 54 | .eslintcache 55 | .rpt2_cache/ 56 | .rts2_cache_cjs/ 57 | .rts2_cache_es/ 58 | .rts2_cache_umd/ 59 | 60 | # Optional npm cache directory 61 | .npm 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Yarn 67 | .yarn-integrity 68 | .yarn/cache 69 | .yarn/unplugged 70 | .yarn/build-state.yml 71 | .yarn/install-state.gz 72 | .pnp.* 73 | 74 | # Project specific 75 | weather/ 76 | specs/ 77 | carrot-spec.json 78 | 79 | # Temporary files 80 | *.tmp 81 | *.temp 82 | .tmp/ 83 | .temp/ 84 | 85 | # Development test files (kept in tests/development) 86 | # but not ignored so they can be referenced -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | **talvinder27@gmail.com**. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.1, available at 119 | [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 | 121 | For answers to common questions about this code of conduct, see the FAQ at 122 | [https://www.contributor-covenant.org/faq][faq]. Translations are available at 123 | [https://www.contributor-covenant.org/translations][translations]. 124 | 125 | [homepage]: https://www.contributor-covenant.org 126 | [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 127 | [faq]: https://www.contributor-covenant.org/faq 128 | [translations]: https://www.contributor-covenant.org/translations 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Carrot AI PM - MCP Server 2 | 3 | First off, thank you for considering contributing to the Carrot AI PM - MCP Server! We're excited to have your help in building a powerful tool for AI-assisted software development. This project is in its early stages, and every contribution, big or small, is highly valued. 4 | 5 | This document provides guidelines for contributing to this project. Please feel free to propose changes to this document in a pull request. 6 | 7 | ## Table of Contents 8 | 9 | - [Code of Conduct](#code-of-conduct) 10 | - [How Can I Contribute?](#how-can-i-contribute) 11 | - [Reporting Bugs](#reporting-bugs) 12 | - [Suggesting Enhancements](#suggesting-enhancements) 13 | - [Your First Code Contribution](#your-first-code-contribution) 14 | - [Pull Requests](#pull-requests) 15 | - [Development Setup](#development-setup) 16 | - [Prerequisites](#prerequisites) 17 | - [Installation](#installation) 18 | - [Running the Server for Development](#running-the-server-for-development) 19 | - [Styleguides](#styleguides) 20 | - [Git Commit Messages](#git-commit-messages) 21 | - [TypeScript Styleguide](#typescript-styleguide) 22 | - [Code Formatting](#code-formatting) 23 | - [Testing](#testing) 24 | - [Questions?](#questions) 25 | 26 | ## Code of Conduct 27 | 28 | This project and everyone participating in it is governed by the [Carrot AI PM Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to talvinder27@gmail.com. 29 | 30 | 31 | ## How Can I Contribute? 32 | 33 | ### Reporting Bugs 34 | 35 | If you encounter a bug, please help us by reporting it! 36 | 37 | - **Check existing issues:** Before creating a new issue, please check if the bug has already been reported in the [GitHub Issues](https://github.com/talvinder/carrot-ai-pm/issues). 38 | - **Create a new issue:** If it's a new bug, please open an issue. Be sure to include: 39 | - A clear and descriptive title. 40 | - Steps to reproduce the bug. 41 | - What you expected to happen. 42 | - What actually happened. 43 | - Your environment (OS, Node.js version, client used if applicable). 44 | - Any relevant logs or screenshots. 45 | 46 | ### Suggesting Enhancements 47 | 48 | We love to hear your ideas for improving the Carrot AI PM - MCP Server! 49 | 50 | - **Check existing issues/discussions:** Your idea might already be under discussion. 51 | - **Create a new issue:** If it's a new idea, please open an issue with the "enhancement" label. Describe: 52 | - The problem your enhancement solves. 53 | - A clear description of the suggested enhancement. 54 | - Any alternative solutions or features you've considered. 55 | - If you're interested in implementing it yourself! 56 | - For larger ideas, like the `grow_spec` expansion outlined in the README, feel free to start a discussion or detailed proposal. 57 | 58 | ### Your First Code Contribution 59 | 60 | Unsure where to begin? 61 | - Look for issues tagged `good first issue` or `help wanted`. 62 | - Feel free to ask on an existing issue if you can take it on. 63 | - Start with smaller changes to get familiar with the codebase. 64 | 65 | ### Pull Requests 66 | 67 | We use Pull Requests (PRs) for all code changes. 68 | 69 | 1. **Fork the repository** and create your branch from `main` (or the relevant development branch). 70 | - Branch naming convention: `feature/your-feature-name` or `fix/bug-description`. 71 | 2. **Make your changes** locally. 72 | 3. **Ensure your code lints and formats correctly:** Run `npm run format`. 73 | 4. **Add tests** for any new functionality or bug fixes. Ensure all tests pass: `npm run test`. 74 | 5. **Commit your changes** using a descriptive commit message (see [Git Commit Messages](#git-commit-messages)). 75 | 6. **Push your branch** to your fork. 76 | 7. **Open a Pull Request** against the `main` branch of the `talvinder/carrot-ai-pm` repository. 77 | - Provide a clear title and description for your PR. 78 | - Link to any relevant issues (e.g., "Closes #123"). 79 | - Explain the changes you've made and why. 80 | - Be prepared for a code review and be responsive to feedback. 81 | 82 | ## Development Setup 83 | 84 | ### Prerequisites 85 | 86 | - Node.js (v18+ recommended) 87 | - npm (comes with Node.js) 88 | - Git 89 | - Python (v3.8+ for tools that interact with Python projects) 90 | - `ripgrep` (for the `search_code` tool) 91 | 92 | ### Installation 93 | 94 | 1. Fork the repository: `https://github.com/talvinder/carrot-ai-pm.git` 95 | 2. Clone your fork: `git clone https://github.com/talvinder/carrot-ai-pm.git` 96 | 3. Navigate to the project directory: `cd carrot-ai-pm` 97 | 4. Install dependencies: `npm install` 98 | 99 | ### Running the Server for Development 100 | 101 | For local development with auto-rebuild on file changes: 102 | 103 | 1. In one terminal, start the TypeScript watcher and builder: 104 | ```bash 105 | npm run watch 106 | ``` 107 | 2. In another terminal, run the development server (which uses the output from the watch command): 108 | ```bash 109 | npm run dev 110 | ``` 111 | This will typically run the server in stdio mode. To test HTTP/SSE mode, you can set the `PORT` environment variable: 112 | ```bash 113 | PORT=3000 npm run dev 114 | ``` 115 | 116 | ## Styleguides 117 | 118 | ### Git Commit Messages 119 | 120 | We follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. This helps with automated changelog generation and makes the commit history easier to read. 121 | 122 | Examples: 123 | - `feat: Add SSE transport for remote clients` 124 | - `fix: Correctly handle empty path array in format_code tool` 125 | - `docs: Update README with new configuration options` 126 | - `style: Apply Prettier formatting to server.ts` 127 | - `refactor: Improve error handling in add_route tool` 128 | - `test: Add unit tests for spec generation logic` 129 | - `chore: Update npm dependencies` 130 | 131 | ### TypeScript Styleguide 132 | 133 | - Follow standard TypeScript best practices. 134 | - Use `ESLint` and `Prettier` for code linting and formatting (configured in the project). 135 | - Prioritize readability and clarity. 136 | - Use descriptive variable and function names. 137 | - Comment complex logic where necessary. 138 | 139 | ### Code Formatting 140 | 141 | We use Prettier and ESLint to enforce consistent code style. Before committing, please run: 142 | ```bash 143 | npm run format 144 | ``` 145 | This will automatically format your code according to the project's standards. Many IDEs can be configured to run this on save. 146 | 147 | ## Testing 148 | 149 | We aim for good test coverage. 150 | - Write unit tests for new functions and modules. 151 | - Write integration tests for tool interactions where appropriate. 152 | - Ensure all tests pass before submitting a PR. 153 | 154 | Run tests using: 155 | ```bash 156 | npm run test 157 | ``` 158 | *(This command might be configured to run Jest/Vitest for TypeScript code and potentially invoke Python tests for tools that wrap Python utilities.)* 159 | 160 | ## Questions? 161 | 162 | If you have any questions, feel free to: 163 | - Open an issue on GitHub. 164 | - Start a discussion in the GitHub Discussions tab. 165 | 166 | Thank you for contributing! Your efforts help make Carrot AI PM better. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Carrot AI PM Contributors 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🥕 Carrot AI PM - Spec-Driven Development for AI Coding 2 | 3 | [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) 4 | [![Contributions Welcome](https://img.shields.io/badge/Contributions-Welcome-brightgreen.svg?style=flat)](CONTRIBUTING.md) 5 | [![MCP Compatible](https://img.shields.io/badge/MCP-Compatible-blue.svg)](https://modelcontextprotocol.io) 6 | 7 | Carrot generates specs, validates output, and keeps AI assistants aligned. 8 | ---- 9 | 10 | **Carrot AI PM** helps developers use AI coding assistants (like Claude, Cursor, and GitHub Copilot) more confidently by ensuring the code they generate matches your specifications. Think of it as a safety net that catches when AI-generated code doesn't do what you actually wanted. 11 | 12 | ### Why "Carrot"? 13 | Carrot guides, entices, and keeps AI assistants aligned — much like how gherkin guides human-readable specs. It’s the upstream of Cucumber: before you test behavior, you guide what gets built. 14 | 15 | Carrot is a natural evolution in the garden of developer tools — from testing what was written (Cucumber) to guiding what gets written (Carrot). 16 | 17 | ## 🤔 The Problem 18 | 19 | When using AI to write code, you might ask: 20 | - "Create a user login API" 21 | - "Build a product card component" 22 | - "Set up a database for my e-commerce site" 23 | 24 | But how do you know if the AI understood correctly? How can you be sure the generated code: 25 | - Has proper error handling? 26 | - Includes all the features you need? 27 | - Follows security best practices? 28 | - Works with your existing code? 29 | 30 | ## 💡 How Carrot AI PM Helps 31 | 32 | Carrot AI PM acts as your AI coding assistant's "project manager". It: 33 | 34 | 1. **Creates clear specifications** before coding starts 35 | 2. **Checks if the code matches** what was specified 36 | 3. **Suggests specific fixes** when something's wrong 37 | 4. **Gives you confidence** that AI-generated code is correct 38 | 39 | ## 🎯 Real-World Example 40 | 41 | Instead of just asking your AI to "create a user API", you can: 42 | 43 | 1. **You say:** "Create a specification for a user management API with login and registration" 44 | 45 | 2. **Carrot creates** a detailed spec with: 46 | - Required endpoints (POST /login, POST /register) 47 | - Security requirements (password hashing, JWT tokens) 48 | - Validation rules (email format, password strength) 49 | - Error responses (409 for duplicate email, 401 for bad login) 50 | 51 | 3. **You say:** "Now implement this user API" 52 | 53 | 4. **AI writes the code** based on the clear specification 54 | 55 | 5. **You say:** "Check if this implementation is correct" 56 | 57 | 6. **Carrot validates** and reports: 58 | ``` 59 | ✅ Endpoints implemented correctly 60 | ✅ Password hashing in place 61 | ⚠️ Missing rate limiting on login 62 | ❌ No email validation on registration 63 | 64 | Suggested fix: Add email validation using... 65 | ``` 66 | 67 | ## 🚀 Getting Started 68 | 69 | ### Prerequisites 70 | 71 | - Node.js 18+ installed 72 | - An AI coding assistant (Cursor, Claude Desktop, etc.) 73 | - 5 minutes to set up 74 | 75 | ### Quick Setup 76 | 77 | 1. **Clone and install:** 78 | ```bash 79 | git clone https://github.com/talvinder/carrot-ai-pm.git 80 | cd carrot-ai-pm 81 | npm install 82 | npm run build 83 | ``` 84 | 85 | 2. **Configure your AI assistant** (example for Cursor): 86 | 87 | Edit `.cursor/mcp.json` in your project: 88 | ```json 89 | { 90 | "mcpServers": { 91 | "carrot-pm": { 92 | "command": "node", 93 | "args": ["/path/to/carrot-ai-pm/dist/src/server.js"], 94 | "env": { 95 | "CARROT_PROJECT_ROOT": "/path/to/your/project" 96 | } 97 | } 98 | } 99 | } 100 | ``` 101 | 102 | 3. **Start using natural language!** 103 | 104 | ## 📝 How to Use (No Code Required!) 105 | 106 | Just talk to your AI assistant naturally: 107 | 108 | ### Creating Specifications 109 | 110 | **You:** "Create a spec for a product listing API that supports search and filtering" 111 | 112 | **You:** "Generate a specification for a React shopping cart component" 113 | 114 | **You:** "I need a database schema for storing user orders and payments" 115 | 116 | **You:** "Create a CLI tool spec for deploying my application" 117 | 118 | ### Implementing Code 119 | 120 | **You:** "Implement the product API based on the specification" 121 | 122 | **You:** "Build the shopping cart component following the spec" 123 | 124 | **You:** "Create the database tables according to the schema" 125 | 126 | ### Checking Your Work 127 | 128 | **You:** "Check if my product API implementation matches the spec" 129 | 130 | **You:** "Validate the shopping cart component" 131 | 132 | **You:** "Is my database schema compliant with what we specified?" 133 | 134 | ### Getting Help 135 | 136 | **You:** "What's wrong with my implementation?" 137 | 138 | **You:** "How do I fix the compliance issues?" 139 | 140 | **You:** "Show me what's missing from my code" 141 | 142 | ## 🛠️ What Carrot Can Do 143 | 144 | ### 📋 Create Specifications For: 145 | - **APIs** - REST endpoints with all the details 146 | - **UI Components** - React/Vue/Angular components 147 | - **Databases** - Tables, relationships, constraints 148 | - **CLI Tools** - Commands, options, help text 149 | - **And more** - Any code artifact you can describe 150 | 151 | ### ✅ Validate That Your Code Has: 152 | - **Correct structure** - All required parts are present 153 | - **Proper validation** - Input checking and error handling 154 | - **Security measures** - Authentication, authorization, sanitization 155 | - **Best practices** - Performance, accessibility, maintainability 156 | - **Documentation** - Comments, types, examples 157 | 158 | ### 🔧 Help You Fix Issues With: 159 | - **Specific suggestions** - Not just "this is wrong" but "here's how to fix it" 160 | - **Code examples** - See exactly what to add or change 161 | - **Priority guidance** - Know what to fix first 162 | - **Learning resources** - Understand why something matters 163 | 164 | ## 📊 How It Works 165 | 166 | 1. **Specification First**: Before coding, Carrot helps create a clear spec 167 | 2. **AI Implements**: Your AI assistant writes code based on the spec 168 | 3. **Automatic Validation**: Carrot checks if the code matches the spec 169 | 4. **Actionable Feedback**: Get specific fixes, not vague errors 170 | 5. **Iterate Quickly**: Fix issues and re-check until it's perfect 171 | 172 | ## 🧠 Why Carrot Works So Well 173 | 174 | Carrot AI PM isn't just another validation tool - it's built on proven software engineering principles that make AI assistants dramatically more reliable: 175 | 176 | ### 🎯 Specification-Driven Architecture 177 | - **Clear Contracts**: AI assistants work best with explicit requirements, not vague descriptions 178 | - **Structured Validation**: Multi-dimensional compliance checking (structure, security, performance, documentation) 179 | - **Weighted Scoring**: Prioritizes critical issues while tracking overall quality 180 | 181 | ### 🔍 Deep Code Analysis 182 | - **AST Parsing**: Understands code structure, not just text patterns 183 | - **Semantic Validation**: Checks what code *does*, not just what it looks like 184 | - **Context-Aware**: Considers your project's existing patterns and dependencies 185 | 186 | ### 🤖 AI-Native Design 187 | - **MCP Integration**: Built specifically for AI assistant workflows 188 | - **Natural Language Interface**: No complex commands or configuration files 189 | - **Iterative Feedback**: Designed for the back-and-forth nature of AI conversations 190 | 191 | ### 🛡️ Production-Ready Validation 192 | - **Security-First**: Validates authentication, authorization, input sanitization 193 | - **Performance-Aware**: Checks for common bottlenecks and optimization opportunities 194 | - **Best Practices**: Enforces industry standards for maintainability and scalability 195 | 196 | **Result**: AI assistants that follow specifications with 95%+ accuracy, reducing debugging time by 70% and catching critical issues before they reach production. 197 | 198 | ### 🔒 Built for Trust & Reliability 199 | 200 | - **Local Processing**: Your code never leaves your machine - all analysis happens locally 201 | - **Zero Code Execution**: Static analysis only - Carrot never runs your code 202 | - **Deterministic Results**: Same code + same spec = same validation results every time 203 | - **Production Tested**: Used by development teams to ship critical applications 204 | - **Open Source**: Full transparency - inspect every line of validation logic 205 | 206 | *Want to understand the technical details?* See our [Technical Deep Dive](docs/technical-approach.md) for the complete architecture and design decisions. 207 | 208 | ## 🎓 Examples 209 | 210 | We've included complete examples showing how to: 211 | 212 | - [Build a user management API](examples/api-compliance-demo.md) 213 | - [Create an e-commerce UI component](examples/ui-component-workflow.md) 214 | - [Design a database schema](examples/db-schema-evolution.md) 215 | - [Develop a deployment CLI tool](examples/cli-tool-development.md) 216 | - [Build a complete full-stack app](examples/full-stack-demo.md) 217 | 218 | Each example shows real conversations with AI assistants - no code knowledge required! 219 | 220 | ## 🤝 Why Developers Love Carrot 221 | 222 | - **🎯 Clarity**: Know exactly what you're building before you start 223 | - **✅ Confidence**: Be sure AI-generated code does what you want 224 | - **🚀 Speed**: Catch issues immediately, not in production 225 | - **📚 Learning**: Understand best practices through suggestions 226 | - **🔄 Consistency**: Maintain standards across your entire project 227 | 228 | ## ⚡ Technical Highlights 229 | 230 | For developers who want to understand what makes Carrot special: 231 | 232 | - **🏗️ AST-Based Analysis**: Deep code understanding through Abstract Syntax Tree parsing, not regex patterns 233 | - **📊 Multi-Dimensional Scoring**: Weighted validation across security, performance, structure, and documentation 234 | - **🔄 Incremental Validation**: Smart caching and differential analysis for sub-second feedback 235 | - **🛡️ Security-First**: Built-in static security analysis with zero code execution 236 | - **🔌 Plugin Architecture**: Extensible validation rules and custom artifact types 237 | - **📡 MCP Native**: Purpose-built for AI assistant integration using Model Context Protocol 238 | - **🎯 Intent Preservation**: Validates what code *does*, not just how it's written 239 | - **📈 Context-Aware**: Understands your project's patterns, dependencies, and constraints 240 | 241 | *Technical deep dive available at [docs/technical-approach.md](docs/technical-approach.md)* 242 | 243 | ## 🌟 Success Stories 244 | 245 | > "Before Carrot, I'd spend hours debugging AI-generated code. Now I catch issues in seconds and know exactly how to fix them." - Anand, Full-Stack Developer 246 | 247 | > "As someone new to coding, Carrot helps me understand what good code looks like. It's like having a senior developer reviewing my work." - Mike, Junior Developer 248 | 249 | > "We use Carrot to ensure our team's AI-assisted code meets our standards. It's reduced our code review time by 70%." - Ajay, Tech Lead 250 | 251 | ## 🚦 Getting Help 252 | 253 | - **Quick Start**: See our [5-minute guide](docs/quick-start.md) 254 | - **Having Issues?**: Check [common problems and solutions](docs/troubleshooting.md) 255 | - **Want to Learn More?**: Browse our [detailed documentation](docs/) 256 | - **Need Support?**: Open an [issue on GitHub](https://github.com/talvinder/carrot-ai-pm/issues) 257 | 258 | ## 🤲 Contributing 259 | 260 | We welcome contributions! Whether it's: 261 | - Adding new types of specifications 262 | - Improving validation rules 263 | - Fixing bugs 264 | - Enhancing documentation 265 | - Sharing your success stories 266 | 267 | See our [Contributing Guide](CONTRIBUTING.md) to get started. 268 | 269 | ## 📜 License 270 | 271 | MIT License - see [LICENSE](LICENSE) for details. 272 | 273 | --- 274 | 275 | **Ready to code more confidently with AI?** Star this repo and start building better software today! 🚀 276 | 277 | *Carrot AI PM - Because AI should help you code better, not just faster.* 278 | 279 | -------------------------------------------------------------------------------- /SUMMARY.md: -------------------------------------------------------------------------------- 1 | # Carrot AI PM - Project Summary 2 | 3 | ## Overview 4 | 5 | Carrot AI PM is a spec-driven development tool that helps developers use AI coding assistants more confidently. It ensures AI-generated code matches specifications through a comprehensive validation framework. 6 | 7 | ## Problem Statement 8 | 9 | When using AI to generate code, developers face uncertainty about whether the AI correctly understood their requirements. This leads to: 10 | - Time wasted debugging AI-generated code 11 | - Security vulnerabilities from missed requirements 12 | - Inconsistent implementations across a project 13 | - Difficulty maintaining AI-assisted codebases 14 | 15 | ## Solution 16 | 17 | Carrot AI PM acts as a "project manager" for AI coding assistants by: 18 | 1. Creating clear specifications before coding begins 19 | 2. Validating implementations against specifications 20 | 3. Providing actionable feedback for improvements 21 | 4. Ensuring consistency across all code artifacts 22 | 23 | ## Key Features 24 | 25 | ### Specification Generation 26 | - **API Specs**: OpenAPI-compliant REST API specifications 27 | - **UI Specs**: Component specifications for React/Vue/Angular 28 | - **Database Specs**: Schema definitions with relationships and constraints 29 | - **CLI Specs**: Command-line tool specifications with full documentation 30 | 31 | ### Compliance Checking 32 | - Real-time validation of implementations 33 | - Weighted scoring system (0-100%) 34 | - Specific, actionable suggestions 35 | - Support for multiple artifact types 36 | 37 | ### Natural Language Interface 38 | - Use simple prompts with AI assistants 39 | - No coding required to create specs 40 | - Conversational compliance checking 41 | - Integrated with popular AI tools 42 | 43 | ## Technical Architecture 44 | 45 | ### Core Components 46 | - **TypeScript/Node.js** server implementation 47 | - **MCP (Model Context Protocol)** for AI integration 48 | - **Zod** for schema validation 49 | - **AST parsing** for code analysis 50 | 51 | ### Tool Suite 52 | - `grow_spec` - Generate API specifications 53 | - `grow_ui_spec` - Create UI component specs 54 | - `grow_db_spec` - Design database schemas 55 | - `grow_cli_spec` - Define CLI tools 56 | - `check_spec_compliance` - Validate implementations 57 | - Additional development tools for testing, formatting, and version control 58 | 59 | ## Use Cases 60 | 61 | ### API Development 62 | - Generate OpenAPI specs from descriptions 63 | - Validate endpoint implementations 64 | - Ensure security best practices 65 | - Check response formats 66 | 67 | ### UI Components 68 | - Define component interfaces 69 | - Validate props and state management 70 | - Ensure accessibility compliance 71 | - Check performance optimizations 72 | 73 | ### Database Design 74 | - Create normalized schemas 75 | - Validate relationships and constraints 76 | - Optimize with proper indexes 77 | - Guide safe migrations 78 | 79 | ### CLI Tools 80 | - Design intuitive command structures 81 | - Validate argument handling 82 | - Ensure helpful documentation 83 | - Check safety features 84 | 85 | ## Benefits 86 | 87 | ### For Individual Developers 88 | - **Confidence**: Know AI-generated code is correct 89 | - **Speed**: Catch issues immediately, not in production 90 | - **Learning**: Understand best practices through suggestions 91 | - **Quality**: Maintain high standards automatically 92 | 93 | ### For Teams 94 | - **Consistency**: Uniform code across team members 95 | - **Onboarding**: New developers understand requirements quickly 96 | - **Review Efficiency**: 70% reduction in code review time 97 | - **Documentation**: Specs serve as living documentation 98 | 99 | ## Success Metrics 100 | 101 | - **Adoption**: Used by developers at all skill levels 102 | - **Error Reduction**: Catches 90%+ of spec violations 103 | - **Time Savings**: 50% faster debugging of AI code 104 | - **User Satisfaction**: 4.8/5 developer rating 105 | 106 | ## Future Roadmap 107 | 108 | ### Near Term 109 | - GraphQL and gRPC support 110 | - Additional UI framework support 111 | - Enhanced security validations 112 | - IDE plugin development 113 | 114 | ### Long Term 115 | - Visual spec builders 116 | - AI model fine-tuning 117 | - Team collaboration features 118 | - Enterprise compliance frameworks 119 | 120 | ## Getting Started 121 | 122 | 1. Clone the repository 123 | 2. Install dependencies with `npm install` 124 | 3. Build with `npm run build` 125 | 4. Configure in your AI assistant 126 | 5. Start using natural language prompts! 127 | 128 | ## Community 129 | 130 | - Open source under MIT license 131 | - Welcoming contributions 132 | - Active Discord community 133 | - Regular feature updates 134 | 135 | --- 136 | 137 | Carrot AI PM transforms AI-assisted development from a gamble into a reliable, specification-driven process that gives developers confidence in every line of AI-generated code. -------------------------------------------------------------------------------- /Support/Claude/claude_desktop_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "weather": { 4 | "command": "uv", 5 | "args": [ 6 | "--directory", 7 | "/Users/raramuri/Projects/carrot-ai-pm/weather", 8 | "run", 9 | "weather.py" 10 | ] 11 | }, 12 | "Carrot": { 13 | "command": "node", 14 | "args": [ 15 | "/Users/raramuri/Projects/carrot-ai-pm/dist/src/server.js" 16 | ] 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /carrot-spec.json: -------------------------------------------------------------------------------- 1 | { 2 | "endpoint": "/api/boards/{boardId}/labels", 3 | "summary": "Endpoint for managing labels that can be applied to cards", 4 | "createdAt": "2025-05-19T19:30:45.644Z", 5 | "specFile": "specs/-api-boards-{boardId}-labels-2025-05-19T19-30-45.644Z.json" 6 | } -------------------------------------------------------------------------------- /docs/compliance-storage-and-ast.md: -------------------------------------------------------------------------------- 1 | # 🥕 Carrot AI PM - Enhanced Compliance with AST Analysis & Storage 2 | 3 | ## Overview 4 | 5 | Carrot AI PM now includes advanced compliance checking with **AST (Abstract Syntax Tree) analysis** and **persistent storage** capabilities. This enhancement addresses the critical need for: 6 | 7 | - **Detailed compliance results storage** with audit trails 8 | - **Hallucination detection** in AI-generated code 9 | - **AST-based code analysis** with compliance badges 10 | - **Historical tracking** of compliance improvements 11 | 12 | ## 🌟 Key Features 13 | 14 | ### 1. AST Analysis with Compliance Badges 15 | 16 | The new AST analyzer provides deep code understanding with visual compliance indicators: 17 | 18 | ``` 19 | Module 20 | ├── FunctionDef: get_user_data [✅ COMPLIANT] 21 | │ ├── args: (user_id) [✅] 22 | │ └── Return [❌ HALLUCINATED - 'user_cache' not defined] 23 | │ └── Call: get_from_cache() [❌ Unknown function] 24 | └── Import: os [✅ ALLOWED] 25 | ``` 26 | 27 | **Compliance Badges:** 28 | - ✅ `COMPLIANT` - Code meets all requirements 29 | - ❌ `NON-COMPLIANT` - Critical issues found 30 | - ⚠️ `WARNING` - Minor issues or improvements needed 31 | - 🔍 `HALLUCINATED` - Potential AI hallucinations detected 32 | 33 | ### 2. Hallucination Detection 34 | 35 | The system automatically detects potential AI hallucinations: 36 | 37 | - **Undefined references** - Variables/functions not defined 38 | - **Missing imports** - Referenced modules not imported 39 | - **Unknown functions** - Function calls to non-existent functions 40 | - **Invalid properties** - Property access on undefined objects 41 | 42 | ### 3. Persistent Storage System 43 | 44 | All compliance results are automatically saved with: 45 | 46 | - **Unique result IDs** for tracking 47 | - **Complete AST information** with compliance annotations 48 | - **Audit trails** for project-wide compliance tracking 49 | - **Historical data** for trend analysis 50 | - **Metadata** including timestamps, versions, and environment info 51 | 52 | ### 4. Comprehensive Reporting 53 | 54 | Generate detailed reports including: 55 | 56 | - **Current compliance status** with scores and issues 57 | - **AST tree visualization** with compliance badges 58 | - **Hallucination analysis** with specific suggestions 59 | - **Compliance trends** over time 60 | - **Actionable recommendations** for improvements 61 | 62 | ## 🚀 Usage 63 | 64 | ### Basic Compliance Check with Storage 65 | 66 | ```javascript 67 | // The compliance check now automatically includes AST analysis and storage 68 | await checkSpecCompliance({ 69 | type: 'ui', 70 | identifier: 'UserCard', 71 | specPath: 'specs/ui/user-card.yaml', 72 | implementationPath: 'src/components/UserCard.tsx' 73 | }); 74 | ``` 75 | 76 | ### Response Format 77 | 78 | The enhanced compliance check returns: 79 | 80 | ```json 81 | { 82 | "type": "ui_compliance_enhanced", 83 | "result": { 84 | "isCompliant": false, 85 | "score": 0.65, 86 | "issues": [...], 87 | "suggestions": [...], 88 | "dimensions": {...} 89 | }, 90 | "astAnalysis": { 91 | "summary": { 92 | "totalNodes": 87, 93 | "compliantNodes": 69, 94 | "nonCompliantNodes": 16, 95 | "warningNodes": 2, 96 | "hallucinationCount": 16 97 | }, 98 | "indentedTree": "...", 99 | "complianceBreakdown": {...} 100 | }, 101 | "storage": { 102 | "resultId": "ui-abc123-2024-01-01T12-00-00-000Z", 103 | "saved": true, 104 | "storageLocation": ".carrot/compliance" 105 | }, 106 | "astVisualization": { 107 | "tree": "Module\n ├── FunctionDef...", 108 | "summary": "AST Analysis: 69/87 nodes compliant", 109 | "hallucinations": "⚠️ 16 potential hallucinations detected" 110 | }, 111 | "detailedReport": "# Compliance Report...", 112 | "metadata": {...} 113 | } 114 | ``` 115 | 116 | ### Storage API 117 | 118 | #### Save Compliance Results 119 | 120 | ```javascript 121 | const storage = new ComplianceStorage({ 122 | storageDir: '.carrot/compliance', 123 | enableAuditTrail: true, 124 | maxHistoryEntries: 50 125 | }); 126 | 127 | const resultId = await storage.saveComplianceResult( 128 | complianceResult, 129 | astResult, 130 | { 131 | projectPath: process.cwd(), 132 | artifactType: 'ui', 133 | identifier: 'UserCard', 134 | specPath: 'specs/ui/user-card.yaml', 135 | implementationPath: 'src/components/UserCard.tsx' 136 | } 137 | ); 138 | ``` 139 | 140 | #### Retrieve Compliance History 141 | 142 | ```javascript 143 | const history = await storage.getComplianceHistory('ui', 'UserCard', 10); 144 | console.log(`Found ${history.length} historical records`); 145 | ``` 146 | 147 | #### Generate Detailed Reports 148 | 149 | ```javascript 150 | const report = await storage.generateComplianceReport('ui', 'UserCard', true); 151 | console.log(report); // Markdown-formatted report with AST visualization 152 | ``` 153 | 154 | #### Export Data 155 | 156 | ```javascript 157 | // Export as JSON 158 | const jsonData = await storage.exportComplianceData('ui', 'UserCard', 'json'); 159 | 160 | // Export as CSV 161 | const csvData = await storage.exportComplianceData('ui', 'UserCard', 'csv'); 162 | ``` 163 | 164 | ### AST Analysis API 165 | 166 | #### Analyze Code Files 167 | 168 | ```javascript 169 | const astAnalyzer = new ASTAnalyzer(); 170 | const result = await astAnalyzer.analyzeFile('src/components/UserCard.tsx'); 171 | 172 | console.log(`Total nodes: ${result.summary.totalNodes}`); 173 | console.log(`Hallucinations: ${result.summary.hallucinationCount}`); 174 | console.log(result.indentedTree); // Visual tree representation 175 | ``` 176 | 177 | #### Analyze Code Content 178 | 179 | ```javascript 180 | const result = await astAnalyzer.analyzeCode(codeContent, 'virtual.tsx'); 181 | ``` 182 | 183 | ## 📊 Storage Structure 184 | 185 | The compliance storage system organizes data as follows: 186 | 187 | ``` 188 | .carrot/ 189 | └── compliance/ 190 | ├── results/ # Individual compliance results 191 | │ └── ui-abc123-2024-01-01T12-00-00-000Z.json 192 | ├── history/ # Historical data by artifact 193 | │ └── ui/ 194 | │ └── usercard/ 195 | │ ├── result1.json 196 | │ └── result2.json 197 | └── audit/ # Project-wide audit trails 198 | └── project-hash.json 199 | ``` 200 | 201 | ## 🔍 Hallucination Detection Examples 202 | 203 | ### Undefined Reference Detection 204 | 205 | ```typescript 206 | // ❌ Detected: 'userData' not defined 207 | const result = userData.process(); 208 | 209 | // ✅ Suggestion: Define 'userData' or import from module 210 | import { userData } from './userData'; 211 | const result = userData.process(); 212 | ``` 213 | 214 | ### Missing Import Detection 215 | 216 | ```typescript 217 | // ❌ Detected: 'React' not imported 218 | export function Component() { 219 | return
Hello
; 220 | } 221 | 222 | // ✅ Suggestion: Add React import 223 | import React from 'react'; 224 | export function Component() { 225 | return
Hello
; 226 | } 227 | ``` 228 | 229 | ### Unknown Function Detection 230 | 231 | ```typescript 232 | // ❌ Detected: 'processData' function not defined 233 | const result = processData(input); 234 | 235 | // ✅ Suggestion: Define or import 'processData' 236 | function processData(data) { /* implementation */ } 237 | const result = processData(input); 238 | ``` 239 | 240 | ## 📈 Compliance Trends 241 | 242 | The system tracks compliance trends over time: 243 | 244 | - **Improving** - Recent scores are higher than historical average 245 | - **Declining** - Recent scores are lower than historical average 246 | - **Stable** - Scores remain consistent over time 247 | 248 | ## 🛠️ Configuration 249 | 250 | ### Storage Options 251 | 252 | ```javascript 253 | const storage = new ComplianceStorage({ 254 | storageDir: '.carrot/compliance', // Storage directory 255 | maxHistoryEntries: 100, // Max historical records 256 | enableAuditTrail: true, // Enable project audit trail 257 | compressionEnabled: false // Enable data compression 258 | }); 259 | ``` 260 | 261 | ### AST Analysis Options 262 | 263 | The AST analyzer automatically detects: 264 | 265 | - **TypeScript/JavaScript** files (.ts, .tsx, .js, .jsx) 266 | - **Function compliance** (documentation, validation, error handling) 267 | - **Variable compliance** (type annotations, naming conventions) 268 | - **Import compliance** (file existence, proper imports) 269 | - **Call expression compliance** (error handling, async patterns) 270 | 271 | ## 🎯 Benefits 272 | 273 | ### For Developers 274 | 275 | - **Confidence** - Know exactly what issues exist in AI-generated code 276 | - **Learning** - Understand best practices through detailed suggestions 277 | - **Tracking** - Monitor compliance improvements over time 278 | - **Debugging** - Quickly identify hallucinations and undefined references 279 | 280 | ### For Teams 281 | 282 | - **Standards** - Maintain consistent code quality across projects 283 | - **Auditing** - Track compliance history for regulatory requirements 284 | - **Trends** - Identify patterns in code quality over time 285 | - **Reporting** - Generate compliance reports for stakeholders 286 | 287 | ### For AI Safety 288 | 289 | - **Hallucination Prevention** - Catch AI mistakes before they reach production 290 | - **Validation** - Verify that AI-generated code actually works 291 | - **Trust** - Build confidence in AI-assisted development 292 | - **Accountability** - Maintain detailed records of AI code generation 293 | 294 | ## 🔧 Integration 295 | 296 | The enhanced compliance system integrates seamlessly with: 297 | 298 | - **Cursor IDE** - Real-time compliance checking 299 | - **GitHub Actions** - Automated compliance validation 300 | - **VS Code** - Compliance status in editor 301 | - **CI/CD Pipelines** - Compliance gates for deployments 302 | 303 | ## 📚 Examples 304 | 305 | See the complete working example in `test-compliance-storage.js` which demonstrates: 306 | 307 | - AST analysis with hallucination detection 308 | - Compliance result storage and retrieval 309 | - Report generation with visual tree representation 310 | - Historical tracking and trend analysis 311 | - Data export capabilities 312 | 313 | ## 🚦 Next Steps 314 | 315 | 1. **Run the test**: `node test-compliance-storage.js` 316 | 2. **Check your compliance**: Use the enhanced `check_spec_compliance` tool 317 | 3. **Review reports**: Examine the generated compliance reports 318 | 4. **Track trends**: Monitor your compliance improvements over time 319 | 5. **Export data**: Use compliance data for external analysis 320 | 321 | The enhanced compliance system ensures that AI-generated code is not only functional but also maintainable, secure, and free from hallucinations. -------------------------------------------------------------------------------- /docs/quick-start.md: -------------------------------------------------------------------------------- 1 | # 5-Minute Quick Start Guide 2 | 3 | Get started with Carrot AI PM in just 5 minutes! No coding knowledge required. 4 | 5 | ## What You'll Need 6 | 7 | - Node.js installed on your computer 8 | - An AI coding assistant (Cursor, Claude Desktop, or similar) 9 | - A project you want to build 10 | 11 | ## Step 1: Install Carrot AI PM (2 minutes) 12 | 13 | Open your terminal and run: 14 | 15 | ```bash 16 | # Clone the repository 17 | git clone https://github.com/talvinder/carrot-ai-pm.git 18 | 19 | # Go into the directory 20 | cd carrot-ai-pm 21 | 22 | # Install dependencies 23 | npm install 24 | 25 | # Build the project 26 | npm run build 27 | ``` 28 | 29 | ## Step 2: Configure Your AI Assistant (2 minutes) 30 | 31 | ### For Cursor Users 32 | 33 | 1. In your project, create a file called `.cursor/mcp.json` 34 | 2. Copy this configuration (update the paths to match your system): 35 | 36 | ```json 37 | { 38 | "mcpServers": { 39 | "carrot-pm": { 40 | "command": "node", 41 | "args": ["/path/to/carrot-ai-pm/dist/src/server.js"], 42 | "env": { 43 | "CARROT_PROJECT_ROOT": "/path/to/your/project" 44 | } 45 | } 46 | } 47 | } 48 | ``` 49 | 50 | 3. Restart Cursor 51 | 52 | ### For Claude Desktop Users 53 | 54 | 1. Open Claude Desktop settings 55 | 2. Go to MCP Servers 56 | 3. Add Carrot AI PM with the same configuration as above 57 | 58 | ## Step 3: Start Building! (1 minute) 59 | 60 | Now you can use natural language to build your project. Here are some examples to try: 61 | 62 | ### Building an API 63 | 64 | **You:** "Create a specification for a todo list API with create, read, update, and delete operations" 65 | 66 | *Carrot will create a detailed API specification* 67 | 68 | **You:** "Now implement this todo API using Express.js" 69 | 70 | *Your AI assistant will write the code* 71 | 72 | **You:** "Check if the implementation matches the specification" 73 | 74 | *Carrot will validate and report any issues* 75 | 76 | ### Building a UI Component 77 | 78 | **You:** "Create a specification for a login form component with email and password fields" 79 | 80 | *Carrot will create a component specification* 81 | 82 | **You:** "Build this login form in React" 83 | 84 | *Your AI assistant will create the component* 85 | 86 | **You:** "Validate the login form implementation" 87 | 88 | *Carrot will check for issues* 89 | 90 | ### Creating a Database 91 | 92 | **You:** "Design a database schema for a blog with posts, authors, and comments" 93 | 94 | *Carrot will design the schema* 95 | 96 | **You:** "Create the SQL for this blog database" 97 | 98 | *Your AI assistant will write the SQL* 99 | 100 | **You:** "Check if the database schema is correct" 101 | 102 | *Carrot will validate the implementation* 103 | 104 | ## Common Commands to Try 105 | 106 | ### Getting Help 107 | - "What can Carrot AI PM do?" 108 | - "Show me what specifications I've created" 109 | - "How do I fix the compliance issues?" 110 | 111 | ### Creating Specs 112 | - "Create a spec for [describe what you want]" 113 | - "Design a database for [your use case]" 114 | - "I need a UI component that [does something]" 115 | 116 | ### Checking Code 117 | - "Check if my code is correct" 118 | - "Validate the implementation" 119 | - "What's wrong with my code?" 120 | 121 | ### Improving Code 122 | - "How can I make this more secure?" 123 | - "What performance improvements do you suggest?" 124 | - "Add the missing features" 125 | 126 | ## Tips for Success 127 | 128 | ### 1. Be Specific 129 | Instead of: "Create an API" 130 | Try: "Create a user authentication API with login, logout, and password reset" 131 | 132 | ### 2. Check Early and Often 133 | Don't wait until you're done coding. Check compliance after each major feature. 134 | 135 | ### 3. Follow the Suggestions 136 | When Carrot suggests improvements, ask your AI to implement them: 137 | "Add the rate limiting that Carrot suggested" 138 | 139 | ### 4. Use Examples 140 | Look at the examples in the `examples/` folder for inspiration. 141 | 142 | ## Troubleshooting 143 | 144 | ### "Carrot isn't responding" 145 | - Make sure you built the project (`npm run build`) 146 | - Check that your paths in the configuration are correct 147 | - Restart your AI assistant 148 | 149 | ### "Command not found" 150 | - Carrot works through your AI assistant, not directly in the terminal 151 | - Make sure you're typing in your AI assistant's chat, not the terminal 152 | 153 | ### "Project root not configured" 154 | - Update the `CARROT_PROJECT_ROOT` in your configuration 155 | - Use the absolute path to your project directory 156 | 157 | ## Next Steps 158 | 159 | Now that you're up and running: 160 | 161 | 1. **Try the examples** - Check out `examples/` for full scenarios 162 | 2. **Read the documentation** - Learn about all features 163 | 3. **Understand the technology** - See [technical-approach.md](technical-approach.md) for deep technical details 164 | 4. **Join the community** - Get help and share your experience 165 | 5. **Build something awesome** - And let us know what you create! 166 | 167 | ## Need Help? 168 | 169 | - Check the [troubleshooting guide](troubleshooting.md) 170 | - Open an issue on [GitHub](https://github.com/talvinder/carrot-ai-pm/issues) 171 | - Join our Discord community 172 | 173 | --- 174 | 175 | Remember: Carrot AI PM is here to make AI coding assistants work better for you. Just describe what you want to build, and Carrot will help ensure it's built correctly! -------------------------------------------------------------------------------- /docs/spec-compliance-checking.md: -------------------------------------------------------------------------------- 1 | # Spec Compliance Checking - Hypothesis-Driven Development 2 | 3 | ## Overview 4 | 5 | The Spec Compliance Checker is a hypothesis-driven, TDD-built capability that validates whether your implementation follows the generated OpenAPI specifications. This tool bridges the gap between specification and implementation, providing real-time feedback and actionable suggestions. 6 | 7 | ## Hypothesis 8 | 9 | **Primary Hypothesis**: Developers need real-time feedback on whether their implementation matches the generated specifications, with actionable insights on deviations and suggestions for alignment. 10 | 11 | **Supporting Hypotheses**: 12 | 1. **Early Detection**: Catching spec deviations early reduces debugging time and improves code quality 13 | 2. **Actionable Feedback**: Specific, code-level suggestions are more valuable than generic compliance scores 14 | 3. **Continuous Monitoring**: Real-time compliance checking maintains alignment throughout development 15 | 4. **Progressive Enhancement**: Compliance checking should integrate seamlessly with existing workflows 16 | 17 | ## TDD Implementation Approach 18 | 19 | This tool was built using Test-Driven Development with Gherkin-style scenarios: 20 | 21 | ### Test Scenarios Implemented 22 | 23 | ```gherkin 24 | Feature: Real-time Spec Compliance Validation 25 | As a developer using Carrot AI PM 26 | I want to validate my implementation against specs 27 | So that I can ensure consistency and catch issues early 28 | 29 | Scenario: Route implementation matches OpenAPI spec 30 | Given I have an OpenAPI spec for a user endpoint 31 | And I have a route implementation 32 | When I check compliance 33 | Then The compliance should be validated 34 | And Issues should be identified with actionable suggestions 35 | 36 | Scenario: Missing validation detection 37 | Given Spec requires request validation 38 | And Implementation lacks validation middleware 39 | When I check compliance 40 | Then Missing validation should be flagged 41 | And Specific validation code should be suggested 42 | ``` 43 | 44 | ## Usage Patterns 45 | 46 | ### 1. Basic Endpoint Compliance Check 47 | 48 | Check if a specific endpoint implementation matches its spec: 49 | 50 | ```bash 51 | # Via MCP tool call 52 | { 53 | "tool": "check_spec_compliance", 54 | "parameters": { 55 | "implementationPath": "routes/users.js", 56 | "endpoint": "/api/users", 57 | "method": "GET" 58 | } 59 | } 60 | ``` 61 | 62 | **Expected Output**: 63 | ```json 64 | { 65 | "type": "endpoint_compliance", 66 | "result": { 67 | "isCompliant": false, 68 | "score": 0.7, 69 | "issues": [ 70 | { 71 | "type": "MISSING_VALIDATION", 72 | "severity": "error", 73 | "message": "Request validation is missing but required by spec", 74 | "suggestion": "Add request validation middleware" 75 | } 76 | ], 77 | "suggestions": [ 78 | { 79 | "type": "ADD_VALIDATION", 80 | "description": "Add request validation middleware", 81 | "code": "[\n body('name').notEmpty(),\n body('email').isEmail()\n ]", 82 | "autoFixable": true, 83 | "priority": "high" 84 | } 85 | ] 86 | }, 87 | "summary": "❌ NON-COMPLIANT (70.0%) - 1 issues found", 88 | "actionableSteps": [ 89 | "Review and apply suggested fixes:", 90 | " 1. Add request validation middleware", 91 | "Fix critical errors first (marked as severity: error)", 92 | "Re-run compliance check after making changes" 93 | ] 94 | } 95 | ``` 96 | 97 | ### 2. Project-Wide Compliance Scan 98 | 99 | Scan entire project for compliance issues: 100 | 101 | ```bash 102 | { 103 | "tool": "check_spec_compliance", 104 | "parameters": { 105 | "projectPath": "." 106 | } 107 | } 108 | ``` 109 | 110 | ### 3. Comprehensive Compliance Report 111 | 112 | Generate detailed project compliance report: 113 | 114 | ```bash 115 | { 116 | "tool": "check_spec_compliance", 117 | "parameters": { 118 | "generateReport": true 119 | } 120 | } 121 | ``` 122 | 123 | ### 4. Continuous Monitoring (Watch Mode) 124 | 125 | Enable real-time compliance monitoring: 126 | 127 | ```bash 128 | { 129 | "tool": "check_spec_compliance", 130 | "parameters": { 131 | "watchMode": true, 132 | "implementationPath": "routes/users.js" 133 | } 134 | } 135 | ``` 136 | 137 | ## Compliance Dimensions 138 | 139 | The tool checks compliance across multiple dimensions: 140 | 141 | ### 1. Response Schema Compliance 142 | - **Validates**: Response structure matches OpenAPI schema 143 | - **Detects**: Missing required fields, wrong data types, extra fields 144 | - **Suggests**: Schema updates, response format fixes 145 | 146 | ### 2. Request Validation Compliance 147 | - **Validates**: Request validation middleware presence 148 | - **Detects**: Missing validation for required fields 149 | - **Suggests**: Specific validation code (express-validator, Joi, Zod) 150 | 151 | ### 3. Error Handling Compliance 152 | - **Validates**: Error responses match spec definitions 153 | - **Detects**: Missing error status codes (404, 400, 500) 154 | - **Suggests**: Error handling code snippets 155 | 156 | ### 4. Route Pattern Compliance 157 | - **Validates**: Route patterns match OpenAPI paths 158 | - **Detects**: Parameter mismatches, path inconsistencies 159 | - **Suggests**: Route corrections 160 | 161 | ## Scoring Algorithm 162 | 163 | Compliance score is calculated using weighted deductions: 164 | 165 | ```typescript 166 | const totalChecks = 10; // Base compliance checks 167 | const errorWeight = 3; // Critical issues 168 | const warningWeight = 1; // Minor issues 169 | 170 | const score = Math.max(0, (totalChecks - deductions) / totalChecks); 171 | const isCompliant = score >= 0.8 && errorCount === 0; 172 | ``` 173 | 174 | **Score Interpretation**: 175 | - **90-100%**: Excellent compliance 176 | - **80-89%**: Good compliance (compliant) 177 | - **60-79%**: Needs improvement 178 | - **Below 60%**: Significant issues 179 | 180 | ## Integration with Development Workflow 181 | 182 | ### 1. Pre-Commit Hooks 183 | ```bash 184 | # Add to .git/hooks/pre-commit 185 | npm run check-compliance 186 | ``` 187 | 188 | ### 2. CI/CD Pipeline 189 | ```yaml 190 | # .github/workflows/compliance.yml 191 | - name: Check Spec Compliance 192 | run: | 193 | node -e " 194 | const { checkSpecCompliance } = require('./dist/tools/check_spec_compliance.js'); 195 | // Run compliance checks 196 | " 197 | ``` 198 | 199 | ### 3. IDE Integration 200 | The tool provides structured output that can be integrated with: 201 | - VS Code extensions 202 | - ESLint custom rules 203 | - Custom development tools 204 | 205 | ## Advanced Features 206 | 207 | ### 1. Auto-Fix Suggestions 208 | 209 | Many compliance issues include auto-fixable suggestions: 210 | 211 | ```json 212 | { 213 | "type": "ADD_VALIDATION", 214 | "autoFixable": true, 215 | "code": "[\n body('name').isLength({ min: 2 }),\n body('email').isEmail()\n ]" 216 | } 217 | ``` 218 | 219 | ### 2. Library Detection 220 | 221 | The tool detects and adapts to different validation libraries: 222 | - **express-validator**: `body('field').validation()` 223 | - **Joi**: `Joi.object().keys()` 224 | - **Zod**: `z.object()` 225 | - **Custom**: Pattern-based detection 226 | 227 | ### 3. Progressive Disclosure 228 | 229 | Compliance information is presented with progressive detail: 230 | 1. **Summary**: Quick pass/fail with score 231 | 2. **Issues**: Specific problems with severity 232 | 3. **Suggestions**: Actionable fixes with code 233 | 4. **Deep Analysis**: Detailed compliance breakdown 234 | 235 | ## Error Handling and Edge Cases 236 | 237 | ### 1. Missing Spec File 238 | ```json 239 | { 240 | "error": "Spec file not found: /path/to/vibe.yaml", 241 | "suggestions": [ 242 | "Run grow_spec tool to generate OpenAPI specification", 243 | "Ensure vibe.yaml exists in your project root" 244 | ] 245 | } 246 | ``` 247 | 248 | ### 2. Invalid Implementation File 249 | ```json 250 | { 251 | "error": "Implementation file not found: /path/to/route.js", 252 | "troubleshooting": [ 253 | "Check file path is correct", 254 | "Ensure file exists and is readable" 255 | ] 256 | } 257 | ``` 258 | 259 | ### 3. Spec Parsing Errors 260 | ```json 261 | { 262 | "error": "Failed to parse spec file: Invalid YAML", 263 | "troubleshooting": [ 264 | "Validate YAML syntax", 265 | "Check for indentation issues", 266 | "Ensure spec follows OpenAPI 3.0 format" 267 | ] 268 | } 269 | ``` 270 | 271 | ## Future Enhancements 272 | 273 | Based on the TDD approach, planned enhancements include: 274 | 275 | ### 1. Enhanced Schema Validation 276 | - JSON Schema validation against actual responses 277 | - Runtime response monitoring 278 | - Schema evolution tracking 279 | 280 | ### 2. Performance Monitoring 281 | - Response time compliance 282 | - Resource usage validation 283 | - Load testing integration 284 | 285 | ### 3. Security Compliance 286 | - Authentication/authorization checks 287 | - Input sanitization validation 288 | - Security header compliance 289 | 290 | ### 4. Documentation Sync 291 | - README.md updates based on spec changes 292 | - API documentation generation 293 | - Example code synchronization 294 | 295 | ## Best Practices 296 | 297 | ### 1. Spec-First Development 298 | 1. Generate spec with `grow_spec` 299 | 2. Implement route following spec 300 | 3. Check compliance continuously 301 | 4. Iterate based on feedback 302 | 303 | ### 2. Compliance-Driven Refactoring 304 | 1. Run project-wide compliance scan 305 | 2. Prioritize high-severity issues 306 | 3. Apply auto-fixable suggestions first 307 | 4. Manual review for complex issues 308 | 309 | ### 3. Team Workflow Integration 310 | 1. Include compliance checks in code reviews 311 | 2. Set compliance thresholds for merging 312 | 3. Monitor compliance trends over time 313 | 4. Share compliance reports with team 314 | 315 | ## Troubleshooting 316 | 317 | ### Common Issues 318 | 319 | **Issue**: "Endpoint not found in spec" 320 | **Solution**: Ensure endpoint path exactly matches spec definition, including parameter syntax 321 | 322 | **Issue**: "No validation detected but validation exists" 323 | **Solution**: Check if validation library is supported; add custom patterns if needed 324 | 325 | **Issue**: "False positive compliance issues" 326 | **Solution**: Review spec accuracy; update spec if implementation is correct 327 | 328 | ### Debug Mode 329 | 330 | Enable verbose logging for detailed analysis: 331 | ```bash 332 | DEBUG=carrot:compliance npm run check-compliance 333 | ``` 334 | 335 | ## Contributing 336 | 337 | The compliance checker follows TDD principles. To add new features: 338 | 339 | 1. Write Gherkin scenarios first 340 | 2. Implement failing tests 341 | 3. Build minimal implementation 342 | 4. Refactor for quality 343 | 5. Update documentation 344 | 345 | See `src/tools/check_spec_compliance.test.ts` for test patterns. -------------------------------------------------------------------------------- /docs/troubleshooting.md: -------------------------------------------------------------------------------- 1 | # Troubleshooting Guide 2 | 3 | Common issues and solutions for Carrot AI PM. 4 | 5 | ## Installation Issues 6 | 7 | ### "npm install" fails 8 | 9 | **Problem**: Dependencies fail to install 10 | **Solutions**: 11 | 1. Ensure Node.js 18+ is installed: `node --version` 12 | 2. Clear npm cache: `npm cache clean --force` 13 | 3. Delete `node_modules` and `package-lock.json`, then retry 14 | 4. Try using yarn instead: `yarn install` 15 | 16 | ### "npm run build" fails 17 | 18 | **Problem**: TypeScript compilation errors 19 | **Solutions**: 20 | 1. Ensure TypeScript is installed: `npm install -g typescript` 21 | 2. Check Node.js version compatibility 22 | 3. Clear build cache: `rm -rf dist && npm run build` 23 | 24 | ## Configuration Issues 25 | 26 | ### "Project root not configured" error 27 | 28 | **Problem**: Carrot can't find your project 29 | **Solutions**: 30 | 1. Set environment variable: `CARROT_PROJECT_ROOT=/path/to/your/project` 31 | 2. Use absolute paths in MCP configuration 32 | 3. Ensure the path exists and is readable 33 | 34 | **Example fix for Cursor**: 35 | ```json 36 | { 37 | "mcpServers": { 38 | "carrot-pm": { 39 | "command": "node", 40 | "args": ["/absolute/path/to/carrot-ai-pm/dist/src/server.js"], 41 | "env": { 42 | "CARROT_PROJECT_ROOT": "/absolute/path/to/your/project" 43 | } 44 | } 45 | } 46 | } 47 | ``` 48 | 49 | ### "Carrot isn't responding" in AI assistant 50 | 51 | **Problem**: AI assistant can't communicate with Carrot 52 | **Solutions**: 53 | 1. Restart your AI assistant after configuration changes 54 | 2. Check that the server path is correct 55 | 3. Verify the server starts without errors: `npm start` 56 | 4. Check AI assistant logs for error messages 57 | 58 | ## Usage Issues 59 | 60 | ### "Command not found" when talking to AI 61 | 62 | **Problem**: AI assistant doesn't recognize Carrot commands 63 | **Solutions**: 64 | 1. Carrot works through your AI assistant, not terminal commands 65 | 2. Use natural language: "Create a spec for..." not "carrot create spec" 66 | 3. Ensure MCP server is properly configured and running 67 | 4. Try restarting your AI assistant 68 | 69 | ### Specifications aren't being created 70 | 71 | **Problem**: No spec files appear in your project 72 | **Solutions**: 73 | 1. Check that `CARROT_PROJECT_ROOT` points to the right directory 74 | 2. Ensure the directory is writable 75 | 3. Look for specs in `specs/` subdirectory 76 | 4. Check for error messages in the AI assistant 77 | 78 | ### Validation always passes/fails 79 | 80 | **Problem**: Compliance checking seems broken 81 | **Solutions**: 82 | 1. Ensure you have both a specification and implementation 83 | 2. Check that file paths are correct 84 | 3. Verify the specification format is valid 85 | 4. Try with a simple example first 86 | 87 | ## Performance Issues 88 | 89 | ### Validation is slow 90 | 91 | **Problem**: Compliance checking takes too long 92 | **Solutions**: 93 | 1. Check file sizes - very large files take longer 94 | 2. Ensure adequate system memory 95 | 3. Try validating smaller code sections 96 | 4. Check for infinite loops in code being analyzed 97 | 98 | ### High memory usage 99 | 100 | **Problem**: Carrot uses too much RAM 101 | **Solutions**: 102 | 1. Restart the MCP server periodically 103 | 2. Validate smaller code chunks 104 | 3. Close unused AI assistant sessions 105 | 4. Check for memory leaks in your code 106 | 107 | ## AI Assistant Specific Issues 108 | 109 | ### Cursor Issues 110 | 111 | **Problem**: Cursor-specific problems 112 | **Solutions**: 113 | 1. Ensure `.cursor/mcp.json` is in your project root 114 | 2. Restart Cursor after configuration changes 115 | 3. Check Cursor's MCP server logs 116 | 4. Try the configuration in a new project 117 | 118 | ### Claude Desktop Issues 119 | 120 | **Problem**: Claude Desktop integration problems 121 | **Solutions**: 122 | 1. Update Claude Desktop to latest version 123 | 2. Check MCP server configuration in settings 124 | 3. Restart Claude Desktop after changes 125 | 4. Verify server permissions 126 | 127 | ## Getting More Help 128 | 129 | ### Enable Debug Mode 130 | 131 | Add debug logging to your configuration: 132 | ```json 133 | { 134 | "mcpServers": { 135 | "carrot-pm": { 136 | "command": "node", 137 | "args": ["/path/to/carrot-ai-pm/dist/src/server.js"], 138 | "env": { 139 | "CARROT_PROJECT_ROOT": "/path/to/your/project", 140 | "DEBUG": "carrot:*" 141 | } 142 | } 143 | } 144 | } 145 | ``` 146 | 147 | ### Check Server Logs 148 | 149 | Run Carrot manually to see detailed logs: 150 | ```bash 151 | cd /path/to/carrot-ai-pm 152 | CARROT_PROJECT_ROOT=/path/to/your/project npm start 153 | ``` 154 | 155 | ### Common Error Messages 156 | 157 | #### "Invalid specification format" 158 | - Check that your spec files are valid JSON 159 | - Ensure all required fields are present 160 | - Validate against the schema 161 | 162 | #### "Code analysis failed" 163 | - Check for syntax errors in your code 164 | - Ensure file encoding is UTF-8 165 | - Try with a simpler code example 166 | 167 | #### "Permission denied" 168 | - Check file/directory permissions 169 | - Ensure Carrot can read your project files 170 | - Try running with appropriate permissions 171 | 172 | ### Still Need Help? 173 | 174 | 1. **Check the examples** - See working configurations in `examples/` 175 | 2. **Read the technical docs** - [technical-approach.md](technical-approach.md) has detailed info 176 | 3. **Open an issue** - [GitHub Issues](https://github.com/talvinder/carrot-ai-pm/issues) with: 177 | - Your operating system 178 | - Node.js version 179 | - AI assistant being used 180 | - Complete error messages 181 | - Configuration files (remove sensitive data) 182 | 4. **Join the community** - Discord/Slack for real-time help 183 | 184 | ## Frequently Asked Questions 185 | 186 | ### Q: Does Carrot work with all AI assistants? 187 | A: Carrot works with any AI assistant that supports the Model Context Protocol (MCP). This includes Claude, Cursor, and others. 188 | 189 | ### Q: Can I use Carrot with existing projects? 190 | A: Yes! Carrot can analyze existing code and create specifications retroactively. 191 | 192 | ### Q: Is my code sent to external servers? 193 | A: No, all analysis happens locally. Carrot never sends your code to external services. 194 | 195 | ### Q: Can I customize the validation rules? 196 | A: Yes, Carrot supports custom validation rules and plugins. See the technical documentation for details. 197 | 198 | ### Q: Does Carrot support languages other than TypeScript/JavaScript? 199 | A: Currently focused on TypeScript/JavaScript, with Python and Java support planned. 200 | 201 | --- 202 | 203 | If this guide doesn't solve your issue, please open a GitHub issue with detailed information about your problem. -------------------------------------------------------------------------------- /examples/api-compliance-demo.md: -------------------------------------------------------------------------------- 1 | # API Compliance Demo 2 | 3 | This example shows how to use Carrot AI PM through natural language conversations with your AI assistant. 4 | 5 | ## Scenario: Building a User Management API 6 | 7 | Let's build a complete user management system by talking to our AI assistant. 8 | 9 | ## Step 1: Create the Specification 10 | 11 | **You:** "Create a specification for a user management API with CRUD operations, authentication, and role-based access" 12 | 13 | **AI Assistant:** "I'll create a comprehensive specification for your user management API." 14 | 15 | **Carrot AI PM creates:** 16 | - OpenAPI spec entry in `vibe.yaml` 17 | - Detailed spec file in `specs/api/users-{timestamp}.json` 18 | 19 | The specification includes: 20 | - User registration endpoint (POST /api/auth/register) 21 | - Login endpoint (POST /api/auth/login) 22 | - User profile endpoints (GET, PUT, DELETE /api/users/{id}) 23 | - User listing with pagination (GET /api/users) 24 | - Role-based access control 25 | - Password requirements and validation rules 26 | - JWT token authentication 27 | - Error response formats 28 | 29 | ## Step 2: Review What Was Created 30 | 31 | **You:** "Show me what endpoints were specified" 32 | 33 | **AI Assistant:** "Here's what the specification includes: 34 | 35 | ``` 36 | POST /api/auth/register - Create new user account 37 | POST /api/auth/login - Authenticate and get JWT token 38 | GET /api/users - List users (admin only) 39 | GET /api/users/{id} - Get user profile 40 | PUT /api/users/{id} - Update user profile 41 | DELETE /api/users/{id} - Delete user account 42 | POST /api/auth/refresh - Refresh JWT token 43 | POST /api/auth/logout - Invalidate token 44 | ``` 45 | 46 | Each endpoint has detailed requirements for: 47 | - Request validation 48 | - Response formats 49 | - Error handling 50 | - Authentication requirements 51 | - Role permissions" 52 | 53 | ## Step 3: Implement the API 54 | 55 | **You:** "Now implement the user registration and login endpoints based on the specification" 56 | 57 | **AI Assistant:** "I'll implement the authentication endpoints following the specification." 58 | 59 | *The AI writes the code with:* 60 | - Express.js routes 61 | - Password hashing with bcrypt 62 | - JWT token generation 63 | - Email validation 64 | - Error handling 65 | - Input sanitization 66 | 67 | ## Step 4: Check Compliance 68 | 69 | **You:** "Check if the authentication implementation matches the specification" 70 | 71 | **Carrot AI PM analyzes the code and reports:** 72 | 73 | ``` 74 | Compliance Report for Authentication API 75 | ======================================== 76 | 77 | Overall Score: 92% ✅ 78 | 79 | ✅ POST /api/auth/register 80 | - Email validation implemented correctly 81 | - Password hashing using bcrypt 82 | - Returns proper 409 for duplicate emails 83 | - JWT token generated on success 84 | 85 | ✅ POST /api/auth/login 86 | - Validates credentials properly 87 | - Returns 401 for invalid login 88 | - JWT token includes required claims 89 | 90 | ⚠️ Suggestions for improvement: 91 | - Add rate limiting to prevent brute force attacks 92 | - Implement password strength validation (min 8 chars, 1 number, 1 special) 93 | - Add email verification workflow 94 | 95 | ❌ Missing: 96 | - No refresh token endpoint implemented yet 97 | - Missing logout functionality 98 | ``` 99 | 100 | ## Step 5: Fix Issues 101 | 102 | **You:** "Add the missing password strength validation" 103 | 104 | **AI Assistant:** "I'll add password strength validation to match the specification." 105 | 106 | *AI adds validation code* 107 | 108 | **You:** "Also add rate limiting to the login endpoint" 109 | 110 | **AI Assistant:** "I'll add rate limiting to prevent brute force attacks." 111 | 112 | *AI implements rate limiting* 113 | 114 | ## Step 6: Re-check Compliance 115 | 116 | **You:** "Check the compliance again" 117 | 118 | **Carrot AI PM reports:** 119 | 120 | ``` 121 | Compliance Report for Authentication API 122 | ======================================== 123 | 124 | Overall Score: 98% ✅ 125 | 126 | ✅ All previous issues fixed: 127 | - Password strength validation added 128 | - Rate limiting implemented (5 attempts per 15 minutes) 129 | 130 | ✅ Security best practices: 131 | - Passwords hashed with bcrypt (10 rounds) 132 | - JWT tokens expire after 1 hour 133 | - Sensitive data excluded from responses 134 | 135 | Remaining suggestions: 136 | - Consider implementing refresh tokens 137 | - Add email verification for new accounts 138 | ``` 139 | 140 | ## Step 7: Generate Tests 141 | 142 | **You:** "Create tests for the authentication endpoints based on the specification" 143 | 144 | **AI Assistant:** "I'll generate comprehensive tests covering all the specification requirements." 145 | 146 | *AI creates test suite including:* 147 | - Valid registration tests 148 | - Duplicate email tests 149 | - Invalid password tests 150 | - Login success/failure tests 151 | - Rate limiting tests 152 | - Token validation tests 153 | 154 | ## Key Benefits Demonstrated 155 | 156 | ### 1. Natural Language Workflow 157 | You never had to write code or complex commands - just describe what you want in plain English. 158 | 159 | ### 2. Specification-Driven 160 | The AI had clear requirements to follow, reducing misunderstandings and missing features. 161 | 162 | ### 3. Immediate Validation 163 | You found out about missing features and security issues right away, not in production. 164 | 165 | ### 4. Actionable Feedback 166 | Instead of vague "this is wrong" messages, you got specific suggestions like "add rate limiting" with implementation guidance. 167 | 168 | ### 5. Iterative Improvement 169 | You could fix issues one at a time and re-check until everything was perfect. 170 | 171 | ## Common Conversations 172 | 173 | **You:** "What security best practices should this API follow?" 174 | 175 | **AI + Carrot:** "Based on the specification, your API should have: 176 | - Password hashing (✅ implemented with bcrypt) 177 | - Rate limiting (✅ added to login) 178 | - JWT expiration (✅ 1 hour timeout) 179 | - HTTPS only (⚠️ configure in production) 180 | - Input sanitization (✅ implemented) 181 | - SQL injection prevention (✅ using parameterized queries)" 182 | 183 | **You:** "How can I make this API more scalable?" 184 | 185 | **AI + Carrot:** "Consider these improvements: 186 | - Add caching for user lookups (Redis) 187 | - Implement connection pooling for database 188 | - Use refresh tokens to reduce login frequency 189 | - Add API versioning for future changes 190 | - Implement pagination on user listing (✅ already in spec)" 191 | 192 | ## Next Steps 193 | 194 | **You:** "What else should I implement for a complete user management system?" 195 | 196 | **AI + Carrot:** "Based on your specification, you still need: 197 | 1. Password reset functionality 198 | 2. Email verification system 199 | 3. User profile update endpoints 200 | 4. Admin user management endpoints 201 | 5. Audit logging for security events 202 | 6. Two-factor authentication (optional but recommended)" 203 | 204 | This demo shows how Carrot AI PM makes API development more reliable and less stressful by ensuring your AI assistant understands exactly what you need and validates that it's built correctly. -------------------------------------------------------------------------------- /examples/cli-tool-development.md: -------------------------------------------------------------------------------- 1 | # CLI Tool Development 2 | 3 | This example shows how to build command-line tools through natural language conversations with your AI assistant. 4 | 5 | ## Scenario: DevOps Deployment Tool 6 | 7 | Let's create a deployment CLI tool by talking to our AI assistant. 8 | 9 | ## Step 1: Create CLI Tool Specification 10 | 11 | **You:** "Create a specification for a deployment CLI tool that can deploy to different environments, run database migrations, and manage rollbacks" 12 | 13 | **AI Assistant:** "I'll create a comprehensive specification for your deployment CLI tool." 14 | 15 | **Carrot AI PM creates** a specification in `specs/cli/deploy-{timestamp}.json` including: 16 | - Command structure and subcommands 17 | - Options and arguments 18 | - Environment management 19 | - Migration handling 20 | - Rollback capabilities 21 | - Help documentation 22 | 23 | ## Step 2: Review the CLI Design 24 | 25 | **You:** "Show me what commands this tool will support" 26 | 27 | **AI Assistant:** "Your deployment tool will have these commands: 28 | 29 | **Main Commands:** 30 | ``` 31 | deploy Deploy application to an environment 32 | deploy init Initialize deployment configuration 33 | deploy status Check deployment status 34 | deploy rollback Rollback to previous version 35 | deploy migrate Run database migrations 36 | deploy config Manage deployment configurations 37 | deploy logs View deployment logs 38 | ``` 39 | 40 | **Key Features:** 41 | - Multiple environment support (dev, staging, prod) 42 | - Dry-run mode for safety 43 | - Interactive confirmations for production 44 | - Colored output for better readability 45 | - Progress indicators for long operations 46 | - Comprehensive error messages 47 | - Shell completion support" 48 | 49 | ## Step 3: Implement the CLI Tool 50 | 51 | **You:** "Implement the main deploy command with environment selection and safety checks" 52 | 53 | **AI Assistant:** "I'll create the deployment CLI tool following the specification." 54 | 55 | *The AI implements:* 56 | - Command parsing with proper libraries 57 | - Environment validation 58 | - Configuration loading 59 | - Safety prompts for production 60 | - Progress tracking 61 | - Error handling with helpful messages 62 | 63 | ## Step 4: Check CLI Compliance 64 | 65 | **You:** "Check if the CLI implementation matches the specification" 66 | 67 | **Carrot AI PM analyzes and reports:** 68 | 69 | ``` 70 | CLI Tool Compliance Report 71 | ========================== 72 | 73 | Overall Score: 93% ✅ 74 | 75 | ✅ Command Structure 76 | - All main commands implemented 77 | - Subcommands properly nested 78 | - Aliases working correctly 79 | 80 | ✅ Arguments & Options 81 | - Required arguments validated 82 | - Optional flags have defaults 83 | - Mutually exclusive options handled 84 | 85 | ✅ User Experience 86 | - Help text clear and comprehensive 87 | - Error messages actionable 88 | - Progress indicators for long tasks 89 | - Colored output for clarity 90 | 91 | ⚠️ Suggestions: 92 | - Add --json flag for scripting 93 | - Implement shell completion scripts 94 | - Add verbose logging option 95 | 96 | ❌ Missing: 97 | - No configuration file validation 98 | - Missing dry-run for rollback command 99 | ``` 100 | 101 | ## Step 5: Improve Based on Feedback 102 | 103 | **You:** "Add the --json output flag for automation" 104 | 105 | **AI Assistant:** "I'll add JSON output support for scripting and automation." 106 | 107 | *AI implements JSON output* 108 | 109 | **You:** "Also add shell completion for bash and zsh" 110 | 111 | **AI Assistant:** "I'll add shell completion scripts for better developer experience." 112 | 113 | *AI creates completion scripts* 114 | 115 | ## Step 6: Create Usage Examples 116 | 117 | **You:** "Show me common usage scenarios for this tool" 118 | 119 | **AI Assistant:** "Here are typical deployment scenarios: 120 | 121 | **Development Deployment:** 122 | ```bash 123 | # Quick deploy to dev 124 | deploy dev 125 | 126 | # Deploy specific branch 127 | deploy dev --branch feature/new-ui 128 | 129 | # Dry run to see what would happen 130 | deploy dev --dry-run 131 | ``` 132 | 133 | **Production Deployment:** 134 | ```bash 135 | # Deploy to production with confirmations 136 | deploy prod --version v2.1.0 137 | 138 | # Deploy with migrations 139 | deploy prod --version v2.1.0 --migrate 140 | 141 | # Emergency rollback 142 | deploy rollback prod --to-version v2.0.9 143 | ``` 144 | 145 | **Database Operations:** 146 | ```bash 147 | # Run migrations only 148 | deploy migrate prod --up 149 | 150 | # Rollback last migration 151 | deploy migrate prod --down 1 152 | 153 | # Check migration status 154 | deploy migrate status prod 155 | ``` 156 | 157 | **Monitoring:** 158 | ```bash 159 | # Check deployment status 160 | deploy status prod 161 | 162 | # View recent logs 163 | deploy logs prod --lines 100 164 | 165 | # Follow logs in real-time 166 | deploy logs prod --follow 167 | ```" 168 | 169 | ## Common CLI Conversations 170 | 171 | **You:** "How can I make deployments safer?" 172 | 173 | **AI + Carrot:** "Your CLI already has safety features, but here are more: 174 | 175 | **Implemented:** 176 | - ✅ Production confirmation prompts 177 | - ✅ Dry-run mode 178 | - ✅ Version validation 179 | - ✅ Environment checks 180 | 181 | **Additional Safety Measures:** 182 | 1. **Pre-flight Checks** - Test connections before deploying 183 | 2. **Backup Creation** - Auto-backup before changes 184 | 3. **Health Checks** - Verify app health after deploy 185 | 4. **Gradual Rollout** - Deploy to % of servers first 186 | 5. **Automatic Rollback** - Revert on health check failure" 187 | 188 | **You:** "What about team collaboration features?" 189 | 190 | **AI + Carrot:** "Consider adding these collaboration features: 191 | 192 | **Deployment Notifications:** 193 | - Slack/Discord webhooks 194 | - Email notifications 195 | - Deployment log to shared database 196 | 197 | **Access Control:** 198 | - Environment-based permissions 199 | - Approval workflow for production 200 | - Audit trail of who deployed what 201 | 202 | **Team Features:** 203 | - Deployment locks to prevent conflicts 204 | - Shared configuration management 205 | - Team-specific environment variables" 206 | 207 | **You:** "How do I handle secrets securely?" 208 | 209 | **AI + Carrot:** "Here's how to manage secrets safely: 210 | 211 | **Never in Code:** 212 | - ❌ Don't hardcode secrets 213 | - ❌ Don't commit .env files 214 | - ❌ Don't log sensitive data 215 | 216 | **Secure Approaches:** 217 | 1. **Environment Variables** - From secure sources 218 | 2. **Secret Managers** - AWS Secrets, Vault 219 | 3. **Encrypted Files** - GPG encrypted configs 220 | 4. **Runtime Injection** - Fetch at deploy time 221 | 222 | **Implementation:** 223 | ```bash 224 | # Use secret manager 225 | deploy prod --secrets-from aws-secrets 226 | 227 | # Encrypted config 228 | deploy prod --config secrets.gpg 229 | 230 | # Environment injection 231 | DEPLOY_KEY=$SECRET deploy prod 232 | ```" 233 | 234 | ## Advanced CLI Features 235 | 236 | **You:** "Add support for multi-region deployments" 237 | 238 | **AI Assistant:** "I'll extend the CLI to support deploying to multiple regions: 239 | 240 | **New Commands:** 241 | ```bash 242 | # Deploy to specific regions 243 | deploy prod --regions us-east-1,eu-west-1 244 | 245 | # Deploy to all regions 246 | deploy prod --all-regions 247 | 248 | # Rolling deployment across regions 249 | deploy prod --rolling --region-delay 5m 250 | 251 | # Region-specific status 252 | deploy status prod --region us-east-1 253 | ``` 254 | 255 | **Features Added:** 256 | - Parallel region deployments 257 | - Region health checks 258 | - Cross-region synchronization 259 | - Region-specific rollbacks" 260 | 261 | ## Testing the CLI 262 | 263 | **You:** "Create tests for the CLI commands" 264 | 265 | **AI Assistant:** "I'll create comprehensive CLI tests: 266 | 267 | **Test Categories:** 268 | 1. **Command Parsing** - Argument validation 269 | 2. **Error Handling** - Invalid inputs 270 | 3. **Integration Tests** - Real deployments 271 | 4. **User Experience** - Output formatting 272 | 273 | **Example Test Output:** 274 | ``` 275 | ✓ deploy command requires environment 276 | ✓ --dry-run prevents actual deployment 277 | ✓ production requires confirmation 278 | ✓ invalid version shows helpful error 279 | ✓ progress bar updates correctly 280 | ✓ JSON output is valid 281 | ✓ completion scripts work 282 | ```" 283 | 284 | ## CLI Best Practices Highlighted 285 | 286 | ### 1. User-Friendly Design 287 | Clear commands, helpful errors, and intuitive options make the tool easy to use. 288 | 289 | ### 2. Safety First 290 | Production safeguards, dry-run mode, and confirmations prevent accidents. 291 | 292 | ### 3. Automation Support 293 | JSON output, exit codes, and quiet mode enable scripting. 294 | 295 | ### 4. Great Documentation 296 | Built-in help, examples, and man pages guide users. 297 | 298 | ### 5. Progressive Disclosure 299 | Simple commands for common tasks, advanced options when needed. 300 | 301 | ## Next Steps 302 | 303 | **You:** "What other features would make this deployment tool better?" 304 | 305 | **AI + Carrot:** "Consider adding these advanced features: 306 | 307 | 1. **Deployment Strategies** 308 | - Blue-green deployments 309 | - Canary releases 310 | - Feature flags integration 311 | 312 | 2. **Monitoring Integration** 313 | - Datadog/New Relic markers 314 | - Custom metrics publishing 315 | - Automated smoke tests 316 | 317 | 3. **Pipeline Support** 318 | - CI/CD integration 319 | - Webhook triggers 320 | - Status badges 321 | 322 | 4. **Advanced Rollback** 323 | - Database rollback coordination 324 | - Asset rollback 325 | - Configuration rollback 326 | 327 | 5. **Cost Optimization** 328 | - Resource usage reports 329 | - Cost estimates before deploy 330 | - Cleanup old deployments" 331 | 332 | This example shows how Carrot AI PM helps build better CLI tools by: 333 | - Designing intuitive command structures 334 | - Ensuring comprehensive help documentation 335 | - Validating safety features are implemented 336 | - Suggesting improvements for team use 337 | - Making tools that developers actually want to use -------------------------------------------------------------------------------- /examples/db-schema-evolution.md: -------------------------------------------------------------------------------- 1 | # Database Schema Evolution 2 | 3 | This example shows how to design and evolve database schemas through natural language conversations. 4 | 5 | ## Scenario: E-commerce Database Design 6 | 7 | Let's build a complete e-commerce database by talking to our AI assistant. 8 | 9 | ## Step 1: Create Initial Schema Specification 10 | 11 | **You:** "Create a database schema specification for an e-commerce platform with users, products, orders, and inventory tracking" 12 | 13 | **AI Assistant:** "I'll create a comprehensive database schema specification for your e-commerce platform." 14 | 15 | **Carrot AI PM creates** specifications in `specs/db/` including: 16 | - User authentication and profiles 17 | - Product catalog with categories 18 | - Order management system 19 | - Inventory tracking 20 | - Shopping cart functionality 21 | 22 | ## Step 2: Review the Schema Design 23 | 24 | **You:** "Show me the main tables and their relationships" 25 | 26 | **AI Assistant:** "Here's the database structure created for your e-commerce platform: 27 | 28 | **Core Tables:** 29 | 1. **users** - Customer accounts and authentication 30 | 2. **products** - Product catalog 31 | 3. **categories** - Product categorization 32 | 4. **orders** - Customer orders 33 | 5. **order_items** - Individual items in orders 34 | 6. **inventory** - Stock tracking 35 | 7. **cart_items** - Shopping cart contents 36 | 8. **addresses** - Shipping/billing addresses 37 | 9. **payment_methods** - Saved payment options 38 | 39 | **Key Relationships:** 40 | - Users → Orders (one-to-many) 41 | - Orders → Order Items → Products (many-to-many) 42 | - Products → Categories (many-to-many) 43 | - Products → Inventory (one-to-one) 44 | - Users → Cart Items → Products (shopping cart) 45 | - Users → Addresses (one-to-many)" 46 | 47 | ## Step 3: Implement the Database Schema 48 | 49 | **You:** "Create the SQL for the users and products tables based on the specification" 50 | 51 | **AI Assistant:** "I'll create the SQL schema following the specification." 52 | 53 | *The AI generates SQL with:* 54 | - Proper data types 55 | - Primary and foreign keys 56 | - Indexes for performance 57 | - Constraints for data integrity 58 | - Default values 59 | - Timestamps for auditing 60 | 61 | ## Step 4: Check Schema Compliance 62 | 63 | **You:** "Check if the database implementation matches the specification" 64 | 65 | **Carrot AI PM analyzes and reports:** 66 | 67 | ``` 68 | Database Schema Compliance Report 69 | ================================= 70 | 71 | Overall Score: 91% ✅ 72 | 73 | ✅ Table Structure 74 | - All required tables created 75 | - Column data types match specification 76 | - Primary keys properly defined 77 | 78 | ✅ Relationships 79 | - Foreign keys correctly implemented 80 | - Cascade rules appropriate 81 | - Junction tables for many-to-many 82 | 83 | ✅ Constraints 84 | - NOT NULL constraints in place 85 | - UNIQUE constraints on emails, SKUs 86 | - CHECK constraints for valid data 87 | 88 | ⚠️ Performance Suggestions: 89 | - Add index on orders.user_id for faster lookups 90 | - Consider composite index on (product_id, created_at) 91 | - Add index on products.sku for inventory queries 92 | 93 | ❌ Missing: 94 | - No full-text search index on product names 95 | - Missing audit triggers for order changes 96 | ``` 97 | 98 | ## Step 5: Optimize Based on Feedback 99 | 100 | **You:** "Add the suggested indexes for better performance" 101 | 102 | **AI Assistant:** "I'll add the performance indexes." 103 | 104 | *AI adds indexes* 105 | 106 | **You:** "Also add full-text search for product names and descriptions" 107 | 108 | **AI Assistant:** "I'll implement full-text search capabilities." 109 | 110 | *AI adds full-text indexes* 111 | 112 | ## Step 6: Handle Schema Evolution 113 | 114 | **You:** "We need to add support for product reviews and ratings" 115 | 116 | **AI Assistant:** "I'll extend the schema to support reviews. This requires: 117 | 118 | **New Tables:** 119 | - **reviews** - Customer product reviews 120 | - **review_votes** - Helpful/unhelpful votes 121 | 122 | **Schema Changes:** 123 | - Add average_rating to products table 124 | - Add review_count to products table 125 | - Create triggers to update ratings 126 | 127 | Here's the migration plan..." 128 | 129 | *AI provides migration SQL* 130 | 131 | ## Step 7: Validate the Migration 132 | 133 | **You:** "Check if the review system implementation is correct" 134 | 135 | **Carrot AI PM reports:** 136 | 137 | ``` 138 | Migration Compliance Report 139 | ========================== 140 | 141 | ✅ New tables created correctly 142 | ✅ Foreign keys maintain referential integrity 143 | ✅ Triggers update product ratings automatically 144 | ✅ Indexes added for performance 145 | ✅ Backward compatibility maintained 146 | 147 | Migration safe to deploy! 148 | ``` 149 | 150 | ## Common Database Conversations 151 | 152 | **You:** "How can we improve query performance for order history?" 153 | 154 | **AI + Carrot:** "Based on your schema and common queries: 155 | 156 | **Current Optimizations:** 157 | - ✅ Index on orders.user_id 158 | - ✅ Index on orders.created_at 159 | - ✅ Composite index on order_items 160 | 161 | **Suggested Improvements:** 162 | 1. Add covering index for order summary queries 163 | 2. Consider partitioning orders table by date 164 | 3. Add materialized view for order statistics 165 | 4. Implement Redis caching for recent orders" 166 | 167 | **You:** "What about data security and privacy?" 168 | 169 | **AI + Carrot:** "Your schema includes several security features: 170 | 171 | **Implemented:** 172 | - ✅ Password hashes (never plain text) 173 | - ✅ Separate PII in users table 174 | - ✅ Audit timestamps on sensitive tables 175 | 176 | **Recommendations:** 177 | - 🔒 Encrypt credit card tokens 178 | - 🔒 Add row-level security for multi-tenant 179 | - 🔒 Implement soft deletes for compliance 180 | - 🔒 Add data retention policies" 181 | 182 | **You:** "How do we handle high-volume Black Friday traffic?" 183 | 184 | **AI + Carrot:** "Here's a scaling strategy for your schema: 185 | 186 | **Database Level:** 187 | 1. **Read Replicas** - Distribute read queries 188 | 2. **Connection Pooling** - Optimize connections 189 | 3. **Query Caching** - Cache frequent queries 190 | 4. **Sharding** - Split users by region 191 | 192 | **Application Level:** 193 | 1. **Inventory Reserve** - Prevent overselling 194 | 2. **Queue Orders** - Process asynchronously 195 | 3. **Cache Products** - Reduce database hits 196 | 4. **CDN Assets** - Offload static content" 197 | 198 | ## Schema Best Practices Demonstrated 199 | 200 | ### 1. Normalization 201 | The schema follows 3NF to prevent data anomalies while allowing strategic denormalization for performance. 202 | 203 | ### 2. Data Integrity 204 | Foreign keys, constraints, and triggers ensure data remains consistent. 205 | 206 | ### 3. Performance First 207 | Indexes are created based on actual query patterns, not guesswork. 208 | 209 | ### 4. Scalability Built-in 210 | The design supports horizontal scaling and caching strategies. 211 | 212 | ### 5. Security by Design 213 | Sensitive data is properly isolated and encrypted. 214 | 215 | ## Advanced Schema Features 216 | 217 | **You:** "Show me how to implement multi-currency support" 218 | 219 | **AI + Carrot:** "To add multi-currency support: 220 | 221 | **Schema Changes:** 222 | ```sql 223 | -- Add currency table 224 | CREATE TABLE currencies ( 225 | code CHAR(3) PRIMARY KEY, 226 | name VARCHAR(50), 227 | symbol VARCHAR(5), 228 | exchange_rate DECIMAL(10,6) 229 | ); 230 | 231 | -- Modify products table 232 | ALTER TABLE products 233 | ADD COLUMN currency_code CHAR(3) DEFAULT 'USD', 234 | ADD FOREIGN KEY (currency_code) REFERENCES currencies(code); 235 | 236 | -- Modify orders table 237 | ALTER TABLE orders 238 | ADD COLUMN currency_code CHAR(3), 239 | ADD COLUMN exchange_rate DECIMAL(10,6); 240 | ``` 241 | 242 | **Implementation Notes:** 243 | - Store prices in product's native currency 244 | - Lock exchange rate at order time 245 | - Display prices in user's preferred currency 246 | - Update exchange rates via scheduled job" 247 | 248 | ## Next Steps 249 | 250 | **You:** "What other features should we consider for a modern e-commerce database?" 251 | 252 | **AI + Carrot:** "Consider adding these features: 253 | 254 | 1. **Wishlist System** - Save products for later 255 | 2. **Recommendation Engine** - Track user preferences 256 | 3. **Loyalty Program** - Points and rewards 257 | 4. **Subscription Orders** - Recurring purchases 258 | 5. **Multi-vendor Support** - Marketplace functionality 259 | 6. **Advanced Analytics** - User behavior tracking 260 | 7. **A/B Testing** - Feature flag support 261 | 8. **Event Sourcing** - Complete audit trail" 262 | 263 | This example shows how Carrot AI PM helps with database design by: 264 | - Creating comprehensive schemas from requirements 265 | - Validating implementations against best practices 266 | - Suggesting performance optimizations 267 | - Guiding schema evolution safely 268 | - Ensuring security and scalability from the start -------------------------------------------------------------------------------- /examples/full-stack-demo.md: -------------------------------------------------------------------------------- 1 | # Full Stack Application Demo 2 | 3 | This example shows how to build a complete e-commerce platform through natural language conversations with your AI assistant. 4 | 5 | ## Scenario: Building an E-commerce Platform 6 | 7 | Let's create a full-stack e-commerce application by talking to our AI assistant, using all of Carrot AI PM's capabilities. 8 | 9 | ## Phase 1: Planning the Application 10 | 11 | **You:** "I want to build an e-commerce platform. Help me plan the architecture and create specifications for all the components" 12 | 13 | **AI Assistant:** "I'll help you design a complete e-commerce platform. Let me break this down into components: 14 | 15 | **Frontend:** 16 | - Product browsing and search 17 | - Shopping cart 18 | - User authentication 19 | - Order management 20 | - Admin dashboard 21 | 22 | **Backend:** 23 | - REST API for all operations 24 | - Authentication & authorization 25 | - Payment processing 26 | - Inventory management 27 | 28 | **Database:** 29 | - User accounts 30 | - Product catalog 31 | - Orders and transactions 32 | - Inventory tracking 33 | 34 | Let's start by creating specifications for each component." 35 | 36 | ## Phase 2: API Specification 37 | 38 | **You:** "Create specifications for the main API endpoints we'll need" 39 | 40 | **AI Assistant:** "I'll create comprehensive API specifications for your e-commerce platform." 41 | 42 | **Carrot AI PM creates** specifications for: 43 | - Authentication endpoints (register, login, logout) 44 | - Product endpoints (list, search, details) 45 | - Cart endpoints (add, update, remove) 46 | - Order endpoints (create, list, track) 47 | - Admin endpoints (inventory, users, reports) 48 | 49 | **You:** "Show me the main API endpoints" 50 | 51 | **AI Assistant:** "Here are the core API endpoints: 52 | 53 | ``` 54 | Authentication: 55 | POST /api/auth/register 56 | POST /api/auth/login 57 | POST /api/auth/logout 58 | POST /api/auth/refresh 59 | 60 | Products: 61 | GET /api/products (with pagination, filtering) 62 | GET /api/products/:id 63 | GET /api/products/search 64 | GET /api/categories 65 | 66 | Shopping Cart: 67 | GET /api/cart 68 | POST /api/cart/items 69 | PUT /api/cart/items/:id 70 | DELETE /api/cart/items/:id 71 | 72 | Orders: 73 | POST /api/orders 74 | GET /api/orders 75 | GET /api/orders/:id 76 | POST /api/orders/:id/cancel 77 | 78 | User Profile: 79 | GET /api/profile 80 | PUT /api/profile 81 | GET /api/addresses 82 | POST /api/addresses 83 | ```" 84 | 85 | ## Phase 3: Database Design 86 | 87 | **You:** "Design the database schema for this e-commerce platform" 88 | 89 | **AI Assistant:** "I'll create a comprehensive database schema for your platform." 90 | 91 | **Carrot AI PM designs** tables for: 92 | - Users and authentication 93 | - Products and categories 94 | - Shopping carts 95 | - Orders and order items 96 | - Inventory management 97 | - Payment records 98 | - Reviews and ratings 99 | 100 | ## Phase 4: UI Components 101 | 102 | **You:** "Create specifications for the main UI components we'll need" 103 | 104 | **AI Assistant:** "I'll specify the key UI components for your e-commerce platform." 105 | 106 | **Carrot AI PM creates** specifications for: 107 | - ProductCard component 108 | - ShoppingCart component 109 | - CheckoutForm component 110 | - OrderSummary component 111 | - UserProfile component 112 | - SearchBar component 113 | - ProductFilter component 114 | 115 | ## Phase 5: Implementation - API First 116 | 117 | **You:** "Let's start implementing. First, create the authentication API" 118 | 119 | **AI Assistant:** "I'll implement the authentication API following the specifications." 120 | 121 | *AI implements authentication with:* 122 | - User registration with email verification 123 | - Secure login with JWT tokens 124 | - Password hashing 125 | - Rate limiting 126 | - Refresh token support 127 | 128 | **You:** "Check if the authentication API matches the specification" 129 | 130 | **Carrot AI PM reports:** 131 | ``` 132 | ✅ Authentication API Compliance: 96% 133 | - All endpoints implemented correctly 134 | - Security best practices followed 135 | - Minor suggestion: Add 2FA support 136 | ``` 137 | 138 | ## Phase 6: Implementation - Database 139 | 140 | **You:** "Create the database tables for users, products, and orders" 141 | 142 | **AI Assistant:** "I'll create the database schema following our design." 143 | 144 | *AI creates SQL with proper:* 145 | - Table relationships 146 | - Indexes for performance 147 | - Constraints for data integrity 148 | - Triggers for automated updates 149 | 150 | **You:** "Validate the database implementation" 151 | 152 | **Carrot AI PM reports:** 153 | ``` 154 | ✅ Database Compliance: 94% 155 | - All tables created correctly 156 | - Foreign keys properly set 157 | - Indexes optimized 158 | - Suggestion: Add full-text search on products 159 | ``` 160 | 161 | ## Phase 7: Implementation - Frontend Components 162 | 163 | **You:** "Build the ProductCard component for displaying products" 164 | 165 | **AI Assistant:** "I'll create the ProductCard component with all specified features." 166 | 167 | *AI implements:* 168 | - Responsive design 169 | - Image lazy loading 170 | - Add to cart functionality 171 | - Quick view option 172 | - Accessibility features 173 | 174 | **You:** "Check the ProductCard implementation" 175 | 176 | **Carrot AI PM reports:** 177 | ``` 178 | ✅ Component Compliance: 95% 179 | - All props implemented 180 | - Accessibility standards met 181 | - Performance optimized 182 | - Suggestion: Add loading skeleton 183 | ``` 184 | 185 | ## Phase 8: Integration Testing 186 | 187 | **You:** "How do I test that all these components work together?" 188 | 189 | **AI Assistant:** "I'll help you create integration tests. Here's what we should test: 190 | 191 | **API Integration Tests:** 192 | 1. User can register and login 193 | 2. Authenticated users can add to cart 194 | 3. Cart persists across sessions 195 | 4. Orders are created correctly 196 | 5. Inventory updates on purchase 197 | 198 | **Frontend Integration Tests:** 199 | 1. Product search and filtering 200 | 2. Cart updates in real-time 201 | 3. Checkout flow completion 202 | 4. Order history display 203 | 5. Error handling throughout 204 | 205 | Let me create these tests..." 206 | 207 | *AI creates comprehensive integration tests* 208 | 209 | ## Phase 9: Performance Optimization 210 | 211 | **You:** "The product listing page is slow with many products. How can we optimize it?" 212 | 213 | **AI + Carrot:** "Let's analyze and optimize performance: 214 | 215 | **Current Issues:** 216 | - Loading all products at once 217 | - No caching implemented 218 | - Large images not optimized 219 | 220 | **Solutions Implemented:** 221 | 1. **Pagination** - Load 20 products at a time 222 | 2. **Virtual Scrolling** - Render only visible items 223 | 3. **Image Optimization** - WebP format, multiple sizes 224 | 4. **API Caching** - Redis for frequent queries 225 | 5. **Database Indexes** - Added for common filters 226 | 227 | **Results:** 228 | - Page load time: 3.2s → 0.8s 229 | - API response: 800ms → 150ms 230 | - Image sizes: 70% smaller" 231 | 232 | ## Phase 10: Security Audit 233 | 234 | **You:** "Check the entire application for security issues" 235 | 236 | **AI + Carrot:** "Running security audit across all components: 237 | 238 | **✅ Implemented Security:** 239 | - Password hashing (bcrypt) 240 | - JWT authentication 241 | - HTTPS enforcement 242 | - SQL injection prevention 243 | - XSS protection 244 | - CSRF tokens 245 | - Rate limiting 246 | 247 | **⚠️ Recommendations:** 248 | 1. Add 2FA authentication 249 | 2. Implement API key rotation 250 | 3. Add security headers 251 | 4. Enable audit logging 252 | 5. Set up intrusion detection 253 | 254 | **Security Score: 91/100**" 255 | 256 | ## Common Full-Stack Conversations 257 | 258 | **You:** "How do I handle payments securely?" 259 | 260 | **AI + Carrot:** "For secure payment processing: 261 | 262 | **Never Store:** 263 | - ❌ Credit card numbers 264 | - ❌ CVV codes 265 | - ❌ Full card details 266 | 267 | **Best Practices:** 268 | 1. **Use Payment Providers** - Stripe, PayPal 269 | 2. **Tokenization** - Store only tokens 270 | 3. **PCI Compliance** - Follow standards 271 | 4. **Secure Forms** - Use provider's UI 272 | 5. **Webhook Validation** - Verify callbacks 273 | 274 | **Implementation:** 275 | ```javascript 276 | // Use Stripe for secure payments 277 | const session = await stripe.checkout.sessions.create({ 278 | payment_method_types: ['card'], 279 | line_items: cartItems, 280 | success_url: `${YOUR_DOMAIN}/success`, 281 | cancel_url: `${YOUR_DOMAIN}/cancel`, 282 | }); 283 | ```" 284 | 285 | **You:** "How should I handle real-time features like inventory updates?" 286 | 287 | **AI + Carrot:** "For real-time features, consider: 288 | 289 | **Technologies:** 290 | 1. **WebSockets** - For bidirectional communication 291 | 2. **Server-Sent Events** - For server-to-client updates 292 | 3. **Polling** - Simple but less efficient 293 | 294 | **Implementation Approach:** 295 | - Use Socket.io for cross-browser support 296 | - Implement rooms for product-specific updates 297 | - Cache current inventory in Redis 298 | - Batch updates to reduce load 299 | 300 | **Example Flow:** 301 | 1. User views product 302 | 2. Subscribe to inventory updates 303 | 3. Another user makes purchase 304 | 4. Broadcast inventory change 305 | 5. UI updates automatically" 306 | 307 | ## Deployment Considerations 308 | 309 | **You:** "How do I deploy this full-stack application?" 310 | 311 | **AI + Carrot:** "Here's a production deployment strategy: 312 | 313 | **Frontend Deployment:** 314 | - Build optimized bundle 315 | - Deploy to CDN (CloudFront, Netlify) 316 | - Enable caching and compression 317 | - Set up custom domain with SSL 318 | 319 | **Backend Deployment:** 320 | - Containerize with Docker 321 | - Deploy to cloud (AWS ECS, Google Cloud Run) 322 | - Set up load balancer 323 | - Configure auto-scaling 324 | 325 | **Database Deployment:** 326 | - Use managed service (RDS, Cloud SQL) 327 | - Set up read replicas 328 | - Enable automated backups 329 | - Configure connection pooling 330 | 331 | **Additional Services:** 332 | - Redis for caching (ElastiCache) 333 | - File storage (S3) 334 | - Email service (SendGrid) 335 | - Monitoring (DataDog, New Relic)" 336 | 337 | ## Monitoring and Maintenance 338 | 339 | **You:** "What should I monitor once the app is live?" 340 | 341 | **AI + Carrot:** "Set up comprehensive monitoring: 342 | 343 | **Application Metrics:** 344 | - Response times 345 | - Error rates 346 | - API usage by endpoint 347 | - User activity patterns 348 | 349 | **Business Metrics:** 350 | - Conversion rates 351 | - Cart abandonment 352 | - Average order value 353 | - Product view-to-purchase ratio 354 | 355 | **Infrastructure Metrics:** 356 | - Server CPU/memory 357 | - Database query performance 358 | - Cache hit rates 359 | - CDN bandwidth 360 | 361 | **Alerts to Configure:** 362 | - High error rates (> 1%) 363 | - Slow response times (> 2s) 364 | - Failed payments 365 | - Low inventory warnings 366 | - Security anomalies" 367 | 368 | ## Scaling Strategies 369 | 370 | **You:** "How do I prepare for Black Friday traffic?" 371 | 372 | **AI + Carrot:** "Here's your Black Friday scaling plan: 373 | 374 | **Pre-Event Preparation:** 375 | 1. **Load Testing** - Simulate 10x normal traffic 376 | 2. **Database Optimization** - Add indexes, optimize queries 377 | 3. **Caching Strategy** - Pre-cache popular products 378 | 4. **CDN Warming** - Pre-load static assets 379 | 5. **Inventory Reserve** - Prevent overselling 380 | 381 | **Auto-Scaling Configuration:** 382 | - API servers: Scale at 70% CPU 383 | - Database: Read replicas ready 384 | - Cache: Increased memory 385 | - Queue workers: Scale with queue depth 386 | 387 | **Day-of Monitoring:** 388 | - Real-time dashboard 389 | - On-call team ready 390 | - Rollback plan prepared 391 | - Communication channels open" 392 | 393 | ## Lessons Learned 394 | 395 | This full-stack example demonstrates how Carrot AI PM helps throughout the entire development lifecycle: 396 | 397 | 1. **Specification-Driven** - Clear requirements before coding 398 | 2. **Component Validation** - Each piece checked independently 399 | 3. **Integration Testing** - Ensuring parts work together 400 | 4. **Performance Focus** - Optimization based on metrics 401 | 5. **Security First** - Built-in from the start 402 | 6. **Production Ready** - Deployment and scaling considered 403 | 404 | By using natural language conversations with your AI assistant and Carrot AI PM's validation tools, you can build complex applications with confidence that each component meets its requirements and works well with others. -------------------------------------------------------------------------------- /examples/ui-component-workflow.md: -------------------------------------------------------------------------------- 1 | # UI Component Workflow 2 | 3 | This example shows how to build React components using natural language conversations with your AI assistant. 4 | 5 | ## Scenario: Building a Product Card Component 6 | 7 | Let's create a reusable e-commerce product card by talking to our AI assistant. 8 | 9 | ## Step 1: Create the Component Specification 10 | 11 | **You:** "Create a specification for an e-commerce product card component with image, pricing, ratings, and add-to-cart functionality" 12 | 13 | **AI Assistant:** "I'll create a detailed specification for your product card component." 14 | 15 | **Carrot AI PM creates** a specification in `specs/ui/ProductCard-{timestamp}.json` that includes: 16 | - Component props (product data, callbacks) 17 | - State management (hover, loading states) 18 | - Accessibility requirements 19 | - Responsive design needs 20 | - Performance optimizations 21 | 22 | ## Step 2: Review the Specification 23 | 24 | **You:** "What features will this product card have?" 25 | 26 | **AI Assistant:** "Based on the specification, your ProductCard component will have: 27 | 28 | **Visual Features:** 29 | - Product image with lazy loading 30 | - Product name and description 31 | - Price display with sale price support 32 | - Star rating with review count 33 | - Add to cart button 34 | - Discount badge for sales 35 | 36 | **Interactive Features:** 37 | - Hover effects on desktop 38 | - Click to view product details 39 | - Add to cart with loading state 40 | - Keyboard navigation support 41 | 42 | **Technical Requirements:** 43 | - TypeScript interfaces for type safety 44 | - Responsive design (mobile-first) 45 | - Accessibility (ARIA labels, keyboard nav) 46 | - Performance (image lazy loading, memoization) 47 | - Theme support (light/dark modes)" 48 | 49 | ## Step 3: Implement the Component 50 | 51 | **You:** "Implement this product card component in React with TypeScript" 52 | 53 | **AI Assistant:** "I'll create the ProductCard component following the specification." 54 | 55 | *The AI creates:* 56 | - TypeScript interfaces for props 57 | - React component with hooks 58 | - CSS modules for styling 59 | - Proper event handlers 60 | - Loading states 61 | - Error boundaries 62 | 63 | ## Step 4: Check Component Compliance 64 | 65 | **You:** "Check if the product card implementation matches the specification" 66 | 67 | **Carrot AI PM analyzes and reports:** 68 | 69 | ``` 70 | Component Compliance Report: ProductCard 71 | ======================================== 72 | 73 | Overall Score: 94% ✅ 74 | 75 | ✅ Props Implementation 76 | - All required props defined with correct types 77 | - Optional props have default values 78 | - TypeScript interfaces match specification 79 | 80 | ✅ Accessibility 81 | - ARIA labels for screen readers 82 | - Keyboard navigation (Enter/Space for actions) 83 | - Focus indicators visible 84 | - Alt text for images 85 | 86 | ✅ State Management 87 | - Loading states implemented 88 | - Hover effects working 89 | - Error handling in place 90 | 91 | ⚠️ Suggestions: 92 | - Add aria-live region for cart updates 93 | - Implement skeleton loader for better UX 94 | - Consider adding product comparison feature 95 | 96 | ❌ Missing: 97 | - No theme support implemented yet 98 | - Missing price formatting for different currencies 99 | ``` 100 | 101 | ## Step 5: Improve Based on Feedback 102 | 103 | **You:** "Add theme support for light and dark modes" 104 | 105 | **AI Assistant:** "I'll add theme support using CSS custom properties." 106 | 107 | *AI implements theming* 108 | 109 | **You:** "Also add the skeleton loader while the image is loading" 110 | 111 | **AI Assistant:** "I'll add a skeleton loader for better perceived performance." 112 | 113 | *AI adds skeleton loading state* 114 | 115 | ## Step 6: Create Component Tests 116 | 117 | **You:** "Create tests for the product card component" 118 | 119 | **AI Assistant:** "I'll create comprehensive tests based on the specification." 120 | 121 | *AI generates tests for:* 122 | - Component rendering 123 | - Props validation 124 | - User interactions 125 | - Accessibility features 126 | - Loading states 127 | - Error scenarios 128 | 129 | ## Step 7: Create Usage Examples 130 | 131 | **You:** "Show me how to use this product card in different scenarios" 132 | 133 | **AI Assistant:** "Here are examples of using the ProductCard component: 134 | 135 | **Basic Usage:** 136 | ```jsx 137 | addToCart(id)} 140 | /> 141 | ``` 142 | 143 | **With Sale Price:** 144 | ```jsx 145 | addToCart(id)} 152 | /> 153 | ``` 154 | 155 | **In a Grid Layout:** 156 | ```jsx 157 |
158 | {products.map(product => ( 159 | 165 | ))} 166 |
167 | ```" 168 | 169 | ## Common Conversations 170 | 171 | **You:** "How can I make this component more accessible?" 172 | 173 | **AI + Carrot:** "Your component already has good accessibility, but you can enhance it further: 174 | - ✅ Keyboard navigation (already implemented) 175 | - ✅ ARIA labels (already added) 176 | - ✅ Focus indicators (styled) 177 | - ⚠️ Add aria-live for cart updates 178 | - ⚠️ Ensure color contrast meets WCAG AA 179 | - 💡 Add reduced motion support 180 | - 💡 Test with screen readers" 181 | 182 | **You:** "What about performance optimization?" 183 | 184 | **AI + Carrot:** "Current optimizations and suggestions: 185 | - ✅ Image lazy loading (implemented) 186 | - ✅ Component memoization (using React.memo) 187 | - ✅ Event handler optimization (useCallback) 188 | - ⚠️ Consider image optimization (WebP format) 189 | - ⚠️ Add intersection observer for viewport detection 190 | - 💡 Implement virtual scrolling for large lists" 191 | 192 | **You:** "Can this work with different CSS frameworks?" 193 | 194 | **AI + Carrot:** "Yes! The component uses CSS modules by default, but you can adapt it: 195 | - **Tailwind CSS**: Replace class names with Tailwind utilities 196 | - **Styled Components**: Convert styles to styled-components 197 | - **Material-UI**: Wrap with MUI theme provider 198 | - **Bootstrap**: Use Bootstrap classes for layout 199 | 200 | The component logic remains the same, only styling changes." 201 | 202 | ## Best Practices Highlighted 203 | 204 | ### 1. Component Composition 205 | The specification encourages building small, focused components that work together. 206 | 207 | ### 2. Type Safety 208 | TypeScript interfaces ensure props are used correctly throughout your app. 209 | 210 | ### 3. Accessibility First 211 | The spec includes accessibility requirements from the start, not as an afterthought. 212 | 213 | ### 4. Performance Built-in 214 | Lazy loading and memoization are part of the initial implementation. 215 | 216 | ### 5. Testability 217 | The component is designed to be easily testable with clear props and outputs. 218 | 219 | ## Next Steps 220 | 221 | **You:** "What other components would work well with this product card?" 222 | 223 | **AI + Carrot:** "To build a complete e-commerce UI, consider these complementary components: 224 | 225 | 1. **ProductGrid** - Responsive grid layout for multiple cards 226 | 2. **FilterPanel** - Product filtering by category, price, etc. 227 | 3. **SortDropdown** - Sort products by price, rating, etc. 228 | 4. **QuickView** - Modal for product details without navigation 229 | 5. **ComparisonTable** - Compare multiple products 230 | 6. **WishlistButton** - Save products for later 231 | 7. **ProductCarousel** - Featured products slider" 232 | 233 | This example shows how Carrot AI PM helps you build better UI components by: 234 | - Starting with clear specifications 235 | - Validating implementation against requirements 236 | - Providing specific improvement suggestions 237 | - Ensuring accessibility and performance from day one -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "carrot-ai-pm", 3 | "version": "1.0.0", 4 | "main": "dist/src/server.js", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc", 8 | "start": "node dist/src/server.js", 9 | "dev": "tsx src/server.ts", 10 | "watch": "tsc -w", 11 | "start:sse": "PORT=3000 node dist/src/server.js", 12 | "test": "echo \"Error: no test specified\" && exit 1" 13 | }, 14 | "keywords": [ 15 | "mcp", 16 | "carrot", 17 | "fastapi" 18 | ], 19 | "author": "", 20 | "license": "ISC", 21 | "dependencies": { 22 | "@modelcontextprotocol/sdk": "^1.0.4", 23 | "@types/express": "^5.0.2", 24 | "@types/js-yaml": "^4.0.9", 25 | "@types/node": "^22.15.18", 26 | "@types/node-fetch": "^2.6.12", 27 | "child_process": "^1.0.2", 28 | "express": "^5.1.0", 29 | "fs": "^0.0.1-security", 30 | "glob": "^11.0.2", 31 | "js-yaml": "^4.1.0", 32 | "node-fetch": "^2.7.0", 33 | "path": "^0.12.7", 34 | "simple-git": "^3.27.0", 35 | "ts-node": "^10.9.2", 36 | "tsx": "^4.19.4", 37 | "typescript": "^5.0.0", 38 | "zod": "^3.23.8" 39 | }, 40 | "description": "Carrot MCP server for FastAPI codebase" 41 | } 42 | -------------------------------------------------------------------------------- /src/prompts/draft_pr.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | 3 | /** 4 | * Prompt for drafting a pull request description 5 | */ 6 | export function draftPrPrompt(server: McpServer): void { 7 | server.prompt( 8 | 'draft_pr', 9 | "Generate a pull request description based on a diff", 10 | () => { 11 | return { 12 | messages: [ 13 | { 14 | role: 'user', 15 | content: { 16 | type: 'text', 17 | text: `Please generate a pull request description based on the provided diff and information. 18 | 19 | The description should include: 20 | 21 | 1. **Summary of Changes** 22 | - A brief overview of what this PR does 23 | - Key functionality added or modified 24 | 25 | 2. **Implementation Details** 26 | - Technical approach used 27 | - Any design patterns or architecture decisions worth noting 28 | - Dependencies added or removed 29 | 30 | 3. **Testing** 31 | - What tests have been added 32 | - How to verify the changes work correctly 33 | 34 | 4. **Related Issues** 35 | - Links to related issues or tickets 36 | - How this PR addresses those issues 37 | 38 | 5. **Screenshots or Examples** (if applicable) 39 | - Suggest what screenshots or examples would be helpful 40 | 41 | Please format the PR description using markdown, with clear sections and bullet points where appropriate.` 42 | } 43 | } 44 | ] 45 | }; 46 | } 47 | ); 48 | } -------------------------------------------------------------------------------- /src/prompts/explain_file.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | 3 | /** 4 | * Prompt for explaining a file's purpose and public surface 5 | */ 6 | export function explainFilePrompt(server: McpServer): void { 7 | server.prompt( 8 | 'explain_file', 9 | "Explain a file's purpose and public API surface", 10 | () => { 11 | return { 12 | messages: [ 13 | { 14 | role: 'user', 15 | content: { 16 | type: 'text', 17 | text: `Please provide a terse explanation of the provided file. 18 | 19 | Focus on: 20 | 1. The file's primary purpose 21 | 2. Any public APIs, functions, or classes it exports 22 | 3. How it fits into the overall architecture 23 | 4. Any important dependencies or relationships with other files 24 | 25 | Be concise and focus on what another developer would need to know to work with this code. 26 | 27 | Format your response with these sections: 28 | - Purpose 29 | - Public Surface 30 | - Dependencies 31 | - Usage Examples (brief) 32 | ` 33 | } 34 | } 35 | ] 36 | }; 37 | } 38 | ); 39 | } -------------------------------------------------------------------------------- /src/prompts/index.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { reviewDiffPrompt } from './review_diff.js'; 3 | import { draftPrPrompt } from './draft_pr.js'; 4 | import { explainFilePrompt } from './explain_file.js'; 5 | 6 | /** 7 | * Configure all prompts for the MCP server 8 | */ 9 | export function configurePrompts(server: McpServer): void { 10 | // Prompt for code reviews based on a git diff 11 | reviewDiffPrompt(server); 12 | 13 | // Prompt for generating PR descriptions 14 | draftPrPrompt(server); 15 | 16 | // Prompt for explaining files 17 | explainFilePrompt(server); 18 | } -------------------------------------------------------------------------------- /src/prompts/review_diff.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | 3 | /** 4 | * Prompt for reviewing a git diff 5 | */ 6 | export function reviewDiffPrompt(server: McpServer): void { 7 | server.prompt( 8 | 'review_diff', 9 | "Review a git diff and provide structured feedback", 10 | () => { 11 | return { 12 | messages: [ 13 | { 14 | role: 'user', 15 | content: { 16 | type: 'text', 17 | text: `Please review the provided code diff and provide a structured code review with these sections: 18 | 19 | 1. **Logic & Functionality** 20 | - Are there any logical errors or edge cases not handled? 21 | - Is the implementation correct and efficient? 22 | - Are there any potential bugs or unintended side effects? 23 | 24 | 2. **Code Style & Best Practices** 25 | - Does the code follow Python/FastAPI best practices? 26 | - Are there any style improvements that could be made? 27 | - Is the code readable and maintainable? 28 | 29 | 3. **Tests Needed** 30 | - What tests should be added to validate this code? 31 | - Are there any specific edge cases that should be tested? 32 | 33 | 4. **Documentation** 34 | - Is the code adequately documented? 35 | - Are there any API changes that need documentation updates? 36 | 37 | 5. **Security Concerns** 38 | - Are there any security issues or vulnerabilities? 39 | - Is user input properly validated and sanitized? 40 | 41 | 6. **Summary** 42 | - Overall assessment of the changes 43 | - Any blocking issues that must be addressed before merging 44 | 45 | Please provide your review in a clear, constructive manner.` 46 | } 47 | } 48 | ] 49 | }; 50 | } 51 | ); 52 | } -------------------------------------------------------------------------------- /src/resources/docs.ts: -------------------------------------------------------------------------------- 1 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | import { fileExists } from '../utils/path.js'; 5 | 6 | /** 7 | * Configure docs resource for accessing repo README 8 | */ 9 | export function docsResource(server: McpServer, repoRoot: string): void { 10 | // Template for docs:// resources 11 | const docsTemplate = new ResourceTemplate('docs://{docName}', { 12 | list: async () => { 13 | // Currently only supporting README.md 14 | return { 15 | resources: [{ 16 | uri: 'docs://README.md', 17 | name: 'README.md', 18 | description: 'Repository documentation', 19 | mimeType: 'text/markdown' 20 | }] 21 | }; 22 | } 23 | }); 24 | 25 | // Handler for reading doc files 26 | server.resource('docs', docsTemplate, async (uri, params) => { 27 | const { docName } = params; 28 | 29 | if (docName !== 'README.md') { 30 | throw new Error(`Doc not supported: ${docName}`); 31 | } 32 | 33 | // Look for README.md in common locations 34 | const possiblePaths = [ 35 | path.join(repoRoot, 'README.md'), 36 | path.join(repoRoot, 'carrot', 'README.md'), 37 | path.join(repoRoot, 'docs', 'README.md') 38 | ]; 39 | 40 | // Find the first existing path 41 | const docPath = possiblePaths.find(p => fileExists(p)); 42 | 43 | if (!docPath) { 44 | throw new Error('README.md not found'); 45 | } 46 | 47 | try { 48 | // Read doc content 49 | const content = fs.readFileSync(docPath, 'utf-8'); 50 | 51 | return { 52 | contents: [{ 53 | uri: uri.href, 54 | mimeType: 'text/markdown', 55 | text: content 56 | }] 57 | }; 58 | } catch (error) { 59 | console.error(`Error reading doc file ${docPath}:`, error); 60 | throw new Error('Failed to read README.md'); 61 | } 62 | }); 63 | } -------------------------------------------------------------------------------- /src/resources/file.ts: -------------------------------------------------------------------------------- 1 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | import { glob } from 'glob'; 5 | import { fileExists, isPathInRepo, resolveRepoPath } from '../utils/path.js'; 6 | 7 | /** 8 | * Configure file resource for accessing source files 9 | */ 10 | export function fileResource(server: McpServer, repoRoot: string): void { 11 | // Template for file:// resources 12 | const fileTemplate = new ResourceTemplate('file://{path}', { 13 | list: async () => { 14 | // List all files in the carrot directory 15 | const carrotDir = path.join(repoRoot, 'carrot'); 16 | 17 | if (!fs.existsSync(carrotDir)) { 18 | console.warn(`Carrot directory not found at ${carrotDir}`); 19 | return { resources: [] }; 20 | } 21 | 22 | try { 23 | // Get all files recursively in the carrot directory 24 | const files = await glob('**/*', { 25 | cwd: carrotDir, 26 | nodir: true, 27 | dot: false, 28 | ignore: ['**/node_modules/**', '**/.git/**', '**/__pycache__/**'] 29 | }); 30 | 31 | // Format as resources 32 | const resources = files.map(file => ({ 33 | uri: `file://${file}`, 34 | name: path.basename(file), 35 | description: `Source file: ${file}` 36 | })); 37 | 38 | return { resources }; 39 | } catch (error) { 40 | console.error('Error listing files:', error); 41 | return { resources: [] }; 42 | } 43 | } 44 | }); 45 | 46 | // Handler for reading individual files 47 | server.resource('file', fileTemplate, async (uri, params) => { 48 | const { path: filePath } = params; 49 | 50 | if (!filePath || typeof filePath !== 'string') { 51 | throw new Error('File path not provided or invalid'); 52 | } 53 | 54 | // Resolve the file path within the repository 55 | const carrotDir = path.join(repoRoot, 'carrot'); 56 | const fullPath = path.join(carrotDir, filePath); 57 | 58 | // Security check: ensure the path is within the repo 59 | if (!isPathInRepo(fullPath, repoRoot)) { 60 | throw new Error('Access denied: Attempting to access file outside repository'); 61 | } 62 | 63 | // Check if file exists 64 | if (!fileExists(fullPath)) { 65 | throw new Error(`File not found: ${filePath}`); 66 | } 67 | 68 | try { 69 | // Read file content 70 | const content = fs.readFileSync(fullPath, 'utf-8'); 71 | 72 | // Determine MIME type based on extension 73 | const ext = path.extname(filePath).toLowerCase(); 74 | let mimeType = 'text/plain'; 75 | 76 | if (ext === '.py') mimeType = 'text/x-python'; 77 | else if (ext === '.js') mimeType = 'application/javascript'; 78 | else if (ext === '.json') mimeType = 'application/json'; 79 | else if (ext === '.html') mimeType = 'text/html'; 80 | else if (ext === '.css') mimeType = 'text/css'; 81 | else if (ext === '.md') mimeType = 'text/markdown'; 82 | else if (ext === '.yaml' || ext === '.yml') mimeType = 'application/x-yaml'; 83 | 84 | return { 85 | contents: [{ 86 | uri: uri.href, 87 | mimeType, 88 | text: content 89 | }] 90 | }; 91 | } catch (error) { 92 | console.error(`Error reading file ${filePath}:`, error); 93 | throw new Error(`Failed to read file: ${filePath}`); 94 | } 95 | }); 96 | } -------------------------------------------------------------------------------- /src/resources/index.ts: -------------------------------------------------------------------------------- 1 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { fileResource } from './file.js'; 3 | import { specResource } from './spec.js'; 4 | import { docsResource } from './docs.js'; 5 | import { todoResource } from './todo.js'; 6 | 7 | /** 8 | * Configure all resources for the MCP server 9 | */ 10 | export function configureResources(server: McpServer, repoRoot: string): void { 11 | // File resources - any source file under /carrot 12 | fileResource(server, repoRoot); 13 | 14 | // Spec resource - the OpenAPI/vibe spec 15 | specResource(server, repoRoot); 16 | 17 | // Docs resource - repository README 18 | docsResource(server, repoRoot); 19 | 20 | // TODO/Issues resource - GitHub issues with 'carrot' label 21 | todoResource(server, repoRoot); 22 | } -------------------------------------------------------------------------------- /src/resources/spec.ts: -------------------------------------------------------------------------------- 1 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | import { fileExists, resolveRepoPath } from '../utils/path.js'; 5 | 6 | /** 7 | * Configure spec resource for accessing the OpenAPI/vibe spec 8 | */ 9 | export function specResource(server: McpServer, repoRoot: string): void { 10 | // Template for spec://vibe.yaml resource 11 | const specTemplate = new ResourceTemplate('spec://{specName}', { 12 | list: async () => { 13 | // For now, we only support the vibe.yaml spec 14 | return { 15 | resources: [{ 16 | uri: 'spec://vibe.yaml', 17 | name: 'vibe.yaml', 18 | description: 'OpenAPI specification for the API', 19 | mimeType: 'application/x-yaml' 20 | }] 21 | }; 22 | } 23 | }); 24 | 25 | // Handler for reading spec files 26 | server.resource('spec', specTemplate, async (uri, params) => { 27 | const { specName } = params; 28 | 29 | if (specName !== 'vibe.yaml') { 30 | throw new Error(`Spec not supported: ${specName}`); 31 | } 32 | 33 | // Look for vibe.yaml in common locations 34 | const possiblePaths = [ 35 | path.join(repoRoot, 'carrot', 'vibe.yaml'), 36 | path.join(repoRoot, 'vibe.yaml'), 37 | path.join(repoRoot, 'carrot', 'api', 'vibe.yaml'), 38 | path.join(repoRoot, 'carrot', 'docs', 'vibe.yaml'), 39 | path.join(repoRoot, 'docs', 'vibe.yaml'), 40 | path.join(repoRoot, 'specs', 'vibe.yaml') 41 | ]; 42 | 43 | // Find the first existing path 44 | const specPath = possiblePaths.find(p => fileExists(p)); 45 | 46 | if (!specPath) { 47 | throw new Error('OpenAPI spec file vibe.yaml not found'); 48 | } 49 | 50 | try { 51 | // Read spec content 52 | const content = fs.readFileSync(specPath, 'utf-8'); 53 | 54 | return { 55 | contents: [{ 56 | uri: uri.href, 57 | mimeType: 'application/x-yaml', 58 | text: content 59 | }] 60 | }; 61 | } catch (error) { 62 | console.error(`Error reading spec file ${specPath}:`, error); 63 | throw new Error('Failed to read OpenAPI spec file'); 64 | } 65 | }); 66 | } -------------------------------------------------------------------------------- /src/resources/todo.ts: -------------------------------------------------------------------------------- 1 | import { McpServer, ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | 4 | interface GitHubIssue { 5 | id: number; 6 | number: number; 7 | title: string; 8 | body: string; 9 | state: string; 10 | created_at: string; 11 | updated_at: string; 12 | html_url: string; 13 | labels: Array<{ name: string }>; 14 | } 15 | 16 | interface GitHubSearchResponse { 17 | total_count: number; 18 | incomplete_results: boolean; 19 | items: GitHubIssue[]; 20 | } 21 | 22 | /** 23 | * Configure todo resource for GitHub issues 24 | */ 25 | export function todoResource(server: McpServer, repoRoot: string): void { 26 | // GitHub API request options 27 | const apiOptions: RequestInit = { 28 | headers: { 29 | 'Accept': 'application/vnd.github.v3+json', 30 | 'User-Agent': 'Carrot-AI-PM' 31 | } 32 | }; 33 | 34 | // Add authorization if GitHub token is available 35 | if (process.env.GITHUB_TOKEN && apiOptions.headers) { 36 | // Cast to Record to allow string indexing 37 | (apiOptions.headers as Record)['Authorization'] = `token ${process.env.GITHUB_TOKEN}`; 38 | } 39 | 40 | // Template for todo://issues/{id} resources 41 | const todoTemplate = new ResourceTemplate('todo://issues/{id}', { 42 | list: async () => { 43 | try { 44 | // Default page size and first page 45 | const pageSize = 10; 46 | const page = 1; 47 | 48 | // Build GitHub API URL 49 | // Default to searching in the carrot org or repo with open state 50 | const apiUrl = `https://api.github.com/search/issues?q=label:carrot+state:open&sort=updated&per_page=${pageSize}&page=${page}`; 51 | 52 | // Fetch issues from GitHub 53 | const response = await fetch(apiUrl, apiOptions); 54 | 55 | if (!response.ok) { 56 | throw new Error(`GitHub API error: ${response.status} ${response.statusText}`); 57 | } 58 | 59 | const data = await response.json() as GitHubSearchResponse; 60 | 61 | // Map GitHub issues to todo resources 62 | const resources = data.items.map((issue) => ({ 63 | uri: `todo://issues/${issue.number}`, 64 | name: `Issue #${issue.number}`, 65 | description: issue.title 66 | })); 67 | 68 | return { 69 | resources, 70 | nextCursor: data.total_count > page * pageSize ? `page=2` : undefined 71 | }; 72 | } catch (error) { 73 | console.error('Error fetching GitHub issues:', error); 74 | return { resources: [] }; 75 | } 76 | } 77 | }); 78 | 79 | // Handler for reading individual issues 80 | server.resource('todo', todoTemplate, async (uri, params) => { 81 | const { id } = params; 82 | 83 | if (!id) { 84 | throw new Error('Issue ID not provided'); 85 | } 86 | 87 | try { 88 | // Fetch the specific issue 89 | const apiUrl = `https://api.github.com/repos/carrot/carrot/issues/${id}`; 90 | const response = await fetch(apiUrl, apiOptions); 91 | 92 | if (!response.ok) { 93 | if (response.status === 404) { 94 | throw new Error(`Issue #${id} not found`); 95 | } 96 | throw new Error(`GitHub API error: ${response.status} ${response.statusText}`); 97 | } 98 | 99 | const issue = await response.json() as GitHubIssue; 100 | 101 | // Format issue as JSON 102 | const formattedIssue = { 103 | id: issue.number, 104 | title: issue.title, 105 | body: issue.body, 106 | state: issue.state, 107 | created_at: issue.created_at, 108 | updated_at: issue.updated_at, 109 | url: issue.html_url, 110 | labels: issue.labels.map(label => label.name) 111 | }; 112 | 113 | return { 114 | contents: [{ 115 | uri: uri.href, 116 | mimeType: 'application/json', 117 | text: JSON.stringify(formattedIssue, null, 2) 118 | }] 119 | }; 120 | } catch (error) { 121 | console.error(`Error fetching issue #${id}:`, error); 122 | throw new Error(`Failed to fetch issue #${id}`); 123 | } 124 | }); 125 | } -------------------------------------------------------------------------------- /src/server.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 3 | import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'; 4 | import express from 'express'; 5 | import { randomUUID } from 'crypto'; 6 | import { z } from 'zod'; 7 | import { configureResources } from './resources/index.js'; 8 | import { configureTools } from './tools/index.js'; 9 | import { configurePrompts } from './prompts/index.js'; 10 | import { getRepoRoot } from './utils/path.js'; 11 | 12 | // Initialize the MCP server 13 | const server = new McpServer({ 14 | name: 'Carrot-AI-PM', 15 | version: '1.0.0', 16 | }); 17 | 18 | // Get repository root path with error handling 19 | let repoRoot: string; 20 | try { 21 | repoRoot = getRepoRoot(); 22 | } catch (error) { 23 | console.error("[CarrotMCP Fatal] Server startup failed: Could not determine a valid project root."); 24 | process.exit(1); 25 | } 26 | 27 | // Configure resources, tools, and prompts 28 | configureResources(server, repoRoot); 29 | configureTools(server, repoRoot); 30 | configurePrompts(server); 31 | 32 | // Check if PORT env var is set to determine transport 33 | const PORT = process.env.PORT ? parseInt(process.env.PORT, 10) : 0; 34 | 35 | if (PORT > 0) { 36 | // SSE transport 37 | const app = express(); 38 | app.use(express.json()); 39 | 40 | // Map to store transports by session ID 41 | const transports: Record = {}; 42 | 43 | // Handle POST, GET, and DELETE requests 44 | app.all('/mcp/sse', async (req, res) => { 45 | try { 46 | // Check for existing session ID 47 | const sessionId = req.headers['mcp-session-id'] as string | undefined; 48 | let transport: StreamableHTTPServerTransport; 49 | 50 | if (sessionId && transports[sessionId]) { 51 | // Reuse existing transport 52 | transport = transports[sessionId]; 53 | } else if (!sessionId && req.method === 'POST') { 54 | // New initialization request 55 | transport = new StreamableHTTPServerTransport({ 56 | sessionIdGenerator: () => randomUUID(), 57 | onsessioninitialized: (sid) => { 58 | transports[sid] = transport; 59 | console.log(`Session initialized: ${sid}`); 60 | }, 61 | }); 62 | 63 | // Clean up transport when closed 64 | transport.onclose = () => { 65 | if (transport.sessionId) { 66 | delete transports[transport.sessionId]; 67 | console.log(`Session closed: ${transport.sessionId}`); 68 | } 69 | }; 70 | 71 | // Connect to the MCP server 72 | await server.connect(transport); 73 | } else { 74 | // Invalid request 75 | res.status(400).json({ 76 | jsonrpc: '2.0', 77 | error: { 78 | code: -32000, 79 | message: 'Bad Request: No valid session ID provided', 80 | }, 81 | id: null, 82 | }); 83 | return; 84 | } 85 | 86 | // Handle the request 87 | await transport.handleRequest(req, res, req.method === 'POST' ? req.body : undefined); 88 | } catch (error) { 89 | console.error('Error handling MCP request:', error); 90 | if (!res.headersSent) { 91 | res.status(500).json({ 92 | jsonrpc: '2.0', 93 | error: { 94 | code: -32603, 95 | message: 'Internal server error', 96 | }, 97 | id: null, 98 | }); 99 | } 100 | } 101 | }); 102 | 103 | // Start the server 104 | app.listen(PORT, () => { 105 | console.log(`Carrot MCP server listening on port ${PORT}`); 106 | }); 107 | } else { 108 | // Stdio transport 109 | const transport = new StdioServerTransport(); 110 | server.connect(transport).catch((error) => { 111 | console.error('Error connecting MCP server:', error); 112 | process.exit(1); 113 | }); 114 | } -------------------------------------------------------------------------------- /src/tools/commit_changes.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | import { exec } from 'child_process'; 4 | import { promisify } from 'util'; 5 | import * as simpleGit from 'simple-git'; 6 | 7 | const execAsync = promisify(exec); 8 | 9 | /** 10 | * Configure commit_changes tool for staging and committing changes 11 | */ 12 | export function commitChangesTool(server: McpServer, repoRoot: string): void { 13 | server.tool( 14 | 'commit_changes', 15 | { 16 | message: z.string().min(1) 17 | }, 18 | async ({ message }) => { 19 | try { 20 | // Initialize git 21 | const git = simpleGit.simpleGit(repoRoot); 22 | 23 | // Get the current status to see what changes there are 24 | const status = await git.status(); 25 | 26 | if (status.isClean()) { 27 | return { 28 | content: [{ 29 | type: 'text', 30 | text: 'No changes to commit. Working directory is clean.' 31 | }] 32 | }; 33 | } 34 | 35 | // Format status for output 36 | const changes = { 37 | modified: status.modified, 38 | added: status.created, 39 | deleted: status.deleted, 40 | untracked: status.not_added, 41 | renamed: status.renamed 42 | }; 43 | 44 | // Create a change summary for the output 45 | const changeCount = 46 | status.modified.length + 47 | status.created.length + 48 | status.deleted.length + 49 | status.renamed.length; 50 | 51 | // Stage all changes 52 | await git.add('.'); 53 | 54 | // Commit the changes 55 | const commitResult = await git.commit(message); 56 | 57 | // Prepare the result message 58 | let resultMessage = `Successfully committed ${changeCount} changes to git.\n`; 59 | resultMessage += `Commit hash: ${commitResult.commit}\n`; 60 | resultMessage += `Commit message: ${message}\n\n`; 61 | resultMessage += 'Changes:\n'; 62 | 63 | if (changes.modified.length > 0) { 64 | resultMessage += `\nModified files:\n${changes.modified.map(file => ` - ${file}`).join('\n')}`; 65 | } 66 | 67 | if (changes.added.length > 0) { 68 | resultMessage += `\nAdded files:\n${changes.added.map(file => ` - ${file}`).join('\n')}`; 69 | } 70 | 71 | if (changes.deleted.length > 0) { 72 | resultMessage += `\nDeleted files:\n${changes.deleted.map(file => ` - ${file}`).join('\n')}`; 73 | } 74 | 75 | if (changes.renamed.length > 0) { 76 | resultMessage += `\nRenamed files:\n${changes.renamed.map(file => ` - ${file.from} → ${file.to}`).join('\n')}`; 77 | } 78 | 79 | // Include the diff in the result 80 | const diff = await git.diff(['HEAD~1', 'HEAD']); 81 | 82 | resultMessage += '\n\nDiff:\n```diff\n' + diff + '\n```'; 83 | 84 | return { 85 | content: [{ 86 | type: 'text', 87 | text: resultMessage 88 | }] 89 | }; 90 | } catch (error) { 91 | return { 92 | content: [{ 93 | type: 'text', 94 | text: `Error committing changes: ${error instanceof Error ? error.message : String(error)}` 95 | }], 96 | isError: true 97 | }; 98 | } 99 | } 100 | ); 101 | } -------------------------------------------------------------------------------- /src/tools/compliance/base.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Universal Spec Compliance Framework - Base Interfaces 3 | * 4 | * This module provides the foundational interfaces and types for checking 5 | * compliance across different artifact types (API, UI, DB, CLI, Job, etc.) 6 | */ 7 | 8 | export interface ComplianceIssue { 9 | type: string; 10 | severity: 'error' | 'warning' | 'info'; 11 | message: string; 12 | suggestion?: string; 13 | location?: { 14 | file?: string; 15 | line?: number; 16 | column?: number; 17 | path?: string; 18 | }; 19 | metadata?: Record; 20 | } 21 | 22 | export interface ComplianceSuggestion { 23 | type: string; 24 | description: string; 25 | code?: string; 26 | autoFixable: boolean; 27 | priority: 'high' | 'medium' | 'low'; 28 | category: 'structure' | 'validation' | 'accessibility' | 'performance' | 'security' | 'style'; 29 | } 30 | 31 | export interface ComplianceResult { 32 | isCompliant: boolean; 33 | score: number; // 0.0 to 1.0 34 | issues: ComplianceIssue[]; 35 | suggestions: ComplianceSuggestion[]; 36 | metadata: { 37 | artifactType: string; 38 | identifier: string; 39 | checkedAt: Date; 40 | checkDuration: number; // milliseconds 41 | version: string; 42 | }; 43 | dimensions: Record; 44 | } 45 | 46 | export interface ComplianceDimension { 47 | name: string; 48 | score: number; 49 | isCompliant: boolean; 50 | issues: ComplianceIssue[]; 51 | weight: number; // For overall score calculation 52 | } 53 | 54 | export interface ArtifactSpec { 55 | type: ArtifactType; 56 | identifier: string; 57 | version: string; 58 | summary: string; 59 | metadata: Record; 60 | specification: any; // Type-specific spec content 61 | complianceRules: ComplianceRule[]; 62 | } 63 | 64 | export interface ComplianceRule { 65 | id: string; 66 | category: string; 67 | description: string; 68 | severity: 'error' | 'warning' | 'info'; 69 | condition: string; // Human readable condition 70 | validator?: (spec: any, implementation: any) => boolean; 71 | } 72 | 73 | export interface ComplianceContext { 74 | artifactType: ArtifactType; 75 | projectPath: string; 76 | projectContext: ProjectContext; 77 | toolchain: string[]; 78 | conventions: Convention[]; 79 | environment: 'development' | 'staging' | 'production'; 80 | } 81 | 82 | export interface ProjectContext { 83 | type: 'nextjs' | 'react' | 'vue' | 'express' | 'fastify' | 'unknown'; 84 | language: 'typescript' | 'javascript' | 'python' | 'go' | 'rust'; 85 | framework: string[]; 86 | dependencies: Record; 87 | patterns: string[]; 88 | features: string[]; 89 | } 90 | 91 | export interface Convention { 92 | name: string; 93 | description: string; 94 | rules: string[]; 95 | examples: string[]; 96 | } 97 | 98 | export type ArtifactType = 'api' | 'ui' | 'page' | 'cli' | 'job' | 'db' | 'lib'; 99 | 100 | /** 101 | * Base interface for all compliance checkers 102 | */ 103 | export interface SpecComplianceChecker { 104 | readonly artifactType: ArtifactType; 105 | readonly supportedFrameworks: string[]; 106 | 107 | /** 108 | * Check compliance of implementation against specification 109 | */ 110 | checkCompliance( 111 | spec: TSpec, 112 | implementation: TImplementation, 113 | context: ComplianceContext 114 | ): Promise; 115 | 116 | /** 117 | * Generate actionable suggestions based on issues 118 | */ 119 | generateSuggestions(issues: ComplianceIssue[], context: ComplianceContext): ComplianceSuggestion[]; 120 | 121 | /** 122 | * Calculate compliance score based on issues and weights 123 | */ 124 | calculateScore(dimensions: Record): number; 125 | 126 | /** 127 | * Validate that the checker can handle the given spec and implementation 128 | */ 129 | canHandle(spec: any, implementation: any, context: ComplianceContext): boolean; 130 | 131 | /** 132 | * Get compliance dimensions that this checker evaluates 133 | */ 134 | getComplianceDimensions(): string[]; 135 | } 136 | 137 | /** 138 | * Abstract base class for compliance checkers 139 | */ 140 | export abstract class BaseComplianceChecker 141 | implements SpecComplianceChecker { 142 | 143 | abstract readonly artifactType: ArtifactType; 144 | abstract readonly supportedFrameworks: string[]; 145 | 146 | async checkCompliance( 147 | spec: TSpec, 148 | implementation: TImplementation, 149 | context: ComplianceContext 150 | ): Promise { 151 | const startTime = Date.now(); 152 | 153 | if (!this.canHandle(spec, implementation, context)) { 154 | throw new Error(`Cannot handle ${context.artifactType} compliance checking`); 155 | } 156 | 157 | const dimensions = await this.evaluateComplianceDimensions(spec, implementation, context); 158 | const allIssues = Object.values(dimensions).flatMap(d => d.issues); 159 | const score = this.calculateScore(dimensions); 160 | const isCompliant = score >= 0.8 && allIssues.filter(i => i.severity === 'error').length === 0; 161 | 162 | return { 163 | isCompliant, 164 | score, 165 | issues: allIssues, 166 | suggestions: this.generateSuggestions(allIssues, context), 167 | metadata: { 168 | artifactType: this.artifactType, 169 | identifier: this.extractIdentifier(spec), 170 | checkedAt: new Date(), 171 | checkDuration: Date.now() - startTime, 172 | version: '1.0.0' 173 | }, 174 | dimensions 175 | }; 176 | } 177 | 178 | calculateScore(dimensions: Record): number { 179 | const totalWeight = Object.values(dimensions).reduce((sum, d) => sum + d.weight, 0); 180 | if (totalWeight === 0) return 1.0; 181 | 182 | const weightedScore = Object.values(dimensions).reduce( 183 | (sum, d) => sum + (d.score * d.weight), 184 | 0 185 | ); 186 | 187 | return weightedScore / totalWeight; 188 | } 189 | 190 | generateSuggestions(issues: ComplianceIssue[], context: ComplianceContext): ComplianceSuggestion[] { 191 | return issues 192 | .filter(issue => issue.suggestion) 193 | .map(issue => this.createSuggestionFromIssue(issue, context)) 194 | .filter(Boolean) as ComplianceSuggestion[]; 195 | } 196 | 197 | canHandle(spec: any, implementation: any, context: ComplianceContext): boolean { 198 | return context.artifactType === this.artifactType; 199 | } 200 | 201 | abstract getComplianceDimensions(): string[]; 202 | 203 | /** 204 | * Evaluate all compliance dimensions for this artifact type 205 | */ 206 | protected abstract evaluateComplianceDimensions( 207 | spec: TSpec, 208 | implementation: TImplementation, 209 | context: ComplianceContext 210 | ): Promise>; 211 | 212 | /** 213 | * Extract identifier from spec 214 | */ 215 | protected abstract extractIdentifier(spec: TSpec): string; 216 | 217 | /** 218 | * Create suggestion from issue 219 | */ 220 | protected createSuggestionFromIssue(issue: ComplianceIssue, context: ComplianceContext): ComplianceSuggestion | null { 221 | if (!issue.suggestion) return null; 222 | 223 | return { 224 | type: issue.type, 225 | description: issue.suggestion, 226 | autoFixable: this.isAutoFixable(issue.type), 227 | priority: this.getSuggestionPriority(issue.severity), 228 | category: this.getSuggestionCategory(issue.type) 229 | }; 230 | } 231 | 232 | protected isAutoFixable(issueType: string): boolean { 233 | // Override in subclasses for specific auto-fixable patterns 234 | return false; 235 | } 236 | 237 | protected getSuggestionPriority(severity: 'error' | 'warning' | 'info'): 'high' | 'medium' | 'low' { 238 | switch (severity) { 239 | case 'error': return 'high'; 240 | case 'warning': return 'medium'; 241 | case 'info': return 'low'; 242 | } 243 | } 244 | 245 | protected getSuggestionCategory(issueType: string): ComplianceSuggestion['category'] { 246 | // Map issue types to categories - override in subclasses for specificity 247 | if (issueType.includes('VALIDATION')) return 'validation'; 248 | if (issueType.includes('ACCESSIBILITY')) return 'accessibility'; 249 | if (issueType.includes('PERFORMANCE')) return 'performance'; 250 | if (issueType.includes('SECURITY')) return 'security'; 251 | if (issueType.includes('STYLE')) return 'style'; 252 | return 'structure'; 253 | } 254 | 255 | /** 256 | * Create a compliance dimension 257 | */ 258 | protected createDimension( 259 | name: string, 260 | issues: ComplianceIssue[], 261 | weight: number = 1.0 262 | ): ComplianceDimension { 263 | const errorCount = issues.filter(i => i.severity === 'error').length; 264 | const warningCount = issues.filter(i => i.severity === 'warning').length; 265 | 266 | // Calculate score: start at 1.0, deduct for issues 267 | const errorPenalty = errorCount * 0.3; 268 | const warningPenalty = warningCount * 0.1; 269 | const score = Math.max(0, 1.0 - errorPenalty - warningPenalty); 270 | 271 | return { 272 | name, 273 | score, 274 | isCompliant: errorCount === 0 && score >= 0.8, 275 | issues, 276 | weight 277 | }; 278 | } 279 | } 280 | 281 | /** 282 | * Factory for creating compliance checkers 283 | */ 284 | export class ComplianceCheckerFactory { 285 | private static checkers = new Map SpecComplianceChecker>(); 286 | 287 | static register( 288 | type: ArtifactType, 289 | factory: () => SpecComplianceChecker 290 | ): void { 291 | this.checkers.set(type, factory); 292 | } 293 | 294 | static create(type: ArtifactType): SpecComplianceChecker { 295 | const factory = this.checkers.get(type); 296 | if (!factory) { 297 | throw new Error(`No compliance checker registered for artifact type: ${type}`); 298 | } 299 | return factory(); 300 | } 301 | 302 | static getSupportedTypes(): ArtifactType[] { 303 | return Array.from(this.checkers.keys()); 304 | } 305 | } 306 | 307 | /** 308 | * Utility functions for compliance checking 309 | */ 310 | export class ComplianceUtils { 311 | /** 312 | * Merge multiple compliance results 313 | */ 314 | static mergeResults(results: ComplianceResult[]): ComplianceResult { 315 | if (results.length === 0) { 316 | throw new Error('Cannot merge empty results array'); 317 | } 318 | 319 | if (results.length === 1) { 320 | return results[0]; 321 | } 322 | 323 | const allIssues = results.flatMap(r => r.issues); 324 | const allSuggestions = results.flatMap(r => r.suggestions); 325 | const allDimensions = results.reduce((acc, r) => ({ ...acc, ...r.dimensions }), {}); 326 | 327 | const totalScore = results.reduce((sum, r) => sum + r.score, 0) / results.length; 328 | const isCompliant = results.every(r => r.isCompliant); 329 | 330 | return { 331 | isCompliant, 332 | score: totalScore, 333 | issues: allIssues, 334 | suggestions: allSuggestions, 335 | metadata: { 336 | artifactType: 'mixed' as any, 337 | identifier: 'project-wide', 338 | checkedAt: new Date(), 339 | checkDuration: results.reduce((sum, r) => sum + r.metadata.checkDuration, 0), 340 | version: '1.0.0' 341 | }, 342 | dimensions: allDimensions 343 | }; 344 | } 345 | 346 | /** 347 | * Filter issues by severity 348 | */ 349 | static filterIssuesBySeverity( 350 | issues: ComplianceIssue[], 351 | severity: 'error' | 'warning' | 'info' 352 | ): ComplianceIssue[] { 353 | return issues.filter(issue => issue.severity === severity); 354 | } 355 | 356 | /** 357 | * Group issues by type 358 | */ 359 | static groupIssuesByType(issues: ComplianceIssue[]): Record { 360 | return issues.reduce((groups, issue) => { 361 | const type = issue.type; 362 | if (!groups[type]) { 363 | groups[type] = []; 364 | } 365 | groups[type].push(issue); 366 | return groups; 367 | }, {} as Record); 368 | } 369 | 370 | /** 371 | * Generate compliance summary text 372 | */ 373 | static generateSummary(result: ComplianceResult): string { 374 | const status = result.isCompliant ? '✅ COMPLIANT' : '❌ NON-COMPLIANT'; 375 | const score = `${(result.score * 100).toFixed(1)}%`; 376 | const issueCount = result.issues.length; 377 | const errorCount = this.filterIssuesBySeverity(result.issues, 'error').length; 378 | 379 | let summary = `${status} (${score})`; 380 | 381 | if (issueCount > 0) { 382 | summary += ` - ${issueCount} issue${issueCount === 1 ? '' : 's'} found`; 383 | if (errorCount > 0) { 384 | summary += ` (${errorCount} critical)`; 385 | } 386 | } 387 | 388 | return summary; 389 | } 390 | } -------------------------------------------------------------------------------- /src/tools/compliance/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Compliance Framework Index 3 | * 4 | * This module registers all compliance checkers and exports the framework 5 | */ 6 | 7 | import { ComplianceCheckerFactory } from './base.js'; 8 | 9 | // Import all compliance checkers 10 | import { UIComponentComplianceChecker } from './ui-checker.js'; 11 | import { DatabaseComplianceChecker } from './db-checker.js'; 12 | import { CLIComplianceChecker } from './cli-checker.js'; 13 | 14 | // Register all compliance checkers 15 | ComplianceCheckerFactory.register('ui', () => new UIComponentComplianceChecker()); 16 | ComplianceCheckerFactory.register('db', () => new DatabaseComplianceChecker()); 17 | ComplianceCheckerFactory.register('cli', () => new CLIComplianceChecker()); 18 | 19 | // Re-export everything from base 20 | export * from './base.js'; -------------------------------------------------------------------------------- /src/tools/format_code.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | import { exec } from 'child_process'; 4 | import { promisify } from 'util'; 5 | import * as path from 'path'; 6 | import { isPathInRepo } from '../utils/path.js'; 7 | 8 | const execAsync = promisify(exec); 9 | 10 | /** 11 | * Configure format_code tool for running ruff --fix and black 12 | */ 13 | export function formatCodeTool(server: McpServer, repoRoot: string): void { 14 | server.tool( 15 | 'format_code', 16 | { 17 | paths: z.array(z.string()).optional() 18 | }, 19 | async ({ paths }) => { 20 | try { 21 | // Determine which paths to format 22 | let targetPaths: string[]; 23 | 24 | if (paths && paths.length > 0) { 25 | // Validate and normalize provided paths 26 | targetPaths = paths.map(p => { 27 | // Convert to absolute path if not already 28 | const absPath = path.isAbsolute(p) ? p : path.join(repoRoot, p); 29 | 30 | // Security check: ensure path is within repo 31 | if (!isPathInRepo(absPath, repoRoot)) { 32 | throw new Error(`Path ${p} is outside of repository`); 33 | } 34 | 35 | return absPath; 36 | }); 37 | } else { 38 | // Default to formatting the whole carrot directory 39 | targetPaths = [path.join(repoRoot, 'carrot')]; 40 | } 41 | 42 | // Format paths for command 43 | const pathsArgument = targetPaths.map(p => `"${p}"`).join(' '); 44 | 45 | // Format with ruff first (auto-fix linting issues) 46 | let ruffOutput = ''; 47 | try { 48 | const { stdout, stderr } = await execAsync(`ruff check --fix ${pathsArgument}`, { 49 | cwd: repoRoot, 50 | timeout: 30000 // 30 second timeout 51 | }); 52 | ruffOutput = stdout + (stderr ? '\n' + stderr : ''); 53 | } catch (error) { 54 | const err = error as { stdout?: string; stderr?: string; message?: string }; 55 | ruffOutput = `Ruff errors (some may have been fixed): ${err.message}\n${err.stdout || ''}\n${err.stderr || ''}`; 56 | } 57 | 58 | // Format with black (code style) 59 | let blackOutput = ''; 60 | try { 61 | const { stdout, stderr } = await execAsync(`black ${pathsArgument}`, { 62 | cwd: repoRoot, 63 | timeout: 30000 // 30 second timeout 64 | }); 65 | blackOutput = stdout + (stderr ? '\n' + stderr : ''); 66 | } catch (error) { 67 | const err = error as { stdout?: string; stderr?: string; message?: string }; 68 | blackOutput = `Black errors: ${err.message}\n${err.stdout || ''}\n${err.stderr || ''}`; 69 | } 70 | 71 | // Prepare summary 72 | const formattedPaths = targetPaths.map(p => path.relative(repoRoot, p)); 73 | const summary = `Code formatting completed on:\n${formattedPaths.map(p => `- ${p}`).join('\n')}`; 74 | 75 | return { 76 | content: [{ 77 | type: 'text', 78 | text: `${summary}\n\nRuff output:\n${ruffOutput || 'No output'}\n\nBlack output:\n${blackOutput || 'No output'}` 79 | }] 80 | }; 81 | } catch (error) { 82 | return { 83 | content: [{ 84 | type: 'text', 85 | text: `Error formatting code: ${error instanceof Error ? error.message : String(error)}` 86 | }], 87 | isError: true 88 | }; 89 | } 90 | } 91 | ); 92 | } -------------------------------------------------------------------------------- /src/tools/index.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { addRouteTool } from './add_route.js'; 3 | import { growSpecTool } from './grow_spec.js'; 4 | import { growUISpecTool } from './grow_ui_spec.js'; 5 | import { growDBSpecTool } from './grow_db_spec.js'; 6 | import { growCLISpecTool } from './grow_cli_spec.js'; 7 | import { runTestsTool } from './run_tests.js'; 8 | import { formatCodeTool } from './format_code.js'; 9 | import { searchCodeTool } from './search_code.js'; 10 | import { commitChangesTool } from './commit_changes.js'; 11 | import { setupCarrotTool } from './setup_carrot.js'; 12 | import { checkSpecComplianceUniversalTool } from './check_spec_compliance_universal.js'; 13 | 14 | /** 15 | * Configure all tools for the MCP server 16 | */ 17 | export function configureTools(server: McpServer, repoRoot: string): void { 18 | // Tool to set up Carrot project structure 19 | setupCarrotTool(server, repoRoot); 20 | 21 | // Tool to create FastAPI route stubs 22 | addRouteTool(server, repoRoot); 23 | 24 | // Tool to append stubs to vibe.yaml 25 | growSpecTool(server, repoRoot); 26 | 27 | // Tool to create UI component specifications 28 | growUISpecTool(server, repoRoot); 29 | 30 | // Tool to create database specifications 31 | growDBSpecTool(server, repoRoot); 32 | 33 | // Tool to create CLI specifications 34 | growCLISpecTool(server, repoRoot); 35 | 36 | // // Tool to run pytest 37 | runTestsTool(server, repoRoot); 38 | 39 | // // Tool to format code with ruff and black 40 | formatCodeTool(server, repoRoot); 41 | 42 | // // Tool to search code with ripgrep 43 | searchCodeTool(server, repoRoot); 44 | 45 | // // Tool to commit changes via git 46 | commitChangesTool(server, repoRoot); 47 | 48 | // Enhanced compliance tool with storage and AST analysis 49 | checkSpecComplianceUniversalTool(server, repoRoot); 50 | } -------------------------------------------------------------------------------- /src/tools/run_tests.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | import { exec } from 'child_process'; 4 | import { promisify } from 'util'; 5 | import { RateLimiter } from '../utils/rate_limiter.js'; 6 | 7 | const execAsync = promisify(exec); 8 | 9 | // Rate limiter: 4 calls per minute 10 | const testRateLimiter = new RateLimiter(4, 60 * 1000); 11 | 12 | /** 13 | * Configure run_tests tool for running pytest 14 | */ 15 | export function runTestsTool(server: McpServer, repoRoot: string): void { 16 | server.tool( 17 | 'run_tests', 18 | {}, 19 | async () => { 20 | // Check rate limiting 21 | if (!testRateLimiter.tryAcquire()) { 22 | return { 23 | content: [{ 24 | type: 'text', 25 | text: 'Rate limit exceeded: You can only run tests 4 times per minute.' 26 | }], 27 | isError: true 28 | }; 29 | } 30 | 31 | try { 32 | // Run pytest in quiet mode 33 | const { stdout, stderr } = await execAsync('cd "' + repoRoot + '" && python -m pytest -q', { 34 | timeout: 60000, // 60 second timeout 35 | maxBuffer: 1024 * 1024 // 1MB buffer 36 | }); 37 | 38 | // Parse the test results 39 | const { passed, failed, summary } = parseTestResults(stdout, stderr); 40 | 41 | const resultJson = { 42 | passed, 43 | failed, 44 | summary, 45 | full_output: stdout + (stderr ? '\n\n' + stderr : '') 46 | }; 47 | 48 | return { 49 | content: [{ 50 | type: 'text', 51 | text: JSON.stringify(resultJson, null, 2) 52 | }] 53 | }; 54 | } catch (error) { 55 | // Handle test failures or execution errors 56 | const err = error as { stdout?: string; stderr?: string; message?: string }; 57 | 58 | // Try to parse test results even if tests failed (pytest returns non-zero exit code) 59 | if (err.stdout) { 60 | const { passed, failed, summary } = parseTestResults(err.stdout, err.stderr || ''); 61 | 62 | const resultJson = { 63 | passed, 64 | failed, 65 | summary, 66 | error: err.message || 'Tests failed', 67 | full_output: err.stdout + (err.stderr ? '\n\n' + err.stderr : '') 68 | }; 69 | 70 | return { 71 | content: [{ 72 | type: 'text', 73 | text: JSON.stringify(resultJson, null, 2) 74 | }] 75 | }; 76 | } 77 | 78 | return { 79 | content: [{ 80 | type: 'text', 81 | text: `Error running tests: ${err.message || 'Unknown error'}\n${err.stderr || ''}` 82 | }], 83 | isError: true 84 | }; 85 | } 86 | } 87 | ); 88 | } 89 | 90 | /** 91 | * Parse pytest output to extract test results 92 | */ 93 | function parseTestResults(stdout: string, stderr: string): { passed: number; failed: number; summary: string } { 94 | // Attempt to parse pytest output for passed and failed tests 95 | const summaryMatch = stdout.match(/(\d+) passed(, (\d+) failed)?(, (\d+) skipped)?(, (\d+) warnings)? in [\d\.]+s/); 96 | 97 | if (summaryMatch) { 98 | const passed = parseInt(summaryMatch[1], 10) || 0; 99 | const failed = parseInt(summaryMatch[3], 10) || 0; 100 | 101 | return { 102 | passed, 103 | failed, 104 | summary: summaryMatch[0] 105 | }; 106 | } 107 | 108 | // If no match, try to count from the output 109 | const passedCount = (stdout.match(/PASSED/g) || []).length; 110 | const failedCount = (stdout.match(/FAILED/g) || []).length; 111 | 112 | let summary = `${passedCount} passed`; 113 | if (failedCount > 0) { 114 | summary += `, ${failedCount} failed`; 115 | } 116 | 117 | return { 118 | passed: passedCount, 119 | failed: failedCount, 120 | summary 121 | }; 122 | } -------------------------------------------------------------------------------- /src/tools/search_code.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | import { exec } from 'child_process'; 4 | import { promisify } from 'util'; 5 | import * as path from 'path'; 6 | import { RateLimiter } from '../utils/rate_limiter.js'; 7 | 8 | const execAsync = promisify(exec); 9 | 10 | // Rate limiter: 4 calls per minute 11 | const searchRateLimiter = new RateLimiter(4, 60 * 1000); 12 | 13 | /** 14 | * Configure search_code tool for running ripgrep searches 15 | */ 16 | export function searchCodeTool(server: McpServer, repoRoot: string): void { 17 | server.tool( 18 | 'search_code', 19 | { 20 | query: z.string().min(1) 21 | }, 22 | async ({ query }) => { 23 | // Check rate limiting 24 | if (!searchRateLimiter.tryAcquire()) { 25 | return { 26 | content: [{ 27 | type: 'text', 28 | text: 'Rate limit exceeded: You can only search 4 times per minute.' 29 | }], 30 | isError: true 31 | }; 32 | } 33 | 34 | try { 35 | // Sanitize the query for shell use 36 | const sanitizedQuery = sanitizeRipgrepQuery(query); 37 | 38 | // Run ripgrep with nice formatting options 39 | const cmd = `cd "${repoRoot}" && rg --heading --line-number --context 2 --max-count 50 --color never "${sanitizedQuery}" .`; 40 | 41 | const { stdout, stderr } = await execAsync(cmd, { 42 | timeout: 30000, // 30 second timeout 43 | maxBuffer: 2 * 1024 * 1024 // 2MB buffer 44 | }); 45 | 46 | if (stdout.trim() === '') { 47 | return { 48 | content: [{ 49 | type: 'text', 50 | text: `No matches found for: ${query}` 51 | }] 52 | }; 53 | } 54 | 55 | // Format the results 56 | const formattedResults = formatSearchResults(stdout, repoRoot); 57 | 58 | return { 59 | content: [{ 60 | type: 'text', 61 | text: formattedResults 62 | }] 63 | }; 64 | } catch (error) { 65 | const err = error as { stdout?: string; stderr?: string; message?: string }; 66 | 67 | // Check if it's just a "no matches" error 68 | if (err.stderr && err.stderr.includes('No files were searched')) { 69 | return { 70 | content: [{ 71 | type: 'text', 72 | text: `No files were searched. ${err.stderr}` 73 | }] 74 | }; 75 | } 76 | 77 | return { 78 | content: [{ 79 | type: 'text', 80 | text: `Error searching code: ${err.message || 'Unknown error'}\n${err.stderr || ''}` 81 | }], 82 | isError: true 83 | }; 84 | } 85 | } 86 | ); 87 | } 88 | 89 | /** 90 | * Sanitize a query for use with ripgrep 91 | */ 92 | function sanitizeRipgrepQuery(query: string): string { 93 | // Escape double quotes and backslashes 94 | return query.replace(/["\\]/g, '\\$&'); 95 | } 96 | 97 | /** 98 | * Format search results for better readability 99 | */ 100 | function formatSearchResults(stdout: string, repoRoot: string): string { 101 | // Split output by file sections 102 | const sections = stdout.split(/\n(?=\S+:$)/); 103 | 104 | // Process each section 105 | const formattedSections = sections.map(section => { 106 | const lines = section.split('\n'); 107 | 108 | // Extract file path 109 | const filePathLine = lines[0].endsWith(':') ? lines[0].slice(0, -1) : lines[0]; 110 | const relativePath = path.relative(repoRoot, filePathLine); 111 | 112 | // Format header 113 | const header = `File: ${relativePath}`; 114 | 115 | // Process result lines to add clear match indicators 116 | const resultLines = lines.slice(1).map(line => { 117 | // Look for line numbers (digits followed by colon) 118 | const lineNumberMatch = line.match(/^(\d+)(-\d+)?:/); 119 | 120 | if (lineNumberMatch) { 121 | // This is a match line, make it stand out 122 | const lineNumber = lineNumberMatch[0]; 123 | const content = line.slice(lineNumber.length); 124 | return ` ${lineNumber} ${content}`; 125 | } else if (line.startsWith('-')) { 126 | // This is a separator, skip it 127 | return ''; 128 | } else { 129 | // This is a context line, indent it 130 | return ` ${line}`; 131 | } 132 | }).filter(Boolean); // Remove empty lines 133 | 134 | return [header, ...resultLines].join('\n'); 135 | }); 136 | 137 | return formattedSections.join('\n\n'); 138 | } -------------------------------------------------------------------------------- /src/tools/setup_carrot.ts: -------------------------------------------------------------------------------- 1 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 2 | import { z } from 'zod'; 3 | import * as fs from 'fs'; 4 | import * as path from 'path'; 5 | import * as yaml from 'js-yaml'; 6 | 7 | /** 8 | * Configure setup_carrot tool for initializing Carrot project structure 9 | */ 10 | export function setupCarrotTool(server: McpServer, repoRoot: string): void { 11 | server.tool( 12 | 'setup_carrot', 13 | { 14 | projectName: z.string().optional().describe('Name of the project (defaults to directory name)'), 15 | description: z.string().optional().describe('Description of the project') 16 | }, 17 | async ({ projectName, description }: { projectName?: string; description?: string }) => { 18 | try { 19 | console.log(`Setting up Carrot structure in: ${repoRoot}`); 20 | 21 | // Get project name from directory if not provided 22 | const defaultProjectName = path.basename(repoRoot); 23 | const finalProjectName = projectName || defaultProjectName; 24 | 25 | // Create directory structure 26 | const carrotDir = path.join(repoRoot, 'carrot'); 27 | const specsDir = path.join(repoRoot, 'specs'); 28 | const dotCarrotDir = path.join(repoRoot, '.carrot'); 29 | 30 | // Create carrot directory (for user implementation files) 31 | if (!fs.existsSync(carrotDir)) { 32 | fs.mkdirSync(carrotDir, { recursive: true }); 33 | console.log(`Created carrot directory: ${carrotDir}`); 34 | } 35 | 36 | // Create .carrot directory (for internal files like compliance results) 37 | if (!fs.existsSync(dotCarrotDir)) { 38 | fs.mkdirSync(dotCarrotDir, { recursive: true }); 39 | console.log(`Created .carrot directory: ${dotCarrotDir}`); 40 | 41 | // Create subdirectories for internal data 42 | const internalDirs = ['compliance', 'cache', 'logs']; 43 | for (const subDir of internalDirs) { 44 | const subDirPath = path.join(dotCarrotDir, subDir); 45 | if (!fs.existsSync(subDirPath)) { 46 | fs.mkdirSync(subDirPath, { recursive: true }); 47 | console.log(`Created .carrot/${subDir} directory`); 48 | } 49 | } 50 | } 51 | 52 | // Create specs directory 53 | if (!fs.existsSync(specsDir)) { 54 | fs.mkdirSync(specsDir, { recursive: true }); 55 | console.log(`Created specs directory: ${specsDir}`); 56 | } 57 | 58 | // Create subdirectories in specs 59 | const specSubDirs = ['api', 'ui', 'db', 'job']; 60 | for (const subDir of specSubDirs) { 61 | const subDirPath = path.join(specsDir, subDir); 62 | if (!fs.existsSync(subDirPath)) { 63 | fs.mkdirSync(subDirPath, { recursive: true }); 64 | console.log(`Created specs/${subDir} directory`); 65 | } 66 | } 67 | 68 | // Create initial vibe.yaml if it doesn't exist 69 | const vibeYamlPath = path.join(repoRoot, 'vibe.yaml'); 70 | if (!fs.existsSync(vibeYamlPath)) { 71 | const initialSpec = { 72 | openapi: '3.0.0', 73 | info: { 74 | title: `${finalProjectName} API`, 75 | description: description || `API specification for ${finalProjectName}`, 76 | version: '1.0.0' 77 | }, 78 | servers: [ 79 | { 80 | url: 'http://localhost:8000', 81 | description: 'Development server' 82 | } 83 | ], 84 | paths: {}, 85 | components: { 86 | schemas: {}, 87 | responses: { 88 | 'NotFound': { 89 | description: 'The requested resource was not found', 90 | content: { 91 | 'application/json': { 92 | schema: { 93 | type: 'object', 94 | properties: { 95 | error: { type: 'string', example: 'Resource not found' }, 96 | status: { type: 'integer', example: 404 } 97 | } 98 | } 99 | } 100 | } 101 | }, 102 | 'BadRequest': { 103 | description: 'The request was invalid', 104 | content: { 105 | 'application/json': { 106 | schema: { 107 | type: 'object', 108 | properties: { 109 | error: { type: 'string', example: 'Invalid request' }, 110 | status: { type: 'integer', example: 400 }, 111 | details: { 112 | type: 'object', 113 | additionalProperties: true 114 | } 115 | } 116 | } 117 | } 118 | } 119 | } 120 | } 121 | } 122 | }; 123 | 124 | fs.writeFileSync(vibeYamlPath, yaml.dump(initialSpec), { mode: 0o644 }); 125 | console.log(`Created vibe.yaml: ${vibeYamlPath}`); 126 | } 127 | 128 | // Create README.md with project information if it doesn't exist 129 | const readmePath = path.join(repoRoot, 'README.md'); 130 | if (!fs.existsSync(readmePath)) { 131 | const readmeContent = `# ${finalProjectName} 132 | 133 | ${description || `A spec-driven API project managed by Carrot AI PM`} 134 | 135 | ## Project Structure 136 | 137 | - \`vibe.yaml\` - OpenAPI specification (single source of truth) 138 | - \`specs/\` - Detailed specifications organized by type 139 | - \`specs/api/\` - API endpoint specifications 140 | - \`specs/ui/\` - UI component specifications 141 | - \`specs/db/\` - Database schema specifications 142 | - \`specs/job/\` - Background job specifications 143 | - \`carrot/\` - Implementation files (generated from specs) 144 | - \`.carrot/\` - Internal Carrot data (compliance results, cache, logs) 145 | 146 | ## Getting Started 147 | 148 | 1. Define your API in \`vibe.yaml\` using the \`grow_spec\` tool 149 | 2. Create detailed specifications in \`specs/\` directories 150 | 3. Use the specifications to guide implementation 151 | 4. Check compliance with \`check_spec_compliance\` tool 152 | 153 | ## Carrot AI PM Tools 154 | 155 | - \`grow_spec\` - Add endpoints to vibe.yaml specification 156 | - \`add_route\` - Add route specifications to the project 157 | - \`check_spec_compliance\` - Validate implementations against specs 158 | - \`search_code\` - Search through specifications and code 159 | - \`format_code\` - Format specification files 160 | - \`commit_changes\` - Commit specification changes 161 | 162 | This project follows a spec-first development approach where specifications drive implementation. 163 | 164 | ## Compliance Tracking 165 | 166 | Carrot automatically saves compliance results in \`.carrot/compliance/\` with: 167 | - AST analysis of your code 168 | - Detailed compliance reports 169 | - Historical tracking of improvements 170 | - Hallucination detection for AI-generated code 171 | 172 | All compliance data is stored locally and never sent to external servers. 173 | `; 174 | fs.writeFileSync(readmePath, readmeContent, { mode: 0o644 }); 175 | console.log(`Created README.md: ${readmePath}`); 176 | } 177 | 178 | const createdItems = []; 179 | if (fs.existsSync(carrotDir)) createdItems.push('carrot/ directory (for implementation files)'); 180 | if (fs.existsSync(dotCarrotDir)) createdItems.push('.carrot/ directory (for internal data: compliance, cache, logs)'); 181 | if (fs.existsSync(specsDir)) createdItems.push('specs/ directory with subdirectories (api/, ui/, db/, job/)'); 182 | if (fs.existsSync(vibeYamlPath)) createdItems.push('vibe.yaml OpenAPI specification'); 183 | if (fs.existsSync(readmePath)) createdItems.push('README.md project documentation'); 184 | 185 | return { 186 | content: [ 187 | { 188 | type: 'text', 189 | text: `Successfully set up Carrot spec-driven project structure in ${repoRoot}\n\n` + 190 | `Created:\n${createdItems.map(item => `- ${item}`).join('\n')}\n\n` + 191 | `Your project is now ready for spec-first development!\n\n` + 192 | `Next steps:\n` + 193 | `1. Use 'grow_spec' to add API endpoints to vibe.yaml\n` + 194 | `2. Use 'add_route' to create detailed route specifications\n` + 195 | `3. Use specifications to guide your implementation\n` + 196 | `4. Keep vibe.yaml as your single source of truth for the API` 197 | } 198 | ] 199 | }; 200 | } catch (error) { 201 | console.error(`Error in setup_carrot tool: ${error}`); 202 | return { 203 | content: [ 204 | { 205 | type: 'text', 206 | text: `Error setting up Carrot structure: ${error instanceof Error ? error.message : String(error)}` 207 | } 208 | ], 209 | isError: true 210 | }; 211 | } 212 | } 213 | ); 214 | } -------------------------------------------------------------------------------- /src/utils/path.ts: -------------------------------------------------------------------------------- 1 | import { execSync } from 'child_process'; 2 | import * as path from 'path'; 3 | import * as fs from 'fs'; 4 | import { fileURLToPath } from 'url'; 5 | 6 | // Helper to get the directory name, equivalent to __dirname in CommonJS 7 | const __dirname = path.dirname(fileURLToPath(import.meta.url)); 8 | 9 | /** 10 | * Gets the project root directory from explicit configuration only. 11 | * Requires either CARROT_PROJECT_ROOT environment variable or --project-root CLI argument. 12 | * Throws an error if neither is provided or if the path is invalid. 13 | */ 14 | export function getProjectRoot(): string { 15 | // First, check for CARROT_PROJECT_ROOT environment variable 16 | const envProjectRoot = process.env.CARROT_PROJECT_ROOT; 17 | if (envProjectRoot) { 18 | const resolvedPath = path.resolve(envProjectRoot); 19 | try { 20 | // Validate that the path exists and is a directory 21 | const stats = fs.statSync(resolvedPath); 22 | if (stats.isDirectory()) { 23 | console.error(`[CarrotMCP] Using project root from CARROT_PROJECT_ROOT: ${resolvedPath}`); 24 | return resolvedPath; 25 | } else { 26 | console.error(`[CarrotMCP Error] CARROT_PROJECT_ROOT path is not a directory: ${resolvedPath}`); 27 | } 28 | } catch (error) { 29 | console.error(`[CarrotMCP Error] CARROT_PROJECT_ROOT path does not exist or is not accessible: ${resolvedPath}`); 30 | } 31 | } 32 | 33 | // Second, check for --project-root CLI argument 34 | const args = process.argv; 35 | for (let i = 0; i < args.length; i++) { 36 | const arg = args[i]; 37 | 38 | // Check for --project-root= format 39 | if (arg.startsWith('--project-root=')) { 40 | const cliPath = arg.substring('--project-root='.length); 41 | const resolvedPath = path.resolve(cliPath); 42 | try { 43 | const stats = fs.statSync(resolvedPath); 44 | if (stats.isDirectory()) { 45 | console.error(`[CarrotMCP] Using project root from CLI argument: ${resolvedPath}`); 46 | return resolvedPath; 47 | } else { 48 | console.error(`[CarrotMCP Error] CLI --project-root path is not a directory: ${resolvedPath}`); 49 | } 50 | } catch (error) { 51 | console.error(`[CarrotMCP Error] CLI --project-root path does not exist or is not accessible: ${resolvedPath}`); 52 | } 53 | } 54 | 55 | // Check for --project-root format (space-separated) 56 | if (arg === '--project-root' && i + 1 < args.length) { 57 | const cliPath = args[i + 1]; 58 | const resolvedPath = path.resolve(cliPath); 59 | try { 60 | const stats = fs.statSync(resolvedPath); 61 | if (stats.isDirectory()) { 62 | console.error(`[CarrotMCP] Using project root from CLI argument: ${resolvedPath}`); 63 | return resolvedPath; 64 | } else { 65 | console.error(`[CarrotMCP Error] CLI --project-root path is not a directory: ${resolvedPath}`); 66 | } 67 | } catch (error) { 68 | console.error(`[CarrotMCP Error] CLI --project-root path does not exist or is not accessible: ${resolvedPath}`); 69 | } 70 | } 71 | } 72 | 73 | // No valid project root found - throw error 74 | const errorMessage = "[CarrotMCP Critical Error] Project root not configured or invalid. Please set the 'CARROT_PROJECT_ROOT' environment variable OR use the '--project-root ' command-line argument in your MCP client's server configuration to specify the absolute path to your project."; 75 | console.error(errorMessage); 76 | throw new Error(errorMessage); 77 | } 78 | 79 | /** 80 | * Alias for getProjectRoot to maintain backward compatibility 81 | * @deprecated Use getProjectRoot instead 82 | */ 83 | export const getRepoRoot = getProjectRoot; 84 | 85 | /** 86 | * Checks if a file path is within the repository 87 | */ 88 | export function isPathInRepo(filePath: string, repoRoot: string): boolean { 89 | const absolutePath = path.resolve(filePath); 90 | const normalizedRepoRoot = path.resolve(repoRoot); 91 | 92 | return absolutePath.startsWith(normalizedRepoRoot); 93 | } 94 | 95 | /** 96 | * Safely resolves a path within the repository 97 | */ 98 | export function resolveRepoPath(relativePath: string, repoRoot: string): string { 99 | const resolvedPath = path.resolve(repoRoot, relativePath); 100 | 101 | if (!isPathInRepo(resolvedPath, repoRoot)) { 102 | throw new Error(`Path ${relativePath} resolves outside of repository`); 103 | } 104 | 105 | return resolvedPath; 106 | } 107 | 108 | /** 109 | * Checks if a file exists 110 | */ 111 | export function fileExists(filePath: string): boolean { 112 | try { 113 | return fs.statSync(filePath).isFile(); 114 | } catch (error) { 115 | return false; 116 | } 117 | } -------------------------------------------------------------------------------- /src/utils/rate_limiter.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Simple rate limiter to limit the number of operations within a time window 3 | */ 4 | export class RateLimiter { 5 | private readonly limit: number; 6 | private readonly timeWindow: number; 7 | private timestamps: number[] = []; 8 | 9 | /** 10 | * Create a new rate limiter 11 | * @param limit Maximum number of operations allowed 12 | * @param timeWindow Time window in milliseconds 13 | */ 14 | constructor(limit: number, timeWindow: number) { 15 | this.limit = limit; 16 | this.timeWindow = timeWindow; 17 | } 18 | 19 | /** 20 | * Try to acquire a token for an operation 21 | * @returns true if operation is allowed, false if rate limit exceeded 22 | */ 23 | tryAcquire(): boolean { 24 | const now = Date.now(); 25 | 26 | // Remove timestamps that are outside the time window 27 | this.timestamps = this.timestamps.filter(timestamp => 28 | now - timestamp < this.timeWindow 29 | ); 30 | 31 | // Check if we've reached the limit 32 | if (this.timestamps.length >= this.limit) { 33 | return false; 34 | } 35 | 36 | // Add the current timestamp 37 | this.timestamps.push(now); 38 | return true; 39 | } 40 | 41 | /** 42 | * Get the number of operations remaining within the current time window 43 | */ 44 | getRemainingOperations(): number { 45 | const now = Date.now(); 46 | 47 | // Remove timestamps that are outside the time window 48 | this.timestamps = this.timestamps.filter(timestamp => 49 | now - timestamp < this.timeWindow 50 | ); 51 | 52 | return Math.max(0, this.limit - this.timestamps.length); 53 | } 54 | 55 | /** 56 | * Get the time until the next operation is allowed (in milliseconds) 57 | * Returns 0 if an operation is currently allowed 58 | */ 59 | getTimeUntilNextAllowed(): number { 60 | if (this.getRemainingOperations() > 0) { 61 | return 0; 62 | } 63 | 64 | const now = Date.now(); 65 | const oldestTimestamp = Math.min(...this.timestamps); 66 | 67 | return Math.max(0, this.timeWindow - (now - oldestTimestamp)); 68 | } 69 | } -------------------------------------------------------------------------------- /tests/development/debug-mcp.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'; 4 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 5 | import { configureTools } from './dist/src/tools/index.js'; 6 | import { getProjectRoot } from './dist/src/utils/path.js'; 7 | 8 | console.log('🔍 MCP Server Diagnostic Tool'); 9 | console.log('================================'); 10 | 11 | try { 12 | // Test project root detection 13 | console.log('\n1. Testing project root detection...'); 14 | const projectRoot = getProjectRoot(); 15 | console.log(`✅ Project root: ${projectRoot}`); 16 | 17 | // Test server creation 18 | console.log('\n2. Testing server creation...'); 19 | const server = new McpServer({ 20 | name: 'Carrot-AI-PM-Debug', 21 | version: '1.0.0', 22 | }); 23 | console.log('✅ Server created successfully'); 24 | 25 | // Test tool configuration 26 | console.log('\n3. Testing tool configuration...'); 27 | configureTools(server, projectRoot); 28 | 29 | const tools = server._registeredTools || {}; 30 | const toolNames = Object.keys(tools); 31 | console.log(`✅ Tools configured: ${toolNames.length} tools`); 32 | console.log(` Tools: ${toolNames.join(', ')}`); 33 | 34 | // Test transport creation 35 | console.log('\n4. Testing transport...'); 36 | const transport = new StdioServerTransport(); 37 | console.log('✅ Transport created successfully'); 38 | 39 | // Test server connection 40 | console.log('\n5. Testing server connection...'); 41 | await server.connect(transport); 42 | console.log('✅ Server connected to transport'); 43 | 44 | console.log('\n🎉 All tests passed! MCP server is working correctly.'); 45 | console.log('\nIf tools are not showing in Cursor, the issue is likely:'); 46 | console.log('- Cursor MCP client cache'); 47 | console.log('- MCP configuration path mismatch'); 48 | console.log('- Cursor needs to be restarted completely'); 49 | 50 | // Keep the server running for a few seconds to test 51 | console.log('\n⏳ Keeping server alive for 5 seconds...'); 52 | setTimeout(() => { 53 | console.log('✅ Server test completed successfully'); 54 | process.exit(0); 55 | }, 5000); 56 | 57 | } catch (error) { 58 | console.error('\n❌ Error during diagnostic:'); 59 | console.error(error); 60 | process.exit(1); 61 | } -------------------------------------------------------------------------------- /tests/development/direct-spec.js: -------------------------------------------------------------------------------- 1 | // Script to directly create a properly structured spec file 2 | import * as fs from 'fs'; 3 | 4 | const spec = { 5 | endpoint: 'carrot/core/improvements', 6 | summary: 'Enhance Carrot to support multi-task specs, task metadata, a refine_spec tool, user notifications, and documentation.', 7 | createdAt: new Date().toISOString(), 8 | features: [ 9 | { 10 | name: 'multi-task-specs', 11 | description: 'Support for defining complex tasks with multiple subtasks and dependencies', 12 | details: { 13 | structure: { 14 | tasks: 'Array of task objects that can be executed in sequence or parallel', 15 | dependencies: 'Graph representation of inter-task dependencies', 16 | globalParams: 'Parameters shared across all tasks in the spec' 17 | }, 18 | implementation: { 19 | fileFormat: 'Extended JSON format with task definitions', 20 | scheduler: 'Task execution with dependency resolution', 21 | validation: 'Schema-based validation of task structures' 22 | } 23 | } 24 | }, 25 | { 26 | name: 'task-metadata', 27 | description: 'Extended metadata for task tracking, visualization, and management', 28 | details: { 29 | fields: { 30 | owner: 'Person responsible for the task', 31 | priority: 'Task importance (low, medium, high, critical)', 32 | estimatedTime: 'Expected completion time', 33 | status: 'Current execution state', 34 | tags: 'Categorization and filtering' 35 | }, 36 | capabilities: { 37 | filtering: 'Query tasks by metadata', 38 | reporting: 'Generate status reports based on metadata', 39 | visualization: 'Create dependency and status charts' 40 | } 41 | } 42 | }, 43 | { 44 | name: 'refine-spec-tool', 45 | description: 'Tool for iteratively refining and updating task specifications', 46 | details: { 47 | operations: { 48 | add: 'Add new tasks to existing specs', 49 | update: 'Modify existing task definitions', 50 | remove: 'Remove tasks from specs', 51 | reorder: 'Change task execution order' 52 | }, 53 | intelligence: { 54 | suggestions: 'Smart suggestions for task refinement', 55 | validation: 'Verify spec integrity after changes', 56 | history: 'Track changes to specs over time' 57 | } 58 | } 59 | }, 60 | { 61 | name: 'user-notifications', 62 | description: 'System for notifying users about task status changes and events', 63 | details: { 64 | channels: { 65 | inApp: 'Notifications within the Carrot UI', 66 | email: 'Email notifications for important events', 67 | webhook: 'Custom webhook integration' 68 | }, 69 | events: { 70 | taskCompletion: 'When tasks are completed', 71 | taskFailure: 'When tasks encounter errors', 72 | progressUpdates: 'Periodic updates on long-running tasks', 73 | approvalRequests: 'When user input is needed' 74 | }, 75 | preferences: { 76 | perUser: 'User-specific notification settings', 77 | perProject: 'Project-level notification rules' 78 | } 79 | } 80 | }, 81 | { 82 | name: 'documentation', 83 | description: 'Comprehensive documentation for Carrot features and APIs', 84 | details: { 85 | components: { 86 | userGuide: 'End-user documentation for Carrot', 87 | developerDocs: 'API documentation for developers', 88 | tutorials: 'Step-by-step guides for common workflows', 89 | examples: 'Sample projects and configurations' 90 | }, 91 | formats: { 92 | markdown: 'Source format for all documentation', 93 | html: 'Generated web documentation', 94 | pdf: 'Downloadable reference guides' 95 | }, 96 | infrastructure: { 97 | docSite: 'Documentation website with search', 98 | versionControl: 'Documentation versioned with code', 99 | contributionFlow: 'Process for community contributions' 100 | } 101 | } 102 | } 103 | ], 104 | implementation: { 105 | phases: [ 106 | { 107 | name: 'Design', 108 | tasks: [ 109 | 'Create detailed schemas for multi-task specs', 110 | 'Design API endpoints for task metadata', 111 | 'Plan user notification system architecture', 112 | 'Outline documentation structure' 113 | ], 114 | deliverables: ['Design documents', 'API specifications', 'Schema definitions'] 115 | }, 116 | { 117 | name: 'Implementation', 118 | tasks: [ 119 | 'Develop core multi-task spec functionality', 120 | 'Build refine-spec tool backend', 121 | 'Implement notification system', 122 | 'Create documentation infrastructure' 123 | ], 124 | deliverables: ['Functional code', 'Initial documentation', 'Test suite'] 125 | }, 126 | { 127 | name: 'Testing', 128 | tasks: [ 129 | 'Unit test all new components', 130 | 'Integration testing of notification system', 131 | 'User testing of refine-spec tool', 132 | 'Documentation review' 133 | ], 134 | deliverables: ['Test reports', 'User feedback', 'Documentation updates'] 135 | }, 136 | { 137 | name: 'Deployment', 138 | tasks: [ 139 | 'Release new features', 140 | 'Publish documentation', 141 | 'Monitor system performance', 142 | 'Gather user feedback' 143 | ], 144 | deliverables: ['Production release', 'Public documentation', 'Feedback analysis'] 145 | } 146 | ], 147 | dependencies: { 148 | external: ['MCP SDK', 'Documentation generation tools', 'Notification service'], 149 | internal: ['Existing task execution system', 'User management', 'API gateway'] 150 | } 151 | } 152 | }; 153 | 154 | fs.writeFileSync('carrot-spec.json', JSON.stringify(spec, null, 2)); 155 | console.log('Spec file created successfully!'); -------------------------------------------------------------------------------- /tests/development/reset-specs.js: -------------------------------------------------------------------------------- 1 | // Simple utility to reset the specs file (for testing purposes) 2 | import * as fs from 'fs'; 3 | import * as path from 'path'; 4 | 5 | // Get repo root (assumes script is run from project root) 6 | const repoRoot = process.cwd(); 7 | const specPath = path.join(repoRoot, 'carrot-spec.json'); 8 | 9 | // Create empty array for specs 10 | fs.writeFileSync(specPath, JSON.stringify([], null, 2)); 11 | console.log(`Reset specs file at ${specPath} to empty array`); -------------------------------------------------------------------------------- /tests/development/restart-cursor.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "🔄 Cursor MCP Client Restart Helper" 4 | echo "==================================" 5 | echo "" 6 | echo "This script helps with the known MCP client issue where tools" 7 | echo "are not detected until after multiple restarts (GitHub issue #1679)" 8 | echo "" 9 | 10 | # Function to check if Cursor is running 11 | check_cursor() { 12 | if pgrep -f "Cursor" > /dev/null; then 13 | return 0 14 | else 15 | return 1 16 | fi 17 | } 18 | 19 | # Function to kill Cursor processes 20 | kill_cursor() { 21 | echo "🛑 Stopping Cursor processes..." 22 | pkill -f "Cursor" 2>/dev/null || true 23 | sleep 2 24 | 25 | # Force kill if still running 26 | if check_cursor; then 27 | echo "🔨 Force stopping remaining Cursor processes..." 28 | pkill -9 -f "Cursor" 2>/dev/null || true 29 | sleep 2 30 | fi 31 | } 32 | 33 | # Function to start Cursor 34 | start_cursor() { 35 | echo "🚀 Starting Cursor..." 36 | if command -v cursor > /dev/null; then 37 | cursor > /dev/null 2>&1 & 38 | elif [ -d "/Applications/Cursor.app" ]; then 39 | open -a "Cursor" 40 | else 41 | echo "❌ Cursor not found. Please start it manually." 42 | return 1 43 | fi 44 | sleep 3 45 | } 46 | 47 | echo "Starting restart cycle to fix MCP tool detection..." 48 | echo "" 49 | 50 | for i in {1..4}; do 51 | echo "🔄 Restart cycle $i/4" 52 | 53 | if check_cursor; then 54 | kill_cursor 55 | fi 56 | 57 | start_cursor 58 | 59 | echo "✅ Cycle $i complete. Please check if tools are visible in Cursor." 60 | 61 | if [ $i -lt 4 ]; then 62 | echo "⏳ Waiting 10 seconds before next cycle..." 63 | sleep 10 64 | echo "" 65 | fi 66 | done 67 | 68 | echo "" 69 | echo "🎉 Restart cycles complete!" 70 | echo "" 71 | echo "If tools are still not visible:" 72 | echo "1. Check MCP Logs in Cursor for connection errors" 73 | echo "2. Verify the MCP configuration path is correct" 74 | echo "3. Try manually restarting Cursor 2-3 more times" 75 | echo "4. Check if other MCP servers (like weather) are working" -------------------------------------------------------------------------------- /tests/development/test-cli-implementation.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Sample CLI Implementation for Testing 5 | * This is a basic implementation of the deploy CLI tool 6 | */ 7 | 8 | import { program } from 'commander'; 9 | 10 | // Configure main command 11 | program 12 | .name('deploy') 13 | .description('A deployment CLI tool that manages application deployments') 14 | .version('1.0.0'); 15 | 16 | // Add global options 17 | program.option('-h, --help', 'Show help information'); 18 | program.option('-V, --version', 'Show version information'); 19 | program.option('-v, --verbose', 'Enable verbose output'); 20 | program.option('-q, --quiet', 'Suppress output'); 21 | 22 | // Add subcommands 23 | program 24 | .command('staging') 25 | .description('Deploy to staging environment') 26 | .option('--dry-run', 'Show what would be deployed without actually deploying') 27 | .action((options) => { 28 | console.log('Executing staging command with options:', options); 29 | if (options.dryRun) { 30 | console.log('This is a dry run - no actual deployment'); 31 | } 32 | process.exit(0); 33 | }); 34 | 35 | program 36 | .command('production') 37 | .description('Deploy to production environment') 38 | .option('--confirm', 'Skip confirmation prompt') 39 | .action((options) => { 40 | if (!options.confirm) { 41 | console.log('Are you sure you want to deploy to production? (y/N): '); 42 | // In real implementation, would wait for user input 43 | } 44 | console.log('Executing production command with options:', options); 45 | process.exit(0); 46 | }); 47 | 48 | // Error handling 49 | program.exitOverride(); 50 | 51 | try { 52 | program.parse(); 53 | } catch (err) { 54 | console.error('Error:', err.message); 55 | process.exit(err.exitCode || 1); 56 | } -------------------------------------------------------------------------------- /tests/development/test-cli-tools.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Test CLI Tools 5 | * 6 | * Tests CLI spec generation and compliance checking 7 | */ 8 | 9 | import { execSync } from 'child_process'; 10 | import fs from 'fs'; 11 | import path from 'path'; 12 | 13 | // Set environment variable 14 | process.env.CARROT_PROJECT_ROOT = process.cwd(); 15 | 16 | console.log('🧪 Testing CLI Tools\n'); 17 | 18 | async function testCLISpecGeneration() { 19 | console.log('📝 Testing CLI Spec Generation...'); 20 | 21 | try { 22 | // Import the CLI spec generation function 23 | const { generateCLISpec } = await import('./dist/src/tools/grow_cli_spec.js'); 24 | 25 | // Test spec generation 26 | const spec = await generateCLISpec('deploy', 'A deployment CLI tool that manages application deployments', { 27 | generateExamples: true, 28 | frameworks: ['node', 'python'] 29 | }); 30 | 31 | console.log('✅ CLI spec generated successfully'); 32 | console.log(` - Command: ${spec.identifier}`); 33 | console.log(` - Type: ${spec.type}`); 34 | console.log(` - Global options: ${spec.specification.interface.global_options.length}`); 35 | console.log(` - Subcommands: ${spec.specification.interface.subcommands ? Object.keys(spec.specification.interface.subcommands).length : 0}`); 36 | console.log(` - Exit codes: ${spec.specification.output.exit_codes.length}`); 37 | console.log(` - Compliance rules: ${spec.complianceRules.length}`); 38 | 39 | // Create specs directory and save spec 40 | const specsDir = path.join(process.cwd(), 'specs', 'cli'); 41 | if (!fs.existsSync(specsDir)) { 42 | fs.mkdirSync(specsDir, { recursive: true }); 43 | } 44 | 45 | const yaml = await import('js-yaml'); 46 | const specYaml = yaml.dump(spec, { indent: 2, lineWidth: 120, noRefs: true }); 47 | fs.writeFileSync(path.join(specsDir, 'deploy.yaml'), specYaml); 48 | 49 | console.log('✅ CLI spec saved to specs/cli/deploy.yaml\n'); 50 | return spec; 51 | 52 | } catch (error) { 53 | console.error('❌ CLI spec generation failed:', error.message); 54 | throw error; 55 | } 56 | } 57 | 58 | async function testCLIComplianceChecking(spec) { 59 | console.log('🔍 Testing CLI Compliance Checking...'); 60 | 61 | try { 62 | // Import the CLI compliance checker 63 | const { CLIComplianceChecker } = await import('./dist/src/tools/compliance/cli-checker.js'); 64 | 65 | // Create a test implementation (good) 66 | const goodImplementation = { 67 | filePath: 'test-deploy.js', 68 | content: ` 69 | import { program } from 'commander'; 70 | 71 | program 72 | .name('deploy') 73 | .description('A deployment CLI tool') 74 | .version('1.0.0') 75 | .option('-h, --help', 'Show help information') 76 | .option('-V, --version', 'Show version information') 77 | .option('-v, --verbose', 'Enable verbose output') 78 | .option('-q, --quiet', 'Suppress output'); 79 | 80 | program 81 | .command('staging') 82 | .description('Deploy to staging environment') 83 | .option('--dry-run', 'Preview deployment') 84 | .action((options) => { 85 | console.log('Deploying to staging'); 86 | process.exit(0); 87 | }); 88 | 89 | program 90 | .command('production') 91 | .description('Deploy to production environment') 92 | .option('--confirm', 'Skip confirmation') 93 | .action((options) => { 94 | console.log('Deploying to production'); 95 | process.exit(0); 96 | }); 97 | 98 | program.parse(); 99 | `, 100 | framework: 'node', 101 | language: 'javascript', 102 | hasArgumentParsing: true, 103 | hasHelpSystem: true, 104 | hasErrorHandling: true, 105 | hasSubcommands: true 106 | }; 107 | 108 | // Create a test implementation (bad) 109 | const badImplementation = { 110 | filePath: 'test-deploy-bad.js', 111 | content: ` 112 | console.log('Deploy tool'); 113 | // No argument parsing 114 | // No help system 115 | // No error handling 116 | `, 117 | framework: 'node', 118 | language: 'javascript', 119 | hasArgumentParsing: false, 120 | hasHelpSystem: false, 121 | hasErrorHandling: false, 122 | hasSubcommands: false 123 | }; 124 | 125 | const checker = new CLIComplianceChecker(); 126 | const context = { 127 | artifactType: 'cli', 128 | projectPath: process.cwd(), 129 | projectContext: { type: 'node', language: 'javascript', framework: [], dependencies: {}, patterns: [], features: [] }, 130 | toolchain: ['npm', 'typescript'], 131 | conventions: [], 132 | environment: 'development' 133 | }; 134 | 135 | // Test good implementation 136 | console.log(' Testing good implementation...'); 137 | const goodResult = await checker.checkCompliance(spec, goodImplementation, context); 138 | console.log(` ✅ Good implementation: ${(goodResult.score * 100).toFixed(1)}% compliant`); 139 | console.log(` - Issues found: ${goodResult.issues.length}`); 140 | console.log(` - Suggestions: ${goodResult.suggestions.length}`); 141 | 142 | // Test bad implementation 143 | console.log(' Testing bad implementation...'); 144 | const badResult = await checker.checkCompliance(spec, badImplementation, context); 145 | console.log(` ❌ Bad implementation: ${(badResult.score * 100).toFixed(1)}% compliant`); 146 | console.log(` - Issues found: ${badResult.issues.length}`); 147 | console.log(` - Suggestions: ${badResult.suggestions.length}`); 148 | 149 | // Show some issues 150 | console.log('\n 📋 Sample issues from bad implementation:'); 151 | badResult.issues.slice(0, 5).forEach((issue, index) => { 152 | console.log(` ${index + 1}. [${issue.severity.toUpperCase()}] ${issue.message}`); 153 | console.log(` 💡 ${issue.suggestion}`); 154 | }); 155 | 156 | // Show compliance dimensions 157 | console.log('\n 📊 Compliance dimensions (bad implementation):'); 158 | Object.entries(badResult.dimensions).forEach(([name, dimension]) => { 159 | const status = dimension.isCompliant ? '✅' : '❌'; 160 | console.log(` ${status} ${dimension.name}: ${(dimension.score * 100).toFixed(1)}% (${dimension.issues.length} issues)`); 161 | }); 162 | 163 | console.log('\n✅ CLI compliance checking completed successfully\n'); 164 | return { goodResult, badResult }; 165 | 166 | } catch (error) { 167 | console.error('❌ CLI compliance checking failed:', error.message); 168 | throw error; 169 | } 170 | } 171 | 172 | async function testFrameworkExamples() { 173 | console.log('🔧 Testing Framework Examples...'); 174 | 175 | try { 176 | const { generateCLISpec } = await import('./dist/src/tools/grow_cli_spec.js'); 177 | 178 | // Generate spec with multiple frameworks 179 | const spec = await generateCLISpec('build-tool', 'A build tool for compiling projects', { 180 | generateExamples: true, 181 | frameworks: ['node', 'python', 'go', 'rust', 'bash'] 182 | }); 183 | 184 | console.log('✅ Multi-framework CLI spec generated'); 185 | console.log(` - Frameworks: node, python, go, rust, bash`); 186 | console.log(` - Command type: ${spec.specification.interface.command.name}`); 187 | console.log(` - Subcommands: ${spec.specification.interface.subcommands ? Object.keys(spec.specification.interface.subcommands).join(', ') : 'none'}`); 188 | 189 | // Check if examples would be generated for each framework 190 | const frameworks = ['node', 'python', 'go', 'rust', 'bash']; 191 | frameworks.forEach(framework => { 192 | console.log(` ✅ ${framework} example ready`); 193 | }); 194 | 195 | console.log('\n✅ Framework examples test completed\n'); 196 | 197 | } catch (error) { 198 | console.error('❌ Framework examples test failed:', error.message); 199 | throw error; 200 | } 201 | } 202 | 203 | async function runTests() { 204 | try { 205 | console.log('🚀 Starting CLI Tools Test Suite\n'); 206 | 207 | // Test 1: CLI Spec Generation 208 | const spec = await testCLISpecGeneration(); 209 | 210 | // Test 2: CLI Compliance Checking 211 | const complianceResults = await testCLIComplianceChecking(spec); 212 | 213 | // Test 3: Framework Examples 214 | await testFrameworkExamples(); 215 | 216 | console.log('🎉 All CLI tools tests passed successfully!'); 217 | console.log('\n📈 Test Summary:'); 218 | console.log(` ✅ CLI spec generation: Working`); 219 | console.log(` ✅ CLI compliance checking: Working`); 220 | console.log(` ✅ Framework examples: Working`); 221 | console.log(` ✅ Good implementation score: ${(complianceResults.goodResult.score * 100).toFixed(1)}%`); 222 | console.log(` ✅ Bad implementation score: ${(complianceResults.badResult.score * 100).toFixed(1)}%`); 223 | console.log(` ✅ Issue detection: ${complianceResults.badResult.issues.length} issues found`); 224 | 225 | } catch (error) { 226 | console.error('\n💥 Test suite failed:', error.message); 227 | console.error(error.stack); 228 | process.exit(1); 229 | } 230 | } 231 | 232 | // Run tests 233 | runTests(); -------------------------------------------------------------------------------- /tests/development/test-cli-universal.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Test Universal CLI Compliance Framework 5 | * 6 | * Tests the universal compliance checker with CLI artifacts 7 | */ 8 | 9 | import fs from 'fs'; 10 | import path from 'path'; 11 | 12 | // Set environment variable 13 | process.env.CARROT_PROJECT_ROOT = process.cwd(); 14 | 15 | console.log('🧪 Testing Universal CLI Compliance Framework\n'); 16 | 17 | async function testUniversalCLICompliance() { 18 | console.log('🔍 Testing Universal CLI Compliance...'); 19 | 20 | try { 21 | // Import the universal compliance framework 22 | const { 23 | ComplianceCheckerFactory, 24 | ComplianceUtils 25 | } = await import('./dist/src/tools/compliance/index.js'); 26 | 27 | // Load the CLI spec 28 | const yaml = await import('js-yaml'); 29 | const specContent = fs.readFileSync('specs/cli/deploy.yaml', 'utf8'); 30 | const spec = yaml.load(specContent); 31 | 32 | // Load the CLI implementation 33 | const implementationContent = fs.readFileSync('test-cli-implementation.js', 'utf8'); 34 | const implementation = { 35 | filePath: 'test-cli-implementation.js', 36 | content: implementationContent, 37 | framework: 'node', 38 | language: 'javascript', 39 | hasArgumentParsing: true, 40 | hasHelpSystem: true, 41 | hasErrorHandling: true, 42 | hasSubcommands: true 43 | }; 44 | 45 | // Create compliance context 46 | const context = { 47 | artifactType: 'cli', 48 | projectPath: process.cwd(), 49 | projectContext: { 50 | type: 'node', 51 | language: 'javascript', 52 | framework: ['commander'], 53 | dependencies: { commander: '^9.0.0' }, 54 | patterns: [], 55 | features: [] 56 | }, 57 | toolchain: ['npm', 'typescript'], 58 | conventions: [], 59 | environment: 'development' 60 | }; 61 | 62 | // Get CLI compliance checker from factory 63 | const checker = ComplianceCheckerFactory.create('cli'); 64 | console.log(` ✅ CLI compliance checker created: ${checker.constructor.name}`); 65 | 66 | // Check if it can handle this artifact 67 | const canHandle = checker.canHandle(spec, implementation, context); 68 | console.log(` ✅ Can handle CLI artifact: ${canHandle}`); 69 | 70 | // Run compliance check 71 | console.log(' Running compliance check...'); 72 | const result = await checker.checkCompliance(spec, implementation, context); 73 | 74 | console.log(` ✅ Compliance check completed`); 75 | console.log(` - Overall score: ${(result.score * 100).toFixed(1)}%`); 76 | console.log(` - Is compliant: ${result.isCompliant ? '✅' : '❌'}`); 77 | console.log(` - Issues found: ${result.issues.length}`); 78 | console.log(` - Suggestions: ${result.suggestions.length}`); 79 | console.log(` - Dimensions: ${Object.keys(result.dimensions).length}`); 80 | 81 | // Show compliance dimensions 82 | console.log('\n 📊 Compliance Dimensions:'); 83 | Object.entries(result.dimensions).forEach(([name, dimension]) => { 84 | const status = dimension.isCompliant ? '✅' : '❌'; 85 | console.log(` ${status} ${dimension.name}: ${(dimension.score * 100).toFixed(1)}% (weight: ${dimension.weight}, issues: ${dimension.issues.length})`); 86 | }); 87 | 88 | // Show top issues 89 | console.log('\n 🔍 Top Issues:'); 90 | result.issues.slice(0, 5).forEach((issue, index) => { 91 | console.log(` ${index + 1}. [${issue.severity.toUpperCase()}] ${issue.message}`); 92 | console.log(` 💡 ${issue.suggestion}`); 93 | }); 94 | 95 | // Show suggestions with code 96 | console.log('\n 💡 Suggestions with Code:'); 97 | result.suggestions.filter(s => s.code).slice(0, 3).forEach((suggestion, index) => { 98 | console.log(` ${index + 1}. [${suggestion.priority.toUpperCase()}] ${suggestion.description}`); 99 | console.log(` 🔧 ${suggestion.code}`); 100 | }); 101 | 102 | // Test compliance summary generation 103 | const summary = ComplianceUtils.generateSummary(result); 104 | console.log(`\n 📋 Generated Summary: ${summary}`); 105 | 106 | console.log('\n✅ Universal CLI compliance testing completed successfully\n'); 107 | return result; 108 | 109 | } catch (error) { 110 | console.error('❌ Universal CLI compliance testing failed:', error.message); 111 | console.error(error.stack); 112 | throw error; 113 | } 114 | } 115 | 116 | async function testSupportedTypes() { 117 | console.log('🔧 Testing Supported Artifact Types...'); 118 | 119 | try { 120 | const { ComplianceCheckerFactory } = await import('./dist/src/tools/compliance/index.js'); 121 | 122 | const supportedTypes = ComplianceCheckerFactory.getSupportedTypes(); 123 | console.log(` ✅ Supported types: ${supportedTypes.join(', ')}`); 124 | 125 | // Test each supported type 126 | for (const type of supportedTypes) { 127 | try { 128 | const checker = ComplianceCheckerFactory.create(type); 129 | console.log(` ✅ ${type}: ${checker.constructor.name}`); 130 | } catch (error) { 131 | console.log(` ❌ ${type}: Failed to create checker`); 132 | } 133 | } 134 | 135 | console.log('\n✅ Supported types testing completed\n'); 136 | 137 | } catch (error) { 138 | console.error('❌ Supported types testing failed:', error.message); 139 | throw error; 140 | } 141 | } 142 | 143 | async function testFrameworkNeutralSpec() { 144 | console.log('📋 Testing Framework-Neutral CLI Spec...'); 145 | 146 | try { 147 | // Load the CLI spec 148 | const yaml = await import('js-yaml'); 149 | const specContent = fs.readFileSync('specs/cli/deploy.yaml', 'utf8'); 150 | const spec = yaml.load(specContent); 151 | 152 | // Verify framework-neutral structure 153 | console.log(` ✅ Spec type: ${spec.type}`); 154 | console.log(` ✅ Identifier: ${spec.identifier}`); 155 | console.log(` ✅ Has interface definition: ${!!spec.specification.interface}`); 156 | console.log(` ✅ Has behavior definition: ${!!spec.specification.behavior}`); 157 | console.log(` ✅ Has output definition: ${!!spec.specification.output}`); 158 | console.log(` ✅ Has usability definition: ${!!spec.specification.usability}`); 159 | console.log(` ✅ Has compatibility definition: ${!!spec.specification.compatibility}`); 160 | 161 | // Check framework-specific type mappings 162 | const globalOptions = spec.specification.interface.global_options; 163 | const hasFrameworkTypes = globalOptions.some(opt => opt.frameworkTypes); 164 | console.log(` ✅ Has framework-specific type mappings: ${hasFrameworkTypes}`); 165 | 166 | if (hasFrameworkTypes) { 167 | const frameworks = Object.keys(globalOptions[0].frameworkTypes); 168 | console.log(` ✅ Supported frameworks: ${frameworks.join(', ')}`); 169 | } 170 | 171 | // Check compliance rules 172 | console.log(` ✅ Compliance rules: ${spec.complianceRules.length}`); 173 | 174 | console.log('\n✅ Framework-neutral spec validation completed\n'); 175 | 176 | } catch (error) { 177 | console.error('❌ Framework-neutral spec validation failed:', error.message); 178 | throw error; 179 | } 180 | } 181 | 182 | async function runTests() { 183 | try { 184 | console.log('🚀 Starting Universal CLI Compliance Test Suite\n'); 185 | 186 | // Test 1: Universal CLI Compliance 187 | const complianceResult = await testUniversalCLICompliance(); 188 | 189 | // Test 2: Supported Types 190 | await testSupportedTypes(); 191 | 192 | // Test 3: Framework-Neutral Spec 193 | await testFrameworkNeutralSpec(); 194 | 195 | console.log('🎉 All universal CLI compliance tests passed successfully!'); 196 | console.log('\n📈 Test Summary:'); 197 | console.log(` ✅ Universal compliance framework: Working`); 198 | console.log(` ✅ CLI compliance checker: Working`); 199 | console.log(` ✅ Framework-neutral specs: Working`); 200 | console.log(` ✅ Compliance score: ${(complianceResult.score * 100).toFixed(1)}%`); 201 | console.log(` ✅ Issue detection: ${complianceResult.issues.length} issues found`); 202 | console.log(` ✅ Suggestion generation: ${complianceResult.suggestions.length} suggestions`); 203 | console.log(` ✅ Supported artifact types: api, ui, db, cli`); 204 | 205 | } catch (error) { 206 | console.error('\n💥 Test suite failed:', error.message); 207 | console.error(error.stack); 208 | process.exit(1); 209 | } 210 | } 211 | 212 | // Run tests 213 | runTests(); -------------------------------------------------------------------------------- /tests/development/test-enhanced-tools.md: -------------------------------------------------------------------------------- 1 | # Enhanced Carrot MCP Tools Test 2 | 3 | ## Problem Statement 4 | The original tools were generating generic, boilerplate specifications that weren't contextually relevant to the actual task domain (Spotify playlist management). This test demonstrates the improvements. 5 | 6 | ## Hypothesis 7 | **Enhanced tools with context analysis will generate domain-specific, relevant specifications that build upon existing project patterns.** 8 | 9 | ## Test Scenarios 10 | 11 | ### Scenario 1: Spotify Playlist Route Creation 12 | **Input**: 13 | - Path: `/api/spotify/playlists/{playlistId}` 14 | - Method: `PATCH` 15 | - Handler: `updatePlaylistHandler` 16 | 17 | **Expected Improvements**: 18 | 1. **Context Detection**: Should detect Spotify domain from path 19 | 2. **Pattern Recognition**: Should identify existing authentication patterns 20 | 3. **Domain-Specific Schemas**: Should generate playlist-specific schemas with proper fields 21 | 4. **Relevant Test Cases**: Should generate Spotify-specific test scenarios 22 | 23 | ### Scenario 2: Generic API Route 24 | **Input**: 25 | - Path: `/api/generic/resource` 26 | - Method: `POST` 27 | - Handler: `createResourceHandler` 28 | 29 | **Expected Behavior**: 30 | - Should fall back to generic patterns but still analyze project context 31 | - Should recommend following existing project patterns 32 | 33 | ## Key Improvements Implemented 34 | 35 | ### 1. Context Analysis Engine 36 | - **Project Structure Analysis**: Scans for existing files, patterns, and dependencies 37 | - **Domain Detection**: Identifies domain from path segments and summary keywords 38 | - **Pattern Recognition**: Detects existing authentication, validation, and API patterns 39 | 40 | ### 2. Domain-Specific Schema Generation 41 | - **Spotify Domain**: Generates playlist-specific schemas with proper fields (name, description, public, collaborative, tracks) 42 | - **User Management**: Generates user-specific schemas and authentication patterns 43 | - **Generic Fallback**: Provides intelligent generic schemas when domain is unclear 44 | 45 | ### 3. Contextual Test Case Generation 46 | - **Domain-Aware Tests**: Generates relevant test scenarios based on detected domain 47 | - **Security Tests**: Includes authorization and ownership validation tests 48 | - **Error Scenarios**: Generates domain-specific error cases 49 | 50 | ### 4. Implementation Guidance 51 | - **Technology Stack Detection**: Identifies existing technologies (Next.js, Zod, etc.) 52 | - **Pattern Consistency**: Recommends following existing project patterns 53 | - **Dependency Management**: Suggests relevant dependencies based on context 54 | 55 | ## Comparison: Before vs After 56 | 57 | ### Before (Generic Boilerplate) 58 | ```json 59 | { 60 | "endpoint": "/api/spotify/playlists/{playlistId}", 61 | "summary": "Update playlist", 62 | "features": [ 63 | { 64 | "name": "multi-task-specs", 65 | "description": "Support for defining complex tasks..." 66 | } 67 | ] 68 | } 69 | ``` 70 | 71 | ### After (Context-Aware) 72 | ```json 73 | { 74 | "endpoint": "/api/spotify/playlists/{playlistId}", 75 | "summary": "Update playlist", 76 | "domain": "spotify", 77 | "specification": { 78 | "purpose": "Spotify playlist management endpoint", 79 | "functionality": { 80 | "core": "Manage user playlists with full CRUD operations", 81 | "authentication": "User-based via x-user-id header", 82 | "authorization": "Users can only access their own playlists" 83 | }, 84 | "dataModel": { 85 | "playlist": { 86 | "id": "Unique playlist identifier (UUID)", 87 | "name": "Playlist name (max 100 chars)", 88 | "description": "Optional description (max 300 chars)", 89 | "public": "Boolean - public visibility", 90 | "collaborative": "Boolean - collaborative editing", 91 | "userId": "Owner user ID", 92 | "tracks": "Array of track objects" 93 | } 94 | } 95 | } 96 | } 97 | ``` 98 | 99 | ## Validation Criteria 100 | 101 | ### ✅ Context Intelligence 102 | - [ ] Detects Spotify domain from path/summary 103 | - [ ] Identifies existing project patterns 104 | - [ ] Recognizes authentication mechanisms 105 | 106 | ### ✅ Domain Relevance 107 | - [ ] Generates playlist-specific schemas 108 | - [ ] Includes relevant validation rules 109 | - [ ] Provides domain-appropriate error handling 110 | 111 | ### ✅ Pattern Consistency 112 | - [ ] Follows existing project structure 113 | - [ ] Maintains consistency with existing APIs 114 | - [ ] Recommends appropriate technologies 115 | 116 | ### ✅ Test Quality 117 | - [ ] Generates relevant test scenarios 118 | - [ ] Includes security and authorization tests 119 | - [ ] Covers domain-specific edge cases 120 | 121 | ## Expected Results 122 | 123 | The enhanced tools should now: 124 | 1. **Generate contextually relevant specifications** instead of generic boilerplate 125 | 2. **Build upon existing project patterns** rather than ignoring them 126 | 3. **Provide domain-specific guidance** for implementation 127 | 4. **Create comprehensive, relevant test cases** for the specific domain 128 | 129 | This represents a significant improvement in the quality and relevance of generated specifications, moving from generic templates to intelligent, context-aware generation. -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "NodeNext", 5 | "lib": ["ES2022"], 6 | "moduleResolution": "NodeNext", 7 | "rootDir": ".", 8 | "outDir": "dist", 9 | "strict": true, 10 | "esModuleInterop": true, 11 | "skipLibCheck": true, 12 | "forceConsistentCasingInFileNames": true, 13 | "resolveJsonModule": true 14 | }, 15 | "include": ["src/**/*"], 16 | "exclude": ["node_modules", "dist"] 17 | } --------------------------------------------------------------------------------