Skip to content
Closed
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
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ rtk gain # Should show token savings stats
rtk init -g # Claude Code / Copilot (default)
rtk init -g --gemini # Gemini CLI
rtk init -g --codex # Codex (OpenAI)
rtk init -g --droid # Factory AI Droid
rtk init -g --agent cursor # Cursor
rtk init --agent windsurf # Windsurf
rtk init --agent cline # Cline / Roo Code
Expand Down Expand Up @@ -360,6 +361,7 @@ RTK supports 12 AI coding tools. Each integration transparently rewrites shell c
| **Cursor** | `rtk init -g --agent cursor` | preToolUse hook (hooks.json) |
| **Gemini CLI** | `rtk init -g --gemini` | BeforeTool hook |
| **Codex** | `rtk init -g --codex` | AGENTS.md + RTK.md instructions |
| **Factory AI Droid** | `rtk init -g --droid` | PreToolUse hook (Execute matcher) |
| **Windsurf** | `rtk init --agent windsurf` | .windsurfrules (project-scoped) |
| **Cline / Roo Code** | `rtk init --agent cline` | .clinerules (project-scoped) |
| **OpenCode** | `rtk init -g --opencode` | Plugin TS (tool.execute.before) |
Expand Down
12 changes: 12 additions & 0 deletions hooks/droid/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# Factory AI Droid Hooks

> Part of [`hooks/`](../README.md) — see also [`src/hooks/`](../../src/hooks/README.md) for installation code

## Specifics

- Shell-based `PreToolUse` hook with `Execute` matcher — requires `jq` for JSON parsing
- Returns `updatedInput` JSON for transparent command rewrite (Droid doesn't know RTK is involved)
- Exits silently (exit 0) on any failure: jq missing, rtk missing, rtk too old (< 0.23.0), no match
- Version guard checks `rtk --version` against minimum 0.23.0
- Hook format is identical to Claude Code (same `hookSpecificOutput` JSON structure)
- Config: `~/.factory/settings.json` with `PreToolUse` → `Execute` matcher
25 changes: 25 additions & 0 deletions hooks/droid/rtk-awareness.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# 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 recent 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
```

## Hook-Based Usage

All other commands are automatically rewritten by the Factory Droid hook.
Example: `git status` → `rtk git status` (transparent, 0 tokens overhead)
98 changes: 98 additions & 0 deletions hooks/droid/rtk-rewrite.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# rtk-hook-version: 1
# RTK Factory Droid hook — rewrites commands to use rtk for token savings.
# Requires: rtk >= 0.23.0, jq
#
# This is a thin delegating hook: all rewrite logic lives in `rtk rewrite`,
# which is the single source of truth (src/discover/registry.rs).
# To add or change rewrite rules, edit the Rust registry — not this file.
#
# Exit code protocol for `rtk rewrite`:
# 0 + stdout Rewrite found, no deny/ask rule matched → auto-allow
# 1 No RTK equivalent → pass through unchanged
# 2 Deny rule matched → pass through (Droid native deny handles it)
# 3 + stdout Ask rule matched → rewrite but let Droid prompt the user

if ! command -v jq &>/dev/null; then
echo "[rtk] WARNING: jq is not installed. Hook cannot rewrite commands. Install jq: https://jqlang.github.io/jq/download/" >&2
exit 0
fi

if ! command -v rtk &>/dev/null; then
echo "[rtk] WARNING: rtk is not installed or not in PATH. Hook cannot rewrite commands. Install: https://github.com/rtk-ai/rtk#installation" >&2
exit 0
fi

# Version guard: rtk rewrite was added in 0.23.0.
# Older binaries: warn once and exit cleanly (no silent failure).
RTK_VERSION=$(rtk --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
if [ -n "$RTK_VERSION" ]; then
MAJOR=$(echo "$RTK_VERSION" | cut -d. -f1)
MINOR=$(echo "$RTK_VERSION" | cut -d. -f2)
# Require >= 0.23.0
if [ "$MAJOR" -eq 0 ] && [ "$MINOR" -lt 23 ]; then
echo "[rtk] WARNING: rtk $RTK_VERSION is too old (need >= 0.23.0). Upgrade: cargo install rtk" >&2
exit 0
fi
fi

INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

if [ -z "$CMD" ]; then
exit 0
fi

# Delegate all rewrite + permission logic to the Rust binary.
REWRITTEN=$(rtk rewrite "$CMD" 2>/dev/null)
EXIT_CODE=$?

case $EXIT_CODE in
0)
# Rewrite found, no permission rules matched — safe to auto-allow.
# If the output is identical, the command was already using RTK.
[ "$CMD" = "$REWRITTEN" ] && exit 0
;;
1)
# No RTK equivalent — pass through unchanged.
exit 0
;;
2)
# Deny rule matched — let Droid's native deny rule handle it.
exit 0
;;
3)
# Ask rule matched — rewrite the command but do NOT auto-allow so that
# Droid prompts the user for confirmation.
;;
*)
exit 0
;;
esac

ORIGINAL_INPUT=$(echo "$INPUT" | jq -c '.tool_input')
UPDATED_INPUT=$(echo "$ORIGINAL_INPUT" | jq --arg cmd "$REWRITTEN" '.command = $cmd')

if [ "$EXIT_CODE" -eq 3 ]; then
# Ask: rewrite the command, omit permissionDecision so Droid prompts.
jq -n \
--argjson updated "$UPDATED_INPUT" \
'{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"updatedInput": $updated
}
}'
else
# Allow: rewrite the command and auto-allow.
jq -n \
--argjson updated "$UPDATED_INPUT" \
'{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "RTK auto-rewrite",
"updatedInput": $updated
}
}'
fi
7 changes: 1 addition & 6 deletions src/cmds/js/pnpm_cmd.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,12 +414,7 @@ fn run_install(args: &[String], verbose: u8) -> Result<i32> {

println!("{}", filtered);

timer.track(
&format!("pnpm install"),
&format!("rtk pnpm install"),
&combined,
&filtered,
);
timer.track("pnpm install", "rtk pnpm install", &combined, &filtered);

Ok(0)
}
Expand Down
Loading