fix: Preserve user custom hooks when enabling mi6

Resolved 💬 3 comments Opened Jan 11, 2026 by sslivkoff Closed Jan 11, 2026

Problem

When mi6 enables hooks, it replaces the entire hook array for each event type, destroying any custom hooks the user may have configured.

Current merge behavior:

User has existing settings.json:

{
  "hooks": {
    "BeforeTool": [
      { "command": "my-custom-logger --event tool" }
    ]
  }
}

After mi6 enable, the custom hook is GONE:

{
  "hooks": {
    "BeforeTool": [
      { "command": "mi6 ingest event BeforeTool ..." }
    ]
  }
}

Expected Behavior

mi6 should append its hooks to existing ones, not replace:

{
  "hooks": {
    "BeforeTool": [
      { "command": "my-custom-logger --event tool" },
      { "command": "mi6 ingest event BeforeTool ..." }
    ]
  }
}

Implementation Notes

  1. When merging hooks, check if mi6 hook already exists (by command prefix "mi6 ingest")
  2. If mi6 hook exists, update it in place
  3. If mi6 hook does not exist, append to array
  4. Never remove non-mi6 hooks
fn merge_hooks(existing: &mut Value, mi6_hooks: Value) {
    for (event_type, mi6_hook) in mi6_hooks.as_object() {
        let hooks_array = existing[event_type].as_array_mut();

        // Remove old mi6 hook if present
        hooks_array.retain(|h| !is_mi6_hook(h));

        // Append new mi6 hook
        hooks_array.push(mi6_hook);
    }
}

fn is_mi6_hook(hook: &Value) -> bool {
    hook["command"].as_str()
        .map(|c| c.starts_with("mi6 ingest"))
        .unwrap_or(false)
}

Scope

  • Affects merge_config() in each framework adapter
  • Applies to JSON-based frameworks (Claude, Gemini, Cursor)
  • TOML frameworks (Codex) need equivalent logic

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