foliko 1.1.13 → 1.1.14
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/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +288 -0
- package/.agent/agents/ambient-agent.md +57 -0
- package/.agent/agents/debugger.md +55 -0
- package/.agent/agents/email-assistant.md +49 -0
- package/.agent/agents/file-manager.md +42 -0
- package/.agent/agents/poster-expert.md +135 -196
- package/.agent/agents/python-developer.md +60 -0
- package/.agent/agents/scheduler.md +59 -0
- package/.agent/agents/web-developer.md +45 -0
- package/.agent/data/default.json +404 -9
- package/.agent/data/plugins-state.json +172 -173
- package/.agent/data/puppeteer-sessions/undefined.json +6 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775618677512.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619073340.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619097536.jpg +0 -0
- package/.agent/data/weixin-media/2026-04-08/img_1775619209388.jpg +0 -0
- package/.agent/mcp_config.json +21 -0
- package/.agent/memory/feedback/mnygjgox-ualjip.md +11 -0
- package/.agent/memory/project/mnqx54u5-loqtoe.md +9 -0
- package/.agent/memory/project/mnqx84cv-mx6dmd.md +9 -0
- package/.agent/memory/project/mnsacuyr-hgtk5n.md +20 -0
- package/.agent/memory/project/mnu5hy2x-bjsg7u.md +9 -0
- package/.agent/memory/project/mny28ot4-8qe9au.md +9 -0
- package/.agent/memory/reference/mnre3cww-penbo1.md +9 -0
- package/.agent/memory/reference/mns9wn48-luerua.md +14 -0
- package/.agent/memory/reference/mns9yz5c-thc2s0.md +16 -0
- package/.agent/memory/reference/mnsfy4um-910f1o.md +23 -0
- package/.agent/memory/reference/mnsg37dp-lmfj18.md +32 -0
- package/.agent/memory/reference/mnsll60q-0j911u.md +36 -0
- package/.agent/memory/reference/mnsmlb5y-nej31u.md +16 -0
- package/.agent/memory/reference/mnssle72-yrot96.md +9 -0
- package/.agent/memory/reference/mnygj8nb-bjthmc.md +20 -0
- package/.agent/memory/user/mnsfuon6-l416q1.md +21 -0
- package/.agent/memory/user/mnsg9kut-95m7rf.md +20 -0
- package/.agent/memory/user/mnu2eo1v-yy6fhe.md +9 -0
- package/.agent/memory/user/mnu2etuo-8u8jk8.md +9 -0
- package/.agent/memory/user/mnx0rk6g-gsznjj.md +9 -0
- package/.agent/memory/user/mnyf1riz-4yo5yz.md +9 -0
- package/.agent/plugins/puppeteer-plugin/README.md +147 -0
- package/.agent/plugins/puppeteer-plugin/index.js +1422 -0
- package/.agent/plugins/puppeteer-plugin/package.json +9 -0
- package/.agent/plugins.json +5 -11
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/rules/allow-rule.md +77 -0
- package/.agent/rules/log-rule.md +83 -0
- package/.agent/rules/security-rule.md +93 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/sessions/cli_default.json +11 -641
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/poster-design/SKILL.md +385 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +81 -0
- package/.agent/workflows/simple-test.md +42 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/structured-orchestrate.md +180 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/.claude/settings.local.json +23 -1
- package/.env.example +56 -56
- package/README.md +441 -441
- package/cli/src/commands/chat.js +9 -15
- package/cli/src/ui/chat-ui.js +41 -71
- package/package.json +1 -1
- package/plugins/default-plugins.js +5 -5
- package/plugins/file-system-plugin.js +1 -1
- package/plugins/memory-plugin.js +12 -12
- package/plugins/plugin-manager-plugin.js +1 -0
- package/plugins/subagent-plugin.js +55 -1
- package/plugins/telegram-plugin.js +9 -6
- package/plugins/weixin-plugin.js +50 -34
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/src/core/agent-chat.js +460 -1612
- package/src/core/agent.js +53 -134
- package/src/core/chat-session.js +423 -0
- package/src/core/context-compressor.js +473 -0
- package/src/core/context-manager.js +0 -48
- package/src/core/framework.js +95 -68
- package/src/core/index.js +11 -0
- package/src/core/notification-manager.js +125 -0
- package/src/core/subagent.js +295 -0
- package/src/core/token-counter.js +190 -0
- package/src/core/tool-executor.js +270 -0
- package/src/executors/mcp-executor.js +14 -1
- package/system.md +312 -2373
- package/.agent/agents/code-assistant.json +0 -17
- package/.agent/agents/email-assistant.json +0 -14
- package/.agent/agents/file-assistant.json +0 -18
- package/.agent/agents/orchestrator-demo.md +0 -53
- package/.agent/agents/orchestrator.json +0 -7
- package/.agent/agents/system-assistant.json +0 -15
- package/.agent/agents/web-assistant.json +0 -12
- package/.agent/data/email/processed-emails.json +0 -1
- package/.agent/data/scheduler/tasks.json +0 -1
- package/.agent/data/web/web-config.json +0 -5
- package/.agent/memory/feedback/mnv3nu27-3o15pf.md +0 -9
- package/.agent/memory/feedback/mnv3o078-b959yj.md +0 -9
- package/.agent/memory/feedback/mnv3o6ej-u0fif5.md +0 -9
- package/.agent/memory/feedback/mnv3obgl-bkkjoj.md +0 -9
- package/.agent/memory/feedback/mnv4a3js-dv6onx.md +0 -9
- package/.agent/memory/feedback/mnv4aacm-sxxowp.md +0 -9
- package/.agent/memory/feedback/mnv4ahto-w40ffm.md +0 -9
- package/.agent/memory/feedback/mnv4anvp-3cs06y.md +0 -9
- package/.agent/memory/feedback/mnvzgvtd-0o2900.md +0 -9
- package/.agent/memory/feedback/mnvzhajn-swbx61.md +0 -15
- package/.agent/memory/feedback/mnvzhgsp-p5vog3.md +0 -9
- package/.agent/memory/feedback/mnvzho0c-fgql7q.md +0 -14
- package/.agent/memory/feedback/mnvzhtzq-ufr5at.md +0 -9
- package/.agent/memory/feedback/mnvzhyb3-9byq2z.md +0 -9
- package/.agent/memory/feedback/mnvzi7hp-hyeafp.md +0 -9
- package/.agent/memory/feedback/mnvzibph-z7rwp5.md +0 -9
- package/.agent/memory/feedback/mnvzilys-7h176w.md +0 -14
- package/.agent/memory/feedback/mnvziuh5-zjshci.md +0 -9
- package/.agent/memory/feedback/mnw07wde-6zqsc8.md +0 -9
- package/.agent/memory/feedback/mnw084bp-j0ba2a.md +0 -9
- package/.agent/memory/user/mnv3n62r-y0h79j.md +0 -21
- package/.agent/memory/user/mnv3n9yf-ead4g8.md +0 -13
- package/.agent/memory/user/mnv3ne3j-82tq1k.md +0 -19
- package/.agent/memory/user/mnv3nhgm-g2s2us.md +0 -11
- package/.agent/memory/user/mnv3nl9u-ejd998.md +0 -16
- package/.agent/memory/user/mnv3nofp-ya5szl.md +0 -10
- package/.agent/memory/user/mnv49qne-bhk0ki.md +0 -9
- package/.agent/memory/user/mnv49w3y-rzr8ju.md +0 -13
- package/.agent/package.json +0 -8
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +0 -89
- package/.agent/plugins/daytona/index.js +0 -377
- package/.agent/plugins/daytona/package.json +0 -12
- package/.agent/plugins/marknative/README.md +0 -134
- package/.agent/plugins/marknative/fonts/SegoeUI Emoji.ttf +0 -0
- package/.agent/plugins/marknative/fonts.zip +0 -0
- package/.agent/plugins/marknative/index.js +0 -256
- package/.agent/plugins/marknative/package.json +0 -12
- package/.agent/plugins/system-info/index.js +0 -387
- package/.agent/plugins/system-info/package.json +0 -4
- package/.agent/plugins/system-info/test.js +0 -40
- package/.agent/plugins/test-plugin.py +0 -123
- package/.agent/plugins/test_nested_plugin.py +0 -85
- package/.agent/python-scripts/test_sample.py +0 -24
- package/.agent/sessions/test.json +0 -16
- package/.agent/skills/agent-browser/SKILL.md +0 -311
- package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
- package/.agent/skills/sysinfo/SKILL.md +0 -38
- package/.agent/skills/sysinfo/system-info.sh +0 -130
- package/.agent/skills/workflow/SKILL.md +0 -324
- package/.agent/test-agent.js +0 -35
- package/.agent/weixin.json +0 -6
- package/.agent/workflows/email-digest.json +0 -50
- package/.agent/workflows/file-backup.json +0 -21
- package/.agent/workflows/get-ip-notify.json +0 -32
- package/.agent/workflows/news-aggregator.json +0 -93
- package/.agent/workflows/news-dashboard-v2.json +0 -94
- package/.agent/workflows/notification-batch.json +0 -32
- package/plugins/python-plugin-loader.js.bak +0 -856
- package/src/core/agent-context.js +0 -188
|
@@ -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,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mcp-builder
|
|
3
|
+
description: MCP (Model Context Protocol) server building principles. Tool design, resource patterns, best practices.
|
|
4
|
+
allowed-tools: Read, Write, Edit, Glob, Grep
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# MCP Builder
|
|
8
|
+
|
|
9
|
+
> Principles for building MCP servers.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## 1. MCP Overview
|
|
14
|
+
|
|
15
|
+
### What is MCP?
|
|
16
|
+
|
|
17
|
+
Model Context Protocol - standard for connecting AI systems with external tools and data sources.
|
|
18
|
+
|
|
19
|
+
### Core Concepts
|
|
20
|
+
|
|
21
|
+
| Concept | Purpose |
|
|
22
|
+
|---------|---------|
|
|
23
|
+
| **Tools** | Functions AI can call |
|
|
24
|
+
| **Resources** | Data AI can read |
|
|
25
|
+
| **Prompts** | Pre-defined prompt templates |
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. Server Architecture
|
|
30
|
+
|
|
31
|
+
### Project Structure
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
my-mcp-server/
|
|
35
|
+
├── src/
|
|
36
|
+
│ └── index.ts # Main entry
|
|
37
|
+
├── package.json
|
|
38
|
+
└── tsconfig.json
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Transport Types
|
|
42
|
+
|
|
43
|
+
| Type | Use |
|
|
44
|
+
|------|-----|
|
|
45
|
+
| **Stdio** | Local, CLI-based |
|
|
46
|
+
| **SSE** | Web-based, streaming |
|
|
47
|
+
| **WebSocket** | Real-time, bidirectional |
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## 3. Tool Design Principles
|
|
52
|
+
|
|
53
|
+
### Good Tool Design
|
|
54
|
+
|
|
55
|
+
| Principle | Description |
|
|
56
|
+
|-----------|-------------|
|
|
57
|
+
| Clear name | Action-oriented (get_weather, create_user) |
|
|
58
|
+
| Single purpose | One thing well |
|
|
59
|
+
| Validated input | Schema with types and descriptions |
|
|
60
|
+
| Structured output | Predictable response format |
|
|
61
|
+
|
|
62
|
+
### Input Schema Design
|
|
63
|
+
|
|
64
|
+
| Field | Required? |
|
|
65
|
+
|-------|-----------|
|
|
66
|
+
| Type | Yes - object |
|
|
67
|
+
| Properties | Define each param |
|
|
68
|
+
| Required | List mandatory params |
|
|
69
|
+
| Description | Human-readable |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## 4. Resource Patterns
|
|
74
|
+
|
|
75
|
+
### Resource Types
|
|
76
|
+
|
|
77
|
+
| Type | Use |
|
|
78
|
+
|------|-----|
|
|
79
|
+
| Static | Fixed data (config, docs) |
|
|
80
|
+
| Dynamic | Generated on request |
|
|
81
|
+
| Template | URI with parameters |
|
|
82
|
+
|
|
83
|
+
### URI Patterns
|
|
84
|
+
|
|
85
|
+
| Pattern | Example |
|
|
86
|
+
|---------|---------|
|
|
87
|
+
| Fixed | `docs://readme` |
|
|
88
|
+
| Parameterized | `users://{userId}` |
|
|
89
|
+
| Collection | `files://project/*` |
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
## 5. Error Handling
|
|
94
|
+
|
|
95
|
+
### Error Types
|
|
96
|
+
|
|
97
|
+
| Situation | Response |
|
|
98
|
+
|-----------|----------|
|
|
99
|
+
| Invalid params | Validation error message |
|
|
100
|
+
| Not found | Clear "not found" |
|
|
101
|
+
| Server error | Generic error, log details |
|
|
102
|
+
|
|
103
|
+
### Best Practices
|
|
104
|
+
|
|
105
|
+
- Return structured errors
|
|
106
|
+
- Don't expose internal details
|
|
107
|
+
- Log for debugging
|
|
108
|
+
- Provide actionable messages
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
## 6. Multimodal Handling
|
|
113
|
+
|
|
114
|
+
### Supported Types
|
|
115
|
+
|
|
116
|
+
| Type | Encoding |
|
|
117
|
+
|------|----------|
|
|
118
|
+
| Text | Plain text |
|
|
119
|
+
| Images | Base64 + MIME type |
|
|
120
|
+
| Files | Base64 + MIME type |
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## 7. Security Principles
|
|
125
|
+
|
|
126
|
+
### Input Validation
|
|
127
|
+
|
|
128
|
+
- Validate all tool inputs
|
|
129
|
+
- Sanitize user-provided data
|
|
130
|
+
- Limit resource access
|
|
131
|
+
|
|
132
|
+
### API Keys
|
|
133
|
+
|
|
134
|
+
- Use environment variables
|
|
135
|
+
- Don't log secrets
|
|
136
|
+
- Validate permissions
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 8. Configuration
|
|
141
|
+
|
|
142
|
+
### Claude Desktop Config
|
|
143
|
+
|
|
144
|
+
| Field | Purpose |
|
|
145
|
+
|-------|---------|
|
|
146
|
+
| command | Executable to run |
|
|
147
|
+
| args | Command arguments |
|
|
148
|
+
| env | Environment variables |
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 9. Testing
|
|
153
|
+
|
|
154
|
+
### Test Categories
|
|
155
|
+
|
|
156
|
+
| Type | Focus |
|
|
157
|
+
|------|-------|
|
|
158
|
+
| Unit | Tool logic |
|
|
159
|
+
| Integration | Full server |
|
|
160
|
+
| Contract | Schema validation |
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## 10. Best Practices Checklist
|
|
165
|
+
|
|
166
|
+
- [ ] Clear, action-oriented tool names
|
|
167
|
+
- [ ] Complete input schemas with descriptions
|
|
168
|
+
- [ ] Structured JSON output
|
|
169
|
+
- [ ] Error handling for all cases
|
|
170
|
+
- [ ] Input validation
|
|
171
|
+
- [ ] Environment-based configuration
|
|
172
|
+
- [ ] Logging for debugging
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
> **Remember:** MCP tools should be simple, focused, and well-documented. The AI relies on descriptions to use them correctly.
|