@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.
- package/dist/cli.js +64 -16
- package/package.json +1 -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/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
|
@@ -1,315 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: >
|
|
3
|
-
PR triage: audit open PRs, deep review selected ones, draft and post review comments.
|
|
4
|
-
Args: "all" to review all, PR numbers to focus (e.g. "42 57"), "en"/"fr" for language, no arg = audit only in French.
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# PR Triage
|
|
8
|
-
|
|
9
|
-
## Quand utiliser
|
|
10
|
-
|
|
11
|
-
| Skill | Usage | Output |
|
|
12
|
-
|-------|-------|--------|
|
|
13
|
-
| `/pr-triage` | Trier, reviewer, commenter les PRs | Tableau d'action + reviews + commentaires postés |
|
|
14
|
-
| `/repo-recap` | Récap général pour partager avec l'équipe | Résumé Markdown (PRs + issues + releases) |
|
|
15
|
-
|
|
16
|
-
**Déclencheurs** :
|
|
17
|
-
- Manuellement : `/pr-triage` ou `/pr-triage all` ou `/pr-triage 42 57`
|
|
18
|
-
- Proactivement : quand >5 PRs ouvertes sans review, ou PR stale >14j détectée
|
|
19
|
-
|
|
20
|
-
---
|
|
21
|
-
|
|
22
|
-
## Langue
|
|
23
|
-
|
|
24
|
-
- Vérifier l'argument passé au skill
|
|
25
|
-
- Si `en` ou `english` → tableaux et résumé en anglais
|
|
26
|
-
- Si `fr`, `french`, ou pas d'argument → français (défaut)
|
|
27
|
-
- Note : les commentaires GitHub (Phase 3) restent TOUJOURS en anglais (audience internationale)
|
|
28
|
-
|
|
29
|
-
---
|
|
30
|
-
|
|
31
|
-
Workflow en 3 phases : audit automatique → deep review opt-in → commentaires avec validation obligatoire.
|
|
32
|
-
|
|
33
|
-
## Préconditions
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
git rev-parse --is-inside-work-tree
|
|
37
|
-
gh auth status
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
Si l'un échoue, stop et expliquer ce qui manque.
|
|
41
|
-
|
|
42
|
-
---
|
|
43
|
-
|
|
44
|
-
## Phase 1 — Audit (toujours exécutée)
|
|
45
|
-
|
|
46
|
-
### Data Gathering (commandes en parallèle)
|
|
47
|
-
|
|
48
|
-
```bash
|
|
49
|
-
# Identité du repo
|
|
50
|
-
gh repo view --json nameWithOwner -q .nameWithOwner
|
|
51
|
-
|
|
52
|
-
# PRs ouvertes avec métadonnées complètes (ajouter body pour cross-référence issues)
|
|
53
|
-
gh pr list --state open --limit 50 \
|
|
54
|
-
--json number,title,author,createdAt,updatedAt,additions,deletions,changedFiles,isDraft,mergeable,reviewDecision,statusCheckRollup,body
|
|
55
|
-
|
|
56
|
-
# Collaborateurs (pour distinguer "nos PRs" des externes)
|
|
57
|
-
gh api "repos/{owner}/{repo}/collaborators" --jq '.[].login'
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
**Fallback collaborateurs** : si `gh api .../collaborators` échoue (403/404) :
|
|
61
|
-
```bash
|
|
62
|
-
# Extraire les auteurs des 10 derniers PRs mergés
|
|
63
|
-
gh pr list --state merged --limit 10 --json author --jq '.[].author.login' | sort -u
|
|
64
|
-
```
|
|
65
|
-
Si toujours ambigu, demander à l'utilisateur via `AskUserQuestion`.
|
|
66
|
-
|
|
67
|
-
Pour chaque PR, récupérer reviews existantes ET fichiers modifiés :
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
gh api "repos/{owner}/{repo}/pulls/{num}/reviews" \
|
|
71
|
-
--jq '[.[] | .user.login + ":" + .state] | join(", ")'
|
|
72
|
-
|
|
73
|
-
# Fichiers modifiés (nécessaire pour overlap detection)
|
|
74
|
-
gh pr view {num} --json files --jq '[.files[].path] | join(",")'
|
|
75
|
-
```
|
|
76
|
-
|
|
77
|
-
**Note rate-limiting** : la récupération des fichiers est N appels API (1 par PR). Pour repos avec 20+ PRs, prioriser les PRs candidates à l'overlap (même domaine fonctionnel, même auteur).
|
|
78
|
-
|
|
79
|
-
**Note** : `author` est un objet `{login: "..."}` — toujours extraire `.author.login`.
|
|
80
|
-
|
|
81
|
-
### Analyse
|
|
82
|
-
|
|
83
|
-
**Classification taille** :
|
|
84
|
-
| Label | Additions |
|
|
85
|
-
|-------|-----------|
|
|
86
|
-
| XS | < 50 |
|
|
87
|
-
| S | 50–200 |
|
|
88
|
-
| M | 200–500 |
|
|
89
|
-
| L | 500–1000 |
|
|
90
|
-
| XL | > 1000 |
|
|
91
|
-
|
|
92
|
-
Format taille : `+{additions}/-{deletions}, {files} files ({label})`
|
|
93
|
-
|
|
94
|
-
**Détections** :
|
|
95
|
-
- **Overlaps** : comparer les listes de fichiers entre PRs — si >50% de fichiers en commun → cross-reference
|
|
96
|
-
- **Clusters** : auteur avec 3+ PRs ouvertes → suggérer ordre de review (plus petite en premier)
|
|
97
|
-
- **Staleness** : aucune activité depuis >14j → flag "stale"
|
|
98
|
-
- **CI status** : via `statusCheckRollup` → `clean` / `unstable` / `dirty`
|
|
99
|
-
- **Reviews** : approved / changes_requested / aucune
|
|
100
|
-
|
|
101
|
-
**Liens PR ↔ Issues** :
|
|
102
|
-
- Scanner le `body` de chaque PR pour `fixes #N`, `closes #N`, `resolves #N` (case-insensitive)
|
|
103
|
-
- Si trouvé, afficher dans le tableau : `Fixes #42` dans la colonne Action/Status
|
|
104
|
-
|
|
105
|
-
**Catégorisation** :
|
|
106
|
-
|
|
107
|
-
_Nos PRs_ : auteur dans la liste des collaborateurs
|
|
108
|
-
|
|
109
|
-
_Externes — Prêtes_ : additions ≤ 1000 ET files ≤ 10 ET `mergeable` ≠ `CONFLICTING` ET CI clean/unstable
|
|
110
|
-
|
|
111
|
-
_Externes — Problématiques_ : un des critères suivants :
|
|
112
|
-
- additions > 1000 OU files > 10
|
|
113
|
-
- OU `mergeable` == `CONFLICTING` (conflit de merge)
|
|
114
|
-
- OU CI dirty (statusCheckRollup contient des échecs)
|
|
115
|
-
- OU overlap avec une autre PR ouverte (>50% fichiers communs)
|
|
116
|
-
|
|
117
|
-
### Output — Tableau de triage
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
## PRs ouvertes ({count})
|
|
121
|
-
|
|
122
|
-
### Nos PRs
|
|
123
|
-
| PR | Titre | Taille | CI | Status |
|
|
124
|
-
| -- | ----- | ------ | -- | ------ |
|
|
125
|
-
|
|
126
|
-
### Externes — Prêtes pour review
|
|
127
|
-
| PR | Auteur | Titre | Taille | CI | Reviews | Action |
|
|
128
|
-
| -- | ------ | ----- | ------ | -- | ------- | ------ |
|
|
129
|
-
|
|
130
|
-
### Externes — Problématiques
|
|
131
|
-
| PR | Auteur | Titre | Taille | Problème | Action recommandée |
|
|
132
|
-
| -- | ------ | ----- | ------ | -------- | ------------------ |
|
|
133
|
-
|
|
134
|
-
### Résumé
|
|
135
|
-
- Quick wins : {PRs XS/S prêtes à merger}
|
|
136
|
-
- Risques : {overlaps, tailles XL, CI dirty}
|
|
137
|
-
- Clusters : {auteurs avec 3+ PRs}
|
|
138
|
-
- Stale : {PRs sans activité >14j}
|
|
139
|
-
- Overlaps : {PRs qui touchent les mêmes fichiers}
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
0 PRs → afficher `Aucune PR ouverte.` et terminer.
|
|
143
|
-
|
|
144
|
-
### Copie automatique
|
|
145
|
-
|
|
146
|
-
Après affichage du tableau de triage, copier dans le presse-papier :
|
|
147
|
-
```bash
|
|
148
|
-
pbcopy <<'EOF'
|
|
149
|
-
{tableau de triage complet}
|
|
150
|
-
EOF
|
|
151
|
-
```
|
|
152
|
-
Confirmer : `Tableau copié dans le presse-papier.` (FR) / `Triage table copied to clipboard.` (EN)
|
|
153
|
-
|
|
154
|
-
---
|
|
155
|
-
|
|
156
|
-
## Phase 2 — Deep Review (opt-in)
|
|
157
|
-
|
|
158
|
-
### Sélection des PRs
|
|
159
|
-
|
|
160
|
-
**Si argument passé** :
|
|
161
|
-
- `"all"` → toutes les PRs externes
|
|
162
|
-
- Numéros (`"42 57"`) → uniquement ces PRs
|
|
163
|
-
- Pas d'argument → proposer via `AskUserQuestion`
|
|
164
|
-
|
|
165
|
-
**Si pas d'argument**, afficher :
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
question: "Quelles PRs voulez-vous reviewer en profondeur ?"
|
|
169
|
-
header: "Deep Review"
|
|
170
|
-
multiSelect: true
|
|
171
|
-
options:
|
|
172
|
-
- label: "Toutes les externes"
|
|
173
|
-
description: "Review {N} PRs externes avec agents code-reviewer en parallèle"
|
|
174
|
-
- label: "Problématiques uniquement"
|
|
175
|
-
description: "Focus sur les {M} PRs à risque (CI dirty, trop large, overlaps)"
|
|
176
|
-
- label: "Prêtes uniquement"
|
|
177
|
-
description: "Review {K} PRs prêtes à merger"
|
|
178
|
-
- label: "Passer"
|
|
179
|
-
description: "Terminer ici — juste l'audit"
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
**Note sur les drafts** :
|
|
183
|
-
- Les PRs en draft sont EXCLUES des options "Toutes les externes" et "Prêtes uniquement"
|
|
184
|
-
- Les PRs en draft sont INCLUSES dans "Problématiques uniquement" (car elles nécessitent attention)
|
|
185
|
-
- Pour reviewer un draft : taper son numéro explicitement (ex: `42`)
|
|
186
|
-
|
|
187
|
-
Si "Passer" → fin du workflow.
|
|
188
|
-
|
|
189
|
-
### Exécution des Reviews
|
|
190
|
-
|
|
191
|
-
Pour chaque PR sélectionnée, lancer un agent `code-reviewer` via **Task tool en parallèle** :
|
|
192
|
-
|
|
193
|
-
```
|
|
194
|
-
subagent_type: code-reviewer
|
|
195
|
-
model: sonnet
|
|
196
|
-
prompt: |
|
|
197
|
-
Review PR #{num}: "{title}" by @{author}
|
|
198
|
-
|
|
199
|
-
**Metadata**: +{additions}/-{deletions}, {changedFiles} files ({size_label})
|
|
200
|
-
**CI**: {ci_status} | **Reviews**: {existing_reviews} | **Draft**: {isDraft}
|
|
201
|
-
|
|
202
|
-
**PR Body**:
|
|
203
|
-
{body}
|
|
204
|
-
|
|
205
|
-
**Diff**:
|
|
206
|
-
{gh pr diff {num} output}
|
|
207
|
-
|
|
208
|
-
Apply your security-guardian and backend-architect skills for this review.
|
|
209
|
-
Additionally, apply the RTK-specific checklist:
|
|
210
|
-
- lazy_static! regex (no inline Regex::new())
|
|
211
|
-
- anyhow::Result + .context() (no unwrap())
|
|
212
|
-
- Fallback to raw command on filter failure
|
|
213
|
-
- Exit code propagation
|
|
214
|
-
- Token savings ≥60% in tests with real fixtures
|
|
215
|
-
- No async/tokio dependencies
|
|
216
|
-
|
|
217
|
-
Return structured review:
|
|
218
|
-
### Critical Issues 🔴
|
|
219
|
-
### Important Issues 🟡
|
|
220
|
-
### Suggestions 🟢
|
|
221
|
-
### What's Good ✅
|
|
222
|
-
|
|
223
|
-
Be specific: quote the file:line, explain why it's an issue, suggest the fix.
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
Récupérer le diff via :
|
|
227
|
-
```bash
|
|
228
|
-
gh pr diff {num}
|
|
229
|
-
gh pr view {num} --json body,title,author -q '{body: .body, title: .title, author: .author.login}'
|
|
230
|
-
```
|
|
231
|
-
|
|
232
|
-
Agréger tous les rapports. Afficher un résumé après toutes les reviews.
|
|
233
|
-
|
|
234
|
-
---
|
|
235
|
-
|
|
236
|
-
## Phase 3 — Commentaires (validation obligatoire)
|
|
237
|
-
|
|
238
|
-
### Génération des drafts
|
|
239
|
-
|
|
240
|
-
Pour chaque PR reviewée, générer un commentaire GitHub en utilisant le template `templates/review-comment.md`.
|
|
241
|
-
|
|
242
|
-
**Règles** :
|
|
243
|
-
- Langue : **anglais** (audience internationale)
|
|
244
|
-
- Ton : professionnel, constructif, factuel
|
|
245
|
-
- Toujours inclure au moins 1 point positif
|
|
246
|
-
- Citer les lignes de code quand pertinent (format `file.rs:42`)
|
|
247
|
-
|
|
248
|
-
### Affichage et validation
|
|
249
|
-
|
|
250
|
-
**Afficher TOUS les commentaires draftés** au format :
|
|
251
|
-
|
|
252
|
-
```
|
|
253
|
-
---
|
|
254
|
-
### Draft — PR #{num}: {title}
|
|
255
|
-
|
|
256
|
-
{commentaire complet}
|
|
257
|
-
|
|
258
|
-
---
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
Puis demander validation via `AskUserQuestion` :
|
|
262
|
-
|
|
263
|
-
```
|
|
264
|
-
question: "Ces commentaires sont prêts. Lesquels voulez-vous poster ?"
|
|
265
|
-
header: "Poster"
|
|
266
|
-
multiSelect: true
|
|
267
|
-
options:
|
|
268
|
-
- label: "Tous ({N} commentaires)"
|
|
269
|
-
description: "Poster sur toutes les PRs reviewées"
|
|
270
|
-
- label: "PR #{x} — {title_truncated}"
|
|
271
|
-
description: "Poster uniquement sur cette PR"
|
|
272
|
-
- label: "Aucun"
|
|
273
|
-
description: "Annuler — ne rien poster"
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
(Générer une option par PR + "Tous" + "Aucun")
|
|
277
|
-
|
|
278
|
-
### Posting
|
|
279
|
-
|
|
280
|
-
Pour chaque commentaire validé :
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
gh pr comment {num} --body-file - <<'REVIEW_EOF'
|
|
284
|
-
{commentaire}
|
|
285
|
-
REVIEW_EOF
|
|
286
|
-
```
|
|
287
|
-
|
|
288
|
-
Confirmer chaque post : `✅ Commentaire posté sur PR #{num}: {title}`
|
|
289
|
-
|
|
290
|
-
Si "Aucun" → `Aucun commentaire posté. Workflow terminé.`
|
|
291
|
-
|
|
292
|
-
---
|
|
293
|
-
|
|
294
|
-
## Gestion des cas limites
|
|
295
|
-
|
|
296
|
-
| Situation | Comportement |
|
|
297
|
-
|-----------|--------------|
|
|
298
|
-
| 0 PRs ouvertes | `Aucune PR ouverte.` + terminer |
|
|
299
|
-
| PR en draft | Indiquer dans tableau, skip pour review sauf si sélectionnée explicitement |
|
|
300
|
-
| CI inconnu | Afficher `?` dans colonne CI |
|
|
301
|
-
| Review agent timeout | Afficher erreur partielle, continuer avec les autres |
|
|
302
|
-
| `gh pr diff` vide | Skip cette PR, notifier l'utilisateur |
|
|
303
|
-
| PR très large (>5000 additions) | Avertir : "Review partielle, diff tronqué" |
|
|
304
|
-
| Collaborateurs API 403/404 | Fallback sur auteurs des 10 derniers PRs mergés |
|
|
305
|
-
|
|
306
|
-
---
|
|
307
|
-
|
|
308
|
-
## Notes
|
|
309
|
-
|
|
310
|
-
- Toujours dériver owner/repo via `gh repo view`, jamais hardcoder
|
|
311
|
-
- Utiliser `gh` CLI (pas `curl` GitHub API) sauf pour la liste des collaborateurs
|
|
312
|
-
- `statusCheckRollup` peut être null → traiter comme `?`
|
|
313
|
-
- `mergeable` peut être `MERGEABLE`, `CONFLICTING`, ou `UNKNOWN` → traiter `UNKNOWN` comme `?`
|
|
314
|
-
- Ne jamais poster sans validation explicite de l'utilisateur dans le chat
|
|
315
|
-
- Les commentaires draftés doivent être visibles AVANT tout `gh pr comment`
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Review Comment Template
|
|
2
|
-
|
|
3
|
-
Use this template to generate GitHub PR review comments. Fill in each section based on the code-reviewer agent output. Comments are posted in **English** (international audience).
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Template
|
|
8
|
-
|
|
9
|
-
```markdown
|
|
10
|
-
## Review
|
|
11
|
-
|
|
12
|
-
**Scope**: Security, code quality, performance, test coverage, architecture
|
|
13
|
-
|
|
14
|
-
### Summary
|
|
15
|
-
|
|
16
|
-
{1–2 sentences: overall assessment. Be direct — what's the main takeaway?}
|
|
17
|
-
|
|
18
|
-
### Critical Issues 🔴
|
|
19
|
-
|
|
20
|
-
{List blocking issues that must be fixed before merge. For each:}
|
|
21
|
-
{- `file.rs:42` — Description of the problem. Why it matters. Suggested fix.}
|
|
22
|
-
|
|
23
|
-
{If none: "None found."}
|
|
24
|
-
|
|
25
|
-
### Important Issues 🟡
|
|
26
|
-
|
|
27
|
-
{List significant issues that should be fixed. For each:}
|
|
28
|
-
{- `file.rs:42` — Description. Why it matters. Suggested fix.}
|
|
29
|
-
|
|
30
|
-
{If none: "None found."}
|
|
31
|
-
|
|
32
|
-
### Suggestions 🟢
|
|
33
|
-
|
|
34
|
-
{List nice-to-haves and minor improvements. For each:}
|
|
35
|
-
{- Description. Context. Optional fix.}
|
|
36
|
-
|
|
37
|
-
{If none: omit this section.}
|
|
38
|
-
|
|
39
|
-
### What's Good ✅
|
|
40
|
-
|
|
41
|
-
{Always include at least 1 positive point. Be specific — what works well and why.}
|
|
42
|
-
{- Description of what's done right.}
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
*Automated review via [rtk](https://github.com/rtk-ai/rtk) `/pr-triage`*
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## Formatting Rules
|
|
51
|
-
|
|
52
|
-
**Citation format** : `file.rs:42` or `` `code snippet` `` for inline references
|
|
53
|
-
|
|
54
|
-
**Issue severity** :
|
|
55
|
-
- 🔴 Critical : security vulnerability, data loss risk, broken functionality, test missing for new feature
|
|
56
|
-
- 🟡 Important : error handling gap, performance regression, scope creep, missing token savings assertion
|
|
57
|
-
- 🟢 Suggestion : naming, DRY opportunity, documentation, style
|
|
58
|
-
|
|
59
|
-
**RTK-specific checks to mention if relevant** :
|
|
60
|
-
- `lazy_static!` for regex (not inline `Regex::new()`)
|
|
61
|
-
- `anyhow::Result` + `.context("msg")` (no bare `?`, no `.unwrap()`)
|
|
62
|
-
- Fallback to raw command on filter failure
|
|
63
|
-
- Exit code propagation (`std::process::exit(code)`)
|
|
64
|
-
- Token savings assertion ≥60% in tests
|
|
65
|
-
- Real fixtures (not synthetic test data)
|
|
66
|
-
- No async/tokio dependencies (startup time)
|
|
67
|
-
|
|
68
|
-
**Tone** : Professional, constructive, factual. Challenge the code, not the person.
|
|
69
|
-
No superlatives ("great", "amazing", "perfect"). No filler ("as mentioned", "it's worth noting").
|
|
70
|
-
|
|
71
|
-
**Length** : Aim for 200–400 words. Long enough to be useful, short enough to be read.
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
description: Generate a comprehensive repo recap (PRs, issues, releases) for sharing with team. Pass "en" or "fr" as argument for language (default fr).
|
|
3
|
-
---
|
|
4
|
-
|
|
5
|
-
# Repo Recap
|
|
6
|
-
|
|
7
|
-
Generate a structured recap of the repository state: open PRs, open issues, recent releases, and executive summary. Output is formatted as Markdown with clickable GitHub links, ready to share.
|
|
8
|
-
|
|
9
|
-
## Language
|
|
10
|
-
|
|
11
|
-
- Check the argument passed to this skill
|
|
12
|
-
- If `en` or `english` → produce the recap in English
|
|
13
|
-
- If `fr`, `french`, or no argument → produce the recap in French (default)
|
|
14
|
-
|
|
15
|
-
## Preconditions
|
|
16
|
-
|
|
17
|
-
Before gathering data, verify:
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
# Must be inside a git repo
|
|
21
|
-
git rev-parse --is-inside-work-tree
|
|
22
|
-
|
|
23
|
-
# Must have gh CLI authenticated
|
|
24
|
-
gh auth status
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
If either fails, stop and tell the user what's missing.
|
|
28
|
-
|
|
29
|
-
## Steps
|
|
30
|
-
|
|
31
|
-
### 1. Gather Data
|
|
32
|
-
|
|
33
|
-
Run these commands in parallel via `gh` CLI:
|
|
34
|
-
|
|
35
|
-
```bash
|
|
36
|
-
# Repo identity (for links)
|
|
37
|
-
gh repo view --json nameWithOwner -q .nameWithOwner
|
|
38
|
-
|
|
39
|
-
# Open PRs with metadata
|
|
40
|
-
gh pr list --state open --limit 50 --json number,title,author,createdAt,changedFiles,additions,deletions,reviewDecision,isDraft
|
|
41
|
-
|
|
42
|
-
# Open issues with metadata
|
|
43
|
-
gh issue list --state open --limit 50 --json number,title,author,createdAt,labels,assignees
|
|
44
|
-
|
|
45
|
-
# Recent releases (for version history)
|
|
46
|
-
gh release list --limit 5
|
|
47
|
-
|
|
48
|
-
# Recently merged PRs (for contributor activity)
|
|
49
|
-
gh pr list --state merged --limit 10 --json number,title,author,mergedAt
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
Note: `author` in JSON results is an object `{login: "..."}` — always extract `.author.login` when processing.
|
|
53
|
-
|
|
54
|
-
### 2. Determine Maintainers
|
|
55
|
-
|
|
56
|
-
To distinguish "our PRs" from external contributions:
|
|
57
|
-
|
|
58
|
-
```bash
|
|
59
|
-
gh api repos/{owner}/{repo}/collaborators --jq '.[].login'
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
If this fails (permissions), fallback: authors with write/admin access are those who merged PRs recently. When in doubt, ask the user.
|
|
63
|
-
|
|
64
|
-
### 3. Analyze and Categorize
|
|
65
|
-
|
|
66
|
-
#### PRs — Categorize into 3 groups:
|
|
67
|
-
|
|
68
|
-
**Our PRs** (author is a repo collaborator):
|
|
69
|
-
- List with PR number (linked), title, size (+additions, files count), status
|
|
70
|
-
|
|
71
|
-
**External — Reviewable** (manageable size, no major blockers):
|
|
72
|
-
- Additions ≤ 1000 AND files ≤ 10
|
|
73
|
-
- No merge conflicts, CI not failing
|
|
74
|
-
- Include: PR link, author, title, size, review status, recommended action
|
|
75
|
-
|
|
76
|
-
**External — Problematic** (any of: too large, CI failing, overlapping, merge conflict):
|
|
77
|
-
- Additions > 1000 OR files > 10
|
|
78
|
-
- OR CI failing (reviewDecision = "CHANGES_REQUESTED" or checks failing)
|
|
79
|
-
- OR touches same files as another open PR (= overlap)
|
|
80
|
-
- Include: PR link, author, title, size, specific problem, action taken/needed
|
|
81
|
-
|
|
82
|
-
**Size labels** (use in "Taille" column for quick visual triage):
|
|
83
|
-
|
|
84
|
-
| Label | Additions |
|
|
85
|
-
| ----- | --------- |
|
|
86
|
-
| XS | < 50 |
|
|
87
|
-
| S | 50-200 |
|
|
88
|
-
| M | 200-500 |
|
|
89
|
-
| L | 500-1000 |
|
|
90
|
-
| XL | > 1000 |
|
|
91
|
-
|
|
92
|
-
Format: `+{additions}, {files} files ({label})` — e.g., `+245, 2 files (S)`
|
|
93
|
-
|
|
94
|
-
#### Detect overlaps:
|
|
95
|
-
Two PRs overlap if they modify the same files. Use `changedFiles` from the JSON data. If >50% file overlap between 2 PRs, flag both as overlapping and cross-reference them.
|
|
96
|
-
|
|
97
|
-
#### Flag clusters:
|
|
98
|
-
If one author has 3+ open PRs, note it as a "cluster" with suggested review order (smallest first, or by dependency chain).
|
|
99
|
-
|
|
100
|
-
#### Issues — Categorize by status:
|
|
101
|
-
- **In progress**: has an associated open PR (match by PR body containing `fixes #N`, `closes #N`, or same topic)
|
|
102
|
-
- **Quick fix**: small scope, actionable (bug reports, small enhancements)
|
|
103
|
-
- **Feature request**: larger scope, needs design discussion
|
|
104
|
-
- **Covered by PR**: an existing PR addresses this issue (link it)
|
|
105
|
-
|
|
106
|
-
### 4. Derive Recent Releases
|
|
107
|
-
|
|
108
|
-
From `gh release list` output, extract version, date, and name. List the 5 most recent.
|
|
109
|
-
|
|
110
|
-
If no releases found, check merged PRs for release-please pattern (title matching `chore(*): release *`) as fallback.
|
|
111
|
-
|
|
112
|
-
### 5. Executive Summary
|
|
113
|
-
|
|
114
|
-
Produce 5-6 bullet points:
|
|
115
|
-
- Total open PRs and issues count
|
|
116
|
-
- Active contributors (who has the most PRs/issues)
|
|
117
|
-
- Main risks (oversized PRs, CI failures, merge conflicts)
|
|
118
|
-
- Quick wins (small PRs ready to merge — XS/S size, no blockers)
|
|
119
|
-
- Bug fixes needed (hook bugs, regressions)
|
|
120
|
-
- Our own PRs status
|
|
121
|
-
|
|
122
|
-
### 6. Format Output
|
|
123
|
-
|
|
124
|
-
Structure the full recap as Markdown with:
|
|
125
|
-
- `# {Repo Name} — Récap au {date}` as title (FR) or `# {Repo Name} — Recap {date}` (EN)
|
|
126
|
-
- Sections separated by `---`
|
|
127
|
-
- All PR/issue numbers as clickable links: `[#123](https://github.com/{owner}/{repo}/pull/123)` for PRs, `.../issues/123` for issues
|
|
128
|
-
- Tables with Markdown pipe syntax for all listings
|
|
129
|
-
- Bold for emphasis on actions and risks
|
|
130
|
-
- Cross-references between related PRs and issues (e.g., "Covered by [#131](link)")
|
|
131
|
-
|
|
132
|
-
**Empty data handling**:
|
|
133
|
-
- 0 open PRs → display "Aucune PR ouverte." (FR) or "No open PRs." (EN) instead of empty table
|
|
134
|
-
- 0 open issues → display "Aucune issue ouverte." (FR) or "No open issues." (EN)
|
|
135
|
-
- 0 releases → display "Aucune release récente." (FR) or "No recent releases." (EN)
|
|
136
|
-
|
|
137
|
-
### 7. Copy to Clipboard
|
|
138
|
-
|
|
139
|
-
After displaying the recap, automatically copy it to clipboard:
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
cat << 'EOF' | pbcopy
|
|
143
|
-
{formatted recap content}
|
|
144
|
-
EOF
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
Confirm with: "Copié dans le presse-papier." (FR) or "Copied to clipboard." (EN)
|
|
148
|
-
|
|
149
|
-
## Output Template (FR)
|
|
150
|
-
|
|
151
|
-
```markdown
|
|
152
|
-
# {Repo Name} — Récap au {date}
|
|
153
|
-
|
|
154
|
-
## Releases récentes
|
|
155
|
-
|
|
156
|
-
| Version | Date | Highlights |
|
|
157
|
-
| ------- | ---- | ---------- |
|
|
158
|
-
| ... | ... | ... |
|
|
159
|
-
|
|
160
|
-
---
|
|
161
|
-
|
|
162
|
-
## PRs ouvertes ({count} total)
|
|
163
|
-
|
|
164
|
-
### Nos PRs
|
|
165
|
-
|
|
166
|
-
| PR | Titre | Taille | Status |
|
|
167
|
-
| -- | ----- | ------ | ------ |
|
|
168
|
-
|
|
169
|
-
### Contributeurs externes — Reviewables
|
|
170
|
-
|
|
171
|
-
| PR | Auteur | Titre | Taille | Status | Action |
|
|
172
|
-
| -- | ------ | ----- | ------ | ------ | ------ |
|
|
173
|
-
|
|
174
|
-
### Contributeurs externes — Problématiques
|
|
175
|
-
|
|
176
|
-
| PR | Auteur | Titre | Taille | Problème | Action |
|
|
177
|
-
| -- | ------ | ----- | ------ | -------- | ------ |
|
|
178
|
-
|
|
179
|
-
---
|
|
180
|
-
|
|
181
|
-
## Issues ouvertes ({count} total)
|
|
182
|
-
|
|
183
|
-
| # | Auteur | Sujet | Priorité |
|
|
184
|
-
| - | ------ | ----- | -------- |
|
|
185
|
-
|
|
186
|
-
---
|
|
187
|
-
|
|
188
|
-
## Résumé exécutif
|
|
189
|
-
|
|
190
|
-
- **Point 1**: ...
|
|
191
|
-
- **Point 2**: ...
|
|
192
|
-
```
|
|
193
|
-
|
|
194
|
-
## Output Template (EN)
|
|
195
|
-
|
|
196
|
-
Same structure but with English headers:
|
|
197
|
-
- "Recent Releases", "Open PRs", "Our PRs", "External — Reviewable", "External — Problematic", "Open Issues", "Executive Summary"
|
|
198
|
-
- Action labels: "To review", "Rebase requested", "Split requested", "Trim requested", "CI broken", "Waiting on author", "Feature request", "Quick fix", "Covered by PR"
|
|
199
|
-
|
|
200
|
-
## Notes
|
|
201
|
-
|
|
202
|
-
- Always use `gh` CLI (not GitHub API directly, except for collaborators list)
|
|
203
|
-
- Derive repo owner/name from `gh repo view`, don't hardcode
|
|
204
|
-
- Keep tables compact — truncate long titles if needed (max ~60 chars)
|
|
205
|
-
- Cross-reference overlapping PRs/issues whenever possible
|
|
206
|
-
- `author` in gh JSON is an object — always use `.author.login`
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: rtk-tdd
|
|
3
|
-
description: >
|
|
4
|
-
Enforces TDD (Red-Green-Refactor) for Rust development. Auto-triggers on
|
|
5
|
-
implementation, testing, refactoring, and bug fixing tasks. Provides
|
|
6
|
-
Rust-idiomatic testing patterns with anyhow/thiserror, cfg(test), and
|
|
7
|
-
Arrange-Act-Assert workflow.
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Rust TDD Workflow
|
|
11
|
-
|
|
12
|
-
## Three Laws of TDD
|
|
13
|
-
|
|
14
|
-
1. Do NOT write production code without a failing test
|
|
15
|
-
2. Write only enough test to fail (including compilation failure)
|
|
16
|
-
3. Write only enough production code to pass the failing test
|
|
17
|
-
|
|
18
|
-
Cycle: **RED** (test fails) -> **GREEN** (minimum to pass) -> **REFACTOR** (cleanup, cargo test)
|
|
19
|
-
|
|
20
|
-
## Red-Green-Refactor Steps
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
1. Write test in #[cfg(test)] mod tests of the SAME file
|
|
24
|
-
2. cargo test MODULE::tests::test_name -- must FAIL (red)
|
|
25
|
-
3. Implement the minimum in the function
|
|
26
|
-
4. cargo test MODULE::tests::test_name -- must PASS (green)
|
|
27
|
-
5. Refactor if needed, re-run cargo test (still green)
|
|
28
|
-
6. cargo fmt && cargo clippy --all-targets && cargo test (final gate)
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Never skip step 2. If the test passes immediately, it tests nothing.
|
|
32
|
-
|
|
33
|
-
## Idiomatic Rust Test Patterns
|
|
34
|
-
|
|
35
|
-
| Pattern | Usage | When |
|
|
36
|
-
|---------|-------|------|
|
|
37
|
-
| Arrange-Act-Assert | Base structure for every test | Always |
|
|
38
|
-
| `assert_eq!` / `assert!` | Direct comparison / booleans | Deterministic values |
|
|
39
|
-
| `assert!(result.is_err())` | Error path testing | Invalid inputs |
|
|
40
|
-
| `Result<()>` return type | Tests with `?` operator | Fallible functions |
|
|
41
|
-
| `#[should_panic]` | Expected panic | Invariants, preconditions |
|
|
42
|
-
| `tempfile::NamedTempFile` | File/I/O tests | Filesystem-dependent code |
|
|
43
|
-
|
|
44
|
-
## Patterns by Code Type
|
|
45
|
-
|
|
46
|
-
| Code Type | Test Pattern | Example |
|
|
47
|
-
|-----------|-------------|---------|
|
|
48
|
-
| Pure function (str -> str) | Input literal -> assert output | `assert_eq!(truncate("hello", 3), "...")` |
|
|
49
|
-
| Parsing/filtering | Raw string -> filter -> contains/not-contains | `assert!(filter(raw).contains("expected"))` |
|
|
50
|
-
| Validation/security | Boundary inputs -> assert bool | `assert!(!is_valid("../etc/passwd"))` |
|
|
51
|
-
| Error handling | Bad input -> `is_err()` | `assert!(parse("garbage").is_err())` |
|
|
52
|
-
| Struct/enum roundtrip | Construct -> serialize -> deserialize -> eq | `assert_eq!(from_str(to_str(x)), x)` |
|
|
53
|
-
|
|
54
|
-
## Naming Convention
|
|
55
|
-
|
|
56
|
-
```
|
|
57
|
-
test_{function}_{scenario}
|
|
58
|
-
test_{function}_{input_type}
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
Examples: `test_truncate_edge_case`, `test_parse_invalid_input`, `test_filter_empty_string`
|
|
62
|
-
|
|
63
|
-
## When NOT to Use Pure TDD
|
|
64
|
-
|
|
65
|
-
- Functions calling `Command::new()` -> test the parser, not the execution
|
|
66
|
-
- `std::process::exit()` -> refactor to `Result` first, then test the Result
|
|
67
|
-
- Direct I/O (SQLite, network) -> use tempfile/mock or test the pure logic separately
|
|
68
|
-
- Main/CLI wiring -> covered by integration/smoke tests
|
|
69
|
-
|
|
70
|
-
## Pre-Commit Gate
|
|
71
|
-
|
|
72
|
-
```bash
|
|
73
|
-
cargo fmt --all --check
|
|
74
|
-
cargo clippy --all-targets
|
|
75
|
-
cargo test
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
All 3 must pass. No exceptions. No `#[allow(...)]` without documented justification.
|