codymaster 4.4.4 → 4.5.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/CHANGELOG.md +33 -0
- package/README.md +29 -14
- package/commands/demo.md +1 -1
- package/dist/context-bus.js +70 -0
- package/dist/context-db.js +265 -0
- package/dist/continuity.js +12 -0
- package/dist/file-watcher.js +79 -0
- package/dist/index.js +152 -1
- package/dist/l0-indexer.js +158 -0
- package/dist/mcp-context-server.js +400 -0
- package/dist/migrate-json-to-sqlite.js +126 -0
- package/dist/skill-chain.js +19 -3
- package/dist/token-budget.js +108 -0
- package/dist/uri-resolver.js +203 -0
- package/package.json +7 -1
- package/skills/_shared/helpers.md +50 -14
- package/skills/cm-autopilot/SKILL.md +29 -0
- package/skills/cm-autopilot/scripts/autopilot.py +190 -0
- package/skills/cm-continuity/SKILL.md +90 -28
- package/skills/cm-quality-gate/SKILL.md +11 -1
- package/skills/cm-safe-deploy/SKILL.md +38 -2
- package/skills/cm-security-gate/SKILL.md +158 -34
- package/skills/cm-skill-chain/SKILL.md +47 -1
- package/skills/cm-start/SKILL.md +11 -2
- package/skills/cm-test-gate/SKILL.md +3 -0
- package/skills/boxme-git-config/SKILL.md +0 -56
- package/skills/boxme-local-dev/SKILL.md +0 -66
- package/skills/jobs-to-be-done/SKILL.md +0 -266
- package/skills/jobs-to-be-done/references/case-studies.md +0 -154
- package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
- package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
- package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
- package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
- package/skills/marketplace-report-crawler/SKILL.md +0 -176
- package/skills/marketplace-report-crawler/config/accounts.json +0 -41
- package/skills/marketplace-report-crawler/config/report-types.json +0 -422
- package/skills/marketplace-report-crawler/config/sessions.json +0 -3
- package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
- package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
- package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
- package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
- package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
- package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
- package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
- package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
- package/skills/medical-research/SKILL.md +0 -194
- package/skills/medical-research/scripts/evidence_checker.py +0 -288
- package/skills/mom-test/SKILL.md +0 -267
- package/skills/mom-test/references/avoiding-bad-data.md +0 -221
- package/skills/mom-test/references/case-studies.md +0 -306
- package/skills/mom-test/references/commitment-advancement.md +0 -219
- package/skills/mom-test/references/finding-conversations.md +0 -251
- package/skills/mom-test/references/processing-learning.md +0 -256
- package/skills/mom-test/references/question-patterns.md +0 -198
- package/skills/pandasai-analytics/SKILL.md +0 -251
- package/skills/release-it/SKILL.md +0 -235
- package/skills/release-it/references/anti-patterns.md +0 -279
- package/skills/release-it/references/capacity-planning.md +0 -285
- package/skills/release-it/references/chaos-engineering.md +0 -325
- package/skills/release-it/references/deployment-strategies.md +0 -331
- package/skills/release-it/references/observability.md +0 -301
- package/skills/release-it/references/stability-patterns.md +0 -355
- package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
- package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
- package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
- package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
- package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
- package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
- package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
- package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
- package/skills/skill-creator-ultra/README.md +0 -1242
- package/skills/skill-creator-ultra/SKILL.md +0 -388
- package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
- package/skills/skill-creator-ultra/agents/comparator.md +0 -202
- package/skills/skill-creator-ultra/agents/grader.md +0 -223
- package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
- package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
- package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
- package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
- package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
- package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
- package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
- package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
- package/skills/skill-creator-ultra/install.ps1 +0 -289
- package/skills/skill-creator-ultra/install.sh +0 -313
- package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
- package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
- package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
- package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
- package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
- package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
- package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
- package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
- package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
- package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
- package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
- package/skills/skill-creator-ultra/resources/checklist.md +0 -243
- package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
- package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
- package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
- package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
- package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
- package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
- package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
- package/skills/skill-creator-ultra/resources/schemas.md +0 -430
- package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
- package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
- package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
- package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
- package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
- package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
- package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
- package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
- package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
- package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
- package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
- package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
- package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
- package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
- package/skills/tailwind-mastery/SKILL.md +0 -229
- package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
- package/skills/vercel-react-best-practices/README.md +0 -123
- package/skills/vercel-react-best-practices/SKILL.md +0 -143
- package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
- package/skills/vercel-react-best-practices/rules/_template.md +0 -28
- package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
- package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
- package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
- package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
- package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
- package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
- package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
- package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
- package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
- package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
- package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
- package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
- package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
- package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
- package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/skills/web-design-guidelines/SKILL.md +0 -39
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
skill_stats.py — Phân tích thống kê nhanh cho SKILL.md
|
|
4
|
-
|
|
5
|
-
Sử dụng:
|
|
6
|
-
python skill_stats.py /path/to/SKILL.md
|
|
7
|
-
python skill_stats.py /path/to/skill-folder/
|
|
8
|
-
python skill_stats.py /path/to/skill-folder/ --json
|
|
9
|
-
|
|
10
|
-
Hiển thị:
|
|
11
|
-
- Tổng dòng, từ, ký tự
|
|
12
|
-
- Số sections, steps, examples, constraints
|
|
13
|
-
- Cognitive Load Score (ước tính)
|
|
14
|
-
- Tỷ lệ phân bổ nội dung (Instructions vs Examples vs Constraints)
|
|
15
|
-
- Cảnh báo nếu quá dài/ngắn
|
|
16
|
-
|
|
17
|
-
Developed by Thân Công Hải — Skill Generator v3.2 Expert
|
|
18
|
-
"""
|
|
19
|
-
|
|
20
|
-
import sys
|
|
21
|
-
import os
|
|
22
|
-
import re
|
|
23
|
-
import json
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
# ============================================================
|
|
27
|
-
# COLOR OUTPUT
|
|
28
|
-
# ============================================================
|
|
29
|
-
|
|
30
|
-
class Colors:
|
|
31
|
-
PASS = '\033[92m'
|
|
32
|
-
FAIL = '\033[91m'
|
|
33
|
-
WARN = '\033[93m'
|
|
34
|
-
INFO = '\033[96m'
|
|
35
|
-
BOLD = '\033[1m'
|
|
36
|
-
DIM = '\033[2m'
|
|
37
|
-
RESET = '\033[0m'
|
|
38
|
-
|
|
39
|
-
@staticmethod
|
|
40
|
-
def enable_windows():
|
|
41
|
-
if os.name == 'nt':
|
|
42
|
-
try:
|
|
43
|
-
import ctypes
|
|
44
|
-
kernel32 = ctypes.windll.kernel32
|
|
45
|
-
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
46
|
-
except Exception:
|
|
47
|
-
pass
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
Colors.enable_windows()
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
def parse_frontmatter(content):
|
|
54
|
-
"""Trích xuất YAML frontmatter."""
|
|
55
|
-
match = re.match(r'^---\s*\n(.*?)\n---\s*\n', content, re.DOTALL)
|
|
56
|
-
if not match:
|
|
57
|
-
return {}, content
|
|
58
|
-
fm_text = match.group(1)
|
|
59
|
-
body = content[match.end():]
|
|
60
|
-
frontmatter = {}
|
|
61
|
-
current_key = None
|
|
62
|
-
current_value = []
|
|
63
|
-
for line in fm_text.split('\n'):
|
|
64
|
-
key_match = re.match(r'^(\w+):\s*(.*)', line)
|
|
65
|
-
if key_match:
|
|
66
|
-
if current_key:
|
|
67
|
-
frontmatter[current_key] = '\n'.join(current_value).strip()
|
|
68
|
-
current_key = key_match.group(1)
|
|
69
|
-
current_value = [key_match.group(2)] if key_match.group(2) and key_match.group(2) != '|' else []
|
|
70
|
-
elif current_key and line.startswith(' '):
|
|
71
|
-
current_value.append(line.strip())
|
|
72
|
-
if current_key:
|
|
73
|
-
frontmatter[current_key] = '\n'.join(current_value).strip()
|
|
74
|
-
return frontmatter, body
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def find_sections_with_sizes(body):
|
|
78
|
-
"""Tìm sections và tính kích thước mỗi section. Bỏ qua headings trong code blocks."""
|
|
79
|
-
sections = []
|
|
80
|
-
current_section = None
|
|
81
|
-
current_lines = 0
|
|
82
|
-
in_code_block = False
|
|
83
|
-
|
|
84
|
-
for line in body.split('\n'):
|
|
85
|
-
stripped = line.strip()
|
|
86
|
-
|
|
87
|
-
# Phát hiện code block
|
|
88
|
-
if stripped.startswith('```'):
|
|
89
|
-
in_code_block = not in_code_block
|
|
90
|
-
current_lines += 1
|
|
91
|
-
continue
|
|
92
|
-
|
|
93
|
-
# Bỏ qua headings trong code block
|
|
94
|
-
if in_code_block:
|
|
95
|
-
current_lines += 1
|
|
96
|
-
continue
|
|
97
|
-
|
|
98
|
-
h1_match = re.match(r'^#\s+(.+)', line)
|
|
99
|
-
if h1_match:
|
|
100
|
-
if current_section:
|
|
101
|
-
sections.append((current_section, current_lines))
|
|
102
|
-
current_section = h1_match.group(1).strip()
|
|
103
|
-
current_lines = 0
|
|
104
|
-
else:
|
|
105
|
-
current_lines += 1
|
|
106
|
-
|
|
107
|
-
if current_section:
|
|
108
|
-
sections.append((current_section, current_lines))
|
|
109
|
-
|
|
110
|
-
return sections
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
# ============================================================
|
|
114
|
-
# COGNITIVE LOAD CALCULATOR
|
|
115
|
-
# ============================================================
|
|
116
|
-
|
|
117
|
-
def calculate_cognitive_load(body):
|
|
118
|
-
"""
|
|
119
|
-
Tính Cognitive Load Score.
|
|
120
|
-
Budget tối đa: 100 điểm
|
|
121
|
-
- Steps: mỗi step = 3 điểm (tối đa 30)
|
|
122
|
-
- Constraints: mỗi constraint = 2 điểm (tối đa 20)
|
|
123
|
-
- Examples: mỗi ví dụ = 5 điểm (tối đa 25)
|
|
124
|
-
- Conditions: mỗi if/nếu = 2 điểm (tối đa 25)
|
|
125
|
-
"""
|
|
126
|
-
steps = len(re.findall(r'^\d+\.', body, re.MULTILINE))
|
|
127
|
-
constraints = len(re.findall(r'(KHÔNG ĐƯỢC|LUÔN LUÔN|🚫|✅)', body))
|
|
128
|
-
examples = len(re.findall(r'^##\s+.*[Vv]í dụ|^##\s+.*[Ee]xample|^###\s+.*[Vv]í dụ', body, re.MULTILINE))
|
|
129
|
-
conditions = len(re.findall(r'\b(nếu|if |khi |when )\b', body, re.IGNORECASE))
|
|
130
|
-
|
|
131
|
-
load = {
|
|
132
|
-
'steps': min(steps * 3, 30),
|
|
133
|
-
'constraints': min(constraints * 2, 20),
|
|
134
|
-
'examples': min(examples * 5, 25),
|
|
135
|
-
'conditions': min(conditions * 2, 25),
|
|
136
|
-
}
|
|
137
|
-
load['total'] = sum(load.values())
|
|
138
|
-
load['raw'] = {'steps': steps, 'constraints': constraints, 'examples': examples, 'conditions': conditions}
|
|
139
|
-
|
|
140
|
-
return load
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
# ============================================================
|
|
144
|
-
# MAIN
|
|
145
|
-
# ============================================================
|
|
146
|
-
|
|
147
|
-
def analyze_skill(target_path, json_output=False):
|
|
148
|
-
"""Phân tích thống kê skill."""
|
|
149
|
-
|
|
150
|
-
if os.path.isdir(target_path):
|
|
151
|
-
skill_md = os.path.join(target_path, 'SKILL.md')
|
|
152
|
-
skill_dir = target_path
|
|
153
|
-
else:
|
|
154
|
-
skill_md = target_path
|
|
155
|
-
skill_dir = os.path.dirname(target_path)
|
|
156
|
-
|
|
157
|
-
if not os.path.exists(skill_md):
|
|
158
|
-
print(f"{Colors.FAIL}❌ Không tìm thấy SKILL.md tại: {skill_md}{Colors.RESET}")
|
|
159
|
-
return False
|
|
160
|
-
|
|
161
|
-
with open(skill_md, 'r', encoding='utf-8') as f:
|
|
162
|
-
content = f.read()
|
|
163
|
-
|
|
164
|
-
frontmatter, body = parse_frontmatter(content)
|
|
165
|
-
name = frontmatter.get('name', 'unknown')
|
|
166
|
-
|
|
167
|
-
# Basic stats
|
|
168
|
-
lines = content.count('\n') + 1
|
|
169
|
-
words = len(content.split())
|
|
170
|
-
chars = len(content)
|
|
171
|
-
|
|
172
|
-
# Section analysis
|
|
173
|
-
sections = find_sections_with_sizes(body)
|
|
174
|
-
h1_count = len(sections)
|
|
175
|
-
h2_count = len(re.findall(r'^##\s+', body, re.MULTILINE))
|
|
176
|
-
h3_count = len(re.findall(r'^###\s+', body, re.MULTILINE))
|
|
177
|
-
|
|
178
|
-
# Content counts
|
|
179
|
-
steps = len(re.findall(r'^\d+\.', body, re.MULTILINE))
|
|
180
|
-
examples = len(re.findall(r'^##\s+.*[Vv]í dụ|^##\s+.*[Ee]xample|^###\s+.*[Vv]í dụ', body, re.MULTILINE))
|
|
181
|
-
constraints_positive = len(re.findall(r'(LUÔN LUÔN|✅)', body))
|
|
182
|
-
constraints_negative = len(re.findall(r'(KHÔNG ĐƯỢC|🚫)', body))
|
|
183
|
-
code_blocks = len(re.findall(r'```', body)) // 2
|
|
184
|
-
tables = len(re.findall(r'^\|', body, re.MULTILINE))
|
|
185
|
-
links = len(re.findall(r'\[.*?\]\(.*?\)', body))
|
|
186
|
-
|
|
187
|
-
# Cognitive Load
|
|
188
|
-
cognitive = calculate_cognitive_load(body)
|
|
189
|
-
|
|
190
|
-
# Directory stats
|
|
191
|
-
dir_files = 0
|
|
192
|
-
dir_scripts = 0
|
|
193
|
-
dir_resources = 0
|
|
194
|
-
dir_examples = 0
|
|
195
|
-
|
|
196
|
-
if os.path.isdir(skill_dir):
|
|
197
|
-
for root, dirs, files in os.walk(skill_dir):
|
|
198
|
-
for f in files:
|
|
199
|
-
dir_files += 1
|
|
200
|
-
rel = os.path.relpath(root, skill_dir)
|
|
201
|
-
if rel.startswith('scripts'):
|
|
202
|
-
dir_scripts += 1
|
|
203
|
-
elif rel.startswith('resources'):
|
|
204
|
-
dir_resources += 1
|
|
205
|
-
elif rel.startswith('examples'):
|
|
206
|
-
dir_examples += 1
|
|
207
|
-
|
|
208
|
-
# JSON output
|
|
209
|
-
if json_output:
|
|
210
|
-
output = {
|
|
211
|
-
'name': name,
|
|
212
|
-
'file': skill_md,
|
|
213
|
-
'basic': {'lines': lines, 'words': words, 'chars': chars},
|
|
214
|
-
'structure': {
|
|
215
|
-
'h1_sections': h1_count, 'h2_sections': h2_count, 'h3_sections': h3_count,
|
|
216
|
-
'steps': steps, 'examples': examples,
|
|
217
|
-
'constraints_positive': constraints_positive,
|
|
218
|
-
'constraints_negative': constraints_negative,
|
|
219
|
-
'code_blocks': code_blocks, 'tables': tables, 'links': links,
|
|
220
|
-
},
|
|
221
|
-
'cognitive_load': cognitive,
|
|
222
|
-
'directory': {
|
|
223
|
-
'total_files': dir_files, 'scripts': dir_scripts,
|
|
224
|
-
'resources': dir_resources, 'examples': dir_examples,
|
|
225
|
-
},
|
|
226
|
-
'sections': [{'name': s[0], 'lines': s[1]} for s in sections],
|
|
227
|
-
}
|
|
228
|
-
print(json.dumps(output, ensure_ascii=False, indent=2))
|
|
229
|
-
return True
|
|
230
|
-
|
|
231
|
-
# Pretty output
|
|
232
|
-
print()
|
|
233
|
-
print(f"{Colors.BOLD}{'=' * 55}{Colors.RESET}")
|
|
234
|
-
print(f"{Colors.BOLD} 📊 SKILL STATS — Phân tích thống kê{Colors.RESET}")
|
|
235
|
-
print(f"{Colors.BOLD} Skill: {Colors.INFO}{name}{Colors.RESET}")
|
|
236
|
-
print(f"{Colors.BOLD}{'=' * 55}{Colors.RESET}")
|
|
237
|
-
print()
|
|
238
|
-
|
|
239
|
-
# Basic
|
|
240
|
-
print(f" {Colors.BOLD}📏 Kích thước:{Colors.RESET}")
|
|
241
|
-
print(f" Dòng: {Colors.INFO}{lines:,}{Colors.RESET}")
|
|
242
|
-
print(f" Từ: {Colors.INFO}{words:,}{Colors.RESET}")
|
|
243
|
-
print(f" Ký tự: {Colors.INFO}{chars:,}{Colors.RESET}")
|
|
244
|
-
print()
|
|
245
|
-
|
|
246
|
-
# Structure
|
|
247
|
-
print(f" {Colors.BOLD}🏗️ Cấu trúc:{Colors.RESET}")
|
|
248
|
-
print(f" Sections (H1): {h1_count}")
|
|
249
|
-
print(f" Sub-sections: {h2_count} (H2) + {h3_count} (H3)")
|
|
250
|
-
print(f" Steps: {steps}")
|
|
251
|
-
print(f" Examples: {examples}")
|
|
252
|
-
print(f" Constraints: ✅ {constraints_positive} (DO) + 🚫 {constraints_negative} (DON'T)")
|
|
253
|
-
print(f" Code blocks: {code_blocks}")
|
|
254
|
-
print(f" Tables: {tables // 2 if tables > 0 else 0}")
|
|
255
|
-
print(f" Links: {links}")
|
|
256
|
-
print()
|
|
257
|
-
|
|
258
|
-
# Cognitive Load
|
|
259
|
-
cl = cognitive
|
|
260
|
-
if cl['total'] <= 50:
|
|
261
|
-
cl_color = Colors.PASS
|
|
262
|
-
cl_status = '🟢 Nhẹ'
|
|
263
|
-
elif cl['total'] <= 75:
|
|
264
|
-
cl_color = Colors.WARN
|
|
265
|
-
cl_status = '🟡 Trung bình'
|
|
266
|
-
else:
|
|
267
|
-
cl_color = Colors.FAIL
|
|
268
|
-
cl_status = '🔴 Nặng'
|
|
269
|
-
|
|
270
|
-
print(f" {Colors.BOLD}🧠 Cognitive Load:{Colors.RESET}")
|
|
271
|
-
print(f" Score: {cl_color}{cl['total']}/100 — {cl_status}{Colors.RESET}")
|
|
272
|
-
print(f" Steps: {cl['raw']['steps']} × 3đ = {cl['steps']}/30")
|
|
273
|
-
print(f" Constraints: {cl['raw']['constraints']} × 2đ = {cl['constraints']}/20")
|
|
274
|
-
print(f" Examples: {cl['raw']['examples']} × 5đ = {cl['examples']}/25")
|
|
275
|
-
print(f" Conditions: {cl['raw']['conditions']} × 2đ = {cl['conditions']}/25")
|
|
276
|
-
print()
|
|
277
|
-
|
|
278
|
-
# Section breakdown
|
|
279
|
-
if sections:
|
|
280
|
-
print(f" {Colors.BOLD}📋 Phân bổ nội dung:{Colors.RESET}")
|
|
281
|
-
total_lines = sum(s[1] for s in sections)
|
|
282
|
-
for section_name, section_lines in sections:
|
|
283
|
-
pct = round(section_lines / total_lines * 100) if total_lines > 0 else 0
|
|
284
|
-
bar = '█' * (pct // 5) + '░' * (20 - pct // 5)
|
|
285
|
-
print(f" {section_name[:25]:<25} {bar} {pct}% ({section_lines} dòng)")
|
|
286
|
-
print()
|
|
287
|
-
|
|
288
|
-
# Directory
|
|
289
|
-
if dir_files > 1:
|
|
290
|
-
print(f" {Colors.BOLD}📁 Thư mục:{Colors.RESET}")
|
|
291
|
-
print(f" Tổng files: {dir_files}")
|
|
292
|
-
print(f" Scripts: {dir_scripts}")
|
|
293
|
-
print(f" Resources: {dir_resources}")
|
|
294
|
-
print(f" Examples: {dir_examples}")
|
|
295
|
-
print()
|
|
296
|
-
|
|
297
|
-
# Warnings
|
|
298
|
-
warnings = []
|
|
299
|
-
if lines < 50:
|
|
300
|
-
warnings.append('Skill quá ngắn (<50 dòng) — có thể thiếu chi tiết')
|
|
301
|
-
if lines > 2000:
|
|
302
|
-
warnings.append('Skill quá dài (>2000 dòng) — cân nhắc tách hoặc dùng resources/')
|
|
303
|
-
if examples == 0:
|
|
304
|
-
warnings.append('KHÔNG có ví dụ — thêm ≥2 ví dụ!')
|
|
305
|
-
if steps == 0:
|
|
306
|
-
warnings.append('KHÔNG có steps đánh số — Instructions nên có bước rõ ràng')
|
|
307
|
-
if constraints_positive + constraints_negative == 0:
|
|
308
|
-
warnings.append('KHÔNG có constraints — thêm quy tắc DOs/DON\'Ts!')
|
|
309
|
-
if cl['total'] > 80:
|
|
310
|
-
warnings.append(f'Cognitive Load cao ({cl["total"]}/100) — AI có thể bị overload')
|
|
311
|
-
|
|
312
|
-
if warnings:
|
|
313
|
-
print(f" {Colors.WARN}⚠️ Cảnh báo:{Colors.RESET}")
|
|
314
|
-
for w in warnings:
|
|
315
|
-
print(f" → {w}")
|
|
316
|
-
print()
|
|
317
|
-
|
|
318
|
-
print(f"{Colors.BOLD}{'=' * 55}{Colors.RESET}")
|
|
319
|
-
print()
|
|
320
|
-
return True
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
if __name__ == '__main__':
|
|
324
|
-
if len(sys.argv) < 2:
|
|
325
|
-
print("Sử dụng: python skill_stats.py <path-to-SKILL.md-or-skill-folder>")
|
|
326
|
-
print("Options:")
|
|
327
|
-
print(" --json Output dạng JSON")
|
|
328
|
-
print()
|
|
329
|
-
print("Ví dụ: python skill_stats.py ./my-skill/")
|
|
330
|
-
sys.exit(1)
|
|
331
|
-
|
|
332
|
-
target = sys.argv[1]
|
|
333
|
-
json_mode = '--json' in sys.argv
|
|
334
|
-
|
|
335
|
-
if not os.path.exists(target):
|
|
336
|
-
print(f"❌ Không tìm thấy: {target}")
|
|
337
|
-
sys.exit(1)
|
|
338
|
-
|
|
339
|
-
analyze_skill(target, json_output=json_mode)
|