From 97c3c5f7f7383f92b3908801ee83fdd703d99af2 Mon Sep 17 00:00:00 2001 From: "Grace (Clawdbot)" Date: Tue, 27 Jan 2026 14:27:49 +0100 Subject: [PATCH] feat(exec-events): bead-7 - add hooks exec config schema --- src/config/schema.ts | 12 ++++++++++++ src/config/types.hooks.ts | 13 +++++++++++++ src/config/zod-schema.hooks.ts | 10 ++++++++++ src/config/zod-schema.ts | 8 +++++++- 4 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/config/schema.ts b/src/config/schema.ts index b4ec8723b..d56ac666c 100644 --- a/src/config/schema.ts +++ b/src/config/schema.ts @@ -180,6 +180,10 @@ const FIELD_LABELS: Record = { "tools.exec.node": "Exec Node Binding", "tools.exec.pathPrepend": "Exec PATH Prepend", "tools.exec.safeBins": "Exec Safe Bins", + "hooks.exec.emitEvents": "Exec Events Enabled", + "hooks.exec.commandWhitelist": "Exec Event Command Allowlist", + "hooks.exec.outputThrottleMs": "Exec Output Throttle (ms)", + "hooks.exec.outputMaxChunkBytes": "Exec Output Max Chunk (bytes)", "tools.message.allowCrossContextSend": "Allow Cross-Context Messaging", "tools.message.crossContext.allowWithinProvider": "Allow Cross-Context (Same Provider)", "tools.message.crossContext.allowAcrossProviders": "Allow Cross-Context (Across Providers)", @@ -420,6 +424,14 @@ const FIELD_HELP: Record = { "tools.exec.pathPrepend": "Directories to prepend to PATH for exec runs (gateway/sandbox).", "tools.exec.safeBins": "Allow stdin-only safe binaries to run without explicit allowlist entries.", + "hooks.exec.emitEvents": + "Emit exec.started/output/completed gateway events for whitelisted commands (default: true).", + "hooks.exec.commandWhitelist": + "Command basenames eligible for exec event emission (default includes codex, claude, opencode, pi, playwright, and puppeteer).", + "hooks.exec.outputThrottleMs": + "Minimum delay between exec output events per process in milliseconds (default: 150).", + "hooks.exec.outputMaxChunkBytes": + "Maximum bytes per exec output event chunk (default: 4096).", "tools.message.allowCrossContextSend": "Legacy override: allow cross-context sends across all providers.", "tools.message.crossContext.allowWithinProvider": diff --git a/src/config/types.hooks.ts b/src/config/types.hooks.ts index 7ca74605a..837b90a24 100644 --- a/src/config/types.hooks.ts +++ b/src/config/types.hooks.ts @@ -110,6 +110,17 @@ export type InternalHooksConfig = { installs?: Record; }; +export type HooksExecConfig = { + /** Emit exec lifecycle events to gateway clients. */ + emitEvents?: boolean; + /** Allowlist of command names to emit exec events for. */ + commandWhitelist?: string[]; + /** Minimum delay between exec output events per process (ms). */ + outputThrottleMs?: number; + /** Maximum output chunk size per exec output event (bytes). */ + outputMaxChunkBytes?: number; +}; + export type HooksConfig = { enabled?: boolean; path?: string; @@ -121,4 +132,6 @@ export type HooksConfig = { gmail?: HooksGmailConfig; /** Internal agent event hooks */ internal?: InternalHooksConfig; + /** Exec lifecycle event emission settings. */ + exec?: HooksExecConfig; }; diff --git a/src/config/zod-schema.hooks.ts b/src/config/zod-schema.hooks.ts index 35e74f7af..fd2383a72 100644 --- a/src/config/zod-schema.hooks.ts +++ b/src/config/zod-schema.hooks.ts @@ -128,3 +128,13 @@ export const HooksGmailSchema = z }) .strict() .optional(); + +export const HooksExecSchema = z + .object({ + emitEvents: z.boolean().optional(), + commandWhitelist: z.array(z.string()).optional(), + outputThrottleMs: z.number().int().nonnegative().optional(), + outputMaxChunkBytes: z.number().int().positive().optional(), + }) + .strict() + .optional(); diff --git a/src/config/zod-schema.ts b/src/config/zod-schema.ts index ce4115517..bee9d8a5f 100644 --- a/src/config/zod-schema.ts +++ b/src/config/zod-schema.ts @@ -3,7 +3,12 @@ import { ToolsSchema } from "./zod-schema.agent-runtime.js"; import { ApprovalsSchema } from "./zod-schema.approvals.js"; import { AgentsSchema, AudioSchema, BindingsSchema, BroadcastSchema } from "./zod-schema.agents.js"; import { HexColorSchema, ModelsConfigSchema } from "./zod-schema.core.js"; -import { HookMappingSchema, HooksGmailSchema, InternalHooksSchema } from "./zod-schema.hooks.js"; +import { + HookMappingSchema, + HooksExecSchema, + HooksGmailSchema, + InternalHooksSchema, +} from "./zod-schema.hooks.js"; import { ChannelsSchema } from "./zod-schema.providers.js"; import { CommandsSchema, MessagesSchema, SessionSchema } from "./zod-schema.session.js"; @@ -242,6 +247,7 @@ export const MoltbotSchema = z mappings: z.array(HookMappingSchema).optional(), gmail: HooksGmailSchema, internal: InternalHooksSchema, + exec: HooksExecSchema, }) .strict() .optional(),