/** * opencode-setup.mjs — OpenCode skill documenting the full system architecture * * PURPOSE: * Documents the complete OpenCode setup including providers, services, * skills, and configuration. New sessions can load this skill to understand * the entire system without rediscovering everything. * * SYSTEM OVERVIEW: * Host: memgpt (kenny@memgpt) * OS: Linux * OpenCode: v1.14.33 * * PROVIDERS: * 1. OpenCode Zen — https://opencode.ai/zen/v1 * Models: GPT-5.4, GPT-5.3-codex, GPT-5-nano, GLM-5, Big Pickle, * MiniMax M2.7, Kimi K2.5 * * 2. XiaomiMimo (SGP) — https://token-plan-sgp.xiaomimimo.com/v1 * Models: Mimo V2.5, Mimo V2.5 Pro, Mimo V2 Omni, Mimo V2 Pro * * 3. Claude Code (proxy) — http://localhost:3000/v1 * Models: Claude Opus 4.7, Claude Sonnet 4.6, Claude Haiku 4.5 * Proxy script: ~/.config/opencode/claude-proxy.mjs * Uses: claude -p CLI with --permission-mode bypassPermissions * * 4. CanopyWave — https://inference.canopywave.io/v1 * Models: DeepSeek V4 Flash, DeepSeek V3.2, GLM-5, Kimi K2.6, etc. * * 5. DeepInfra — https://api.deepinfra.com/v1 * Models: DeepSeek, Gemini, Llama, Qwen, GLM, Kimi, MiniMax, etc. * * 6. Ollama (remote) — http://llm01:11434/v1 * Models: Gemma 4 31B, Qwen 3.6 * * SERVICES (systemd user services): * 1. opencode-serve.service — Main OpenCode server (port 4096) * ExecStart: ~/.config/opencode/opencode-start.sh * Supports: --omoa flag for oh-my-openagent injection * * 2. opencode-telegram-bot.service — Telegram bot client * Bot: @twentyninehairs_opencode_mem_bot * Config: ~/.config/opencode-telegram-bot/.env * Connects to: http://localhost:4096 * * 3. claude-proxy.service — Proxy for Claude models * Port: 3000 * Script: ~/.config/opencode/claude-proxy.mjs * Uses: /home/kenny/.local/bin/claude -p * * SKILLS: * 1. nextcloud — File operations with nc.hibbhome.com * Scripts: ~/.config/opencode/skills/nextcloud.sh, nextcloud.mjs * * 2. omoa-toggle — Toggle oh-my-openagent plugin * Script: ~/.config/opencode/skills/omoa-toggle.mjs * CLI: ~/.config/opencode/omoa * * 3. git-ops — Git operations with Hibbhome Gitea server * Script: ~/.config/opencode/skills/git-ops.mjs * * 4. opencode-setup — This skill (system documentation) * * CONFIGURATION: * Main config: ~/.config/opencode/opencode.json * Skills dir: ~/.config/opencode/skills/ * Claude proxy: ~/.config/opencode/claude-proxy.mjs * Telegram bot config: ~/.config/opencode-telegram-bot/.env * * GIT SERVER: * API: https://git.hibbhome.com * SSH: git@wwwdb.dmz.home.hibbhome.com * API key: fc4332a8a1a87b1f8cbcc01668ed94803dcd3a81 * Organization: Hibbhome * * SSH KEYS: * Gitea: ~/.ssh/id_gitea (ed25519) * Added to Gitea server for passwordless push * * NEXTCLOUD: * URL: https://nc.hibbhome.com * User: opencode_memgpt * Password: ioH2o-QnQJx-8z7Dx-edPyx-pmxLA * * OH-MY-OPENAGENT: * State file: ~/.config/opencode/omoa-enabled * Toggle: omoa [on|off|status|toggle] * Post-upgrade: omoa-post-upgrade.sh * Uses OPENCODE_CONFIG_CONTENT for runtime injection * * TELEGRAM BOT: * Bot username: @twentyninehairs_opencode_mem_bot * User ID: 5274535598 * Commands: /commands → omoa_toggle, /commands → nextcloud_*, etc. * * REPLICATING TO NEW SYSTEM: * 1. Install OpenCode: https://opencode.ai * 2. Clone this repo: git clone git@wwwdb.dmz.home.hibbhome.com:Hibbhome/opencode-omoa-toggle.git * 3. Copy config files to ~/.config/opencode/ * 4. Install npm packages: cd ~/.config/opencode && npm install * 5. Set up systemd services (see systemd service files) * 6. Configure Telegram bot (see opencode-telegram-bot/.env) * 7. Add SSH keys to Gitea * * CREATED: 2026-05-03 */ import { tool } from "@opencode-ai/plugin/tool"; import { execSync } from "node:child_process"; import { readFileSync } from "node:fs"; export const OpenCodeSetupPlugin = async (_ctx) => { return { tool: { /** * Show system status */ setup_status: tool({ description: "Show OpenCode system status (services, providers, skills)", args: {}, async execute() { try { const services = execSync("systemctl --user status opencode-serve.service opencode-telegram-bot.service claude-proxy.service 2>&1 | grep -E 'Active|Main'", { encoding: "utf-8" }); return `SERVICES:\n${services}\n\nUse skill("opencode-setup") for full documentation.`; } catch (err) { return `Error: ${err.message}`; } }, }), /** * Show provider configuration */ setup_providers: tool({ description: "Show configured providers and models", args: {}, async execute() { try { const config = JSON.parse(readFileSync("/home/kenny/.config/opencode/opencode.json", "utf-8")); const providers = Object.entries(config.provider || {}).map(([name, p]) => { const models = Object.keys(p.models || {}).join(", "); return `- ${name}: ${p.options?.baseURL || 'N/A'}\n Models: ${models}`; }).join("\n"); return `PROVIDERS:\n${providers}`; } catch (err) { return `Error: ${err.message}`; } }, }), /** * Show installed skills */ setup_skills: tool({ description: "Show installed skills", args: {}, async execute() { try { const config = JSON.parse(readFileSync("/home/kenny/.config/opencode/opencode.json", "utf-8")); const skills = Object.entries(config.skills || {}).map(([name, s]) => { return `- ${name}: ${s.description}`; }).join("\n"); return `SKILLS:\n${skills}`; } catch (err) { return `Error: ${err.message}`; } }, }), }, }; };