This commit is contained in:
Ben Kraus
2026-01-02 09:32:51 -07:00
committed by Cameron Palmer
parent 38adfa4d8b
commit 98e154b18e
6 changed files with 105 additions and 8 deletions

View File

@@ -0,0 +1,40 @@
// Package opencode provides OpenCode plugin management.
package opencode
import (
"embed"
"fmt"
"os"
"path/filepath"
)
//go:embed plugin/gastown.js
var pluginFS embed.FS
// EnsurePluginAt ensures the Gas Town OpenCode plugin exists.
// If the file already exists, it's left unchanged.
func EnsurePluginAt(workDir, pluginDir, pluginFile string) error {
if pluginDir == "" || pluginFile == "" {
return nil
}
pluginPath := filepath.Join(workDir, pluginDir, pluginFile)
if _, err := os.Stat(pluginPath); err == nil {
return nil
}
if err := os.MkdirAll(filepath.Dir(pluginPath), 0755); err != nil {
return fmt.Errorf("creating plugin directory: %w", err)
}
content, err := pluginFS.ReadFile("plugin/gastown.js")
if err != nil {
return fmt.Errorf("reading plugin template: %w", err)
}
if err := os.WriteFile(pluginPath, content, 0644); err != nil {
return fmt.Errorf("writing plugin: %w", err)
}
return nil
}

View File

@@ -0,0 +1,32 @@
// Gas Town OpenCode plugin: hooks SessionStart/Compaction via events.
export const GasTown = async ({ $, directory }) => {
const role = (process.env.GT_ROLE || "").toLowerCase();
const autonomousRoles = new Set(["polecat", "witness", "refinery", "deacon"]);
let didInit = false;
const run = async (cmd) => {
try {
await $`/bin/sh -lc ${cmd}`.cwd(directory);
} catch (err) {
console.error(`[gastown] ${cmd} failed`, err?.message || err);
}
};
const onSessionCreated = async () => {
if (didInit) return;
didInit = true;
await run("gt prime");
if (autonomousRoles.has(role)) {
await run("gt mail check --inject");
}
await run("gt nudge deacon session-started");
};
return {
event: async ({ event }) => {
if (event?.type === "session.created") {
await onSessionCreated();
}
},
};
};