| 3383 | #endif |
| 3384 | |
| 3385 | static int cbm_upsert_codex_hooks_command(const char *config_path, const char *command, |
| 3386 | const char *command_windows) { |
| 3387 | if (!config_path || !command || !command_windows) { |
| 3388 | return CLI_ERR; |
| 3389 | } |
| 3390 | char escaped[CLI_BUF_8K]; |
| 3391 | char escaped_windows[CLI_BUF_8K]; |
| 3392 | if (cbm_toml_escape_basic_string(command, escaped, sizeof(escaped)) != CLI_OK || |
| 3393 | cbm_toml_escape_basic_string(command_windows, escaped_windows, sizeof(escaped_windows)) != |
| 3394 | CLI_OK) { |
| 3395 | return CLI_ERR; |
| 3396 | } |
| 3397 | char block[CLI_BUF_8K]; |
| 3398 | int written = snprintf(block, sizeof(block), |
| 3399 | "[[hooks.SessionStart]]\n" |
| 3400 | "matcher = \"startup|resume|clear|compact\"\n\n" |
| 3401 | "[[hooks.SessionStart.hooks]]\n" |
| 3402 | "type = \"command\"\n" |
| 3403 | "command = \"%s\"\n" |
| 3404 | "command_windows = \"%s\"\n" |
| 3405 | "timeout = 5\n\n" |
| 3406 | "[[hooks.SubagentStart]]\n" |
| 3407 | "matcher = \"*\"\n\n" |
| 3408 | "[[hooks.SubagentStart.hooks]]\n" |
| 3409 | "type = \"command\"\n" |
| 3410 | "command = \"%s\"\n" |
| 3411 | "command_windows = \"%s\"\n" |
| 3412 | "timeout = 5\n", |
| 3413 | escaped, escaped_windows, escaped, escaped_windows); |
| 3414 | if (written < 0 || (size_t)written >= sizeof(block)) { |
| 3415 | return CLI_ERR; |
| 3416 | } |
| 3417 | return cbm_toml_upsert_managed_block(config_path, CODEX_HOOK_BEGIN, CODEX_HOOK_END, block) == 0 |
| 3418 | ? CLI_OK |
| 3419 | : CLI_ERR; |
| 3420 | } |
| 3421 | |
| 3422 | /* Public path used by config-level regression tests and manual callers. */ |
| 3423 | int cbm_upsert_codex_hooks(const char *config_path) { |
no test coverage detected