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