#!/bin/bash # OpenDia DXT Build Script - Fixed Version # Run this from the OpenDia project root directory set -e # Exit on any error echo "๐Ÿš€ Building OpenDia DXT package..." # Check if we're in the right directory if [ ! -f "opendia-mcp/package.json" ]; then echo "โŒ Error: Please run this script from the OpenDia project root directory" echo " Expected to find: opendia-mcp/package.json" echo " Current directory: $(pwd)" exit 1 fi if [ ! -d "opendia-extension" ]; then echo "โŒ Error: opendia-extension directory not found" exit 1 fi # Clean and create dist directory echo "๐Ÿงน Cleaning previous build..." rm -rf dist mkdir -p dist/opendia-dxt echo "๐Ÿ“ฆ Setting up package..." # Copy server files cp opendia-mcp/server.js dist/opendia-dxt/ # Create optimized package.json for DXT cat > dist/opendia-dxt/package.json << 'EOF' { "name": "opendia", "version": "1.0.5", "description": "๐ŸŽฏ OpenDia - The open alternative to Dia. Connect your browser to AI models with anti-detection bypass for Twitter/X, LinkedIn, Facebook", "main": "server.js", "scripts": { "start": "node server.js" }, "keywords": [ "mcp", "browser", "automation", "ai", "claude", "chrome", "extension", "twitter", "linkedin", "facebook", "anti-detection", "dxt" ], "author": "Aaron Elijah Mars ", "license": "MIT", "dependencies": { "cors": "^2.8.5", "express": "^4.21.2", "ws": "^8.18.0" }, "engines": { "node": ">=16.0.0" } } EOF # Install dependencies echo "โฌ‡๏ธ Installing dependencies..." cd dist/opendia-dxt npm install --production --silent cd ../.. # Copy browser extension echo "๐ŸŒ Copying browser extension..." cp -r opendia-extension dist/opendia-dxt/extension # Copy logo/icon files for DXT - try multiple sources echo "๐ŸŽจ Copying logo files..." LOGO_COPIED=false # Try different icon files from the extension for icon_file in "icon-128.png" "icon-48.png" "icon-32.png" "icon-16.png" "icon.png"; do if [ -f "opendia-extension/$icon_file" ]; then cp "opendia-extension/$icon_file" dist/opendia-dxt/icon.png echo "โœ… Logo copied from extension/$icon_file" LOGO_COPIED=true break fi done # If no extension icon found, check root directory if [ "$LOGO_COPIED" = false ]; then for icon_file in "icon.png" "logo.png" "opendia.png"; do if [ -f "$icon_file" ]; then cp "$icon_file" dist/opendia-dxt/icon.png echo "โœ… Logo copied from $icon_file" LOGO_COPIED=true break fi done fi # Create a simple placeholder if no icon found if [ "$LOGO_COPIED" = false ]; then echo "โš ๏ธ No logo file found, you may need to add icon.png manually to dist/opendia-dxt/" fi # Create DXT manifest - CORRECT FORMAT BASED ON WORKING EXAMPLES echo "๐Ÿ“‹ Creating DXT manifest..." cat > dist/opendia-dxt/manifest.json << 'EOF' { "dxt_version": "0.1", "name": "opendia", "display_name": "OpenDia - Browser Automation", "version": "1.0.5", "description": "๐ŸŽฏ OpenDia - The open alternative to Dia. Connect your browser to AI models with anti-detection bypass for Twitter/X, LinkedIn, Facebook + universal automation", "author": { "name": "Aaron Elijah Mars", "email": "aaronjmars@proton.me", "url": "https://github.com/aaronjmars/opendia" }, "homepage": "https://github.com/aaronjmars/opendia", "license": "MIT", "keywords": ["browser", "automation", "mcp", "ai", "claude", "chrome", "extension", "twitter", "linkedin", "facebook", "anti-detection"], "icon": "icon.png", "icons": { "128": "icon.png" }, "server": { "type": "node", "entry_point": "server.js", "mcp_config": { "command": "node", "args": ["${__dirname}/server.js"], "env": { "NODE_ENV": "production", "WS_PORT": "${user_config.ws_port}", "HTTP_PORT": "${user_config.http_port}", "ENABLE_TUNNEL": "${user_config.enable_tunnel}", "SAFETY_MODE": "${user_config.safety_mode}" } } }, "user_config": { "ws_port": { "type": "number", "title": "WebSocket Port", "description": "Port for Chrome extension connection", "default": 5555, "minimum": 1024, "maximum": 65535 }, "http_port": { "type": "number", "title": "HTTP Port", "description": "Port for HTTP/SSE server", "default": 5556, "minimum": 1024, "maximum": 65535 }, "enable_tunnel": { "type": "boolean", "title": "Auto-Tunnel", "description": "Automatically create ngrok tunnel for online AI access (requires ngrok)", "default": false }, "safety_mode": { "type": "boolean", "title": "Safety Mode", "description": "Block write/edit tools (element_click, element_fill) by default", "default": false } }, "tools": [ { "name": "page_analyze", "description": "๐Ÿ” Analyze any tab without switching! Two-phase intelligent page analysis" }, { "name": "page_extract_content", "description": "๐Ÿ“„ Extract content from any tab without switching!" }, { "name": "element_click", "description": "๐Ÿ–ฑ๏ธ Click elements with anti-detection bypass for social platforms" }, { "name": "element_fill", "description": "โœ๏ธ Fill forms with anti-detection bypass for Twitter/X, LinkedIn, Facebook" }, { "name": "page_navigate", "description": "๐Ÿงญ Navigate to URLs with wait conditions" }, { "name": "page_wait_for", "description": "โณ Wait for elements or conditions" }, { "name": "tab_create", "description": "๐Ÿ“ฑ Create single or multiple tabs with batch support" }, { "name": "tab_close", "description": "โŒ Close specific tab(s) by ID" }, { "name": "tab_list", "description": "๐Ÿ“‹ Get list of all open tabs with IDs" }, { "name": "tab_switch", "description": "๐Ÿ”„ Switch to specific tab by ID" }, { "name": "element_get_state", "description": "๐Ÿ” Get detailed element state information" }, { "name": "get_bookmarks", "description": "๐Ÿ“š Get all bookmarks or search for specific ones" }, { "name": "add_bookmark", "description": "โž• Add new bookmark" }, { "name": "get_history", "description": "๐Ÿ•’ Search browser history with comprehensive filters" }, { "name": "get_selected_text", "description": "๐Ÿ“ Get selected text from any tab" }, { "name": "page_scroll", "description": "๐Ÿ“œ Scroll any tab without switching" }, { "name": "get_page_links", "description": "๐Ÿ”— Get all hyperlinks with smart filtering" }, { "name": "page_style", "description": "๐ŸŽจ Transform page appearance with themes and effects" } ], "capabilities": { "browser_automation": true, "anti_detection": true, "background_tabs": true, "multi_tab_workflows": true, "content_extraction": true, "form_filling": true, "social_media_posting": true, "page_styling": true, "bookmark_management": true, "history_search": true, "tab_management": true }, "requirements": { "chrome_extension": { "name": "OpenDia Browser Extension", "description": "Required Chrome extension for browser automation by Aaron Elijah Mars", "version": "1.0.5", "auto_install": false } } } EOF # Validate JSON syntax echo "๐Ÿ” Validating manifest.json..." if ! python3 -m json.tool dist/opendia-dxt/manifest.json > /dev/null 2>&1; then echo "โŒ Error: Invalid JSON in manifest.json" exit 1 fi echo "โœ… Manifest JSON is valid" # Copy documentation echo "๐Ÿ“ Adding documentation..." cp README.md dist/opendia-dxt/ 2>/dev/null || echo "โš ๏ธ README.md not found, skipping" cp LICENSE dist/opendia-dxt/ 2>/dev/null || echo "โš ๏ธ LICENSE not found, skipping" # Create extension installation guide cat > dist/opendia-dxt/EXTENSION_INSTALL.md << 'EOF' # OpenDia Chrome Extension Installation ## Quick Setup 1. **Enable Developer Mode** - Go to `chrome://extensions/` - Toggle "Developer mode" in the top right 2. **Install Extension** - Click "Load unpacked" - Select the `extension/` folder from this DXT package - Extension should appear in your extensions list 3. **Verify Connection** - Click the OpenDia extension icon - Should show "Connected to MCP server" - Green status indicator means ready to use ## Supported Browsers - Google Chrome, Arc Browser, Microsoft Edge, Brave Browser, Opera - Any Chromium-based browser ## Features ๐ŸŽฏ Anti-detection bypass for Twitter/X, LinkedIn, Facebook ๐Ÿ“ฑ Smart automation and page analysis ๐Ÿ”ง Form filling with enhanced compatibility ๐Ÿ“Š Multi-tab workflows and background operations ๐ŸŽจ Page styling and visual customization For more help, visit: https://github.com/aaronjmars/opendia EOF # Verify structure before zipping echo "๐Ÿ” Verifying DXT structure..." echo "๐Ÿ“‹ Files in DXT directory:" ls -la dist/opendia-dxt/ # Check if icon exists and show its details if [ -f "dist/opendia-dxt/icon.png" ]; then echo "โœ… Icon file found:" file dist/opendia-dxt/icon.png ls -lh dist/opendia-dxt/icon.png else echo "โŒ Icon file missing!" fi # Verify manifest.json exists and is at root level if [ ! -f "dist/opendia-dxt/manifest.json" ]; then echo "โŒ Error: manifest.json not found!" exit 1 fi echo "โœ… Structure verified" # Create the DXT archive - CRITICAL: ZIP from inside the directory echo "๐Ÿ—œ๏ธ Creating DXT archive..." cd dist/opendia-dxt zip -r ../opendia.dxt . -q cd ../.. # Verify the DXT file structure echo "๐Ÿ” Verifying DXT file contents..." if ! unzip -l dist/opendia.dxt | grep -q "manifest.json"; then echo "โŒ Error: manifest.json not found in DXT file!" echo "DXT contents:" unzip -l dist/opendia.dxt exit 1 fi # Get file size DXT_SIZE=$(du -h dist/opendia.dxt | cut -f1) echo "" echo "โœ… DXT package created successfully!" echo "๐Ÿ“ฆ File: dist/opendia.dxt" echo "๐Ÿ’พ Size: $DXT_SIZE" echo "" echo "๐Ÿ“‹ DXT Contents:" unzip -l dist/opendia.dxt | head -10 echo "" echo "๐Ÿš€ Installation:" echo "1. Double-click the .dxt file" echo "2. Or: Claude Desktop Settings โ†’ Extensions โ†’ Install Extension" echo "3. Install Chrome extension from extension/ folder" echo "" echo "๐ŸŽฏ Features ready: Anti-detection bypass + universal automation"