Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# CLAUDE.md

@RTK.md

## After every change

Always execute tasks in this order:
Expand All @@ -18,4 +20,4 @@ Always execute tasks in this order:

## Git

- Do not ever commit to the default, `main`, or `master` Git branches. Always ask if a new branch should be created instead.
- Do not ever commit to the default, `main`, or `master` Git branches. Always ask if a new branch should be created instead.
29 changes: 29 additions & 0 deletions .claude/RTK.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 Claude 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 Claude Code hook.
Example: `git status` → `rtk git status` (transparent, 0 tokens overhead)

Refer to CLAUDE.md for full command reference.
1 change: 1 addition & 0 deletions .claude/hooks/.rtk-hook.sha256
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ef0d630994fd7ef5f2b84fb66cd6249c493bb8736bcacd4734d7c798125018fb rtk-rewrite.sh
98 changes: 98 additions & 0 deletions .claude/hooks/rtk-rewrite.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env bash
# rtk-hook-version: 3
# RTK Claude Code 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 (Claude Code native deny handles it)
# 3 + stdout Ask rule matched → rewrite but let Claude Code 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 Claude Code's native deny rule handle it.
exit 0
;;
3)
# Ask rule matched — rewrite the command but do NOT auto-allow so that
# Claude Code 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 Claude Code 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
13 changes: 12 additions & 1 deletion .claude/settings.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"model": "us.anthropic.claude-opus-4-6-v1",
"model": "opus",
"hooks": {
"Notification": [
{
Expand All @@ -22,6 +22,17 @@
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "/Users/cemmer/.claude/hooks/rtk-rewrite.sh"
}
]
}
]
},
"statusLine": {
Expand Down
5 changes: 3 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Secrets
*secrets.bash
*secrets.*
id_rsa*
*kubeconfig*
*.pem
Expand All @@ -9,7 +9,8 @@ id_rsa*
!.config/powerline

.claude/*
!.claude/hooks
!.claude/skills
.claude/skills/githuman
!.claude/CLAUDE.md
!.claude/*.md
!.claude/settings.json
21 changes: 13 additions & 8 deletions dotpack/.10_macos.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,19 @@ fi

# https://docs.brew.sh/Shell-Completion
if type brew &>/dev/null; then
HOMEBREW_PREFIX="$(brew --prefix)"
if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]]; then
source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
else
for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*; do
# shellcheck disable=SC1090
[[ -r "${COMPLETION}" ]] && source "${COMPLETION}"
done
if [[ "$(basename "${SHELL}")" == "zsh" ]]; then
autoload -Uz compinit
compinit
elif [[ "$(basename "${SHELL}")" == "bash" ]]; then
HOMEBREW_PREFIX="$(brew --prefix)"
if [[ -r "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh" ]]; then
source "${HOMEBREW_PREFIX}/etc/profile.d/bash_completion.sh"
else
for COMPLETION in "${HOMEBREW_PREFIX}/etc/bash_completion.d/"*; do
# shellcheck disable=SC1090
[[ -r "${COMPLETION}" ]] && source "${COMPLETION}"
done
fi
fi
fi

Expand Down
2 changes: 2 additions & 0 deletions dotpack/.30_claude.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
##### https://code.claude.com/docs/en/overview

export RTK_TELEMETRY_DISABLED=1

__claude_auto_update() {
if command -v claude &> /dev/null; then
claude() {
Expand Down
2 changes: 1 addition & 1 deletion install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function link() {

# Assume symlinks are ok
if [[ -h "${link}" ]]; then
echo -e "\033[93mIgnoring:\033[0m ${link}"
echo -e "\033[33mIgnoring:\033[0m ${link}"
continue
fi

Expand Down
27 changes: 24 additions & 3 deletions packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ if [[ "${OSTYPE:-}" == "darwin"* ]]; then
fi
command -v jq > /dev/null || brew install jq
command -v rename > /dev/null || brew install rename
command -v rtk > /dev/null || brew install rtk
command -v terminal-notifier > /dev/null || brew install terminal-notifier
command -v tree > /dev/null || brew install tree
command -v watch > /dev/null || brew install watch
Expand Down Expand Up @@ -58,6 +59,7 @@ if [[ "${OSTYPE:-}" == "darwin"* ]]; then
#echo "nordvpn"
#echo "postman"
echo "rectangle"
echo "resilio-sync"
#echo "sdformatter"
#echo "signal"
#echo "slack"
Expand All @@ -74,10 +76,29 @@ if [[ "${OSTYPE:-}" == "darwin"* ]]; then
| jq --raw-output ".casks[] | select(.token==\"${cask}\") | .artifacts[] | .app // empty | .[]" \
| xargs -I {} sh -c 'test ! -d "/Applications/{}" && echo "{}"' || true)
if [[ -n "${missing_apps}" ]]; then
echo "missing, installing ..."
echo -e "\033[33mmissing, installing ...\033[0m"
brew install --cask "${cask}"
else
echo "found"
echo -e "\033[92mfound\033[0m"
fi
done

# Uninstall old Homebrew casks
if ! sudo -n true &> /dev/null; then
echo -e "\033[1;33mWARN:\033[0m you may be asked for your password to run 'brew uninstall --cask'\n"
fi
for cask in $(
echo "messenger"
); do
printf "Checking for cask '${cask}' ... "
existing_apps=$(brew info --json=v2 --cask "${cask}" \
| jq --raw-output ".casks[] | select(.token==\"${cask}\") | .artifacts[] | .app // empty | .[]" \
| xargs -I {} sh -c 'test -d "/Applications/{}" && echo "{}"' || true)
if [[ -n "${existing_apps}" ]]; then
echo -e "\033[33mfound, uninstalling ...\033[0m"
brew uninstall --cask "${cask}"
else
echo -e "\033[92mnot found\033[0m"
fi
done

Expand Down Expand Up @@ -114,6 +135,6 @@ if [[ "${OSTYPE:-}" == "darwin"* ]]; then
if ! sudo -n true &> /dev/null; then
echo -e "\033[1;33mWARN:\033[0m you may be asked for your password to run 'xcodebuild -license'\n"
fi
sudo xcodebuild -license status || sudo xcodebuild -license accept
sudo xcodebuild -license status || sudo xcodebuild -license accept || true
fi
fi
Loading