Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 41 additions & 0 deletions hooks/codebuddy/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# CodeBuddy Code Hook

This directory contains RTK integration files for [CodeBuddy Code](https://cnb.cool/codebuddy/codebuddy-code).

## How it works

RTK installs a `PreToolUse` hook into `~/.codebuddy/settings.json`. When CodeBuddy Code
runs a Bash tool, the hook intercepts the command and rewrites it to use `rtk`, reducing
LLM token consumption by 60-90%.

## Setup

```bash
rtk init -g --agent codebuddy
```

## Files

- `rtk-awareness.md` — Slim RTK awareness instructions written to `~/.codebuddy/CODEBUDDY.md`

## Hook format

CodeBuddy Code uses the same `PreToolUse` JSON protocol as Claude Code:

```json
{
"tool_name": "Bash",
"tool_input": { "command": "git status" }
}
```

The hook responds with:

```json
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": { "command": "rtk git status" }
}
}
```
29 changes: 29 additions & 0 deletions hooks/codebuddy/rtk-awareness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# RTK - Rust Token Killer

**Usage**: Token-optimized CLI proxy (60-90% savings on dev operations)

## Meta Commands (always use rtk directly)

```bash
rtk gain # Show token savings analytics
rtk gain --history # Show command usage history with savings
rtk discover # Analyze CodeBuddy Code history for missed opportunities
rtk proxy <cmd> # Execute raw command without filtering (for debugging)
```

## Installation Verification

```bash
rtk --version # Should show: rtk X.Y.Z
rtk gain # Should work (not "command not found")
which rtk # Verify correct binary
```

⚠️ **Name collision**: If `rtk gain` fails, you may have reachingforthejack/rtk (Rust Type Kit) installed instead.

## Hook-Based Usage

All other commands are automatically rewritten by the CodeBuddy Code hook.
Example: `git status` → `rtk git status` (transparent, 0 tokens overhead)

Refer to CODEBUDDY.md for full command reference.
3 changes: 3 additions & 0 deletions src/hooks/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ pub const BEFORE_TOOL_KEY: &str = "BeforeTool";
pub const CLAUDE_HOOK_COMMAND: &str = "rtk hook claude";
/// Native Rust hook command for Cursor (replaces rtk-rewrite.sh).
pub const CURSOR_HOOK_COMMAND: &str = "rtk hook cursor";
/// Native Rust hook command for CodeBuddy Code (replaces rtk-rewrite.sh).
pub const CODEBUDDY_HOOK_COMMAND: &str = "rtk hook codebuddy";

pub const CONFIG_DIR: &str = ".config";
pub const OPENCODE_SUBDIR: &str = "opencode";
Expand All @@ -26,3 +28,4 @@ pub const HERMES_PLUGINS_SUBDIR: &str = "plugins";
pub const HERMES_PLUGIN_NAME: &str = "rtk-rewrite";
pub const HERMES_PLUGIN_INIT_FILE: &str = "__init__.py";
pub const HERMES_PLUGIN_MANIFEST_FILE: &str = "plugin.yaml";
pub const CODEBUDDY_DIR: &str = ".codebuddy";
41 changes: 41 additions & 0 deletions src/hooks/hook_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,47 @@ fn run_claude_inner(input: &str) -> Option<String> {
}
}

// ── CodeBuddy Code native hook ─────────────────────────────────

/// Run the CodeBuddy Code PreToolUse hook natively.
///
/// CodeBuddy Code uses the same hook JSON protocol as Claude Code
/// (`tool_input.command` + `PreToolUse` event), so we delegate directly
/// to `process_claude_payload`.
pub fn run_codebuddy() -> Result<()> {
let input = read_stdin_limited()?;

let input = input.trim();
if input.is_empty() {
return Ok(());
}

let v: Value = match serde_json::from_str(input) {
Ok(v) => v,
Err(e) => {
let _ = writeln!(io::stderr(), "[rtk hook] Failed to parse JSON input: {e}");
return Ok(());
}
};

match process_claude_payload(&v) {
PayloadAction::Rewrite {
cmd,
rewritten,
output,
} => {
audit_log("rewrite", &cmd, &rewritten);
let _ = writeln!(io::stdout(), "{output}");
}
PayloadAction::Skip { reason, cmd } => {
audit_log(reason, &cmd, "");
}
PayloadAction::Ignore => {}
}

Ok(())
}

// ── Cursor native hook ─────────────────────────────────────────

/// Cursor on Windows ships hook payloads with one or more leading
Expand Down
Loading