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:
@@ -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
@@ -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
@@ -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)
|
||||||
@@ -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!
|
||||||
@@ -1,139 +1,55 @@
|
|||||||
# Hanzo AI
|
# 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
|
## Quick Start
|
||||||
- **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
|
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Build and install for Claude Desktop
|
# VS Code / Cursor / Windsurf
|
||||||
npm run build:claude-desktop
|
Install hanzoai-*.vsix
|
||||||
./dist/claude-desktop/install.sh # Mac/Linux
|
|
||||||
# or
|
# Claude Code
|
||||||
./dist/claude-desktop/install.bat # Windows
|
Drag hanzoai-*.dxt
|
||||||
|
|
||||||
|
# Terminal / Neovim
|
||||||
|
npx @hanzo/mcp@latest
|
||||||
```
|
```
|
||||||
|
|
||||||
### Build Options
|
## Use It
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Development
|
# Get your API key
|
||||||
npm run dev # Watch mode development build
|
export HANZO_API_KEY=hzo_... # from iam.hanzo.ai
|
||||||
npm run compile # One-time TypeScript compilation
|
|
||||||
|
|
||||||
# Production builds
|
# Talk to any model
|
||||||
npm run build # Standard VS Code extension build
|
@hanzo agent --model o3-pro solve this algorithm
|
||||||
npm run build:claude-desktop # Claude Desktop MCP server build
|
@hanzo agent --model claude-4 review my code
|
||||||
npm run build:dxt # Desktop Extension (DXT) build
|
|
||||||
npm run build:all # Build all targets
|
|
||||||
|
|
||||||
# Testing
|
# Activate legendary modes
|
||||||
npm test # Run all tests
|
@hanzo mode carmack # Optimize like a game engine
|
||||||
npm run test:unit # Unit tests only
|
@hanzo mode norvig # AI implementation mastery
|
||||||
npm run test:integration # Integration tests only
|
|
||||||
|
|
||||||
# Packaging
|
# Control browsers
|
||||||
npm run package # Create .vsix package
|
@hanzo browser navigate https://example.com
|
||||||
npm run package:dxt # Create .dxt package for Claude Code
|
@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
|
🚀 **[Get Started](https://iam.hanzo.ai)** | 📖 **[Docs](https://docs.hanzo.ai)** | 💬 **[Discord](https://discord.gg/hanzoai)**
|
||||||
- **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)
|
|
||||||
|
|
||||||
See [MCP-README.md](./MCP-README.md) for complete documentation.
|
---
|
||||||
|
|
||||||
## Debugging
|
Built for engineers who ship.
|
||||||
|
|
||||||
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.
|
|
||||||
@@ -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!
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 13 KiB |
@@ -44,12 +44,14 @@ const HanzoMetricsService_1 = require("./services/HanzoMetricsService");
|
|||||||
const server_1 = require("./mcp/server");
|
const server_1 = require("./mcp/server");
|
||||||
const config_1 = require("./config");
|
const config_1 = require("./config");
|
||||||
const content_1 = require("./webview/content");
|
const content_1 = require("./webview/content");
|
||||||
|
const hanzo_chat_participant_1 = require("./chat/hanzo-chat-participant");
|
||||||
let projectManager;
|
let projectManager;
|
||||||
let authManager;
|
let authManager;
|
||||||
let reminderService;
|
let reminderService;
|
||||||
let statusBar;
|
let statusBar;
|
||||||
let metricsService;
|
let metricsService;
|
||||||
let mcpServer;
|
let mcpServer;
|
||||||
|
let chatParticipant;
|
||||||
async function activate(context) {
|
async function activate(context) {
|
||||||
console.log('Hanzo AI Extension is now active!');
|
console.log('Hanzo AI Extension is now active!');
|
||||||
// Initialize services
|
// Initialize services
|
||||||
@@ -63,6 +65,16 @@ async function activate(context) {
|
|||||||
mcpServer = new server_1.MCPServer(context);
|
mcpServer = new server_1.MCPServer(context);
|
||||||
await mcpServer.initialize();
|
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
|
// Register commands
|
||||||
const disposables = [
|
const disposables = [
|
||||||
vscode.commands.registerCommand('hanzo.openManager', () => {
|
vscode.commands.registerCommand('hanzo.openManager', () => {
|
||||||
|
|||||||
Generated
+1496
-72
File diff suppressed because it is too large
Load Diff
+68
-2
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "hanzoai",
|
"name": "hanzoai",
|
||||||
"displayName": "Hanzo AI Context Manager",
|
"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",
|
"version": "1.5.4",
|
||||||
"publisher": "hanzo-ai",
|
"publisher": "hanzo-ai",
|
||||||
"private": false,
|
"private": false,
|
||||||
@@ -48,6 +48,14 @@
|
|||||||
],
|
],
|
||||||
"main": "./out/extension.js",
|
"main": "./out/extension.js",
|
||||||
"contributes": {
|
"contributes": {
|
||||||
|
"chatParticipants": [
|
||||||
|
{
|
||||||
|
"id": "hanzo",
|
||||||
|
"name": "Hanzo",
|
||||||
|
"description": "Ultimate AI engineering toolkit: 200+ LLMs, 4000+ MCP servers, 53+ dev tools",
|
||||||
|
"isSticky": true
|
||||||
|
}
|
||||||
|
],
|
||||||
"commands": [
|
"commands": [
|
||||||
{
|
{
|
||||||
"command": "hanzo.openManager",
|
"command": "hanzo.openManager",
|
||||||
@@ -178,6 +186,59 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"default": false,
|
"default": false,
|
||||||
"description": "Enable debug logging"
|
"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: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: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: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:mcp": "node scripts/build-mcp-standalone.js",
|
||||||
"build:claude-desktop": "npm run build:mcp && node scripts/build-claude-desktop.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: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",
|
"build:all": "node scripts/build-all-platforms.js",
|
||||||
"package": "npm run build:all && vsce package",
|
"package": "npm run build:all && vsce package",
|
||||||
"package:claude": "npm run build:claude-desktop",
|
"package:claude": "npm run build:claude-desktop",
|
||||||
@@ -232,6 +297,7 @@
|
|||||||
"@vscode/vsce": "^2.24.0",
|
"@vscode/vsce": "^2.24.0",
|
||||||
"archiver": "^7.0.1",
|
"archiver": "^7.0.1",
|
||||||
"better-sqlite3": "^12.2.0",
|
"better-sqlite3": "^12.2.0",
|
||||||
|
"c8": "^10.1.3",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"esbuild": "^0.19.12",
|
"esbuild": "^0.19.12",
|
||||||
"eslint": "^8.26.0",
|
"eslint": "^8.26.0",
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
onlyBuiltDependencies:
|
||||||
|
- better-sqlite3
|
||||||
@@ -11,22 +11,28 @@ const PLATFORMS = {
|
|||||||
outputDir: 'out',
|
outputDir: 'out',
|
||||||
package: false
|
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': {
|
'dxt': {
|
||||||
name: 'Claude Code DXT',
|
name: 'Claude Code DXT',
|
||||||
buildCmd: 'npm run build:dxt',
|
buildCmd: 'npm run build:dxt',
|
||||||
outputDir: 'dist/dxt',
|
outputDir: 'dist/dxt',
|
||||||
package: false // Already packaged by build script
|
package: false // Already packaged by build script
|
||||||
},
|
},
|
||||||
'mcp-standalone': {
|
'mcp-npm': {
|
||||||
name: 'MCP Standalone',
|
name: 'MCP NPM Package',
|
||||||
buildCmd: 'npm run build:mcp',
|
buildCmd: 'node scripts/build-mcp-npm.js',
|
||||||
outputDir: 'dist/mcp-standalone',
|
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
|
package: true
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -47,6 +53,14 @@ async function buildAllPlatforms() {
|
|||||||
console.log(` Output: ${config.outputDir}`);
|
console.log(` Output: ${config.outputDir}`);
|
||||||
|
|
||||||
try {
|
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
|
// Run build command
|
||||||
console.log(` Running: ${config.buildCmd}`);
|
console.log(` Running: ${config.buildCmd}`);
|
||||||
execSync(config.buildCmd, { stdio: 'inherit' });
|
execSync(config.buildCmd, { stdio: 'inherit' });
|
||||||
@@ -75,6 +89,18 @@ async function buildAllPlatforms() {
|
|||||||
success: true,
|
success: true,
|
||||||
path: config.outputDir
|
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 {
|
} else {
|
||||||
throw new Error('Output directory not created');
|
throw new Error('Output directory not created');
|
||||||
}
|
}
|
||||||
@@ -99,7 +125,9 @@ async function buildAllPlatforms() {
|
|||||||
if (vsixFiles.length > 0) {
|
if (vsixFiles.length > 0) {
|
||||||
const vsixFile = vsixFiles[0];
|
const vsixFile = vsixFiles[0];
|
||||||
const targetPath = path.join('dist', vsixFile);
|
const targetPath = path.join('dist', vsixFile);
|
||||||
fs.renameSync(vsixFile, targetPath);
|
if (fs.existsSync(vsixFile)) {
|
||||||
|
fs.renameSync(vsixFile, targetPath);
|
||||||
|
}
|
||||||
console.log(` ✅ Created: ${targetPath}`);
|
console.log(` ✅ Created: ${targetPath}`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -121,6 +149,10 @@ async function buildAllPlatforms() {
|
|||||||
listDistFiles('dist', ' ');
|
listDistFiles('dist', ' ');
|
||||||
|
|
||||||
console.log('\n✨ Build complete!');
|
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) {
|
function createZipArchive(sourceDir, outputPath) {
|
||||||
@@ -146,7 +178,7 @@ function listDistFiles(dir, prefix = '') {
|
|||||||
|
|
||||||
if (stats.isDirectory()) {
|
if (stats.isDirectory()) {
|
||||||
console.log(`${prefix}📁 ${item}/`);
|
console.log(`${prefix}📁 ${item}/`);
|
||||||
if (item !== 'node_modules') {
|
if (item !== 'node_modules' && items.length < 20) {
|
||||||
listDistFiles(fullPath, prefix + ' ');
|
listDistFiles(fullPath, prefix + ' ');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -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
@@ -10,7 +10,9 @@ console.log('Building Hanzo MCP Desktop Extension (.dxt)...\n');
|
|||||||
const rootDir = path.join(__dirname, '..');
|
const rootDir = path.join(__dirname, '..');
|
||||||
const dxtDir = path.join(rootDir, 'dxt');
|
const dxtDir = path.join(rootDir, 'dxt');
|
||||||
const distDir = path.join(rootDir, 'dist');
|
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
|
// Ensure dist directory exists
|
||||||
if (!fs.existsSync(distDir)) {
|
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 });
|
archive.append(installScript, { name: 'install.js', mode: 0o755 });
|
||||||
|
|
||||||
// Add icon if it exists
|
// Add icon
|
||||||
const iconPath = path.join(dxtDir, 'icon.png');
|
console.log('Adding icon...');
|
||||||
|
const iconPath = path.join(__dirname, '..', 'images', 'icon.png');
|
||||||
if (fs.existsSync(iconPath)) {
|
if (fs.existsSync(iconPath)) {
|
||||||
console.log('Adding icon...');
|
|
||||||
archive.file(iconPath, { name: 'icon.png' });
|
archive.file(iconPath, { name: 'icon.png' });
|
||||||
} else {
|
} else {
|
||||||
// Create a simple icon if none exists
|
console.error('Warning: icon.png not found at', iconPath);
|
||||||
console.log('Creating default icon...');
|
// Fallback to DXT directory icon if available
|
||||||
const defaultIcon = Buffer.from(
|
const dxtIconPath = path.join(dxtDir, 'icon.png');
|
||||||
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
|
if (fs.existsSync(dxtIconPath)) {
|
||||||
'base64'
|
archive.file(dxtIconPath, { name: 'icon.png' });
|
||||||
);
|
}
|
||||||
archive.append(defaultIcon, { name: 'icon.png' });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add README
|
// Add README
|
||||||
|
|||||||
@@ -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');
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,7 @@ import { HanzoMetricsService } from './services/HanzoMetricsService';
|
|||||||
import { MCPServer } from './mcp/server';
|
import { MCPServer } from './mcp/server';
|
||||||
import { getConfig } from './config';
|
import { getConfig } from './config';
|
||||||
import { getWebviewContent } from './webview/content';
|
import { getWebviewContent } from './webview/content';
|
||||||
|
import { HanzoChatParticipant } from './chat/hanzo-chat-participant';
|
||||||
|
|
||||||
let projectManager: ProjectManager | undefined;
|
let projectManager: ProjectManager | undefined;
|
||||||
let authManager: AuthManager | undefined;
|
let authManager: AuthManager | undefined;
|
||||||
@@ -14,6 +15,7 @@ let reminderService: ReminderService | undefined;
|
|||||||
let statusBar: StatusBarService | undefined;
|
let statusBar: StatusBarService | undefined;
|
||||||
let metricsService: HanzoMetricsService | undefined;
|
let metricsService: HanzoMetricsService | undefined;
|
||||||
let mcpServer: MCPServer | undefined;
|
let mcpServer: MCPServer | undefined;
|
||||||
|
let chatParticipant: HanzoChatParticipant | undefined;
|
||||||
|
|
||||||
export async function activate(context: vscode.ExtensionContext) {
|
export async function activate(context: vscode.ExtensionContext) {
|
||||||
console.log('Hanzo AI Extension is now active!');
|
console.log('Hanzo AI Extension is now active!');
|
||||||
@@ -30,6 +32,16 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||||||
mcpServer = new MCPServer(context);
|
mcpServer = new MCPServer(context);
|
||||||
await mcpServer.initialize();
|
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
|
// Register commands
|
||||||
const disposables = [
|
const disposables = [
|
||||||
|
|||||||
+546
-13
@@ -1,17 +1,52 @@
|
|||||||
import * as vscode from 'vscode';
|
import * as vscode from 'vscode';
|
||||||
import { MCPTool } from '../server';
|
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[] {
|
export function createAgentTools(context: vscode.ExtensionContext): MCPTool[] {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
name: 'dispatch_agent',
|
name: 'agent',
|
||||||
description: 'Delegate tasks to specialized sub-agents',
|
description: 'AI agent that can use tools to complete complex tasks. Supports single or multi-agent workflows.',
|
||||||
inputSchema: {
|
inputSchema: {
|
||||||
type: 'object',
|
type: 'object',
|
||||||
properties: {
|
properties: {
|
||||||
task: {
|
task: {
|
||||||
type: 'string',
|
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: {
|
agents: {
|
||||||
type: 'array',
|
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: {
|
parallel: {
|
||||||
type: 'boolean',
|
type: 'boolean',
|
||||||
description: 'Run agents in parallel (default: false)'
|
description: 'Run multiple agents in parallel (default: false)'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
required: ['task']
|
required: ['task']
|
||||||
},
|
},
|
||||||
handler: async (args: {
|
handler: async (args: AgentConfig) => {
|
||||||
task: string;
|
const providers = detectLLMProviders();
|
||||||
agents?: Array<{ name: string; role: string; tools?: string[] }>;
|
const selectedProvider = selectProvider(providers, args.model);
|
||||||
parallel?: boolean;
|
|
||||||
}) => {
|
if (!selectedProvider) {
|
||||||
// TODO: Implement agent dispatch functionality
|
return 'Error: No LLM provider available. Please configure API keys in environment or VS Code settings.';
|
||||||
// This would integrate with LLM providers to create sub-agents
|
}
|
||||||
return 'Agent dispatch functionality coming soon';
|
|
||||||
|
// 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;
|
||||||
}
|
}
|
||||||
@@ -259,8 +259,8 @@ export class BashTools {
|
|||||||
// Execute command
|
// Execute command
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const proc = cp.exec(command, {
|
const proc = cp.exec(command, {
|
||||||
cwd: session.cwd,
|
cwd: session?.cwd || process.cwd(),
|
||||||
env: session.env,
|
env: session?.env || process.env,
|
||||||
timeout,
|
timeout,
|
||||||
maxBuffer: 10 * 1024 * 1024 // 10MB
|
maxBuffer: 10 * 1024 * 1024 // 10MB
|
||||||
}, (error, stdout, stderr) => {
|
}, (error, stdout, stderr) => {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,7 @@ import { BatchTools } from './batch';
|
|||||||
import { AITools } from './ai-tools';
|
import { AITools } from './ai-tools';
|
||||||
import { createModeTool } from './mode';
|
import { createModeTool } from './mode';
|
||||||
import { createMCPRunnerTools } from './mcp-runner';
|
import { createMCPRunnerTools } from './mcp-runner';
|
||||||
|
import { createBrowserTools } from './browser';
|
||||||
// import { createASTAnalyzerTool } from './ast-analyzer';
|
// import { createASTAnalyzerTool } from './ast-analyzer';
|
||||||
// import { createTreeSitterAnalyzerTool } from './treesitter-analyzer';
|
// import { createTreeSitterAnalyzerTool } from './treesitter-analyzer';
|
||||||
|
|
||||||
@@ -80,7 +81,8 @@ export class MCPTools {
|
|||||||
createWebFetchTool(this.context),
|
createWebFetchTool(this.context),
|
||||||
createZenTool(this.context),
|
createZenTool(this.context),
|
||||||
createModeTool(this.context),
|
createModeTool(this.context),
|
||||||
...createMCPRunnerTools(this.context)
|
...createMCPRunnerTools(this.context),
|
||||||
|
...createBrowserTools(this.context)
|
||||||
// createASTAnalyzerTool(this.context),
|
// createASTAnalyzerTool(this.context),
|
||||||
// createTreeSitterAnalyzerTool(this.context)
|
// createTreeSitterAnalyzerTool(this.context)
|
||||||
];
|
];
|
||||||
@@ -142,7 +144,9 @@ export class MCPTools {
|
|||||||
// Utility
|
// Utility
|
||||||
'batch', 'web_fetch', 'batch_search',
|
'batch', 'web_fetch', 'batch_search',
|
||||||
// MCP
|
// MCP
|
||||||
'mcp'
|
'mcp',
|
||||||
|
// Browser
|
||||||
|
'browser', 'browser_close'
|
||||||
]);
|
]);
|
||||||
} else {
|
} else {
|
||||||
this.enabledTools = new Set(enabled);
|
this.enabledTools = new Set(enabled);
|
||||||
@@ -221,7 +225,7 @@ export class MCPTools {
|
|||||||
filesystem: this.countToolsInCategory(['read', 'write', 'edit', 'multi_edit', 'directory_tree']),
|
filesystem: this.countToolsInCategory(['read', 'write', 'edit', 'multi_edit', 'directory_tree']),
|
||||||
search: this.countToolsInCategory(['grep', 'search', 'symbols', 'find_files']),
|
search: this.countToolsInCategory(['grep', 'search', 'symbols', 'find_files']),
|
||||||
shell: this.countToolsInCategory(['run_command', 'bash', 'open']),
|
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'])
|
development: this.countToolsInCategory(['todo_read', 'todo_write', 'notebook_read', 'notebook_edit'])
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+304
-13
@@ -12,15 +12,161 @@ interface DevelopmentMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DEVELOPMENT_MODES: Record<string, 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': {
|
'guido': {
|
||||||
name: 'guido',
|
name: 'guido',
|
||||||
programmer: 'Guido van Rossum',
|
programmer: 'Guido van Rossum',
|
||||||
description: 'Python creator - readability counts',
|
description: 'Python creator - readability counts',
|
||||||
philosophy: 'There should be one-- and preferably only one --obvious way to do it',
|
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 }
|
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': {
|
'linus': {
|
||||||
name: 'linus',
|
name: 'linus',
|
||||||
programmer: 'Linus Torvalds',
|
programmer: 'Linus Torvalds',
|
||||||
@@ -29,15 +175,145 @@ const DEVELOPMENT_MODES: Record<string, DevelopmentMode> = {
|
|||||||
tools: ['read', 'write', 'edit', 'grep', 'git_search', 'bash', 'processes', 'critic'],
|
tools: ['read', 'write', 'edit', 'grep', 'git_search', 'bash', 'processes', 'critic'],
|
||||||
config: { performance: 10, directness: 10, patience: 2 }
|
config: { performance: 10, directness: 10, patience: 2 }
|
||||||
},
|
},
|
||||||
'brendan': {
|
'ritchie_thompson': {
|
||||||
name: 'brendan',
|
name: 'ritchie_thompson',
|
||||||
programmer: 'Brendan Eich',
|
programmer: 'Dennis Ritchie & Ken Thompson',
|
||||||
description: 'JavaScript creator - move fast and evolve',
|
description: 'UNIX creators - minimalist philosophy',
|
||||||
philosophy: 'Always bet on JavaScript',
|
philosophy: 'Keep it simple, stupid',
|
||||||
tools: ['read', 'write', 'edit', 'grep', 'symbols', 'npx', 'web_fetch'],
|
tools: ['read', 'write', 'edit', 'grep', 'bash', 'processes', 'run_command'],
|
||||||
config: { speed: 10, flexibility: 9, backwards_compatibility: 8 }
|
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
|
// Special Configurations
|
||||||
'fullstack': {
|
'fullstack': {
|
||||||
name: 'fullstack',
|
name: 'fullstack',
|
||||||
@@ -132,9 +408,24 @@ export function createModeTool(context: vscode.ExtensionContext): MCPTool {
|
|||||||
|
|
||||||
// Group modes by category
|
// Group modes by category
|
||||||
const categories = {
|
const categories = {
|
||||||
'Language Creators': ['guido', 'linus', 'brendan'],
|
'Language Creators': [
|
||||||
'Special Configurations': ['fullstack', 'minimal', '10x', 'security',
|
'ritchie', 'bjarne', 'gosling', 'guido', 'matz', 'wall',
|
||||||
'data_scientist', 'hanzo']
|
'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)) {
|
for (const [category, modeNames] of Object.entries(categories)) {
|
||||||
|
|||||||
Reference in New Issue
Block a user