Node
npm install @six5536/agent-harness-adapter-nodePrebuilt for Linux (glibc; x64, arm64), macOS (x64, arm64) and Windows (x64). API reference.
Install an integration
Section titled “Install an integration”A manifest is a file’s path, an object, or null for the repository’s
config.
import aha from "@six5536/agent-harness-adapter-node";
const mytool = { version: 1, name: "mytool", instructions: "Run `mytool check` before you finish.\n", skills: [{ name: "mytool", description: "Check the project with mytool.", body: "Run `mytool check`; fix what it reports.\n" }], hooks: [{ event: "pre-tool", tools: "shell", command: "mytool hook {harness} {event}" }], allow_commands: ["mytool"],};
const result = aha.install(mytool, ["claude", "codex", "gemini"]);for (const h of result.harnesses) { console.log(h.harness, h.parts.map((p) => `${p.state} ${p.path}`));}The third argument takes options: scope ("project", "user" or
"local"), root (the project directory), home, and for install force
and without (InstallOptions).
uninstall and status take the same arguments. Results are the JSON of
agent-harness-adapter install --json.
Answer a hook
Section titled “Answer a hook”With command = "mytool hook {harness} {event}", runHook reads the
harness’s input as Claude Code’s and writes your answer in the harness’s form.
// mytool hook <harness> <event>: Claude Code's input in, its answer out,// translated for whichever agent ran the hook.import aha from "@six5536/agent-harness-adapter-node";
const [harness, event] = process.argv.slice(2);const code = await aha.runHook(harness, event, (hook) => String(hook.tool_input?.command ?? "").includes("rm -rf") ? { decision: "block", reason: "mytool: no rm -rf here" } : null,);process.exit(code);parseHook and answerHook do the two halves separately. Errors throw with
the library’s message.