Skip to main content

spool/cli/
hook.rs

1//! `spool hook <subcommand>` command handlers.
2//!
3//! Thin glue between clap arg structs and `hook_runtime` entry points.
4//! Each handler wraps the actual hook in [`hook_runtime::run_silent`]
5//! so any internal failure becomes a stderr log + exit 0 (D7).
6
7use crate::cli::args::{
8    HookArgs, HookCommand, HookPostToolUseArgs, HookSessionStartArgs, HookSimpleArgs, HookStopArgs,
9};
10use crate::domain::WakeupProfile;
11use crate::hook_runtime::{self, post_tool_use, pre_compact, session_start, stop, user_prompt};
12
13pub fn execute(args: HookArgs) -> anyhow::Result<()> {
14    match args.command {
15        HookCommand::SessionStart(a) => execute_session_start(a),
16        HookCommand::UserPrompt(a) => execute_user_prompt(a),
17        HookCommand::PostToolUse(a) => execute_post_tool_use(a),
18        HookCommand::Stop(a) => execute_stop(a),
19        HookCommand::PreCompact(a) => execute_pre_compact(a),
20    }
21}
22
23fn execute_session_start(args: HookSessionStartArgs) -> anyhow::Result<()> {
24    hook_runtime::run_silent("session-start", || {
25        session_start::run(session_start::SessionStartArgs {
26            config_path: args.config,
27            cwd: args.cwd,
28            task: args.task,
29            profile: WakeupProfile::from(args.profile),
30        })
31    });
32    Ok(())
33}
34
35fn execute_user_prompt(args: HookSimpleArgs) -> anyhow::Result<()> {
36    hook_runtime::run_silent("user-prompt", || {
37        user_prompt::run(user_prompt::UserPromptArgs {
38            config_path: args.config,
39            cwd: args.cwd,
40            prompt_override: None,
41        })
42    });
43    Ok(())
44}
45
46fn execute_post_tool_use(args: HookPostToolUseArgs) -> anyhow::Result<()> {
47    hook_runtime::run_silent("post-tool-use", || {
48        post_tool_use::run(post_tool_use::PostToolUseArgs {
49            config_path: args.config,
50            cwd: args.cwd,
51            tool_name: args.tool_name,
52            payload: args.payload,
53        })
54    });
55    Ok(())
56}
57
58fn execute_stop(args: HookStopArgs) -> anyhow::Result<()> {
59    hook_runtime::run_silent("stop", || {
60        stop::run(stop::StopArgs {
61            config_path: args.config,
62            cwd: args.cwd,
63            transcript_path: args.transcript_path,
64            hook_input: args.hook_input,
65            home: args.home,
66        })
67        .map(|_report| ())
68    });
69    Ok(())
70}
71
72fn execute_pre_compact(args: HookSimpleArgs) -> anyhow::Result<()> {
73    hook_runtime::run_silent("pre-compact", || {
74        pre_compact::run(pre_compact::PreCompactArgs {
75            config_path: args.config,
76            cwd: args.cwd,
77            context_override: None,
78        })?;
79        Ok(())
80    });
81    Ok(())
82}