feat: Transform Hanzo AI into ultimate AI engineering toolkit

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

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

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

Documentation:
- Short punchy README focused on benefits
- Comprehensive HANZO_MODES.md for legendary modes
- Updated HANZO_AI.md with complete feature set
- Links to docs.hanzo.ai for full documentation
This commit is contained in:
Hanzo Dev
2025-07-04 22:04:15 -04:00
parent 0b6f26d0bf
commit 40d8709d6e
23 changed files with 4768 additions and 248 deletions
+44 -12
View File
@@ -11,22 +11,28 @@ const PLATFORMS = {
outputDir: 'out',
package: false
},
'claude-desktop': {
name: 'Claude Desktop MCP',
buildCmd: 'npm run build:claude-desktop',
outputDir: 'dist/claude-desktop',
package: false // Already packaged by build script
},
'dxt': {
name: 'Claude Code DXT',
buildCmd: 'npm run build:dxt',
outputDir: 'dist/dxt',
package: false // Already packaged by build script
},
'mcp-standalone': {
name: 'MCP Standalone',
buildCmd: 'npm run build:mcp',
outputDir: 'dist/mcp-standalone',
'mcp-npm': {
name: 'MCP NPM Package',
buildCmd: 'node scripts/build-mcp-npm.js',
outputDir: 'dist/npm',
package: false
},
'cursor': {
name: 'Cursor IDE Extension',
buildCmd: 'npm run build:cursor',
outputDir: 'dist/cursor',
package: true
},
'windsurf': {
name: 'Windsurf Extension',
buildCmd: 'npm run build:windsurf',
outputDir: 'dist/windsurf',
package: true
}
};
@@ -47,6 +53,14 @@ async function buildAllPlatforms() {
console.log(` Output: ${config.outputDir}`);
try {
// Skip if build command doesn't exist yet
if (platform === 'cursor' || platform === 'windsurf') {
if (!fs.existsSync(`scripts/build-${platform}.js`)) {
console.log(` ⏭️ Skipped (build script not implemented yet)`);
continue;
}
}
// Run build command
console.log(` Running: ${config.buildCmd}`);
execSync(config.buildCmd, { stdio: 'inherit' });
@@ -75,6 +89,18 @@ async function buildAllPlatforms() {
success: true,
path: config.outputDir
});
} else if (platform === 'dxt') {
// DXT outputs to dist/ directly
const dxtFile = 'dist/hanzo-ai.dxt';
if (fs.existsSync(dxtFile)) {
const stats = fs.statSync(dxtFile);
console.log(` ✅ Success! Created ${dxtFile} (${(stats.size / 1024 / 1024).toFixed(2)} MB)`);
results.push({
platform,
success: true,
path: dxtFile
});
}
} else {
throw new Error('Output directory not created');
}
@@ -99,7 +125,9 @@ async function buildAllPlatforms() {
if (vsixFiles.length > 0) {
const vsixFile = vsixFiles[0];
const targetPath = path.join('dist', vsixFile);
fs.renameSync(vsixFile, targetPath);
if (fs.existsSync(vsixFile)) {
fs.renameSync(vsixFile, targetPath);
}
console.log(` ✅ Created: ${targetPath}`);
}
} catch (error) {
@@ -121,6 +149,10 @@ async function buildAllPlatforms() {
listDistFiles('dist', ' ');
console.log('\n✨ Build complete!');
console.log('\n📦 Installation methods:');
console.log(' Claude Code: Drag dist/hanzoai-*.dxt into Claude Code');
console.log(' Claude Desktop/Code: npx @hanzo/mcp@latest');
console.log(' VS Code: Install dist/hanzoai-*.vsix');
}
function createZipArchive(sourceDir, outputPath) {
@@ -146,7 +178,7 @@ function listDistFiles(dir, prefix = '') {
if (stats.isDirectory()) {
console.log(`${prefix}📁 ${item}/`);
if (item !== 'node_modules') {
if (item !== 'node_modules' && items.length < 20) {
listDistFiles(fullPath, prefix + ' ');
}
} else {
+53
View File
@@ -0,0 +1,53 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('🚀 Building Hanzo MCP for Cursor IDE...\n');
// Cursor uses the same VSIX format as VS Code
// We'll build a standard VSIX that Cursor can install
const distDir = path.join(__dirname, '..', 'dist', 'cursor');
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
fs.mkdirSync(distDir, { recursive: true });
}
try {
// First compile the TypeScript
console.log('📦 Compiling TypeScript...');
execSync('node scripts/compile-main.js', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Build MCP components
console.log('🔧 Building MCP components...');
execSync('npm run build:mcp', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Package the extension
console.log('📦 Packaging Cursor extension...');
execSync('vsce package --no-dependencies --out dist/cursor/', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Read package.json to get version
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
const version = packageJson.version;
// Rename the output file to include cursor in the name
const vsixFiles = fs.readdirSync(distDir).filter(f => f.endsWith('.vsix'));
if (vsixFiles.length > 0) {
const oldPath = path.join(distDir, vsixFiles[0]);
const newPath = path.join(distDir, `hanzoai-cursor-${version}.vsix`);
fs.renameSync(oldPath, newPath);
console.log(`\n✅ Successfully built Cursor extension: ${newPath}`);
console.log(`📦 File size: ${(fs.statSync(newPath).size / 1024 / 1024).toFixed(2)} MB`);
console.log('\n📥 To install in Cursor:');
console.log(' 1. Open Cursor');
console.log(' 2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)');
console.log(' 3. Run "Extensions: Install from VSIX..."');
console.log(` 4. Select ${newPath}`);
}
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}
+12 -11
View File
@@ -10,7 +10,9 @@ console.log('Building Hanzo MCP Desktop Extension (.dxt)...\n');
const rootDir = path.join(__dirname, '..');
const dxtDir = path.join(rootDir, 'dxt');
const distDir = path.join(rootDir, 'dist');
const outputFile = path.join(distDir, 'hanzo-ai.dxt');
const packageJson = JSON.parse(fs.readFileSync(path.join(rootDir, 'package.json'), 'utf8'));
const version = packageJson.version;
const outputFile = path.join(distDir, `hanzoai-${version}.dxt`);
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
@@ -120,19 +122,18 @@ console.log('\\nFor more information: https://github.com/hanzoai/extension');
archive.append(installScript, { name: 'install.js', mode: 0o755 });
// Add icon if it exists
const iconPath = path.join(dxtDir, 'icon.png');
// Add icon
console.log('Adding icon...');
const iconPath = path.join(__dirname, '..', 'images', 'icon.png');
if (fs.existsSync(iconPath)) {
console.log('Adding icon...');
archive.file(iconPath, { name: 'icon.png' });
} else {
// Create a simple icon if none exists
console.log('Creating default icon...');
const defaultIcon = Buffer.from(
'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg==',
'base64'
);
archive.append(defaultIcon, { name: 'icon.png' });
console.error('Warning: icon.png not found at', iconPath);
// Fallback to DXT directory icon if available
const dxtIconPath = path.join(dxtDir, 'icon.png');
if (fs.existsSync(dxtIconPath)) {
archive.file(dxtIconPath, { name: 'icon.png' });
}
}
// Add README
+248
View File
@@ -0,0 +1,248 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('Building @hanzo/mcp npm package...\n');
// Ensure dist directory exists
if (!fs.existsSync('dist')) {
fs.mkdirSync('dist');
}
const npmDir = path.join('dist', 'npm');
if (!fs.existsSync(npmDir)) {
fs.mkdirSync(npmDir, { recursive: true });
}
// First build the MCP server
console.log('Building MCP server...');
execSync('npm run build:mcp', { stdio: 'inherit' });
// Copy server file
console.log('Copying server files...');
fs.copyFileSync('dist/mcp-server.js', path.join(npmDir, 'server.js'));
// Create package.json for npm
const packageJson = {
name: '@hanzo/mcp',
version: require('../package.json').version,
description: 'Hanzo AI MCP server - powerful development tools for Claude Desktop and Claude Code',
main: 'server.js',
bin: {
'hanzo-mcp': './cli.js'
},
scripts: {
start: 'node server.js'
},
keywords: [
'mcp',
'model-context-protocol',
'claude',
'claude-desktop',
'claude-code',
'ai',
'development-tools',
'hanzo'
],
author: 'Hanzo Industries Inc',
license: 'MIT',
repository: {
type: 'git',
url: 'git+https://github.com/hanzoai/extension.git'
},
homepage: 'https://github.com/hanzoai/extension#readme',
bugs: {
url: 'https://github.com/hanzoai/extension/issues'
},
engines: {
node: '>=16.0.0'
},
files: [
'server.js',
'cli.js',
'README.md'
],
publishConfig: {
access: 'public',
registry: 'https://registry.npmjs.org/'
}
};
// Create CLI wrapper
const cliScript = `#!/usr/bin/env node
const { spawn } = require('child_process');
const path = require('path');
const os = require('os');
const fs = require('fs');
const args = process.argv.slice(2);
const command = args[0];
if (command === 'install' || (!command && !args.includes('--help')) || args.includes('--claude-code')) {
console.log('\\n📦 Installing Hanzo MCP...\\n');
// Detect Claude Desktop config location
let configPath;
if (process.platform === 'darwin') {
configPath = path.join(os.homedir(), 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json');
} else if (process.platform === 'win32') {
configPath = path.join(process.env.APPDATA || '', 'Claude', 'claude_desktop_config.json');
} else {
configPath = path.join(os.homedir(), '.config', 'Claude', 'claude_desktop_config.json');
}
// Check if running in Claude Code (no config needed)
if (process.env.CLAUDE_CODE || args.includes('--claude-code')) {
console.log('✅ Hanzo MCP is ready for Claude Code!');
console.log('\\nTo use in Claude Code:');
console.log('1. The MCP server is available at:', path.join(__dirname, 'server.js'));
console.log('2. Tools will be automatically available in your conversations');
return;
}
// For Claude Desktop, update config
console.log('Configuring for Claude Desktop...');
console.log('Config location:', configPath);
try {
// Ensure directory exists
const configDir = path.dirname(configPath);
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}
// Read existing config or create new
let config = {};
if (fs.existsSync(configPath)) {
config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
}
// Ensure mcpServers exists
if (!config.mcpServers) {
config.mcpServers = {};
}
// Add Hanzo MCP
config.mcpServers['hanzo-mcp'] = {
command: 'node',
args: [path.join(__dirname, 'server.js')],
env: {}
};
// Write config
fs.writeFileSync(configPath, JSON.stringify(config, null, 2));
console.log('\\n✅ Hanzo MCP installed successfully!');
console.log('\\n🔄 Please restart Claude Desktop to use the new tools.');
console.log('\\n📚 Available tools:');
console.log(' - File operations (read, write, edit)');
console.log(' - Search (grep, git_search, symbols)');
console.log(' - Shell commands (bash, processes)');
console.log(' - AI tools (llm, consensus, mode)');
console.log(' - And many more!');
} catch (error) {
console.error('\\n❌ Installation failed:', error.message);
console.error('\\nManual installation:');
console.error('1. Add to your Claude Desktop config:');
console.error(JSON.stringify({
mcpServers: {
'hanzo-mcp': {
command: 'node',
args: [path.join(__dirname, 'server.js')]
}
}
}, null, 2));
}
} else if (command === 'start') {
// Start the MCP server directly
const server = spawn('node', [path.join(__dirname, 'server.js')], {
stdio: 'inherit'
});
server.on('error', (err) => {
console.error('Failed to start server:', err);
process.exit(1);
});
} else {
console.log('Hanzo MCP - Model Context Protocol Server');
console.log('');
console.log('Usage:');
console.log(' npx @hanzo/mcp Install and configure');
console.log(' npx @hanzo/mcp install Install and configure');
console.log(' npx @hanzo/mcp start Start the MCP server');
console.log('');
console.log('Options:');
console.log(' --claude-code Configure for Claude Code');
}
`;
// Create README
const readme = `# @hanzo/mcp
Hanzo AI MCP (Model Context Protocol) server - powerful development tools for Claude Desktop and Claude Code.
## Quick Install
\`\`\`bash
npx @hanzo/mcp@latest
\`\`\`
This will automatically configure the MCP server for your environment.
## Manual Installation
### Claude Desktop
Add to your \`claude_desktop_config.json\`:
\`\`\`json
{
"mcpServers": {
"hanzo-mcp": {
"command": "npx",
"args": ["@hanzo/mcp@latest", "start"]
}
}
}
\`\`\`
### Claude Code
For Claude Code, install the DXT extension or run:
\`\`\`bash
npx @hanzo/mcp@latest --claude-code
\`\`\`
## Available Tools
- **File Operations**: read, write, edit, multi_edit, directory_tree
- **Search**: grep, git_search, find_files, symbols
- **Shell**: bash, run_command, processes, open
- **AI Tools**: llm, consensus, agent, mode
- **Development**: todo, critic, think, rules
- **Web**: web_fetch, batch_search
- **And many more!**
## Documentation
See [https://github.com/hanzoai/extension](https://github.com/hanzoai/extension) for full documentation.
`;
// Write files
console.log('Creating npm package files...');
fs.writeFileSync(path.join(npmDir, 'package.json'), JSON.stringify(packageJson, null, 2));
fs.writeFileSync(path.join(npmDir, 'cli.js'), cliScript);
fs.chmodSync(path.join(npmDir, 'cli.js'), '755');
fs.writeFileSync(path.join(npmDir, 'README.md'), readme);
console.log(`\n✅ NPM package created at: ${npmDir}`);
console.log('\nTo publish:');
console.log(` cd ${npmDir}`);
console.log(' npm publish\n');
console.log('Users can then install with:');
console.log(' npx @hanzo/mcp@latest');
+57
View File
@@ -0,0 +1,57 @@
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
console.log('🏄 Building Hanzo MCP for Windsurf IDE...\n');
// Windsurf uses the same VSIX format as VS Code
// We'll build a standard VSIX that Windsurf can install
const distDir = path.join(__dirname, '..', 'dist', 'windsurf');
// Ensure dist directory exists
if (!fs.existsSync(distDir)) {
fs.mkdirSync(distDir, { recursive: true });
}
try {
// First compile the TypeScript
console.log('📦 Compiling TypeScript...');
execSync('node scripts/compile-main.js', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Build MCP components
console.log('🔧 Building MCP components...');
execSync('npm run build:mcp', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Package the extension
console.log('📦 Packaging Windsurf extension...');
execSync('vsce package --no-dependencies --out dist/windsurf/', { stdio: 'inherit', cwd: path.join(__dirname, '..') });
// Read package.json to get version
const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8'));
const version = packageJson.version;
// Rename the output file to include windsurf in the name
const vsixFiles = fs.readdirSync(distDir).filter(f => f.endsWith('.vsix'));
if (vsixFiles.length > 0) {
const oldPath = path.join(distDir, vsixFiles[0]);
const newPath = path.join(distDir, `hanzoai-windsurf-${version}.vsix`);
fs.renameSync(oldPath, newPath);
console.log(`\n✅ Successfully built Windsurf extension: ${newPath}`);
console.log(`📦 File size: ${(fs.statSync(newPath).size / 1024 / 1024).toFixed(2)} MB`);
console.log('\n📥 To install in Windsurf:');
console.log(' 1. Open Windsurf');
console.log(' 2. Press Cmd+Shift+P (Mac) or Ctrl+Shift+P (Windows/Linux)');
console.log(' 3. Run "Extensions: Install from VSIX..."');
console.log(` 4. Select ${newPath}`);
console.log('\n💡 Windsurf integration includes:');
console.log(' - Full MCP tools access via @hanzo chat participant');
console.log(' - Access to 200+ LLMs through Hanzo AI');
console.log(' - 4000+ MCP servers integration');
}
} catch (error) {
console.error('❌ Build failed:', error.message);
process.exit(1);
}