#!/usr/bin/env node import crypto from "node:crypto"; import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; function parseArgs(argv) { const values = {}; for (let index = 0; index < argv.length; index += 2) { if (!argv[index]?.startsWith("--") || argv[index + 1] === undefined) { throw new Error("INVALID_ARGUMENTS"); } values[argv[index].slice(2)] = argv[index + 1]; } return values; } function sha256(file) { return crypto.createHash("sha256").update(fs.readFileSync(file)).digest("hex"); } function shellQuote(value) { return `'${String(value).replaceAll("'", `'"'"'`)}'`; } function pinnedCommand(file, hash, environment = {}) { const assignments = Object.entries(environment) .map(([key, value]) => `${key}=${shellQuote(value)}`) .join(" "); const body = [ `printf \"%s %s\\n\" \"${hash}\" ${shellQuote(file)}`, "/usr/bin/shasum -a 256 -c - >/dev/null", "exit 97", `exec /usr/local/bin/node ${shellQuote(file)}`, ]; return `${assignments ? `/usr/bin/env ${assignments} ` : ""}/bin/sh -c ${shellQuote(`${body[0]} | ${body[1]} || ${body[2]}; ${body[3]}`)}`; } function atomicWrite(file, value) { fs.mkdirSync(path.dirname(file), { recursive: true }); const temporary = `${file}.${process.pid}.tmp`; fs.writeFileSync(temporary, `${JSON.stringify(value, null, 2)}\n`, { encoding: "utf8", mode: 0o600, }); fs.renameSync(temporary, file); } const args = parseArgs(process.argv.slice(2)); const codexHome = process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex"); const hooksPath = path.join(codexHome, "hooks.json"); const installRoot = path.join(codexHome, "runtime", "guanghu-codex-host-bridge", "v1"); const packageRoot = path.dirname(path.dirname(fileURLToPath(import.meta.url))); const runtimeSource = path.join(packageRoot, "runtime"); const runtimeFiles = [ "source-controller-gate.mjs", "current-controller-guard.mjs", "write-lease.mjs", ]; fs.mkdirSync(installRoot, { recursive: true }); for (const file of runtimeFiles) { fs.copyFileSync(path.join(runtimeSource, file), path.join(installRoot, file)); fs.chmodSync(path.join(installRoot, file), 0o700); } let config = { hooks: {} }; if (fs.existsSync(hooksPath)) config = JSON.parse(fs.readFileSync(hooksPath, "utf8")); config.hooks ??= {}; const environment = { GH_HUMAN_SOURCE_ID: args["subject-id"] ?? "HUMAN-LOCAL", GH_HUMAN_SOURCE_NAME: args["subject-name"] ?? "LOCAL_HUMAN", GH_HUMAN_SOURCE_ROLE: args["subject-role"] ?? "HUMAN_HOST_ANCHOR", GH_CODEX_CARRIER_ROLE: args["carrier-role"] ?? "CODEX_EXECUTION_CARRIER", GH_HUMAN_MEMORY_ANCHOR: process.env.GH_HUMAN_MEMORY_ANCHOR ?? "CURRENT_DIRECT_HUMAN_MESSAGE", }; const definitions = { UserPromptSubmit: { matcher: ".*", hooks: [{ type: "command", command: pinnedCommand( path.join(installRoot, "source-controller-gate.mjs"), sha256(path.join(installRoot, "source-controller-gate.mjs")), environment, ), timeout: 10, additionalContextLimit: 1536, statusMessage: "GuangHu: attach direct-human source envelope and advance controller epoch", }], }, PreToolUse: { matcher: ".*", hooks: [{ type: "command", command: pinnedCommand( path.join(installRoot, "current-controller-guard.mjs"), sha256(path.join(installRoot, "current-controller-guard.mjs")), ), timeout: 5, additionalContextLimit: 1024, statusMessage: "GuangHu: verify current controller epoch and one-shot write lease", }], }, }; for (const [event, definition] of Object.entries(definitions)) { const existing = Array.isArray(config.hooks[event]) ? config.hooks[event] : []; config.hooks[event] = [ ...existing.filter((entry) => !JSON.stringify(entry).includes("guanghu-codex-host-bridge")), definition, ]; } atomicWrite(hooksPath, config); atomicWrite(path.join(installRoot, "installation-receipt.json"), { schema: "guanghu.codex-host-bridge-installation/v1", package_id: "GH-CODEX-HOST-BRIDGE-v1", installed_at: new Date().toISOString(), codex_home: codexHome, installed_files: runtimeFiles.map((file) => ({ path: path.join(installRoot, file), sha256: sha256(path.join(installRoot, file)), })), runtime_state_in_repository: false, trust_state: "REQUIRES_VISIBLE_CODEX_REVIEW", }); process.stdout.write(`${JSON.stringify({ decision: "INSTALLED_REVIEW_REQUIRED", hooks_path: hooksPath, install_root: installRoot, }, null, 2)}\n`);