| 3445 | #endif |
| 3446 | |
| 3447 | static int cbm_upsert_codex_hooks_command(const char *config_path, const char *command, |
| 3448 | const char *command_windows) { |
| 3449 | if (!config_path || !command || !command_windows) { |
| 3450 | return CLI_ERR; |
| 3451 | } |
| 3452 | char escaped[CLI_BUF_8K]; |
| 3453 | char escaped_windows[CLI_BUF_8K]; |
| 3454 | if (cbm_toml_escape_basic_string(command, escaped, sizeof(escaped)) != CLI_OK || |
| 3455 | cbm_toml_escape_basic_string(command_windows, escaped_windows, sizeof(escaped_windows)) != |
| 3456 | CLI_OK) { |
| 3457 | return CLI_ERR; |
| 3458 | } |
| 3459 | char block[CLI_BUF_8K]; |
| 3460 | int written = snprintf(block, sizeof(block), |
| 3461 | "[[hooks.SessionStart]]\n" |
| 3462 | "matcher = \"startup|resume|clear|compact\"\n\n" |
| 3463 | "[[hooks.SessionStart.hooks]]\n" |
| 3464 | "type = \"command\"\n" |
| 3465 | "command = \"%s\"\n" |
| 3466 | "command_windows = \"%s\"\n" |
| 3467 | "timeout = 5\n\n" |
| 3468 | "[[hooks.SubagentStart]]\n" |
| 3469 | "matcher = \"*\"\n\n" |
| 3470 | "[[hooks.SubagentStart.hooks]]\n" |
| 3471 | "type = \"command\"\n" |
| 3472 | "command = \"%s\"\n" |
| 3473 | "command_windows = \"%s\"\n" |
| 3474 | "timeout = 5\n", |
| 3475 | escaped, escaped_windows, escaped, escaped_windows); |
| 3476 | if (written < 0 || (size_t)written >= sizeof(block)) { |
| 3477 | return CLI_ERR; |
| 3478 | } |
| 3479 | return cbm_toml_upsert_managed_block(config_path, CODEX_HOOK_BEGIN, CODEX_HOOK_END, block) == 0 |
| 3480 | ? CLI_OK |
| 3481 | : CLI_ERR; |
| 3482 | } |
| 3483 | |
| 3484 | /* Public path used by config-level regression tests and manual callers. */ |
| 3485 | int cbm_upsert_codex_hooks(const char *config_path) { |
no test coverage detected