@hasna/terminal 2.3.0 → 2.3.1

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.
Files changed (202) hide show
  1. package/dist/cli.js +64 -16
  2. package/package.json +1 -1
  3. package/src/ai.ts +8 -0
  4. package/src/cli.tsx +57 -18
  5. package/src/output-processor.ts +6 -1
  6. package/src/output-store.ts +58 -12
  7. package/src/tool-profiles.ts +139 -0
  8. package/temp/rtk/.claude/agents/code-reviewer.md +0 -221
  9. package/temp/rtk/.claude/agents/debugger.md +0 -519
  10. package/temp/rtk/.claude/agents/rtk-testing-specialist.md +0 -461
  11. package/temp/rtk/.claude/agents/rust-rtk.md +0 -511
  12. package/temp/rtk/.claude/agents/technical-writer.md +0 -355
  13. package/temp/rtk/.claude/commands/diagnose.md +0 -352
  14. package/temp/rtk/.claude/commands/test-routing.md +0 -362
  15. package/temp/rtk/.claude/hooks/bash/pre-commit-format.sh +0 -16
  16. package/temp/rtk/.claude/hooks/rtk-rewrite.sh +0 -70
  17. package/temp/rtk/.claude/hooks/rtk-suggest.sh +0 -152
  18. package/temp/rtk/.claude/rules/cli-testing.md +0 -526
  19. package/temp/rtk/.claude/skills/issue-triage/SKILL.md +0 -348
  20. package/temp/rtk/.claude/skills/issue-triage/templates/issue-comment.md +0 -134
  21. package/temp/rtk/.claude/skills/performance.md +0 -435
  22. package/temp/rtk/.claude/skills/pr-triage/SKILL.md +0 -315
  23. package/temp/rtk/.claude/skills/pr-triage/templates/review-comment.md +0 -71
  24. package/temp/rtk/.claude/skills/repo-recap.md +0 -206
  25. package/temp/rtk/.claude/skills/rtk-tdd/SKILL.md +0 -78
  26. package/temp/rtk/.claude/skills/rtk-tdd/references/testing-patterns.md +0 -124
  27. package/temp/rtk/.claude/skills/security-guardian.md +0 -503
  28. package/temp/rtk/.claude/skills/ship.md +0 -404
  29. package/temp/rtk/.github/workflows/benchmark.yml +0 -34
  30. package/temp/rtk/.github/workflows/dco-check.yaml +0 -12
  31. package/temp/rtk/.github/workflows/release-please.yml +0 -51
  32. package/temp/rtk/.github/workflows/release.yml +0 -343
  33. package/temp/rtk/.github/workflows/security-check.yml +0 -135
  34. package/temp/rtk/.github/workflows/validate-docs.yml +0 -78
  35. package/temp/rtk/.release-please-manifest.json +0 -3
  36. package/temp/rtk/ARCHITECTURE.md +0 -1491
  37. package/temp/rtk/CHANGELOG.md +0 -640
  38. package/temp/rtk/CLAUDE.md +0 -605
  39. package/temp/rtk/CONTRIBUTING.md +0 -199
  40. package/temp/rtk/Cargo.lock +0 -1668
  41. package/temp/rtk/Cargo.toml +0 -64
  42. package/temp/rtk/Formula/rtk.rb +0 -43
  43. package/temp/rtk/INSTALL.md +0 -390
  44. package/temp/rtk/LICENSE +0 -21
  45. package/temp/rtk/README.md +0 -386
  46. package/temp/rtk/README_es.md +0 -159
  47. package/temp/rtk/README_fr.md +0 -197
  48. package/temp/rtk/README_ja.md +0 -159
  49. package/temp/rtk/README_ko.md +0 -159
  50. package/temp/rtk/README_zh.md +0 -167
  51. package/temp/rtk/ROADMAP.md +0 -15
  52. package/temp/rtk/SECURITY.md +0 -217
  53. package/temp/rtk/TEST_EXEC_TIME.md +0 -102
  54. package/temp/rtk/build.rs +0 -57
  55. package/temp/rtk/docs/AUDIT_GUIDE.md +0 -432
  56. package/temp/rtk/docs/FEATURES.md +0 -1410
  57. package/temp/rtk/docs/TROUBLESHOOTING.md +0 -309
  58. package/temp/rtk/docs/filter-workflow.md +0 -102
  59. package/temp/rtk/docs/images/gain-dashboard.jpg +0 -0
  60. package/temp/rtk/docs/tracking.md +0 -583
  61. package/temp/rtk/hooks/opencode-rtk.ts +0 -39
  62. package/temp/rtk/hooks/rtk-awareness.md +0 -29
  63. package/temp/rtk/hooks/rtk-rewrite.sh +0 -61
  64. package/temp/rtk/hooks/test-rtk-rewrite.sh +0 -442
  65. package/temp/rtk/install.sh +0 -124
  66. package/temp/rtk/release-please-config.json +0 -10
  67. package/temp/rtk/scripts/benchmark.sh +0 -592
  68. package/temp/rtk/scripts/check-installation.sh +0 -162
  69. package/temp/rtk/scripts/install-local.sh +0 -37
  70. package/temp/rtk/scripts/rtk-economics.sh +0 -137
  71. package/temp/rtk/scripts/test-all.sh +0 -561
  72. package/temp/rtk/scripts/test-aristote.sh +0 -227
  73. package/temp/rtk/scripts/test-tracking.sh +0 -79
  74. package/temp/rtk/scripts/update-readme-metrics.sh +0 -32
  75. package/temp/rtk/scripts/validate-docs.sh +0 -73
  76. package/temp/rtk/src/aws_cmd.rs +0 -880
  77. package/temp/rtk/src/binlog.rs +0 -1645
  78. package/temp/rtk/src/cargo_cmd.rs +0 -1727
  79. package/temp/rtk/src/cc_economics.rs +0 -1157
  80. package/temp/rtk/src/ccusage.rs +0 -340
  81. package/temp/rtk/src/config.rs +0 -187
  82. package/temp/rtk/src/container.rs +0 -855
  83. package/temp/rtk/src/curl_cmd.rs +0 -134
  84. package/temp/rtk/src/deps.rs +0 -268
  85. package/temp/rtk/src/diff_cmd.rs +0 -367
  86. package/temp/rtk/src/discover/mod.rs +0 -274
  87. package/temp/rtk/src/discover/provider.rs +0 -388
  88. package/temp/rtk/src/discover/registry.rs +0 -2022
  89. package/temp/rtk/src/discover/report.rs +0 -202
  90. package/temp/rtk/src/discover/rules.rs +0 -667
  91. package/temp/rtk/src/display_helpers.rs +0 -402
  92. package/temp/rtk/src/dotnet_cmd.rs +0 -1771
  93. package/temp/rtk/src/dotnet_format_report.rs +0 -133
  94. package/temp/rtk/src/dotnet_trx.rs +0 -593
  95. package/temp/rtk/src/env_cmd.rs +0 -204
  96. package/temp/rtk/src/filter.rs +0 -462
  97. package/temp/rtk/src/filters/README.md +0 -52
  98. package/temp/rtk/src/filters/ansible-playbook.toml +0 -34
  99. package/temp/rtk/src/filters/basedpyright.toml +0 -47
  100. package/temp/rtk/src/filters/biome.toml +0 -45
  101. package/temp/rtk/src/filters/brew-install.toml +0 -37
  102. package/temp/rtk/src/filters/composer-install.toml +0 -40
  103. package/temp/rtk/src/filters/df.toml +0 -16
  104. package/temp/rtk/src/filters/dotnet-build.toml +0 -64
  105. package/temp/rtk/src/filters/du.toml +0 -16
  106. package/temp/rtk/src/filters/fail2ban-client.toml +0 -15
  107. package/temp/rtk/src/filters/gcc.toml +0 -49
  108. package/temp/rtk/src/filters/gcloud.toml +0 -22
  109. package/temp/rtk/src/filters/hadolint.toml +0 -24
  110. package/temp/rtk/src/filters/helm.toml +0 -29
  111. package/temp/rtk/src/filters/iptables.toml +0 -27
  112. package/temp/rtk/src/filters/jj.toml +0 -28
  113. package/temp/rtk/src/filters/jq.toml +0 -24
  114. package/temp/rtk/src/filters/make.toml +0 -41
  115. package/temp/rtk/src/filters/markdownlint.toml +0 -24
  116. package/temp/rtk/src/filters/mix-compile.toml +0 -27
  117. package/temp/rtk/src/filters/mix-format.toml +0 -15
  118. package/temp/rtk/src/filters/mvn-build.toml +0 -44
  119. package/temp/rtk/src/filters/oxlint.toml +0 -43
  120. package/temp/rtk/src/filters/ping.toml +0 -63
  121. package/temp/rtk/src/filters/pio-run.toml +0 -40
  122. package/temp/rtk/src/filters/poetry-install.toml +0 -50
  123. package/temp/rtk/src/filters/pre-commit.toml +0 -35
  124. package/temp/rtk/src/filters/ps.toml +0 -16
  125. package/temp/rtk/src/filters/quarto-render.toml +0 -41
  126. package/temp/rtk/src/filters/rsync.toml +0 -48
  127. package/temp/rtk/src/filters/shellcheck.toml +0 -27
  128. package/temp/rtk/src/filters/shopify-theme.toml +0 -29
  129. package/temp/rtk/src/filters/skopeo.toml +0 -45
  130. package/temp/rtk/src/filters/sops.toml +0 -16
  131. package/temp/rtk/src/filters/ssh.toml +0 -44
  132. package/temp/rtk/src/filters/stat.toml +0 -34
  133. package/temp/rtk/src/filters/swift-build.toml +0 -41
  134. package/temp/rtk/src/filters/systemctl-status.toml +0 -33
  135. package/temp/rtk/src/filters/terraform-plan.toml +0 -35
  136. package/temp/rtk/src/filters/tofu-fmt.toml +0 -16
  137. package/temp/rtk/src/filters/tofu-init.toml +0 -38
  138. package/temp/rtk/src/filters/tofu-plan.toml +0 -35
  139. package/temp/rtk/src/filters/tofu-validate.toml +0 -17
  140. package/temp/rtk/src/filters/trunk-build.toml +0 -39
  141. package/temp/rtk/src/filters/ty.toml +0 -50
  142. package/temp/rtk/src/filters/uv-sync.toml +0 -37
  143. package/temp/rtk/src/filters/xcodebuild.toml +0 -99
  144. package/temp/rtk/src/filters/yamllint.toml +0 -25
  145. package/temp/rtk/src/find_cmd.rs +0 -598
  146. package/temp/rtk/src/format_cmd.rs +0 -386
  147. package/temp/rtk/src/gain.rs +0 -723
  148. package/temp/rtk/src/gh_cmd.rs +0 -1651
  149. package/temp/rtk/src/git.rs +0 -2012
  150. package/temp/rtk/src/go_cmd.rs +0 -592
  151. package/temp/rtk/src/golangci_cmd.rs +0 -254
  152. package/temp/rtk/src/grep_cmd.rs +0 -288
  153. package/temp/rtk/src/gt_cmd.rs +0 -810
  154. package/temp/rtk/src/hook_audit_cmd.rs +0 -283
  155. package/temp/rtk/src/hook_check.rs +0 -171
  156. package/temp/rtk/src/init.rs +0 -1859
  157. package/temp/rtk/src/integrity.rs +0 -537
  158. package/temp/rtk/src/json_cmd.rs +0 -231
  159. package/temp/rtk/src/learn/detector.rs +0 -628
  160. package/temp/rtk/src/learn/mod.rs +0 -119
  161. package/temp/rtk/src/learn/report.rs +0 -184
  162. package/temp/rtk/src/lint_cmd.rs +0 -694
  163. package/temp/rtk/src/local_llm.rs +0 -316
  164. package/temp/rtk/src/log_cmd.rs +0 -248
  165. package/temp/rtk/src/ls.rs +0 -324
  166. package/temp/rtk/src/main.rs +0 -2482
  167. package/temp/rtk/src/mypy_cmd.rs +0 -389
  168. package/temp/rtk/src/next_cmd.rs +0 -241
  169. package/temp/rtk/src/npm_cmd.rs +0 -236
  170. package/temp/rtk/src/parser/README.md +0 -267
  171. package/temp/rtk/src/parser/error.rs +0 -46
  172. package/temp/rtk/src/parser/formatter.rs +0 -336
  173. package/temp/rtk/src/parser/mod.rs +0 -311
  174. package/temp/rtk/src/parser/types.rs +0 -119
  175. package/temp/rtk/src/pip_cmd.rs +0 -302
  176. package/temp/rtk/src/playwright_cmd.rs +0 -479
  177. package/temp/rtk/src/pnpm_cmd.rs +0 -573
  178. package/temp/rtk/src/prettier_cmd.rs +0 -221
  179. package/temp/rtk/src/prisma_cmd.rs +0 -482
  180. package/temp/rtk/src/psql_cmd.rs +0 -382
  181. package/temp/rtk/src/pytest_cmd.rs +0 -384
  182. package/temp/rtk/src/read.rs +0 -217
  183. package/temp/rtk/src/rewrite_cmd.rs +0 -50
  184. package/temp/rtk/src/ruff_cmd.rs +0 -402
  185. package/temp/rtk/src/runner.rs +0 -271
  186. package/temp/rtk/src/summary.rs +0 -297
  187. package/temp/rtk/src/tee.rs +0 -405
  188. package/temp/rtk/src/telemetry.rs +0 -248
  189. package/temp/rtk/src/toml_filter.rs +0 -1655
  190. package/temp/rtk/src/tracking.rs +0 -1416
  191. package/temp/rtk/src/tree.rs +0 -209
  192. package/temp/rtk/src/tsc_cmd.rs +0 -259
  193. package/temp/rtk/src/utils.rs +0 -432
  194. package/temp/rtk/src/verify_cmd.rs +0 -47
  195. package/temp/rtk/src/vitest_cmd.rs +0 -385
  196. package/temp/rtk/src/wc_cmd.rs +0 -401
  197. package/temp/rtk/src/wget_cmd.rs +0 -260
  198. package/temp/rtk/tests/fixtures/dotnet/build_failed.txt +0 -11
  199. package/temp/rtk/tests/fixtures/dotnet/format_changes.json +0 -31
  200. package/temp/rtk/tests/fixtures/dotnet/format_empty.json +0 -1
  201. package/temp/rtk/tests/fixtures/dotnet/format_success.json +0 -12
  202. package/temp/rtk/tests/fixtures/dotnet/test_failed.txt +0 -18
@@ -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
- }'