(stdout: string)
| 397 | } |
| 398 | |
| 399 | function parseHookOutput(stdout: string): { |
| 400 | json?: HookJSONOutput |
| 401 | plainText?: string |
| 402 | validationError?: string |
| 403 | } { |
| 404 | const trimmed = stdout.trim() |
| 405 | if (!trimmed.startsWith('{')) { |
| 406 | logForDebugging('Hook output does not start with {, treating as plain text') |
| 407 | return { plainText: stdout } |
| 408 | } |
| 409 | |
| 410 | try { |
| 411 | const result = validateHookJson(trimmed) |
| 412 | if ('json' in result) { |
| 413 | return result |
| 414 | } |
| 415 | // For command hooks, include the schema hint in the error message |
| 416 | const errorMessage = `${result.validationError}\n\nExpected schema:\n${jsonStringify( |
| 417 | { |
| 418 | continue: 'boolean (optional)', |
| 419 | suppressOutput: 'boolean (optional)', |
| 420 | stopReason: 'string (optional)', |
| 421 | decision: '"approve" | "block" (optional)', |
| 422 | reason: 'string (optional)', |
| 423 | systemMessage: 'string (optional)', |
| 424 | permissionDecision: '"allow" | "deny" | "ask" (optional)', |
| 425 | hookSpecificOutput: { |
| 426 | 'for PreToolUse': { |
| 427 | hookEventName: '"PreToolUse"', |
| 428 | permissionDecision: '"allow" | "deny" | "ask" (optional)', |
| 429 | permissionDecisionReason: 'string (optional)', |
| 430 | updatedInput: 'object (optional) - Modified tool input to use', |
| 431 | }, |
| 432 | 'for UserPromptSubmit': { |
| 433 | hookEventName: '"UserPromptSubmit"', |
| 434 | additionalContext: 'string (required)', |
| 435 | }, |
| 436 | 'for PostToolUse': { |
| 437 | hookEventName: '"PostToolUse"', |
| 438 | additionalContext: 'string (optional)', |
| 439 | }, |
| 440 | }, |
| 441 | }, |
| 442 | null, |
| 443 | 2, |
| 444 | )}` |
| 445 | logForDebugging(errorMessage) |
| 446 | return { plainText: stdout, validationError: errorMessage } |
| 447 | } catch (e) { |
| 448 | logForDebugging(`Failed to parse hook output as JSON: ${e}`) |
| 449 | return { plainText: stdout } |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | function parseHttpHookOutput(body: string): { |
| 454 | json?: HookJSONOutput |
no test coverage detected