@k2works/claude-code-booster 0.8.0 → 0.9.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/lib/assets/.claude/README.md +54 -136
- package/lib/assets/.claude/assets/.gitkeep +0 -0
- package/lib/assets/.claude/commands/git-commit.md +47 -0
- package/lib/assets/.claude/commands/ops.md +16 -16
- package/lib/assets/.claude/scripts/.gitkeep +0 -0
- package/lib/assets/README.md +77 -3
- package/lib/assets/apps/.gitkeep +0 -0
- package/package.json +1 -1
- package/lib/assets/.claude/agents/roles/analyzer.md +0 -267
- package/lib/assets/.claude/agents/roles/architect.md +0 -233
- package/lib/assets/.claude/agents/roles/backend.md +0 -303
- package/lib/assets/.claude/agents/roles/frontend.md +0 -294
- package/lib/assets/.claude/agents/roles/mobile.md +0 -309
- package/lib/assets/.claude/agents/roles/performance.md +0 -254
- package/lib/assets/.claude/agents/roles/qa.md +0 -266
- package/lib/assets/.claude/agents/roles/reviewer.md +0 -252
- package/lib/assets/.claude/agents/roles/security.md +0 -392
- package/lib/assets/.claude/assets/confirm.mp3 +0 -0
- package/lib/assets/.claude/assets/perfect.mp3 +0 -0
- package/lib/assets/.claude/assets/silent.wav +0 -0
- package/lib/assets/.claude/commands/analyze-dependencies.md +0 -158
- package/lib/assets/.claude/commands/analyze-performance.md +0 -116
- package/lib/assets/.claude/commands/check-fact.md +0 -104
- package/lib/assets/.claude/commands/check-github-ci.md +0 -53
- package/lib/assets/.claude/commands/check-prompt.md +0 -461
- package/lib/assets/.claude/commands/commit-message.md +0 -348
- package/lib/assets/.claude/commands/context7.md +0 -50
- package/lib/assets/.claude/commands/design-patterns.md +0 -186
- package/lib/assets/.claude/commands/explain-code.md +0 -75
- package/lib/assets/.claude/commands/fix-error.md +0 -258
- package/lib/assets/.claude/commands/multi-role.md +0 -291
- package/lib/assets/.claude/commands/next.md +0 -136
- package/lib/assets/.claude/commands/pr-auto-update.md +0 -460
- package/lib/assets/.claude/commands/pr-create.md +0 -249
- package/lib/assets/.claude/commands/pr-feedback.md +0 -143
- package/lib/assets/.claude/commands/pr-issue.md +0 -78
- package/lib/assets/.claude/commands/pr-list.md +0 -66
- package/lib/assets/.claude/commands/pr-review.md +0 -142
- package/lib/assets/.claude/commands/refactor.md +0 -147
- package/lib/assets/.claude/commands/role-debate.md +0 -571
- package/lib/assets/.claude/commands/role-help.md +0 -276
- package/lib/assets/.claude/commands/role.md +0 -360
- package/lib/assets/.claude/commands/screenshot.md +0 -103
- package/lib/assets/.claude/commands/search-gemini.md +0 -66
- package/lib/assets/.claude/commands/semantic-commit.md +0 -1129
- package/lib/assets/.claude/commands/sequential-thinking.md +0 -90
- package/lib/assets/.claude/commands/show-plan.md +0 -59
- package/lib/assets/.claude/commands/smart-review.md +0 -174
- package/lib/assets/.claude/commands/spec.md +0 -559
- package/lib/assets/.claude/commands/style-ai-writing.md +0 -186
- package/lib/assets/.claude/commands/task.md +0 -223
- package/lib/assets/.claude/commands/tech-debt.md +0 -87
- package/lib/assets/.claude/commands/ultrathink.md +0 -65
- package/lib/assets/.claude/commands/update-dart-doc.md +0 -202
- package/lib/assets/.claude/commands/update-doc-string.md +0 -306
- package/lib/assets/.claude/commands/update-flutter-deps.md +0 -105
- package/lib/assets/.claude/commands/update-node-deps.md +0 -105
- package/lib/assets/.claude/commands/update-rust-deps.md +0 -107
- package/lib/assets/.claude/scripts/auto-comment.sh +0 -16
- package/lib/assets/.claude/scripts/check-ai-commit.sh +0 -20
- package/lib/assets/.claude/scripts/check-continue.sh +0 -97
- package/lib/assets/.claude/scripts/check-locales.sh +0 -1080
- package/lib/assets/.claude/scripts/check-project-plan.sh +0 -25
- package/lib/assets/.claude/scripts/debug-hook.sh +0 -7
- package/lib/assets/.claude/scripts/deny-check.sh +0 -69
- package/lib/assets/.claude/scripts/install.sh +0 -174
- package/lib/assets/.claude/scripts/ja-space-exclusions.json +0 -18
- package/lib/assets/.claude/scripts/ja-space-format.sh +0 -45
- package/lib/assets/.claude/scripts/preserve-file-permissions.sh +0 -83
- package/lib/assets/.claude/scripts/statusline.sh +0 -153
- /package/lib/assets/{app → .claude/agents/roles}/.gitkeep +0 -0
|
@@ -1,1080 +0,0 @@
|
|
|
1
|
-
#!/bin/bash
|
|
2
|
-
|
|
3
|
-
# Validate language versions for completeness and consistency
|
|
4
|
-
# Ensures each locale has all required files and structure
|
|
5
|
-
# Adapted for locales/ directory structure
|
|
6
|
-
|
|
7
|
-
set -e
|
|
8
|
-
|
|
9
|
-
# Colors for output
|
|
10
|
-
RED='\033[0;31m'
|
|
11
|
-
GREEN='\033[0;32m'
|
|
12
|
-
YELLOW='\033[1;33m'
|
|
13
|
-
BLUE='\033[0;34m'
|
|
14
|
-
NC='\033[0m'
|
|
15
|
-
|
|
16
|
-
# Project paths
|
|
17
|
-
PROJECT_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
18
|
-
LOCALES_DIR="$PROJECT_ROOT/locales"
|
|
19
|
-
COMMANDS_DIR="$PROJECT_ROOT/commands"
|
|
20
|
-
AGENTS_DIR="$PROJECT_ROOT/agents"
|
|
21
|
-
|
|
22
|
-
# Required directories for each locale
|
|
23
|
-
REQUIRED_DIRS=("commands" "agents/roles")
|
|
24
|
-
|
|
25
|
-
# Counters
|
|
26
|
-
TOTAL_CHECKS=0
|
|
27
|
-
PASSED_CHECKS=0
|
|
28
|
-
FAILED_CHECKS=0
|
|
29
|
-
WARNINGS=0
|
|
30
|
-
|
|
31
|
-
print_info() {
|
|
32
|
-
echo -e "${BLUE}[INFO]${NC} $1"
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
print_success() {
|
|
36
|
-
echo -e "${GREEN}[✓]${NC} $1"
|
|
37
|
-
PASSED_CHECKS=$((PASSED_CHECKS + 1))
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
print_warning() {
|
|
41
|
-
echo -e "${YELLOW}[⚠]${NC} $1"
|
|
42
|
-
WARNINGS=$((WARNINGS + 1))
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
print_error() {
|
|
46
|
-
echo -e "${RED}[✗]${NC} $1"
|
|
47
|
-
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
# Function to check directory structure
|
|
51
|
-
check_structure() {
|
|
52
|
-
local locale="$1"
|
|
53
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
54
|
-
|
|
55
|
-
print_info "Checking directory structure for $locale..."
|
|
56
|
-
|
|
57
|
-
for dir in "${REQUIRED_DIRS[@]}"; do
|
|
58
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
59
|
-
if [[ -d "$locale_dir/$dir" ]]; then
|
|
60
|
-
print_success "$dir exists"
|
|
61
|
-
else
|
|
62
|
-
print_error "$dir is missing"
|
|
63
|
-
fi
|
|
64
|
-
done
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
# Function to count files in directories
|
|
68
|
-
count_files() {
|
|
69
|
-
local locale="$1"
|
|
70
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
71
|
-
|
|
72
|
-
print_info "File counts for $locale:"
|
|
73
|
-
|
|
74
|
-
# Count command files
|
|
75
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
76
|
-
local cmd_count
|
|
77
|
-
cmd_count=$(find "$locale_dir/commands" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
78
|
-
echo " Commands: $cmd_count files"
|
|
79
|
-
fi
|
|
80
|
-
|
|
81
|
-
# Count role files
|
|
82
|
-
if [[ -d "$locale_dir/agents/roles" ]]; then
|
|
83
|
-
local role_count
|
|
84
|
-
role_count=$(find "$locale_dir/agents/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
85
|
-
echo " Roles: $role_count files"
|
|
86
|
-
fi
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
# Function to check for language-specific content
|
|
90
|
-
check_language_content() {
|
|
91
|
-
local locale="$1"
|
|
92
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
93
|
-
|
|
94
|
-
print_info "Checking language content for $locale..."
|
|
95
|
-
|
|
96
|
-
# Define expected language patterns
|
|
97
|
-
case "$locale" in
|
|
98
|
-
zh)
|
|
99
|
-
# Check for Chinese content and no Japanese
|
|
100
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
101
|
-
local contaminated_files=()
|
|
102
|
-
# Check for Japanese (hiragana, katakana)
|
|
103
|
-
while IFS= read -r file; do
|
|
104
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
105
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
106
|
-
|
|
107
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
108
|
-
while IFS= read -r file; do
|
|
109
|
-
# Skip if already detected
|
|
110
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
111
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
112
|
-
fi
|
|
113
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
114
|
-
|
|
115
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
116
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
117
|
-
print_success "No Japanese contamination found in Chinese files"
|
|
118
|
-
else
|
|
119
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} Chinese files:"
|
|
120
|
-
for file in "${contaminated_files[@]}"; do
|
|
121
|
-
echo " ⚠️ $file"
|
|
122
|
-
done
|
|
123
|
-
WARNINGS=$((WARNINGS + 1))
|
|
124
|
-
fi
|
|
125
|
-
|
|
126
|
-
# Also check for Chinese content
|
|
127
|
-
local zh_files
|
|
128
|
-
zh_files=$(grep -c '[一-龯]' "$locale_dir/commands"/*.md 2>/dev/null | grep -cv ':0' || echo "0")
|
|
129
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
130
|
-
if [[ $zh_files -gt 0 ]]; then
|
|
131
|
-
print_success "Found Chinese content in $zh_files command files"
|
|
132
|
-
else
|
|
133
|
-
print_warning "No Chinese content found in commands"
|
|
134
|
-
fi
|
|
135
|
-
fi
|
|
136
|
-
;;
|
|
137
|
-
en)
|
|
138
|
-
# Check for English content and no Japanese
|
|
139
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
140
|
-
local contaminated_files=()
|
|
141
|
-
# Check for Japanese (hiragana, katakana, kanji frequently used in Japanese)
|
|
142
|
-
while IFS= read -r file; do
|
|
143
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
144
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
145
|
-
|
|
146
|
-
# Also check for common Japanese kanji patterns
|
|
147
|
-
while IFS= read -r file; do
|
|
148
|
-
# Skip if already detected
|
|
149
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
150
|
-
contaminated_files+=("$(basename "$file"): Japanese kanji")
|
|
151
|
-
fi
|
|
152
|
-
done < <(grep -lE '調査|実装|機能|開発|修正|追加|削除|更新|確認|設定' "$locale_dir"/**/*.md 2>/dev/null)
|
|
153
|
-
|
|
154
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
155
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
156
|
-
print_success "No Japanese contamination found in English files"
|
|
157
|
-
else
|
|
158
|
-
print_warning "Found language contamination in ${#contaminated_files[@]} English files:"
|
|
159
|
-
for file in "${contaminated_files[@]}"; do
|
|
160
|
-
echo " ⚠️ $file"
|
|
161
|
-
done
|
|
162
|
-
WARNINGS=$((WARNINGS + 1))
|
|
163
|
-
fi
|
|
164
|
-
fi
|
|
165
|
-
;;
|
|
166
|
-
es)
|
|
167
|
-
# Check for Spanish content and no Japanese
|
|
168
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
169
|
-
local contaminated_files=()
|
|
170
|
-
# Check for Japanese (hiragana, katakana)
|
|
171
|
-
while IFS= read -r file; do
|
|
172
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
173
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
174
|
-
|
|
175
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
176
|
-
while IFS= read -r file; do
|
|
177
|
-
# Skip if already detected
|
|
178
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
179
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
180
|
-
fi
|
|
181
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
182
|
-
|
|
183
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
184
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
185
|
-
print_success "No Japanese contamination found in Spanish files"
|
|
186
|
-
else
|
|
187
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} Spanish files:"
|
|
188
|
-
for file in "${contaminated_files[@]}"; do
|
|
189
|
-
echo " ⚠️ $file"
|
|
190
|
-
done
|
|
191
|
-
WARNINGS=$((WARNINGS + 1))
|
|
192
|
-
fi
|
|
193
|
-
fi
|
|
194
|
-
;;
|
|
195
|
-
ko)
|
|
196
|
-
# Check for Korean content and no Japanese
|
|
197
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
198
|
-
local contaminated_files=()
|
|
199
|
-
# Check for Japanese (hiragana, katakana)
|
|
200
|
-
while IFS= read -r file; do
|
|
201
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
202
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
203
|
-
|
|
204
|
-
# Check for common Japanese kanji patterns (different from Korean hanja usage)
|
|
205
|
-
while IFS= read -r file; do
|
|
206
|
-
# Skip if already detected
|
|
207
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
208
|
-
contaminated_files+=("$(basename "$file"): Japanese kanji")
|
|
209
|
-
fi
|
|
210
|
-
done < <(grep -lE '調査|実装|機能|開発|修正|追加|削除|更新|確認|設定' "$locale_dir"/**/*.md 2>/dev/null)
|
|
211
|
-
|
|
212
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
213
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
214
|
-
print_success "No Japanese contamination found in Korean files"
|
|
215
|
-
else
|
|
216
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} Korean files:"
|
|
217
|
-
for file in "${contaminated_files[@]}"; do
|
|
218
|
-
echo " ⚠️ $file"
|
|
219
|
-
done
|
|
220
|
-
WARNINGS=$((WARNINGS + 1))
|
|
221
|
-
fi
|
|
222
|
-
fi
|
|
223
|
-
;;
|
|
224
|
-
pt)
|
|
225
|
-
# Check for Portuguese content and no Japanese
|
|
226
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
227
|
-
local contaminated_files=()
|
|
228
|
-
# Check for Japanese (hiragana, katakana)
|
|
229
|
-
while IFS= read -r file; do
|
|
230
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
231
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
232
|
-
|
|
233
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
234
|
-
while IFS= read -r file; do
|
|
235
|
-
# Skip if already detected
|
|
236
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
237
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
238
|
-
fi
|
|
239
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
240
|
-
|
|
241
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
242
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
243
|
-
print_success "No Japanese contamination found in Portuguese files"
|
|
244
|
-
else
|
|
245
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} Portuguese files:"
|
|
246
|
-
for file in "${contaminated_files[@]}"; do
|
|
247
|
-
echo " ⚠️ $file"
|
|
248
|
-
done
|
|
249
|
-
WARNINGS=$((WARNINGS + 1))
|
|
250
|
-
fi
|
|
251
|
-
fi
|
|
252
|
-
;;
|
|
253
|
-
fr)
|
|
254
|
-
# Check for French content and no Japanese
|
|
255
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
256
|
-
local contaminated_files=()
|
|
257
|
-
# Check for Japanese (hiragana, katakana)
|
|
258
|
-
while IFS= read -r file; do
|
|
259
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
260
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
261
|
-
|
|
262
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
263
|
-
while IFS= read -r file; do
|
|
264
|
-
# Skip if already detected
|
|
265
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
266
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
267
|
-
fi
|
|
268
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
269
|
-
|
|
270
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
271
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
272
|
-
print_success "No Japanese contamination found in fr files"
|
|
273
|
-
else
|
|
274
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} French files:"
|
|
275
|
-
for file in "${contaminated_files[@]}"; do
|
|
276
|
-
echo " ⚠️ $file"
|
|
277
|
-
done
|
|
278
|
-
WARNINGS=$((WARNINGS + 1))
|
|
279
|
-
fi
|
|
280
|
-
fi
|
|
281
|
-
;;
|
|
282
|
-
zh-cn)
|
|
283
|
-
# Check for Simplified Chinese and no Japanese/Traditional Chinese
|
|
284
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
285
|
-
local contaminated_files=()
|
|
286
|
-
# Check for Japanese-specific characters (hiragana, katakana)
|
|
287
|
-
while IFS= read -r file; do
|
|
288
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
289
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
290
|
-
|
|
291
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
292
|
-
while IFS= read -r file; do
|
|
293
|
-
# Skip if already detected
|
|
294
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
295
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
296
|
-
fi
|
|
297
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
298
|
-
|
|
299
|
-
# Check for Traditional Chinese specific characters (avoiding false positives)
|
|
300
|
-
# Note: 繁 is excluded as it appears in valid simplified words like 频繁
|
|
301
|
-
while IFS= read -r file; do
|
|
302
|
-
# Skip if already detected
|
|
303
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
304
|
-
contaminated_files+=("$(basename "$file"): Traditional Chinese")
|
|
305
|
-
fi
|
|
306
|
-
done < <(grep -lE '體|憂|鬱|臺|灣|關係|發現|實現|專|業|檔|產|學|雜|難|應|轉|變' "$locale_dir"/**/*.md 2>/dev/null)
|
|
307
|
-
|
|
308
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
309
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
310
|
-
print_success "No foreign language contamination found in Simplified Chinese files"
|
|
311
|
-
else
|
|
312
|
-
print_warning "Found language contamination in ${#contaminated_files[@]} Simplified Chinese files:"
|
|
313
|
-
for file in "${contaminated_files[@]}"; do
|
|
314
|
-
echo " ⚠️ $file"
|
|
315
|
-
done
|
|
316
|
-
WARNINGS=$((WARNINGS + 1))
|
|
317
|
-
fi
|
|
318
|
-
fi
|
|
319
|
-
;;
|
|
320
|
-
zh-tw)
|
|
321
|
-
# Check for Traditional Chinese and no Japanese/Simplified Chinese
|
|
322
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
323
|
-
local contaminated_files=()
|
|
324
|
-
# Check for Japanese-specific characters (hiragana, katakana)
|
|
325
|
-
while IFS= read -r file; do
|
|
326
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
327
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
328
|
-
|
|
329
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
330
|
-
while IFS= read -r file; do
|
|
331
|
-
# Skip if already detected
|
|
332
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
333
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
334
|
-
fi
|
|
335
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
336
|
-
|
|
337
|
-
# Check for Simplified Chinese specific characters (avoiding false positives)
|
|
338
|
-
while IFS= read -r file; do
|
|
339
|
-
# Skip if already detected
|
|
340
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
341
|
-
contaminated_files+=("$(basename "$file"): Simplified Chinese")
|
|
342
|
-
fi
|
|
343
|
-
done < <(grep -lE '简体|发现|实现|关系|忧郁|台湾|专业|档案|产品|学习|杂志|应用|转换|变化' "$locale_dir"/**/*.md 2>/dev/null)
|
|
344
|
-
|
|
345
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
346
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
347
|
-
print_success "No foreign language contamination found in Traditional Chinese files"
|
|
348
|
-
else
|
|
349
|
-
print_warning "Found language contamination in ${#contaminated_files[@]} Traditional Chinese files:"
|
|
350
|
-
for file in "${contaminated_files[@]}"; do
|
|
351
|
-
echo " ⚠️ $file"
|
|
352
|
-
done
|
|
353
|
-
WARNINGS=$((WARNINGS + 1))
|
|
354
|
-
fi
|
|
355
|
-
fi
|
|
356
|
-
;;
|
|
357
|
-
*)
|
|
358
|
-
# Default: Check for Japanese contamination in all other locales
|
|
359
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
360
|
-
local contaminated_files=()
|
|
361
|
-
# Check for Japanese (hiragana, katakana)
|
|
362
|
-
while IFS= read -r file; do
|
|
363
|
-
contaminated_files+=("$(basename "$file"): Japanese")
|
|
364
|
-
done < <(grep -l '[ぁ-んァ-ヶー]' "$locale_dir"/**/*.md 2>/dev/null)
|
|
365
|
-
|
|
366
|
-
# Check for Japanese sentence patterns (more reliable than individual kanji)
|
|
367
|
-
while IFS= read -r file; do
|
|
368
|
-
# Skip if already detected
|
|
369
|
-
if ! echo "${contaminated_files[@]}" | grep -q "$(basename "$file")"; then
|
|
370
|
-
contaminated_files+=("$(basename "$file"): Japanese patterns")
|
|
371
|
-
fi
|
|
372
|
-
done < <(grep -lE 'です|ます|である|により|において|について|に関して' "$locale_dir"/**/*.md 2>/dev/null)
|
|
373
|
-
|
|
374
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
375
|
-
if [[ ${#contaminated_files[@]} -eq 0 ]]; then
|
|
376
|
-
print_success "No Japanese contamination found in $locale files"
|
|
377
|
-
else
|
|
378
|
-
print_warning "Found Japanese contamination in ${#contaminated_files[@]} $locale files:"
|
|
379
|
-
for file in "${contaminated_files[@]}"; do
|
|
380
|
-
echo " ⚠️ $file"
|
|
381
|
-
done
|
|
382
|
-
WARNINGS=$((WARNINGS + 1))
|
|
383
|
-
fi
|
|
384
|
-
fi
|
|
385
|
-
;;
|
|
386
|
-
esac
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
# Function to check language codes in specific command files
|
|
390
|
-
check_language_codes() {
|
|
391
|
-
local locale="$1"
|
|
392
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
393
|
-
|
|
394
|
-
print_info "Checking language codes in command files for $locale..."
|
|
395
|
-
|
|
396
|
-
# Files that should have language-specific --lang options
|
|
397
|
-
local target_files=("semantic-commit.md" "commit-message.md" "pr-auto-update.md" "update-doc-string.md")
|
|
398
|
-
local issues_found=0
|
|
399
|
-
|
|
400
|
-
# Define expected language codes for each locale
|
|
401
|
-
local expected_lang=""
|
|
402
|
-
local allow_ja_in_option=false
|
|
403
|
-
case "$locale" in
|
|
404
|
-
ja)
|
|
405
|
-
expected_lang="ja"
|
|
406
|
-
allow_ja_in_option=true
|
|
407
|
-
;;
|
|
408
|
-
en)
|
|
409
|
-
expected_lang="en"
|
|
410
|
-
# English version should only support English
|
|
411
|
-
;;
|
|
412
|
-
es) expected_lang="es" ;;
|
|
413
|
-
fr) expected_lang="fr" ;;
|
|
414
|
-
ko) expected_lang="ko" ;;
|
|
415
|
-
pt) expected_lang="pt" ;;
|
|
416
|
-
zh-cn) expected_lang="zh-cn" ;;
|
|
417
|
-
zh-tw) expected_lang="zh-tw" ;;
|
|
418
|
-
*) expected_lang="$locale" ;;
|
|
419
|
-
esac
|
|
420
|
-
|
|
421
|
-
for file in "${target_files[@]}"; do
|
|
422
|
-
local file_path="$locale_dir/commands/$file"
|
|
423
|
-
if [[ -f "$file_path" ]]; then
|
|
424
|
-
# Check for incorrect language codes
|
|
425
|
-
if [[ "$locale" == "en" ]]; then
|
|
426
|
-
# English version should only have 'en', not 'ja' or other languages
|
|
427
|
-
if grep -qE "\-\-lang.*[\((].*[,,]" "$file_path" 2>/dev/null; then
|
|
428
|
-
print_error "$file contains multiple language options in English version (should be 'en' only)"
|
|
429
|
-
issues_found=$((issues_found + 1))
|
|
430
|
-
fi
|
|
431
|
-
if grep -qE "\-\-lang.*[\((].*ja[,\))]" "$file_path" 2>/dev/null; then
|
|
432
|
-
print_error "$file contains Japanese language code 'ja' in English version"
|
|
433
|
-
issues_found=$((issues_found + 1))
|
|
434
|
-
fi
|
|
435
|
-
elif [[ "$locale" != "ja" ]]; then
|
|
436
|
-
# Non-Japanese, non-English locales should not have 'ja'
|
|
437
|
-
if grep -qE "\-\-lang.*[\((].*ja[,\))]" "$file_path" 2>/dev/null; then
|
|
438
|
-
print_error "$file contains Japanese language code 'ja' instead of '$expected_lang'"
|
|
439
|
-
issues_found=$((issues_found + 1))
|
|
440
|
-
fi
|
|
441
|
-
|
|
442
|
-
# Check for JSON examples with "language": "ja"
|
|
443
|
-
if grep -qE '"language":\s*"ja"' "$file_path" 2>/dev/null; then
|
|
444
|
-
print_error "$file contains JSON with Japanese language code in 'language' field"
|
|
445
|
-
issues_found=$((issues_found + 1))
|
|
446
|
-
fi
|
|
447
|
-
|
|
448
|
-
# Check if the file contains the correct language code
|
|
449
|
-
# Look for patterns like (en, pt) or <en|pt> or (en, zh-cn)(full-width parentheses)
|
|
450
|
-
if ! grep -qE "(\-\-lang.*[\((].*$expected_lang[,\))]|\-\-lang.*<.*\|?$expected_lang>)" "$file_path" 2>/dev/null; then
|
|
451
|
-
print_warning "$file may be missing the correct language code '$expected_lang'"
|
|
452
|
-
WARNINGS=$((WARNINGS + 1))
|
|
453
|
-
fi
|
|
454
|
-
|
|
455
|
-
# Special check for update-doc-string.md - DOC_LANGUAGE variable
|
|
456
|
-
if [[ "$file" == "update-doc-string.md" ]]; then
|
|
457
|
-
if grep -qE 'DOC_LANGUAGE="ja"' "$file_path" 2>/dev/null; then
|
|
458
|
-
print_error "$file contains DOC_LANGUAGE=\"ja\" instead of \"$expected_lang\""
|
|
459
|
-
issues_found=$((issues_found + 1))
|
|
460
|
-
fi
|
|
461
|
-
fi
|
|
462
|
-
fi
|
|
463
|
-
fi
|
|
464
|
-
done
|
|
465
|
-
|
|
466
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
467
|
-
if [[ $issues_found -eq 0 ]]; then
|
|
468
|
-
print_success "All language codes are correct for $locale"
|
|
469
|
-
else
|
|
470
|
-
print_error "Found $issues_found language code issues in $locale"
|
|
471
|
-
ERRORS=$((ERRORS + 1))
|
|
472
|
-
fi
|
|
473
|
-
}
|
|
474
|
-
|
|
475
|
-
# Function to compare with Japanese base files
|
|
476
|
-
compare_with_base() {
|
|
477
|
-
local locale="$1"
|
|
478
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
479
|
-
|
|
480
|
-
print_info "Comparing $locale with Japanese base files..."
|
|
481
|
-
|
|
482
|
-
# Compare command counts
|
|
483
|
-
if [[ -d "$COMMANDS_DIR" ]] && [[ -d "$locale_dir/commands" ]]; then
|
|
484
|
-
local base_count
|
|
485
|
-
base_count=$(find "$COMMANDS_DIR" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
486
|
-
local locale_count
|
|
487
|
-
locale_count=$(find "$locale_dir/commands" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
488
|
-
|
|
489
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
490
|
-
if [[ $locale_count -eq $base_count ]]; then
|
|
491
|
-
print_success "Command file count matches base ($base_count files)"
|
|
492
|
-
else
|
|
493
|
-
print_warning "Command file count differs from base (base: $base_count, $locale: $locale_count)"
|
|
494
|
-
fi
|
|
495
|
-
fi
|
|
496
|
-
|
|
497
|
-
# Compare role counts
|
|
498
|
-
if [[ -d "$AGENTS_DIR/roles" ]] && [[ -d "$locale_dir/agents/roles" ]]; then
|
|
499
|
-
local base_count
|
|
500
|
-
base_count=$(find "$AGENTS_DIR/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
501
|
-
local locale_count
|
|
502
|
-
locale_count=$(find "$locale_dir/agents/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
503
|
-
|
|
504
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
505
|
-
if [[ $locale_count -eq $base_count ]]; then
|
|
506
|
-
print_success "Role file count matches base ($base_count files)"
|
|
507
|
-
else
|
|
508
|
-
print_warning "Role file count differs from base (base: $base_count, $locale: $locale_count)"
|
|
509
|
-
fi
|
|
510
|
-
fi
|
|
511
|
-
|
|
512
|
-
# Check for CLAUDE.md
|
|
513
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
514
|
-
if [[ -f "$locale_dir/CLAUDE.md" ]]; then
|
|
515
|
-
print_success "CLAUDE.md exists"
|
|
516
|
-
else
|
|
517
|
-
print_error "CLAUDE.md is missing"
|
|
518
|
-
fi
|
|
519
|
-
|
|
520
|
-
# Check for COMMAND_TEMPLATE.md
|
|
521
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
522
|
-
if [[ -f "$locale_dir/COMMAND_TEMPLATE.md" ]]; then
|
|
523
|
-
print_success "COMMAND_TEMPLATE.md exists"
|
|
524
|
-
else
|
|
525
|
-
print_error "COMMAND_TEMPLATE.md is missing"
|
|
526
|
-
fi
|
|
527
|
-
|
|
528
|
-
# Check for missing files
|
|
529
|
-
print_info "Checking for missing files in $locale..."
|
|
530
|
-
local missing_files=0
|
|
531
|
-
|
|
532
|
-
for file in "$COMMANDS_DIR"/*.md; do
|
|
533
|
-
if [[ -f "$file" ]]; then
|
|
534
|
-
local basename
|
|
535
|
-
basename=$(basename "$file")
|
|
536
|
-
if [[ ! -f "$locale_dir/commands/$basename" ]]; then
|
|
537
|
-
print_warning "Missing in $locale: commands/$basename"
|
|
538
|
-
missing_files=$((missing_files + 1))
|
|
539
|
-
fi
|
|
540
|
-
fi
|
|
541
|
-
done
|
|
542
|
-
|
|
543
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
544
|
-
if [[ $missing_files -eq 0 ]]; then
|
|
545
|
-
print_success "All command files have corresponding translations"
|
|
546
|
-
else
|
|
547
|
-
print_error "$missing_files command files are missing translations"
|
|
548
|
-
fi
|
|
549
|
-
|
|
550
|
-
# Check for significant differences in content
|
|
551
|
-
print_info "Checking content differences for $locale..."
|
|
552
|
-
local content_issues=0
|
|
553
|
-
local files_with_issues=()
|
|
554
|
-
|
|
555
|
-
# Check command files
|
|
556
|
-
for file in "$COMMANDS_DIR"/*.md; do
|
|
557
|
-
if [[ -f "$file" ]]; then
|
|
558
|
-
local basename
|
|
559
|
-
basename=$(basename "$file")
|
|
560
|
-
local locale_file="$locale_dir/commands/$basename"
|
|
561
|
-
if [[ -f "$locale_file" ]]; then
|
|
562
|
-
local ja_lines
|
|
563
|
-
ja_lines=$(wc -l <"$file")
|
|
564
|
-
local locale_lines
|
|
565
|
-
locale_lines=$(wc -l <"$locale_file")
|
|
566
|
-
local ja_sections
|
|
567
|
-
ja_sections=$(grep -c "^#" "$file" || echo 0)
|
|
568
|
-
local locale_sections
|
|
569
|
-
locale_sections=$(grep -c "^#" "$locale_file" || echo 0)
|
|
570
|
-
|
|
571
|
-
# Check line count difference (more than 50% difference)
|
|
572
|
-
if [[ $ja_lines -gt 0 ]]; then
|
|
573
|
-
local line_ratio=$((locale_lines * 100 / ja_lines))
|
|
574
|
-
if [[ $line_ratio -lt 50 ]] || [[ $line_ratio -gt 150 ]]; then
|
|
575
|
-
files_with_issues+=("commands/$basename (lines: ${line_ratio}%)")
|
|
576
|
-
content_issues=$((content_issues + 1))
|
|
577
|
-
fi
|
|
578
|
-
fi
|
|
579
|
-
|
|
580
|
-
# Check section count difference
|
|
581
|
-
if [[ $ja_sections -ne $locale_sections ]]; then
|
|
582
|
-
files_with_issues+=("commands/$basename (sections: JP=$ja_sections, $locale=$locale_sections)")
|
|
583
|
-
content_issues=$((content_issues + 1))
|
|
584
|
-
fi
|
|
585
|
-
fi
|
|
586
|
-
fi
|
|
587
|
-
done
|
|
588
|
-
|
|
589
|
-
# Check role files
|
|
590
|
-
for file in "$AGENTS_DIR/roles"/*.md; do
|
|
591
|
-
if [[ -f "$file" ]]; then
|
|
592
|
-
local basename
|
|
593
|
-
basename=$(basename "$file")
|
|
594
|
-
local locale_file="$locale_dir/agents/roles/$basename"
|
|
595
|
-
if [[ -f "$locale_file" ]]; then
|
|
596
|
-
local ja_lines
|
|
597
|
-
ja_lines=$(wc -l <"$file")
|
|
598
|
-
local locale_lines
|
|
599
|
-
locale_lines=$(wc -l <"$locale_file")
|
|
600
|
-
local ja_sections
|
|
601
|
-
ja_sections=$(grep -c "^#" "$file" || echo 0)
|
|
602
|
-
local locale_sections
|
|
603
|
-
locale_sections=$(grep -c "^#" "$locale_file" || echo 0)
|
|
604
|
-
|
|
605
|
-
# Check line count difference (more than 50% difference)
|
|
606
|
-
if [[ $ja_lines -gt 0 ]]; then
|
|
607
|
-
local line_ratio=$((locale_lines * 100 / ja_lines))
|
|
608
|
-
if [[ $line_ratio -lt 50 ]] || [[ $line_ratio -gt 150 ]]; then
|
|
609
|
-
files_with_issues+=("agents/roles/$basename (lines: ${line_ratio}%)")
|
|
610
|
-
content_issues=$((content_issues + 1))
|
|
611
|
-
fi
|
|
612
|
-
fi
|
|
613
|
-
|
|
614
|
-
# Check section count difference
|
|
615
|
-
if [[ $ja_sections -ne $locale_sections ]]; then
|
|
616
|
-
files_with_issues+=("agents/roles/$basename (sections: JP=$ja_sections, $locale=$locale_sections)")
|
|
617
|
-
content_issues=$((content_issues + 1))
|
|
618
|
-
fi
|
|
619
|
-
fi
|
|
620
|
-
fi
|
|
621
|
-
done
|
|
622
|
-
|
|
623
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
624
|
-
if [[ $content_issues -eq 0 ]]; then
|
|
625
|
-
print_success "All translated files have consistent content structure"
|
|
626
|
-
else
|
|
627
|
-
print_warning "Found $content_issues files with significant differences:"
|
|
628
|
-
for issue in "${files_with_issues[@]}"; do
|
|
629
|
-
echo " ⚠️ $issue"
|
|
630
|
-
done
|
|
631
|
-
WARNINGS=$((WARNINGS + content_issues))
|
|
632
|
-
fi
|
|
633
|
-
}
|
|
634
|
-
|
|
635
|
-
# Function to compare locales
|
|
636
|
-
compare_locales() {
|
|
637
|
-
local locale1="$1"
|
|
638
|
-
local locale2="$2"
|
|
639
|
-
|
|
640
|
-
print_info "Comparing $locale1 and $locale2..."
|
|
641
|
-
|
|
642
|
-
# Compare command counts
|
|
643
|
-
if [[ -d "$LOCALES_DIR/$locale1/commands" ]] && [[ -d "$LOCALES_DIR/$locale2/commands" ]]; then
|
|
644
|
-
local count1
|
|
645
|
-
count1=$(find "$LOCALES_DIR/$locale1/commands" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
646
|
-
local count2
|
|
647
|
-
count2=$(find "$LOCALES_DIR/$locale2/commands" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
648
|
-
|
|
649
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
650
|
-
if [[ $count1 -eq $count2 ]]; then
|
|
651
|
-
print_success "Command file count matches ($count1 files)"
|
|
652
|
-
else
|
|
653
|
-
print_error "Command file count mismatch ($locale1: $count1, $locale2: $count2)"
|
|
654
|
-
fi
|
|
655
|
-
fi
|
|
656
|
-
|
|
657
|
-
# Compare role counts
|
|
658
|
-
if [[ -d "$LOCALES_DIR/$locale1/agents/roles" ]] && [[ -d "$LOCALES_DIR/$locale2/agents/roles" ]]; then
|
|
659
|
-
local count1
|
|
660
|
-
count1=$(find "$LOCALES_DIR/$locale1/agents/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
661
|
-
local count2
|
|
662
|
-
count2=$(find "$LOCALES_DIR/$locale2/agents/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
663
|
-
|
|
664
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
665
|
-
if [[ $count1 -eq $count2 ]]; then
|
|
666
|
-
print_success "Role file count matches ($count1 files)"
|
|
667
|
-
else
|
|
668
|
-
print_error "Role file count mismatch ($locale1: $count1, $locale2: $count2)"
|
|
669
|
-
fi
|
|
670
|
-
fi
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
# Function to check file sizes and quality metrics
|
|
674
|
-
check_quality_metrics() {
|
|
675
|
-
local locale="$1"
|
|
676
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
677
|
-
|
|
678
|
-
print_info "Quality metrics for $locale..."
|
|
679
|
-
|
|
680
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
681
|
-
# Calculate average file size
|
|
682
|
-
local total_size=0
|
|
683
|
-
local file_count=0
|
|
684
|
-
local smallest_file=""
|
|
685
|
-
local smallest_size=999999
|
|
686
|
-
local largest_file=""
|
|
687
|
-
local largest_size=0
|
|
688
|
-
|
|
689
|
-
for file in "$locale_dir/commands"/*.md; do
|
|
690
|
-
if [[ -f "$file" ]]; then
|
|
691
|
-
local size
|
|
692
|
-
size=$(wc -c <"$file")
|
|
693
|
-
total_size=$((total_size + size))
|
|
694
|
-
file_count=$((file_count + 1))
|
|
695
|
-
|
|
696
|
-
if [[ $size -lt $smallest_size ]]; then
|
|
697
|
-
smallest_size=$size
|
|
698
|
-
smallest_file=$(basename "$file")
|
|
699
|
-
fi
|
|
700
|
-
|
|
701
|
-
if [[ $size -gt $largest_size ]]; then
|
|
702
|
-
largest_size=$size
|
|
703
|
-
largest_file=$(basename "$file")
|
|
704
|
-
fi
|
|
705
|
-
fi
|
|
706
|
-
done
|
|
707
|
-
|
|
708
|
-
if [[ $file_count -gt 0 ]]; then
|
|
709
|
-
local avg_size=$((total_size / file_count))
|
|
710
|
-
echo " 📊 Average file size: $(format_bytes "$avg_size")"
|
|
711
|
-
echo " 📄 Smallest: $smallest_file ($(format_bytes "$smallest_size"))"
|
|
712
|
-
echo " 📄 Largest: $largest_file ($(format_bytes "$largest_size"))"
|
|
713
|
-
fi
|
|
714
|
-
fi
|
|
715
|
-
}
|
|
716
|
-
|
|
717
|
-
# Helper function to format bytes
|
|
718
|
-
format_bytes() {
|
|
719
|
-
local bytes=$1
|
|
720
|
-
if [[ $bytes -lt 1024 ]]; then
|
|
721
|
-
echo "${bytes}B"
|
|
722
|
-
elif [[ $bytes -lt 1048576 ]]; then
|
|
723
|
-
echo "$((bytes / 1024)) KB"
|
|
724
|
-
else
|
|
725
|
-
echo "$((bytes / 1048576)) MB"
|
|
726
|
-
fi
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
# Function to generate detailed report
|
|
730
|
-
generate_report() {
|
|
731
|
-
echo ""
|
|
732
|
-
echo "╔════════════════════════════════╗"
|
|
733
|
-
echo "║ Validation Report ║"
|
|
734
|
-
echo "╚════════════════════════════════╝"
|
|
735
|
-
echo ""
|
|
736
|
-
echo "📈 Statistics:"
|
|
737
|
-
echo " • Total checks performed: $TOTAL_CHECKS"
|
|
738
|
-
echo -e " • ${GREEN}✅ Passed: $PASSED_CHECKS${NC}"
|
|
739
|
-
echo -e " • ${RED}❌ Failed: $FAILED_CHECKS${NC}"
|
|
740
|
-
echo -e " • ${YELLOW}⚠️ Warnings: $WARNINGS${NC}"
|
|
741
|
-
|
|
742
|
-
local success_rate=0
|
|
743
|
-
if [[ $TOTAL_CHECKS -gt 0 ]]; then
|
|
744
|
-
success_rate=$((PASSED_CHECKS * 100 / TOTAL_CHECKS))
|
|
745
|
-
fi
|
|
746
|
-
|
|
747
|
-
echo ""
|
|
748
|
-
echo "📊 Success Rate: ${success_rate}%"
|
|
749
|
-
|
|
750
|
-
# Progress bar
|
|
751
|
-
echo -n " ["
|
|
752
|
-
local bar_length=30
|
|
753
|
-
local filled=$((success_rate * bar_length / 100))
|
|
754
|
-
for ((i = 0; i < filled; i++)); do
|
|
755
|
-
echo -n "█"
|
|
756
|
-
done
|
|
757
|
-
for ((i = filled; i < bar_length; i++)); do
|
|
758
|
-
echo -n "░"
|
|
759
|
-
done
|
|
760
|
-
echo "]"
|
|
761
|
-
|
|
762
|
-
echo ""
|
|
763
|
-
if [[ $FAILED_CHECKS -eq 0 ]]; then
|
|
764
|
-
echo -e "${GREEN}╔═══════════════════════════════════╗${NC}"
|
|
765
|
-
echo -e "${GREEN}║ 🎉 All validation checks passed! ║${NC}"
|
|
766
|
-
echo -e "${GREEN}╚═══════════════════════════════════╝${NC}"
|
|
767
|
-
return 0
|
|
768
|
-
else
|
|
769
|
-
echo -e "${RED}╔═══════════════════════════════════════╗${NC}"
|
|
770
|
-
echo -e "${RED}║ ⚠️ Validation failed: $FAILED_CHECKS error(s) ║${NC}"
|
|
771
|
-
echo -e "${RED}╚═══════════════════════════════════════╝${NC}"
|
|
772
|
-
return 1
|
|
773
|
-
fi
|
|
774
|
-
}
|
|
775
|
-
|
|
776
|
-
# Function to check documentation files (README in root, CLAUDE and COMMAND_TEMPLATE in locales)
|
|
777
|
-
check_documentation_files() {
|
|
778
|
-
local locale="$1"
|
|
779
|
-
|
|
780
|
-
print_info "Checking documentation files for $locale..."
|
|
781
|
-
|
|
782
|
-
# README files are in root with suffix
|
|
783
|
-
# CLAUDE.md and COMMAND_TEMPLATE.md are in locales without suffix
|
|
784
|
-
local doc_files=(
|
|
785
|
-
"README_${locale}.md"
|
|
786
|
-
"locales/${locale}/CLAUDE.md"
|
|
787
|
-
"locales/${locale}/COMMAND_TEMPLATE.md"
|
|
788
|
-
)
|
|
789
|
-
|
|
790
|
-
local base_files=(
|
|
791
|
-
"README.md"
|
|
792
|
-
"CLAUDE.md"
|
|
793
|
-
"COMMAND_TEMPLATE.md"
|
|
794
|
-
)
|
|
795
|
-
|
|
796
|
-
local missing_docs=()
|
|
797
|
-
local found_docs=0
|
|
798
|
-
local content_issues=0
|
|
799
|
-
|
|
800
|
-
for i in "${!doc_files[@]}"; do
|
|
801
|
-
local doc_file="${doc_files[$i]}"
|
|
802
|
-
local base_file="${base_files[$i]}"
|
|
803
|
-
local file_path="$PROJECT_ROOT/$doc_file"
|
|
804
|
-
local base_path="$PROJECT_ROOT/$base_file"
|
|
805
|
-
|
|
806
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
807
|
-
|
|
808
|
-
if [[ -f "$file_path" ]]; then
|
|
809
|
-
print_success "$(basename "$doc_file") exists"
|
|
810
|
-
found_docs=$((found_docs + 1))
|
|
811
|
-
|
|
812
|
-
# Check if file has substantial content
|
|
813
|
-
local size
|
|
814
|
-
size=$(wc -c <"$file_path")
|
|
815
|
-
if [[ $size -lt 500 ]]; then
|
|
816
|
-
print_warning " ⚠️ $(basename "$doc_file") seems too small (${size} bytes)"
|
|
817
|
-
WARNINGS=$((WARNINGS + 1))
|
|
818
|
-
fi
|
|
819
|
-
|
|
820
|
-
# Compare sections with base file (excluding code blocks)
|
|
821
|
-
if [[ -f "$base_path" ]]; then
|
|
822
|
-
# Count sections excluding those in code blocks
|
|
823
|
-
# Method: Remove code blocks first, then count headers
|
|
824
|
-
local base_sections
|
|
825
|
-
base_sections=$(sed '/^```/,/^```/d' "$base_path" 2>/dev/null | grep -c -E "^#{1,3} " || echo "0")
|
|
826
|
-
local locale_sections
|
|
827
|
-
locale_sections=$(sed '/^```/,/^```/d' "$file_path" 2>/dev/null | grep -c -E "^#{1,3} " || echo "0")
|
|
828
|
-
|
|
829
|
-
# If sed fails, fallback to simple grep
|
|
830
|
-
if [[ -z "$base_sections" || "$base_sections" -eq 0 ]]; then
|
|
831
|
-
base_sections=$(grep -c -E "^#{1,3} " "$base_path" || echo "0")
|
|
832
|
-
fi
|
|
833
|
-
if [[ -z "$locale_sections" || "$locale_sections" -eq 0 ]]; then
|
|
834
|
-
locale_sections=$(grep -c -E "^#{1,3} " "$file_path" || echo "0")
|
|
835
|
-
fi
|
|
836
|
-
|
|
837
|
-
# Check section differences - warn if any difference
|
|
838
|
-
if [[ $locale_sections -ne $base_sections ]]; then
|
|
839
|
-
print_warning " ⚠️ Section count mismatch in $(basename "$doc_file"): Base=$base_sections, $locale=$locale_sections"
|
|
840
|
-
content_issues=$((content_issues + 1))
|
|
841
|
-
WARNINGS=$((WARNINGS + 1))
|
|
842
|
-
fi
|
|
843
|
-
|
|
844
|
-
# Check line count differences - warn if > 5%
|
|
845
|
-
local base_lines
|
|
846
|
-
base_lines=$(wc -l <"$base_path" | tr -d ' ')
|
|
847
|
-
local locale_lines
|
|
848
|
-
locale_lines=$(wc -l <"$file_path" | tr -d ' ')
|
|
849
|
-
|
|
850
|
-
if [[ $base_lines -gt 0 ]]; then
|
|
851
|
-
local line_diff=$((locale_lines - base_lines))
|
|
852
|
-
if [[ $line_diff -lt 0 ]]; then
|
|
853
|
-
line_diff=$((-line_diff))
|
|
854
|
-
fi
|
|
855
|
-
local diff_percent=$((line_diff * 100 / base_lines))
|
|
856
|
-
|
|
857
|
-
if [[ $diff_percent -gt 5 ]]; then
|
|
858
|
-
print_warning " ⚠️ Line count difference > 5% in $(basename "$doc_file"): Base=$base_lines lines, $locale=$locale_lines lines (${diff_percent}% difference)"
|
|
859
|
-
WARNINGS=$((WARNINGS + 1))
|
|
860
|
-
fi
|
|
861
|
-
fi
|
|
862
|
-
|
|
863
|
-
# Check for Spanish-specific quality issues
|
|
864
|
-
if [[ "$locale" == "es" ]]; then
|
|
865
|
-
# Check for common Spanish translation issues
|
|
866
|
-
local quality_issues=0
|
|
867
|
-
|
|
868
|
-
# Check for missing accents in common words
|
|
869
|
-
if grep -q -E "\b(mas|tambien|facil|rapido|faciles|despues|mas)\b" "$file_path" 2>/dev/null; then
|
|
870
|
-
print_warning " ⚠️ Possible missing accents detected in $(basename "$doc_file")"
|
|
871
|
-
quality_issues=$((quality_issues + 1))
|
|
872
|
-
fi
|
|
873
|
-
|
|
874
|
-
# Check for incorrect verb forms or anglicisms
|
|
875
|
-
if grep -q -E "(hacer click|hacer clic|setear|testear)" "$file_path" 2>/dev/null; then
|
|
876
|
-
print_warning " ⚠️ Possible anglicisms detected in $(basename "$doc_file")"
|
|
877
|
-
quality_issues=$((quality_issues + 1))
|
|
878
|
-
fi
|
|
879
|
-
|
|
880
|
-
# Check for proper Spanish punctuation (¿ and ¡)
|
|
881
|
-
local questions
|
|
882
|
-
questions=$(grep -c "?" "$file_path" 2>/dev/null || echo 0)
|
|
883
|
-
questions=${questions//[^0-9]/} # Remove non-digit characters
|
|
884
|
-
local spanish_questions
|
|
885
|
-
spanish_questions=$(grep -c "¿" "$file_path" 2>/dev/null || echo 0)
|
|
886
|
-
spanish_questions=${spanish_questions//[^0-9]/} # Remove non-digit characters
|
|
887
|
-
if [[ $questions -gt 0 ]] && [[ $spanish_questions -eq 0 ]]; then
|
|
888
|
-
print_warning " ⚠️ Missing Spanish question marks (¿) in $(basename "$doc_file")"
|
|
889
|
-
quality_issues=$((quality_issues + 1))
|
|
890
|
-
fi
|
|
891
|
-
|
|
892
|
-
if [[ $quality_issues -gt 0 ]]; then
|
|
893
|
-
WARNINGS=$((WARNINGS + quality_issues))
|
|
894
|
-
fi
|
|
895
|
-
fi
|
|
896
|
-
fi
|
|
897
|
-
else
|
|
898
|
-
print_error "$(basename "$doc_file") is missing"
|
|
899
|
-
missing_docs+=("$(basename "$doc_file")")
|
|
900
|
-
FAILED_CHECKS=$((FAILED_CHECKS + 1))
|
|
901
|
-
fi
|
|
902
|
-
done
|
|
903
|
-
|
|
904
|
-
# Summary
|
|
905
|
-
if [[ ${#missing_docs[@]} -eq 0 ]]; then
|
|
906
|
-
if [[ $content_issues -eq 0 ]]; then
|
|
907
|
-
print_info "All documentation files present and consistent for $locale"
|
|
908
|
-
else
|
|
909
|
-
print_warning "Documentation files present but with $content_issues content issues for $locale"
|
|
910
|
-
fi
|
|
911
|
-
else
|
|
912
|
-
print_warning "Missing documentation files: ${missing_docs[*]}"
|
|
913
|
-
fi
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
# Function to check for translation completeness
|
|
917
|
-
check_translation_completeness() {
|
|
918
|
-
local locale="$1"
|
|
919
|
-
local locale_dir="$LOCALES_DIR/$locale"
|
|
920
|
-
|
|
921
|
-
print_info "Translation completeness for $locale..."
|
|
922
|
-
|
|
923
|
-
if [[ -d "$locale_dir/commands" ]]; then
|
|
924
|
-
local empty_files=0
|
|
925
|
-
local incomplete_files=()
|
|
926
|
-
|
|
927
|
-
for file in "$locale_dir/commands"/*.md; do
|
|
928
|
-
if [[ -f "$file" ]]; then
|
|
929
|
-
local lines
|
|
930
|
-
lines=$(wc -l <"$file")
|
|
931
|
-
local size
|
|
932
|
-
size=$(wc -c <"$file")
|
|
933
|
-
|
|
934
|
-
if [[ $size -lt 100 ]]; then
|
|
935
|
-
empty_files=$((empty_files + 1))
|
|
936
|
-
incomplete_files+=("$(basename "$file")")
|
|
937
|
-
elif [[ $lines -lt 10 ]]; then
|
|
938
|
-
incomplete_files+=("$(basename "$file")")
|
|
939
|
-
fi
|
|
940
|
-
fi
|
|
941
|
-
done
|
|
942
|
-
|
|
943
|
-
TOTAL_CHECKS=$((TOTAL_CHECKS + 1))
|
|
944
|
-
if [[ $empty_files -eq 0 && ${#incomplete_files[@]} -eq 0 ]]; then
|
|
945
|
-
print_success "All files appear to be fully translated"
|
|
946
|
-
else
|
|
947
|
-
if [[ $empty_files -gt 0 ]]; then
|
|
948
|
-
print_warning "Found $empty_files nearly empty files (<100 bytes)"
|
|
949
|
-
fi
|
|
950
|
-
if [[ ${#incomplete_files[@]} -gt 0 ]]; then
|
|
951
|
-
print_warning "Potentially incomplete translations (< 10 lines):"
|
|
952
|
-
for file in "${incomplete_files[@]:0:5}"; do
|
|
953
|
-
echo " ⚠️ $file"
|
|
954
|
-
done
|
|
955
|
-
if [[ ${#incomplete_files[@]} -gt 5 ]]; then
|
|
956
|
-
echo " ... and $((${#incomplete_files[@]} - 5)) more"
|
|
957
|
-
fi
|
|
958
|
-
fi
|
|
959
|
-
fi
|
|
960
|
-
fi
|
|
961
|
-
}
|
|
962
|
-
|
|
963
|
-
# Main execution
|
|
964
|
-
main() {
|
|
965
|
-
echo ""
|
|
966
|
-
echo "╔═══════════════════════════════════════╗"
|
|
967
|
-
echo "║ 🔍 Locale Validation Tool ║"
|
|
968
|
-
echo "╠═══════════════════════════════════════╣"
|
|
969
|
-
echo "║ Enhanced validation & reporting ║"
|
|
970
|
-
echo "╚═══════════════════════════════════════╝"
|
|
971
|
-
echo ""
|
|
972
|
-
|
|
973
|
-
# Check if locales directory exists
|
|
974
|
-
if [[ ! -d "$LOCALES_DIR" ]]; then
|
|
975
|
-
print_warning "Locales directory not found: $LOCALES_DIR"
|
|
976
|
-
print_info "This project uses Japanese as the base language in commands/ and agents/"
|
|
977
|
-
fi
|
|
978
|
-
|
|
979
|
-
# Parse arguments
|
|
980
|
-
if [[ $# -eq 0 ]]; then
|
|
981
|
-
# Check base Japanese files first
|
|
982
|
-
echo "────────────────────────────────"
|
|
983
|
-
echo "Base Files (Japanese)"
|
|
984
|
-
echo "────────────────────────────────"
|
|
985
|
-
|
|
986
|
-
if [[ -d "$COMMANDS_DIR" ]]; then
|
|
987
|
-
local ja_cmd_count
|
|
988
|
-
ja_cmd_count=$(find "$COMMANDS_DIR" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
989
|
-
echo " Commands: $ja_cmd_count files"
|
|
990
|
-
fi
|
|
991
|
-
|
|
992
|
-
if [[ -d "$AGENTS_DIR/roles" ]]; then
|
|
993
|
-
local ja_role_count
|
|
994
|
-
ja_role_count=$(find "$AGENTS_DIR/roles" -name "*.md" -type f -exec printf '.' \; | wc -c)
|
|
995
|
-
echo " Roles: $ja_role_count files"
|
|
996
|
-
fi
|
|
997
|
-
|
|
998
|
-
# Check for main documentation files
|
|
999
|
-
local main_docs=()
|
|
1000
|
-
[[ -f "$PROJECT_ROOT/README.md" ]] && main_docs+=("README.md")
|
|
1001
|
-
[[ -f "$PROJECT_ROOT/CLAUDE.md" ]] && main_docs+=("CLAUDE.md")
|
|
1002
|
-
[[ -f "$PROJECT_ROOT/docs/templates/COMMAND_TEMPLATE.md" ]] && main_docs+=("COMMAND_TEMPLATE.md")
|
|
1003
|
-
|
|
1004
|
-
if [[ ${#main_docs[@]} -gt 0 ]]; then
|
|
1005
|
-
echo " Documentation: ${#main_docs[@]} files (${main_docs[*]})"
|
|
1006
|
-
fi
|
|
1007
|
-
echo ""
|
|
1008
|
-
|
|
1009
|
-
# Validate all locales if directory exists
|
|
1010
|
-
if [[ -d "$LOCALES_DIR" ]]; then
|
|
1011
|
-
print_info "Validating all locales..."
|
|
1012
|
-
echo ""
|
|
1013
|
-
|
|
1014
|
-
for locale_dir in "$LOCALES_DIR"/*; do
|
|
1015
|
-
if [[ -d "$locale_dir" ]]; then
|
|
1016
|
-
local locale
|
|
1017
|
-
locale=$(basename "$locale_dir")
|
|
1018
|
-
echo "────────────────────────────────"
|
|
1019
|
-
echo "Locale: $locale"
|
|
1020
|
-
echo "────────────────────────────────"
|
|
1021
|
-
check_structure "$locale"
|
|
1022
|
-
count_files "$locale"
|
|
1023
|
-
check_language_content "$locale"
|
|
1024
|
-
check_language_codes "$locale"
|
|
1025
|
-
check_quality_metrics "$locale"
|
|
1026
|
-
check_translation_completeness "$locale"
|
|
1027
|
-
check_documentation_files "$locale"
|
|
1028
|
-
compare_with_base "$locale"
|
|
1029
|
-
echo ""
|
|
1030
|
-
fi
|
|
1031
|
-
done
|
|
1032
|
-
|
|
1033
|
-
# Compare locales if multiple exist
|
|
1034
|
-
local locales=()
|
|
1035
|
-
while IFS= read -r dir; do
|
|
1036
|
-
locales+=("$(basename "$dir")")
|
|
1037
|
-
done < <(find "$LOCALES_DIR" -mindepth 1 -maxdepth 1 -type d)
|
|
1038
|
-
if [[ ${#locales[@]} -ge 2 ]]; then
|
|
1039
|
-
echo "────────────────────────────────"
|
|
1040
|
-
echo "Locale Comparison"
|
|
1041
|
-
echo "────────────────────────────────"
|
|
1042
|
-
compare_locales "${locales[0]}" "${locales[1]}"
|
|
1043
|
-
fi
|
|
1044
|
-
fi
|
|
1045
|
-
|
|
1046
|
-
else
|
|
1047
|
-
# Validate specific locale
|
|
1048
|
-
local locale="$1"
|
|
1049
|
-
|
|
1050
|
-
if [[ ! -d "$LOCALES_DIR/$locale" ]]; then
|
|
1051
|
-
print_error "Locale not found: $locale"
|
|
1052
|
-
print_info "Available locales:"
|
|
1053
|
-
for dir in "$LOCALES_DIR"/*; do
|
|
1054
|
-
if [[ -d "$dir" ]]; then
|
|
1055
|
-
echo " - $(basename "$dir")"
|
|
1056
|
-
fi
|
|
1057
|
-
done
|
|
1058
|
-
exit 1
|
|
1059
|
-
fi
|
|
1060
|
-
|
|
1061
|
-
check_structure "$locale"
|
|
1062
|
-
count_files "$locale"
|
|
1063
|
-
check_language_content "$locale"
|
|
1064
|
-
check_language_codes "$locale"
|
|
1065
|
-
check_quality_metrics "$locale"
|
|
1066
|
-
check_translation_completeness "$locale"
|
|
1067
|
-
check_documentation_files "$locale"
|
|
1068
|
-
compare_with_base "$locale"
|
|
1069
|
-
|
|
1070
|
-
# If second argument provided, compare with it
|
|
1071
|
-
if [[ -n "${2:-}" ]]; then
|
|
1072
|
-
echo ""
|
|
1073
|
-
compare_locales "$locale" "$2"
|
|
1074
|
-
fi
|
|
1075
|
-
fi
|
|
1076
|
-
|
|
1077
|
-
generate_report
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
main "$@"
|