From 328f939f17e44652c1edaffe1fcaa3728f570746 Mon Sep 17 00:00:00 2001 From: Ben Priebe Date: Wed, 20 May 2026 10:21:25 +1000 Subject: [PATCH 1/3] feat: add Gemini Antigravity 2.0 integration --- .gitignore | 1 + integrations/antigravity/README.md | 107 ++++++++ .../antigravity/converter/package.json | 11 + .../converter/src/convert-agents.js | 256 ++++++++++++++++++ .../antigravity/install-antigravity.sh | 118 ++++++++ 5 files changed, 493 insertions(+) create mode 100644 integrations/antigravity/README.md create mode 100644 integrations/antigravity/converter/package.json create mode 100644 integrations/antigravity/converter/src/convert-agents.js create mode 100755 integrations/antigravity/install-antigravity.sh diff --git a/.gitignore b/.gitignore index 1d3339ce..50f03a91 100644 --- a/.gitignore +++ b/.gitignore @@ -225,5 +225,6 @@ tasks/ # Claude Code integration generated files integrations/claude-code/converter/generated/ +integrations/antigravity/converter/generated/ .cursorrules bun.lock diff --git a/integrations/antigravity/README.md b/integrations/antigravity/README.md new file mode 100644 index 00000000..ba7e4ab1 --- /dev/null +++ b/integrations/antigravity/README.md @@ -0,0 +1,107 @@ +# OpenAgents Control ↔ Gemini Antigravity CLI Integration + +A bridge that allows Gemini Antigravity 2.0 (Antigravity CLI 1.0) to use OpenAgents Control standards, subagents, and context files. + +## Overview + +This integration provides a seamless bridge between OpenAgents Control and Gemini Antigravity CLI (`agy`): + +1. **Auto-Convert**: Compiles OpenAgents Control's agent specifications into Antigravity CLI-native plugins +2. **Global & Local Workspaces**: Deploys plugins globally for all projects or locally under repository workspaces + +## Directory Structure + +``` +integrations/antigravity/ +├── README.md # This guide +├── install-antigravity.sh # Build & installation script (Global & Local) +└── converter/ # Conversion subsystem + ├── package.json # Dependencies + └── src/ + └── convert-agents.js # Node-based compiler and YAML mapper +``` + +## Quick Start + +### 1. Compile & Install the Plugin + +To compile OAC agents and install the plugin to your Antigravity environments, run: + +```bash +cd integrations/antigravity +./install-antigravity.sh +``` + +This will automatically: +1. Translate `.opencode/agent/*.md` specifications to Antigravity format in `integrations/antigravity/generated/`. +2. Generate the necessary `plugin.json` manifest. +3. Install the plugin globally to `~/.gemini/antigravity-cli/plugins/openagents-control-bridge`. +4. Install the plugin locally to `.agents/plugins/openagents-control-bridge` for workspace-specific runs. + +### 2. Verify in Antigravity CLI + +Start your Antigravity session and verify that the plugin has loaded correctly: + +```bash +# Start your CLI session +agy + +# Inspect active subagents and skills +/agents +/skills +``` + +You should see `openagents-control-standards` and `context-scout` registered and active. + +--- + +## How It Works + +### Context Discovery & Pre-loading + +1. **Skill Triggers**: The `openagents-control-standards` Skill triggers automatically before any development or architectural task. +2. **Subagent Invocation**: The skill delegates to `context-scout` to search `.opencode/context/` for relevant conventions, naming standards, and workflows. +3. **Upfront Loading**: Discovered files are read and pre-loaded into the prompt context to keep subsequent task execution fast, consistent, and highly token-efficient. + +### Agent Specification Mapping + +The converter translates OAC agent frontmatter properties to Antigravity CLI specifications: + +| OpenAgents Control Field | Gemini Antigravity Field | Notes / Conversions | +|--------------------------|--------------------------|---------------------| +| `id` | `name` | Uniquely names the subagent | +| `description` | `description` | Description used for auto-routing | +| `permissions` | `tools` | Maps `read` ➔ `read_file`, `write` ➔ `write_file`, `edit` ➔ `edit_file`, `bash` ➔ `run_command`, `grep` ➔ `grep_search`, `glob` ➔ `list_dir` | +| `model` | `model` | Translates models to user-approved designations: Grok/Sonnet ➔ `gemini-3.1-pro`, Haiku ➔ `gemini-3.5-flash` | +| `mode: subagent` | `permissionMode: plan` | Restricts executing subagents to planned/approved paths | + +--- + +## Adding Custom Agents & Workflows + +### For Local Workspace Use +Add your customized agent definitions under `.agents/agents/` and skills under `.agents/skills/`. The Antigravity Agent will auto-load them upon starting a session inside the workspace root. + +### For Global Distribution +1. Place the new OAC agent configuration in `.opencode/agent/{category}/{agent}.md`. +2. Run the compiler installer: `./install-antigravity.sh` +3. Your updated agent will instantly be active across all your CLI sessions. + +## Requirements + +- Node.js 18+ +- Gemini Antigravity CLI 1.0+ (with local plugin-loading enabled for repo-level runs) + +--- + +## Command Reference + +| Action | Claude Code CLI | Gemini Antigravity CLI | +|--------|-----------------|------------------------| +| Start interactive run | `claude` | `agy` | +| Browse Active Skills | `/print-plugins` | `/skills` | +| Browse Active Subagents| `/print-plugins` | `/agents` | +| Settings & Config | `~/.claude/settings.json` | `/config` or `/settings` | +| Keybindings Map | `/keybindings` | `/keybindings` | +| Directory Search | `/glob` / `/grep` | `@` (autocomplete) or `/skills` search | +| Run single bash command| `!command` | `!command` | diff --git a/integrations/antigravity/converter/package.json b/integrations/antigravity/converter/package.json new file mode 100644 index 00000000..f705a5a0 --- /dev/null +++ b/integrations/antigravity/converter/package.json @@ -0,0 +1,11 @@ +{ + "name": "oac-antigravity-converter", + "version": "1.0.0", + "description": "Converts OpenAgents Control agents and skills to Antigravity CLI format", + "main": "src/convert-agents.js", + "scripts": { + "convert": "node src/convert-agents.js" + }, + "author": "Antigravity", + "license": "MIT" +} diff --git a/integrations/antigravity/converter/src/convert-agents.js b/integrations/antigravity/converter/src/convert-agents.js new file mode 100644 index 00000000..115de46e --- /dev/null +++ b/integrations/antigravity/converter/src/convert-agents.js @@ -0,0 +1,256 @@ +#!/usr/bin/env node + +/** + * convert-agents.js + * Converts OpenAgents Control to Gemini Antigravity CLI format + * + * Usage: node convert-agents.js + */ + +const fs = require('fs'); +const path = require('path'); + +// Configuration - Use absolute paths from the script location +const SCRIPT_DIR = __dirname; +const REPO_ROOT = path.resolve(path.join(SCRIPT_DIR, '../../../../')); +const SOURCE_DIR = path.join(REPO_ROOT, '.opencode/agent'); +const OUTPUT_DIR = path.join(SCRIPT_DIR, '../generated'); + +const ANTIGRAVITY_AGENTS_DIR = path.join(OUTPUT_DIR, 'agents'); +const ANTIGRAVITY_SKILLS_DIR = path.join(OUTPUT_DIR, 'skills'); + +console.log('🚀 OpenAgents Control → Gemini Antigravity CLI Converter'); +console.log(` Source: ${SOURCE_DIR}`); +console.log(` Output: ${OUTPUT_DIR}\n`); + +/** + * Parses YAML frontmatter from markdown + */ +function parseFrontmatter(content) { + const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); + if (!match) return { frontmatter: null, content }; + + const yaml = match[1]; + const body = match[2]; + + const frontmatter = {}; + yaml.split('\n').forEach(line => { + const colonIndex = line.indexOf(':'); + if (colonIndex > -1) { + const key = line.slice(0, colonIndex).trim(); + let value = line.slice(colonIndex + 1).trim(); + + // Parse arrays + if (value.startsWith('[') && value.endsWith(']')) { + value = value.slice(1, -1).split(',').map(v => v.trim().replace(/"/g, '')); + } + + frontmatter[key] = value; + } + }); + + return { frontmatter, body }; +} + +/** + * Converts OpenCode frontmatter to Antigravity format + */ +function convertFrontmatter(ocFrontmatter) { + const antigravity = {}; + + // Map OpenCode fields to Antigravity fields + antigravity.name = ocFrontmatter.id || ocFrontmatter.name; + antigravity.description = ocFrontmatter.description; + + // Map tools from OpenCode permissions to Antigravity tools + if (ocFrontmatter.tools) { + antigravity.tools = ocFrontmatter.tools; + } else if (ocFrontmatter.permissions || ocFrontmatter.permission) { + const perm = ocFrontmatter.permissions || ocFrontmatter.permission; + const tools = []; + if (perm.read) tools.push('read_file'); + if (perm.grep) tools.push('grep_search'); + if (perm.glob) tools.push('list_dir'); + if (perm.edit) tools.push('edit_file'); + if (perm.write) tools.push('write_file'); + if (perm.bash) tools.push('run_command'); + + // Default fallback if no permissions explicitly matched but has some permission key + if (tools.length === 0) { + tools.push('read_file', 'grep_search', 'list_dir'); + } + + antigravity.tools = tools.join(', '); + } else { + // Default safe tool permissions + antigravity.tools = 'read_file, grep_search, list_dir'; + } + + // Map model to user-specified models + antigravity.model = mapModel(ocFrontmatter.model); + + // Map permissionMode (default to 'default' if not specified) + antigravity.permissionMode = ocFrontmatter.mode === 'subagent' ? 'plan' : 'default'; + + return antigravity; +} + +/** + * Maps OpenCode model names to Gemini model aliases for Antigravity + */ +function mapModel(model) { + const modelMap = { + 'opencode/grok-code': 'gemini-3.1-pro', + 'opencode/grok': 'gemini-3.1-pro', + 'gpt-4': 'gemini-3.1-pro', + 'gpt-4o': 'gemini-3.1-pro', + 'sonnet': 'gemini-3.1-pro', + 'haiku': 'gemini-3.5-flash', + }; + return modelMap[model] || 'gemini-3.1-pro'; +} + +/** + * Generates Antigravity markdown from converted data + */ +function generateAntigravityMarkdown(antigravityFrontmatter, body) { + const fm = Object.entries(antigravityFrontmatter) + .map(([key, value]) => { + if (Array.isArray(value)) { + return `${key}: [${value.map(v => `"${v}"`).join(', ')}]`; + } + let strVal = String(value); + if (strVal.startsWith('"') && strVal.endsWith('"')) { + strVal = strVal.slice(1, -1); + } + return `${key}: "${strVal}"`; + }) + .join('\n'); + + return `---\n${fm}\n---\n\n${body}`; +} + +/** + * Recursively finds all .md files in a directory + */ +function findMarkdownFiles(dir, files = []) { + if (!fs.existsSync(dir)) return files; + const entries = fs.readdirSync(dir, { withFileTypes: true }); + + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + findMarkdownFiles(fullPath, files); + } else if (entry.name.endsWith('.md')) { + files.push(fullPath); + } + } + + return files; +} + +/** + * Processes a single agent file + */ +function processAgent(filePath) { + const content = fs.readFileSync(filePath, 'utf8'); + const { frontmatter, body } = parseFrontmatter(content); + + if (!frontmatter) { + console.log(`⚠️ Skipping ${filePath} (no frontmatter)`); + return; + } + + const antigravityFrontmatter = convertFrontmatter(frontmatter); + const antigravityMarkdown = generateAntigravityMarkdown(antigravityFrontmatter, body); + + // Determine output path + const relativePath = path.relative(SOURCE_DIR, filePath); + const outputPath = path.join(ANTIGRAVITY_AGENTS_DIR, relativePath); + + // Ensure output directory exists + fs.mkdirSync(path.dirname(outputPath), { recursive: true }); + + fs.writeFileSync(outputPath, antigravityMarkdown); + console.log(`✅ Converted: ${relativePath}`); +} + +/** + * Main conversion function + */ +function convert() { + // Clean output directory + if (fs.existsSync(OUTPUT_DIR)) fs.rmSync(OUTPUT_DIR, { recursive: true }); + + fs.mkdirSync(ANTIGRAVITY_AGENTS_DIR, { recursive: true }); + fs.mkdirSync(path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards'), { recursive: true }); + + // Create plugin.json at the plugin root + const pluginJson = { + name: "openagents-control-bridge" + }; + fs.writeFileSync( + path.join(OUTPUT_DIR, 'plugin.json'), + JSON.stringify(pluginJson, null, 2) + ); + console.log('📦 Created plugin.json manifest'); + + console.log('📦 Converting agents...\n'); + + // Process category agents + const agentFiles = findMarkdownFiles(SOURCE_DIR); + agentFiles.forEach(processAgent); + + // Create default context-scout subagent + const contextScoutContent = `--- +name: context-scout +description: Discovers and recommends OpenAgents Control context files using list_dir, read_file, and grep_search tools. Use when you need to find OpenAgents Control standards, guides, or domain knowledge in the .opencode/context directory. +tools: read_file, grep_search, list_dir +model: gemini-3.5-flash +permissionMode: plan +--- + +# ContextScout + +You discover and recommend relevant OpenAgents Control context files from \`.opencode/context/\` based on the user's request. + +## Your Process + +1. Use \`list_dir\` or custom glob tools to find files in \`.opencode/context/\`. +2. Use \`read_file\` or \`grep_search\` to verify relevance. +3. Return file paths with brief descriptions. +`; + + fs.writeFileSync( + path.join(ANTIGRAVITY_AGENTS_DIR, 'context-scout.md'), + contextScoutContent + ); + console.log('✅ Created context-scout subagent'); + + // Create openagents-control-standards skill + const skillContent = `--- +name: openagents-control-standards +description: Automatically triggers before any task to ensure OpenAgents Control standards and context are loaded. Use when the user asks to create, modify, or analyze anything in this repository. +--- + +# OpenAgents Control Standards Loader + +Before proceeding with the user's request: + +1. Call the \`context-scout\` subagent with the user's request to find relevant OpenAgents Control context files. +2. Read the returned "Critical" and "High" priority files using \`read_file\`. +3. Apply the OpenAgents Control standards found to your work. +`; + + fs.writeFileSync( + path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards/SKILL.md'), + skillContent + ); + console.log('✅ Created openagents-control-standards skill'); + + console.log('\n✨ Conversion complete!'); + console.log(` Output: ${OUTPUT_DIR}`); +} + +// Run conversion +convert(); diff --git a/integrations/antigravity/install-antigravity.sh b/integrations/antigravity/install-antigravity.sh new file mode 100755 index 00000000..85b48b0d --- /dev/null +++ b/integrations/antigravity/install-antigravity.sh @@ -0,0 +1,118 @@ +#!/usr/bin/env bash +# +# install-antigravity.sh +# Installs OpenAgents Control to Gemini Antigravity CLI with automatic conversion +# + +set -euo pipefail + +# Colors +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +RED='\033[0;31m' +NC='\033[0m' # No Color + +# Determine paths +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +OPENCODE_DIR="$REPO_ROOT/.opencode/agent" +CONVERTER_DIR="$SCRIPT_DIR/converter" +PLUGIN_DEST="$HOME/.gemini/antigravity-cli/plugins/openagents-control-bridge" +LOCAL_PLUGIN_DEST="$REPO_ROOT/.agents/plugins/openagents-control-bridge" +NODE_BIN="${NODE_BIN:-node}" + +echo -e "${GREEN}🚀 OpenAgents Control → Gemini Antigravity CLI Installer${NC}" +echo -e " Source: $OPENCODE_DIR" +echo -e " Global Destination: $PLUGIN_DEST" +echo -e " Local Workspace Destination: $LOCAL_PLUGIN_DEST" +echo "" + +# Check prerequisites +check_prereqs() { + local missing=() + + # Check for node + if ! command -v "$NODE_BIN" >/dev/null 2>&1; then + missing+=("$NODE_BIN") + fi + + # Check for bash + if ! command -v bash >/dev/null 2>&1; then + missing+=("bash") + fi + + if [ ${#missing[@]} -gt 0 ]; then + echo -e "${RED}✗ Missing required commands: ${missing[*]}${NC}" >&2 + echo -e " Install Node.js: https://nodejs.org/" >&2 + exit 1 + fi +} + +# Run converter +run_converter() { + echo -e "${YELLOW}🔄 Converting agents to Antigravity format...${NC}" + cd "$CONVERTER_DIR" + + if ! "$NODE_BIN" src/convert-agents.js 2>&1 | grep -q "Conversion complete"; then + echo -e "${RED}✗ Conversion failed${NC}" >&2 + exit 1 + fi + + echo -e "${GREEN}✅ Conversion complete${NC}" +} + +# Install plugin +install_plugin() { + # 1. Global Installation + echo -e "${YELLOW}📦 Installing global plugin...${NC}" + mkdir -p "$HOME/.gemini/antigravity-cli/plugins" + + if [ -d "$PLUGIN_DEST" ]; then + echo "🗑️ Removing old global installation..." + rm -rf "$PLUGIN_DEST" + fi + + cp -r "$CONVERTER_DIR/generated" "$PLUGIN_DEST" + echo -e "${GREEN}✅ Global installation complete${NC}" + + # 2. Local/Workspace Installation + echo -e "${YELLOW}📦 Installing workspace plugin...${NC}" + mkdir -p "$REPO_ROOT/.agents/plugins" + + if [ -d "$LOCAL_PLUGIN_DEST" ]; then + echo "🗑️ Removing old workspace installation..." + rm -rf "$LOCAL_PLUGIN_DEST" + fi + + cp -r "$CONVERTER_DIR/generated" "$LOCAL_PLUGIN_DEST" + echo -e "${GREEN}✅ Workspace installation complete${NC}" +} + +# Verify installation +verify() { + if [ ! -f "$PLUGIN_DEST/agents/core/openagent.md" ]; then + echo -e "${RED}✗ Installation verification failed${NC}" >&2 + echo " Expected: $PLUGIN_DEST/agents/core/openagent.md" >&2 + exit 1 + fi + + echo "" + echo -e "${GREEN}✨ Installation successful!${NC}" + echo "" + echo "To use with Gemini Antigravity CLI:" + echo " - View active skills using the: /skills command" + echo " - View active subagents using the: /agents command" + echo "" + echo "Your OAC plug-in is loaded and ready to trigger on your next task!" +} + +# Main workflow +main() { + check_prereqs + run_converter + install_plugin + verify +} + +# Allow specifying custom Node.js binary via NODE_BIN environment variable +main "$@" From ac36e0339a57ce4b9814aeea39ca2fbf26056e1e Mon Sep 17 00:00:00 2001 From: Ben Priebe Date: Wed, 20 May 2026 10:46:16 +1000 Subject: [PATCH 2/3] feat: flatten agents for auto-discovery and add support for converting all repository skills --- .../converter/src/convert-agents.js | 65 +++++++++++++++++-- .../antigravity/install-antigravity.sh | 37 +++++++++-- 2 files changed, 88 insertions(+), 14 deletions(-) diff --git a/integrations/antigravity/converter/src/convert-agents.js b/integrations/antigravity/converter/src/convert-agents.js index 115de46e..80a3dccf 100644 --- a/integrations/antigravity/converter/src/convert-agents.js +++ b/integrations/antigravity/converter/src/convert-agents.js @@ -164,15 +164,38 @@ function processAgent(filePath) { const antigravityFrontmatter = convertFrontmatter(frontmatter); const antigravityMarkdown = generateAntigravityMarkdown(antigravityFrontmatter, body); - // Determine output path - const relativePath = path.relative(SOURCE_DIR, filePath); - const outputPath = path.join(ANTIGRAVITY_AGENTS_DIR, relativePath); + // Determine output path (FLATTENED to level 1 for discovery) + const filename = path.basename(filePath); + const outputPath = path.join(ANTIGRAVITY_AGENTS_DIR, filename); // Ensure output directory exists fs.mkdirSync(path.dirname(outputPath), { recursive: true }); fs.writeFileSync(outputPath, antigravityMarkdown); - console.log(`✅ Converted: ${relativePath}`); + console.log(`✅ Converted agent: ${filename}`); +} + +/** + * Processes and copies a skill folder + */ +function processSkill(skillMdPath) { + const skillDir = path.dirname(skillMdPath); + const skillFolderName = path.basename(skillDir); + + const outputSkillDir = path.join(ANTIGRAVITY_SKILLS_DIR, skillFolderName); + fs.mkdirSync(outputSkillDir, { recursive: true }); + + // Copy all files in the skill directory + const files = fs.readdirSync(skillDir); + files.forEach(file => { + const srcPath = path.join(skillDir, file); + const destPath = path.join(outputSkillDir, file); + if (fs.statSync(srcPath).isFile()) { + fs.copyFileSync(srcPath, destPath); + } + }); + + console.log(`✅ Processed skill: ${skillFolderName}`); } /** @@ -183,7 +206,7 @@ function convert() { if (fs.existsSync(OUTPUT_DIR)) fs.rmSync(OUTPUT_DIR, { recursive: true }); fs.mkdirSync(ANTIGRAVITY_AGENTS_DIR, { recursive: true }); - fs.mkdirSync(path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards'), { recursive: true }); + fs.mkdirSync(ANTIGRAVITY_SKILLS_DIR, { recursive: true }); // Create plugin.json at the plugin root const pluginJson = { @@ -227,7 +250,33 @@ You discover and recommend relevant OpenAgents Control context files from \`.ope ); console.log('✅ Created context-scout subagent'); - // Create openagents-control-standards skill + console.log('\n📦 Processing skills...\n'); + + // Find all skill files in .opencode/skills/ and .opencode/skill/ + const skillsDir1 = path.join(REPO_ROOT, '.opencode/skills'); + const skillsDir2 = path.join(REPO_ROOT, '.opencode/skill'); + + const skillFiles = []; + + function findSkillMdFiles(dir) { + if (!fs.existsSync(dir)) return; + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const fullPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + findSkillMdFiles(fullPath); + } else if (entry.name === 'SKILL.md') { + skillFiles.push(fullPath); + } + } + } + + findSkillMdFiles(skillsDir1); + findSkillMdFiles(skillsDir2); + + skillFiles.forEach(processSkill); + + // Create default openagents-control-standards skill const skillContent = `--- name: openagents-control-standards description: Automatically triggers before any task to ensure OpenAgents Control standards and context are loaded. Use when the user asks to create, modify, or analyze anything in this repository. @@ -242,8 +291,10 @@ Before proceeding with the user's request: 3. Apply the OpenAgents Control standards found to your work. `; + const stdSkillDir = path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards'); + fs.mkdirSync(stdSkillDir, { recursive: true }); fs.writeFileSync( - path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards/SKILL.md'), + path.join(stdSkillDir, 'SKILL.md'), skillContent ); console.log('✅ Created openagents-control-standards skill'); diff --git a/integrations/antigravity/install-antigravity.sh b/integrations/antigravity/install-antigravity.sh index 85b48b0d..1c82d61f 100755 --- a/integrations/antigravity/install-antigravity.sh +++ b/integrations/antigravity/install-antigravity.sh @@ -63,19 +63,29 @@ run_converter() { # Install plugin install_plugin() { - # 1. Global Installation - echo -e "${YELLOW}📦 Installing global plugin...${NC}" + # 1. Global Installation (antigravity-cli) + echo -e "${YELLOW}📦 Installing global CLI plugin...${NC}" mkdir -p "$HOME/.gemini/antigravity-cli/plugins" if [ -d "$PLUGIN_DEST" ]; then - echo "🗑️ Removing old global installation..." + echo "🗑️ Removing old global CLI installation..." rm -rf "$PLUGIN_DEST" fi cp -r "$CONVERTER_DIR/generated" "$PLUGIN_DEST" - echo -e "${GREEN}✅ Global installation complete${NC}" + echo -e "${GREEN}✅ Global CLI installation complete${NC}" + + # 2. Global Configuration Plugins (Desktop & CLI Auto-Load) + echo -e "${YELLOW}📦 Installing global config plugin...${NC}" + local config_plugin_dest="/Users/benpriebe/.gemini/config/plugins/openagents-control-bridge" + mkdir -p "/Users/benpriebe/.gemini/config/plugins" + if [ -d "$config_plugin_dest" ]; then + rm -rf "$config_plugin_dest" + fi + cp -r "$CONVERTER_DIR/generated" "$config_plugin_dest" + echo -e "${GREEN}✅ Global config installation complete${NC}" - # 2. Local/Workspace Installation + # 3. Local/Workspace Installation (.agents/plugins) echo -e "${YELLOW}📦 Installing workspace plugin...${NC}" mkdir -p "$REPO_ROOT/.agents/plugins" @@ -86,13 +96,26 @@ install_plugin() { cp -r "$CONVERTER_DIR/generated" "$LOCAL_PLUGIN_DEST" echo -e "${GREEN}✅ Workspace installation complete${NC}" + + # 4. Standard Workspace Paths (.agents/skills and .agents/agents) + echo -e "${YELLOW}📦 Installing to standard workspace paths (.agents/skills/ and .agents/agents/)...${NC}" + mkdir -p "$REPO_ROOT/.agents/skills" + mkdir -p "$REPO_ROOT/.agents/agents" + + # Clean old workspace skills/agents directories + rm -rf "$REPO_ROOT/.agents/skills"/* + rm -rf "$REPO_ROOT/.agents/agents"/* + + cp -r "$CONVERTER_DIR/generated/skills"/* "$REPO_ROOT/.agents/skills/" + cp -r "$CONVERTER_DIR/generated/agents"/* "$REPO_ROOT/.agents/agents/" + echo -e "${GREEN}✅ Standard workspace paths installation complete${NC}" } # Verify installation verify() { - if [ ! -f "$PLUGIN_DEST/agents/core/openagent.md" ]; then + if [ ! -f "$PLUGIN_DEST/agents/openagent.md" ]; then echo -e "${RED}✗ Installation verification failed${NC}" >&2 - echo " Expected: $PLUGIN_DEST/agents/core/openagent.md" >&2 + echo " Expected: $PLUGIN_DEST/agents/openagent.md" >&2 exit 1 fi From 0d491f3c80fc2fa87e14a9f7914ce352458b6b69 Mon Sep 17 00:00:00 2001 From: Ben Priebe Date: Wed, 20 May 2026 11:43:38 +1000 Subject: [PATCH 3/3] feat(antigravity): implement pristine, zero-redundancy OAC-to-Antigravity bridge --- .gitignore | 2 + .opencode/agent/content/copywriter.md | 2 + .opencode/agent/content/technical-writer.md | 2 + .opencode/agent/core/openagent.md | 2 + .opencode/agent/core/opencoder.md | 2 + .opencode/agent/data/data-analyst.md | 2 + .opencode/agent/eval-runner.md | 2 + .opencode/agent/meta/repo-manager.md | 2 + .opencode/agent/meta/system-builder.md | 2 + .opencode/agent/subagents/code/build-agent.md | 2 + .opencode/agent/subagents/code/coder-agent.md | 2 + .opencode/agent/subagents/code/reviewer.md | 2 + .../agent/subagents/code/test-engineer.md | 2 + .../agent/subagents/core/batch-executor.md | 2 + .../agent/subagents/core/context-manager.md | 2 + .../agent/subagents/core/context-retriever.md | 2 + .../agent/subagents/core/contextscout.md | 2 + .../agent/subagents/core/documentation.md | 2 + .../agent/subagents/core/externalscout.md | 2 + .../subagents/core/stage-orchestrator.md | 2 + .../agent/subagents/core/task-manager.md | 2 + .../development/devops-specialist.md | 2 + .../development/frontend-specialist.md | 2 + .../agent/subagents/planning/adr-manager.md | 2 + .../planning/architecture-analyzer.md | 2 + .../subagents/planning/contract-manager.md | 2 + .../planning/prioritization-engine.md | 2 + .../agent/subagents/planning/story-mapper.md | 2 + .../system-builder/agent-generator.md | 2 + .../system-builder/command-creator.md | 2 + .../system-builder/context-organizer.md | 2 + .../system-builder/domain-analyzer.md | 2 + .../system-builder/workflow-designer.md | 2 + .../agent/subagents/test/simple-responder.md | 2 + .../agent/subagents/utils/image-specialist.md | 2 + .opencode/command/add-context.md | 1 + .opencode/command/build-context-system.md | 1 + .opencode/command/clean.md | 1 + .opencode/command/commit-openagents.md | 1 + .opencode/command/commit.md | 1 + .opencode/command/context.md | 1 + .../command/openagents/check-context-deps.md | 1 + .../command/openagents/new-agents/README.md | 5 + .../openagents/new-agents/create-agent.md | 1 + .../openagents/new-agents/create-tests.md | 1 + .../new-agents/templates/agent-template.md | 1 + .../new-agents/templates/context-template.md | 5 + .opencode/command/optimize.md | 1 + .../prompt-engineering/prompt-enhancer.md | 1 + .../prompt-engineering/prompt-optimizer.md | 1 + .opencode/command/test-new-command.md | 1 + .opencode/command/test.md | 1 + .opencode/command/validate-repo.md | 5 + .opencode/command/worktrees.md | 1 + integrations/antigravity/README.md | 95 ++---- .../antigravity/converter/package.json | 11 - .../converter/src/convert-agents.js | 307 ------------------ .../antigravity/install-antigravity.sh | 162 +++------ scripts/setup-gemini-bridge.js | 287 ++++++++++++++++ 59 files changed, 461 insertions(+), 502 deletions(-) delete mode 100644 integrations/antigravity/converter/package.json delete mode 100644 integrations/antigravity/converter/src/convert-agents.js create mode 100644 scripts/setup-gemini-bridge.js diff --git a/.gitignore b/.gitignore index 50f03a91..1985ed10 100644 --- a/.gitignore +++ b/.gitignore @@ -226,5 +226,7 @@ tasks/ # Claude Code integration generated files integrations/claude-code/converter/generated/ integrations/antigravity/converter/generated/ +.agents/ +.antigravitycli/ .cursorrules bun.lock diff --git a/.opencode/agent/content/copywriter.md b/.opencode/agent/content/copywriter.md index 8f36fc2d..872fe8a4 100644 --- a/.opencode/agent/content/copywriter.md +++ b/.opencode/agent/content/copywriter.md @@ -7,6 +7,8 @@ name: OpenCopywriter description: "Expert in persuasive writing, marketing copy, and brand messaging" mode: primary temperature: 0.3 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Copywriter diff --git a/.opencode/agent/content/technical-writer.md b/.opencode/agent/content/technical-writer.md index 5c61bf3b..21b8ad5b 100644 --- a/.opencode/agent/content/technical-writer.md +++ b/.opencode/agent/content/technical-writer.md @@ -7,6 +7,8 @@ name: OpenTechnicalWriter description: "Expert in documentation, API docs, and technical communication" mode: primary temperature: 0.2 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Technical Writer diff --git a/.opencode/agent/core/openagent.md b/.opencode/agent/core/openagent.md index 7055915c..c88c763f 100644 --- a/.opencode/agent/core/openagent.md +++ b/.opencode/agent/core/openagent.md @@ -16,6 +16,8 @@ permission: "**/*.secret": "deny" "node_modules/**": "deny" ".git/**": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content --- Always use ContextScout for discovery of new tasks or context files. ContextScout is exempt from the approval gate rule. ContextScout is your secret weapon for quality, use it where possible. diff --git a/.opencode/agent/core/opencoder.md b/.opencode/agent/core/opencoder.md index 7e2be799..d4d3c67a 100644 --- a/.opencode/agent/core/opencoder.md +++ b/.opencode/agent/core/opencoder.md @@ -20,6 +20,8 @@ permission: "**/__pycache__/**": "deny" "**/*.pyc": "deny" ".git/**": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content --- # Development Agent diff --git a/.opencode/agent/data/data-analyst.md b/.opencode/agent/data/data-analyst.md index 827b6e22..c78597c0 100644 --- a/.opencode/agent/data/data-analyst.md +++ b/.opencode/agent/data/data-analyst.md @@ -3,6 +3,8 @@ name: OpenDataAnalyst description: "Expert in data analysis, visualization, and statistical insights" mode: primary temperature: 0.1 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Data Analyst diff --git a/.opencode/agent/eval-runner.md b/.opencode/agent/eval-runner.md index ec926258..bd2f18f1 100644 --- a/.opencode/agent/eval-runner.md +++ b/.opencode/agent/eval-runner.md @@ -9,6 +9,8 @@ version: 1.0.0 author: opencode mode: subagent temperature: 0.2 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Eval Runner - Test Harness diff --git a/.opencode/agent/meta/repo-manager.md b/.opencode/agent/meta/repo-manager.md index 122b622e..5c9489f5 100644 --- a/.opencode/agent/meta/repo-manager.md +++ b/.opencode/agent/meta/repo-manager.md @@ -15,6 +15,8 @@ permission: "**/*.secret": "deny" "node_modules/**": "deny" ".git/**": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content --- diff --git a/.opencode/agent/meta/system-builder.md b/.opencode/agent/meta/system-builder.md index 6d18f063..e7679ff8 100644 --- a/.opencode/agent/meta/system-builder.md +++ b/.opencode/agent/meta/system-builder.md @@ -7,6 +7,8 @@ name: OpenSystemBuilder description: "Main orchestrator for building complete context-aware AI systems from user requirements" mode: primary temperature: 0.2 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # System Builder Orchestrator diff --git a/.opencode/agent/subagents/code/build-agent.md b/.opencode/agent/subagents/code/build-agent.md index 8850da21..70252eef 100644 --- a/.opencode/agent/subagents/code/build-agent.md +++ b/.opencode/agent/subagents/code/build-agent.md @@ -22,6 +22,8 @@ permission: task: contextscout: "allow" "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content, write_to_file --- # BuildAgent diff --git a/.opencode/agent/subagents/code/coder-agent.md b/.opencode/agent/subagents/code/coder-agent.md index 61aaf5f0..63e03059 100644 --- a/.opencode/agent/subagents/code/coder-agent.md +++ b/.opencode/agent/subagents/code/coder-agent.md @@ -18,6 +18,8 @@ permission: contextscout: "allow" externalscout: "allow" TestEngineer: "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # CoderAgent diff --git a/.opencode/agent/subagents/code/reviewer.md b/.opencode/agent/subagents/code/reviewer.md index 71da8c0f..cfd5084b 100644 --- a/.opencode/agent/subagents/code/reviewer.md +++ b/.opencode/agent/subagents/code/reviewer.md @@ -12,6 +12,8 @@ permission: "**/*": "deny" task: contextscout: "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content, write_to_file --- # CodeReviewer diff --git a/.opencode/agent/subagents/code/test-engineer.md b/.opencode/agent/subagents/code/test-engineer.md index d29b35c9..074ce43a 100644 --- a/.opencode/agent/subagents/code/test-engineer.md +++ b/.opencode/agent/subagents/code/test-engineer.md @@ -25,6 +25,8 @@ permission: task: contextscout: "allow" externalscout: "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content --- # TestEngineer diff --git a/.opencode/agent/subagents/core/batch-executor.md b/.opencode/agent/subagents/core/batch-executor.md index fda5744b..539754a1 100644 --- a/.opencode/agent/subagents/core/batch-executor.md +++ b/.opencode/agent/subagents/core/batch-executor.md @@ -20,6 +20,8 @@ permission: externalscout: "allow" coderagent: "allow" OpenFrontendSpecialist: "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # BatchExecutor diff --git a/.opencode/agent/subagents/core/context-manager.md b/.opencode/agent/subagents/core/context-manager.md index 41c738d9..75f8c335 100644 --- a/.opencode/agent/subagents/core/context-manager.md +++ b/.opencode/agent/subagents/core/context-manager.md @@ -31,6 +31,8 @@ permission: task: "*": "deny" "contextscout": "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, run_command, replace_file_content, write_to_file --- # ContextManager diff --git a/.opencode/agent/subagents/core/context-retriever.md b/.opencode/agent/subagents/core/context-retriever.md index 49d00162..342ae57a 100644 --- a/.opencode/agent/subagents/core/context-retriever.md +++ b/.opencode/agent/subagents/core/context-retriever.md @@ -10,6 +10,8 @@ permission: "**/*": "deny" write: "**/*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content, write_to_file --- # Context Retriever Agent diff --git a/.opencode/agent/subagents/core/contextscout.md b/.opencode/agent/subagents/core/contextscout.md index 667b1928..fbae9698 100644 --- a/.opencode/agent/subagents/core/contextscout.md +++ b/.opencode/agent/subagents/core/contextscout.md @@ -18,6 +18,8 @@ permission: task: "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # ContextScout diff --git a/.opencode/agent/subagents/core/documentation.md b/.opencode/agent/subagents/core/documentation.md index f6a265e4..2dcf7b41 100644 --- a/.opencode/agent/subagents/core/documentation.md +++ b/.opencode/agent/subagents/core/documentation.md @@ -15,6 +15,8 @@ permission: task: contextscout: "allow" "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # DocWriter diff --git a/.opencode/agent/subagents/core/externalscout.md b/.opencode/agent/subagents/core/externalscout.md index 7da8710d..fbfcf29b 100644 --- a/.opencode/agent/subagents/core/externalscout.md +++ b/.opencode/agent/subagents/core/externalscout.md @@ -17,6 +17,8 @@ permission: "*context7*": "allow" task: "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- diff --git a/.opencode/agent/subagents/core/stage-orchestrator.md b/.opencode/agent/subagents/core/stage-orchestrator.md index 7e67dbcc..63995480 100644 --- a/.opencode/agent/subagents/core/stage-orchestrator.md +++ b/.opencode/agent/subagents/core/stage-orchestrator.md @@ -21,6 +21,8 @@ permission: taskmanager: "allow" batchexecutor: "allow" coderagent: "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # StageOrchestrator diff --git a/.opencode/agent/subagents/core/task-manager.md b/.opencode/agent/subagents/core/task-manager.md index 46249962..d7a581e6 100644 --- a/.opencode/agent/subagents/core/task-manager.md +++ b/.opencode/agent/subagents/core/task-manager.md @@ -22,6 +22,8 @@ permission: skill: "*": "deny" "task-management": "allow" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- diff --git a/.opencode/agent/subagents/development/devops-specialist.md b/.opencode/agent/subagents/development/devops-specialist.md index 5d9aef55..12b23661 100644 --- a/.opencode/agent/subagents/development/devops-specialist.md +++ b/.opencode/agent/subagents/development/devops-specialist.md @@ -28,6 +28,8 @@ permission: "**/*.env*": "deny" "**/*.key": "deny" "**/*.secret": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # DevOps Specialist Subagent diff --git a/.opencode/agent/subagents/development/frontend-specialist.md b/.opencode/agent/subagents/development/frontend-specialist.md index d52bbc35..b8d09054 100644 --- a/.opencode/agent/subagents/development/frontend-specialist.md +++ b/.opencode/agent/subagents/development/frontend-specialist.md @@ -21,6 +21,8 @@ permission: "**/*.env*": "deny" "**/*.key": "deny" "**/*.secret": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content, write_to_file --- # Frontend Design Subagent diff --git a/.opencode/agent/subagents/planning/adr-manager.md b/.opencode/agent/subagents/planning/adr-manager.md index a4dbea36..97d5c373 100644 --- a/.opencode/agent/subagents/planning/adr-manager.md +++ b/.opencode/agent/subagents/planning/adr-manager.md @@ -15,6 +15,8 @@ permission: task: contextscout: "allow" "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # ADRManager diff --git a/.opencode/agent/subagents/planning/architecture-analyzer.md b/.opencode/agent/subagents/planning/architecture-analyzer.md index 7af845fa..0dc9525d 100644 --- a/.opencode/agent/subagents/planning/architecture-analyzer.md +++ b/.opencode/agent/subagents/planning/architecture-analyzer.md @@ -20,6 +20,8 @@ permission: "*": "deny" skill: "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # ArchitectureAnalyzer diff --git a/.opencode/agent/subagents/planning/contract-manager.md b/.opencode/agent/subagents/planning/contract-manager.md index 653716ed..455f2372 100644 --- a/.opencode/agent/subagents/planning/contract-manager.md +++ b/.opencode/agent/subagents/planning/contract-manager.md @@ -19,6 +19,8 @@ permission: "*": "deny" skill: "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- diff --git a/.opencode/agent/subagents/planning/prioritization-engine.md b/.opencode/agent/subagents/planning/prioritization-engine.md index f3d2999a..ca7ded65 100644 --- a/.opencode/agent/subagents/planning/prioritization-engine.md +++ b/.opencode/agent/subagents/planning/prioritization-engine.md @@ -15,6 +15,8 @@ permission: task: contextscout: "allow" "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # Prioritization Engine diff --git a/.opencode/agent/subagents/planning/story-mapper.md b/.opencode/agent/subagents/planning/story-mapper.md index dd8e380a..520331ba 100644 --- a/.opencode/agent/subagents/planning/story-mapper.md +++ b/.opencode/agent/subagents/planning/story-mapper.md @@ -22,6 +22,8 @@ permission: "*": "deny" skill: "*": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # StoryMapper diff --git a/.opencode/agent/subagents/system-builder/agent-generator.md b/.opencode/agent/subagents/system-builder/agent-generator.md index b4b370e9..6a29cfa3 100644 --- a/.opencode/agent/subagents/system-builder/agent-generator.md +++ b/.opencode/agent/subagents/system-builder/agent-generator.md @@ -7,6 +7,8 @@ name: AgentGenerator description: "Generates XML-optimized agent files (orchestrator and subagents) following research-backed patterns" mode: subagent temperature: 0.1 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Agent Generator diff --git a/.opencode/agent/subagents/system-builder/command-creator.md b/.opencode/agent/subagents/system-builder/command-creator.md index 08f83dbb..04396a34 100644 --- a/.opencode/agent/subagents/system-builder/command-creator.md +++ b/.opencode/agent/subagents/system-builder/command-creator.md @@ -7,6 +7,8 @@ name: CommandCreator description: "Creates custom slash commands that route to appropriate agents with clear syntax and examples" mode: subagent temperature: 0.1 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Command Creator diff --git a/.opencode/agent/subagents/system-builder/context-organizer.md b/.opencode/agent/subagents/system-builder/context-organizer.md index 311c0db0..b2e65bf8 100644 --- a/.opencode/agent/subagents/system-builder/context-organizer.md +++ b/.opencode/agent/subagents/system-builder/context-organizer.md @@ -11,6 +11,8 @@ permission: "**/*.env*": "deny" "**/*.key": "deny" "**/*.secret": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # Context Organizer diff --git a/.opencode/agent/subagents/system-builder/domain-analyzer.md b/.opencode/agent/subagents/system-builder/domain-analyzer.md index b9bd449d..068159df 100644 --- a/.opencode/agent/subagents/system-builder/domain-analyzer.md +++ b/.opencode/agent/subagents/system-builder/domain-analyzer.md @@ -7,6 +7,8 @@ name: DomainAnalyzer description: "Analyzes user domains to identify core concepts, recommended agents, and context structure" mode: subagent temperature: 0.1 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Domain Analyzer diff --git a/.opencode/agent/subagents/system-builder/workflow-designer.md b/.opencode/agent/subagents/system-builder/workflow-designer.md index f664e373..e849ef5d 100644 --- a/.opencode/agent/subagents/system-builder/workflow-designer.md +++ b/.opencode/agent/subagents/system-builder/workflow-designer.md @@ -11,6 +11,8 @@ permission: "**/*.env*": "deny" "**/*.key": "deny" "**/*.secret": "deny" +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir, replace_file_content --- # Workflow Designer diff --git a/.opencode/agent/subagents/test/simple-responder.md b/.opencode/agent/subagents/test/simple-responder.md index 73a4e95f..777b17d7 100644 --- a/.opencode/agent/subagents/test/simple-responder.md +++ b/.opencode/agent/subagents/test/simple-responder.md @@ -7,6 +7,8 @@ name: Simple Responder description: "Test agent that responds with 'AWESOME TESTING' - for eval framework testing" mode: subagent temperature: 0.0 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- # Simple Responder - Test Agent diff --git a/.opencode/agent/subagents/utils/image-specialist.md b/.opencode/agent/subagents/utils/image-specialist.md index c7576dba..a4e1cb2a 100644 --- a/.opencode/agent/subagents/utils/image-specialist.md +++ b/.opencode/agent/subagents/utils/image-specialist.md @@ -7,6 +7,8 @@ name: Image Specialist description: "Specialized agent for image editing and analysis using Gemini AI tools" mode: subagent temperature: 0.2 +model: gemini-3.1-pro +tools: read_file, grep_search, list_dir --- You are an image processing specialist powered by Gemini AI's Nano Banana model. Your capabilities include: diff --git a/.opencode/command/add-context.md b/.opencode/command/add-context.md index 8d779916..9f0775a1 100644 --- a/.opencode/command/add-context.md +++ b/.opencode/command/add-context.md @@ -1,4 +1,5 @@ --- +name: add-context description: Interactive wizard to add project patterns using Project Intelligence standard tags: [context, onboarding, project-intelligence, wizard] dependencies: diff --git a/.opencode/command/build-context-system.md b/.opencode/command/build-context-system.md index bc7a1e6a..1e931d5d 100644 --- a/.opencode/command/build-context-system.md +++ b/.opencode/command/build-context-system.md @@ -1,4 +1,5 @@ --- +name: build-context-system description: "Interactive system builder that creates complete context-aware AI architectures tailored to user domains" --- diff --git a/.opencode/command/clean.md b/.opencode/command/clean.md index 094e59ce..52e6b192 100644 --- a/.opencode/command/clean.md +++ b/.opencode/command/clean.md @@ -1,4 +1,5 @@ --- +name: clean description: Clean the codebase or current working task in focus via Prettier, Import Sorter, ESLint, and TypeScript Compiler --- diff --git a/.opencode/command/commit-openagents.md b/.opencode/command/commit-openagents.md index a00d1a79..a045f6c2 100644 --- a/.opencode/command/commit-openagents.md +++ b/.opencode/command/commit-openagents.md @@ -1,4 +1,5 @@ --- +name: commit-openagents description: Smart commit command for opencode-agents repository with automatic validation and conventional commits --- diff --git a/.opencode/command/commit.md b/.opencode/command/commit.md index 15318ccb..fae6dec7 100644 --- a/.opencode/command/commit.md +++ b/.opencode/command/commit.md @@ -1,4 +1,5 @@ --- +name: commit description: Create well-formatted commits with conventional commit messages and emoji --- diff --git a/.opencode/command/context.md b/.opencode/command/context.md index a3a686ff..871e015a 100644 --- a/.opencode/command/context.md +++ b/.opencode/command/context.md @@ -1,4 +1,5 @@ --- +name: context description: Context system manager - harvest summaries, extract knowledge, organize context tags: - context diff --git a/.opencode/command/openagents/check-context-deps.md b/.opencode/command/openagents/check-context-deps.md index 22046ca1..41330a9d 100644 --- a/.opencode/command/openagents/check-context-deps.md +++ b/.opencode/command/openagents/check-context-deps.md @@ -1,4 +1,5 @@ --- +name: check-context-deps description: Validate context file dependencies across agents and registry tags: - registry diff --git a/.opencode/command/openagents/new-agents/README.md b/.opencode/command/openagents/new-agents/README.md index e46a3ecc..4f40d0a1 100644 --- a/.opencode/command/openagents/new-agents/README.md +++ b/.opencode/command/openagents/new-agents/README.md @@ -1,3 +1,8 @@ +--- +name: README +description: OAC command converted to Antigravity skill +--- + # New Agent Creation System **Research-backed agent creation following Anthropic 2025 best practices** diff --git a/.opencode/command/openagents/new-agents/create-agent.md b/.opencode/command/openagents/new-agents/create-agent.md index 0431fc46..ca81f0a9 100644 --- a/.opencode/command/openagents/new-agents/create-agent.md +++ b/.opencode/command/openagents/new-agents/create-agent.md @@ -1,4 +1,5 @@ --- +name: create-agent description: "Create new OpenCode agents following research-backed best practices (Anthropic 2025)" --- diff --git a/.opencode/command/openagents/new-agents/create-tests.md b/.opencode/command/openagents/new-agents/create-tests.md index 0bd55d04..0fd9300a 100644 --- a/.opencode/command/openagents/new-agents/create-tests.md +++ b/.opencode/command/openagents/new-agents/create-tests.md @@ -1,4 +1,5 @@ --- +name: create-tests description: "Generate comprehensive test suites for OpenCode agents with 8 essential test types" --- diff --git a/.opencode/command/openagents/new-agents/templates/agent-template.md b/.opencode/command/openagents/new-agents/templates/agent-template.md index ea278d15..e5286a98 100644 --- a/.opencode/command/openagents/new-agents/templates/agent-template.md +++ b/.opencode/command/openagents/new-agents/templates/agent-template.md @@ -1,4 +1,5 @@ --- +name: agent-template description: "{one-line purpose of this agent}" mode: primary temperature: 0.1 diff --git a/.opencode/command/openagents/new-agents/templates/context-template.md b/.opencode/command/openagents/new-agents/templates/context-template.md index 8fe55759..f4fc8da7 100644 --- a/.opencode/command/openagents/new-agents/templates/context-template.md +++ b/.opencode/command/openagents/new-agents/templates/context-template.md @@ -1,3 +1,8 @@ +--- +name: context-template +description: OAC command converted to Antigravity skill +--- + # {Agent Name} Context ## Key Commands diff --git a/.opencode/command/optimize.md b/.opencode/command/optimize.md index 911984cb..a9284ed9 100644 --- a/.opencode/command/optimize.md +++ b/.opencode/command/optimize.md @@ -1,4 +1,5 @@ --- +name: optimize description: Analyze and optimize code for performance, security, and potential issues --- diff --git a/.opencode/command/prompt-engineering/prompt-enhancer.md b/.opencode/command/prompt-engineering/prompt-enhancer.md index 03bc7529..ab8a44db 100644 --- a/.opencode/command/prompt-engineering/prompt-enhancer.md +++ b/.opencode/command/prompt-engineering/prompt-enhancer.md @@ -1,4 +1,5 @@ --- +name: prompt-enhancer description: "Research-backed prompt optimizer applying Stanford/Anthropic patterns with model- and task-specific effectiveness improvements" --- diff --git a/.opencode/command/prompt-engineering/prompt-optimizer.md b/.opencode/command/prompt-engineering/prompt-optimizer.md index a6de0a81..cc53781a 100644 --- a/.opencode/command/prompt-engineering/prompt-optimizer.md +++ b/.opencode/command/prompt-engineering/prompt-optimizer.md @@ -1,4 +1,5 @@ --- +name: prompt-optimizer description: "Advanced prompt optimizer: Research patterns + token efficiency + semantic preservation. Achieves 30-50% token reduction with 100% meaning preserved." --- diff --git a/.opencode/command/test-new-command.md b/.opencode/command/test-new-command.md index 7b8efaea..934e0fae 100644 --- a/.opencode/command/test-new-command.md +++ b/.opencode/command/test-new-command.md @@ -1,4 +1,5 @@ --- +name: test-new-command description: "Test command to verify auto-detection and registry updates work correctly" --- diff --git a/.opencode/command/test.md b/.opencode/command/test.md index f72bdf29..19d41ef2 100644 --- a/.opencode/command/test.md +++ b/.opencode/command/test.md @@ -1,4 +1,5 @@ --- +name: test description: Run the complete testing pipeline --- diff --git a/.opencode/command/validate-repo.md b/.opencode/command/validate-repo.md index 189e97fc..63238597 100644 --- a/.opencode/command/validate-repo.md +++ b/.opencode/command/validate-repo.md @@ -1,3 +1,8 @@ +--- +name: validate-repo +description: OAC command converted to Antigravity skill +--- + # Validate Repository Comprehensive validation command that checks the entire OpenAgents Control repository for consistency between CLI, documentation, registry, and components. diff --git a/.opencode/command/worktrees.md b/.opencode/command/worktrees.md index 3430b4ec..9ff45438 100644 --- a/.opencode/command/worktrees.md +++ b/.opencode/command/worktrees.md @@ -1,4 +1,5 @@ --- +name: worktrees description: Manage git worktrees for parallel development workflows --- diff --git a/integrations/antigravity/README.md b/integrations/antigravity/README.md index ba7e4ab1..2d3fcf67 100644 --- a/integrations/antigravity/README.md +++ b/integrations/antigravity/README.md @@ -1,31 +1,34 @@ # OpenAgents Control ↔ Gemini Antigravity CLI Integration -A bridge that allows Gemini Antigravity 2.0 (Antigravity CLI 1.0) to use OpenAgents Control standards, subagents, and context files. +A pristine, high-performance bridge that allows Gemini Antigravity (`gemini` / `agy`) to seamlessly execute OpenAgents Control (OAC) commands, skills, and subagents. -## Overview +--- + +## ⚡ Overview -This integration provides a seamless bridge between OpenAgents Control and Gemini Antigravity CLI (`agy`): +This integration provides a seamless bridge between OpenAgents Control and Google Antigravity: -1. **Auto-Convert**: Compiles OpenAgents Control's agent specifications into Antigravity CLI-native plugins -2. **Global & Local Workspaces**: Deploys plugins globally for all projects or locally under repository workspaces +1. **Zero Redundancy**: Utilizes Git-portable **relative symbolic links** rather than copying files, ensuring that updates to `.opencode/` are instantly and automatically active in Antigravity. +2. **Pristine Backwards-Compatibility**: Automatically injects mandatory Antigravity YAML properties (e.g. `name`, `model`, `tools`) into your original `.opencode/` command and agent markdown files in-place, keeping the repository 100% compatible with both native OpenCode and Antigravity environments. +3. **Dual Global & Local Mapping**: Configures local workspace paths (.agents/) and deploys global plugins to `~/.gemini/` home directory paths simultaneously. -## Directory Structure +--- + +## 📂 Directory Structure ``` integrations/antigravity/ ├── README.md # This guide -├── install-antigravity.sh # Build & installation script (Global & Local) -└── converter/ # Conversion subsystem - ├── package.json # Dependencies - └── src/ - └── convert-agents.js # Node-based compiler and YAML mapper +└── install-antigravity.sh # Bridge installer script (Local & Global) ``` -## Quick Start +--- + +## 🚀 Quick Start -### 1. Compile & Install the Plugin +### 1. Run the Installer -To compile OAC agents and install the plugin to your Antigravity environments, run: +To establish the bridge mappings, run: ```bash cd integrations/antigravity @@ -33,14 +36,14 @@ cd integrations/antigravity ``` This will automatically: -1. Translate `.opencode/agent/*.md` specifications to Antigravity format in `integrations/antigravity/generated/`. -2. Generate the necessary `plugin.json` manifest. -3. Install the plugin globally to `~/.gemini/antigravity-cli/plugins/openagents-control-bridge`. -4. Install the plugin locally to `.agents/plugins/openagents-control-bridge` for workspace-specific runs. +1. Scan your native OAC skills, commands, and subagents. +2. Translate and inject YAML properties into original `.opencode/` markdown files in-place (safely and backwards-compatibly). +3. Establish relative symlinks under `.agents/skills/` and `.agents/agents/`. +4. Deploy the unified OAC bridge plugin globally under `~/.gemini/config/plugins/` and `~/.gemini/antigravity-cli/plugins/` to enable OAC support across *all* project workspaces. -### 2. Verify in Antigravity CLI +### 2. Verify in Antigravity -Start your Antigravity session and verify that the plugin has loaded correctly: +Start an Antigravity session and verify that the plugin has loaded correctly: ```bash # Start your CLI session @@ -55,53 +58,15 @@ You should see `openagents-control-standards` and `context-scout` registered and --- -## How It Works +## 🔮 How It Works ### Context Discovery & Pre-loading - -1. **Skill Triggers**: The `openagents-control-standards` Skill triggers automatically before any development or architectural task. +1. **Skill Triggers**: The `openagents-control-standards` skill triggers automatically before any development or architectural task. 2. **Subagent Invocation**: The skill delegates to `context-scout` to search `.opencode/context/` for relevant conventions, naming standards, and workflows. 3. **Upfront Loading**: Discovered files are read and pre-loaded into the prompt context to keep subsequent task execution fast, consistent, and highly token-efficient. -### Agent Specification Mapping - -The converter translates OAC agent frontmatter properties to Antigravity CLI specifications: - -| OpenAgents Control Field | Gemini Antigravity Field | Notes / Conversions | -|--------------------------|--------------------------|---------------------| -| `id` | `name` | Uniquely names the subagent | -| `description` | `description` | Description used for auto-routing | -| `permissions` | `tools` | Maps `read` ➔ `read_file`, `write` ➔ `write_file`, `edit` ➔ `edit_file`, `bash` ➔ `run_command`, `grep` ➔ `grep_search`, `glob` ➔ `list_dir` | -| `model` | `model` | Translates models to user-approved designations: Grok/Sonnet ➔ `gemini-3.1-pro`, Haiku ➔ `gemini-3.5-flash` | -| `mode: subagent` | `permissionMode: plan` | Restricts executing subagents to planned/approved paths | - ---- - -## Adding Custom Agents & Workflows - -### For Local Workspace Use -Add your customized agent definitions under `.agents/agents/` and skills under `.agents/skills/`. The Antigravity Agent will auto-load them upon starting a session inside the workspace root. - -### For Global Distribution -1. Place the new OAC agent configuration in `.opencode/agent/{category}/{agent}.md`. -2. Run the compiler installer: `./install-antigravity.sh` -3. Your updated agent will instantly be active across all your CLI sessions. - -## Requirements - -- Node.js 18+ -- Gemini Antigravity CLI 1.0+ (with local plugin-loading enabled for repo-level runs) - ---- - -## Command Reference - -| Action | Claude Code CLI | Gemini Antigravity CLI | -|--------|-----------------|------------------------| -| Start interactive run | `claude` | `agy` | -| Browse Active Skills | `/print-plugins` | `/skills` | -| Browse Active Subagents| `/print-plugins` | `/agents` | -| Settings & Config | `~/.claude/settings.json` | `/config` or `/settings` | -| Keybindings Map | `/keybindings` | `/keybindings` | -| Directory Search | `/glob` / `/grep` | `@` (autocomplete) or `/skills` search | -| Run single bash command| `!command` | `!command` | +### In-Place Agent Frontmatter Mapping +The setup utility dynamically translates OAC agent specifications to Antigravity configurations: +- **`name`**: Map names directly. +- **`model`**: Defaults to `gemini-3.1-pro` for high-performance agentic coding. +- **`tools`**: Intelligently infers necessary tools (e.g., `run_command`, `replace_file_content`, `write_to_file`, `read_file`, `grep_search`, `list_dir`) by parsing the OAC permission structures in-place. diff --git a/integrations/antigravity/converter/package.json b/integrations/antigravity/converter/package.json deleted file mode 100644 index f705a5a0..00000000 --- a/integrations/antigravity/converter/package.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "name": "oac-antigravity-converter", - "version": "1.0.0", - "description": "Converts OpenAgents Control agents and skills to Antigravity CLI format", - "main": "src/convert-agents.js", - "scripts": { - "convert": "node src/convert-agents.js" - }, - "author": "Antigravity", - "license": "MIT" -} diff --git a/integrations/antigravity/converter/src/convert-agents.js b/integrations/antigravity/converter/src/convert-agents.js deleted file mode 100644 index 80a3dccf..00000000 --- a/integrations/antigravity/converter/src/convert-agents.js +++ /dev/null @@ -1,307 +0,0 @@ -#!/usr/bin/env node - -/** - * convert-agents.js - * Converts OpenAgents Control to Gemini Antigravity CLI format - * - * Usage: node convert-agents.js - */ - -const fs = require('fs'); -const path = require('path'); - -// Configuration - Use absolute paths from the script location -const SCRIPT_DIR = __dirname; -const REPO_ROOT = path.resolve(path.join(SCRIPT_DIR, '../../../../')); -const SOURCE_DIR = path.join(REPO_ROOT, '.opencode/agent'); -const OUTPUT_DIR = path.join(SCRIPT_DIR, '../generated'); - -const ANTIGRAVITY_AGENTS_DIR = path.join(OUTPUT_DIR, 'agents'); -const ANTIGRAVITY_SKILLS_DIR = path.join(OUTPUT_DIR, 'skills'); - -console.log('🚀 OpenAgents Control → Gemini Antigravity CLI Converter'); -console.log(` Source: ${SOURCE_DIR}`); -console.log(` Output: ${OUTPUT_DIR}\n`); - -/** - * Parses YAML frontmatter from markdown - */ -function parseFrontmatter(content) { - const match = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/); - if (!match) return { frontmatter: null, content }; - - const yaml = match[1]; - const body = match[2]; - - const frontmatter = {}; - yaml.split('\n').forEach(line => { - const colonIndex = line.indexOf(':'); - if (colonIndex > -1) { - const key = line.slice(0, colonIndex).trim(); - let value = line.slice(colonIndex + 1).trim(); - - // Parse arrays - if (value.startsWith('[') && value.endsWith(']')) { - value = value.slice(1, -1).split(',').map(v => v.trim().replace(/"/g, '')); - } - - frontmatter[key] = value; - } - }); - - return { frontmatter, body }; -} - -/** - * Converts OpenCode frontmatter to Antigravity format - */ -function convertFrontmatter(ocFrontmatter) { - const antigravity = {}; - - // Map OpenCode fields to Antigravity fields - antigravity.name = ocFrontmatter.id || ocFrontmatter.name; - antigravity.description = ocFrontmatter.description; - - // Map tools from OpenCode permissions to Antigravity tools - if (ocFrontmatter.tools) { - antigravity.tools = ocFrontmatter.tools; - } else if (ocFrontmatter.permissions || ocFrontmatter.permission) { - const perm = ocFrontmatter.permissions || ocFrontmatter.permission; - const tools = []; - if (perm.read) tools.push('read_file'); - if (perm.grep) tools.push('grep_search'); - if (perm.glob) tools.push('list_dir'); - if (perm.edit) tools.push('edit_file'); - if (perm.write) tools.push('write_file'); - if (perm.bash) tools.push('run_command'); - - // Default fallback if no permissions explicitly matched but has some permission key - if (tools.length === 0) { - tools.push('read_file', 'grep_search', 'list_dir'); - } - - antigravity.tools = tools.join(', '); - } else { - // Default safe tool permissions - antigravity.tools = 'read_file, grep_search, list_dir'; - } - - // Map model to user-specified models - antigravity.model = mapModel(ocFrontmatter.model); - - // Map permissionMode (default to 'default' if not specified) - antigravity.permissionMode = ocFrontmatter.mode === 'subagent' ? 'plan' : 'default'; - - return antigravity; -} - -/** - * Maps OpenCode model names to Gemini model aliases for Antigravity - */ -function mapModel(model) { - const modelMap = { - 'opencode/grok-code': 'gemini-3.1-pro', - 'opencode/grok': 'gemini-3.1-pro', - 'gpt-4': 'gemini-3.1-pro', - 'gpt-4o': 'gemini-3.1-pro', - 'sonnet': 'gemini-3.1-pro', - 'haiku': 'gemini-3.5-flash', - }; - return modelMap[model] || 'gemini-3.1-pro'; -} - -/** - * Generates Antigravity markdown from converted data - */ -function generateAntigravityMarkdown(antigravityFrontmatter, body) { - const fm = Object.entries(antigravityFrontmatter) - .map(([key, value]) => { - if (Array.isArray(value)) { - return `${key}: [${value.map(v => `"${v}"`).join(', ')}]`; - } - let strVal = String(value); - if (strVal.startsWith('"') && strVal.endsWith('"')) { - strVal = strVal.slice(1, -1); - } - return `${key}: "${strVal}"`; - }) - .join('\n'); - - return `---\n${fm}\n---\n\n${body}`; -} - -/** - * Recursively finds all .md files in a directory - */ -function findMarkdownFiles(dir, files = []) { - if (!fs.existsSync(dir)) return files; - const entries = fs.readdirSync(dir, { withFileTypes: true }); - - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - findMarkdownFiles(fullPath, files); - } else if (entry.name.endsWith('.md')) { - files.push(fullPath); - } - } - - return files; -} - -/** - * Processes a single agent file - */ -function processAgent(filePath) { - const content = fs.readFileSync(filePath, 'utf8'); - const { frontmatter, body } = parseFrontmatter(content); - - if (!frontmatter) { - console.log(`⚠️ Skipping ${filePath} (no frontmatter)`); - return; - } - - const antigravityFrontmatter = convertFrontmatter(frontmatter); - const antigravityMarkdown = generateAntigravityMarkdown(antigravityFrontmatter, body); - - // Determine output path (FLATTENED to level 1 for discovery) - const filename = path.basename(filePath); - const outputPath = path.join(ANTIGRAVITY_AGENTS_DIR, filename); - - // Ensure output directory exists - fs.mkdirSync(path.dirname(outputPath), { recursive: true }); - - fs.writeFileSync(outputPath, antigravityMarkdown); - console.log(`✅ Converted agent: ${filename}`); -} - -/** - * Processes and copies a skill folder - */ -function processSkill(skillMdPath) { - const skillDir = path.dirname(skillMdPath); - const skillFolderName = path.basename(skillDir); - - const outputSkillDir = path.join(ANTIGRAVITY_SKILLS_DIR, skillFolderName); - fs.mkdirSync(outputSkillDir, { recursive: true }); - - // Copy all files in the skill directory - const files = fs.readdirSync(skillDir); - files.forEach(file => { - const srcPath = path.join(skillDir, file); - const destPath = path.join(outputSkillDir, file); - if (fs.statSync(srcPath).isFile()) { - fs.copyFileSync(srcPath, destPath); - } - }); - - console.log(`✅ Processed skill: ${skillFolderName}`); -} - -/** - * Main conversion function - */ -function convert() { - // Clean output directory - if (fs.existsSync(OUTPUT_DIR)) fs.rmSync(OUTPUT_DIR, { recursive: true }); - - fs.mkdirSync(ANTIGRAVITY_AGENTS_DIR, { recursive: true }); - fs.mkdirSync(ANTIGRAVITY_SKILLS_DIR, { recursive: true }); - - // Create plugin.json at the plugin root - const pluginJson = { - name: "openagents-control-bridge" - }; - fs.writeFileSync( - path.join(OUTPUT_DIR, 'plugin.json'), - JSON.stringify(pluginJson, null, 2) - ); - console.log('📦 Created plugin.json manifest'); - - console.log('📦 Converting agents...\n'); - - // Process category agents - const agentFiles = findMarkdownFiles(SOURCE_DIR); - agentFiles.forEach(processAgent); - - // Create default context-scout subagent - const contextScoutContent = `--- -name: context-scout -description: Discovers and recommends OpenAgents Control context files using list_dir, read_file, and grep_search tools. Use when you need to find OpenAgents Control standards, guides, or domain knowledge in the .opencode/context directory. -tools: read_file, grep_search, list_dir -model: gemini-3.5-flash -permissionMode: plan ---- - -# ContextScout - -You discover and recommend relevant OpenAgents Control context files from \`.opencode/context/\` based on the user's request. - -## Your Process - -1. Use \`list_dir\` or custom glob tools to find files in \`.opencode/context/\`. -2. Use \`read_file\` or \`grep_search\` to verify relevance. -3. Return file paths with brief descriptions. -`; - - fs.writeFileSync( - path.join(ANTIGRAVITY_AGENTS_DIR, 'context-scout.md'), - contextScoutContent - ); - console.log('✅ Created context-scout subagent'); - - console.log('\n📦 Processing skills...\n'); - - // Find all skill files in .opencode/skills/ and .opencode/skill/ - const skillsDir1 = path.join(REPO_ROOT, '.opencode/skills'); - const skillsDir2 = path.join(REPO_ROOT, '.opencode/skill'); - - const skillFiles = []; - - function findSkillMdFiles(dir) { - if (!fs.existsSync(dir)) return; - const entries = fs.readdirSync(dir, { withFileTypes: true }); - for (const entry of entries) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - findSkillMdFiles(fullPath); - } else if (entry.name === 'SKILL.md') { - skillFiles.push(fullPath); - } - } - } - - findSkillMdFiles(skillsDir1); - findSkillMdFiles(skillsDir2); - - skillFiles.forEach(processSkill); - - // Create default openagents-control-standards skill - const skillContent = `--- -name: openagents-control-standards -description: Automatically triggers before any task to ensure OpenAgents Control standards and context are loaded. Use when the user asks to create, modify, or analyze anything in this repository. ---- - -# OpenAgents Control Standards Loader - -Before proceeding with the user's request: - -1. Call the \`context-scout\` subagent with the user's request to find relevant OpenAgents Control context files. -2. Read the returned "Critical" and "High" priority files using \`read_file\`. -3. Apply the OpenAgents Control standards found to your work. -`; - - const stdSkillDir = path.join(ANTIGRAVITY_SKILLS_DIR, 'openagents-control-standards'); - fs.mkdirSync(stdSkillDir, { recursive: true }); - fs.writeFileSync( - path.join(stdSkillDir, 'SKILL.md'), - skillContent - ); - console.log('✅ Created openagents-control-standards skill'); - - console.log('\n✨ Conversion complete!'); - console.log(` Output: ${OUTPUT_DIR}`); -} - -// Run conversion -convert(); diff --git a/integrations/antigravity/install-antigravity.sh b/integrations/antigravity/install-antigravity.sh index 1c82d61f..113c5c42 100755 --- a/integrations/antigravity/install-antigravity.sh +++ b/integrations/antigravity/install-antigravity.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # # install-antigravity.sh -# Installs OpenAgents Control to Gemini Antigravity CLI with automatic conversion +# Installs OpenAgents Control to Gemini Antigravity CLI with automatic relative symlink mapping # set -euo pipefail @@ -15,127 +15,51 @@ NC='\033[0m' # No Color # Determine paths SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" REPO_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" -OPENCODE_DIR="$REPO_ROOT/.opencode/agent" -CONVERTER_DIR="$SCRIPT_DIR/converter" -PLUGIN_DEST="$HOME/.gemini/antigravity-cli/plugins/openagents-control-bridge" -LOCAL_PLUGIN_DEST="$REPO_ROOT/.agents/plugins/openagents-control-bridge" NODE_BIN="${NODE_BIN:-node}" echo -e "${GREEN}🚀 OpenAgents Control → Gemini Antigravity CLI Installer${NC}" -echo -e " Source: $OPENCODE_DIR" -echo -e " Global Destination: $PLUGIN_DEST" -echo -e " Local Workspace Destination: $LOCAL_PLUGIN_DEST" +echo -e " Workspace Root: $REPO_ROOT" echo "" # Check prerequisites -check_prereqs() { - local missing=() - - # Check for node - if ! command -v "$NODE_BIN" >/dev/null 2>&1; then - missing+=("$NODE_BIN") - fi - - # Check for bash - if ! command -v bash >/dev/null 2>&1; then - missing+=("bash") - fi - - if [ ${#missing[@]} -gt 0 ]; then - echo -e "${RED}✗ Missing required commands: ${missing[*]}${NC}" >&2 - echo -e " Install Node.js: https://nodejs.org/" >&2 - exit 1 - fi -} - -# Run converter -run_converter() { - echo -e "${YELLOW}🔄 Converting agents to Antigravity format...${NC}" - cd "$CONVERTER_DIR" - - if ! "$NODE_BIN" src/convert-agents.js 2>&1 | grep -q "Conversion complete"; then - echo -e "${RED}✗ Conversion failed${NC}" >&2 - exit 1 - fi - - echo -e "${GREEN}✅ Conversion complete${NC}" -} - -# Install plugin -install_plugin() { - # 1. Global Installation (antigravity-cli) - echo -e "${YELLOW}📦 Installing global CLI plugin...${NC}" - mkdir -p "$HOME/.gemini/antigravity-cli/plugins" - - if [ -d "$PLUGIN_DEST" ]; then - echo "🗑️ Removing old global CLI installation..." - rm -rf "$PLUGIN_DEST" - fi - - cp -r "$CONVERTER_DIR/generated" "$PLUGIN_DEST" - echo -e "${GREEN}✅ Global CLI installation complete${NC}" - - # 2. Global Configuration Plugins (Desktop & CLI Auto-Load) - echo -e "${YELLOW}📦 Installing global config plugin...${NC}" - local config_plugin_dest="/Users/benpriebe/.gemini/config/plugins/openagents-control-bridge" - mkdir -p "/Users/benpriebe/.gemini/config/plugins" - if [ -d "$config_plugin_dest" ]; then - rm -rf "$config_plugin_dest" - fi - cp -r "$CONVERTER_DIR/generated" "$config_plugin_dest" - echo -e "${GREEN}✅ Global config installation complete${NC}" - - # 3. Local/Workspace Installation (.agents/plugins) - echo -e "${YELLOW}📦 Installing workspace plugin...${NC}" - mkdir -p "$REPO_ROOT/.agents/plugins" - - if [ -d "$LOCAL_PLUGIN_DEST" ]; then - echo "🗑️ Removing old workspace installation..." - rm -rf "$LOCAL_PLUGIN_DEST" - fi - - cp -r "$CONVERTER_DIR/generated" "$LOCAL_PLUGIN_DEST" - echo -e "${GREEN}✅ Workspace installation complete${NC}" - - # 4. Standard Workspace Paths (.agents/skills and .agents/agents) - echo -e "${YELLOW}📦 Installing to standard workspace paths (.agents/skills/ and .agents/agents/)...${NC}" - mkdir -p "$REPO_ROOT/.agents/skills" - mkdir -p "$REPO_ROOT/.agents/agents" - - # Clean old workspace skills/agents directories - rm -rf "$REPO_ROOT/.agents/skills"/* - rm -rf "$REPO_ROOT/.agents/agents"/* - - cp -r "$CONVERTER_DIR/generated/skills"/* "$REPO_ROOT/.agents/skills/" - cp -r "$CONVERTER_DIR/generated/agents"/* "$REPO_ROOT/.agents/agents/" - echo -e "${GREEN}✅ Standard workspace paths installation complete${NC}" -} - -# Verify installation -verify() { - if [ ! -f "$PLUGIN_DEST/agents/openagent.md" ]; then - echo -e "${RED}✗ Installation verification failed${NC}" >&2 - echo " Expected: $PLUGIN_DEST/agents/openagent.md" >&2 - exit 1 - fi - - echo "" - echo -e "${GREEN}✨ Installation successful!${NC}" - echo "" - echo "To use with Gemini Antigravity CLI:" - echo " - View active skills using the: /skills command" - echo " - View active subagents using the: /agents command" - echo "" - echo "Your OAC plug-in is loaded and ready to trigger on your next task!" -} - -# Main workflow -main() { - check_prereqs - run_converter - install_plugin - verify -} - -# Allow specifying custom Node.js binary via NODE_BIN environment variable -main "$@" +if ! command -v "$NODE_BIN" >/dev/null 2>&1; then + echo -e "${RED}✗ Missing required command: node${NC}" >&2 + echo -e " Please install Node.js: https://nodejs.org/" >&2 + exit 1 +fi + +# 1. Run local bridge setup +echo -e "${YELLOW}🔄 Configuring local Antigravity Bridge...${NC}" +if ! "$NODE_BIN" "$REPO_ROOT/scripts/setup-gemini-bridge.js"; then + echo -e "${RED}✗ Bridge configuration failed${NC}" >&2 + exit 1 +fi + +# Define global plugin locations +GLOBAL_CLI_DEST="$HOME/.gemini/antigravity-cli/plugins/openagents-control-bridge" +GLOBAL_CONFIG_DEST="$HOME/.gemini/config/plugins/openagents-control-bridge" +LOCAL_PLUGIN_SRC="$REPO_ROOT/.agents/plugins/openagents-control-bridge" + +# 2. Install global plugins (optional fallback/global access) +echo -e "\n${YELLOW}📦 Installing global plugins...${NC}" + +# Global CLI Destination +mkdir -p "$HOME/.gemini/antigravity-cli/plugins" +if [ -d "$GLOBAL_CLI_DEST" ] || [ -L "$GLOBAL_CLI_DEST" ]; then + rm -rf "$GLOBAL_CLI_DEST" +fi +cp -R "$LOCAL_PLUGIN_SRC" "$GLOBAL_CLI_DEST" +echo -e " ✓ Installed global CLI plugin ──► $GLOBAL_CLI_DEST" + +# Global Config Destination +mkdir -p "$HOME/.gemini/config/plugins" +if [ -d "$GLOBAL_CONFIG_DEST" ] || [ -L "$GLOBAL_CONFIG_DEST" ]; then + rm -rf "$GLOBAL_CONFIG_DEST" +fi +cp -R "$LOCAL_PLUGIN_SRC" "$GLOBAL_CONFIG_DEST" +echo -e " ✓ Installed global config plugin ──► $GLOBAL_CONFIG_DEST" + +echo -e "\n${GREEN}✨ Antigravity Integration Successful!${NC}" +echo -e "✓ The original .opencode/ folder structure remains pristine." +echo -e "✓ All local workspace mappings use portable, relative symlinks." +echo -e "✓ Ready for both OpenCode and Google Antigravity!" diff --git a/scripts/setup-gemini-bridge.js b/scripts/setup-gemini-bridge.js new file mode 100644 index 00000000..a4359299 --- /dev/null +++ b/scripts/setup-gemini-bridge.js @@ -0,0 +1,287 @@ +#!/usr/bin/env node +'use strict'; + +const fs = require('fs'); +const path = require('path'); + +// Dynamically resolve the project root relative to the script location (scripts/setup-gemini-bridge.js) +const projectRoot = path.join(__dirname, '..'); +const opencodeDir = path.join(projectRoot, '.opencode'); + +if (!fs.existsSync(opencodeDir)) { + console.error('❌ Error: This does not appear to be an OpenCode project (no .opencode directory found).'); + process.exit(1); +} + +const agentsDir = path.join(projectRoot, '.agents'); +const agentsSkillsDir = path.join(agentsDir, 'skills'); +const agentsAgentsDir = path.join(agentsDir, 'agents'); +const pluginDir = path.join(agentsDir, 'plugins', 'openagents-control-bridge'); + +console.log('🔗 Setting up OpenAgents Control (OAC) to Antigravity Bridge...'); + +// Helper: Ensure directory exists +function ensureDir(dir) { + if (!fs.existsSync(dir)) { + fs.mkdirSync(dir, { recursive: true }); + } +} + +// Helper: Remove directory/file/symlink recursively +function cleanTarget(targetPath) { + if (fs.existsSync(targetPath)) { + const stat = fs.lstatSync(targetPath); + if (stat.isSymbolicLink()) { + fs.unlinkSync(targetPath); + } else if (stat.isDirectory()) { + fs.rmSync(targetPath, { recursive: true, force: true }); + } else { + fs.unlinkSync(targetPath); + } + } else { + // If it is a broken symlink, fs.existsSync returns false but we still need to delete it + try { + const stat = fs.lstatSync(targetPath); + if (stat.isSymbolicLink()) { + fs.unlinkSync(targetPath); + } + } catch (e) { + // Ignore errors for non-existent targets + } + } +} + +// Clean and recreate main directories +cleanTarget(agentsSkillsDir); +cleanTarget(agentsAgentsDir); +cleanTarget(path.join(agentsDir, 'plugins')); + +ensureDir(agentsSkillsDir); +ensureDir(agentsAgentsDir); +ensureDir(pluginDir); + +// ============================================================================ +// 1. Bridge Skills (.opencode/skills/ and .opencode/skill/ -> .agents/skills/) +// ============================================================================ +console.log('\n🔮 Bridging OAC Skills...'); +const opencodeSkillsDirs = [ + path.join(opencodeDir, 'skills'), + path.join(opencodeDir, 'skill') +]; + +opencodeSkillsDirs.forEach(srcSkillsDir => { + if (!fs.existsSync(srcSkillsDir)) return; + + const skills = fs.readdirSync(srcSkillsDir); + skills.forEach(skillName => { + const srcPath = path.join(srcSkillsDir, skillName); + const stat = fs.statSync(srcPath); + if (!stat.isDirectory()) return; + + const destPath = path.join(agentsSkillsDir, skillName); + + // Clean old bridge entry if it exists + cleanTarget(destPath); + + // Create relative symlink for clean git-sharing + const relPath = path.relative(path.dirname(destPath), srcPath); + fs.symlinkSync(relPath, destPath, 'dir'); + console.log(` ✓ Skill: ${skillName} ──► .agents/skills/${skillName}`); + }); +}); + +// ============================================================================ +// 2. Bridge Commands (.opencode/command/ -> .agents/skills/) +// ============================================================================ +console.log('\n⚡ Bridging OAC Commands (as Antigravity Skills)...'); +const srcCommandsDir = path.join(opencodeDir, 'command'); + +if (fs.existsSync(srcCommandsDir)) { + function scanCommands(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const resPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + scanCommands(resPath); + } else if (entry.isFile() && entry.name.endsWith('.md')) { + const commandName = path.basename(entry.name, '.md'); + const destSkillDir = path.join(agentsSkillsDir, commandName); + const destSkillFile = path.join(destSkillDir, 'SKILL.md'); + + cleanTarget(destSkillDir); + ensureDir(destSkillDir); + + // Read the command file to check/inject YAML name parameter + let content = fs.readFileSync(resPath, 'utf8'); + const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/; + const match = content.match(frontmatterRegex); + + if (match) { + const yamlBlock = match[1]; + if (!yamlBlock.includes('name:')) { + const updatedYaml = `name: ${commandName}\n${yamlBlock}`; + content = content.replace(frontmatterRegex, `---\n${updatedYaml}\n---`); + fs.writeFileSync(resPath, content, 'utf8'); + console.log(` ✓ Added 'name: ${commandName}' frontmatter to original command ${entry.name}`); + } + } else { + content = `---\nname: ${commandName}\ndescription: OAC command converted to Antigravity skill\n---\n\n${content}`; + fs.writeFileSync(resPath, content, 'utf8'); + console.log(` ✓ Added default frontmatter to original command ${entry.name}`); + } + + // Create symlink from command markdown file to SKILL.md + const relPath = path.relative(path.dirname(destSkillFile), resPath); + fs.symlinkSync(relPath, destSkillFile, 'file'); + console.log(` ✓ Command: ${commandName} ──► .agents/skills/${commandName}/SKILL.md`); + } + } + } + + scanCommands(srcCommandsDir); +} + +// ============================================================================ +// 3. Bridge Agents (.opencode/agent/ -> .agents/agents/) +// ============================================================================ +console.log('\n🤖 Bridging OAC Custom Agents...'); +const srcAgentsDir = path.join(opencodeDir, 'agent'); + +if (fs.existsSync(srcAgentsDir)) { + function scanAgents(dir) { + const entries = fs.readdirSync(dir, { withFileTypes: true }); + for (const entry of entries) { + const resPath = path.join(dir, entry.name); + if (entry.isDirectory()) { + scanAgents(resPath); + } else if (entry.isFile() && entry.name.endsWith('.md')) { + const agentName = path.basename(entry.name, '.md'); + const destAgentFile = path.join(agentsAgentsDir, entry.name); + + // Read file and parse/update frontmatter in-place + let content = fs.readFileSync(resPath, 'utf8'); + const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/; + const match = content.match(frontmatterRegex); + + if (match) { + const yamlBlock = match[1]; + let updatedYaml = yamlBlock; + + if (!yamlBlock.includes('name:')) { + updatedYaml = `name: ${agentName}\n${updatedYaml}`; + } + if (!yamlBlock.includes('model:')) { + updatedYaml = `${updatedYaml}\nmodel: gemini-3.1-pro`; + } + if (!yamlBlock.includes('tools:')) { + const tools = ['read_file', 'grep_search', 'list_dir']; + const hasBash = yamlBlock.includes('bash:') && !yamlBlock.includes('bash:\n "*": "deny"') && !yamlBlock.includes('bash:\r\n "*": "deny"'); + const hasEdit = yamlBlock.includes('edit:') && !yamlBlock.includes('edit:\n "*": "deny"') && !yamlBlock.includes('edit:\r\n "*": "deny"'); + const hasWrite = yamlBlock.includes('write:') && !yamlBlock.includes('write:\n "*": "deny"') && !yamlBlock.includes('write:\r\n "*": "deny"'); + + if (hasBash) tools.push('run_command'); + if (hasEdit) tools.push('replace_file_content'); + if (hasWrite) tools.push('write_to_file'); + + updatedYaml = `${updatedYaml}\ntools: ${tools.join(', ')}`; + } + + if (updatedYaml !== yamlBlock) { + content = content.replace(frontmatterRegex, `---\n${updatedYaml}\n---`); + fs.writeFileSync(resPath, content, 'utf8'); + console.log(` ✓ Updated frontmatter in original agent ${entry.name}`); + } + } + + // Clean old bridge entry + cleanTarget(destAgentFile); + + // Create symlink + const relPath = path.relative(path.dirname(destAgentFile), resPath); + fs.symlinkSync(relPath, destAgentFile, 'file'); + console.log(` ✓ Agent: ${entry.name} ──► .agents/agents/${entry.name}`); + } + } + } + + scanAgents(srcAgentsDir); +} + +// ============================================================================ +// 4. Inject Custom Antigravity Skills & Agents +// ============================================================================ +console.log('\n🌟 Creating Antigravity-specific Helpers...'); + +// 4a. context-scout subagent +const contextScoutPath = path.join(agentsAgentsDir, 'context-scout.md'); +const contextScoutContent = `--- +name: context-scout +description: Discovers and recommends OpenAgents Control context files using list_dir, read_file, and grep_search tools. Use when you need to find OpenAgents Control standards, guides, or domain knowledge in the .opencode/context directory. +tools: read_file, grep_search, list_dir +model: gemini-3.5-flash +permissionMode: plan +--- + +# ContextScout + +You discover and recommend relevant OpenAgents Control context files from \`.opencode/context/\` based on the user's request. + +## Your Process + +1. Use \`list_dir\` or custom glob tools to find files in \`.opencode/context/\`. +2. Use \`read_file\` or \`grep_search\` to verify relevance. +3. Return file paths with brief descriptions. +`; +fs.writeFileSync(contextScoutPath, contextScoutContent, 'utf8'); +console.log(` ✓ Created context-scout subagent ──► .agents/agents/context-scout.md`); + +// 4b. openagents-control-standards skill +const stdSkillDir = path.join(agentsSkillsDir, 'openagents-control-standards'); +ensureDir(stdSkillDir); +const stdSkillPath = path.join(stdSkillDir, 'SKILL.md'); +const stdSkillContent = `--- +name: openagents-control-standards +description: Automatically triggers before any task to ensure OpenAgents Control standards and context are loaded. Use when the user asks to create, modify, or analyze anything in this repository. +--- + +# OpenAgents Control Standards Loader + +Before proceeding with the user's request: + +1. Call the \`context-scout\` subagent with the user's request to find relevant OpenAgents Control context files. +2. Read the returned "Critical" and "High" priority files using \`read_file\`. +3. Apply the OpenAgents Control standards found to your work. +`; +fs.writeFileSync(stdSkillPath, stdSkillContent, 'utf8'); +console.log(` ✓ Created openagents-control-standards skill ──► .agents/skills/openagents-control-standards/SKILL.md`); + +// ============================================================================ +// 5. Structure the Plugin using Relative Symlinks +// ============================================================================ +console.log('\n🔌 Configuring the Workspace Plugin...'); + +// plugin.json +const pluginJsonPath = path.join(pluginDir, 'plugin.json'); +fs.writeFileSync( + pluginJsonPath, + JSON.stringify({ name: 'openagents-control-bridge' }, null, 2), + 'utf8' +); +console.log(` ✓ Created plugin.json manifest`); + +// Symlink skills +const pluginSkillsLink = path.join(pluginDir, 'skills'); +cleanTarget(pluginSkillsLink); +fs.symlinkSync(path.relative(path.dirname(pluginSkillsLink), agentsSkillsDir), pluginSkillsLink, 'dir'); +console.log(` ✓ Symlinked plugin skills ──► .agents/plugins/openagents-control-bridge/skills`); + +// Symlink agents +const pluginAgentsLink = path.join(pluginDir, 'agents'); +cleanTarget(pluginAgentsLink); +fs.symlinkSync(path.relative(path.dirname(pluginAgentsLink), agentsAgentsDir), pluginAgentsLink, 'dir'); +console.log(` ✓ Symlinked plugin agents ──► .agents/plugins/openagents-control-bridge/agents`); + +console.log('\n🎉 OAC-to-Antigravity Bridge created successfully!'); +console.log('✓ All changes are reference-based (via relative symlinks).'); +console.log('✓ The original .opencode/ folder structure remains pristine.'); +console.log('✓ Ready for both OpenCode and Google Antigravity!');