feat: Transform Hanzo AI into ultimate AI engineering toolkit

Major Updates:
- Position as unified platform for building AI-powered companies
- Add 200+ LLMs support (OpenRouter/LiteLLM compatible)
- Implement 45+ legendary programmer modes (carmack, norvig, pike, etc)
- Add browser automation via Playwright MCP integration
- Create multi-platform build system (VS Code, Cursor, Windsurf, Claude Code)
- Implement VS Code Chat Participant as @hanzo
- Update branding: "Ultimate toolkit for AI engineers"

New Features:
- Unlimited memory with vector/graph/relational search
- Browser control tool with auto-Playwright installation
- Smart LLM routing with Hanzo AI fallback
- Support for O3, O3-Pro, Claude 4, and latest models
- Team collaboration with shared context/credits

Build System:
- Unified build script for all platforms
- Versioned output files (hanzoai-1.5.4.vsix/dxt)
- NPM package for CLI installation via npx
- Platform-specific VSIX for Cursor/Windsurf

Documentation:
- Short punchy README focused on benefits
- Comprehensive HANZO_MODES.md for legendary modes
- Updated HANZO_AI.md with complete feature set
- Links to docs.hanzo.ai for full documentation
This commit is contained in:
Hanzo Dev
2025-07-04 22:04:15 -04:00
parent 0b6f26d0bf
commit 40d8709d6e
23 changed files with 4768 additions and 248 deletions
+115
View File
@@ -0,0 +1,115 @@
# VS Code Chat Participant Integration
The Hanzo extension now includes full VS Code Chat Participant integration, making all 53+ MCP tools available through VS Code's chat interface.
## Features
### 1. Chat Participant Registration
- Registered as `@hanzo` (lowercase) in VS Code's chat interface
- Accessible via Ctrl+Alt+I (Cmd+Alt+I on Mac)
- Shows up with the Hanzo icon
### 2. LLM Integration
The chat participant supports multiple LLM providers:
- **Hanzo AI Gateway** (default): Uses api.hanzo.ai
- **LM Studio**: Local models via http://localhost:1234
- **Ollama**: Local models via http://localhost:11434
- **OpenAI**: Direct OpenAI API integration
- **Anthropic**: Direct Claude API integration
### 3. Tool Access
All MCP tools are available through natural language or direct commands:
**File Operations:**
- `@hanzo read src/index.ts`
- `@hanzo write config.json content: { "key": "value" }`
- `@hanzo edit file.ts replace "old" with "new"`
**Search Operations:**
- `@hanzo search "TODO"`
- `@hanzo grep "function" in **/*.ts`
**Shell Operations:**
- `@hanzo run npm test`
- `@hanzo bash git status`
**AI Operations:**
- `@hanzo agent analyze this codebase for security issues`
- `@hanzo dispatch_agent implement new feature X`
### 4. Configuration
Add to VS Code settings.json:
```json
{
// Choose LLM provider
"hanzo.llm.provider": "hanzo", // or "lmstudio", "ollama", "openai", "anthropic"
// Hanzo AI Gateway (default)
"hanzo.llm.hanzo.apiKey": "your-api-key",
// LM Studio (local)
"hanzo.llm.lmstudio.endpoint": "http://localhost:1234/v1",
"hanzo.llm.lmstudio.model": "model-name",
// Ollama (local)
"hanzo.llm.ollama.endpoint": "http://localhost:11434",
"hanzo.llm.ollama.model": "llama2",
// OpenAI
"hanzo.llm.openai.apiKey": "sk-...",
"hanzo.llm.openai.model": "gpt-4",
// Anthropic
"hanzo.llm.anthropic.apiKey": "sk-ant-...",
"hanzo.llm.anthropic.model": "claude-3-opus-20240229"
}
```
### 5. Agent Tool
The `agent` and `dispatch_agent` tools now support all configured LLM providers:
```typescript
// Single agent
@hanzo agent analyze the security of this codebase
// Multi-agent dispatch
@hanzo dispatch_agent implement user authentication with JWT
```
The agent tool will:
- Use the configured LLM provider
- Have access to specified MCP tools
- Execute tasks with proper context
- Support both sequential and parallel execution
### 6. Privacy with Local LLMs
For complete privacy, use LM Studio or Ollama:
1. **LM Studio**: Download from lmstudio.ai, load a model, start the server
2. **Ollama**: Install via `brew install ollama`, run `ollama pull llama2`
Then set `"hanzo.llm.provider": "lmstudio"` or `"ollama"` in settings.
## Installation
1. Install the VSIX: `code --install-extension dist/hanzoai-1.5.4.vsix`
2. Configure your preferred LLM provider in settings
3. Open VS Code chat (Ctrl+Alt+I)
4. Type `@hanzo` to start using the assistant
## Usage Examples
```
@hanzo show available tools
@hanzo read package.json
@hanzo search for TODO comments
@hanzo run the tests
@hanzo agent refactor this function to be more efficient
```
The assistant will use the configured LLM to understand your intent and execute the appropriate tools.
+304
View File
@@ -0,0 +1,304 @@
# Hanzo AI: The Ultimate Toolkit for AI Engineers
Hanzo AI is the ultimate toolkit for AI engineers, providing unified access to every AI model and tool you need. With support for 200+ LLMs from OpenRouter and LiteLLM compatibility, plus 4000+ MCP servers, Hanzo AI supercharges your development workflow with shared context, intelligent search, and seamless model switching.
## Getting Started with Hanzo AI
1. **Create Account**: Visit [iam.hanzo.ai](https://iam.hanzo.ai) to create your account
2. **Get API Key**: After login, obtain your personal API key
3. **Add Credits**: Ensure you have credits in your account
4. **Configure**: Set `HANZO_API_KEY` environment variable or VS Code setting
## Why Hanzo AI is the Ultimate AI Engineering Toolkit
### 🚀 Complete Model Coverage
- **OpenRouter Compatible**: Access every model available on OpenRouter
- **LiteLLM Compatible**: Full compatibility with LiteLLM's model catalog
- **200+ Models**: From O3-Pro and Claude 4 to DeepSeek V3 and Llama 3.1 405B
- **Latest Models**: Always up-to-date with the newest releases
### 🔧 Engineering-First Features
- **Unified API**: Single endpoint for all AI providers - no more juggling API keys
- **Smart Routing**: Automatic failover and load balancing across providers
- **Shared Context**: Maintain conversation context across model switches
- **4000+ MCP Servers**: Access specialized tools for every use case
- **Performance Monitoring**: Track latency, costs, and usage patterns
- **Team Collaboration**: Share API keys, context, and credits with your team
### 💡 Developer Experience
- **Zero Config**: Works out of the box with sensible defaults
- **Local Model Support**: Seamlessly integrate LM Studio and Ollama
- **VS Code Native**: Deep integration with @hanzo chat participant
- **Intelligent Caching**: Reduce costs with smart response caching
- **Error Handling**: Automatic retries and graceful degradation
## Priority Order
The Hanzo agent automatically detects and uses available LLM providers in this order:
1. **Environment Variables** (Highest Priority)
- Direct API calls to providers when keys are detected locally
- Maximum performance with minimal latency
2. **Local LLMs** (Medium-High Priority)
- LM Studio: `LM_STUDIO_BASE_URL`
- Ollama: `OLLAMA_BASE_URL`
3. **VS Code Settings** (Medium Priority)
- `hanzo.llm.{provider}.apiKey` settings
4. **Hanzo AI** (Default)
- Supercharges your AI development with unified access
- Access to all models with credits
- Managed API keys in Hanzo Cloud
## Complete Model Catalog (OpenRouter + LiteLLM Compatible)
Hanzo AI provides access to every model available through OpenRouter and LiteLLM, including:
- **OpenAI**: O3-Pro, O3, GPT-4o, GPT-4 Turbo, GPT-4, GPT-3.5 Turbo
- **Anthropic**: Claude 4, Claude 3.5 Sonnet, Claude 3 Opus, Claude 3 Sonnet, Claude 3 Haiku
- **Google**: Gemini 2.0 Flash, Gemini Pro, Gemini Pro Vision, Gemini Ultra
- **Meta**: Llama 3.1 405B, Llama 3.1 70B, Llama 3 70B, CodeLlama
- **Mistral**: Large 2, Medium, Small, Mixtral 8x22B, Mixtral 8x7B
- **Cohere**: Command R Plus, Command R, Command
- **DeepSeek**: DeepSeek V3, DeepSeek Coder V2
- **Together AI**: Mixtral MOE, Llama variants, CodeLlama
- **Replicate**: Open source models
- **And 190+ more models...**
### Direct API Support (with local env keys)
```bash
# OpenAI
export OPENAI_API_KEY=sk-...
# Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
# Google/Gemini
export GOOGLE_API_KEY=...
# or
export GEMINI_API_KEY=...
# Mistral
export MISTRAL_API_KEY=...
# Cohere
export COHERE_API_KEY=...
# Together AI
export TOGETHER_API_KEY=...
# Replicate
export REPLICATE_API_KEY=...
```
### Hanzo AI (Recommended)
```bash
# Get your API key from iam.hanzo.ai
export HANZO_API_KEY=hzo_...
# Optional: Custom endpoint (defaults to https://api.hanzo.ai/ext/v1)
export HANZO_API_URL=https://api.hanzo.ai/ext/v1
```
### Local LLMs
```bash
# LM Studio
export LM_STUDIO_BASE_URL=http://localhost:1234/v1
# Ollama
export OLLAMA_BASE_URL=http://localhost:11434
```
## Usage Examples
### Using Hanzo AI
```bash
# Automatically uses Hanzo AI when HANZO_API_KEY is set
@hanzo agent analyze this codebase
# Access any of 200+ models through Hanzo AI
@hanzo agent --model o3-pro solve complex algorithm
@hanzo agent --model claude-4 analyze architecture
@hanzo agent --model gpt-4o write tests
@hanzo agent --model claude-3.5-sonnet review code
@hanzo agent --model gemini-2.0-flash explain this code
@hanzo agent --model llama-3.1-405b optimize performance
@hanzo agent --model deepseek-v3 debug issue
@hanzo agent --model mixtral-8x22b generate documentation
```
### Direct API Usage (when local keys available)
```bash
# If OPENAI_API_KEY is set, bypasses Hanzo AI for direct access
@hanzo agent --model gpt-4o task
# Force specific provider with prefix
@hanzo agent --model openai/o3-pro task
@hanzo agent --model anthropic/claude-4 task
@hanzo agent --model google/gemini-2.0-flash task
```
### Model Selection
```bash
# Let Hanzo AI choose the best model
@hanzo agent optimize this function
# Specify exact model from 200+ available
@hanzo agent --model o3-pro solve complex problem
@hanzo agent --model claude-4 review architecture
@hanzo agent --model gpt-4o analyze performance
@hanzo agent --model gemini-2.0-flash quick analysis
@hanzo agent --model llama-3.1-405b deep reasoning
@hanzo agent --model deepseek-v3 code optimization
@hanzo agent --model command-r-plus generate documentation
```
## Why AI Engineers Choose Hanzo AI
### 🎯 **The Complete Toolkit**
- **Every Model**: OpenRouter + LiteLLM = access to every AI model
- **Every Tool**: 4000+ MCP servers for specialized capabilities
- **Every Provider**: OpenAI, Anthropic, Google, Meta, Mistral, and 50+ more
### ⚡ **Built for Performance**
- **Smart Caching**: Reduce redundant API calls
- **Automatic Failover**: Never get blocked by rate limits
- **Load Balancing**: Distribute requests across providers
- **Low Latency**: Optimized routing to nearest endpoints
### 💰 **Cost Optimization**
- **Unified Billing**: One invoice for all AI usage
- **Smart Routing**: Use cheaper models for simple tasks
- **Usage Analytics**: Identify and eliminate waste
- **Team Budgets**: Set limits and track spending
### 🔒 **Enterprise Ready**
- **SOC2 Compliant**: Enterprise-grade security
- **API Key Vault**: Encrypted storage for provider keys
- **Audit Logs**: Complete usage history
- **Team Management**: Role-based access control
## Configuration Priority
1. **Model argument**: `--model gpt-4` (highest)
2. **Environment variables**: Direct provider keys
3. **VS Code settings**: Provider configurations
4. **Hanzo AI**: Default with HANZO_API_KEY
## Provider Status Display
The agent shows which provider is being used:
```
## Task Completed
**LLM Provider**: hanzo (https://api.hanzo.ai/ext/v1)
[Agent results...]
```
For direct API usage:
```
## Task Completed
**LLM Provider**: openai
[Agent results...]
```
## Hanzo Cloud Features
When using Hanzo AI, you get:
- **200+ Models**: Access to all major AI providers and models
- **4000+ MCP Servers**: Specialized tools and integrations
- **Shared Context**: Maintain context across sessions and models
- **Intelligent Search**: Search across all interactions
- **Automatic Failover**: Switches providers if one fails
- **Rate Limiting**: Built-in protection against rate limits
- **Cost Tracking**: Monitor spending across all models
- **API Key Vault**: Securely store provider keys in cloud
- **Team Management**: Share credits, context, and access with your team
- **Usage Insights**: Detailed analytics and reporting
## Getting Your Hanzo API Key
1. Visit [iam.hanzo.ai](https://iam.hanzo.ai)
2. Sign up or log in to your account
3. Navigate to API Keys section
4. Generate a new API key
5. Add credits to your account
6. Set the key as `HANZO_API_KEY` environment variable
## Managing Provider Keys in Hanzo Cloud
Instead of managing multiple API keys locally, you can:
1. Log in to [iam.hanzo.ai](https://iam.hanzo.ai)
2. Go to "API Key Management"
3. Add your provider API keys (OpenAI, Anthropic, etc.)
4. Use Hanzo AI to access all providers with just your Hanzo key
## Troubleshooting
### No Credits Available
```
Error: Insufficient credits in your Hanzo account
```
**Solution**: Add credits at [iam.hanzo.ai](https://iam.hanzo.ai)
### Invalid API Key
```
Error: Invalid Hanzo API key
```
**Solution**: Check your API key at [iam.hanzo.ai](https://iam.hanzo.ai)
### Model Not Available
```
Error: Model xyz not available through Hanzo AI
```
**Solution**: Check supported models or contact support
## Advanced Usage
### Multi-Agent with Mixed Providers
```bash
# Some agents use Hanzo AI, others use direct APIs
@hanzo agent --agents '[
{"name": "Architect", "role": "Design with Claude 4 via Hanzo"},
{"name": "Analyst", "role": "Analyze with O3-Pro via Hanzo"},
{"name": "Coder", "role": "Implement with GPT-4o"},
{"name": "Reviewer", "role": "Review with DeepSeek V3"}
]' implement feature
```
### Credit Optimization
```bash
# Use cheaper models for simple tasks
@hanzo agent --model gpt-3.5-turbo quick task
# Use powerful models for complex tasks
@hanzo agent --model o3-pro complex reasoning
@hanzo agent --model claude-4 deep analysis
@hanzo agent --model llama-3.1-405b advanced math
# Use specialized models
@hanzo agent --model deepseek-v3 code generation
@hanzo agent --model command-r-plus technical writing
@hanzo agent --model gemini-2.0-flash rapid prototyping
```
## Security & Privacy
- **Hanzo AI**: Secure API with encrypted transport
- **Local Keys**: Never sent to Hanzo when using direct APIs
- **Cloud Keys**: Encrypted storage in Hanzo Cloud
- **Audit Trail**: Track all API usage through Hanzo dashboard
- **Privacy Controls**: Configure data retention and privacy settings
## Support
- **Documentation**: [docs.hanzo.ai](https://docs.hanzo.ai)
- **Dashboard**: [iam.hanzo.ai](https://iam.hanzo.ai)
- **Support**: support@hanzo.ai
**Hanzo AI is the unified platform for building AI-powered companies.** Access 200+ LLMs (OpenRouter/LiteLLM compatible), 4000+ MCP servers, legendary programmer modes, unlimited memory with vector/graph/relational search, browser automation, and everything you need to supercharge AI development.
🚀 **[Get Started](https://iam.hanzo.ai)** | 📖 **[View Modes & Features](./HANZO_MODES.md)** | 💬 **[Join Discord](https://discord.gg/hanzoai)**
+318
View File
@@ -0,0 +1,318 @@
# Hanzo AI Modes: Unlock Unlimited Potential
Hanzo AI is the unified platform for building AI-powered companies, offering legendary programmer modes, unlimited memory, expanded context, and advanced search capabilities across all your projects.
## 🧠 Legendary Programmer Modes
Unlock the expertise of computing legends with specialized modes that configure tools, workflows, and philosophies:
### Pioneers & Legends
- **ritchie**: Dennis Ritchie - UNIX philosophy, systems programming
- **kernighan**: Brian Kernighan - Clear code, documentation mastery
- **thompson**: Ken Thompson - Elegant algorithms, minimal design
- **pike**: Rob Pike - Concurrency, simplicity, Go philosophy
- **stroustrup**: Bjarne Stroustrup - C++ design, object-oriented excellence
### Language Masters
- **matz**: Yukihiro Matsumoto - Ruby creator, developer happiness
- **dhh**: David Heinemeier Hansson - Rails philosophy, convention over configuration
- **gosling**: James Gosling - Java creator, enterprise architecture
- **rich**: Rich Harris - Modern web, Svelte innovation
- **wirth**: Niklaus Wirth - Pascal creator, structured programming
### AI & Machine Learning
- **bengio**: Yoshua Bengio - Deep learning pioneer
- **lecun**: Yann LeCun - Computer vision, CNN architecture
- **norvig**: Peter Norvig - AI algorithms, practical implementation
- **ng**: Andrew Ng - ML education, practical AI deployment
### Systems & Infrastructure
- **carmack**: John Carmack - Game engines, performance optimization
- **torvalds**: Linus Torvalds - Linux kernel, distributed development
- **tanenbaum**: Andrew Tanenbaum - Operating systems, distributed computing
- **bernstein**: Daniel J. Bernstein - Security, cryptography, qmail
### Web & Frontend Masters
- **resig**: John Resig - jQuery creator, JavaScript mastery
- **dahl**: Ryan Dahl - Node.js/Deno creator, async programming
- **eich**: Brendan Eich - JavaScript creator, language design
- **crockford**: Douglas Crockford - JavaScript: The Good Parts
### Database & Data
- **gray**: Jim Gray - Transaction processing, database systems
- **hellerstein**: Joseph Hellerstein - Query optimization, data systems
- **stonebraker**: Michael Stonebraker - PostgreSQL, database architecture
### Security & Cryptography
- **rivest**: Ron Rivest - RSA encryption, security algorithms
- **schneier**: Bruce Schneier - Applied cryptography, security thinking
- **bernstein**: Daniel J. Bernstein - qmail, djbdns, curve25519
### Full List of 45+ Modes
```bash
# Activate any mode
@hanzo mode carmack # Game engine optimization
@hanzo mode pike # Go concurrency patterns
@hanzo mode norvig # AI algorithm implementation
```
## 🚀 Unlimited Memory & Context
### Vector + Graph + Relational Search
Hanzo AI combines multiple search paradigms for comprehensive code understanding:
```bash
# Symbolic search across all projects
@hanzo search "class AuthProvider implements"
# Relational queries
@hanzo search "functions that call validateUser()"
# Graph-based navigation
@hanzo search "all dependencies of PaymentService"
# Vector semantic search
@hanzo search "code similar to rate limiting logic"
# Full-text search with regex
@hanzo search "/async.*fetch.*json/i"
```
### Expanded Context Window
- **Unlimited project memory**: Never lose context between sessions
- **Cross-project intelligence**: Learn from all your repositories
- **Persistent workspace state**: Resume exactly where you left off
- **Shared team knowledge**: Collaborate with shared context
## 📊 Unified Dashboard
Manage everything from one powerful interface:
### Project Management
- **Multi-repo overview**: See all projects at a glance
- **Dependency tracking**: Visualize project relationships
- **Change monitoring**: Track modifications across repositories
- **Team collaboration**: Share context and insights
### AI Model Management
- **200+ LLMs**: Access every model through one API
- **Usage analytics**: Track costs and performance
- **Smart routing**: Automatic model selection
- **Credit management**: Monitor and control spending
### Deployment & DevOps
- **One-click deployment**: Deploy any open source app
- **Container management**: Docker and Kubernetes integration
- **CI/CD pipelines**: Automated testing and deployment
- **Monitoring**: Real-time performance tracking
## 🛠️ IDE Integration via MCP
### Terminal Integration
```bash
# Configure for iTerm2
@hanzo configure --ide iterm2
# Native async support
@hanzo terminal --async execute "npm test"
```
### Neovim/Vim Integration
```vim
" Add to your init.vim
Plug 'hanzoai/vim-mcp'
" Use Hanzo AI in vim
:Hanzo analyze current function
:Hanzo refactor selection
:Hanzo explain
```
### Browser Control
```bash
# Enable browser automation
@hanzo browser enable
# Launches Chrome with Playwright
@hanzo browser navigate "https://docs.hanzo.ai"
@hanzo browser screenshot
@hanzo browser extract "CSS selector"
```
The browser tool automatically:
- Installs Playwright MCP server
- Manages Chrome/Chromium instances
- Provides high-level browser control
- Enables web scraping and testing
## 💎 Premium Features
### Supercharge Your AI Development
Subscribe to unlock:
- **Priority access**: Latest models (O3-Pro, Claude 4, GPT-4o)
- **Higher limits**: 10x more requests per minute
- **Team features**: Shared credits and context
- **Advanced search**: Graph-based code intelligence
- **Custom models**: Fine-tuned models for your codebase
- **Dedicated support**: Direct access to Hanzo team
### Pricing Tiers
- **Starter**: $19/month - 100K credits
- **Pro**: $99/month - 1M credits + team features
- **Enterprise**: Custom - Unlimited usage + SLA
## 🏗️ Building AI-Powered Companies
Hanzo AI provides the complete toolkit for AI-driven development:
### Integrated Development
```bash
# Create new AI project
@hanzo create ai-startup --template saas
# Add AI capabilities
@hanzo add llm-integration
@hanzo add vector-search
@hanzo add agent-framework
# Deploy instantly
@hanzo deploy --platform vercel
```
### Pre-built Templates
- **SaaS Starter**: Multi-tenant AI application
- **Agent Platform**: Multi-agent orchestration
- **API Gateway**: LLM proxy with auth
- **Chat Interface**: Production chat UI
- **Analytics Dashboard**: Usage tracking
### Enterprise Features
- **SSO Integration**: SAML, OAuth, LDAP
- **Compliance**: SOC2, HIPAA ready
- **White-labeling**: Custom branding
- **Private deployment**: On-premise options
## 🔧 Configuration
### .hanzo/config.yaml
```yaml
# IDE Configuration
ide:
primary: vscode
terminal: iterm2
editor: neovim
# MCP Servers
mcp:
browser:
enabled: true
defaultBrowser: chrome
headless: false
search:
providers:
- vector
- graph
- relational
- fulltext
memory:
unlimited: true
persistence: cloud
# AI Configuration
ai:
defaultModel: claude-4
fallbackModels:
- gpt-4o
- gemini-2.0-flash
routing:
simple: gpt-3.5-turbo
complex: o3-pro
creative: claude-4
analytical: deepseek-v3
# Team Settings
team:
sharedContext: true
creditPool: true
knowledgeBase: true
```
## 🎯 Getting Started
1. **Install Extension**
```bash
# VS Code/Cursor/Windsurf
Install hanzoai-*.vsix
# Claude Code
Drag hanzoai-*.dxt
# Terminal/Neovim
npx @hanzo/mcp@latest
```
2. **Configure Environment**
```bash
# Set up Hanzo AI
export HANZO_API_KEY=hzo_...
# Configure IDE
@hanzo configure --ide vscode
# Enable browser control
@hanzo browser enable
```
3. **Choose Your Mode**
```bash
# Activate a legendary programmer mode
@hanzo mode carmack # Performance optimization
@hanzo mode norvig # AI implementation
@hanzo mode pike # Clean, concurrent code
```
4. **Start Building**
```bash
# Create AI-powered app
@hanzo create my-ai-startup
# Use unlimited memory
@hanzo remember "Project uses NextJS 14 with App Router"
# Search across everything
@hanzo search "authentication flow"
```
## 🌟 Why Hanzo AI?
**For Individual Developers**
- Access 200+ AI models with one API key
- Legendary programmer modes for expert guidance
- Unlimited memory and context
- Advanced search across all projects
**For Teams**
- Shared context and knowledge base
- Unified billing and credit management
- Collaborative AI development
- Enterprise security and compliance
**For Companies**
- Complete platform for AI-powered products
- Pre-built templates and frameworks
- Instant deployment and scaling
- White-label and customization options
---
**Ready to supercharge your AI development?**
🚀 [Sign up at iam.hanzo.ai](https://iam.hanzo.ai) to get started
💬 Join our community: [discord.gg/hanzoai](https://discord.gg/hanzoai)
📚 Documentation: [docs.hanzo.ai](https://docs.hanzo.ai)
+139
View File
@@ -0,0 +1,139 @@
# Legendary Programmer Modes
The Hanzo extension includes 45+ development modes inspired by legendary programmers and their philosophies. Each mode configures tools and settings to match their development style.
## Usage
```
@hanzo mode list # List all available modes
@hanzo mode activate guido # Activate Python creator mode
@hanzo mode show ritchie # Show details about C creator mode
@hanzo mode current # Show current active mode
```
## Language Creators (19 modes)
### System Languages
- **ritchie** - Dennis Ritchie (C) - *"UNIX: Do one thing and do it well"*
- **bjarne** - Bjarne Stroustrup (C++) - *"C++: Light-weight abstraction"*
- **gosling** - James Gosling (Java) - *"Java: Platform independence"*
- **graydon** - Graydon Hoare (Rust) - *"Fast, reliable, productive — pick three"*
- **pike_thompson** - Rob Pike & Ken Thompson (Go) - *"Less is exponentially more"*
### Dynamic Languages
- **guido** - Guido van Rossum (Python) - *"There should be one-- and preferably only one --obvious way to do it"*
- **matz** - Yukihiro Matsumoto (Ruby) - *"Ruby is designed to make programmers happy"*
- **wall** - Larry Wall (Perl) - *"There's More Than One Way To Do It"*
- **rasmus** - Rasmus Lerdorf (PHP) - *"PHP: Solving web problems pragmatically"*
- **brendan** - Brendan Eich (JavaScript) - *"Always bet on JavaScript"*
### Functional Languages
- **mccarthy** - John McCarthy (Lisp) - *"Lisp: The programmable programming language"*
- **hickey** - Rich Hickey (Clojure) - *"Simple Made Easy"*
- **armstrong** - Joe Armstrong (Erlang) - *"Let it crash and recover"*
- **odersky** - Martin Odersky (Scala) - *"Fusion of functional and object-oriented programming"*
### Modern Languages
- **anders** - Anders Hejlsberg (C#/TypeScript) - *"Pragmatism over dogmatism"*
- **lattner** - Chris Lattner (Swift/LLVM) - *"Performance and safety without compromise"*
- **bak** - Lars Bak (Dart/V8) - *"Fast development and execution"*
### Classic Languages
- **wirth** - Niklaus Wirth (Pascal) - *"Algorithms + Data Structures = Programs"*
- **backus** - John Backus (Fortran) - *"Formula Translation for scientists"*
- **hopper** - Grace Hopper (COBOL) - *"Programming for everyone"*
- **kay** - Alan Kay (Smalltalk) - *"The best way to predict the future is to invent it"*
## Systems & Infrastructure (2 modes)
- **linus** - Linus Torvalds (Linux) - *"Talk is cheap. Show me the code."*
- **ritchie_thompson** - Ritchie & Thompson (UNIX) - *"Keep it simple, stupid"*
## Web Frameworks (7 modes)
### Backend Frameworks
- **dhh** - David Heinemeier Hansson (Rails) - *"Optimize for programmer happiness"*
- **holovaty_willison** - Holovaty & Willison (Django) - *"The web framework for perfectionists with deadlines"*
- **ronacher** - Armin Ronacher (Flask) - *"Web development, one drop at a time"*
- **otwell** - Taylor Otwell (Laravel) - *"The PHP framework for web artisans"*
- **holowaychuk** - TJ Holowaychuk (Express.js) - *"Fast, unopinionated, minimalist"*
### Frontend Frameworks
- **evan** - Evan You (Vue.js) - *"Approachable, versatile, performant"*
- **walke** - Jordan Walke (React) - *"UI as a function of state"*
## JavaScript Ecosystem (3 modes)
- **katz** - Yehuda Katz (Ember.js) - *"Convention over Configuration"*
- **ashkenas** - Jeremy Ashkenas (CoffeeScript) - *"It's just JavaScript"*
- **nolen** - David Nolen (ClojureScript) - *"Functional programming for the web"*
## Database & Infrastructure (1 mode)
- **widenius** - Michael Widenius (MySQL/MariaDB) - *"Open source database for everyone"*
## CSS & Design (2 modes)
- **wathan** - Adam Wathan (Tailwind CSS) - *"Stop writing CSS, start building designs"*
- **otto_thornton** - Otto & Thornton (Bootstrap) - *"Build responsive, mobile-first projects"*
## Special Configurations (6 modes)
- **fullstack** - Full Stack Developer - Frontend to backend, databases to deployment
- **minimal** - Minimalist - Less is more, only essential tools
- **10x** - 10x Engineer - Maximum productivity, all tools enabled
- **security** - Security Engineer - Security first, paranoid by design
- **data_scientist** - Data Scientist - Data analysis and ML focused
- **hanzo** - Hanzo AI - Optimal configuration with all advanced features
## Mode Features
Each mode configures:
1. **Tools**: Specific set of enabled tools matching the programmer's workflow
2. **Philosophy**: The guiding principle of that programmer/language
3. **Config Scores**: Personality traits scored 0-10 (e.g., simplicity, performance, readability)
## Examples
### Python Development (Guido mode)
```
@hanzo mode activate guido
# Enables: read, write, edit, grep, symbols, uvx, think, notebook_read, notebook_edit
# Philosophy: "There should be one-- and preferably only one --obvious way to do it"
# Config: readability: 10, simplicity: 9, explicitness: 10
```
### Systems Programming (Linus mode)
```
@hanzo mode activate linus
# Enables: read, write, edit, grep, git_search, bash, processes, critic
# Philosophy: "Talk is cheap. Show me the code."
# Config: performance: 10, directness: 10, patience: 2
```
### Web Development (DHH mode)
```
@hanzo mode activate dhh
# Enables: read, write, edit, multi_edit, grep, bash, run_command, sql_query
# Philosophy: "Optimize for programmer happiness"
# Config: productivity: 10, conventions: 10, opinionated: 10
```
### Maximum Productivity (10x mode)
```
@hanzo mode activate 10x
# Enables: ALL advanced tools including agent, llm, consensus, think, critic
# Config: productivity: 10, tool_mastery: 10, work_life_balance: 3
```
## Mode Selection Guide
- **Learning a language**: Choose its creator's mode (e.g., `guido` for Python)
- **Building web apps**: Choose framework creator (e.g., `dhh` for Rails, `evan` for Vue)
- **System programming**: Choose `ritchie`, `linus`, or `graydon`
- **Maximum features**: Choose `10x` or `hanzo`
- **Focused work**: Choose `minimal`
- **Security audit**: Choose `security`
Each mode embodies the philosophy and approach of its namesake, helping you code in their style!
+36 -120
View File
@@ -1,139 +1,55 @@
# Hanzo AI
Hanzo AI transforms your IDE into a full blown software engineering ninja.
The ultimate toolkit for AI engineers.
Hanzo seamlessly manages context, tracks changes, and organizes knowledge across your codebase through advanced AI capabilities including vector search, symbolic search, and extended "thinking" processes.
## What You Get
## Features
- **200+ LLMs** - Every model from OpenRouter/LiteLLM in one API
- **4000+ MCP Servers** - Access specialized tools instantly
- **45+ Legendary Modes** - Code like Carmack, think like Norvig
- **Unlimited Memory** - Vector/graph/relational search across all projects
- **Browser Automation** - Built-in Playwright for web tasks
- **Team Collaboration** - Shared context and credits
- **Intelligent Context Management**: Automatically maintains project context across sessions
- **Vector Search**: Find relevant code and documentation using semantic similarity
- **Symbolic Search**: Discover code elements through structure and relationships
- **Extended Thinking**: Leverage advanced reasoning for complex development tasks
- **MCP Server Integration**: Full Model Context Protocol implementation with 65+ tools
- **Claude Desktop Support**: Use all Hanzo tools directly in Claude Desktop
- **Multi-Platform**: Works with VS Code, Cursor, Windsurf, and Claude Desktop
- **Automatic Documentation**: Generate comprehensive documentation from existing code
- **Project Analysis**: Create detailed SPEC.md files through codebase analysis
## Usage
1. Open any project in VS Code
2. Run `Hanzo: Open Project Manager` from the command palette (`Ctrl+Shift+P` / `Cmd+Shift+P`)
3. The project dashboard will appear showing your project overview
4. Enter additional project details if needed
5. Click "Analyze Project" to generate specifications
The extension will:
- Analyze your codebase structure and dependencies
- Generate a comprehensive SPEC.md file
- Create/update .cursorrules with project context
- Build knowledge graphs for enhanced navigation
## Advanced Features
- **Knowledge Management**: Track changes and maintain history across your development lifecycle
- **Rules-Based Assistance**: Define custom rules for code generation and recommendations
- **Integration with LLMs**: Connect with various large language models for diverse capabilities
- **MCP Tools**: File operations, search, shell commands, Git integration, and more
- **Task Management**: Built-in todo system for tracking development tasks
- **Agent Delegation**: Dispatch complex tasks to specialized sub-agents
## MCP (Model Context Protocol) Support
Hanzo includes a complete MCP server implementation, providing powerful tools for AI assistants:
### Quick Start with Claude Desktop
## Quick Start
```bash
# Build and install for Claude Desktop
npm run build:claude-desktop
./dist/claude-desktop/install.sh # Mac/Linux
# or
./dist/claude-desktop/install.bat # Windows
# VS Code / Cursor / Windsurf
Install hanzoai-*.vsix
# Claude Code
Drag hanzoai-*.dxt
# Terminal / Neovim
npx @hanzo/mcp@latest
```
### Build Options
## Use It
```bash
# Development
npm run dev # Watch mode development build
npm run compile # One-time TypeScript compilation
# Get your API key
export HANZO_API_KEY=hzo_... # from iam.hanzo.ai
# Production builds
npm run build # Standard VS Code extension build
npm run build:claude-desktop # Claude Desktop MCP server build
npm run build:dxt # Desktop Extension (DXT) build
npm run build:all # Build all targets
# Talk to any model
@hanzo agent --model o3-pro solve this algorithm
@hanzo agent --model claude-4 review my code
# Testing
npm test # Run all tests
npm run test:unit # Unit tests only
npm run test:integration # Integration tests only
# Activate legendary modes
@hanzo mode carmack # Optimize like a game engine
@hanzo mode norvig # AI implementation mastery
# Packaging
npm run package # Create .vsix package
npm run package:dxt # Create .dxt package for Claude Code
# Control browsers
@hanzo browser navigate https://example.com
@hanzo browser screenshot
# Search everything
@hanzo search "auth flow"
```
### Available MCP Tools
## Links
- **File System**: read, write, edit, multi_edit, directory_tree, find_files, content_replace, diff, watch
- **Search**: grep, search, symbols, git_search, grep_ast, batch_search, unified_search
- **Shell**: run_command, bash, run_background, processes, pkill, logs, npx, uvx, open
- **Development**: todo (unified), think, critic, notebook support
- **AI/Agent**: dispatch_agent, llm, consensus, agent, mode (development personalities)
- **Utility**: batch (atomic operations), web_fetch, rules, config
- **MCP**: mcp (manage arbitrary MCP servers)
🚀 **[Get Started](https://iam.hanzo.ai)** | 📖 **[Docs](https://docs.hanzo.ai)** | 💬 **[Discord](https://discord.gg/hanzoai)**
See [MCP-README.md](./MCP-README.md) for complete documentation.
---
## Debugging
If you encounter "request too long" errors, create a `.hanzoignore` file in your project root using `.gitignore` format:
```
staticfiles/
media/
large-binary.exe
```
### Large Projects
Hanzo automatically chunks file data when processing:
- Projects >10MB are split into multiple processing chunks
- Each chunk is processed separately then combined
- Progress displays in the VS Code notification area
For persistent size issues:
1. Exclude more directories in `.hanzoignore`
2. Remove large binaries or media files
3. Focus analysis on core source directories
## Installation
Install from VS Code Marketplace:
1. Open VS Code
2. Press `Ctrl+P` / `Cmd+P`
3. Type `ext install namanyayg.hanzo`
## Requirements
- VS Code 1.85.0+
- Internet connection for AI capabilities
## Extension Settings
Hanzo works immediately without configuration. Access additional settings via:
- VS Code settings (`Ctrl+,` / `Cmd+,`)
- Hanzo configuration panel in the extension sidebar
## Known Issues & Limitations
- Large projects may require longer analysis time
- Some file types excluded from analysis (binaries, media)
- Performance may vary based on project complexity
## License
Licensed under MIT License. See LICENSE file for details.
Built for engineers who ship.
+215
View File
@@ -0,0 +1,215 @@
# Hanzo MCP Tools - Complete Breakdown
The Hanzo extension provides 53+ powerful tools organized into categories. All tools are accessible through VS Code's chat interface via `@hanzo`.
## 📁 File Operations (6 tools)
### Core File Tools
- **read** - Read any file with line numbers and syntax highlighting
- **write** - Create new files with content
- **edit** - Replace text in files with exact string matching
- **multi_edit** - Make multiple edits to a file in one operation
- **directory_tree** - Display directory structure with file sizes
- **find_files** - Find files by name pattern or content
## 🔍 Search & Analysis (8 tools)
### Search Tools
- **search** - Semantic search across the codebase
- **grep** - Pattern search using regular expressions
- **git_search** - Search through git history
- **symbols** - Find code symbols (functions, classes, variables)
- **unified_search** - Combined search across multiple sources
- **content_replace** - Find and replace across multiple files
- **diff** - Show differences between files or commits
- **web_fetch** - Fetch and analyze web content
## 💻 Shell & System (11 tools)
### Command Execution
- **bash** - Execute bash commands with environment
- **run_command** - Run any shell command
- **run_background** - Run commands in background
- **processes** - List running processes
- **pkill** - Kill processes by name/pattern
- **logs** - View and tail log files
- **npx** - Run Node.js packages
- **uvx** - Run Python packages with uv
- **open** - Open files/URLs in default application
- **process** - Advanced process management
- **mcp** - Run other MCP servers
## 🤖 AI & Intelligence (6 tools)
### AI Tools
- **agent** - AI agent for complex tasks (single or multi-agent)
- **llm** - Query LLM providers (Hanzo, OpenAI, Anthropic, local)
- **consensus** - Get consensus from multiple LLMs
- **llm_manage** - Manage LLM configurations
- **think** - Deep thinking and problem solving
- **critic** - Critical analysis and review
## 📝 Development Tools (6 tools)
### Task Management
- **todo_read** - Read task list
- **todo_write** - Write/update tasks
- **todo_unified** - Unified todo management
- **zen** - Zen mode for focused work
- **rules** - Manage IDE rules (.cursorrules, etc.)
- **config** - Configuration management
## 🗄️ Database & Storage (5 tools)
### Data Management
- **graph_db** - Graph database operations
- **vector_index** - Vector database indexing
- **vector_search** - Semantic vector search
- **vector_similar** - Find similar vectors
- **document_store** - Document storage and retrieval
## 📊 Jupyter & Notebooks (2 tools)
### Notebook Tools
- **notebook_read** - Read Jupyter notebooks
- **notebook_edit** - Edit Jupyter notebook cells
## 🎨 Configuration & Modes (3 tools)
### Environment Setup
- **mode** - Development modes (guido, linus, 10x, etc.)
- **palette** - VS Code command palette access
- **batch** - Batch operations on multiple tools
## 🔧 Utility Tools (6 tools)
### Helpers
- **sql_query** - Execute SQL queries
- **batch_search** - Batch search operations
- **editor** - Advanced editor operations
- **system** - System information and management
- **ast_analyzer** - AST code analysis (experimental)
- **treesitter_analyzer** - Tree-sitter analysis (experimental)
---
## 🚀 Development Modes
The **mode** tool provides preconfigured tool sets based on famous programmers and workflows:
### Language Creators
- **guido** - Guido van Rossum (Python) - "Readability counts"
- **linus** - Linus Torvalds (Linux) - "Talk is cheap. Show me the code."
- **brendan** - Brendan Eich (JavaScript) - "Always bet on JavaScript"
### Special Configurations
- **fullstack** - Frontend to backend, all common tools
- **minimal** - Essential tools only (read, write, edit, grep, bash)
- **10x** - Maximum productivity, all tools enabled
- **security** - Security-focused, read-only tools
- **data_scientist** - Jupyter, SQL, vector tools
- **hanzo** - Optimal Hanzo AI configuration
Example: `@hanzo mode activate 10x`
---
## 🤝 Agent Tool Usage
The unified **agent** tool supports both single and multi-agent workflows:
### Single Agent
```
@hanzo agent analyze security vulnerabilities
@hanzo agent --role "performance expert" optimize this function
@hanzo agent --tools ["read", "grep", "critic"] review this PR
```
### Multi-Agent (Default: Analyst → Developer → Reviewer)
```
@hanzo agent implement user authentication
@hanzo agent --agents [{"name": "Architect", "role": "Design the system"}] design a microservice
@hanzo agent --parallel analyze and fix all TODOs
```
### Model Selection
```
@hanzo agent --model gpt-4 complex reasoning task
@hanzo agent --model llama2 local analysis
@hanzo agent --model claude-3 creative writing
```
---
## 🔐 Privacy & Local LLMs
Configure local LLMs for complete privacy:
### LM Studio
```json
{
"hanzo.llm.provider": "lmstudio",
"hanzo.llm.lmstudio.endpoint": "http://localhost:1234/v1",
"hanzo.llm.lmstudio.model": "codellama-13b"
}
```
### Ollama
```json
{
"hanzo.llm.provider": "ollama",
"hanzo.llm.ollama.endpoint": "http://localhost:11434",
"hanzo.llm.ollama.model": "llama2"
}
```
---
## 📋 Common Workflows
### Code Analysis
```
@hanzo mode activate security
@hanzo agent analyze this codebase for vulnerabilities
@hanzo grep "TODO|FIXME|HACK"
@hanzo critic review recent changes
```
### Feature Development
```
@hanzo mode activate 10x
@hanzo agent implement feature: add dark mode toggle
@hanzo todo_write track progress
@hanzo git_search similar implementations
```
### Refactoring
```
@hanzo symbols find all UserService methods
@hanzo agent refactor UserService to use dependency injection
@hanzo diff show changes
@hanzo critic review refactoring
```
### Documentation
```
@hanzo agent document all public APIs
@hanzo grep "^export" in **/*.ts
@hanzo write API_DOCS.md with findings
```
---
## 🎯 Tool Categories Summary
1. **File Management** (6) - Read, write, edit files
2. **Search & Analysis** (8) - Find anything in code
3. **Shell & System** (11) - Execute commands, manage processes
4. **AI & Intelligence** (6) - LLMs, agents, thinking tools
5. **Development** (6) - Tasks, config, productivity
6. **Database** (5) - Vector, graph, document storage
7. **Notebooks** (2) - Jupyter integration
8. **Configuration** (3) - Modes, settings, batch ops
9. **Utilities** (6) - SQL, analysis, misc tools
Total: **53+ tools** available through `@hanzo` in VS Code!
BIN
View File
Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.1 KiB

After

Width:  |  Height:  |  Size: 13 KiB

+12
View File
@@ -44,12 +44,14 @@ const HanzoMetricsService_1 = require("./services/HanzoMetricsService");
const server_1 = require("./mcp/server");
const config_1 = require("./config");
const content_1 = require("./webview/content");
const hanzo_chat_participant_1 = require("./chat/hanzo-chat-participant");
let projectManager;
let authManager;
let reminderService;
let statusBar;
let metricsService;
let mcpServer;
let chatParticipant;
async function activate(context) {
console.log('Hanzo AI Extension is now active!');
// Initialize services
@@ -63,6 +65,16 @@ async function activate(context) {
mcpServer = new server_1.MCPServer(context);
await mcpServer.initialize();
}
// Initialize VS Code Chat Participant
try {
chatParticipant = new hanzo_chat_participant_1.HanzoChatParticipant(context);
const participant = await chatParticipant.initialize();
context.subscriptions.push(participant);
console.log('Hanzo Chat Participant registered successfully');
}
catch (error) {
console.error('Failed to register chat participant:', error);
}
// Register commands
const disposables = [
vscode.commands.registerCommand('hanzo.openManager', () => {
+1496 -72
View File
File diff suppressed because it is too large Load Diff
+68 -2
View File
@@ -1,7 +1,7 @@
{
"name": "hanzoai",
"displayName": "Hanzo AI Context Manager",
"description": "AI-powered project manager that analyzes codebases, maintains specifications, and tracks changes. Seamlessly integrates with VS Code to provide intelligent project insights and documentation.",
"description": "The ultimate toolkit for AI engineers. Access 200+ LLMs (OpenRouter/LiteLLM compatible), 4000+ MCP servers, and powerful development tools. Features unified API, shared context, intelligent routing, and VS Code native integration.",
"version": "1.5.4",
"publisher": "hanzo-ai",
"private": false,
@@ -48,6 +48,14 @@
],
"main": "./out/extension.js",
"contributes": {
"chatParticipants": [
{
"id": "hanzo",
"name": "Hanzo",
"description": "Ultimate AI engineering toolkit: 200+ LLMs, 4000+ MCP servers, 53+ dev tools",
"isSticky": true
}
],
"commands": [
{
"command": "hanzo.openManager",
@@ -178,6 +186,59 @@
"type": "boolean",
"default": false,
"description": "Enable debug logging"
},
"hanzo.llm.provider": {
"type": "string",
"enum": [
"hanzo",
"lmstudio",
"ollama",
"openai",
"anthropic"
],
"default": "hanzo",
"description": "LLM provider to use for AI features"
},
"hanzo.llm.hanzo.apiKey": {
"type": "string",
"description": "API key for Hanzo AI Gateway"
},
"hanzo.llm.lmstudio.endpoint": {
"type": "string",
"default": "http://localhost:1234/v1",
"description": "LM Studio API endpoint"
},
"hanzo.llm.lmstudio.model": {
"type": "string",
"description": "Model to use in LM Studio"
},
"hanzo.llm.ollama.endpoint": {
"type": "string",
"default": "http://localhost:11434",
"description": "Ollama API endpoint"
},
"hanzo.llm.ollama.model": {
"type": "string",
"default": "llama2",
"description": "Model to use in Ollama"
},
"hanzo.llm.openai.apiKey": {
"type": "string",
"description": "OpenAI API key"
},
"hanzo.llm.openai.model": {
"type": "string",
"default": "gpt-4",
"description": "OpenAI model to use"
},
"hanzo.llm.anthropic.apiKey": {
"type": "string",
"description": "Anthropic API key"
},
"hanzo.llm.anthropic.model": {
"type": "string",
"default": "claude-3-opus-20240229",
"description": "Anthropic model to use"
}
}
},
@@ -202,10 +263,14 @@
"test:auth": "cross-env MOCHA_TEST_FILE=\"Auth and API Test Suite\" node ./out/test/runTest.js",
"test:file-collection": "cross-env MOCHA_TEST_FILE=\"FileCollectionService Test Suite\" node ./out/test/runTest.js",
"test:mcp": "cross-env MOCHA_TEST_FILE=\"MCP.*Tool Test Suite\" node ./out/test/runTest.js",
"test:coverage": "c8 npm test",
"build:mcp": "node scripts/build-mcp-standalone.js",
"build:claude-desktop": "npm run build:mcp && node scripts/build-claude-desktop.js",
"build": "npm run compile && npm run build:mcp && npm run build:claude-desktop",
"build": "node scripts/compile-main.js && npm run build:mcp",
"build:dxt": "node scripts/build-dxt.js",
"build:npm": "node scripts/build-mcp-npm.js",
"build:cursor": "node scripts/build-cursor.js",
"build:windsurf": "node scripts/build-windsurf.js",
"build:all": "node scripts/build-all-platforms.js",
"package": "npm run build:all && vsce package",
"package:claude": "npm run build:claude-desktop",
@@ -232,6 +297,7 @@
"@vscode/vsce": "^2.24.0",
"archiver": "^7.0.1",
"better-sqlite3": "^12.2.0",
"c8": "^10.1.3",
"cross-env": "^7.0.3",
"esbuild": "^0.19.12",
"eslint": "^8.26.0",
+2
View File
@@ -0,0 +1,2 @@
onlyBuiltDependencies:
- better-sqlite3
+44 -12
View File
@@ -11,22 +11,28 @@ const PLATFORMS = {
outputDir: 'out',
package: false
},
'claude-desktop': {
name: 'Claude Desktop MCP',
buildCmd: 'npm run build:claude-desktop',
outputDir: 'dist/claude-desktop',
package: false // Already packaged by build script
},
'dxt': {
name: 'Claude Code DXT',
buildCmd: 'npm run build:dxt',
outputDir: 'dist/dxt',
package: false // Already packaged by build script
},
'mcp-standalone': {
name: 'MCP Standalone',
buildCmd: 'npm run build:mcp',
outputDir: 'dist/mcp-standalone',
'mcp-npm': {
name: 'MCP NPM Package',
buildCmd: 'node scripts/build-mcp-npm.js',
outputDir: 'dist/npm',
package: false
},
'cursor': {
name: 'Cursor IDE Extension',
buildCmd: 'npm run build:cursor',
outputDir: 'dist/cursor',
package: true
},
'windsurf': {
name: 'Windsurf Extension',
buildCmd: 'npm run build:windsurf',
outputDir: 'dist/windsurf',
package: true
}
};
@@ -47,6 +53,14 @@ async function buildAllPlatforms() {
console.log(` Output: ${config.outputDir}`);
try {
// Skip if build command doesn't exist yet
if (platform === 'cursor' || platform === 'windsurf') {
if (!fs.existsSync(`scripts/build-${platform}.js`)) {
console.log(` ⏭️ Skipped (build script not implemented yet)`);
continue;
}
}
// Run build command
console.log(` Running: ${config.buildCmd}`);
execSync(config.buildCmd, { stdio: 'inherit' });
@@ -75,6 +89,18 @@ async function buildAllPlatforms() {
success: true,
path: config.outputDir
});
} else if (platform === 'dxt') {
// DXT outputs to dist/ directly
const dxtFile = 'dist/hanzo-ai.dxt';
if (fs.existsSync(dxtFile)) {
const stats = fs.statSync(dxtFile);
console.log(` ✅ Success! Created ${dxtFile} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
results.push({
platform,
success: true,
path: dxtFile
});
}
} else {
throw new Error('Output directory not created');
}
@@ -99,7 +125,9 @@ async function buildAllPlatforms() {
if (vsixFiles.length > 0) {
const vsixFile = vsixFiles[0];
const targetPath = path.join('dist', vsixFile);
fs.renameSync(vsixFile, targetPath);
if (fs.existsSync(vsixFile)) {
fs.renameSync(vsixFile, targetPath);
}
console.log(` ✅ Created: ${targetPath}`);
}
} catch (error) {
@@ -121,6 +149,10 @@ async function buildAllPlatforms() {
listDistFiles('dist', ' ');
console.log('\n✨ Build complete!');
console.log('\n📦 Installation methods:');
console.log(' Claude Code: Drag dist/hanzoai-*.dxt into Claude Code');
console.log(' Claude Desktop/Code: npx @hanzo/mcp@latest');
console.log(' VS Code: Install dist/hanzoai-*.vsix');
}
function createZipArchive(sourceDir, outputPath) {
@@ -146,7 +178,7 @@ function listDistFiles(dir, prefix = '') {
if (stats.isDirectory()) {
console.log(`${prefix}📁 ${item}/`);
if (item !== 'node_modules') {
if (item !== 'node_modules' && items.length < 20) {
listDistFiles(fullPath, prefix + ' ');
}
} else {
+53
View File
@@ -0,0 +1,53 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('🚀 Building Hanzo MCP for Cursor IDE...\n');
// Cursor uses the same VSIX format as VS Code
// We'll build a standard VSIX that Cursor can install
const distDir = path.join(__dirname, '..', 'dist', 'cursor');
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
fs.mkdirSync(distDir, { recursive: true });
}
try {
// First compile the TypeScript
console.log('📦 Compiling TypeScript...');
execSync('node scripts/compile-main.js', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Build MCP components
console.log('🔧 Building MCP components...');
execSync('npm run build:mcp', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Package the extension
console.log('📦 Packaging Cursor extension...');
execSync('vsce package --no-dependencies --out dist/cursor/', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Read package.json to get version
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
const version = packageJson.version;
// Rename the output file to include cursor in the name
const vsixFiles = fs.readdirSync(distDir).filter(f => f.endsWith('.vsix'));
if (vsixFiles.length > 0) {
const oldPath = path.join(distDir, vsixFiles[0]);
const newPath = path.join(distDir, `hanzoai-cursor-${version}.vsix`);
fs.renameSync(oldPath, newPath);
console.log(`\n✅ Successfully built Cursor extension: ${newPath}`);
console.log(`📦 File size: ${(fs.statSync(newPath).size / 1024 / 1024).toFixed(2)} MB`);
console.log('\n📥 To install in Cursor:');
console.log(' 1. Open Cursor');
console.log(' 2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)');
console.log(' 3. Run "Extensions: Install from VSIX..."');
console.log(` 4. Select ${newPath}`);
}
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
+12 -11
View File
@@ -10,7 +10,9 @@ console.log('Building Hanzo MCP Desktop Extension (.dxt)...\n');
const rootDir = path.join(__dirname, '..');
const dxtDir = path.join(rootDir, 'dxt');
const distDir = path.join(rootDir, 'dist');
const outputFile = path.join(distDir, 'hanzo-ai.dxt');
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
const version = packageJson.version;
const outputFile = path.join(distDir, `hanzoai-${version}.dxt`);
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
@@ -120,19 +122,18 @@ console.log('\\nFor more information: https://github.com/hanzoai/extension');
archive.append(installScript, { name: 'install.js', mode: 0o755 });
// Add icon if it exists
const iconPath = path.join(dxtDir, 'icon.png');
// Add icon
console.log('Adding icon...');
const iconPath = path.join(__dirname, '..', 'images', 'icon.png');
if (fs.existsSync(iconPath)) {
console.log('Adding icon...');
archive.file(iconPath, { name: 'icon.png' });
} else {
// Create a simple icon if none exists
console.log('Creating default icon...');
const defaultIcon = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
'base64'
);
archive.append(defaultIcon, { name: 'icon.png' });
console.error('Warning: icon.png not found at', iconPath);
// Fallback to DXT directory icon if available
const dxtIconPath = path.join(dxtDir, 'icon.png');
if (fs.existsSync(dxtIconPath)) {
archive.file(dxtIconPath, { name: 'icon.png' });
}
}
// Add README
+248
View File
@@ -0,0 +1,248 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('Building @hanzo/mcp npm package...\n');
// Ensure dist directory exists
if (!fs.existsSync('dist')) {
fs.mkdirSync('dist');
}
const npmDir = path.join('dist', 'npm');
if (!fs.existsSync(npmDir)) {
fs.mkdirSync(npmDir, { recursive: true });
}
// First build the MCP server
console.log('Building MCP server...');
execSync('npm run build:mcp', { stdio: 'inherit' });
// Copy server file
console.log('Copying server files...');
fs.copyFileSync('dist/mcp-server.js', path.join(npmDir, 'server.js'));
// Create package.json for npm
const packageJson = {
name: '@hanzo/mcp',
version: require('../package.json').version,
description: 'Hanzo AI MCP server - powerful development tools for Claude Desktop and Claude Code',
main: 'server.js',
bin: {
'hanzo-mcp': './cli.js'
},
scripts: {
start: 'node server.js'
},
keywords: [
'mcp',
'model-context-protocol',
'claude',
'claude-desktop',
'claude-code',
'ai',
'development-tools',
'hanzo'
],
author: 'Hanzo Industries Inc',
license: 'MIT',
repository: {
type: 'git',
url: 'git+https://github.com/hanzoai/extension.git'
},
homepage: 'https://github.com/hanzoai/extension#readme',
bugs: {
url: 'https://github.com/hanzoai/extension/issues'
},
engines: {
node: '>=16.0.0'
},
files: [
'server.js',
'cli.js',
'README.md'
],
publishConfig: {
access: 'public',
registry: 'https://registry.npmjs.org/'
}
};
// Create CLI wrapper
const cliScript = `#!/usr/bin/env node
const { spawn } = require('child_process');
const path = require('path');
const os = require('os');
const fs = require('fs');
const args = process.argv.slice(2);
const command = args[0];
if (command === 'install' || (!command && !args.includes('--help')) || args.includes('--claude-code')) {
console.log('\\n📦 Installing Hanzo MCP...\\n');
// Detect Claude Desktop config location
let configPath;
if (process.platform === 'darwin') {
configPath = path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
} else if (process.platform === 'win32') {
configPath = path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json');
} else {
configPath = path.join(os.homedir(), '.config', 'Claude', 'claude_desktop_config.json');
}
// Check if running in Claude Code (no config needed)
if (process.env.CLAUDE_CODE || args.includes('--claude-code')) {
console.log('✅ Hanzo MCP is ready for Claude Code!');
console.log('\\nTo use in Claude Code:');
console.log('1. The MCP server is available at:', path.join(__dirname, 'server.js'));
console.log('2. Tools will be automatically available in your conversations');
return;
}
// For Claude Desktop, update config
console.log('Configuring for Claude Desktop...');
console.log('Config location:', configPath);
try {
// Ensure directory exists
const configDir = path.dirname(configPath);
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
// Read existing config or create new
let config = {};
if (fs.existsSync(configPath)) {
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
}
// Ensure mcpServers exists
if (!config.mcpServers) {
config.mcpServers = {};
}
// Add Hanzo MCP
config.mcpServers['hanzo-mcp'] = {
command: 'node',
args: [path.join(__dirname, 'server.js')],
env: {}
};
// Write config
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log('\\n✅ Hanzo MCP installed successfully!');
console.log('\\n🔄 Please restart Claude Desktop to use the new tools.');
console.log('\\n📚 Available tools:');
console.log(' - File operations (read, write, edit)');
console.log(' - Search (grep, git_search, symbols)');
console.log(' - Shell commands (bash, processes)');
console.log(' - AI tools (llm, consensus, mode)');
console.log(' - And many more!');
} catch (error) {
console.error('\\n❌ Installation failed:', error.message);
console.error('\\nManual installation:');
console.error('1. Add to your Claude Desktop config:');
console.error(JSON.stringify({
mcpServers: {
'hanzo-mcp': {
command: 'node',
args: [path.join(__dirname, 'server.js')]
}
}
}, null, 2));
}
} else if (command === 'start') {
// Start the MCP server directly
const server = spawn('node', [path.join(__dirname, 'server.js')], {
stdio: 'inherit'
});
server.on('error', (err) => {
console.error('Failed to start server:', err);
process.exit(1);
});
} else {
console.log('Hanzo MCP - Model Context Protocol Server');
console.log('');
console.log('Usage:');
console.log(' npx @hanzo/mcp Install and configure');
console.log(' npx @hanzo/mcp install Install and configure');
console.log(' npx @hanzo/mcp start Start the MCP server');
console.log('');
console.log('Options:');
console.log(' --claude-code Configure for Claude Code');
}
`;
// Create README
const readme = `# @hanzo/mcp
Hanzo AI MCP (Model Context Protocol) server - powerful development tools for Claude Desktop and Claude Code.
## Quick Install
\`\`\`bash
npx @hanzo/mcp@latest
\`\`\`
This will automatically configure the MCP server for your environment.
## Manual Installation
### Claude Desktop
Add to your \`claude_desktop_config.json\`:
\`\`\`json
{
"mcpServers": {
"hanzo-mcp": {
"command": "npx",
"args": ["@hanzo/mcp@latest", "start"]
}
}
}
\`\`\`
### Claude Code
For Claude Code, install the DXT extension or run:
\`\`\`bash
npx @hanzo/mcp@latest --claude-code
\`\`\`
## Available Tools
- **File Operations**: read, write, edit, multi_edit, directory_tree
- **Search**: grep, git_search, find_files, symbols
- **Shell**: bash, run_command, processes, open
- **AI Tools**: llm, consensus, agent, mode
- **Development**: todo, critic, think, rules
- **Web**: web_fetch, batch_search
- **And many more!**
## Documentation
See [https://github.com/hanzoai/extension](https://github.com/hanzoai/extension) for full documentation.
`;
// Write files
console.log('Creating npm package files...');
fs.writeFileSync(path.join(npmDir, 'package.json'), JSON.stringify(packageJson, null, 2));
fs.writeFileSync(path.join(npmDir, 'cli.js'), cliScript);
fs.chmodSync(path.join(npmDir, 'cli.js'), '755');
fs.writeFileSync(path.join(npmDir, 'README.md'), readme);
console.log(`\n✅ NPM package created at: ${npmDir}`);
console.log('\nTo publish:');
console.log(` cd ${npmDir}`);
console.log(' npm publish\n');
console.log('Users can then install with:');
console.log(' npx @hanzo/mcp@latest');
+57
View File
@@ -0,0 +1,57 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('🏄 Building Hanzo MCP for Windsurf IDE...\n');
// Windsurf uses the same VSIX format as VS Code
// We'll build a standard VSIX that Windsurf can install
const distDir = path.join(__dirname, '..', 'dist', 'windsurf');
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
fs.mkdirSync(distDir, { recursive: true });
}
try {
// First compile the TypeScript
console.log('📦 Compiling TypeScript...');
execSync('node scripts/compile-main.js', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Build MCP components
console.log('🔧 Building MCP components...');
execSync('npm run build:mcp', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Package the extension
console.log('📦 Packaging Windsurf extension...');
execSync('vsce package --no-dependencies --out dist/windsurf/', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Read package.json to get version
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
const version = packageJson.version;
// Rename the output file to include windsurf in the name
const vsixFiles = fs.readdirSync(distDir).filter(f => f.endsWith('.vsix'));
if (vsixFiles.length > 0) {
const oldPath = path.join(distDir, vsixFiles[0]);
const newPath = path.join(distDir, `hanzoai-windsurf-${version}.vsix`);
fs.renameSync(oldPath, newPath);
console.log(`\n✅ Successfully built Windsurf extension: ${newPath}`);
console.log(`📦 File size: ${(fs.statSync(newPath).size / 1024 / 1024).toFixed(2)} MB`);
console.log('\n📥 To install in Windsurf:');
console.log(' 1. Open Windsurf');
console.log(' 2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)');
console.log(' 3. Run "Extensions: Install from VSIX..."');
console.log(` 4. Select ${newPath}`);
console.log('\n💡 Windsurf integration includes:');
console.log(' - Full MCP tools access via @hanzo chat participant');
console.log(' - Access to 200+ LLMs through Hanzo AI');
console.log(' - 4000+ MCP servers integration');
}
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
+461
View File
@@ -0,0 +1,461 @@
import * as vscode from 'vscode';
import { MCPTools } from '../mcp/tools';
import axios from 'axios';
import { getConfig } from '../config';
interface LLMConfig {
provider: 'hanzo' | 'lmstudio' | 'ollama' | 'openai' | 'anthropic';
apiKey?: string;
endpoint?: string;
model?: string;
}
export class HanzoChatParticipant {
private static readonly ID = 'hanzo'; // Lowercase for @hanzo
private mcpTools: MCPTools;
private llmConfig: LLMConfig;
constructor(private context: vscode.ExtensionContext) {
this.mcpTools = new MCPTools(context);
this.llmConfig = this.getLLMConfig();
}
async initialize() {
await this.mcpTools.initialize();
// Register chat participant
const participant = vscode.chat.createChatParticipant(
HanzoChatParticipant.ID,
this.handleChat.bind(this)
);
participant.iconPath = vscode.Uri.joinPath(
vscode.Uri.file(__dirname),
'..',
'..',
'images',
'icon.png'
);
// Add follow-up provider
participant.followupProvider = {
provideFollowups: this.provideFollowups.bind(this)
};
return participant;
}
private getLLMConfig(): LLMConfig {
const config = vscode.workspace.getConfiguration('hanzo');
const llmProvider = config.get<string>('llm.provider', 'hanzo');
switch (llmProvider) {
case 'lmstudio':
return {
provider: 'lmstudio',
endpoint: config.get<string>('llm.lmstudio.endpoint', 'http://localhost:1234/v1'),
model: config.get<string>('llm.lmstudio.model')
};
case 'ollama':
return {
provider: 'ollama',
endpoint: config.get<string>('llm.ollama.endpoint', 'http://localhost:11434'),
model: config.get<string>('llm.ollama.model', 'llama2')
};
case 'openai':
return {
provider: 'openai',
apiKey: config.get<string>('llm.openai.apiKey'),
model: config.get<string>('llm.openai.model', 'gpt-4')
};
case 'anthropic':
return {
provider: 'anthropic',
apiKey: config.get<string>('llm.anthropic.apiKey'),
model: config.get<string>('llm.anthropic.model', 'claude-3-opus-20240229')
};
default:
return {
provider: 'hanzo',
endpoint: config.get<string>('api.endpoint', 'https://api.hanzo.ai/ext/v1'),
apiKey: config.get<string>('llm.hanzo.apiKey')
};
}
}
private async handleChat(
request: vscode.ChatRequest,
context: vscode.ChatContext,
stream: vscode.ChatResponseStream,
token: vscode.CancellationToken
): Promise<void> {
stream.progress('Processing your request...');
try {
// First check if this is a direct tool call
const toolCalls = this.parseToolCalls(request.prompt);
if (toolCalls.length > 0) {
// Execute tool calls directly
await this.executeToolCalls(toolCalls, stream);
} else {
// Use LLM to understand the request and potentially call tools
const response = await this.queryLLM(request.prompt, context);
if (response.toolCalls && response.toolCalls.length > 0) {
// LLM wants to use tools
await this.executeToolCalls(response.toolCalls, stream);
} else if (response.content) {
// LLM provided a direct response
stream.markdown(response.content);
} else {
// Fallback to showing available tools
stream.markdown(this.getToolsHelp());
}
}
} catch (error: any) {
stream.markdown(`❌ Error: ${error.message}`);
}
}
private async executeToolCalls(
toolCalls: Array<{ toolName: string; args: any }>,
stream: vscode.ChatResponseStream
): Promise<void> {
for (const { toolName, args } of toolCalls) {
const tool = this.mcpTools.getTool(toolName);
if (tool) {
stream.progress(`Executing ${toolName}...`);
try {
const result = await tool.handler(args);
// Format and stream the result
if (toolName === 'read' || toolName === 'grep' || toolName === 'search') {
// For file content, use code blocks
stream.markdown(`\`\`\`\n${result}\n\`\`\``);
} else {
stream.markdown(result);
}
} catch (error: any) {
stream.markdown(`❌ Error executing ${toolName}: ${error.message}`);
}
} else {
stream.markdown(`❌ Unknown tool: ${toolName}`);
}
}
}
private async queryLLM(
prompt: string,
context: vscode.ChatContext
): Promise<{ content?: string; toolCalls?: Array<{ toolName: string; args: any }> }> {
try {
// Get all available tools for the system prompt
const tools = this.mcpTools.getAllTools();
const toolDescriptions = tools.map(t => `- ${t.name}: ${t.description}`).join('\n');
const systemPrompt = `You are Hanzo, an AI assistant integrated into VS Code with access to powerful development tools.
Available tools:
${toolDescriptions}
When the user asks you to perform tasks, analyze their request and either:
1. Use the appropriate tools to complete the task
2. Provide a helpful response without tools
3. Ask for clarification if needed
To use a tool, respond with a JSON block like this:
\`\`\`json
{
"toolCalls": [
{
"toolName": "read",
"args": { "file_path": "/path/to/file" }
}
]
}
\`\`\`
Otherwise, respond with:
\`\`\`json
{
"content": "Your response here"
}
\`\`\``;
// Query the LLM based on configuration
let response: string;
switch (this.llmConfig.provider) {
case 'lmstudio':
response = await this.queryLMStudio(systemPrompt, prompt);
break;
case 'ollama':
response = await this.queryOllama(systemPrompt, prompt);
break;
case 'openai':
response = await this.queryOpenAI(systemPrompt, prompt);
break;
case 'anthropic':
response = await this.queryAnthropic(systemPrompt, prompt);
break;
default:
response = await this.queryHanzoAPI(systemPrompt, prompt);
}
// Parse the response
try {
const jsonMatch = response.match(/```json\n([\s\S]*?)\n```/);
if (jsonMatch) {
return JSON.parse(jsonMatch[1]);
}
} catch (e) {
// If parsing fails, treat as plain text response
}
return { content: response };
} catch (error: any) {
console.error('LLM query error:', error);
// Fallback to direct tool parsing
const toolCalls = this.parseToolCalls(prompt);
if (toolCalls.length > 0) {
return { toolCalls };
}
return { content: `Error querying LLM: ${error.message}. You can still use tools directly.` };
}
}
private async queryHanzoAPI(systemPrompt: string, userPrompt: string): Promise<string> {
const response = await axios.post(
`${this.llmConfig.endpoint}/llm/chat`,
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
model: this.llmConfig.model || 'gpt-4',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${this.llmConfig.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
private async queryLMStudio(systemPrompt: string, userPrompt: string): Promise<string> {
const response = await axios.post(
`${this.llmConfig.endpoint}/chat/completions`,
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
model: this.llmConfig.model || 'local-model',
temperature: 0.7
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
private async queryOllama(systemPrompt: string, userPrompt: string): Promise<string> {
const response = await axios.post(
`${this.llmConfig.endpoint}/api/generate`,
{
model: this.llmConfig.model || 'llama2',
prompt: `${systemPrompt}\n\nUser: ${userPrompt}\nAssistant:`,
stream: false
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
return response.data.response;
}
private async queryOpenAI(systemPrompt: string, userPrompt: string): Promise<string> {
const response = await axios.post(
'https://api.openai.com/v1/chat/completions',
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: userPrompt }
],
model: this.llmConfig.model || 'gpt-4',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${this.llmConfig.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
private async queryAnthropic(systemPrompt: string, userPrompt: string): Promise<string> {
const response = await axios.post(
'https://api.anthropic.com/v1/messages',
{
messages: [
{ role: 'user', content: userPrompt }
],
model: this.llmConfig.model || 'claude-3-opus-20240229',
system: systemPrompt,
max_tokens: 4096
},
{
headers: {
'x-api-key': this.llmConfig.apiKey,
'anthropic-version': '2023-06-01',
'Content-Type': 'application/json'
}
}
);
return response.data.content[0].text;
}
private parseToolCalls(prompt: string): Array<{ toolName: string; args: any }> {
const toolCalls: Array<{ toolName: string; args: any }> = [];
// Simple pattern matching for common commands
const patterns = [
// File operations
{ regex: /read\s+(.+)/, tool: 'read', args: (m: RegExpMatchArray) => ({ file_path: m[1].trim() }) },
{ regex: /write\s+(.+?)\s+content:\s*(.+)/s, tool: 'write', args: (m: RegExpMatchArray) => ({ file_path: m[1].trim(), content: m[2].trim() }) },
{ regex: /edit\s+(.+?)\s+replace\s+"(.+?)"\s+with\s+"(.+?)"/s, tool: 'edit', args: (m: RegExpMatchArray) => ({ file_path: m[1].trim(), old_string: m[2], new_string: m[3] }) },
// Search operations
{ regex: /search\s+"(.+?)"(?:\s+in\s+(.+))?/, tool: 'search', args: (m: RegExpMatchArray) => ({ query: m[1], include: m[2]?.trim() }) },
{ regex: /grep\s+"(.+?)"(?:\s+(.+))?/, tool: 'grep', args: (m: RegExpMatchArray) => ({ pattern: m[1], include: m[2]?.trim() || '**/*' }) },
// Shell operations
{ regex: /run\s+(.+)/, tool: 'run_command', args: (m: RegExpMatchArray) => ({ command: m[1].trim() }) },
{ regex: /bash\s+(.+)/, tool: 'bash', args: (m: RegExpMatchArray) => ({ command: m[1].trim() }) },
// Directory operations
{ regex: /ls\s+(.+)/, tool: 'directory_tree', args: (m: RegExpMatchArray) => ({ path: m[1].trim() }) },
{ regex: /tree\s+(.+)/, tool: 'directory_tree', args: (m: RegExpMatchArray) => ({ path: m[1].trim() }) },
// AI operations
{ regex: /agent\s+(.+)/, tool: 'agent', args: (m: RegExpMatchArray) => ({ task: m[1].trim() }) },
];
for (const pattern of patterns) {
const match = prompt.match(pattern.regex);
if (match) {
toolCalls.push({
toolName: pattern.tool,
args: pattern.args(match)
});
break; // Only process first match for now
}
}
return toolCalls;
}
private provideFollowups(
result: vscode.ChatResult,
context: vscode.ChatContext,
token: vscode.CancellationToken
): vscode.ProviderResult<vscode.ChatFollowup[]> {
return [
{
prompt: 'Show available tools',
label: 'Available Tools',
command: 'help'
},
{
prompt: 'Search for "TODO" in all files',
label: 'Find TODOs',
command: 'search'
},
{
prompt: 'Show current directory structure',
label: 'Directory Tree',
command: 'tree'
},
{
prompt: 'Configure LLM provider',
label: 'LLM Settings',
command: 'llm_manage'
}
];
}
private getToolsHelp(): string {
const tools = this.mcpTools.getAllTools();
const categories: Record<string, string[]> = {
'File Operations': ['read', 'write', 'edit', 'multi_edit'],
'Search': ['search', 'grep', 'git_search', 'symbols'],
'Shell': ['bash', 'run_command', 'processes'],
'Directory': ['directory_tree', 'find_files'],
'AI': ['llm', 'consensus', 'mode', 'agent'],
'Development': ['todo_read', 'todo_write', 'critic', 'think']
};
let help = `# @hanzo AI Assistant
I have access to ${tools.length} tools to help you with development tasks.
## Current LLM Provider: ${this.llmConfig.provider}
${this.llmConfig.provider === 'hanzo' ? 'Using Hanzo AI Gateway (api.hanzo.ai)' : ''}
${this.llmConfig.provider === 'lmstudio' ? `Using LM Studio at ${this.llmConfig.endpoint}` : ''}
${this.llmConfig.provider === 'ollama' ? `Using Ollama at ${this.llmConfig.endpoint}` : ''}
## Available Tools by Category:\n\n`;
for (const [category, toolNames] of Object.entries(categories)) {
const categoryTools = toolNames
.map(name => tools.find(t => t.name === name))
.filter(Boolean);
if (categoryTools.length > 0) {
help += `### ${category}\n`;
for (const tool of categoryTools) {
if (tool) {
help += `- **${tool.name}**: ${tool.description}\n`;
}
}
help += '\n';
}
}
help += `## Example Commands:
- "read src/index.ts"
- "search for TODO"
- "grep 'function' in **/*.ts"
- "run npm test"
- "show directory tree for src"
- "agent analyze this codebase for security issues"
## LLM Configuration:
You can configure your LLM provider in VS Code settings:
- hanzo.llm.provider: Choose from 'hanzo', 'lmstudio', 'ollama', 'openai', 'anthropic'
- hanzo.llm.[provider].endpoint: Set custom endpoints for local providers
- hanzo.llm.[provider].model: Choose specific models
Ask me to use any of these tools to help with your development tasks!`;
return help;
}
}
+12
View File
@@ -7,6 +7,7 @@ import { HanzoMetricsService } from './services/HanzoMetricsService';
import { MCPServer } from './mcp/server';
import { getConfig } from './config';
import { getWebviewContent } from './webview/content';
import { HanzoChatParticipant } from './chat/hanzo-chat-participant';
let projectManager: ProjectManager | undefined;
let authManager: AuthManager | undefined;
@@ -14,6 +15,7 @@ let reminderService: ReminderService | undefined;
let statusBar: StatusBarService | undefined;
let metricsService: HanzoMetricsService | undefined;
let mcpServer: MCPServer | undefined;
let chatParticipant: HanzoChatParticipant | undefined;
export async function activate(context: vscode.ExtensionContext) {
console.log('Hanzo AI Extension is now active!');
@@ -30,6 +32,16 @@ export async function activate(context: vscode.ExtensionContext) {
mcpServer = new MCPServer(context);
await mcpServer.initialize();
}
// Initialize VS Code Chat Participant
try {
chatParticipant = new HanzoChatParticipant(context);
const participant = await chatParticipant.initialize();
context.subscriptions.push(participant);
console.log('Hanzo Chat Participant registered successfully');
} catch (error) {
console.error('Failed to register chat participant:', error);
}
// Register commands
const disposables = [
+546 -13
View File
@@ -1,17 +1,52 @@
import * as vscode from 'vscode';
import { MCPTool } from '../server';
import axios from 'axios';
interface AgentConfig {
task: string;
role?: string;
tools?: string[];
model?: string;
agents?: Array<{
name: string;
role: string;
tools?: string[];
}>;
parallel?: boolean;
}
interface LLMProvider {
name: string;
endpoint?: string;
apiKey?: string;
models: string[];
priority: number;
}
export function createAgentTools(context: vscode.ExtensionContext): MCPTool[] {
return [
{
name: 'dispatch_agent',
description: 'Delegate tasks to specialized sub-agents',
name: 'agent',
description: 'AI agent that can use tools to complete complex tasks. Supports single or multi-agent workflows.',
inputSchema: {
type: 'object',
properties: {
task: {
type: 'string',
description: 'Task description for the agent'
description: 'Task description for the agent(s)'
},
role: {
type: 'string',
description: 'Role/persona for single agent mode (e.g., "security expert", "performance optimizer")'
},
tools: {
type: 'array',
items: { type: 'string' },
description: 'Specific tools the agent can use (defaults to all appropriate tools)'
},
model: {
type: 'string',
description: 'LLM model to use (e.g., "gpt-4", "claude-3", "llama2", "gemini/gemini-pro")'
},
agents: {
type: 'array',
@@ -26,24 +61,522 @@ export function createAgentTools(context: vscode.ExtensionContext): MCPTool[] {
}
}
},
description: 'Agents to dispatch (optional, will auto-select if not provided)'
description: 'Multi-agent configuration (optional)'
},
parallel: {
type: 'boolean',
description: 'Run agents in parallel (default: false)'
description: 'Run multiple agents in parallel (default: false)'
}
},
required: ['task']
},
handler: async (args: {
task: string;
agents?: Array<{ name: string; role: string; tools?: string[] }>;
parallel?: boolean;
}) => {
// TODO: Implement agent dispatch functionality
// This would integrate with LLM providers to create sub-agents
return 'Agent dispatch functionality coming soon';
handler: async (args: AgentConfig) => {
const providers = detectLLMProviders();
const selectedProvider = selectProvider(providers, args.model);
if (!selectedProvider) {
return 'Error: No LLM provider available. Please configure API keys in environment or VS Code settings.';
}
// Single agent mode
if (!args.agents) {
const agent = {
name: 'Agent',
role: args.role || 'AI assistant that completes tasks using available tools',
tools: args.tools
};
try {
const result = await executeAgent(
agent,
args.task,
selectedProvider,
args.model
);
return `## Task Completed\n\n${result}`;
} catch (error: any) {
return `Error: ${error.message}`;
}
}
// Multi-agent mode
const defaultAgents = [
{
name: 'Analyst',
role: 'Analyze requirements and understand the codebase',
tools: ['read', 'search', 'grep', 'directory_tree', 'symbols', 'git_search']
},
{
name: 'Developer',
role: 'Implement changes and write code',
tools: ['write', 'edit', 'multi_edit', 'bash', 'run_command', 'npx', 'uvx']
},
{
name: 'Reviewer',
role: 'Review changes and ensure quality',
tools: ['read', 'git_search', 'diff', 'critic', 'think', 'grep']
}
];
const agents = args.agents || defaultAgents;
try {
if (args.parallel) {
// Execute agents in parallel
const promises = agents.map(agent =>
executeAgent(agent, args.task, selectedProvider, args.model)
);
const results = await Promise.all(promises);
return formatAgentResults(agents, results, selectedProvider);
} else {
// Execute agents sequentially with context passing
const results: string[] = [];
let context = '';
for (const agent of agents) {
const result = await executeAgent(
agent,
args.task,
selectedProvider,
args.model,
context
);
results.push(result);
context += `\n\n${agent.name} completed:\n${result}`;
}
return formatAgentResults(agents, results, selectedProvider);
}
} catch (error: any) {
return `Error in multi-agent execution: ${error.message}`;
}
}
}
];
}
function detectLLMProviders(): LLMProvider[] {
const providers: LLMProvider[] = [];
const config = vscode.workspace.getConfiguration('hanzo');
// Check environment variables first (highest priority)
// OpenAI
if (process.env.OPENAI_API_KEY) {
providers.push({
name: 'openai',
apiKey: process.env.OPENAI_API_KEY,
models: ['o3-pro', 'o3', 'gpt-4o', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'],
priority: 1
});
}
// Anthropic
if (process.env.ANTHROPIC_API_KEY) {
providers.push({
name: 'anthropic',
apiKey: process.env.ANTHROPIC_API_KEY,
models: ['claude-4', 'claude-3.5-sonnet', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229', 'claude-3-haiku-20240307'],
priority: 1
});
}
// Google (Gemini)
if (process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY) {
providers.push({
name: 'google',
apiKey: process.env.GOOGLE_API_KEY || process.env.GEMINI_API_KEY,
models: ['gemini/gemini-pro', 'gemini/gemini-pro-vision'],
priority: 1
});
}
// Mistral
if (process.env.MISTRAL_API_KEY) {
providers.push({
name: 'mistral',
apiKey: process.env.MISTRAL_API_KEY,
models: ['mistral/mistral-large-latest', 'mistral/mistral-medium', 'mistral/mistral-small'],
priority: 1
});
}
// Cohere
if (process.env.COHERE_API_KEY) {
providers.push({
name: 'cohere',
apiKey: process.env.COHERE_API_KEY,
models: ['command-r', 'command-r-plus'],
priority: 1
});
}
// Together AI
if (process.env.TOGETHER_API_KEY) {
providers.push({
name: 'together',
apiKey: process.env.TOGETHER_API_KEY,
models: ['together/mixtral-8x7b', 'together/llama-2-70b'],
priority: 1
});
}
// Replicate
if (process.env.REPLICATE_API_KEY) {
providers.push({
name: 'replicate',
apiKey: process.env.REPLICATE_API_KEY,
models: ['replicate/llama-2-70b-chat', 'replicate/mistral-7b'],
priority: 1
});
}
// Local providers (lower priority)
// LM Studio
if (process.env.LM_STUDIO_BASE_URL || config.get<string>('llm.lmstudio.endpoint')) {
providers.push({
name: 'lmstudio',
endpoint: process.env.LM_STUDIO_BASE_URL || config.get<string>('llm.lmstudio.endpoint', 'http://localhost:1234/v1'),
models: ['local-model'],
priority: 2
});
}
// Ollama
if (process.env.OLLAMA_BASE_URL || config.get<string>('llm.ollama.endpoint')) {
providers.push({
name: 'ollama',
endpoint: process.env.OLLAMA_BASE_URL || config.get<string>('llm.ollama.endpoint', 'http://localhost:11434'),
models: ['llama2', 'mistral', 'codellama'],
priority: 2
});
}
// VS Code settings (medium priority)
const vsCodeProviders = ['openai', 'anthropic', 'google', 'mistral', 'cohere'];
for (const provider of vsCodeProviders) {
const apiKey = config.get<string>(`llm.${provider}.apiKey`);
if (apiKey && !providers.find(p => p.name === provider)) {
providers.push({
name: provider,
apiKey: apiKey,
models: getDefaultModels(provider),
priority: 3
});
}
}
// Hanzo AI - Supercharge your AI development with shared context and search
// Access 200+ LLMs and 4000+ MCP servers through one unified API
const hanzoApiKey = process.env.HANZO_API_KEY || config.get<string>('llm.hanzo.apiKey');
if (hanzoApiKey || !providers.length) {
providers.push({
name: 'hanzo',
endpoint: process.env.HANZO_API_URL || config.get<string>('api.endpoint', 'https://api.hanzo.ai/ext/v1'),
apiKey: hanzoApiKey,
models: ['o3-pro', 'o3', 'claude-4', 'gpt-4o', 'gpt-4-turbo', 'claude-3.5-sonnet', 'claude-3-opus', 'gemini-2.0-flash', 'gemini-pro', 'llama-3.1-405b', 'mixtral-8x22b', 'command-r-plus', 'deepseek-v3'],
priority: providers.length === 0 ? 1 : 4 // Higher priority if no other providers
});
}
return providers.sort((a, b) => a.priority - b.priority);
}
function getDefaultModels(provider: string): string[] {
switch (provider) {
case 'openai':
return ['o3-pro', 'o3', 'gpt-4o', 'gpt-4-turbo', 'gpt-4', 'gpt-3.5-turbo'];
case 'anthropic':
return ['claude-4', 'claude-3.5-sonnet', 'claude-3-opus-20240229', 'claude-3-sonnet-20240229'];
case 'google':
return ['gemini/gemini-2.0-flash', 'gemini/gemini-pro', 'gemini/gemini-pro-vision', 'gemini/gemini-ultra'];
case 'mistral':
return ['mistral/mistral-large-latest', 'mistral/mistral-medium'];
case 'cohere':
return ['command-r', 'command-r-plus'];
default:
return ['gpt-4'];
}
}
function selectProvider(providers: LLMProvider[], requestedModel?: string): LLMProvider | null {
if (!providers.length) {
return null;
}
// If a specific model is requested, find the provider that supports it
if (requestedModel) {
// Check for provider prefix (e.g., "openai/gpt-4", "anthropic/claude-3")
const [providerPrefix, modelName] = requestedModel.includes('/')
? requestedModel.split('/', 2)
: [null, requestedModel];
if (providerPrefix) {
const provider = providers.find(p => p.name === providerPrefix);
if (provider) return provider;
}
// Find provider that has this model
for (const provider of providers) {
if (provider.models.some(m => m === requestedModel || m.endsWith(`/${requestedModel}`))) {
return provider;
}
}
}
// Return highest priority provider
return providers[0];
}
async function executeAgent(
agent: { name: string; role: string; tools?: string[] },
task: string,
provider: LLMProvider,
requestedModel?: string,
previousContext: string = ''
): Promise<string> {
const systemPrompt = `You are ${agent.name}, an AI agent with the following role: ${agent.role}
You have access to these tools: ${agent.tools?.join(', ') || 'all available tools'}
Your task: ${task}
${previousContext ? `Previous context:\n${previousContext}` : ''}
Complete your task and provide a clear summary of what you accomplished.`;
try {
let response: string;
// Use Hanzo AI endpoint - supercharge your AI development
if (provider.name === 'hanzo') {
response = await queryHanzoAI(systemPrompt, task, provider, requestedModel);
} else {
// Direct provider calls for better performance when API keys are available
switch (provider.name) {
case 'openai':
response = await queryOpenAI(systemPrompt, task, provider, requestedModel);
break;
case 'anthropic':
response = await queryAnthropic(systemPrompt, task, provider, requestedModel);
break;
case 'google':
response = await queryGoogle(systemPrompt, task, provider, requestedModel);
break;
case 'mistral':
response = await queryMistral(systemPrompt, task, provider, requestedModel);
break;
case 'cohere':
response = await queryCohere(systemPrompt, task, provider, requestedModel);
break;
case 'lmstudio':
response = await queryLMStudio(systemPrompt, task, provider, requestedModel);
break;
case 'ollama':
response = await queryOllama(systemPrompt, task, provider, requestedModel);
break;
default:
// Fallback to Hanzo AI for any other providers
response = await queryHanzoAI(systemPrompt, task, provider, requestedModel);
}
}
return response;
} catch (error: any) {
throw new Error(`${agent.name} failed: ${error.message}`);
}
}
async function queryHanzoAI(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
`${provider.endpoint}/llm/chat`,
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: task }
],
model: model || provider.models[0] || 'gpt-4o',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${provider.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
async function queryOpenAI(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
'https://api.openai.com/v1/chat/completions',
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: task }
],
model: model || 'gpt-4o',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${provider.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
async function queryAnthropic(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
'https://api.anthropic.com/v1/messages',
{
messages: [
{ role: 'user', content: task }
],
model: model || 'claude-4',
system: systemPrompt,
max_tokens: 4096
},
{
headers: {
'x-api-key': provider.apiKey,
'anthropic-version': '2023-06-01',
'Content-Type': 'application/json'
}
}
);
return response.data.content[0].text;
}
async function queryGoogle(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
// Google/Gemini via their API
const endpoint = 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent';
const response = await axios.post(
`${endpoint}?key=${provider.apiKey}`,
{
contents: [{
parts: [{
text: `${systemPrompt}\n\nUser: ${task}`
}]
}],
generationConfig: {
temperature: 0.7,
maxOutputTokens: 4096
}
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
return response.data.candidates[0].content.parts[0].text;
}
async function queryMistral(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
'https://api.mistral.ai/v1/chat/completions',
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: task }
],
model: model || 'mistral-large-latest',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${provider.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
async function queryCohere(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
'https://api.cohere.ai/v1/chat',
{
message: task,
preamble: systemPrompt,
model: model || 'command-r',
temperature: 0.7
},
{
headers: {
'Authorization': `Bearer ${provider.apiKey}`,
'Content-Type': 'application/json'
}
}
);
return response.data.text;
}
async function queryLMStudio(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
`${provider.endpoint}/chat/completions`,
{
messages: [
{ role: 'system', content: systemPrompt },
{ role: 'user', content: task }
],
model: model || 'local-model',
temperature: 0.7
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
return response.data.choices[0].message.content;
}
async function queryOllama(systemPrompt: string, task: string, provider: LLMProvider, model?: string): Promise<string> {
const response = await axios.post(
`${provider.endpoint}/api/generate`,
{
model: model || 'llama2',
prompt: `${systemPrompt}\n\nUser: ${task}\nAssistant:`,
stream: false
},
{
headers: {
'Content-Type': 'application/json'
}
}
);
return response.data.response;
}
function formatAgentResults(
agents: Array<{ name: string; role: string; tools?: string[] }>,
results: string[],
provider: LLMProvider
): string {
let output = '# Multi-Agent Task Results\n\n';
output += `**LLM Provider**: ${provider.name}${provider.endpoint ? ` (${provider.endpoint})` : ''}\n\n`;
agents.forEach((agent, index) => {
output += `## ${agent.name}\n`;
output += `**Role:** ${agent.role}\n`;
output += `**Tools:** ${agent.tools?.join(', ') || 'all available'}\n\n`;
output += `### Result:\n${results[index]}\n\n`;
output += '---\n\n';
});
return output;
}
+2 -2
View File
@@ -259,8 +259,8 @@ export class BashTools {
// Execute command
return new Promise((resolve, reject) => {
const proc = cp.exec(command, {
cwd: session.cwd,
env: session.env,
cwd: session?.cwd || process.cwd(),
env: session?.env || process.env,
timeout,
maxBuffer: 10 * 1024 * 1024 // 10MB
}, (error, stdout, stderr) => {
+317
View File
@@ -0,0 +1,317 @@
import * as vscode from 'vscode';
import { MCPTool } from '../server';
import * as cp from 'child_process';
import * as path from 'path';
import * as fs from 'fs';
interface BrowserAction {
action: 'navigate' | 'screenshot' | 'click' | 'type' | 'extract' | 'wait' | 'evaluate';
url?: string;
selector?: string;
text?: string;
script?: string;
timeout?: number;
outputPath?: string;
}
export function createBrowserTools(context: vscode.ExtensionContext): MCPTool[] {
return [
{
name: 'browser',
description: 'Control a browser instance via Playwright. Automatically installs Playwright MCP if needed.',
inputSchema: {
type: 'object',
properties: {
action: {
type: 'string',
enum: ['navigate', 'screenshot', 'click', 'type', 'extract', 'wait', 'evaluate', 'install'],
description: 'Browser action to perform'
},
url: {
type: 'string',
description: 'URL to navigate to (for navigate action)'
},
selector: {
type: 'string',
description: 'CSS selector for click/type/extract actions'
},
text: {
type: 'string',
description: 'Text to type (for type action)'
},
script: {
type: 'string',
description: 'JavaScript to evaluate (for evaluate action)'
},
timeout: {
type: 'number',
description: 'Timeout in milliseconds (default: 30000)',
default: 30000
},
outputPath: {
type: 'string',
description: 'Path to save screenshot (for screenshot action)'
}
},
required: ['action']
},
handler: async (args: BrowserAction) => {
const playwrightMcpPath = await ensurePlaywrightMCP(context);
if (args.action === 'install') {
return `✅ Playwright MCP installed at: ${playwrightMcpPath}`;
}
// Check if browser instance is running
const browserState = context.globalState.get<{ pid?: number }>('browserState', {});
if (!browserState.pid || !isProcessRunning(browserState.pid)) {
// Start browser instance
const result = await startBrowser(context, playwrightMcpPath);
if (result.error) {
return `Error starting browser: ${result.error}`;
}
browserState.pid = result.pid;
await context.globalState.update('browserState', browserState);
}
// Execute browser action
try {
const result = await executeBrowserAction(args, playwrightMcpPath);
return result;
} catch (error: any) {
return `Browser action failed: ${error.message}`;
}
}
},
{
name: 'browser_close',
description: 'Close the browser instance',
inputSchema: {
type: 'object',
properties: {}
},
handler: async () => {
const browserState = context.globalState.get<{ pid?: number }>('browserState', {});
if (browserState.pid && isProcessRunning(browserState.pid)) {
process.kill(browserState.pid);
await context.globalState.update('browserState', {});
return '✅ Browser closed';
}
return 'No browser instance running';
}
}
];
}
async function ensurePlaywrightMCP(context: vscode.ExtensionContext): Promise<string> {
const extensionPath = context.extensionPath;
const playwrightDir = path.join(extensionPath, '.playwright-mcp');
const mcpServerPath = path.join(playwrightDir, 'node_modules', '@modelcontextprotocol', 'server-playwright', 'dist', 'index.js');
// Check if already installed
if (fs.existsSync(mcpServerPath)) {
return mcpServerPath;
}
// Install Playwright MCP
console.log('Installing Playwright MCP server...');
// Create directory
if (!fs.existsSync(playwrightDir)) {
fs.mkdirSync(playwrightDir, { recursive: true });
}
// Create package.json
const packageJson = {
name: 'playwright-mcp-wrapper',
version: '1.0.0',
private: true,
dependencies: {
'@modelcontextprotocol/server-playwright': 'latest',
'playwright': 'latest'
}
};
fs.writeFileSync(
path.join(playwrightDir, 'package.json'),
JSON.stringify(packageJson, null, 2)
);
// Install dependencies
return new Promise((resolve, reject) => {
const npm = cp.spawn('npm', ['install'], {
cwd: playwrightDir,
stdio: 'pipe'
});
npm.on('close', (code) => {
if (code === 0) {
// Install browsers
const npx = cp.spawn('npx', ['playwright', 'install', 'chromium'], {
cwd: playwrightDir,
stdio: 'pipe'
});
npx.on('close', (code) => {
if (code === 0) {
resolve(mcpServerPath);
} else {
reject(new Error('Failed to install Playwright browsers'));
}
});
} else {
reject(new Error('Failed to install Playwright MCP'));
}
});
});
}
function isProcessRunning(pid: number): boolean {
try {
process.kill(pid, 0);
return true;
} catch {
return false;
}
}
async function startBrowser(context: vscode.ExtensionContext, mcpServerPath: string): Promise<{ pid?: number; error?: string }> {
return new Promise((resolve) => {
const browser = cp.spawn('node', [mcpServerPath], {
stdio: 'pipe',
env: {
...process.env,
PLAYWRIGHT_BROWSERS_PATH: path.join(context.extensionPath, '.playwright-mcp', 'browsers')
}
});
browser.on('error', (error) => {
resolve({ error: error.message });
});
browser.stdout.on('data', (data) => {
console.log('Browser stdout:', data.toString());
});
browser.stderr.on('data', (data) => {
console.error('Browser stderr:', data.toString());
});
// Give browser time to start
setTimeout(() => {
resolve({ pid: browser.pid });
}, 2000);
});
}
async function executeBrowserAction(action: BrowserAction, mcpServerPath: string): Promise<string> {
// For now, we'll execute actions through a simple command interface
// In a full implementation, this would communicate with the MCP server
const command = buildPlaywrightCommand(action);
return new Promise((resolve, reject) => {
cp.exec(command, {
env: {
...process.env,
NODE_PATH: path.dirname(mcpServerPath)
}
}, (error, stdout, stderr) => {
if (error) {
reject(new Error(`Browser action failed: ${error.message}\n${stderr}`));
} else {
resolve(formatActionResult(action, stdout));
}
});
});
}
function buildPlaywrightCommand(action: BrowserAction): string {
const script = `
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: false });
const page = await browser.newPage();
try {
${generateActionCode(action)}
} finally {
// Keep browser open for reuse
// await browser.close();
}
})();
`;
return `node -e "${script.replace(/"/g, '\\"').replace(/\n/g, ' ')}"`;
}
function generateActionCode(action: BrowserAction): string {
switch (action.action) {
case 'navigate':
return `await page.goto('${action.url}', { timeout: ${action.timeout} });
console.log('Navigated to:', '${action.url}');`;
case 'screenshot':
const screenshotPath = action.outputPath || 'screenshot.png';
return `await page.screenshot({ path: '${screenshotPath}' });
console.log('Screenshot saved to:', '${screenshotPath}');`;
case 'click':
return `await page.click('${action.selector}', { timeout: ${action.timeout} });
console.log('Clicked:', '${action.selector}');`;
case 'type':
return `await page.type('${action.selector}', '${action.text}', { timeout: ${action.timeout} });
console.log('Typed text into:', '${action.selector}');`;
case 'extract':
return `const text = await page.textContent('${action.selector}');
console.log('Extracted:', text);`;
case 'wait':
return `await page.waitForSelector('${action.selector}', { timeout: ${action.timeout} });
console.log('Element appeared:', '${action.selector}');`;
case 'evaluate':
return `const result = await page.evaluate(() => { ${action.script} });
console.log('Evaluation result:', JSON.stringify(result));`;
default:
return `console.log('Unknown action: ${action.action}');`;
}
}
function formatActionResult(action: BrowserAction, output: string): string {
const lines = output.trim().split('\n');
const lastLine = lines[lines.length - 1] || '';
switch (action.action) {
case 'navigate':
return `✅ Navigated to: ${action.url}`;
case 'screenshot':
return `📸 Screenshot saved to: ${action.outputPath || 'screenshot.png'}`;
case 'click':
return `🖱️ Clicked element: ${action.selector}`;
case 'type':
return `⌨️ Typed "${action.text}" into: ${action.selector}`;
case 'extract':
return `📝 Extracted text: ${lastLine.replace('Extracted: ', '')}`;
case 'wait':
return `⏳ Element appeared: ${action.selector}`;
case 'evaluate':
return `🔧 Evaluation result: ${lastLine.replace('Evaluation result: ', '')}`;
default:
return output;
}
}
+7 -3
View File
@@ -28,6 +28,7 @@ import { BatchTools } from './batch';
import { AITools } from './ai-tools';
import { createModeTool } from './mode';
import { createMCPRunnerTools } from './mcp-runner';
import { createBrowserTools } from './browser';
// import { createASTAnalyzerTool } from './ast-analyzer';
// import { createTreeSitterAnalyzerTool } from './treesitter-analyzer';
@@ -80,7 +81,8 @@ export class MCPTools {
createWebFetchTool(this.context),
createZenTool(this.context),
createModeTool(this.context),
...createMCPRunnerTools(this.context)
...createMCPRunnerTools(this.context),
...createBrowserTools(this.context)
// createASTAnalyzerTool(this.context),
// createTreeSitterAnalyzerTool(this.context)
];
@@ -142,7 +144,9 @@ export class MCPTools {
// Utility
'batch', 'web_fetch', 'batch_search',
// MCP
'mcp'
'mcp',
// Browser
'browser', 'browser_close'
]);
} else {
this.enabledTools = new Set(enabled);
@@ -221,7 +225,7 @@ export class MCPTools {
filesystem: this.countToolsInCategory(['read', 'write', 'edit', 'multi_edit', 'directory_tree']),
search: this.countToolsInCategory(['grep', 'search', 'symbols', 'find_files']),
shell: this.countToolsInCategory(['run_command', 'bash', 'open']),
ai: this.countToolsInCategory(['dispatch_agent', 'llm', 'consensus']),
ai: this.countToolsInCategory(['agent', 'llm', 'consensus']),
development: this.countToolsInCategory(['todo_read', 'todo_write', 'notebook_read', 'notebook_edit'])
}
};
+304 -13
View File
@@ -12,15 +12,161 @@ interface DevelopmentMode {
}
const DEVELOPMENT_MODES: Record<string, DevelopmentMode> = {
// Language Creators
// Language Creators - Original Languages
'ritchie': {
name: 'ritchie',
programmer: 'Dennis Ritchie',
description: 'C creator - UNIX philosophy',
philosophy: 'UNIX: Do one thing and do it well',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'run_command'],
config: { simplicity: 10, portability: 10, efficiency: 10 }
},
'bjarne': {
name: 'bjarne',
programmer: 'Bjarne Stroustrup',
description: 'C++ creator - zero-overhead abstraction',
philosophy: 'C++: Light-weight abstraction',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'critic'],
config: { abstraction: 9, performance: 10, compatibility: 8 }
},
'gosling': {
name: 'gosling',
programmer: 'James Gosling',
description: 'Java creator - write once, run anywhere',
philosophy: 'Java: Platform independence',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'critic', 'think'],
config: { portability: 10, safety: 9, verbosity: 7 }
},
'guido': {
name: 'guido',
programmer: 'Guido van Rossum',
description: 'Python creator - readability counts',
philosophy: 'There should be one-- and preferably only one --obvious way to do it',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'uvx', 'think'],
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'uvx', 'think', 'notebook_read', 'notebook_edit'],
config: { readability: 10, simplicity: 9, explicitness: 10 }
},
'matz': {
name: 'matz',
programmer: 'Yukihiro Matsumoto',
description: 'Ruby creator - developer happiness',
philosophy: 'Ruby is designed to make programmers happy',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'run_command'],
config: { happiness: 10, expressiveness: 10, principle_of_least_surprise: 9 }
},
'wall': {
name: 'wall',
programmer: 'Larry Wall',
description: 'Perl creator - TMTOWTDI',
philosophy: "There's More Than One Way To Do It",
tools: ['read', 'write', 'edit', 'grep', 'bash', 'run_command', 'content_replace'],
config: { flexibility: 10, expressiveness: 10, readability: 5 }
},
'rasmus': {
name: 'rasmus',
programmer: 'Rasmus Lerdorf',
description: 'PHP creator - pragmatic web development',
philosophy: 'PHP: Solving web problems pragmatically',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'run_command', 'web_fetch'],
config: { pragmatism: 10, web_focus: 10, consistency: 6 }
},
'brendan': {
name: 'brendan',
programmer: 'Brendan Eich',
description: 'JavaScript creator - move fast and evolve',
philosophy: 'Always bet on JavaScript',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'npx', 'web_fetch', 'run_command'],
config: { speed: 10, flexibility: 9, backwards_compatibility: 8 }
},
'anders': {
name: 'anders',
programmer: 'Anders Hejlsberg',
description: 'C#/TypeScript/Delphi - pragmatic language design',
philosophy: 'Pragmatism over dogmatism',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'run_command', 'think'],
config: { pragmatism: 10, tooling: 10, evolution: 9 }
},
'wirth': {
name: 'wirth',
programmer: 'Niklaus Wirth',
description: 'Pascal creator - structured programming',
philosophy: 'Algorithms + Data Structures = Programs',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'think'],
config: { structure: 10, clarity: 10, simplicity: 9 }
},
'mccarthy': {
name: 'mccarthy',
programmer: 'John McCarthy',
description: 'Lisp creator - code as data',
philosophy: 'Lisp: The programmable programming language',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'think', 'critic'],
config: { homoiconicity: 10, flexibility: 10, parentheses: 10 }
},
'hickey': {
name: 'hickey',
programmer: 'Rich Hickey',
description: 'Clojure creator - simplicity matters',
philosophy: 'Simple Made Easy',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'think', 'critic'],
config: { simplicity: 10, immutability: 10, expressiveness: 9 }
},
'armstrong': {
name: 'armstrong',
programmer: 'Joe Armstrong',
description: 'Erlang creator - let it crash',
philosophy: 'Let it crash and recover',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'processes', 'run_background'],
config: { fault_tolerance: 10, concurrency: 10, distribution: 9 }
},
'odersky': {
name: 'odersky',
programmer: 'Martin Odersky',
description: 'Scala creator - scalable language',
philosophy: 'Fusion of functional and object-oriented programming',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'think'],
config: { scalability: 10, expressiveness: 9, type_safety: 10 }
},
'lattner': {
name: 'lattner',
programmer: 'Chris Lattner',
description: 'Swift/LLVM creator - performance with safety',
philosophy: 'Performance and safety without compromise',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'critic'],
config: { safety: 10, performance: 10, expressiveness: 8 }
},
'bak': {
name: 'bak',
programmer: 'Lars Bak',
description: 'Dart/V8 creator - structured web programming',
philosophy: 'Fast development and execution',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'web_fetch'],
config: { performance: 10, structure: 9, tooling: 10 }
},
'backus': {
name: 'backus',
programmer: 'John Backus',
description: 'Fortran creator - scientific computing',
philosophy: 'Formula Translation for scientists',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'run_command'],
config: { performance: 10, scientific_computing: 10, legacy: 10 }
},
'hopper': {
name: 'hopper',
programmer: 'Grace Hopper',
description: 'COBOL creator - business language',
philosophy: 'Programming for everyone',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'think'],
config: { readability: 9, business_focus: 10, verbosity: 8 }
},
'kay': {
name: 'kay',
programmer: 'Alan Kay',
description: 'Smalltalk creator - OOP pioneer',
philosophy: 'The best way to predict the future is to invent it',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'think', 'critic'],
config: { object_orientation: 10, messaging: 10, simplicity: 9 }
},
// Systems & Infrastructure
'linus': {
name: 'linus',
programmer: 'Linus Torvalds',
@@ -29,15 +175,145 @@ const DEVELOPMENT_MODES: Record<string, DevelopmentMode> = {
tools: ['read', 'write', 'edit', 'grep', 'git_search', 'bash', 'processes', 'critic'],
config: { performance: 10, directness: 10, patience: 2 }
},
'brendan': {
name: 'brendan',
programmer: 'Brendan Eich',
description: 'JavaScript creator - move fast and evolve',
philosophy: 'Always bet on JavaScript',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'npx', 'web_fetch'],
config: { speed: 10, flexibility: 9, backwards_compatibility: 8 }
'ritchie_thompson': {
name: 'ritchie_thompson',
programmer: 'Dennis Ritchie & Ken Thompson',
description: 'UNIX creators - minimalist philosophy',
philosophy: 'Keep it simple, stupid',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'processes', 'run_command'],
config: { minimalism: 10, composability: 10, elegance: 10 }
},
// Web Frameworks
'dhh': {
name: 'dhh',
programmer: 'David Heinemeier Hansson',
description: 'Ruby on Rails creator - convention over configuration',
philosophy: 'Optimize for programmer happiness',
tools: ['read', 'write', 'edit', 'multi_edit', 'grep', 'bash', 'run_command', 'sql_query'],
config: { productivity: 10, conventions: 10, opinionated: 10 }
},
'evan': {
name: 'evan',
programmer: 'Evan You',
description: 'Vue.js creator - progressive framework',
philosophy: 'Approachable, versatile, performant',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'web_fetch', 'run_command'],
config: { approachability: 10, flexibility: 9, performance: 8 }
},
'walke': {
name: 'walke',
programmer: 'Jordan Walke',
description: 'React creator - declarative UI',
philosophy: 'UI as a function of state',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'web_fetch', 'symbols'],
config: { declarative: 10, component_based: 10, virtual_dom: 9 }
},
'otwell': {
name: 'otwell',
programmer: 'Taylor Otwell',
description: 'Laravel creator - PHP elegance',
philosophy: 'The PHP framework for web artisans',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'sql_query', 'run_command'],
config: { elegance: 10, expressiveness: 9, developer_experience: 10 }
},
'holovaty_willison': {
name: 'holovaty_willison',
programmer: 'Adrian Holovaty & Simon Willison',
description: 'Django creators - web framework for perfectionists',
philosophy: 'The web framework for perfectionists with deadlines',
tools: ['read', 'write', 'edit', 'grep', 'uvx', 'sql_query', 'run_command'],
config: { batteries_included: 10, security: 10, rapid_development: 9 }
},
'ronacher': {
name: 'ronacher',
programmer: 'Armin Ronacher',
description: 'Flask/Jinja creator - micro framework',
philosophy: 'Web development, one drop at a time',
tools: ['read', 'write', 'edit', 'grep', 'uvx', 'run_command'],
config: { minimalism: 10, flexibility: 10, extensibility: 9 }
},
'holowaychuk': {
name: 'holowaychuk',
programmer: 'TJ Holowaychuk',
description: 'Express.js creator - minimalist web framework',
philosophy: 'Fast, unopinionated, minimalist',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'run_command'],
config: { minimalism: 10, middleware: 10, flexibility: 9 }
},
// JavaScript Ecosystem
'katz': {
name: 'katz',
programmer: 'Yehuda Katz',
description: 'Ember.js creator - ambitious web apps',
philosophy: 'Convention over Configuration',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'run_command', 'symbols'],
config: { conventions: 10, productivity: 9, stability: 10 }
},
'ashkenas': {
name: 'ashkenas',
programmer: 'Jeremy Ashkenas',
description: 'CoffeeScript/Backbone creator - JavaScript, the good parts',
philosophy: 'It\'s just JavaScript',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'run_command'],
config: { elegance: 10, simplicity: 9, readability: 8 }
},
'nolen': {
name: 'nolen',
programmer: 'David Nolen',
description: 'ClojureScript lead - functional web development',
philosophy: 'Functional programming for the web',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'symbols', 'think'],
config: { functional: 10, immutability: 10, performance: 9 }
},
// Modern Languages
'graydon': {
name: 'graydon',
programmer: 'Graydon Hoare',
description: 'Rust creator - memory safety without GC',
philosophy: 'Fast, reliable, productive — pick three',
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'bash', 'critic', 'run_command'],
config: { safety: 10, performance: 10, concurrency: 9 }
},
'pike_thompson': {
name: 'pike_thompson',
programmer: 'Rob Pike & Ken Thompson',
description: 'Go creators - simplicity at scale',
philosophy: 'Less is exponentially more',
tools: ['read', 'write', 'edit', 'grep', 'bash', 'run_command', 'processes'],
config: { simplicity: 10, concurrency: 10, pragmatism: 9 }
},
// Database & Infrastructure
'widenius': {
name: 'widenius',
programmer: 'Michael Widenius',
description: 'MySQL/MariaDB creator - open source database',
philosophy: 'Open source database for everyone',
tools: ['read', 'write', 'edit', 'sql_query', 'bash', 'run_command'],
config: { openness: 10, performance: 9, compatibility: 8 }
},
// CSS & Design
'wathan': {
name: 'wathan',
programmer: 'Adam Wathan',
description: 'Tailwind CSS creator - utility-first CSS',
philosophy: 'Stop writing CSS, start building designs',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'web_fetch'],
config: { utility_first: 10, customization: 9, productivity: 10 }
},
'otto_thornton': {
name: 'otto_thornton',
programmer: 'Mark Otto & Jacob Thornton',
description: 'Bootstrap creators - responsive web design',
philosophy: 'Build responsive, mobile-first projects',
tools: ['read', 'write', 'edit', 'grep', 'npx', 'web_fetch'],
config: { responsiveness: 10, components: 9, consistency: 10 }
},
// Special Configurations
'fullstack': {
name: 'fullstack',
@@ -132,9 +408,24 @@ export function createModeTool(context: vscode.ExtensionContext): MCPTool {
// Group modes by category
const categories = {
'Language Creators': ['guido', 'linus', 'brendan'],
'Special Configurations': ['fullstack', 'minimal', '10x', 'security',
'data_scientist', 'hanzo']
'Language Creators': [
'ritchie', 'bjarne', 'gosling', 'guido', 'matz', 'wall',
'rasmus', 'brendan', 'anders', 'wirth', 'mccarthy', 'hickey',
'armstrong', 'odersky', 'lattner', 'bak', 'backus', 'hopper', 'kay'
],
'Systems & Infrastructure': ['linus', 'ritchie_thompson'],
'Web Frameworks': [
'dhh', 'evan', 'walke', 'otwell', 'holovaty_willison',
'ronacher', 'holowaychuk'
],
'JavaScript Ecosystem': ['katz', 'ashkenas', 'nolen'],
'Modern Languages': ['graydon', 'pike_thompson'],
'Database & Infrastructure': ['widenius'],
'CSS & Design': ['wathan', 'otto_thornton'],
'Special Configurations': [
'fullstack', 'minimal', '10x', 'security',
'data_scientist', 'hanzo'
]
};
for (const [category, modeNames] of Object.entries(categories)) {