diff --git a/README.md b/README.md index b064bec..b948b7d 100644 --- a/README.md +++ b/README.md @@ -8,51 +8,81 @@ oh-my-openagent adds multi-model orchestration, LSP tools, and other advanced fe ## How It Works -The solution uses the `OPENCODE_CONFIG_CONTENT` environment variable, which has higher runtime precedence than the config file. This means: +The solution uses: +1. **State file** (`~/.config/opencode/omoa-enabled`) — determines if omoa should be active +2. **`OPENCODE_CONFIG_CONTENT` environment variable** — injects the plugin at runtime (higher precedence than config file) +3. **Post-upgrade script** — removes plugin entry from `opencode.json` after running upstream installer -- The base `opencode.json` stays clean (no plugin entry) -- The plugin is only injected at runtime when needed +This approach: +- Keeps `opencode.json` clean (no plugin entry) +- Is compatible with upstream install script - No file mutation, no backups, no restore ## Files - `opencode-start.sh` — Wrapper script that starts OpenCode with/without omoa -- `omoa-restart.mjs` — OpenCode skill for Telegram bot integration +- `omoa-post-upgrade.sh` — Removes omoa plugin from `opencode.json` after upstream install +- `omoa-toggle.mjs` — OpenCode skill for Telegram bot integration - `README.md` — This file -## Usage - -### Shell Script - -```bash -./opencode-start.sh # Start without omoa (vanilla) -./opencode-start.sh --omoa # Start with omoa enabled -``` - -### Telegram Bot - -When registered in `opencode.json` under "skills", use `/commands` in Telegram: -- `restart_with_omoa` — Restart OpenCode with omoa enabled -- `restart_without_omoa` — Restart OpenCode without omoa (vanilla) - ## Installation 1. Copy files to `~/.config/opencode/` -2. Update systemd service to use `opencode-start.sh`: +2. Make scripts executable: + ```bash + chmod +x ~/.config/opencode/opencode-start.sh + chmod +x ~/.config/opencode/omoa-post-upgrade.sh + ``` +3. Symlink to PATH: + ```bash + ln -sf ~/.config/opencode/opencode-start.sh ~/.local/bin/opencode-start + ln -sf ~/.config/opencode/omoa-post-upgrade.sh ~/.local/bin/omoa-post-upgrade + ``` +4. Update systemd service to use wrapper: ```ini [Service] ExecStart=/home/kenny/.config/opencode/opencode-start.sh ``` -3. Add skill to `opencode.json`: +5. Add skill to `opencode.json`: ```json "skills": { - "omoa-restart": { - "description": "Restart OpenCode with/without oh-my-openagent", - "path": "/home/kenny/.config/opencode/skills/omoa-restart.mjs" + "omoa-toggle": { + "description": "Toggle oh-my-openagent on/off", + "path": "/home/kenny/.config/opencode/skills/omoa-toggle.mjs" } } ``` -4. Restart services +6. Restart services + +## Usage + +### Shell + +```bash +# Start without omoa (vanilla) +opencode-start + +# Start with omoa enabled +opencode-start --omoa + +# After running upstream install script +omoa-post-upgrade +``` + +### Telegram Bot + +Use `/commands` → `omoa_toggle`: +- `on` — Enable omoa (creates state file, restarts server) +- `off` — Disable omoa (deletes state file, restarts server) +- `status` — Check if omoa is enabled + +### After Upstream Updates + +When you run the upstream install script: +```bash +npx oh-my-openagent@latest install +omoa-post-upgrade # Clean the plugin entry from opencode.json +``` ## Author diff --git a/omoa-post-upgrade.sh b/omoa-post-upgrade.sh new file mode 100755 index 0000000..46485e9 --- /dev/null +++ b/omoa-post-upgrade.sh @@ -0,0 +1,55 @@ +#!/bin/bash +# ============================================================================= +# omoa-post-upgrade.sh — Clean oh-my-openagent plugin from opencode.json +# ============================================================================= +# +# PURPOSE: +# After running the upstream oh-my-openagent install script, this script +# removes the plugin entry from opencode.json. This keeps the config clean +# so that omoa can be injected at runtime via OPENCODE_CONFIG_CONTENT. +# +# WHY THIS EXISTS: +# The upstream install script adds "oh-my-openagent@latest" to the plugin +# array in opencode.json. This conflicts with our runtime injection approach +# because: +# - If the plugin is in both opencode.json AND OPENCODE_CONFIG_CONTENT, +# it may be loaded twice +# - Our toggle approach uses OPENCODE_CONFIG_CONTENT to inject the plugin +# only when needed, so the config file should stay clean +# +# USAGE: +# ./omoa-post-upgrade.sh — Remove omoa plugin from opencode.json +# +# WHEN TO RUN: +# After running: npx oh-my-openagent@latest install +# This script is idempotent — safe to run multiple times +# +# UPSTREAM REPO: +# https://git.hibbhome.com/Hibbhome/opencode-omoa-toggle +# +# CREATED: 2026-05-03 +# ============================================================================= + +CONFIG_FILE="$HOME/.config/opencode/opencode.json" + +# Use python3 to remove oh-my-openagent from the plugin array +python3 -c " +import json + +with open('$CONFIG_FILE', 'r') as f: + config = json.load(f) + +# Remove oh-my-openagent from plugin array if present +if 'plugin' in config: + original = config['plugin'][:] + config['plugin'] = [p for p in config['plugin'] if 'oh-my-openagent' not in p] + + if original != config['plugin']: + with open('$CONFIG_FILE', 'w') as f: + json.dump(config, f, indent=2) + print('Removed oh-my-openagent from opencode.json') + else: + print('oh-my-openagent not found in opencode.json — no changes needed') +else: + print('No plugin array in opencode.json — no changes needed') +" diff --git a/omoa-toggle.mjs b/omoa-toggle.mjs new file mode 100644 index 0000000..82ba245 --- /dev/null +++ b/omoa-toggle.mjs @@ -0,0 +1,86 @@ +/** + * omoa-toggle.mjs — OpenCode skill to toggle oh-my-openagent on/off + * + * PURPOSE: + * Provides a single Telegram command to toggle oh-my-openagent on/off. + * Creates or deletes a state file, then restarts the OpenCode server. + * + * HOW IT WORKS: + * - State file: ~/.config/opencode/omoa-enabled + * - If state file exists → omoa is enabled + * - If state file does not exist → omoa is disabled + * - The opencode-start.sh script checks for this state file at startup + * - If present, it injects omoa via OPENCODE_CONFIG_CONTENT + * - If absent, it starts OpenCode vanilla (no omoa) + * + * USAGE: + * In Telegram: /commands → omoa_toggle + * Actions: + * - on: Create state file, restart server (enables omoa) + * - off: Delete state file, restart server (disables omoa) + * - status: Check if state file exists + * + * UPSTREAM COMPATIBILITY: + * This approach does NOT modify opencode.json directly. + * The upstream install script can run safely — use omoa-post-upgrade.sh + * to clean the plugin entry from opencode.json after running the installer. + * + * UPSTREAM REPO: + * https://git.hibbhome.com/Hibbhome/opencode-omoa-toggle + * + * CREATED: 2026-05-03 + */ + +import { tool } from "@opencode-ai/plugin/tool"; +import { execSync } from "node:child_process"; +import { existsSync, writeFileSync, unlinkSync } from "node:fs"; + +const STATE_FILE = "/home/kenny/.config/opencode/omoa-enabled"; + +export const OmoaTogglePlugin = async (_ctx) => { + return { + tool: { + omoa_toggle: tool({ + description: "Toggle oh-my-openagent on or off", + args: { + action: tool.schema.enum(["on", "off", "status"]).describe("Action: on, off, or status"), + }, + async execute(args) { + try { + if (args.action === "status") { + return existsSync(STATE_FILE) + ? "oh-my-openagent is ENABLED (state file exists)" + : "oh-my-openagent is DISABLED (no state file)"; + } + + if (args.action === "on") { + // Create state file to enable omoa + writeFileSync(STATE_FILE, new Date().toISOString()); + + // Restart the OpenCode server + execSync("systemctl --user restart opencode-serve.service"); + + return "oh-my-openagent ENABLED. Server restarting..."; + } + + if (args.action === "off") { + // Delete state file to disable omoa + if (existsSync(STATE_FILE)) { + unlinkSync(STATE_FILE); + } + + // Restart the OpenCode server + execSync("systemctl --user restart opencode-serve.service"); + + return "oh-my-openagent DISABLED. Server restarting..."; + } + + return "Invalid action. Use: on, off, or status"; + } catch (err) { + return `Error: ${err.message}`; + } + }, + }), + }, + }; +}; diff --git a/opencode-start.sh b/opencode-start.sh index d207d4e..d574c21 100755 --- a/opencode-start.sh +++ b/opencode-start.sh @@ -4,21 +4,34 @@ # ============================================================================= # # PURPOSE: -# Wrapper script that starts the OpenCode server, optionally injecting the -# oh-my-openagent plugin at runtime via OPENCODE_CONFIG_CONTENT. -# No files are mutated — the base opencode.json stays clean. -# -# USAGE: -# ./opencode-start.sh — Start without omoa (vanilla) -# ./opencode-start.sh --omoa — Start with omoa enabled +# Wrapper script that starts the OpenCode server. If a state file exists +# at ~/.config/opencode/omoa-enabled, the oh-my-openagent plugin is injected +# at runtime via OPENCODE_CONFIG_CONTENT. Otherwise, OpenCode starts vanilla. # # HOW IT WORKS: -# - Reads ~/.config/opencode/opencode.json -# - If --omoa flag is set, uses python3 to add oh-my-openagent@latest to the -# plugin array and sets OPENCODE_CONFIG_CONTENT with the modified JSON -# - If --omoa is not set, starts with the clean config file -# - OPENCODE_CONFIG_CONTENT has higher precedence than the config file, -# so the plugin is only active for that process +# - Checks for state file: ~/.config/opencode/omoa-enabled +# - If state file exists: +# - Reads opencode.json +# - Uses python3 to add oh-my-openagent@latest to the plugin array +# - Sets OPENCODE_CONFIG_CONTENT with the modified JSON +# - OPENCODE_CONFIG_CONTENT has higher precedence than the config file +# - If state file does not exist: +# - Starts OpenCode with the clean config file (no omoa) +# - No files are mutated — the base opencode.json stays clean +# +# STATE FILE: +# ~/.config/opencode/omoa-enabled +# - If this file exists, omoa is enabled +# - If this file does not exist, omoa is disabled +# - Created/deleted by the omoa_toggle Telegram skill +# +# USAGE: +# opencode-start — Start without omoa (vanilla) +# opencode-start --omoa — Start with omoa enabled +# +# SYSTEMD INTEGRATION: +# This script is used as the ExecStart command in the opencode-serve.service. +# The systemd service runs this in the background. # # UPSTREAM REPO: # https://git.hibbhome.com/Hibbhome/opencode-omoa-toggle @@ -28,9 +41,22 @@ CONFIG_FILE="$HOME/.config/opencode/opencode.json" OPENCODE_BIN="$HOME/.opencode/bin/opencode" +STATE_FILE="$HOME/.config/opencode/omoa-enabled" PORT=4096 +# Check if omoa should be enabled +# Either via state file or --omoa flag +ENABLE_OMOA=false + +if [ -f "$STATE_FILE" ]; then + ENABLE_OMOA=true +fi + if [[ "$*" == *"--omoa"* ]]; then + ENABLE_OMOA=true +fi + +if [ "$ENABLE_OMOA" = true ]; then # Inject oh-my-openagent plugin at runtime using python3 MODIFIED_CONFIG=$(python3 -c " import json