#!/usr/bin/env node import fs from "node:fs"; import os from "node:os"; import path from "node:path"; import { fileURLToPath } from "node:url"; const codexHome = process.env.CODEX_HOME ?? path.join(os.homedir(), ".codex"); const controlRoot = process.env.GH_CODEX_CONTROL_ROOT ?? path.join( codexHome, "runtime", "guanghu-codex-host-bridge", "state", "control", ); const controllerPath = path.join(controlRoot, "current-controller.json"); const leasePath = path.join(controlRoot, "write-lease.json"); const leaseScript = path.join(path.dirname(fileURLToPath(import.meta.url)), "write-lease.mjs"); function readJson(file) { try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return null; } } function emit(value) { process.stdout.write(JSON.stringify(value)); } function allow(additionalContext = null) { emit(additionalContext ? { hookSpecificOutput: { hookEventName: "PreToolUse", additionalContext, }, } : { continue: true }); } function deny(reason) { emit({ hookSpecificOutput: { hookEventName: "PreToolUse", permissionDecision: "deny", permissionDecisionReason: reason, }, }); } function payloadOf(input) { if (typeof input.tool_input === "string") return input.tool_input; try { return JSON.stringify(input.tool_input ?? {}); } catch { return ""; } } function highRiskCategory(input) { const name = String(input.tool_name ?? ""); const payload = payloadOf(input); const combined = `${name}\n${payload}`; if (combined.includes(leaseScript)) return null; if ( /\bgit\b[\s\S]{0,900}\bpush\b/iu.test(combined) || /\b(?:gh\s+(?:pr\s+(?:create|merge)|release\s+create|repo\s+delete)|docker\s+push)\b/iu.test(combined) ) return "remote_git"; if ( /\b(?:npm|pnpm|yarn|cargo|twine)\s+publish\b/iu.test(combined) || /\b(?:vercel|flyctl|netlify)\b[\s\S]{0,300}\b(?:deploy|publish|--prod)\b/iu.test(combined) || /\b(?:wrangler|kubectl|helm)\b[\s\S]{0,300}\b(?:deploy|publish|apply|delete|patch|replace|upgrade)\b/iu.test(combined) || /\bcurl\b[\s\S]{0,500}(?:-X|--request)\s*(?:POST|PUT|PATCH|DELETE)\b/iu.test(combined) || /(?:deploy|publish|create_release|merge_pull_request|send_email)/iu.test(name) ) return "external_publish"; if ( /\brm\s+/iu.test(payload) || /\bfind\b[\s\S]{0,700}\s-delete\b/iu.test(payload) || /\b(?:npm|pnpm|yarn)\s+cache\s+(?:clean|clear)\b/iu.test(payload) || /\bcargo\s+clean\b/iu.test(payload) || /\bxcodebuild\b[\s\S]{0,300}\bclean\b/iu.test(payload) || /\b(?:brew|port)\s+cleanup\b/iu.test(payload) || /\bgit\b[\s\S]{0,300}\b(?:clean\b|reset\s+--hard\b)/iu.test(payload) || /\bdiskutil\b[\s\S]{0,200}\berase/iu.test(payload) || /\*\*\* Delete File:/u.test(payload) ) return "destructive_cleanup"; return null; } function capabilityTool(input) { const name = String(input.tool_name ?? ""); return ( ["Bash", "exec_command", "functions.exec_command", "functions.exec", "apply_patch", "write_stdin"].includes(name) || /(?:^|__)(?:exec|exec_command|apply_patch|write_stdin|computer_use|control_chrome|control_in_app_browser)(?:$|__)/iu.test(name) || /(?:create|update|delete|remove|write|send|merge|deploy|publish|push)/iu.test(name) ); } function consumeLease(input, controller, category) { const lease = readJson(leasePath); if ( !lease || lease.schema !== "guanghu.codex-one-shot-write-lease/v1" || lease.one_shot !== true || lease.control_epoch !== controller.control_epoch || lease.session_id !== input.session_id || lease.turn_id !== input.turn_id || lease.category !== category || lease.cwd !== path.resolve(input.cwd ?? process.cwd()) || !Number.isFinite(lease.expires_at_unix_ms) || lease.expires_at_unix_ms < Date.now() ) return null; try { fs.unlinkSync(leasePath); } catch { return null; } return lease; } let input = {}; try { const raw = fs.readFileSync(0, "utf8").trim(); if (raw) input = JSON.parse(raw); } catch { input = {}; } if ((input.hook_event_name ?? input.hookEventName) !== "PreToolUse") process.exit(0); const controller = readJson(controllerPath); const currentSession = Boolean( controller?.schema === "guanghu.codex-current-controller/v1" && controller.direct_human_natural_language === true && controller.session_id === input.session_id ); if (!currentSession && capabilityTool(input)) { deny(`STALE_OR_UNCLAIMED_CODEX_TASK_CAPABILITY_BLOCKED; current_session=${controller?.session_id ?? "NONE"}; attempted_session=${input.session_id ?? "UNKNOWN"}`); process.exit(0); } const category = highRiskCategory(input); if (!category) { allow(); process.exit(0); } if (!currentSession) { deny(`STALE_OR_UNCLAIMED_CODEX_TASK_HIGH_RISK_BLOCKED; category=${category}`); process.exit(0); } const lease = consumeLease(input, controller, category); if (!lease) { deny(`CURRENT_CODEX_TASK_ONE_SHOT_LEASE_REQUIRED; category=${category}; issue_only_after_explicit_current_turn_human_authorization`); process.exit(0); } allow(`GUANGHU_ONE_SHOT_WRITE_LEASE_CONSUMED lease_id=${lease.lease_id}; category=${category}; target=${lease.target}`);