153 lines
4.9 KiB
JavaScript

/**
* omoa.mjs — Unified OpenCode skill for oh-my-openagent management
*
* PURPOSE:
* Single skill to manage oh-my-openagent from within OpenCode sessions.
* Combines toggle, status, and post-upgrade cleanup into one interface.
*
* STATE FILE:
* ~/.config/opencode/omoa-enabled
* - If this file exists, omoa is enabled
* - If this file does not exist, omoa is disabled
*
* HOW IT WORKS:
* - Toggle: Creates/deletes state file, restarts server
* - Status: Checks if state file exists
* - Post-upgrade: Removes omoa plugin from opencode.json after upstream install
* - The opencode-start.sh script checks for state file at startup
* - If present, injects omoa via OPENCODE_CONFIG_CONTENT
*
* USAGE:
* skill("omoa") — Load this skill
* Then use the helper functions:
* - omoa_status: Check if omoa is enabled
* - omoa_enable: Enable omoa (create state file, restart server)
* - omoa_disable: Disable omoa (delete state file, restart server)
* - omoa_toggle: Toggle omoa on/off
* - omoa_post_upgrade: Clean opencode.json after upstream install
*
* CLI EQUIVALENT:
* omoa [on|off|status|toggle]
* omoa-post-upgrade
*
* 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, readFileSync, writeFileSync as writeSync } from "node:fs";
const STATE_FILE = "/home/kenny/.config/opencode/omoa-enabled";
const CONFIG_FILE = "/home/kenny/.config/opencode/opencode.json";
export const OmoaPlugin = async (_ctx) => {
return {
tool: {
/**
* Check if omoa is enabled
*/
omoa_status: tool({
description: "Check if oh-my-openagent is enabled",
args: {},
async execute() {
const enabled = existsSync(STATE_FILE);
return enabled
? "oh-my-openagent is ENABLED (state file exists)"
: "oh-my-openagent is DISABLED (no state file)";
},
}),
/**
* Enable omoa
*/
omoa_enable: tool({
description: "Enable oh-my-openagent (create state file, restart server)",
args: {},
async execute() {
try {
writeFileSync(STATE_FILE, new Date().toISOString());
execSync("systemctl --user restart opencode-serve.service");
return "oh-my-openagent ENABLED. Server restarting...";
} catch (err) {
return `Error: ${err.message}`;
}
},
}),
/**
* Disable omoa
*/
omoa_disable: tool({
description: "Disable oh-my-openagent (delete state file, restart server)",
args: {},
async execute() {
try {
if (existsSync(STATE_FILE)) {
unlinkSync(STATE_FILE);
}
execSync("systemctl --user restart opencode-serve.service");
return "oh-my-openagent DISABLED. Server restarting...";
} catch (err) {
return `Error: ${err.message}`;
}
},
}),
/**
* Toggle omoa on/off
*/
omoa_toggle: tool({
description: "Toggle oh-my-openagent on/off",
args: {},
async execute() {
try {
if (existsSync(STATE_FILE)) {
unlinkSync(STATE_FILE);
execSync("systemctl --user restart opencode-serve.service");
return "oh-my-openagent DISABLED. Server restarting...";
} else {
writeFileSync(STATE_FILE, new Date().toISOString());
execSync("systemctl --user restart opencode-serve.service");
return "oh-my-openagent ENABLED. Server restarting...";
}
} catch (err) {
return `Error: ${err.message}`;
}
},
}),
/**
* Post-upgrade cleanup
*/
omoa_post_upgrade: tool({
description: "Remove oh-my-openagent plugin from opencode.json after upstream install",
args: {},
async execute() {
try {
const config = JSON.parse(readFileSync(CONFIG_FILE, "utf-8"));
if (!config.plugin || !Array.isArray(config.plugin)) {
return "No plugin array in opencode.json — no changes needed";
}
const original = [...config.plugin];
config.plugin = config.plugin.filter(p => !p.includes("oh-my-openagent"));
if (original.length === config.plugin.length) {
return "oh-my-openagent not found in opencode.json — no changes needed";
}
writeSync(CONFIG_FILE, JSON.stringify(config, null, 2));
return `Removed oh-my-openagent from opencode.json (${original.length}${config.plugin.length} plugins)`;
} catch (err) {
return `Error: ${err.message}`;
}
},
}),
},
};
};