UNPKG

autoagent-cli

Version:

Run autonomous AI agents using Claude or Gemini for task execution

166 lines (165 loc) 5.93 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.HookManager = void 0; const child_process_1 = require("child_process"); const git_commit_hook_js_1 = require("../hooks/git-commit-hook.js"); const git_push_hook_js_1 = require("../hooks/git-push-hook.js"); class HookManager { constructor(config, sessionId, workspace) { this.config = config; this.sessionId = sessionId; this.workspace = workspace; } async executeHooks(hookPoint, data) { const hooks = this.config[hookPoint] || []; const hookData = { ...data, eventName: hookPoint, sessionId: this.sessionId, workspace: this.workspace, timestamp: Date.now() }; for (const hook of hooks) { try { let result; if (hook.type === 'command') { result = await this.executeCommandHook(hook, hookData, hookPoint); } else { result = await this.executeBuiltinHook(hook, hookData); } if (result.blocked) { return result; } if (result.output !== undefined && result.output !== null && result.output.length > 0) { console.log(result.output); } } catch (error) { console.error(`Hook error: ${error instanceof Error ? error.message : String(error)}`); } } return { blocked: false }; } async executeCommandHook(hook, data, hookPoint) { if (hook.command === undefined || hook.command === null || hook.command === '') { throw new Error('Command hook missing command field'); } const command = this.interpolateCommand(hook.command, data); const input = JSON.stringify(data, null, 2); const timeout = hook.timeout ?? 60000; const result = await this.runCommand(command, input, timeout); if (result.stdout && result.stdout.length > 0) { console.log(result.stdout); } if (result.exitCode === 2 && (hookPoint.startsWith('Pre') || hookPoint === 'Stop')) { return { blocked: true, reason: result.stderr || 'Blocked by hook', output: result.stdout }; } else if (result.exitCode !== 0) { if (result.stderr && result.stderr.length > 0) { console.error(result.stderr); } } if (result.stdout && result.stdout.length > 0) { try { const jsonOutput = JSON.parse(result.stdout); if (jsonOutput.decision === 'block') { return { blocked: true, reason: jsonOutput.reason ?? 'Blocked by hook', output: jsonOutput.feedback }; } } catch { } } return { blocked: false, output: result.stdout }; } async executeBuiltinHook(hook, data) { switch (hook.type) { case 'git-commit': { const gitCommitHook = new git_commit_hook_js_1.GitCommitHook(); return gitCommitHook.execute(data, hook); } case 'git-push': { const gitPushHook = new git_push_hook_js_1.GitPushHook(); return gitPushHook.execute(data, hook); } default: { console.warn(`Built-in hook type '${hook.type}' not yet implemented`); return { blocked: false }; } } } interpolateCommand(command, data) { return command.replace(/\{\{(\w+)\}\}/g, (match, key) => { const value = data[key]; if (value === undefined) { return match; } if (Array.isArray(value)) { return value.join(' '); } return String(value); }); } async runCommand(command, input, timeout) { return new Promise((resolve) => { let stdout = ''; let stderr = ''; let timedOut = false; const child = (0, child_process_1.spawn)(command, { shell: true, cwd: this.workspace, env: { ...process.env }, windowsHide: true }); const timer = setTimeout(() => { timedOut = true; child.kill('SIGTERM'); setTimeout(() => { if (!child.killed) { child.kill('SIGKILL'); } }, 5000); }, timeout); child.stdout?.on('data', (data) => { stdout += data.toString(); }); child.stderr?.on('data', (data) => { stderr += data.toString(); }); if (input.length > 0) { child.stdin?.write(input); child.stdin?.end(); } child.on('exit', (code, signal) => { clearTimeout(timer); resolve({ exitCode: code ?? (signal ? 1 : 0), stdout: stdout.trim(), stderr: stderr.trim(), timedOut }); }); child.on('error', (error) => { clearTimeout(timer); resolve({ exitCode: 1, stdout: stdout.trim(), stderr: `Failed to execute command: ${error.message}`, timedOut: false }); }); }); } } exports.HookManager = HookManager;