Skip to content

Instantly share code, notes, and snippets.

@dkandalov
Created May 15, 2026 12:08
Show Gist options
  • Select an option

  • Save dkandalov/84d1720684e15fdc9508c25915ef2cb0 to your computer and use it in GitHub Desktop.

Select an option

Save dkandalov/84d1720684e15fdc9508c25915ef2cb0 to your computer and use it in GitHub Desktop.
Plugin for OpenCode to commit modified files after executing edit tools (see https://opencode.ai/docs/plugins)
import type {Hooks, PluginInput} from "@opencode-ai/plugin"
export default async function (input: PluginInput): Promise<Hooks> {
const {$, client} = input
return {
"tool.execute.after": async (info, output) => {
try {
const editTools = ["write", "multiedit", "apply_patch", "edit", "search_replace", "create", "rename_element"]
if (!editTools.includes(info.tool)) return
const modifiedFiles = await findModifiedFile(info, client);
if (modifiedFiles.length === 0) return
await $`git add ${modifiedFiles} --ignore-errors`.quiet().nothrow()
await $`git commit -m "OpenCode WIP: ${info.tool} ${output.title}" --no-verify --allow-empty -- ${modifiedFiles}`.quiet().nothrow()
} catch (err) {
await client.app.log({
body: {
service: "auto-commit-hook",
level: "warn",
message: `Git commit failed on ${info.tool}`,
extra: {output: err},
},
})
}
},
}
}
async function findModifiedFile(info: { sessionID: string; args: any }, client) {
const args = info.args || {}
const files = new Set<string>()
if (args.path) files.add(args.path)
if (args.file) files.add(args.file)
if (args.filePath) files.add(args.filePath)
if (Array.isArray(args.files)) args.files.forEach(f => files.add(f))
// Fallback to session summary if no files found in args
if (files.size === 0) {
const result = await client.session.get({path: {sessionID: info.sessionID}})
result.data?.summary?.diffs?.forEach(d => files.add(d.file))
}
return [...files].filter(Boolean);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment