@musashishao/agent-kit 1.0.0

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.

Potentially problematic release.


This version of @musashishao/agent-kit might be problematic. Click here for more details.

Files changed (220) hide show
  1. package/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
  2. package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
  3. package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
  4. package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
  5. package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
  6. package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
  7. package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
  8. package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  9. package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  10. package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
  11. package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  12. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  13. package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  14. package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  15. package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
  16. package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  17. package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  18. package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  19. package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  20. package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
  21. package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
  22. package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  23. package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  24. package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
  25. package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
  26. package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +487 -0
  27. package/.agent/.shared/ui-ux-pro-max/scripts/search.py +76 -0
  28. package/.agent/ARCHITECTURE.md +225 -0
  29. package/.agent/CONTEXT.md +229 -0
  30. package/.agent/FEATURE_ROADMAP.md +435 -0
  31. package/.agent/PROMPT_TEMPLATES.md +261 -0
  32. package/.agent/agents/backend-specialist.md +263 -0
  33. package/.agent/agents/database-architect.md +226 -0
  34. package/.agent/agents/debugger.md +225 -0
  35. package/.agent/agents/devops-engineer.md +242 -0
  36. package/.agent/agents/documentation-writer.md +104 -0
  37. package/.agent/agents/explorer-agent.md +73 -0
  38. package/.agent/agents/frontend-specialist.md +556 -0
  39. package/.agent/agents/game-developer.md +162 -0
  40. package/.agent/agents/mobile-developer.md +377 -0
  41. package/.agent/agents/orchestrator.md +416 -0
  42. package/.agent/agents/penetration-tester.md +188 -0
  43. package/.agent/agents/performance-optimizer.md +187 -0
  44. package/.agent/agents/project-planner.md +403 -0
  45. package/.agent/agents/security-auditor.md +170 -0
  46. package/.agent/agents/seo-specialist.md +111 -0
  47. package/.agent/agents/test-engineer.md +158 -0
  48. package/.agent/rules/GEMINI.md +251 -0
  49. package/.agent/skills/api-patterns/SKILL.md +81 -0
  50. package/.agent/skills/api-patterns/api-style.md +42 -0
  51. package/.agent/skills/api-patterns/auth.md +24 -0
  52. package/.agent/skills/api-patterns/documentation.md +26 -0
  53. package/.agent/skills/api-patterns/graphql.md +41 -0
  54. package/.agent/skills/api-patterns/rate-limiting.md +31 -0
  55. package/.agent/skills/api-patterns/response.md +37 -0
  56. package/.agent/skills/api-patterns/rest.md +40 -0
  57. package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
  58. package/.agent/skills/api-patterns/security-testing.md +122 -0
  59. package/.agent/skills/api-patterns/trpc.md +41 -0
  60. package/.agent/skills/api-patterns/versioning.md +22 -0
  61. package/.agent/skills/app-builder/SKILL.md +75 -0
  62. package/.agent/skills/app-builder/agent-coordination.md +71 -0
  63. package/.agent/skills/app-builder/feature-building.md +53 -0
  64. package/.agent/skills/app-builder/project-detection.md +34 -0
  65. package/.agent/skills/app-builder/scaffolding.md +118 -0
  66. package/.agent/skills/app-builder/tech-stack.md +40 -0
  67. package/.agent/skills/app-builder/templates/SKILL.md +39 -0
  68. package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
  69. package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
  70. package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
  71. package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
  72. package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
  73. package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
  74. package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
  75. package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +82 -0
  76. package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +100 -0
  77. package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +106 -0
  78. package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +101 -0
  79. package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
  80. package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +93 -0
  81. package/.agent/skills/architecture/SKILL.md +55 -0
  82. package/.agent/skills/architecture/context-discovery.md +43 -0
  83. package/.agent/skills/architecture/examples.md +94 -0
  84. package/.agent/skills/architecture/pattern-selection.md +68 -0
  85. package/.agent/skills/architecture/patterns-reference.md +50 -0
  86. package/.agent/skills/architecture/trade-off-analysis.md +77 -0
  87. package/.agent/skills/bash-linux/SKILL.md +199 -0
  88. package/.agent/skills/behavioral-modes/SKILL.md +242 -0
  89. package/.agent/skills/brainstorming/SKILL.md +163 -0
  90. package/.agent/skills/brainstorming/dynamic-questioning.md +350 -0
  91. package/.agent/skills/clean-code/SKILL.md +201 -0
  92. package/.agent/skills/code-review-checklist/SKILL.md +109 -0
  93. package/.agent/skills/database-design/SKILL.md +52 -0
  94. package/.agent/skills/database-design/database-selection.md +43 -0
  95. package/.agent/skills/database-design/indexing.md +39 -0
  96. package/.agent/skills/database-design/migrations.md +48 -0
  97. package/.agent/skills/database-design/optimization.md +36 -0
  98. package/.agent/skills/database-design/orm-selection.md +30 -0
  99. package/.agent/skills/database-design/schema-design.md +56 -0
  100. package/.agent/skills/database-design/scripts/schema_validator.py +172 -0
  101. package/.agent/skills/deployment-procedures/SKILL.md +241 -0
  102. package/.agent/skills/doc.md +177 -0
  103. package/.agent/skills/docker-expert/SKILL.md +409 -0
  104. package/.agent/skills/documentation-templates/SKILL.md +194 -0
  105. package/.agent/skills/frontend-design/SKILL.md +396 -0
  106. package/.agent/skills/frontend-design/animation-guide.md +331 -0
  107. package/.agent/skills/frontend-design/color-system.md +311 -0
  108. package/.agent/skills/frontend-design/decision-trees.md +418 -0
  109. package/.agent/skills/frontend-design/motion-graphics.md +306 -0
  110. package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
  111. package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
  112. package/.agent/skills/frontend-design/typography-system.md +345 -0
  113. package/.agent/skills/frontend-design/ux-psychology.md +541 -0
  114. package/.agent/skills/frontend-design/visual-effects.md +383 -0
  115. package/.agent/skills/game-development/2d-games/SKILL.md +119 -0
  116. package/.agent/skills/game-development/3d-games/SKILL.md +135 -0
  117. package/.agent/skills/game-development/SKILL.md +167 -0
  118. package/.agent/skills/game-development/game-art/SKILL.md +185 -0
  119. package/.agent/skills/game-development/game-audio/SKILL.md +190 -0
  120. package/.agent/skills/game-development/game-design/SKILL.md +129 -0
  121. package/.agent/skills/game-development/mobile-games/SKILL.md +108 -0
  122. package/.agent/skills/game-development/multiplayer/SKILL.md +132 -0
  123. package/.agent/skills/game-development/pc-games/SKILL.md +144 -0
  124. package/.agent/skills/game-development/vr-ar/SKILL.md +123 -0
  125. package/.agent/skills/game-development/web-games/SKILL.md +150 -0
  126. package/.agent/skills/geo-fundamentals/SKILL.md +156 -0
  127. package/.agent/skills/geo-fundamentals/scripts/geo_checker.py +289 -0
  128. package/.agent/skills/i18n-localization/SKILL.md +154 -0
  129. package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
  130. package/.agent/skills/lint-and-validate/SKILL.md +45 -0
  131. package/.agent/skills/lint-and-validate/scripts/lint_runner.py +172 -0
  132. package/.agent/skills/lint-and-validate/scripts/type_coverage.py +173 -0
  133. package/.agent/skills/mcp-builder/SKILL.md +176 -0
  134. package/.agent/skills/mobile-design/SKILL.md +394 -0
  135. package/.agent/skills/mobile-design/decision-trees.md +516 -0
  136. package/.agent/skills/mobile-design/mobile-backend.md +491 -0
  137. package/.agent/skills/mobile-design/mobile-color-system.md +420 -0
  138. package/.agent/skills/mobile-design/mobile-debugging.md +122 -0
  139. package/.agent/skills/mobile-design/mobile-design-thinking.md +357 -0
  140. package/.agent/skills/mobile-design/mobile-navigation.md +458 -0
  141. package/.agent/skills/mobile-design/mobile-performance.md +767 -0
  142. package/.agent/skills/mobile-design/mobile-testing.md +356 -0
  143. package/.agent/skills/mobile-design/mobile-typography.md +433 -0
  144. package/.agent/skills/mobile-design/platform-android.md +666 -0
  145. package/.agent/skills/mobile-design/platform-ios.md +561 -0
  146. package/.agent/skills/mobile-design/scripts/mobile_audit.py +670 -0
  147. package/.agent/skills/mobile-design/touch-psychology.md +537 -0
  148. package/.agent/skills/nestjs-expert/SKILL.md +552 -0
  149. package/.agent/skills/nextjs-best-practices/SKILL.md +203 -0
  150. package/.agent/skills/nodejs-best-practices/SKILL.md +333 -0
  151. package/.agent/skills/parallel-agents/SKILL.md +175 -0
  152. package/.agent/skills/performance-profiling/SKILL.md +143 -0
  153. package/.agent/skills/performance-profiling/scripts/lighthouse_audit.py +76 -0
  154. package/.agent/skills/plan-writing/SKILL.md +152 -0
  155. package/.agent/skills/powershell-windows/SKILL.md +167 -0
  156. package/.agent/skills/prisma-expert/SKILL.md +355 -0
  157. package/.agent/skills/python-patterns/SKILL.md +441 -0
  158. package/.agent/skills/react-patterns/SKILL.md +198 -0
  159. package/.agent/skills/red-team-tactics/SKILL.md +199 -0
  160. package/.agent/skills/seo-fundamentals/SKILL.md +129 -0
  161. package/.agent/skills/seo-fundamentals/scripts/seo_checker.py +219 -0
  162. package/.agent/skills/server-management/SKILL.md +161 -0
  163. package/.agent/skills/systematic-debugging/SKILL.md +109 -0
  164. package/.agent/skills/tailwind-patterns/SKILL.md +269 -0
  165. package/.agent/skills/tdd-workflow/SKILL.md +149 -0
  166. package/.agent/skills/testing-patterns/SKILL.md +178 -0
  167. package/.agent/skills/testing-patterns/scripts/test_runner.py +219 -0
  168. package/.agent/skills/typescript-expert/SKILL.md +429 -0
  169. package/.agent/skills/typescript-expert/references/tsconfig-strict.json +92 -0
  170. package/.agent/skills/typescript-expert/references/typescript-cheatsheet.md +383 -0
  171. package/.agent/skills/typescript-expert/references/utility-types.ts +335 -0
  172. package/.agent/skills/typescript-expert/scripts/ts_diagnostic.py +203 -0
  173. package/.agent/skills/ui-ux-pro-max/SKILL.md +351 -0
  174. package/.agent/skills/ui-ux-pro-max/data/charts.csv +26 -0
  175. package/.agent/skills/ui-ux-pro-max/data/colors.csv +97 -0
  176. package/.agent/skills/ui-ux-pro-max/data/icons.csv +101 -0
  177. package/.agent/skills/ui-ux-pro-max/data/landing.csv +31 -0
  178. package/.agent/skills/ui-ux-pro-max/data/products.csv +97 -0
  179. package/.agent/skills/ui-ux-pro-max/data/prompts.csv +24 -0
  180. package/.agent/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
  181. package/.agent/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
  182. package/.agent/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
  183. package/.agent/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
  184. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
  185. package/.agent/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
  186. package/.agent/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
  187. package/.agent/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
  188. package/.agent/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
  189. package/.agent/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
  190. package/.agent/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
  191. package/.agent/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
  192. package/.agent/skills/ui-ux-pro-max/data/styles.csv +59 -0
  193. package/.agent/skills/ui-ux-pro-max/data/typography.csv +58 -0
  194. package/.agent/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
  195. package/.agent/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
  196. package/.agent/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
  197. package/.agent/skills/ui-ux-pro-max/scripts/core.py +257 -0
  198. package/.agent/skills/ui-ux-pro-max/scripts/design_system.py +487 -0
  199. package/.agent/skills/ui-ux-pro-max/scripts/search.py +76 -0
  200. package/.agent/skills/vulnerability-scanner/SKILL.md +276 -0
  201. package/.agent/skills/vulnerability-scanner/checklists.md +121 -0
  202. package/.agent/skills/vulnerability-scanner/scripts/security_scan.py +458 -0
  203. package/.agent/skills/webapp-testing/SKILL.md +187 -0
  204. package/.agent/skills/webapp-testing/scripts/playwright_runner.py +173 -0
  205. package/.agent/workflows/brainstorm.md +113 -0
  206. package/.agent/workflows/create.md +59 -0
  207. package/.agent/workflows/debug.md +103 -0
  208. package/.agent/workflows/deploy.md +176 -0
  209. package/.agent/workflows/enhance.md +63 -0
  210. package/.agent/workflows/orchestrate.md +237 -0
  211. package/.agent/workflows/plan.md +89 -0
  212. package/.agent/workflows/preview.md +80 -0
  213. package/.agent/workflows/status.md +86 -0
  214. package/.agent/workflows/test.md +144 -0
  215. package/.agent/workflows/ui-ux-pro-max.md +231 -0
  216. package/LICENSE +21 -0
  217. package/README.md +101 -0
  218. package/bin/cli.js +235 -0
  219. package/index.js +1 -0
  220. package/package.json +43 -0
@@ -0,0 +1,241 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ i18n Checker - Detects hardcoded strings and missing translations.
4
+ Scans for untranslated text in React, Vue, and Python files.
5
+ """
6
+ import sys
7
+ import re
8
+ import json
9
+ from pathlib import Path
10
+
11
+ # Fix Windows console encoding for Unicode output
12
+ try:
13
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
14
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
15
+ except AttributeError:
16
+ pass # Python < 3.7
17
+
18
+ # Patterns that indicate hardcoded strings (should be translated)
19
+ HARDCODED_PATTERNS = {
20
+ 'jsx': [
21
+ # Text directly in JSX: <div>Hello World</div>
22
+ r'>\s*[A-Z][a-zA-Z\s]{3,30}\s*</',
23
+ # JSX attribute strings: title="Welcome"
24
+ r'(title|placeholder|label|alt|aria-label)="[A-Z][a-zA-Z\s]{2,}"',
25
+ # Button/heading text
26
+ r'<(button|h[1-6]|p|span|label)[^>]*>\s*[A-Z][a-zA-Z\s!?.,]{3,}\s*</',
27
+ ],
28
+ 'vue': [
29
+ # Vue template text
30
+ r'>\s*[A-Z][a-zA-Z\s]{3,30}\s*</',
31
+ r'(placeholder|label|title)="[A-Z][a-zA-Z\s]{2,}"',
32
+ ],
33
+ 'python': [
34
+ # print/raise with string literals
35
+ r'(print|raise\s+\w+)\s*\(\s*["\'][A-Z][^"\']{5,}["\']',
36
+ # Flask flash messages
37
+ r'flash\s*\(\s*["\'][A-Z][^"\']{5,}["\']',
38
+ ]
39
+ }
40
+
41
+ # Patterns that indicate proper i18n usage
42
+ I18N_PATTERNS = [
43
+ r't\(["\']', # t('key') - react-i18next
44
+ r'useTranslation', # React hook
45
+ r'\$t\(', # Vue i18n
46
+ r'_\(["\']', # Python gettext
47
+ r'gettext\(', # Python gettext
48
+ r'useTranslations', # next-intl
49
+ r'FormattedMessage', # react-intl
50
+ r'i18n\.', # Generic i18n
51
+ ]
52
+
53
+ def find_locale_files(project_path: Path) -> list:
54
+ """Find translation/locale files."""
55
+ patterns = [
56
+ "**/locales/**/*.json",
57
+ "**/translations/**/*.json",
58
+ "**/lang/**/*.json",
59
+ "**/i18n/**/*.json",
60
+ "**/messages/*.json",
61
+ "**/*.po", # gettext
62
+ ]
63
+
64
+ files = []
65
+ for pattern in patterns:
66
+ files.extend(project_path.glob(pattern))
67
+
68
+ return [f for f in files if 'node_modules' not in str(f)]
69
+
70
+ def check_locale_completeness(locale_files: list) -> dict:
71
+ """Check if all locales have the same keys."""
72
+ issues = []
73
+ passed = []
74
+
75
+ if not locale_files:
76
+ return {'passed': [], 'issues': ["[!] No locale files found"]}
77
+
78
+ # Group by parent folder (language)
79
+ locales = {}
80
+ for f in locale_files:
81
+ if f.suffix == '.json':
82
+ try:
83
+ lang = f.parent.name
84
+ content = json.loads(f.read_text(encoding='utf-8'))
85
+ if lang not in locales:
86
+ locales[lang] = {}
87
+ locales[lang][f.stem] = set(flatten_keys(content))
88
+ except:
89
+ continue
90
+
91
+ if len(locales) < 2:
92
+ passed.append(f"[OK] Found {len(locale_files)} locale file(s)")
93
+ return {'passed': passed, 'issues': issues}
94
+
95
+ passed.append(f"[OK] Found {len(locales)} language(s): {', '.join(locales.keys())}")
96
+
97
+ # Compare keys across locales
98
+ all_langs = list(locales.keys())
99
+ base_lang = all_langs[0]
100
+
101
+ for namespace in locales.get(base_lang, {}):
102
+ base_keys = locales[base_lang].get(namespace, set())
103
+
104
+ for lang in all_langs[1:]:
105
+ other_keys = locales.get(lang, {}).get(namespace, set())
106
+
107
+ missing = base_keys - other_keys
108
+ if missing:
109
+ issues.append(f"[X] {lang}/{namespace}: Missing {len(missing)} keys")
110
+
111
+ extra = other_keys - base_keys
112
+ if extra:
113
+ issues.append(f"[!] {lang}/{namespace}: {len(extra)} extra keys")
114
+
115
+ if not issues:
116
+ passed.append("[OK] All locales have matching keys")
117
+
118
+ return {'passed': passed, 'issues': issues}
119
+
120
+ def flatten_keys(d, prefix=''):
121
+ """Flatten nested dict keys."""
122
+ keys = set()
123
+ for k, v in d.items():
124
+ new_key = f"{prefix}.{k}" if prefix else k
125
+ if isinstance(v, dict):
126
+ keys.update(flatten_keys(v, new_key))
127
+ else:
128
+ keys.add(new_key)
129
+ return keys
130
+
131
+ def check_hardcoded_strings(project_path: Path) -> dict:
132
+ """Check for hardcoded strings in code files."""
133
+ issues = []
134
+ passed = []
135
+
136
+ # Find code files
137
+ extensions = {
138
+ '.tsx': 'jsx', '.jsx': 'jsx', '.ts': 'jsx', '.js': 'jsx',
139
+ '.vue': 'vue',
140
+ '.py': 'python'
141
+ }
142
+
143
+ code_files = []
144
+ for ext in extensions:
145
+ code_files.extend(project_path.rglob(f"*{ext}"))
146
+
147
+ code_files = [f for f in code_files if not any(x in str(f) for x in
148
+ ['node_modules', '.git', 'dist', 'build', '__pycache__', 'venv', 'test', 'spec'])]
149
+
150
+ if not code_files:
151
+ return {'passed': ["[!] No code files found"], 'issues': []}
152
+
153
+ files_with_i18n = 0
154
+ files_with_hardcoded = 0
155
+ hardcoded_examples = []
156
+
157
+ for file_path in code_files[:50]: # Limit
158
+ try:
159
+ content = file_path.read_text(encoding='utf-8', errors='ignore')
160
+ ext = file_path.suffix
161
+ file_type = extensions.get(ext, 'jsx')
162
+
163
+ # Check for i18n usage
164
+ has_i18n = any(re.search(p, content) for p in I18N_PATTERNS)
165
+ if has_i18n:
166
+ files_with_i18n += 1
167
+
168
+ # Check for hardcoded strings
169
+ patterns = HARDCODED_PATTERNS.get(file_type, [])
170
+ hardcoded_found = False
171
+
172
+ for pattern in patterns:
173
+ matches = re.findall(pattern, content)
174
+ if matches and not has_i18n:
175
+ hardcoded_found = True
176
+ if len(hardcoded_examples) < 5:
177
+ hardcoded_examples.append(f"{file_path.name}: {str(matches[0])[:40]}...")
178
+
179
+ if hardcoded_found:
180
+ files_with_hardcoded += 1
181
+
182
+ except:
183
+ continue
184
+
185
+ passed.append(f"[OK] Analyzed {len(code_files)} code files")
186
+
187
+ if files_with_i18n > 0:
188
+ passed.append(f"[OK] {files_with_i18n} files use i18n")
189
+
190
+ if files_with_hardcoded > 0:
191
+ issues.append(f"[X] {files_with_hardcoded} files may have hardcoded strings")
192
+ for ex in hardcoded_examples:
193
+ issues.append(f" → {ex}")
194
+ else:
195
+ passed.append("[OK] No obvious hardcoded strings detected")
196
+
197
+ return {'passed': passed, 'issues': issues}
198
+
199
+ def main():
200
+ target = sys.argv[1] if len(sys.argv) > 1 else "."
201
+ project_path = Path(target)
202
+
203
+ print("\n" + "=" * 60)
204
+ print(" i18n CHECKER - Internationalization Audit")
205
+ print("=" * 60 + "\n")
206
+
207
+ # Check locale files
208
+ locale_files = find_locale_files(project_path)
209
+ locale_result = check_locale_completeness(locale_files)
210
+
211
+ # Check hardcoded strings
212
+ code_result = check_hardcoded_strings(project_path)
213
+
214
+ # Print results
215
+ print("[LOCALE FILES]")
216
+ print("-" * 40)
217
+ for item in locale_result['passed']:
218
+ print(f" {item}")
219
+ for item in locale_result['issues']:
220
+ print(f" {item}")
221
+
222
+ print("\n[CODE ANALYSIS]")
223
+ print("-" * 40)
224
+ for item in code_result['passed']:
225
+ print(f" {item}")
226
+ for item in code_result['issues']:
227
+ print(f" {item}")
228
+
229
+ # Summary
230
+ critical_issues = sum(1 for i in locale_result['issues'] + code_result['issues'] if i.startswith("[X]"))
231
+
232
+ print("\n" + "=" * 60)
233
+ if critical_issues == 0:
234
+ print("[OK] i18n CHECK: PASSED")
235
+ sys.exit(0)
236
+ else:
237
+ print(f"[X] i18n CHECK: {critical_issues} issues found")
238
+ sys.exit(1)
239
+
240
+ if __name__ == "__main__":
241
+ main()
@@ -0,0 +1,45 @@
1
+ ---
2
+ name: lint-and-validate
3
+ description: Automatic quality control, linting, and static analysis procedures. Use after every code modification to ensure syntax correctness and project standards. Triggers onKeywords: lint, format, check, validate, types, static analysis.
4
+ allowed-tools: Read, Glob, Grep, Bash
5
+ ---
6
+
7
+ # Lint and Validate Skill
8
+
9
+ > **MANDATORY:** Run appropriate validation tools after EVERY code change. Do not finish a task until the code is error-free.
10
+
11
+ ### Procedures by Ecosystem
12
+
13
+ #### Node.js / TypeScript
14
+ 1. **Lint/Fix:** `npm run lint` or `npx eslint "path" --fix`
15
+ 2. **Types:** `npx tsc --noEmit`
16
+ 3. **Security:** `npm audit --audit-level=high`
17
+
18
+ #### Python
19
+ 1. **Linter (Ruff):** `ruff check "path" --fix` (Fast & Modern)
20
+ 2. **Security (Bandit):** `bandit -r "path" -ll`
21
+ 3. **Types (MyPy):** `mypy "path"`
22
+
23
+ ## The Quality Loop
24
+ 1. **Write/Edit Code**
25
+ 2. **Run Audit:** `npm run lint && npx tsc --noEmit`
26
+ 3. **Analyze Report:** Check the "FINAL AUDIT REPORT" section.
27
+ 4. **Fix & Repeat:** Submitting code with "FINAL AUDIT" failures is NOT allowed.
28
+
29
+ ## Error Handling
30
+ - If `lint` fails: Fix the style or syntax issues immediately.
31
+ - If `tsc` fails: Correct type mismatches before proceeding.
32
+ - If no tool is configured: Check the project root for `.eslintrc`, `tsconfig.json`, `pyproject.toml` and suggest creating one.
33
+
34
+ ---
35
+ **Strict Rule:** No code should be committed or reported as "done" without passing these checks.
36
+
37
+ ---
38
+
39
+ ## Scripts
40
+
41
+ | Script | Purpose | Command |
42
+ |--------|---------|---------|
43
+ | `scripts/lint_runner.py` | Unified lint check | `python scripts/lint_runner.py <project_path>` |
44
+ | `scripts/type_coverage.py` | Type coverage analysis | `python scripts/type_coverage.py <project_path>` |
45
+
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Lint Runner - Unified linting and type checking
4
+ Runs appropriate linters based on project type.
5
+
6
+ Usage:
7
+ python lint_runner.py <project_path>
8
+
9
+ Supports:
10
+ - Node.js: npm run lint, npx tsc --noEmit
11
+ - Python: ruff check, mypy
12
+ """
13
+
14
+ import subprocess
15
+ import sys
16
+ import json
17
+ from pathlib import Path
18
+ from datetime import datetime
19
+
20
+ # Fix Windows console encoding
21
+ try:
22
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
23
+ except:
24
+ pass
25
+
26
+
27
+ def detect_project_type(project_path: Path) -> dict:
28
+ """Detect project type and available linters."""
29
+ result = {
30
+ "type": "unknown",
31
+ "linters": []
32
+ }
33
+
34
+ # Node.js project
35
+ package_json = project_path / "package.json"
36
+ if package_json.exists():
37
+ result["type"] = "node"
38
+ try:
39
+ pkg = json.loads(package_json.read_text(encoding='utf-8'))
40
+ scripts = pkg.get("scripts", {})
41
+ deps = {**pkg.get("dependencies", {}), **pkg.get("devDependencies", {})}
42
+
43
+ # Check for lint script
44
+ if "lint" in scripts:
45
+ result["linters"].append({"name": "npm lint", "cmd": ["npm", "run", "lint"]})
46
+ elif "eslint" in deps:
47
+ result["linters"].append({"name": "eslint", "cmd": ["npx", "eslint", "."]})
48
+
49
+ # Check for TypeScript
50
+ if "typescript" in deps or (project_path / "tsconfig.json").exists():
51
+ result["linters"].append({"name": "tsc", "cmd": ["npx", "tsc", "--noEmit"]})
52
+
53
+ except:
54
+ pass
55
+
56
+ # Python project
57
+ if (project_path / "pyproject.toml").exists() or (project_path / "requirements.txt").exists():
58
+ result["type"] = "python"
59
+
60
+ # Check for ruff
61
+ result["linters"].append({"name": "ruff", "cmd": ["ruff", "check", "."]})
62
+
63
+ # Check for mypy
64
+ if (project_path / "mypy.ini").exists() or (project_path / "pyproject.toml").exists():
65
+ result["linters"].append({"name": "mypy", "cmd": ["mypy", "."]})
66
+
67
+ return result
68
+
69
+
70
+ def run_linter(linter: dict, cwd: Path) -> dict:
71
+ """Run a single linter and return results."""
72
+ result = {
73
+ "name": linter["name"],
74
+ "passed": False,
75
+ "output": "",
76
+ "error": ""
77
+ }
78
+
79
+ try:
80
+ proc = subprocess.run(
81
+ linter["cmd"],
82
+ cwd=str(cwd),
83
+ capture_output=True,
84
+ text=True,
85
+ encoding='utf-8',
86
+ errors='replace',
87
+ timeout=120
88
+ )
89
+
90
+ result["output"] = proc.stdout[:2000] if proc.stdout else ""
91
+ result["error"] = proc.stderr[:500] if proc.stderr else ""
92
+ result["passed"] = proc.returncode == 0
93
+
94
+ except FileNotFoundError:
95
+ result["error"] = f"Command not found: {linter['cmd'][0]}"
96
+ except subprocess.TimeoutExpired:
97
+ result["error"] = "Timeout after 120s"
98
+ except Exception as e:
99
+ result["error"] = str(e)
100
+
101
+ return result
102
+
103
+
104
+ def main():
105
+ project_path = Path(sys.argv[1] if len(sys.argv) > 1 else ".").resolve()
106
+
107
+ print(f"\n{'='*60}")
108
+ print(f"[LINT RUNNER] Unified Linting")
109
+ print(f"{'='*60}")
110
+ print(f"Project: {project_path}")
111
+ print(f"Time: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
112
+
113
+ # Detect project type
114
+ project_info = detect_project_type(project_path)
115
+ print(f"Type: {project_info['type']}")
116
+ print(f"Linters: {len(project_info['linters'])}")
117
+ print("-"*60)
118
+
119
+ if not project_info["linters"]:
120
+ print("No linters found for this project type.")
121
+ output = {
122
+ "script": "lint_runner",
123
+ "project": str(project_path),
124
+ "type": project_info["type"],
125
+ "checks": [],
126
+ "passed": True,
127
+ "message": "No linters configured"
128
+ }
129
+ print(json.dumps(output, indent=2))
130
+ sys.exit(0)
131
+
132
+ # Run each linter
133
+ results = []
134
+ all_passed = True
135
+
136
+ for linter in project_info["linters"]:
137
+ print(f"\nRunning: {linter['name']}...")
138
+ result = run_linter(linter, project_path)
139
+ results.append(result)
140
+
141
+ if result["passed"]:
142
+ print(f" [PASS] {linter['name']}")
143
+ else:
144
+ print(f" [FAIL] {linter['name']}")
145
+ if result["error"]:
146
+ print(f" Error: {result['error'][:200]}")
147
+ all_passed = False
148
+
149
+ # Summary
150
+ print("\n" + "="*60)
151
+ print("SUMMARY")
152
+ print("="*60)
153
+
154
+ for r in results:
155
+ icon = "[PASS]" if r["passed"] else "[FAIL]"
156
+ print(f"{icon} {r['name']}")
157
+
158
+ output = {
159
+ "script": "lint_runner",
160
+ "project": str(project_path),
161
+ "type": project_info["type"],
162
+ "checks": results,
163
+ "passed": all_passed
164
+ }
165
+
166
+ print("\n" + json.dumps(output, indent=2))
167
+
168
+ sys.exit(0 if all_passed else 1)
169
+
170
+
171
+ if __name__ == "__main__":
172
+ main()
@@ -0,0 +1,173 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Type Coverage Checker - Measures TypeScript/Python type coverage.
4
+ Identifies untyped functions, any usage, and type safety issues.
5
+ """
6
+ import sys
7
+ import re
8
+ import subprocess
9
+ from pathlib import Path
10
+
11
+ # Fix Windows console encoding for Unicode output
12
+ try:
13
+ sys.stdout.reconfigure(encoding='utf-8', errors='replace')
14
+ sys.stderr.reconfigure(encoding='utf-8', errors='replace')
15
+ except AttributeError:
16
+ pass # Python < 3.7
17
+
18
+ def check_typescript_coverage(project_path: Path) -> dict:
19
+ """Check TypeScript type coverage."""
20
+ issues = []
21
+ passed = []
22
+ stats = {'any_count': 0, 'untyped_functions': 0, 'total_functions': 0}
23
+
24
+ ts_files = list(project_path.rglob("*.ts")) + list(project_path.rglob("*.tsx"))
25
+ ts_files = [f for f in ts_files if 'node_modules' not in str(f) and '.d.ts' not in str(f)]
26
+
27
+ if not ts_files:
28
+ return {'type': 'typescript', 'files': 0, 'passed': [], 'issues': ["[!] No TypeScript files found"], 'stats': stats}
29
+
30
+ for file_path in ts_files[:30]: # Limit
31
+ try:
32
+ content = file_path.read_text(encoding='utf-8', errors='ignore')
33
+
34
+ # Count 'any' usage
35
+ any_matches = re.findall(r':\s*any\b', content)
36
+ stats['any_count'] += len(any_matches)
37
+
38
+ # Find functions without return types
39
+ # function name(params) { - no return type
40
+ untyped = re.findall(r'function\s+\w+\s*\([^)]*\)\s*{', content)
41
+ # Arrow functions without types: const fn = (x) => or (x) =>
42
+ untyped += re.findall(r'=\s*\([^:)]*\)\s*=>', content)
43
+ stats['untyped_functions'] += len(untyped)
44
+
45
+ # Count typed functions
46
+ typed = re.findall(r'function\s+\w+\s*\([^)]*\)\s*:\s*\w+', content)
47
+ typed += re.findall(r':\s*\([^)]*\)\s*=>\s*\w+', content)
48
+ stats['total_functions'] += len(typed) + len(untyped)
49
+
50
+ except Exception:
51
+ continue
52
+
53
+ # Analyze results
54
+ if stats['any_count'] == 0:
55
+ passed.append("[OK] No 'any' types found")
56
+ elif stats['any_count'] <= 5:
57
+ issues.append(f"[!] {stats['any_count']} 'any' types found (acceptable)")
58
+ else:
59
+ issues.append(f"[X] {stats['any_count']} 'any' types found (too many)")
60
+
61
+ if stats['total_functions'] > 0:
62
+ typed_ratio = (stats['total_functions'] - stats['untyped_functions']) / stats['total_functions'] * 100
63
+ if typed_ratio >= 80:
64
+ passed.append(f"[OK] Type coverage: {typed_ratio:.0f}%")
65
+ elif typed_ratio >= 50:
66
+ issues.append(f"[!] Type coverage: {typed_ratio:.0f}% (improve)")
67
+ else:
68
+ issues.append(f"[X] Type coverage: {typed_ratio:.0f}% (too low)")
69
+
70
+ passed.append(f"[OK] Analyzed {len(ts_files)} TypeScript files")
71
+
72
+ return {'type': 'typescript', 'files': len(ts_files), 'passed': passed, 'issues': issues, 'stats': stats}
73
+
74
+ def check_python_coverage(project_path: Path) -> dict:
75
+ """Check Python type hints coverage."""
76
+ issues = []
77
+ passed = []
78
+ stats = {'untyped_functions': 0, 'typed_functions': 0, 'any_count': 0}
79
+
80
+ py_files = list(project_path.rglob("*.py"))
81
+ py_files = [f for f in py_files if not any(x in str(f) for x in ['venv', '__pycache__', '.git', 'node_modules'])]
82
+
83
+ if not py_files:
84
+ return {'type': 'python', 'files': 0, 'passed': [], 'issues': ["[!] No Python files found"], 'stats': stats}
85
+
86
+ for file_path in py_files[:30]: # Limit
87
+ try:
88
+ content = file_path.read_text(encoding='utf-8', errors='ignore')
89
+
90
+ # Count Any usage
91
+ any_matches = re.findall(r':\s*Any\b', content)
92
+ stats['any_count'] += len(any_matches)
93
+
94
+ # Find functions with type hints
95
+ typed_funcs = re.findall(r'def\s+\w+\s*\([^)]*:[^)]+\)', content)
96
+ typed_funcs += re.findall(r'def\s+\w+\s*\([^)]*\)\s*->', content)
97
+ stats['typed_functions'] += len(typed_funcs)
98
+
99
+ # Find functions without type hints
100
+ all_funcs = re.findall(r'def\s+\w+\s*\(', content)
101
+ stats['untyped_functions'] += len(all_funcs) - len(typed_funcs)
102
+
103
+ except Exception:
104
+ continue
105
+
106
+ total = stats['typed_functions'] + stats['untyped_functions']
107
+
108
+ if total > 0:
109
+ typed_ratio = stats['typed_functions'] / total * 100
110
+ if typed_ratio >= 70:
111
+ passed.append(f"[OK] Type hints coverage: {typed_ratio:.0f}%")
112
+ elif typed_ratio >= 40:
113
+ issues.append(f"[!] Type hints coverage: {typed_ratio:.0f}%")
114
+ else:
115
+ issues.append(f"[X] Type hints coverage: {typed_ratio:.0f}% (add type hints)")
116
+
117
+ if stats['any_count'] == 0:
118
+ passed.append("[OK] No 'Any' types found")
119
+ elif stats['any_count'] <= 3:
120
+ issues.append(f"[!] {stats['any_count']} 'Any' types found")
121
+ else:
122
+ issues.append(f"[X] {stats['any_count']} 'Any' types found")
123
+
124
+ passed.append(f"[OK] Analyzed {len(py_files)} Python files")
125
+
126
+ return {'type': 'python', 'files': len(py_files), 'passed': passed, 'issues': issues, 'stats': stats}
127
+
128
+ def main():
129
+ target = sys.argv[1] if len(sys.argv) > 1 else "."
130
+ project_path = Path(target)
131
+
132
+ print("\n" + "=" * 60)
133
+ print(" TYPE COVERAGE CHECKER")
134
+ print("=" * 60 + "\n")
135
+
136
+ results = []
137
+
138
+ # Check TypeScript
139
+ ts_result = check_typescript_coverage(project_path)
140
+ if ts_result['files'] > 0:
141
+ results.append(ts_result)
142
+
143
+ # Check Python
144
+ py_result = check_python_coverage(project_path)
145
+ if py_result['files'] > 0:
146
+ results.append(py_result)
147
+
148
+ if not results:
149
+ print("[!] No TypeScript or Python files found.")
150
+ sys.exit(0)
151
+
152
+ # Print results
153
+ critical_issues = 0
154
+ for result in results:
155
+ print(f"\n[{result['type'].upper()}]")
156
+ print("-" * 40)
157
+ for item in result['passed']:
158
+ print(f" {item}")
159
+ for item in result['issues']:
160
+ print(f" {item}")
161
+ if item.startswith("[X]"):
162
+ critical_issues += 1
163
+
164
+ print("\n" + "=" * 60)
165
+ if critical_issues == 0:
166
+ print("[OK] TYPE COVERAGE: ACCEPTABLE")
167
+ sys.exit(0)
168
+ else:
169
+ print(f"[X] TYPE COVERAGE: {critical_issues} critical issues")
170
+ sys.exit(1)
171
+
172
+ if __name__ == "__main__":
173
+ main()