@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.
Files changed (267) hide show
  1. package/dist/App.js +404 -0
  2. package/dist/Browse.js +79 -0
  3. package/dist/FuzzyPicker.js +47 -0
  4. package/dist/Onboarding.js +51 -0
  5. package/dist/Spinner.js +12 -0
  6. package/dist/StatusBar.js +49 -0
  7. package/dist/ai.js +322 -0
  8. package/dist/cache.js +41 -0
  9. package/dist/cli.js +64 -16
  10. package/dist/command-rewriter.js +64 -0
  11. package/dist/command-validator.js +86 -0
  12. package/dist/compression.js +107 -0
  13. package/dist/context-hints.js +275 -0
  14. package/dist/diff-cache.js +107 -0
  15. package/dist/discover.js +212 -0
  16. package/dist/economy.js +123 -0
  17. package/dist/expand-store.js +38 -0
  18. package/dist/file-cache.js +72 -0
  19. package/dist/file-index.js +62 -0
  20. package/dist/history.js +62 -0
  21. package/dist/lazy-executor.js +54 -0
  22. package/dist/line-dedup.js +59 -0
  23. package/dist/loop-detector.js +75 -0
  24. package/dist/mcp/install.js +98 -0
  25. package/dist/mcp/server.js +569 -0
  26. package/dist/noise-filter.js +86 -0
  27. package/dist/output-processor.js +129 -0
  28. package/dist/output-router.js +41 -0
  29. package/dist/output-store.js +111 -0
  30. package/dist/parsers/base.js +2 -0
  31. package/dist/parsers/build.js +64 -0
  32. package/dist/parsers/errors.js +101 -0
  33. package/dist/parsers/files.js +78 -0
  34. package/dist/parsers/git.js +99 -0
  35. package/dist/parsers/index.js +48 -0
  36. package/dist/parsers/tests.js +89 -0
  37. package/dist/providers/anthropic.js +39 -0
  38. package/dist/providers/base.js +4 -0
  39. package/dist/providers/cerebras.js +95 -0
  40. package/dist/providers/groq.js +95 -0
  41. package/dist/providers/index.js +73 -0
  42. package/dist/providers/xai.js +95 -0
  43. package/dist/recipes/model.js +20 -0
  44. package/dist/recipes/storage.js +136 -0
  45. package/dist/search/content-search.js +68 -0
  46. package/dist/search/file-search.js +61 -0
  47. package/dist/search/filters.js +34 -0
  48. package/dist/search/index.js +5 -0
  49. package/dist/search/semantic.js +320 -0
  50. package/dist/session-boot.js +59 -0
  51. package/dist/session-context.js +55 -0
  52. package/dist/sessions-db.js +173 -0
  53. package/dist/smart-display.js +286 -0
  54. package/dist/snapshots.js +51 -0
  55. package/dist/supervisor.js +112 -0
  56. package/dist/test-watchlist.js +131 -0
  57. package/dist/tool-profiles.js +122 -0
  58. package/dist/tree.js +94 -0
  59. package/dist/usage-cache.js +65 -0
  60. package/package.json +8 -1
  61. package/src/ai.ts +8 -0
  62. package/src/cli.tsx +57 -18
  63. package/src/output-processor.ts +6 -1
  64. package/src/output-store.ts +58 -12
  65. package/src/tool-profiles.ts +139 -0
  66. package/.claude/scheduled_tasks.lock +0 -1
  67. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -20
  68. package/.github/ISSUE_TEMPLATE/feature_request.md +0 -14
  69. package/CONTRIBUTING.md +0 -80
  70. package/benchmarks/benchmark.mjs +0 -115
  71. package/imported_modules.txt +0 -0
  72. package/temp/rtk/.claude/agents/code-reviewer.md +0 -221
  73. package/temp/rtk/.claude/agents/debugger.md +0 -519
  74. package/temp/rtk/.claude/agents/rtk-testing-specialist.md +0 -461
  75. package/temp/rtk/.claude/agents/rust-rtk.md +0 -511
  76. package/temp/rtk/.claude/agents/technical-writer.md +0 -355
  77. package/temp/rtk/.claude/commands/diagnose.md +0 -352
  78. package/temp/rtk/.claude/commands/test-routing.md +0 -362
  79. package/temp/rtk/.claude/hooks/bash/pre-commit-format.sh +0 -16
  80. package/temp/rtk/.claude/hooks/rtk-rewrite.sh +0 -70
  81. package/temp/rtk/.claude/hooks/rtk-suggest.sh +0 -152
  82. package/temp/rtk/.claude/rules/cli-testing.md +0 -526
  83. package/temp/rtk/.claude/skills/issue-triage/SKILL.md +0 -348
  84. package/temp/rtk/.claude/skills/issue-triage/templates/issue-comment.md +0 -134
  85. package/temp/rtk/.claude/skills/performance.md +0 -435
  86. package/temp/rtk/.claude/skills/pr-triage/SKILL.md +0 -315
  87. package/temp/rtk/.claude/skills/pr-triage/templates/review-comment.md +0 -71
  88. package/temp/rtk/.claude/skills/repo-recap.md +0 -206
  89. package/temp/rtk/.claude/skills/rtk-tdd/SKILL.md +0 -78
  90. package/temp/rtk/.claude/skills/rtk-tdd/references/testing-patterns.md +0 -124
  91. package/temp/rtk/.claude/skills/security-guardian.md +0 -503
  92. package/temp/rtk/.claude/skills/ship.md +0 -404
  93. package/temp/rtk/.github/workflows/benchmark.yml +0 -34
  94. package/temp/rtk/.github/workflows/dco-check.yaml +0 -12
  95. package/temp/rtk/.github/workflows/release-please.yml +0 -51
  96. package/temp/rtk/.github/workflows/release.yml +0 -343
  97. package/temp/rtk/.github/workflows/security-check.yml +0 -135
  98. package/temp/rtk/.github/workflows/validate-docs.yml +0 -78
  99. package/temp/rtk/.release-please-manifest.json +0 -3
  100. package/temp/rtk/ARCHITECTURE.md +0 -1491
  101. package/temp/rtk/CHANGELOG.md +0 -640
  102. package/temp/rtk/CLAUDE.md +0 -605
  103. package/temp/rtk/CONTRIBUTING.md +0 -199
  104. package/temp/rtk/Cargo.lock +0 -1668
  105. package/temp/rtk/Cargo.toml +0 -64
  106. package/temp/rtk/Formula/rtk.rb +0 -43
  107. package/temp/rtk/INSTALL.md +0 -390
  108. package/temp/rtk/LICENSE +0 -21
  109. package/temp/rtk/README.md +0 -386
  110. package/temp/rtk/README_es.md +0 -159
  111. package/temp/rtk/README_fr.md +0 -197
  112. package/temp/rtk/README_ja.md +0 -159
  113. package/temp/rtk/README_ko.md +0 -159
  114. package/temp/rtk/README_zh.md +0 -167
  115. package/temp/rtk/ROADMAP.md +0 -15
  116. package/temp/rtk/SECURITY.md +0 -217
  117. package/temp/rtk/TEST_EXEC_TIME.md +0 -102
  118. package/temp/rtk/build.rs +0 -57
  119. package/temp/rtk/docs/AUDIT_GUIDE.md +0 -432
  120. package/temp/rtk/docs/FEATURES.md +0 -1410
  121. package/temp/rtk/docs/TROUBLESHOOTING.md +0 -309
  122. package/temp/rtk/docs/filter-workflow.md +0 -102
  123. package/temp/rtk/docs/images/gain-dashboard.jpg +0 -0
  124. package/temp/rtk/docs/tracking.md +0 -583
  125. package/temp/rtk/hooks/opencode-rtk.ts +0 -39
  126. package/temp/rtk/hooks/rtk-awareness.md +0 -29
  127. package/temp/rtk/hooks/rtk-rewrite.sh +0 -61
  128. package/temp/rtk/hooks/test-rtk-rewrite.sh +0 -442
  129. package/temp/rtk/install.sh +0 -124
  130. package/temp/rtk/release-please-config.json +0 -10
  131. package/temp/rtk/scripts/benchmark.sh +0 -592
  132. package/temp/rtk/scripts/check-installation.sh +0 -162
  133. package/temp/rtk/scripts/install-local.sh +0 -37
  134. package/temp/rtk/scripts/rtk-economics.sh +0 -137
  135. package/temp/rtk/scripts/test-all.sh +0 -561
  136. package/temp/rtk/scripts/test-aristote.sh +0 -227
  137. package/temp/rtk/scripts/test-tracking.sh +0 -79
  138. package/temp/rtk/scripts/update-readme-metrics.sh +0 -32
  139. package/temp/rtk/scripts/validate-docs.sh +0 -73
  140. package/temp/rtk/src/aws_cmd.rs +0 -880
  141. package/temp/rtk/src/binlog.rs +0 -1645
  142. package/temp/rtk/src/cargo_cmd.rs +0 -1727
  143. package/temp/rtk/src/cc_economics.rs +0 -1157
  144. package/temp/rtk/src/ccusage.rs +0 -340
  145. package/temp/rtk/src/config.rs +0 -187
  146. package/temp/rtk/src/container.rs +0 -855
  147. package/temp/rtk/src/curl_cmd.rs +0 -134
  148. package/temp/rtk/src/deps.rs +0 -268
  149. package/temp/rtk/src/diff_cmd.rs +0 -367
  150. package/temp/rtk/src/discover/mod.rs +0 -274
  151. package/temp/rtk/src/discover/provider.rs +0 -388
  152. package/temp/rtk/src/discover/registry.rs +0 -2022
  153. package/temp/rtk/src/discover/report.rs +0 -202
  154. package/temp/rtk/src/discover/rules.rs +0 -667
  155. package/temp/rtk/src/display_helpers.rs +0 -402
  156. package/temp/rtk/src/dotnet_cmd.rs +0 -1771
  157. package/temp/rtk/src/dotnet_format_report.rs +0 -133
  158. package/temp/rtk/src/dotnet_trx.rs +0 -593
  159. package/temp/rtk/src/env_cmd.rs +0 -204
  160. package/temp/rtk/src/filter.rs +0 -462
  161. package/temp/rtk/src/filters/README.md +0 -52
  162. package/temp/rtk/src/filters/ansible-playbook.toml +0 -34
  163. package/temp/rtk/src/filters/basedpyright.toml +0 -47
  164. package/temp/rtk/src/filters/biome.toml +0 -45
  165. package/temp/rtk/src/filters/brew-install.toml +0 -37
  166. package/temp/rtk/src/filters/composer-install.toml +0 -40
  167. package/temp/rtk/src/filters/df.toml +0 -16
  168. package/temp/rtk/src/filters/dotnet-build.toml +0 -64
  169. package/temp/rtk/src/filters/du.toml +0 -16
  170. package/temp/rtk/src/filters/fail2ban-client.toml +0 -15
  171. package/temp/rtk/src/filters/gcc.toml +0 -49
  172. package/temp/rtk/src/filters/gcloud.toml +0 -22
  173. package/temp/rtk/src/filters/hadolint.toml +0 -24
  174. package/temp/rtk/src/filters/helm.toml +0 -29
  175. package/temp/rtk/src/filters/iptables.toml +0 -27
  176. package/temp/rtk/src/filters/jj.toml +0 -28
  177. package/temp/rtk/src/filters/jq.toml +0 -24
  178. package/temp/rtk/src/filters/make.toml +0 -41
  179. package/temp/rtk/src/filters/markdownlint.toml +0 -24
  180. package/temp/rtk/src/filters/mix-compile.toml +0 -27
  181. package/temp/rtk/src/filters/mix-format.toml +0 -15
  182. package/temp/rtk/src/filters/mvn-build.toml +0 -44
  183. package/temp/rtk/src/filters/oxlint.toml +0 -43
  184. package/temp/rtk/src/filters/ping.toml +0 -63
  185. package/temp/rtk/src/filters/pio-run.toml +0 -40
  186. package/temp/rtk/src/filters/poetry-install.toml +0 -50
  187. package/temp/rtk/src/filters/pre-commit.toml +0 -35
  188. package/temp/rtk/src/filters/ps.toml +0 -16
  189. package/temp/rtk/src/filters/quarto-render.toml +0 -41
  190. package/temp/rtk/src/filters/rsync.toml +0 -48
  191. package/temp/rtk/src/filters/shellcheck.toml +0 -27
  192. package/temp/rtk/src/filters/shopify-theme.toml +0 -29
  193. package/temp/rtk/src/filters/skopeo.toml +0 -45
  194. package/temp/rtk/src/filters/sops.toml +0 -16
  195. package/temp/rtk/src/filters/ssh.toml +0 -44
  196. package/temp/rtk/src/filters/stat.toml +0 -34
  197. package/temp/rtk/src/filters/swift-build.toml +0 -41
  198. package/temp/rtk/src/filters/systemctl-status.toml +0 -33
  199. package/temp/rtk/src/filters/terraform-plan.toml +0 -35
  200. package/temp/rtk/src/filters/tofu-fmt.toml +0 -16
  201. package/temp/rtk/src/filters/tofu-init.toml +0 -38
  202. package/temp/rtk/src/filters/tofu-plan.toml +0 -35
  203. package/temp/rtk/src/filters/tofu-validate.toml +0 -17
  204. package/temp/rtk/src/filters/trunk-build.toml +0 -39
  205. package/temp/rtk/src/filters/ty.toml +0 -50
  206. package/temp/rtk/src/filters/uv-sync.toml +0 -37
  207. package/temp/rtk/src/filters/xcodebuild.toml +0 -99
  208. package/temp/rtk/src/filters/yamllint.toml +0 -25
  209. package/temp/rtk/src/find_cmd.rs +0 -598
  210. package/temp/rtk/src/format_cmd.rs +0 -386
  211. package/temp/rtk/src/gain.rs +0 -723
  212. package/temp/rtk/src/gh_cmd.rs +0 -1651
  213. package/temp/rtk/src/git.rs +0 -2012
  214. package/temp/rtk/src/go_cmd.rs +0 -592
  215. package/temp/rtk/src/golangci_cmd.rs +0 -254
  216. package/temp/rtk/src/grep_cmd.rs +0 -288
  217. package/temp/rtk/src/gt_cmd.rs +0 -810
  218. package/temp/rtk/src/hook_audit_cmd.rs +0 -283
  219. package/temp/rtk/src/hook_check.rs +0 -171
  220. package/temp/rtk/src/init.rs +0 -1859
  221. package/temp/rtk/src/integrity.rs +0 -537
  222. package/temp/rtk/src/json_cmd.rs +0 -231
  223. package/temp/rtk/src/learn/detector.rs +0 -628
  224. package/temp/rtk/src/learn/mod.rs +0 -119
  225. package/temp/rtk/src/learn/report.rs +0 -184
  226. package/temp/rtk/src/lint_cmd.rs +0 -694
  227. package/temp/rtk/src/local_llm.rs +0 -316
  228. package/temp/rtk/src/log_cmd.rs +0 -248
  229. package/temp/rtk/src/ls.rs +0 -324
  230. package/temp/rtk/src/main.rs +0 -2482
  231. package/temp/rtk/src/mypy_cmd.rs +0 -389
  232. package/temp/rtk/src/next_cmd.rs +0 -241
  233. package/temp/rtk/src/npm_cmd.rs +0 -236
  234. package/temp/rtk/src/parser/README.md +0 -267
  235. package/temp/rtk/src/parser/error.rs +0 -46
  236. package/temp/rtk/src/parser/formatter.rs +0 -336
  237. package/temp/rtk/src/parser/mod.rs +0 -311
  238. package/temp/rtk/src/parser/types.rs +0 -119
  239. package/temp/rtk/src/pip_cmd.rs +0 -302
  240. package/temp/rtk/src/playwright_cmd.rs +0 -479
  241. package/temp/rtk/src/pnpm_cmd.rs +0 -573
  242. package/temp/rtk/src/prettier_cmd.rs +0 -221
  243. package/temp/rtk/src/prisma_cmd.rs +0 -482
  244. package/temp/rtk/src/psql_cmd.rs +0 -382
  245. package/temp/rtk/src/pytest_cmd.rs +0 -384
  246. package/temp/rtk/src/read.rs +0 -217
  247. package/temp/rtk/src/rewrite_cmd.rs +0 -50
  248. package/temp/rtk/src/ruff_cmd.rs +0 -402
  249. package/temp/rtk/src/runner.rs +0 -271
  250. package/temp/rtk/src/summary.rs +0 -297
  251. package/temp/rtk/src/tee.rs +0 -405
  252. package/temp/rtk/src/telemetry.rs +0 -248
  253. package/temp/rtk/src/toml_filter.rs +0 -1655
  254. package/temp/rtk/src/tracking.rs +0 -1416
  255. package/temp/rtk/src/tree.rs +0 -209
  256. package/temp/rtk/src/tsc_cmd.rs +0 -259
  257. package/temp/rtk/src/utils.rs +0 -432
  258. package/temp/rtk/src/verify_cmd.rs +0 -47
  259. package/temp/rtk/src/vitest_cmd.rs +0 -385
  260. package/temp/rtk/src/wc_cmd.rs +0 -401
  261. package/temp/rtk/src/wget_cmd.rs +0 -260
  262. package/temp/rtk/tests/fixtures/dotnet/build_failed.txt +0 -11
  263. package/temp/rtk/tests/fixtures/dotnet/format_changes.json +0 -31
  264. package/temp/rtk/tests/fixtures/dotnet/format_empty.json +0 -1
  265. package/temp/rtk/tests/fixtures/dotnet/format_success.json +0 -12
  266. package/temp/rtk/tests/fixtures/dotnet/test_failed.txt +0 -18
  267. package/tsconfig.json +0 -15
