Files
dev-workflows/adapters/opencode/dev-workflows.ts
EvandroandClaude Opus 5.5 29b5ebf400 feat: install into Claude Code, opencode or Hermes from one script
opencode reads the same SKILL.md files but needs its own subagent format and a
TypeScript plugin for the guard, formatter and gate, so install.py converts the
agents and points the copies at this checkout.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-24 21:52:06 -03:00

35 lines
1.7 KiB
TypeScript

// dev-workflows for opencode: the same guard, formatter and gate scripts the Claude Code hooks run.
// Installed by `python3 scripts/install.py opencode`, which replaces __DW_ROOT__ with the checkout path.
// opencode cannot block the end of a turn, so a missing or failing gate is logged instead of blocking.
const ROOT = "__DW_ROOT__"
const DevWorkflows = async (ctx: any) => {
const $ = ctx.$ ?? (globalThis as any).Bun?.$
const directory = ctx.directory ?? ctx.location?.directory ?? process.cwd()
return {
"tool.execute.before": async (input: any, output: any) => {
if (!["bash", "shell"].includes(String(input?.tool ?? "").toLowerCase())) return
const command = output?.args?.command
if (typeof command !== "string" || !command) return
const r = await $`python3 ${ROOT}/scripts/hooks/bash_guard.py --check ${command}`.quiet().nothrow()
if (r.exitCode === 2) throw new Error(String(r.stdout).trim())
},
"tool.execute.after": async (input: any, output: any) => {
if (!["edit", "write", "patch", "multiedit"].includes(String(input?.tool ?? "").toLowerCase())) return
const file = input?.args?.filePath ?? output?.args?.filePath
if (typeof file === "string" && file) {
await $`python3 ${ROOT}/scripts/hooks/post_edit.py --file ${file}`.quiet().nothrow()
}
},
event: async ({ event }: any) => {
if (event?.type !== "session.idle") return
const r = await $`python3 ${ROOT}/scripts/hooks/stop_gate.py --check ${directory}`.quiet().nothrow()
if (r.exitCode === 2) {
await ctx.client?.app?.log?.({ body: { service: "dev-workflows", level: "warn", message: String(r.stdout).trim() } })
}
},
}
}
export default { id: "dev-workflows", setup: DevWorkflows }