({
json: rawJson,
command,
hookName,
toolUseID,
hookEvent,
expectedHookEvent,
stdout,
stderr,
exitCode,
durationMs,
}: {
json: SyncHookJSONOutput
command: string
hookName: string
toolUseID: string
hookEvent: HookEvent
expectedHookEvent?: HookEvent
stdout?: string
stderr?: string
exitCode?: number
durationMs?: number
})
| 567 | } |
| 568 | |
| 569 | function processHookJSONOutput({ |
| 570 | json: rawJson, |
| 571 | command, |
| 572 | hookName, |
| 573 | toolUseID, |
| 574 | hookEvent, |
| 575 | expectedHookEvent, |
| 576 | stdout, |
| 577 | stderr, |
| 578 | exitCode, |
| 579 | durationMs, |
| 580 | }: { |
| 581 | json: SyncHookJSONOutput |
| 582 | command: string |
| 583 | hookName: string |
| 584 | toolUseID: string |
| 585 | hookEvent: HookEvent |
| 586 | expectedHookEvent?: HookEvent |
| 587 | stdout?: string |
| 588 | stderr?: string |
| 589 | exitCode?: number |
| 590 | durationMs?: number |
| 591 | }): Partial<HookResult> { |
| 592 | const result: Partial<HookResult> = {} |
| 593 | |
| 594 | // Cast to typed interface for type-safe property access |
| 595 | const json = rawJson as TypedSyncHookOutput |
| 596 | |
| 597 | // At this point we know it's a sync response |
| 598 | const syncJson = json |
| 599 | |
| 600 | // Handle common elements |
| 601 | if (syncJson.continue === false) { |
| 602 | result.preventContinuation = true |
| 603 | if (syncJson.stopReason) { |
| 604 | result.stopReason = syncJson.stopReason |
| 605 | } |
| 606 | } |
| 607 | |
| 608 | if (json.decision) { |
| 609 | switch (json.decision) { |
| 610 | case 'approve': |
| 611 | result.permissionBehavior = 'allow' |
| 612 | break |
| 613 | case 'block': |
| 614 | result.permissionBehavior = 'deny' |
| 615 | result.blockingError = { |
| 616 | blockingError: json.reason || 'Blocked by hook', |
| 617 | command, |
| 618 | } |
| 619 | break |
| 620 | default: |
| 621 | // Handle unknown decision types as errors |
| 622 | throw new Error( |
| 623 | `Unknown hook decision type: ${json.decision}. Valid types are: approve, block`, |
| 624 | ) |
| 625 | } |
| 626 | } |
no test coverage detected