5 Commits
Author SHA1 Message Date
Felipe Neves RicardoandClaude Opus 5.5 2c0fab6155 fix(hooks): send the [briefing] keys on the session-start handoff GET (#998)
docs/marker-file.md says the hook scripts forward `briefing` and
`briefing_budget` on the handoff lookup when the marker opts in. Only the
Kiro CLI and Kimi Code scripts did; the session-start scripts of Claude
Code, Codex, Cursor, Gemini CLI, OpenCode, Command Code, Devin and
Antigravity CLI built the GET from ai_memory_marker_qs alone, and the
PowerShell library added the briefing query only for Kimi and Grok. A
script install with `inject_on_session_start = true` therefore got the
handoff without the brief, while the native `ai-memory hook` command
sent both.

Each of those scripts now appends ai_memory_briefing_qs to its handoff
GET, and Invoke-AiMemoryHook adds Get-AiMemoryBriefingQuery to every
session-start fetch outside Kiro's once-per-session gate. No gate is
added: the native session-start path sends the keys on every start.

tests/hooks/test_lib.sh discovers every bundle whose session-start.sh
fetches the handoff and asserts the keys are present when the marker
opts in and absent when it opts out, plus a static check on the
PowerShell library.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019KhB86k7H61CePGZdxtwyz
2026-09-30 17:51:53 -03:00
AkitaOnRails 78904b82ed fix(hooks): preserve handoffs across empty sessions (#386) 2026-08-12 00:57:00 -03:00
AkitaOnRails e577e4b60f fix(hooks): finish marker integration 2026-05-25 16:23:28 -03:00
AkitaOnRails 80c068b95e feat: add Windows hook support 2026-05-25 13:56:51 -03:00
AkitaOnRailsandClaude Opus 4.7 6744ce33f7 install-hooks: support cursor + gemini-cli + open-code + openclaw
After research against each agent's official docs / repo, completed
the install-hooks --apply matrix:

  agent       | shape              | config file
  ------------|--------------------|---------------------------------
  claude-code | nested JSON        | ~/.claude/settings.json
  codex       | nested JSON        | ~/.codex/hooks.json
  cursor      | flat JSON          | ~/.cursor/hooks.json
  gemini-cli  | nested JSON        | ~/.gemini/settings.json
  open-code   | TypeScript plugin  | ~/.config/opencode/plugins/ai-memory.ts
  openclaw    | (no lifecycle hooks supported — only HTTP webhooks)

## Architecture

Refactored `render_shared.rs` into a data-driven design:

  pub(crate) enum HookShape { Nested, Flat }
  pub(crate) struct HookProfile {
      pub events: &'static [(&'static str, &'static str)],
      pub shape: HookShape,
  }
  pub(crate) const {CLAUDE_CODE,CODEX,CURSOR,GEMINI}_PROFILE: HookProfile = …;
  pub(crate) fn build_profile_payload(&HookProfile, …) -> Value;

Adding a new JSON-config agent now needs only:
  - hook script dir under hooks/<agent-name>/
  - an event list constant + a HookProfile
  - a thin apply_to_<agent>_settings() function pointing at the right
    config-file path

No control-flow branching for new agents — the shape variant in the
profile is enough.

## Per-agent specifics discovered

  - Cursor: FLAT shape (no inner `hooks` array), camelCase events,
    requires top-level `"version": 1` key. ai-memory's
    `beforeSubmitPrompt` is Cursor's closest match to
    UserPromptSubmit. (Source: https://cursor.com/docs/agent/hooks)
  - Gemini CLI: nested shape (same as Claude Code), PascalCase
    events, DIFFERENT vocabulary:
      BeforeTool / AfterTool  (≈ PreToolUse / PostToolUse)
      PreCompress             (≈ PreCompact)
      No UserPromptSubmit / Stop equivalents — skipped.
    (Source: https://geminicli.com/docs/hooks/reference)
  - Codex: nested shape, PascalCase, NO SessionEnd (uses Stop for
    both turn-end and session-end). (Source:
    openai/codex/codex-rs/config/src/hooks_tests.rs)
  - OpenCode: hooks via TypeScript plugin, NOT JSON. Event names
    use dot.case (`session.created`, `tool.execute.before`).
    apply path generates a `.ts` file under
    ~/.config/opencode/plugins/ that uses Bun's shell ($) to
    invoke ai-memory's shell hooks. (Source:
    https://opencode.ai/docs/plugins/)
  - OpenClaw: confirmed via https://docs.openclaw.ai/gateway/configuration
    that it has NO lifecycle hooks — only HTTP webhook ingress.
    apply path prints the explanation + workaround suggestion
    rather than silently doing nothing.

## hooks/ directory

Two new agent dirs: hooks/cursor/, hooks/gemini-cli/ (copied from
claude-code/ with `agent=NAME` substituted in the curl query
strings). All hook scripts remain functionally identical — only
the agent-label tag in the URL differs.

## Tests

  - `cursor_payload_uses_flat_shape` — asserts no inner `hooks`
    array, camelCase events, command at outer level.
  - `gemini_payload_uses_nested_shape_with_gemini_event_names` —
    asserts CC's nested shape + Gemini-specific event vocab,
    forbids CC-only events from leaking through.
  - Existing claude_code_payload_* + codex tests continue to pass
    against the shared `build_profile_payload` path.

All workspace tests green; clippy clean.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-22 23:47:05 -03:00