@hasna/terminal 2.3.0 → 2.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.js +404 -0
- package/dist/Browse.js +79 -0
- package/dist/FuzzyPicker.js +47 -0
- package/dist/Onboarding.js +51 -0
- package/dist/Spinner.js +12 -0
- package/dist/StatusBar.js +49 -0
- package/dist/ai.js +322 -0
- package/dist/cache.js +41 -0
- package/dist/cli.js +64 -16
- package/dist/command-rewriter.js +64 -0
- package/dist/command-validator.js +86 -0
- package/dist/compression.js +107 -0
- package/dist/context-hints.js +275 -0
- package/dist/diff-cache.js +107 -0
- package/dist/discover.js +212 -0
- package/dist/economy.js +123 -0
- package/dist/expand-store.js +38 -0
- package/dist/file-cache.js +72 -0
- package/dist/file-index.js +62 -0
- package/dist/history.js +62 -0
- package/dist/lazy-executor.js +54 -0
- package/dist/line-dedup.js +59 -0
- package/dist/loop-detector.js +75 -0
- package/dist/mcp/install.js +98 -0
- package/dist/mcp/server.js +569 -0
- package/dist/noise-filter.js +86 -0
- package/dist/output-processor.js +129 -0
- package/dist/output-router.js +41 -0
- package/dist/output-store.js +111 -0
- package/dist/parsers/base.js +2 -0
- package/dist/parsers/build.js +64 -0
- package/dist/parsers/errors.js +101 -0
- package/dist/parsers/files.js +78 -0
- package/dist/parsers/git.js +99 -0
- package/dist/parsers/index.js +48 -0
- package/dist/parsers/tests.js +89 -0
- package/dist/providers/anthropic.js +39 -0
- package/dist/providers/base.js +4 -0
- package/dist/providers/cerebras.js +95 -0
- package/dist/providers/groq.js +95 -0
- package/dist/providers/index.js +73 -0
- package/dist/providers/xai.js +95 -0
- package/dist/recipes/model.js +20 -0
- package/dist/recipes/storage.js +136 -0
- package/dist/search/content-search.js +68 -0
- package/dist/search/file-search.js +61 -0
- package/dist/search/filters.js +34 -0
- package/dist/search/index.js +5 -0
- package/dist/search/semantic.js +320 -0
- package/dist/session-boot.js +59 -0
- package/dist/session-context.js +55 -0
- package/dist/sessions-db.js +173 -0
- package/dist/smart-display.js +286 -0
- package/dist/snapshots.js +51 -0
- package/dist/supervisor.js +112 -0
- package/dist/test-watchlist.js +131 -0
- package/dist/tool-profiles.js +122 -0
- package/dist/tree.js +94 -0
- package/dist/usage-cache.js +65 -0
- package/package.json +8 -1
- package/src/ai.ts +8 -0
- package/src/cli.tsx +57 -18
- package/src/output-processor.ts +6 -1
- package/src/output-store.ts +58 -12
- package/src/tool-profiles.ts +139 -0
- package/.claude/scheduled_tasks.lock +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -20
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
- package/CONTRIBUTING.md +0 -80
- package/benchmarks/benchmark.mjs +0 -115
- package/imported_modules.txt +0 -0
- package/temp/rtk/.claude/agents/code-reviewer.md +0 -221
- package/temp/rtk/.claude/agents/debugger.md +0 -519
- package/temp/rtk/.claude/agents/rtk-testing-specialist.md +0 -461
- package/temp/rtk/.claude/agents/rust-rtk.md +0 -511
- package/temp/rtk/.claude/agents/technical-writer.md +0 -355
- package/temp/rtk/.claude/commands/diagnose.md +0 -352
- package/temp/rtk/.claude/commands/test-routing.md +0 -362
- package/temp/rtk/.claude/hooks/bash/pre-commit-format.sh +0 -16
- package/temp/rtk/.claude/hooks/rtk-rewrite.sh +0 -70
- package/temp/rtk/.claude/hooks/rtk-suggest.sh +0 -152
- package/temp/rtk/.claude/rules/cli-testing.md +0 -526
- package/temp/rtk/.claude/skills/issue-triage/SKILL.md +0 -348
- package/temp/rtk/.claude/skills/issue-triage/templates/issue-comment.md +0 -134
- package/temp/rtk/.claude/skills/performance.md +0 -435
- package/temp/rtk/.claude/skills/pr-triage/SKILL.md +0 -315
- package/temp/rtk/.claude/skills/pr-triage/templates/review-comment.md +0 -71
- package/temp/rtk/.claude/skills/repo-recap.md +0 -206
- package/temp/rtk/.claude/skills/rtk-tdd/SKILL.md +0 -78
- package/temp/rtk/.claude/skills/rtk-tdd/references/testing-patterns.md +0 -124
- package/temp/rtk/.claude/skills/security-guardian.md +0 -503
- package/temp/rtk/.claude/skills/ship.md +0 -404
- package/temp/rtk/.github/workflows/benchmark.yml +0 -34
- package/temp/rtk/.github/workflows/dco-check.yaml +0 -12
- package/temp/rtk/.github/workflows/release-please.yml +0 -51
- package/temp/rtk/.github/workflows/release.yml +0 -343
- package/temp/rtk/.github/workflows/security-check.yml +0 -135
- package/temp/rtk/.github/workflows/validate-docs.yml +0 -78
- package/temp/rtk/.release-please-manifest.json +0 -3
- package/temp/rtk/ARCHITECTURE.md +0 -1491
- package/temp/rtk/CHANGELOG.md +0 -640
- package/temp/rtk/CLAUDE.md +0 -605
- package/temp/rtk/CONTRIBUTING.md +0 -199
- package/temp/rtk/Cargo.lock +0 -1668
- package/temp/rtk/Cargo.toml +0 -64
- package/temp/rtk/Formula/rtk.rb +0 -43
- package/temp/rtk/INSTALL.md +0 -390
- package/temp/rtk/LICENSE +0 -21
- package/temp/rtk/README.md +0 -386
- package/temp/rtk/README_es.md +0 -159
- package/temp/rtk/README_fr.md +0 -197
- package/temp/rtk/README_ja.md +0 -159
- package/temp/rtk/README_ko.md +0 -159
- package/temp/rtk/README_zh.md +0 -167
- package/temp/rtk/ROADMAP.md +0 -15
- package/temp/rtk/SECURITY.md +0 -217
- package/temp/rtk/TEST_EXEC_TIME.md +0 -102
- package/temp/rtk/build.rs +0 -57
- package/temp/rtk/docs/AUDIT_GUIDE.md +0 -432
- package/temp/rtk/docs/FEATURES.md +0 -1410
- package/temp/rtk/docs/TROUBLESHOOTING.md +0 -309
- package/temp/rtk/docs/filter-workflow.md +0 -102
- package/temp/rtk/docs/images/gain-dashboard.jpg +0 -0
- package/temp/rtk/docs/tracking.md +0 -583
- package/temp/rtk/hooks/opencode-rtk.ts +0 -39
- package/temp/rtk/hooks/rtk-awareness.md +0 -29
- package/temp/rtk/hooks/rtk-rewrite.sh +0 -61
- package/temp/rtk/hooks/test-rtk-rewrite.sh +0 -442
- package/temp/rtk/install.sh +0 -124
- package/temp/rtk/release-please-config.json +0 -10
- package/temp/rtk/scripts/benchmark.sh +0 -592
- package/temp/rtk/scripts/check-installation.sh +0 -162
- package/temp/rtk/scripts/install-local.sh +0 -37
- package/temp/rtk/scripts/rtk-economics.sh +0 -137
- package/temp/rtk/scripts/test-all.sh +0 -561
- package/temp/rtk/scripts/test-aristote.sh +0 -227
- package/temp/rtk/scripts/test-tracking.sh +0 -79
- package/temp/rtk/scripts/update-readme-metrics.sh +0 -32
- package/temp/rtk/scripts/validate-docs.sh +0 -73
- package/temp/rtk/src/aws_cmd.rs +0 -880
- package/temp/rtk/src/binlog.rs +0 -1645
- package/temp/rtk/src/cargo_cmd.rs +0 -1727
- package/temp/rtk/src/cc_economics.rs +0 -1157
- package/temp/rtk/src/ccusage.rs +0 -340
- package/temp/rtk/src/config.rs +0 -187
- package/temp/rtk/src/container.rs +0 -855
- package/temp/rtk/src/curl_cmd.rs +0 -134
- package/temp/rtk/src/deps.rs +0 -268
- package/temp/rtk/src/diff_cmd.rs +0 -367
- package/temp/rtk/src/discover/mod.rs +0 -274
- package/temp/rtk/src/discover/provider.rs +0 -388
- package/temp/rtk/src/discover/registry.rs +0 -2022
- package/temp/rtk/src/discover/report.rs +0 -202
- package/temp/rtk/src/discover/rules.rs +0 -667
- package/temp/rtk/src/display_helpers.rs +0 -402
- package/temp/rtk/src/dotnet_cmd.rs +0 -1771
- package/temp/rtk/src/dotnet_format_report.rs +0 -133
- package/temp/rtk/src/dotnet_trx.rs +0 -593
- package/temp/rtk/src/env_cmd.rs +0 -204
- package/temp/rtk/src/filter.rs +0 -462
- package/temp/rtk/src/filters/README.md +0 -52
- package/temp/rtk/src/filters/ansible-playbook.toml +0 -34
- package/temp/rtk/src/filters/basedpyright.toml +0 -47
- package/temp/rtk/src/filters/biome.toml +0 -45
- package/temp/rtk/src/filters/brew-install.toml +0 -37
- package/temp/rtk/src/filters/composer-install.toml +0 -40
- package/temp/rtk/src/filters/df.toml +0 -16
- package/temp/rtk/src/filters/dotnet-build.toml +0 -64
- package/temp/rtk/src/filters/du.toml +0 -16
- package/temp/rtk/src/filters/fail2ban-client.toml +0 -15
- package/temp/rtk/src/filters/gcc.toml +0 -49
- package/temp/rtk/src/filters/gcloud.toml +0 -22
- package/temp/rtk/src/filters/hadolint.toml +0 -24
- package/temp/rtk/src/filters/helm.toml +0 -29
- package/temp/rtk/src/filters/iptables.toml +0 -27
- package/temp/rtk/src/filters/jj.toml +0 -28
- package/temp/rtk/src/filters/jq.toml +0 -24
- package/temp/rtk/src/filters/make.toml +0 -41
- package/temp/rtk/src/filters/markdownlint.toml +0 -24
- package/temp/rtk/src/filters/mix-compile.toml +0 -27
- package/temp/rtk/src/filters/mix-format.toml +0 -15
- package/temp/rtk/src/filters/mvn-build.toml +0 -44
- package/temp/rtk/src/filters/oxlint.toml +0 -43
- package/temp/rtk/src/filters/ping.toml +0 -63
- package/temp/rtk/src/filters/pio-run.toml +0 -40
- package/temp/rtk/src/filters/poetry-install.toml +0 -50
- package/temp/rtk/src/filters/pre-commit.toml +0 -35
- package/temp/rtk/src/filters/ps.toml +0 -16
- package/temp/rtk/src/filters/quarto-render.toml +0 -41
- package/temp/rtk/src/filters/rsync.toml +0 -48
- package/temp/rtk/src/filters/shellcheck.toml +0 -27
- package/temp/rtk/src/filters/shopify-theme.toml +0 -29
- package/temp/rtk/src/filters/skopeo.toml +0 -45
- package/temp/rtk/src/filters/sops.toml +0 -16
- package/temp/rtk/src/filters/ssh.toml +0 -44
- package/temp/rtk/src/filters/stat.toml +0 -34
- package/temp/rtk/src/filters/swift-build.toml +0 -41
- package/temp/rtk/src/filters/systemctl-status.toml +0 -33
- package/temp/rtk/src/filters/terraform-plan.toml +0 -35
- package/temp/rtk/src/filters/tofu-fmt.toml +0 -16
- package/temp/rtk/src/filters/tofu-init.toml +0 -38
- package/temp/rtk/src/filters/tofu-plan.toml +0 -35
- package/temp/rtk/src/filters/tofu-validate.toml +0 -17
- package/temp/rtk/src/filters/trunk-build.toml +0 -39
- package/temp/rtk/src/filters/ty.toml +0 -50
- package/temp/rtk/src/filters/uv-sync.toml +0 -37
- package/temp/rtk/src/filters/xcodebuild.toml +0 -99
- package/temp/rtk/src/filters/yamllint.toml +0 -25
- package/temp/rtk/src/find_cmd.rs +0 -598
- package/temp/rtk/src/format_cmd.rs +0 -386
- package/temp/rtk/src/gain.rs +0 -723
- package/temp/rtk/src/gh_cmd.rs +0 -1651
- package/temp/rtk/src/git.rs +0 -2012
- package/temp/rtk/src/go_cmd.rs +0 -592
- package/temp/rtk/src/golangci_cmd.rs +0 -254
- package/temp/rtk/src/grep_cmd.rs +0 -288
- package/temp/rtk/src/gt_cmd.rs +0 -810
- package/temp/rtk/src/hook_audit_cmd.rs +0 -283
- package/temp/rtk/src/hook_check.rs +0 -171
- package/temp/rtk/src/init.rs +0 -1859
- package/temp/rtk/src/integrity.rs +0 -537
- package/temp/rtk/src/json_cmd.rs +0 -231
- package/temp/rtk/src/learn/detector.rs +0 -628
- package/temp/rtk/src/learn/mod.rs +0 -119
- package/temp/rtk/src/learn/report.rs +0 -184
- package/temp/rtk/src/lint_cmd.rs +0 -694
- package/temp/rtk/src/local_llm.rs +0 -316
- package/temp/rtk/src/log_cmd.rs +0 -248
- package/temp/rtk/src/ls.rs +0 -324
- package/temp/rtk/src/main.rs +0 -2482
- package/temp/rtk/src/mypy_cmd.rs +0 -389
- package/temp/rtk/src/next_cmd.rs +0 -241
- package/temp/rtk/src/npm_cmd.rs +0 -236
- package/temp/rtk/src/parser/README.md +0 -267
- package/temp/rtk/src/parser/error.rs +0 -46
- package/temp/rtk/src/parser/formatter.rs +0 -336
- package/temp/rtk/src/parser/mod.rs +0 -311
- package/temp/rtk/src/parser/types.rs +0 -119
- package/temp/rtk/src/pip_cmd.rs +0 -302
- package/temp/rtk/src/playwright_cmd.rs +0 -479
- package/temp/rtk/src/pnpm_cmd.rs +0 -573
- package/temp/rtk/src/prettier_cmd.rs +0 -221
- package/temp/rtk/src/prisma_cmd.rs +0 -482
- package/temp/rtk/src/psql_cmd.rs +0 -382
- package/temp/rtk/src/pytest_cmd.rs +0 -384
- package/temp/rtk/src/read.rs +0 -217
- package/temp/rtk/src/rewrite_cmd.rs +0 -50
- package/temp/rtk/src/ruff_cmd.rs +0 -402
- package/temp/rtk/src/runner.rs +0 -271
- package/temp/rtk/src/summary.rs +0 -297
- package/temp/rtk/src/tee.rs +0 -405
- package/temp/rtk/src/telemetry.rs +0 -248
- package/temp/rtk/src/toml_filter.rs +0 -1655
- package/temp/rtk/src/tracking.rs +0 -1416
- package/temp/rtk/src/tree.rs +0 -209
- package/temp/rtk/src/tsc_cmd.rs +0 -259
- package/temp/rtk/src/utils.rs +0 -432
- package/temp/rtk/src/verify_cmd.rs +0 -47
- package/temp/rtk/src/vitest_cmd.rs +0 -385
- package/temp/rtk/src/wc_cmd.rs +0 -401
- package/temp/rtk/src/wget_cmd.rs +0 -260
- package/temp/rtk/tests/fixtures/dotnet/build_failed.txt +0 -11
- package/temp/rtk/tests/fixtures/dotnet/format_changes.json +0 -31
- package/temp/rtk/tests/fixtures/dotnet/format_empty.json +0 -1
- package/temp/rtk/tests/fixtures/dotnet/format_success.json +0 -12
- package/temp/rtk/tests/fixtures/dotnet/test_failed.txt +0 -18
- package/tsconfig.json +0 -15
|
@@ -1,583 +0,0 @@
|
|
|
1
|
-
# RTK Tracking API Documentation
|
|
2
|
-
|
|
3
|
-
Comprehensive documentation for RTK's token savings tracking system.
|
|
4
|
-
|
|
5
|
-
## Table of Contents
|
|
6
|
-
|
|
7
|
-
- [Overview](#overview)
|
|
8
|
-
- [Architecture](#architecture)
|
|
9
|
-
- [Public API](#public-api)
|
|
10
|
-
- [Usage Examples](#usage-examples)
|
|
11
|
-
- [Data Formats](#data-formats)
|
|
12
|
-
- [Integration Examples](#integration-examples)
|
|
13
|
-
- [Database Schema](#database-schema)
|
|
14
|
-
|
|
15
|
-
## Overview
|
|
16
|
-
|
|
17
|
-
RTK's tracking system records every command execution to provide analytics on token savings. The system:
|
|
18
|
-
- Stores command history in SQLite (~/.local/share/rtk/tracking.db)
|
|
19
|
-
- Tracks input/output tokens, savings percentage, and execution time
|
|
20
|
-
- Automatically cleans up records older than 90 days
|
|
21
|
-
- Provides aggregation APIs (daily/weekly/monthly)
|
|
22
|
-
- Exports to JSON/CSV for external integrations
|
|
23
|
-
|
|
24
|
-
## Architecture
|
|
25
|
-
|
|
26
|
-
### Data Flow
|
|
27
|
-
|
|
28
|
-
```
|
|
29
|
-
rtk command execution
|
|
30
|
-
↓
|
|
31
|
-
TimedExecution::start()
|
|
32
|
-
↓
|
|
33
|
-
[command runs]
|
|
34
|
-
↓
|
|
35
|
-
TimedExecution::track(original_cmd, rtk_cmd, input, output)
|
|
36
|
-
↓
|
|
37
|
-
Tracker::record(original_cmd, rtk_cmd, input_tokens, output_tokens, exec_time_ms)
|
|
38
|
-
↓
|
|
39
|
-
SQLite database (~/.local/share/rtk/tracking.db)
|
|
40
|
-
↓
|
|
41
|
-
Aggregation APIs (get_summary, get_all_days, etc.)
|
|
42
|
-
↓
|
|
43
|
-
CLI output (rtk gain) or JSON/CSV export
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Storage Location
|
|
47
|
-
|
|
48
|
-
- **Linux**: `~/.local/share/rtk/tracking.db`
|
|
49
|
-
- **macOS**: `~/Library/Application Support/rtk/tracking.db`
|
|
50
|
-
- **Windows**: `%APPDATA%\rtk\tracking.db`
|
|
51
|
-
|
|
52
|
-
### Data Retention
|
|
53
|
-
|
|
54
|
-
Records older than **90 days** are automatically deleted on each write operation to prevent unbounded database growth.
|
|
55
|
-
|
|
56
|
-
## Public API
|
|
57
|
-
|
|
58
|
-
### Core Types
|
|
59
|
-
|
|
60
|
-
#### `Tracker`
|
|
61
|
-
|
|
62
|
-
Main tracking interface for recording and querying command history.
|
|
63
|
-
|
|
64
|
-
```rust
|
|
65
|
-
pub struct Tracker {
|
|
66
|
-
conn: Connection, // SQLite connection
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
impl Tracker {
|
|
70
|
-
/// Create new tracker instance (opens/creates database)
|
|
71
|
-
pub fn new() -> Result<Self>;
|
|
72
|
-
|
|
73
|
-
/// Record a command execution
|
|
74
|
-
pub fn record(
|
|
75
|
-
&self,
|
|
76
|
-
original_cmd: &str, // Standard command (e.g., "ls -la")
|
|
77
|
-
rtk_cmd: &str, // RTK command (e.g., "rtk ls")
|
|
78
|
-
input_tokens: usize, // Estimated input tokens
|
|
79
|
-
output_tokens: usize, // Actual output tokens
|
|
80
|
-
exec_time_ms: u64, // Execution time in milliseconds
|
|
81
|
-
) -> Result<()>;
|
|
82
|
-
|
|
83
|
-
/// Get overall summary statistics
|
|
84
|
-
pub fn get_summary(&self) -> Result<GainSummary>;
|
|
85
|
-
|
|
86
|
-
/// Get daily statistics (all days)
|
|
87
|
-
pub fn get_all_days(&self) -> Result<Vec<DayStats>>;
|
|
88
|
-
|
|
89
|
-
/// Get weekly statistics (grouped by week)
|
|
90
|
-
pub fn get_by_week(&self) -> Result<Vec<WeekStats>>;
|
|
91
|
-
|
|
92
|
-
/// Get monthly statistics (grouped by month)
|
|
93
|
-
pub fn get_by_month(&self) -> Result<Vec<MonthStats>>;
|
|
94
|
-
|
|
95
|
-
/// Get recent command history (limit = max records)
|
|
96
|
-
pub fn get_recent(&self, limit: usize) -> Result<Vec<CommandRecord>>;
|
|
97
|
-
}
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
#### `GainSummary`
|
|
101
|
-
|
|
102
|
-
Aggregated statistics across all recorded commands.
|
|
103
|
-
|
|
104
|
-
```rust
|
|
105
|
-
pub struct GainSummary {
|
|
106
|
-
pub total_commands: usize, // Total commands recorded
|
|
107
|
-
pub total_input: usize, // Total input tokens
|
|
108
|
-
pub total_output: usize, // Total output tokens
|
|
109
|
-
pub total_saved: usize, // Total tokens saved
|
|
110
|
-
pub avg_savings_pct: f64, // Average savings percentage
|
|
111
|
-
pub total_time_ms: u64, // Total execution time (ms)
|
|
112
|
-
pub avg_time_ms: u64, // Average execution time (ms)
|
|
113
|
-
pub by_command: Vec<(String, usize, usize, f64, u64)>, // Top 10 commands
|
|
114
|
-
pub by_day: Vec<(String, usize)>, // Last 30 days
|
|
115
|
-
}
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
#### `DayStats`
|
|
119
|
-
|
|
120
|
-
Daily statistics (Serializable for JSON export).
|
|
121
|
-
|
|
122
|
-
```rust
|
|
123
|
-
#[derive(Debug, Serialize)]
|
|
124
|
-
pub struct DayStats {
|
|
125
|
-
pub date: String, // ISO date (YYYY-MM-DD)
|
|
126
|
-
pub commands: usize, // Commands executed this day
|
|
127
|
-
pub input_tokens: usize, // Total input tokens
|
|
128
|
-
pub output_tokens: usize, // Total output tokens
|
|
129
|
-
pub saved_tokens: usize, // Total tokens saved
|
|
130
|
-
pub savings_pct: f64, // Savings percentage
|
|
131
|
-
pub total_time_ms: u64, // Total execution time (ms)
|
|
132
|
-
pub avg_time_ms: u64, // Average execution time (ms)
|
|
133
|
-
}
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
#### `WeekStats`
|
|
137
|
-
|
|
138
|
-
Weekly statistics (Serializable for JSON export).
|
|
139
|
-
|
|
140
|
-
```rust
|
|
141
|
-
#[derive(Debug, Serialize)]
|
|
142
|
-
pub struct WeekStats {
|
|
143
|
-
pub week_start: String, // ISO date (YYYY-MM-DD)
|
|
144
|
-
pub week_end: String, // ISO date (YYYY-MM-DD)
|
|
145
|
-
pub commands: usize,
|
|
146
|
-
pub input_tokens: usize,
|
|
147
|
-
pub output_tokens: usize,
|
|
148
|
-
pub saved_tokens: usize,
|
|
149
|
-
pub savings_pct: f64,
|
|
150
|
-
pub total_time_ms: u64,
|
|
151
|
-
pub avg_time_ms: u64,
|
|
152
|
-
}
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
#### `MonthStats`
|
|
156
|
-
|
|
157
|
-
Monthly statistics (Serializable for JSON export).
|
|
158
|
-
|
|
159
|
-
```rust
|
|
160
|
-
#[derive(Debug, Serialize)]
|
|
161
|
-
pub struct MonthStats {
|
|
162
|
-
pub month: String, // YYYY-MM format
|
|
163
|
-
pub commands: usize,
|
|
164
|
-
pub input_tokens: usize,
|
|
165
|
-
pub output_tokens: usize,
|
|
166
|
-
pub saved_tokens: usize,
|
|
167
|
-
pub savings_pct: f64,
|
|
168
|
-
pub total_time_ms: u64,
|
|
169
|
-
pub avg_time_ms: u64,
|
|
170
|
-
}
|
|
171
|
-
```
|
|
172
|
-
|
|
173
|
-
#### `CommandRecord`
|
|
174
|
-
|
|
175
|
-
Individual command record from history.
|
|
176
|
-
|
|
177
|
-
```rust
|
|
178
|
-
pub struct CommandRecord {
|
|
179
|
-
pub timestamp: DateTime<Utc>, // UTC timestamp
|
|
180
|
-
pub rtk_cmd: String, // RTK command used
|
|
181
|
-
pub saved_tokens: usize, // Tokens saved
|
|
182
|
-
pub savings_pct: f64, // Savings percentage
|
|
183
|
-
}
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
#### `TimedExecution`
|
|
187
|
-
|
|
188
|
-
Helper for timing command execution (preferred API).
|
|
189
|
-
|
|
190
|
-
```rust
|
|
191
|
-
pub struct TimedExecution {
|
|
192
|
-
start: Instant,
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
impl TimedExecution {
|
|
196
|
-
/// Start timing a command execution
|
|
197
|
-
pub fn start() -> Self;
|
|
198
|
-
|
|
199
|
-
/// Track command with elapsed time
|
|
200
|
-
pub fn track(&self, original_cmd: &str, rtk_cmd: &str, input: &str, output: &str);
|
|
201
|
-
|
|
202
|
-
/// Track passthrough commands (timing-only, no token counting)
|
|
203
|
-
pub fn track_passthrough(&self, original_cmd: &str, rtk_cmd: &str);
|
|
204
|
-
}
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
### Utility Functions
|
|
208
|
-
|
|
209
|
-
```rust
|
|
210
|
-
/// Estimate token count (~4 chars = 1 token)
|
|
211
|
-
pub fn estimate_tokens(text: &str) -> usize;
|
|
212
|
-
|
|
213
|
-
/// Format OsString args for display
|
|
214
|
-
pub fn args_display(args: &[OsString]) -> String;
|
|
215
|
-
|
|
216
|
-
/// Legacy tracking function (deprecated, use TimedExecution)
|
|
217
|
-
#[deprecated(note = "Use TimedExecution instead")]
|
|
218
|
-
pub fn track(original_cmd: &str, rtk_cmd: &str, input: &str, output: &str);
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
## Usage Examples
|
|
222
|
-
|
|
223
|
-
### Basic Tracking
|
|
224
|
-
|
|
225
|
-
```rust
|
|
226
|
-
use rtk::tracking::{TimedExecution, Tracker};
|
|
227
|
-
|
|
228
|
-
fn main() -> anyhow::Result<()> {
|
|
229
|
-
// Start timer
|
|
230
|
-
let timer = TimedExecution::start();
|
|
231
|
-
|
|
232
|
-
// Execute command
|
|
233
|
-
let input = execute_original_command()?;
|
|
234
|
-
let output = execute_rtk_command()?;
|
|
235
|
-
|
|
236
|
-
// Track execution
|
|
237
|
-
timer.track("ls -la", "rtk ls", &input, &output);
|
|
238
|
-
|
|
239
|
-
Ok(())
|
|
240
|
-
}
|
|
241
|
-
```
|
|
242
|
-
|
|
243
|
-
### Querying Statistics
|
|
244
|
-
|
|
245
|
-
```rust
|
|
246
|
-
use rtk::tracking::Tracker;
|
|
247
|
-
|
|
248
|
-
fn main() -> anyhow::Result<()> {
|
|
249
|
-
let tracker = Tracker::new()?;
|
|
250
|
-
|
|
251
|
-
// Get overall summary
|
|
252
|
-
let summary = tracker.get_summary()?;
|
|
253
|
-
println!("Total commands: {}", summary.total_commands);
|
|
254
|
-
println!("Total saved: {} tokens", summary.total_saved);
|
|
255
|
-
println!("Average savings: {:.1}%", summary.avg_savings_pct);
|
|
256
|
-
|
|
257
|
-
// Get daily breakdown
|
|
258
|
-
let days = tracker.get_all_days()?;
|
|
259
|
-
for day in days.iter().take(7) {
|
|
260
|
-
println!("{}: {} commands, {} tokens saved",
|
|
261
|
-
day.date, day.commands, day.saved_tokens);
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
// Get recent history
|
|
265
|
-
let recent = tracker.get_recent(10)?;
|
|
266
|
-
for cmd in recent {
|
|
267
|
-
println!("{}: {} saved {:.1}%",
|
|
268
|
-
cmd.timestamp, cmd.rtk_cmd, cmd.savings_pct);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
Ok(())
|
|
272
|
-
}
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
### Passthrough Commands
|
|
276
|
-
|
|
277
|
-
For commands that stream output or run interactively (no output capture):
|
|
278
|
-
|
|
279
|
-
```rust
|
|
280
|
-
use rtk::tracking::TimedExecution;
|
|
281
|
-
|
|
282
|
-
fn main() -> anyhow::Result<()> {
|
|
283
|
-
let timer = TimedExecution::start();
|
|
284
|
-
|
|
285
|
-
// Execute streaming command (e.g., git tag --list)
|
|
286
|
-
execute_streaming_command()?;
|
|
287
|
-
|
|
288
|
-
// Track timing only (input_tokens=0, output_tokens=0)
|
|
289
|
-
timer.track_passthrough("git tag --list", "rtk git tag --list");
|
|
290
|
-
|
|
291
|
-
Ok(())
|
|
292
|
-
}
|
|
293
|
-
```
|
|
294
|
-
|
|
295
|
-
## Data Formats
|
|
296
|
-
|
|
297
|
-
### JSON Export Schema
|
|
298
|
-
|
|
299
|
-
#### DayStats JSON
|
|
300
|
-
|
|
301
|
-
```json
|
|
302
|
-
{
|
|
303
|
-
"date": "2026-02-03",
|
|
304
|
-
"commands": 42,
|
|
305
|
-
"input_tokens": 15420,
|
|
306
|
-
"output_tokens": 3842,
|
|
307
|
-
"saved_tokens": 11578,
|
|
308
|
-
"savings_pct": 75.08,
|
|
309
|
-
"total_time_ms": 8450,
|
|
310
|
-
"avg_time_ms": 201
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
#### WeekStats JSON
|
|
315
|
-
|
|
316
|
-
```json
|
|
317
|
-
{
|
|
318
|
-
"week_start": "2026-01-27",
|
|
319
|
-
"week_end": "2026-02-02",
|
|
320
|
-
"commands": 284,
|
|
321
|
-
"input_tokens": 98234,
|
|
322
|
-
"output_tokens": 19847,
|
|
323
|
-
"saved_tokens": 78387,
|
|
324
|
-
"savings_pct": 79.80,
|
|
325
|
-
"total_time_ms": 56780,
|
|
326
|
-
"avg_time_ms": 200
|
|
327
|
-
}
|
|
328
|
-
```
|
|
329
|
-
|
|
330
|
-
#### MonthStats JSON
|
|
331
|
-
|
|
332
|
-
```json
|
|
333
|
-
{
|
|
334
|
-
"month": "2026-02",
|
|
335
|
-
"commands": 1247,
|
|
336
|
-
"input_tokens": 456789,
|
|
337
|
-
"output_tokens": 91358,
|
|
338
|
-
"saved_tokens": 365431,
|
|
339
|
-
"savings_pct": 80.00,
|
|
340
|
-
"total_time_ms": 249560,
|
|
341
|
-
"avg_time_ms": 200
|
|
342
|
-
}
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
### CSV Export Schema
|
|
346
|
-
|
|
347
|
-
```csv
|
|
348
|
-
date,commands,input_tokens,output_tokens,saved_tokens,savings_pct,total_time_ms,avg_time_ms
|
|
349
|
-
2026-02-03,42,15420,3842,11578,75.08,8450,201
|
|
350
|
-
2026-02-02,38,14230,3557,10673,75.00,7600,200
|
|
351
|
-
2026-02-01,45,16890,4223,12667,75.00,9000,200
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
## Integration Examples
|
|
355
|
-
|
|
356
|
-
### GitHub Actions - Track Savings in CI
|
|
357
|
-
|
|
358
|
-
```yaml
|
|
359
|
-
# .github/workflows/track-rtk-savings.yml
|
|
360
|
-
name: Track RTK Savings
|
|
361
|
-
|
|
362
|
-
on:
|
|
363
|
-
schedule:
|
|
364
|
-
- cron: '0 0 * * 1' # Weekly on Monday
|
|
365
|
-
workflow_dispatch:
|
|
366
|
-
|
|
367
|
-
jobs:
|
|
368
|
-
track-savings:
|
|
369
|
-
runs-on: ubuntu-latest
|
|
370
|
-
steps:
|
|
371
|
-
- name: Install RTK
|
|
372
|
-
run: cargo install --git https://github.com/rtk-ai/rtk
|
|
373
|
-
|
|
374
|
-
- name: Export weekly stats
|
|
375
|
-
run: |
|
|
376
|
-
rtk gain --weekly --format json > rtk-weekly.json
|
|
377
|
-
cat rtk-weekly.json
|
|
378
|
-
|
|
379
|
-
- name: Upload artifact
|
|
380
|
-
uses: actions/upload-artifact@v3
|
|
381
|
-
with:
|
|
382
|
-
name: rtk-metrics
|
|
383
|
-
path: rtk-weekly.json
|
|
384
|
-
|
|
385
|
-
- name: Post to Slack
|
|
386
|
-
if: success()
|
|
387
|
-
env:
|
|
388
|
-
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
|
389
|
-
run: |
|
|
390
|
-
SAVINGS=$(jq -r '.[0].saved_tokens' rtk-weekly.json)
|
|
391
|
-
PCT=$(jq -r '.[0].savings_pct' rtk-weekly.json)
|
|
392
|
-
curl -X POST -H 'Content-type: application/json' \
|
|
393
|
-
--data "{\"text\":\"📊 RTK Weekly: ${SAVINGS} tokens saved (${PCT}%)\"}" \
|
|
394
|
-
$SLACK_WEBHOOK
|
|
395
|
-
```
|
|
396
|
-
|
|
397
|
-
### Custom Dashboard Script
|
|
398
|
-
|
|
399
|
-
```python
|
|
400
|
-
#!/usr/bin/env python3
|
|
401
|
-
"""
|
|
402
|
-
Export RTK metrics to Grafana/Datadog/etc.
|
|
403
|
-
"""
|
|
404
|
-
import json
|
|
405
|
-
import subprocess
|
|
406
|
-
from datetime import datetime
|
|
407
|
-
|
|
408
|
-
def get_rtk_metrics():
|
|
409
|
-
"""Fetch RTK metrics as JSON."""
|
|
410
|
-
result = subprocess.run(
|
|
411
|
-
["rtk", "gain", "--all", "--format", "json"],
|
|
412
|
-
capture_output=True,
|
|
413
|
-
text=True
|
|
414
|
-
)
|
|
415
|
-
return json.loads(result.stdout)
|
|
416
|
-
|
|
417
|
-
def export_to_datadog(metrics):
|
|
418
|
-
"""Send metrics to Datadog."""
|
|
419
|
-
import datadog
|
|
420
|
-
|
|
421
|
-
datadog.initialize(api_key="YOUR_API_KEY")
|
|
422
|
-
|
|
423
|
-
for day in metrics.get("daily", []):
|
|
424
|
-
datadog.api.Metric.send(
|
|
425
|
-
metric="rtk.tokens_saved",
|
|
426
|
-
points=[(datetime.now().timestamp(), day["saved_tokens"])],
|
|
427
|
-
tags=[f"date:{day['date']}"]
|
|
428
|
-
)
|
|
429
|
-
|
|
430
|
-
datadog.api.Metric.send(
|
|
431
|
-
metric="rtk.savings_pct",
|
|
432
|
-
points=[(datetime.now().timestamp(), day["savings_pct"])],
|
|
433
|
-
tags=[f"date:{day['date']}"]
|
|
434
|
-
)
|
|
435
|
-
|
|
436
|
-
if __name__ == "__main__":
|
|
437
|
-
metrics = get_rtk_metrics()
|
|
438
|
-
export_to_datadog(metrics)
|
|
439
|
-
print(f"Exported {len(metrics.get('daily', []))} days to Datadog")
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
### Rust Integration (Using RTK as Library)
|
|
443
|
-
|
|
444
|
-
```rust
|
|
445
|
-
// In your Cargo.toml
|
|
446
|
-
// [dependencies]
|
|
447
|
-
// rtk = { git = "https://github.com/rtk-ai/rtk" }
|
|
448
|
-
|
|
449
|
-
use rtk::tracking::{Tracker, TimedExecution};
|
|
450
|
-
use anyhow::Result;
|
|
451
|
-
|
|
452
|
-
fn main() -> Result<()> {
|
|
453
|
-
// Track your own commands
|
|
454
|
-
let timer = TimedExecution::start();
|
|
455
|
-
|
|
456
|
-
let input = run_expensive_operation()?;
|
|
457
|
-
let output = run_optimized_operation()?;
|
|
458
|
-
|
|
459
|
-
timer.track(
|
|
460
|
-
"expensive_operation",
|
|
461
|
-
"optimized_operation",
|
|
462
|
-
&input,
|
|
463
|
-
&output
|
|
464
|
-
);
|
|
465
|
-
|
|
466
|
-
// Query aggregated stats
|
|
467
|
-
let tracker = Tracker::new()?;
|
|
468
|
-
let summary = tracker.get_summary()?;
|
|
469
|
-
|
|
470
|
-
println!("Total savings: {} tokens ({:.1}%)",
|
|
471
|
-
summary.total_saved,
|
|
472
|
-
summary.avg_savings_pct
|
|
473
|
-
);
|
|
474
|
-
|
|
475
|
-
// Export to JSON for external tools
|
|
476
|
-
let days = tracker.get_all_days()?;
|
|
477
|
-
let json = serde_json::to_string_pretty(&days)?;
|
|
478
|
-
std::fs::write("metrics.json", json)?;
|
|
479
|
-
|
|
480
|
-
Ok(())
|
|
481
|
-
}
|
|
482
|
-
```
|
|
483
|
-
|
|
484
|
-
## Database Schema
|
|
485
|
-
|
|
486
|
-
### Table: `commands`
|
|
487
|
-
|
|
488
|
-
```sql
|
|
489
|
-
CREATE TABLE commands (
|
|
490
|
-
id INTEGER PRIMARY KEY,
|
|
491
|
-
timestamp TEXT NOT NULL, -- RFC3339 UTC timestamp
|
|
492
|
-
original_cmd TEXT NOT NULL, -- Original command (e.g., "ls -la")
|
|
493
|
-
rtk_cmd TEXT NOT NULL, -- RTK command (e.g., "rtk ls")
|
|
494
|
-
input_tokens INTEGER NOT NULL, -- Estimated input tokens
|
|
495
|
-
output_tokens INTEGER NOT NULL, -- Actual output tokens
|
|
496
|
-
saved_tokens INTEGER NOT NULL, -- input_tokens - output_tokens
|
|
497
|
-
savings_pct REAL NOT NULL, -- (saved/input) * 100
|
|
498
|
-
exec_time_ms INTEGER DEFAULT 0 -- Execution time in milliseconds
|
|
499
|
-
);
|
|
500
|
-
|
|
501
|
-
CREATE INDEX idx_timestamp ON commands(timestamp);
|
|
502
|
-
```
|
|
503
|
-
|
|
504
|
-
### Automatic Cleanup
|
|
505
|
-
|
|
506
|
-
On every write operation (`Tracker::record`), records older than 90 days are deleted:
|
|
507
|
-
|
|
508
|
-
```rust
|
|
509
|
-
fn cleanup_old(&self) -> Result<()> {
|
|
510
|
-
let cutoff = Utc::now() - chrono::Duration::days(90);
|
|
511
|
-
self.conn.execute(
|
|
512
|
-
"DELETE FROM commands WHERE timestamp < ?1",
|
|
513
|
-
params![cutoff.to_rfc3339()],
|
|
514
|
-
)?;
|
|
515
|
-
Ok(())
|
|
516
|
-
}
|
|
517
|
-
```
|
|
518
|
-
|
|
519
|
-
### Migration Support
|
|
520
|
-
|
|
521
|
-
The system automatically adds new columns if they don't exist (e.g., `exec_time_ms` was added later):
|
|
522
|
-
|
|
523
|
-
```rust
|
|
524
|
-
// Safe migration on Tracker::new()
|
|
525
|
-
let _ = conn.execute(
|
|
526
|
-
"ALTER TABLE commands ADD COLUMN exec_time_ms INTEGER DEFAULT 0",
|
|
527
|
-
[],
|
|
528
|
-
);
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
## Performance Considerations
|
|
532
|
-
|
|
533
|
-
- **SQLite WAL mode**: Not enabled (may add in future for concurrent writes)
|
|
534
|
-
- **Index on timestamp**: Enables fast date-range queries
|
|
535
|
-
- **Automatic cleanup**: Prevents database from growing unbounded
|
|
536
|
-
- **Token estimation**: ~4 chars = 1 token (simple, fast approximation)
|
|
537
|
-
- **Aggregation queries**: Use SQL GROUP BY for efficient aggregation
|
|
538
|
-
|
|
539
|
-
## Security & Privacy
|
|
540
|
-
|
|
541
|
-
- **Local storage only**: Database never leaves the machine
|
|
542
|
-
- **No telemetry**: RTK does not phone home or send analytics
|
|
543
|
-
- **User control**: Users can delete `~/.local/share/rtk/tracking.db` anytime
|
|
544
|
-
- **90-day retention**: Old data automatically purged
|
|
545
|
-
|
|
546
|
-
## Troubleshooting
|
|
547
|
-
|
|
548
|
-
### Database locked error
|
|
549
|
-
|
|
550
|
-
If you see "database is locked" errors:
|
|
551
|
-
- Ensure only one RTK process writes at a time
|
|
552
|
-
- Check file permissions on `~/.local/share/rtk/tracking.db`
|
|
553
|
-
- Delete and recreate: `rm ~/.local/share/rtk/tracking.db && rtk gain`
|
|
554
|
-
|
|
555
|
-
### Missing exec_time_ms column
|
|
556
|
-
|
|
557
|
-
Older databases may not have the `exec_time_ms` column. RTK automatically migrates on first use, but you can force it:
|
|
558
|
-
|
|
559
|
-
```bash
|
|
560
|
-
sqlite3 ~/.local/share/rtk/tracking.db \
|
|
561
|
-
"ALTER TABLE commands ADD COLUMN exec_time_ms INTEGER DEFAULT 0"
|
|
562
|
-
```
|
|
563
|
-
|
|
564
|
-
### Incorrect token counts
|
|
565
|
-
|
|
566
|
-
Token estimation uses `~4 chars = 1 token`. This is approximate. For precise counts, integrate with your LLM's tokenizer API.
|
|
567
|
-
|
|
568
|
-
## Future Enhancements
|
|
569
|
-
|
|
570
|
-
Planned improvements (contributions welcome):
|
|
571
|
-
|
|
572
|
-
- [ ] Export to Prometheus/OpenMetrics format
|
|
573
|
-
- [ ] Support for custom retention periods (not just 90 days)
|
|
574
|
-
- [ ] SQLite WAL mode for concurrent writes
|
|
575
|
-
- [ ] Per-project tracking (multiple databases)
|
|
576
|
-
- [ ] Integration with Claude API for precise token counts
|
|
577
|
-
- [ ] Web dashboard (localhost) for visualizing trends
|
|
578
|
-
|
|
579
|
-
## See Also
|
|
580
|
-
|
|
581
|
-
- [README.md](../README.md) - Main project documentation
|
|
582
|
-
- [COMMAND_AUDIT.md](../claudedocs/COMMAND_AUDIT.md) - List of all RTK commands
|
|
583
|
-
- [Rust docs](https://docs.rs/) - Run `cargo doc --open` for API docs
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import type { Plugin } from "@opencode-ai/plugin"
|
|
2
|
-
|
|
3
|
-
// RTK OpenCode plugin — rewrites commands to use rtk for token savings.
|
|
4
|
-
// Requires: rtk >= 0.23.0 in PATH.
|
|
5
|
-
//
|
|
6
|
-
// This is a thin delegating plugin: all rewrite logic lives in `rtk rewrite`,
|
|
7
|
-
// which is the single source of truth (src/discover/registry.rs).
|
|
8
|
-
// To add or change rewrite rules, edit the Rust registry — not this file.
|
|
9
|
-
|
|
10
|
-
export const RtkOpenCodePlugin: Plugin = async ({ $ }) => {
|
|
11
|
-
try {
|
|
12
|
-
await $`which rtk`.quiet()
|
|
13
|
-
} catch {
|
|
14
|
-
console.warn("[rtk] rtk binary not found in PATH — plugin disabled")
|
|
15
|
-
return {}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return {
|
|
19
|
-
"tool.execute.before": async (input, output) => {
|
|
20
|
-
const tool = String(input?.tool ?? "").toLowerCase()
|
|
21
|
-
if (tool !== "bash" && tool !== "shell") return
|
|
22
|
-
const args = output?.args
|
|
23
|
-
if (!args || typeof args !== "object") return
|
|
24
|
-
|
|
25
|
-
const command = (args as Record<string, unknown>).command
|
|
26
|
-
if (typeof command !== "string" || !command) return
|
|
27
|
-
|
|
28
|
-
try {
|
|
29
|
-
const result = await $`rtk rewrite ${command}`.quiet().nothrow()
|
|
30
|
-
const rewritten = String(result.stdout).trim()
|
|
31
|
-
if (rewritten && rewritten !== command) {
|
|
32
|
-
;(args as Record<string, unknown>).command = rewritten
|
|
33
|
-
}
|
|
34
|
-
} catch {
|
|
35
|
-
// rtk rewrite failed — pass through unchanged
|
|
36
|
-
}
|
|
37
|
-
},
|
|
38
|
-
}
|
|
39
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# RTK - Rust Token Killer
|
|
2
|
-
|
|
3
|
-
**Usage**: Token-optimized CLI proxy (60-90% savings on dev operations)
|
|
4
|
-
|
|
5
|
-
## Meta Commands (always use rtk directly)
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
rtk gain # Show token savings analytics
|
|
9
|
-
rtk gain --history # Show command usage history with savings
|
|
10
|
-
rtk discover # Analyze Claude Code history for missed opportunities
|
|
11
|
-
rtk proxy <cmd> # Execute raw command without filtering (for debugging)
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
## Installation Verification
|
|
15
|
-
|
|
16
|
-
```bash
|
|
17
|
-
rtk --version # Should show: rtk X.Y.Z
|
|
18
|
-
rtk gain # Should work (not "command not found")
|
|
19
|
-
which rtk # Verify correct binary
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
⚠️ **Name collision**: If `rtk gain` fails, you may have reachingforthejack/rtk (Rust Type Kit) installed instead.
|
|
23
|
-
|
|
24
|
-
## Hook-Based Usage
|
|
25
|
-
|
|
26
|
-
All other commands are automatically rewritten by the Claude Code hook.
|
|
27
|
-
Example: `git status` → `rtk git status` (transparent, 0 tokens overhead)
|
|
28
|
-
|
|
29
|
-
Refer to CLAUDE.md for full command reference.
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env bash
|
|
2
|
-
# rtk-hook-version: 2
|
|
3
|
-
# RTK Claude Code hook — rewrites commands to use rtk for token savings.
|
|
4
|
-
# Requires: rtk >= 0.23.0, jq
|
|
5
|
-
#
|
|
6
|
-
# This is a thin delegating hook: all rewrite logic lives in `rtk rewrite`,
|
|
7
|
-
# which is the single source of truth (src/discover/registry.rs).
|
|
8
|
-
# To add or change rewrite rules, edit the Rust registry — not this file.
|
|
9
|
-
|
|
10
|
-
if ! command -v jq &>/dev/null; then
|
|
11
|
-
echo "[rtk] WARNING: jq is not installed. Hook cannot rewrite commands. Install jq: https://jqlang.github.io/jq/download/" >&2
|
|
12
|
-
exit 0
|
|
13
|
-
fi
|
|
14
|
-
|
|
15
|
-
if ! command -v rtk &>/dev/null; then
|
|
16
|
-
echo "[rtk] WARNING: rtk is not installed or not in PATH. Hook cannot rewrite commands. Install: https://github.com/rtk-ai/rtk#installation" >&2
|
|
17
|
-
exit 0
|
|
18
|
-
fi
|
|
19
|
-
|
|
20
|
-
# Version guard: rtk rewrite was added in 0.23.0.
|
|
21
|
-
# Older binaries: warn once and exit cleanly (no silent failure).
|
|
22
|
-
RTK_VERSION=$(rtk --version 2>/dev/null | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
|
23
|
-
if [ -n "$RTK_VERSION" ]; then
|
|
24
|
-
MAJOR=$(echo "$RTK_VERSION" | cut -d. -f1)
|
|
25
|
-
MINOR=$(echo "$RTK_VERSION" | cut -d. -f2)
|
|
26
|
-
# Require >= 0.23.0
|
|
27
|
-
if [ "$MAJOR" -eq 0 ] && [ "$MINOR" -lt 23 ]; then
|
|
28
|
-
echo "[rtk] WARNING: rtk $RTK_VERSION is too old (need >= 0.23.0). Upgrade: cargo install rtk" >&2
|
|
29
|
-
exit 0
|
|
30
|
-
fi
|
|
31
|
-
fi
|
|
32
|
-
|
|
33
|
-
INPUT=$(cat)
|
|
34
|
-
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
|
|
35
|
-
|
|
36
|
-
if [ -z "$CMD" ]; then
|
|
37
|
-
exit 0
|
|
38
|
-
fi
|
|
39
|
-
|
|
40
|
-
# Delegate all rewrite logic to the Rust binary.
|
|
41
|
-
# rtk rewrite exits 1 when there's no rewrite — hook passes through silently.
|
|
42
|
-
REWRITTEN=$(rtk rewrite "$CMD" 2>/dev/null) || exit 0
|
|
43
|
-
|
|
44
|
-
# No change — nothing to do.
|
|
45
|
-
if [ "$CMD" = "$REWRITTEN" ]; then
|
|
46
|
-
exit 0
|
|
47
|
-
fi
|
|
48
|
-
|
|
49
|
-
ORIGINAL_INPUT=$(echo "$INPUT" | jq -c '.tool_input')
|
|
50
|
-
UPDATED_INPUT=$(echo "$ORIGINAL_INPUT" | jq --arg cmd "$REWRITTEN" '.command = $cmd')
|
|
51
|
-
|
|
52
|
-
jq -n \
|
|
53
|
-
--argjson updated "$UPDATED_INPUT" \
|
|
54
|
-
'{
|
|
55
|
-
"hookSpecificOutput": {
|
|
56
|
-
"hookEventName": "PreToolUse",
|
|
57
|
-
"permissionDecision": "allow",
|
|
58
|
-
"permissionDecisionReason": "RTK auto-rewrite",
|
|
59
|
-
"updatedInput": $updated
|
|
60
|
-
}
|
|
61
|
-
}'
|