@@ -1,526 +0,0 @@
1
- # CLI Testing Strategy
2
-
3
- Comprehensive testing rules for RTK CLI tool development.
4
-
5
- ## Snapshot Testing (🔴 Critical)
6
-
7
- **Priority**: 🔴 **Triggers**: All filter changes, output format modifications
8
-
9
- Use `insta` crate for output validation. This is the **primary testing strategy** for RTK filters.
10
-
11
- ### Basic Snapshot Test
12
-
13
- ```rust
14
- use insta::assert_snapshot;
15
-
16
- #[test]
17
- fn test_git_log_output() {
18
- let input = include_str!("../tests/fixtures/git_log_raw.txt");
19
- let output = filter_git_log(input);
20
-
21
- // Snapshot test - will fail if output changes
22
- assert_snapshot!(output);
23
- }
24
- ```
25
-
26
- ### Workflow
27
-
28
- 1. **Write test**: Add `assert_snapshot!(output);` in test
29
- 2. **Run tests**: `cargo test` (creates new snapshots on first run)
30
- 3. **Review snapshots**: `cargo insta review` (interactive review)
31
- 4. **Accept changes**: `cargo insta accept` (if output is correct)
32
-
33
- ### When to Use
34
-
35
- - **Every new filter**: All filters must have snapshot test
36
- - **Output format changes**: When modifying filter logic
37
- - **Regression detection**: Catch unintended changes
38
-
39
- ### Example Workflow
40
-
41
- ```bash
42
- # 1. Create fixture from real command
43
- git log -20 > tests/fixtures/git_log_raw.txt
44
-
45
- # 2. Write test with assert_snapshot!
46
- cat > src/git.rs <<'EOF'
47
- #[cfg(test)]
48
- mod tests {
49
- use insta::assert_snapshot;
50
-
51
- #[test]
52
- fn test_git_log_format() {
53
- let input = include_str!("../tests/fixtures/git_log_raw.txt");
54
- let output = filter_git_log(input);
55
- assert_snapshot!(output);
56
- }
57
- }
58
- EOF
59
-
60
- # 3. Run test (creates snapshot)
61
- cargo test test_git_log_format
62
-
63
- # 4. Review snapshot
64
- cargo insta review
65
- # Press 'a' to accept, 'r' to reject
66
-
67
- # 5. Snapshot saved in src/snapshots/git.rs.snap
68
- ```
69
-
70
- ## Token Accuracy Testing (🔴 Critical)
71
-
72
- **Priority**: 🔴 **Triggers**: All filter implementations, token savings claims
73
-
74
- All filters **MUST** verify 60-90% token savings claims with real fixtures.
75
-
76
- ### Token Count Test
77
-
78
- ```rust
79
- #[cfg(test)]
80
- mod tests {
81
- fn count_tokens(text: &str) -> usize {
82
- text.split_whitespace().count()
83
- }
84
-
85
- #[test]
86
- fn test_git_log_savings() {
87
- let input = include_str!("../tests/fixtures/git_log_raw.txt");
88
- let output = filter_git_log(input);
89
-
90
- let input_tokens = count_tokens(input);
91
- let output_tokens = count_tokens(&output);
92
-
93
- let savings = 100.0 - (output_tokens as f64 / input_tokens as f64 * 100.0);
94
-
95
- assert!(
96
- savings >= 60.0,
97
- "Git log filter: expected ≥60% savings, got {:.1}%",
98
- savings
99
- );
100
- }
101
- }
102
- ```
103
-
104
- ### Creating Fixtures
105
-
106
- **Use real command output**, not synthetic data:
107
-
108
- ```bash
109
- # Capture real output
110
- git log -20 > tests/fixtures/git_log_raw.txt
111
- cargo test 2>&1 > tests/fixtures/cargo_test_raw.txt
112
- gh pr view 123 > tests/fixtures/gh_pr_view_raw.txt
113
- pnpm list > tests/fixtures/pnpm_list_raw.txt
114
-
115
- # Then use in tests:
116
- # let input = include_str!("../tests/fixtures/git_log_raw.txt");
117
- ```
118
-
119
- ### Savings Targets by Filter
120
-
121
- | Filter | Expected Savings | Rationale |
122
- |--------|------------------|-----------|
123
- | `git log` | 80%+ | Condense commits to hash + message |
124
- | `cargo test` | 90%+ | Show failures only |
125
- | `gh pr view` | 87%+ | Remove ASCII art, verbose metadata |
126
- | `pnpm list` | 70%+ | Compact dependency tree |
127
- | `docker ps` | 60%+ | Essential fields only |
128
-
129
- **Release blocker**: If savings drop below 60% for any filter, investigate and fix before merge.
130
-
131
- ## Cross-Platform Testing (🔴 Critical)
132
-
133
- **Priority**: 🔴 **Triggers**: Shell escaping changes, command execution logic
134
-
135
- RTK must work on macOS (zsh), Linux (bash), Windows (PowerShell). Shell escaping differs.
136
-
137
- ### Platform-Specific Tests
138
-
139
- ```rust
140
- #[cfg(target_os = "windows")]
141
- const EXPECTED_SHELL: &str = "cmd.exe";
142
-
143
- #[cfg(target_os = "macos")]
144
- const EXPECTED_SHELL: &str = "zsh";
145
-
146
- #[cfg(target_os = "linux")]
147
- const EXPECTED_SHELL: &str = "bash";
148
-
149
- #[test]
150
- fn test_shell_escaping() {
151
- let cmd = r#"git log --format="%H %s""#;
152
- let escaped = escape_for_shell(cmd);
153
-
154
- #[cfg(target_os = "windows")]
155
- assert_eq!(escaped, r#"git log --format=\"%H %s\""#);
156
-
157
- #[cfg(not(target_os = "windows"))]
158
- assert_eq!(escaped, r#"git log --format="%H %s""#);
159
- }
160
- ```
161
-
162
- ### Testing Platforms
163
-
164
- **macOS (primary)**:
165
- ```bash
166
- cargo test # Local testing
167
- ```
168
-
169
- **Linux (via Docker)**:
170
- ```bash
171
- docker run --rm -v $(pwd):/rtk -w /rtk rust:latest cargo test
172
- ```
173
-
174
- **Windows (via CI)**:
175
- Trust GitHub Actions CI/CD pipeline or test manually if Windows machine available.
176
-
177
- ### Shell Differences
178
-
179
- | Platform | Shell | Quote Escape | Path Sep |
180
- |----------|-------|--------------|----------|
181
- | macOS | zsh | `'single'` or `"double"` | `/` |
182
- | Linux | bash | `'single'` or `"double"` | `/` |
183
- | Windows | PowerShell | `` `backtick `` or `"double"` | `\` |
184
-
185
- ## Integration Tests (🟡 Important)
186
-
187
- **Priority**: 🟡 **Triggers**: New filter, command routing changes, release preparation
188
-
189
- Integration tests execute real commands via RTK to verify end-to-end behavior.
190
-
191
- ### Real Command Execution
192
-
193
- ```rust
194
- #[test]
195
- #[ignore] // Run with: cargo test --ignored
196
- fn test_real_git_log() {
197
- // Requires:
198
- // 1. RTK binary installed (cargo install --path .)
199
- // 2. Git repository available
200
-
201
- let output = std::process::Command::new("rtk")
202
- .args(&["git", "log", "-10"])
203
- .output()
204
- .expect("Failed to run rtk");
205
-
206
- assert!(output.status.success());
207
- assert!(!output.stdout.is_empty());
208
-
209
- // Verify condensed (not raw git output)
210
- let stdout = String::from_utf8_lossy(&output.stdout);
211
- assert!(stdout.len() < 5000, "Output too large, filter not working");
212
- }
213
- ```
214
-
215
- ### Running Integration Tests
216
-
217
- ```bash
218
- # 1. Install RTK locally
219
- cargo install --path .
220
-
221
- # 2. Run integration tests
222
- cargo test --ignored
223
-
224
- # 3. Run specific test
225
- cargo test --ignored test_real_git_log
226
- ```
227
-
228
- ### When to Run
229
-
230
- - **Before release**: Always run integration tests
231
- - **After filter changes**: Verify filter works with real command
232
- - **After hook changes**: Verify Claude Code integration works
233
-
234
- ## Performance Testing (🟡 Important)
235
-
236
- **Priority**: 🟡 **Triggers**: Performance-related changes, release preparation
237
-
238
- RTK targets <10ms startup time and <5MB memory usage.
239
-
240
- ### Benchmark Startup Time
241
-
242
- ```bash
243
- # Install hyperfine
244
- brew install hyperfine # macOS
245
- cargo install hyperfine # or via cargo
246
-
247
- # Benchmark RTK vs raw command
248
- hyperfine 'rtk git status' 'git status' --warmup 3
249
-
250
- # Should show RTK startup <10ms
251
- # Example output:
252
- # rtk git status 6.2 ms ± 0.3 ms
253
- # git status 8.1 ms ± 0.4 ms
254
- ```
255
-
256
- ### Memory Usage
257
-
258
- ```bash
259
- # macOS
260
- /usr/bin/time -l rtk git status
261
- # Look for "maximum resident set size" - should be <5MB
262
-
263
- # Linux
264
- /usr/bin/time -v rtk git status
265
- # Look for "Maximum resident set size" - should be <5000 kbytes
266
- ```
267
-
268
- ### Regression Detection
269
-
270
- **Before changes**:
271
- ```bash
272
- hyperfine 'rtk git log -10' --warmup 3 > /tmp/before.txt
273
- ```
274
-
275
- **After changes**:
276
- ```bash
277
- cargo build --release
278
- hyperfine 'target/release/rtk git log -10' --warmup 3 > /tmp/after.txt
279
- ```
280
-
281
- **Compare**:
282
- ```bash
283
- diff /tmp/before.txt /tmp/after.txt
284
- # If startup time increased >2ms, investigate
285
- ```
286
-
287
- ### Performance Targets
288
-
289
- | Metric | Target | Verification |
290
- |--------|--------|--------------|
291
- | Startup time | <10ms | `hyperfine 'rtk <cmd>'` |
292
- | Memory usage | <5MB | `time -l rtk <cmd>` |
293
- | Binary size | <5MB | `ls -lh target/release/rtk` |
294
-
295
- ## Test Organization
296
-
297
- **Directory structure**:
298
-
299
- ```
300
- rtk/
301
- ├── src/
302
- │ ├── git.rs # Filter implementation
303
- │ │ └── #[cfg(test)] mod tests { ... } # Unit tests
304
- │ ├── snapshots/ # Insta snapshots
305
- │ │ └── git.rs.snap # Snapshot for git tests
306
- ├── tests/
307
- │ ├── common/
308
- │ │ └── mod.rs # Shared test utilities (count_tokens)
309
- │ ├── fixtures/ # Real command output
310
- │ │ ├── git_log_raw.txt
311
- │ │ ├── cargo_test_raw.txt
312
- │ │ └── gh_pr_view_raw.txt
313
- │ └── integration_test.rs # Integration tests (#[ignore])
314
- ```
315
-
316
- **Best practices**:
317
- - **Unit tests**: Embedded in module (`#[cfg(test)] mod tests`)
318
- - **Fixtures**: Real command output in `tests/fixtures/`
319
- - **Snapshots**: Auto-generated in `src/snapshots/` (by insta)
320
- - **Shared utils**: `tests/common/mod.rs` (count_tokens, helpers)
321
- - **Integration**: `tests/` with `#[ignore]` attribute
322
-
323
- ## Testing Checklist
324
-
325
- When adding/modifying a filter:
326
-
327
- ### Implementation Phase
328
- - [ ] Create fixture from real command output
329
- - [ ] Add snapshot test with `assert_snapshot!()`
330
- - [ ] Add token accuracy test (verify ≥60% savings)
331
- - [ ] Test cross-platform shell escaping (if applicable)
332
-
333
- ### Quality Checks
334
- - [ ] Run `cargo test --all` (all tests pass)
335
- - [ ] Run `cargo insta review` (review snapshots)
336
- - [ ] Run `cargo test --ignored` (integration tests pass)
337
- - [ ] Benchmark startup time with `hyperfine` (<10ms)
338
-
339
- ### Before Merge
340
- - [ ] All tests passing (`cargo test --all`)
341
- - [ ] Snapshots reviewed and accepted (`cargo insta accept`)
342
- - [ ] Token savings ≥60% verified
343
- - [ ] Cross-platform tests passed (macOS + Linux)
344
- - [ ] Performance benchmarks passed (<10ms startup)
345
-
346
- ### Before Release
347
- - [ ] Integration tests passed (`cargo test --ignored`)
348
- - [ ] Performance regression check (hyperfine comparison)
349
- - [ ] Memory usage verified (<5MB with `time -l`)
350
- - [ ] Cross-platform CI passed (macOS + Linux + Windows)
351
-
352
- ## Common Testing Patterns
353
-
354
- ### Pattern: Snapshot + Token Accuracy
355
-
356
- **Use case**: Testing filter output format and savings
357
-
358
- ```rust
359
- #[cfg(test)]
360
- mod tests {
361
- use super::*;
362
- use insta::assert_snapshot;
363
-
364
- fn count_tokens(text: &str) -> usize {
365
- text.split_whitespace().count()
366
- }
367
-
368
- #[test]
369
- fn test_output_format() {
370
- let input = include_str!("../tests/fixtures/cmd_raw.txt");
371
- let output = filter_cmd(input);
372
- assert_snapshot!(output);
373
- }
374
-
375
- #[test]
376
- fn test_token_savings() {
377
- let input = include_str!("../tests/fixtures/cmd_raw.txt");
378
- let output = filter_cmd(input);
379
-
380
- let savings = 100.0 - (count_tokens(&output) as f64 / count_tokens(input) as f64 * 100.0);
381
- assert!(savings >= 60.0, "Expected ≥60% savings, got {:.1}%", savings);
382
- }
383
- }
384
- ```
385
-
386
- ### Pattern: Edge Case Testing
387
-
388
- **Use case**: Testing filter robustness
389
-
390
- ```rust
391
- #[test]
392
- fn test_empty_input() {
393
- let output = filter_cmd("");
394
- assert_eq!(output, "");
395
- }
396
-
397
- #[test]
398
- fn test_malformed_input() {
399
- let malformed = "not valid command output";
400
- let output = filter_cmd(malformed);
401
- // Should either:
402
- // 1. Return best-effort filtered output, OR
403
- // 2. Return original input unchanged (fallback)
404
- // Both acceptable - just don't panic!
405
- assert!(!output.is_empty());
406
- }
407
-
408
- #[test]
409
- fn test_unicode_input() {
410
- let unicode = "commit 日本語メッセージ";
411
- let output = filter_cmd(unicode);
412
- assert!(output.contains("commit"));
413
- }
414
-
415
- #[test]
416
- fn test_ansi_codes() {
417
- let ansi = "\x1b[32mSuccess\x1b[0m";
418
- let output = filter_cmd(ansi);
419
- // Should strip ANSI or preserve, but not break
420
- assert!(output.contains("Success") || output.contains("\x1b[32m"));
421
- }
422
- ```
423
-
424
- ### Pattern: Integration Test
425
-
426
- **Use case**: Verify end-to-end behavior
427
-
428
- ```rust
429
- #[test]
430
- #[ignore]
431
- fn test_real_command_execution() {
432
- let output = std::process::Command::new("rtk")
433
- .args(&["cmd", "args"])
434
- .output()
435
- .expect("Failed to run rtk");
436
-
437
- assert!(output.status.success());
438
- assert!(!output.stdout.is_empty());
439
-
440
- let stdout = String::from_utf8_lossy(&output.stdout);
441
- assert!(stdout.len() < 5000, "Output too large");
442
- }
443
- ```
444
-
445
- ## Anti-Patterns
446
-
447
- ❌ **DON'T** test with hardcoded synthetic data
448
- ```rust
449
- // ❌ WRONG
450
- let input = "commit abc123\nAuthor: John";
451
- let output = filter_git_log(input);
452
- // Synthetic data doesn't reflect real command output
453
- ```
454
-
455
- ✅ **DO** use real command fixtures
456
- ```rust
457
- // ✅ RIGHT
458
- let input = include_str!("../tests/fixtures/git_log_raw.txt");
459
- let output = filter_git_log(input);
460
- // Real output from `git log -20`
461
- ```
462
-
463
- ❌ **DON'T** skip cross-platform tests
464
- ```rust
465
- // ❌ WRONG - only tests current platform
466
- #[test]
467
- fn test_shell_escaping() {
468
- let escaped = escape("test");
469
- assert_eq!(escaped, "test");
470
- }
471
- ```
472
-
473
- ✅ **DO** test all platforms with cfg
474
- ```rust
475
- // ✅ RIGHT - tests all platforms
476
- #[test]
477
- fn test_shell_escaping() {
478
- let escaped = escape("test");
479
-
480
- #[cfg(target_os = "windows")]
481
- assert_eq!(escaped, "\"test\"");
482
-
483
- #[cfg(not(target_os = "windows"))]
484
- assert_eq!(escaped, "test");
485
- }
486
- ```
487
-
488
- ❌ **DON'T** ignore performance regressions
489
- ```rust
490
- // ❌ WRONG - no performance tracking
491
- #[test]
492
- fn test_filter() {
493
- let output = filter_cmd(input);
494
- assert!(!output.is_empty());
495
- }
496
- ```
497
-
498
- ✅ **DO** benchmark and track performance
499
- ```bash
500
- # ✅ RIGHT - benchmark before/after
501
- hyperfine 'rtk cmd' --warmup 3 > /tmp/before.txt
502
- # Make changes
503
- cargo build --release
504
- hyperfine 'target/release/rtk cmd' --warmup 3 > /tmp/after.txt
505
- diff /tmp/before.txt /tmp/after.txt
506
- ```
507
-
508
- ❌ **DON'T** accept <60% token savings
509
- ```rust
510
- // ❌ WRONG - no savings verification
511
- #[test]
512
- fn test_filter() {
513
- let output = filter_cmd(input);
514
- assert!(!output.is_empty());
515
- }
516
- ```
517
-
518
- ✅ **DO** verify savings claims
519
- ```rust
520
- // ✅ RIGHT - verify ≥60% savings
521
- #[test]
522
- fn test_token_savings() {
523
- let savings = calculate_savings(input, output);
524
- assert!(savings >= 60.0, "Expected ≥60%, got {:.1}%", savings);
525
- }
526
- ```