codymaster 4.4.5 → 4.5.2

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.
Files changed (197) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +29 -14
  3. package/commands/demo.md +1 -1
  4. package/dist/context-bus.js +70 -0
  5. package/dist/context-db.js +265 -0
  6. package/dist/continuity.js +12 -0
  7. package/dist/file-watcher.js +79 -0
  8. package/dist/index.js +152 -1
  9. package/dist/l0-indexer.js +158 -0
  10. package/dist/mcp-context-server.js +400 -0
  11. package/dist/migrate-json-to-sqlite.js +126 -0
  12. package/dist/skill-chain.js +19 -3
  13. package/dist/token-budget.js +108 -0
  14. package/dist/uri-resolver.js +203 -0
  15. package/package.json +5 -1
  16. package/scripts/gate-0-secrets.js +63 -0
  17. package/scripts/gate-1-syntax.js +53 -0
  18. package/scripts/gate-5-dist-verify.js +55 -0
  19. package/scripts/gate-6-smoke-test.js +30 -0
  20. package/scripts/index-codebase.sh +552 -0
  21. package/scripts/mcp-bridge.js +284 -0
  22. package/scripts/postinstall.js +301 -0
  23. package/scripts/security-fixer.js +143 -0
  24. package/scripts/security-scan.js +55 -0
  25. package/scripts/test-gemini.js +13 -0
  26. package/scripts/todo-bridge.js +112 -0
  27. package/skills/_shared/helpers.md +50 -14
  28. package/skills/cm-autopilot/SKILL.md +29 -0
  29. package/skills/cm-autopilot/scripts/autopilot.py +190 -0
  30. package/skills/cm-continuity/SKILL.md +90 -28
  31. package/skills/cm-skill-chain/SKILL.md +47 -1
  32. package/skills/cm-start/SKILL.md +11 -2
  33. package/skills/boxme-git-config/SKILL.md +0 -56
  34. package/skills/boxme-local-dev/SKILL.md +0 -66
  35. package/skills/jobs-to-be-done/SKILL.md +0 -266
  36. package/skills/jobs-to-be-done/references/case-studies.md +0 -154
  37. package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
  38. package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
  39. package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
  40. package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
  41. package/skills/marketplace-report-crawler/SKILL.md +0 -176
  42. package/skills/marketplace-report-crawler/config/accounts.json +0 -41
  43. package/skills/marketplace-report-crawler/config/report-types.json +0 -422
  44. package/skills/marketplace-report-crawler/config/sessions.json +0 -3
  45. package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
  46. package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
  47. package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
  48. package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
  49. package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
  50. package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
  51. package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
  52. package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
  53. package/skills/medical-research/SKILL.md +0 -194
  54. package/skills/medical-research/scripts/evidence_checker.py +0 -288
  55. package/skills/mom-test/SKILL.md +0 -267
  56. package/skills/mom-test/references/avoiding-bad-data.md +0 -221
  57. package/skills/mom-test/references/case-studies.md +0 -306
  58. package/skills/mom-test/references/commitment-advancement.md +0 -219
  59. package/skills/mom-test/references/finding-conversations.md +0 -251
  60. package/skills/mom-test/references/processing-learning.md +0 -256
  61. package/skills/mom-test/references/question-patterns.md +0 -198
  62. package/skills/pandasai-analytics/SKILL.md +0 -251
  63. package/skills/release-it/SKILL.md +0 -235
  64. package/skills/release-it/references/anti-patterns.md +0 -279
  65. package/skills/release-it/references/capacity-planning.md +0 -285
  66. package/skills/release-it/references/chaos-engineering.md +0 -325
  67. package/skills/release-it/references/deployment-strategies.md +0 -331
  68. package/skills/release-it/references/observability.md +0 -301
  69. package/skills/release-it/references/stability-patterns.md +0 -355
  70. package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
  71. package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
  72. package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
  73. package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
  74. package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
  75. package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
  76. package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
  77. package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
  78. package/skills/skill-creator-ultra/README.md +0 -1242
  79. package/skills/skill-creator-ultra/SKILL.md +0 -388
  80. package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
  81. package/skills/skill-creator-ultra/agents/comparator.md +0 -202
  82. package/skills/skill-creator-ultra/agents/grader.md +0 -223
  83. package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
  84. package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
  85. package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
  86. package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
  87. package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
  88. package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
  89. package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
  90. package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
  91. package/skills/skill-creator-ultra/install.ps1 +0 -289
  92. package/skills/skill-creator-ultra/install.sh +0 -313
  93. package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
  94. package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
  95. package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
  96. package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
  97. package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
  98. package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
  99. package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
  100. package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
  101. package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
  102. package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
  103. package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
  104. package/skills/skill-creator-ultra/resources/checklist.md +0 -243
  105. package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
  106. package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
  107. package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
  108. package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
  109. package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
  110. package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
  111. package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
  112. package/skills/skill-creator-ultra/resources/schemas.md +0 -430
  113. package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
  114. package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
  115. package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
  116. package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
  117. package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
  118. package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
  119. package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
  120. package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
  121. package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
  122. package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
  123. package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
  124. package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
  125. package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
  126. package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
  127. package/skills/tailwind-mastery/SKILL.md +0 -229
  128. package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
  129. package/skills/vercel-react-best-practices/README.md +0 -123
  130. package/skills/vercel-react-best-practices/SKILL.md +0 -143
  131. package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
  132. package/skills/vercel-react-best-practices/rules/_template.md +0 -28
  133. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  134. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  135. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  136. package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  137. package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  138. package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  139. package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  140. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  141. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  142. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  143. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  144. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  145. package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  146. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  147. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  148. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  149. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  150. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  151. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  152. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  153. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  154. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  155. package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  156. package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  157. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  158. package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  159. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  160. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  161. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  162. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  163. package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  164. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  165. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  166. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  167. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  168. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  169. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  170. package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  171. package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  172. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  173. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  174. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  175. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  176. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  177. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  178. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  179. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  180. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  181. package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  182. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  183. package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  184. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  185. package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  186. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  187. package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  188. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  189. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  190. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  191. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  192. package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  193. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  194. package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  195. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  196. package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  197. package/skills/web-design-guidelines/SKILL.md +0 -39
@@ -1,398 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- simulate_skill.py — Mô phỏng chạy thử Skill với input giả
4
-
5
- Sử dụng:
6
- python simulate_skill.py /path/to/SKILL.md
7
-
8
- Script sẽ:
9
- 1. Parse SKILL.md
10
- 2. Trích xuất Instructions (các bước)
11
- 3. Trích xuất Examples (input/output mẫu)
12
- 4. Mô phỏng "dry run" — đi qua từng bước
13
- 5. Report: Bước nào rõ ràng, bước nào mơ hồ
14
- """
15
-
16
- import sys
17
- import os
18
- import re
19
- from pathlib import Path
20
-
21
-
22
- class Colors:
23
- PASS = '\033[92m'
24
- FAIL = '\033[91m'
25
- WARN = '\033[93m'
26
- INFO = '\033[96m'
27
- BOLD = '\033[1m'
28
- DIM = '\033[2m'
29
- RESET = '\033[0m'
30
-
31
- @staticmethod
32
- def enable_windows():
33
- if os.name == 'nt':
34
- try:
35
- import ctypes
36
- kernel32 = ctypes.windll.kernel32
37
- kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
38
- except Exception:
39
- pass
40
-
41
-
42
- def parse_frontmatter(content):
43
- """Trích xuất YAML frontmatter."""
44
- pattern = r'^---\s*\n(.*?)\n---\s*\n(.*)$'
45
- match = re.match(pattern, content, re.DOTALL)
46
- if not match:
47
- return {}, content
48
-
49
- yaml_content = match.group(1)
50
- body = match.group(2)
51
-
52
- frontmatter = {}
53
- current_key = None
54
- current_value = []
55
-
56
- for line in yaml_content.strip().split('\n'):
57
- if ':' in line and not line.startswith(' ') and not line.startswith('\t'):
58
- if current_key:
59
- frontmatter[current_key] = '\n'.join(current_value).strip().strip('"').strip("'")
60
- key, _, value = line.partition(':')
61
- current_key = key.strip()
62
- current_value = [value.strip().strip('"').strip("'").strip('|')]
63
- elif current_key:
64
- current_value.append(line.strip())
65
-
66
- if current_key:
67
- frontmatter[current_key] = '\n'.join(current_value).strip()
68
-
69
- return frontmatter, body
70
-
71
-
72
- def extract_steps(body):
73
- """Trích xuất các bước từ Instructions section."""
74
- steps = []
75
- in_instructions = False
76
- current_step = None
77
-
78
- for line in body.split('\n'):
79
- stripped = line.strip()
80
-
81
- # Bắt đầu section Instructions
82
- if re.match(r'^#{1,2}\s+Instructions', stripped, re.IGNORECASE):
83
- in_instructions = True
84
- continue
85
-
86
- # Kết thúc section (gặp heading mới cùng level)
87
- if in_instructions and re.match(r'^#{1,2}\s+(?!Bước|Step|Stage)', stripped):
88
- if not re.match(r'^#{3,}', stripped):
89
- break
90
-
91
- if in_instructions:
92
- # Tìm numbered step
93
- step_match = re.match(r'^(\d+)\.\s+(.+)', stripped)
94
- if step_match:
95
- if current_step:
96
- steps.append(current_step)
97
- current_step = {
98
- 'number': int(step_match.group(1)),
99
- 'text': step_match.group(2),
100
- 'sub_steps': [],
101
- 'has_condition': False,
102
- 'has_action': False,
103
- 'has_error_handling': False,
104
- }
105
- elif current_step and stripped.startswith(('-', '*', '•')):
106
- sub = stripped.lstrip('-*• ').strip()
107
- current_step['sub_steps'].append(sub)
108
-
109
- if current_step:
110
- steps.append(current_step)
111
-
112
- return steps
113
-
114
-
115
- def extract_examples(body):
116
- """Trích xuất ví dụ từ Examples section."""
117
- examples = []
118
- in_examples = False
119
- current_example = None
120
-
121
- for line in body.split('\n'):
122
- stripped = line.strip()
123
-
124
- if re.match(r'^#{1,2}\s+Examples', stripped, re.IGNORECASE):
125
- in_examples = True
126
- continue
127
-
128
- if in_examples and re.match(r'^#{1,2}\s+(?!Ví dụ|Example)', stripped):
129
- if not re.match(r'^#{3,}', stripped):
130
- break
131
-
132
- if in_examples:
133
- example_match = re.match(r'^#{2,3}\s+(?:Ví dụ|Example)\s*\d*[:.]\s*(.*)', stripped, re.IGNORECASE)
134
- if example_match:
135
- if current_example:
136
- examples.append(current_example)
137
- current_example = {
138
- 'title': example_match.group(1),
139
- 'has_input': False,
140
- 'has_output': False,
141
- }
142
-
143
- if current_example:
144
- if re.match(r'\*\*Input', stripped, re.IGNORECASE):
145
- current_example['has_input'] = True
146
- if re.match(r'\*\*Output', stripped, re.IGNORECASE):
147
- current_example['has_output'] = True
148
-
149
- if current_example:
150
- examples.append(current_example)
151
-
152
- return examples
153
-
154
-
155
- def extract_constraints(body):
156
- """Trích xuất constraints."""
157
- constraints = []
158
- in_constraints = False
159
-
160
- for line in body.split('\n'):
161
- stripped = line.strip()
162
-
163
- if re.match(r'^#{1,2}\s+Constraints', stripped, re.IGNORECASE):
164
- in_constraints = True
165
- continue
166
-
167
- if in_constraints and re.match(r'^#{1,2}\s+', stripped):
168
- if not re.match(r'^#{3,}', stripped):
169
- break
170
-
171
- if in_constraints:
172
- constraint_match = re.match(r'^[-*]\s+(.+)', stripped)
173
- if constraint_match:
174
- text = constraint_match.group(1)
175
- is_negative = any(kw in text.upper() for kw in ['KHÔNG ĐƯỢC', 'KHÔNG BAO GIỜ', 'TUYỆT ĐỐI KHÔNG', 'NEVER', '🚫'])
176
- is_positive = any(kw in text.upper() for kw in ['LUÔN LUÔN', 'ALWAYS', 'BẮT BUỘC', '✅'])
177
- constraints.append({
178
- 'text': text,
179
- 'type': 'negative' if is_negative else ('positive' if is_positive else 'neutral'),
180
- })
181
-
182
- return constraints
183
-
184
-
185
- # Danh sách từ mơ hồ cần cảnh báo
186
- AMBIGUOUS_WORDS = [
187
- ('xử lý', 'parse/validate/transform/filter'),
188
- ('kiểm tra', 'so sánh X với Y / đảm bảo X ≥ 0'),
189
- ('tối ưu', 'giảm thời gian <2s / giảm bundle <500KB'),
190
- ('phù hợp', 'khớp regex / thuộc danh sách X'),
191
- ('tốt', 'pass test / response <200ms'),
192
- ('sạch', 'không duplicate / function <30 dòng'),
193
- ('nhiều', '≥5 items / >1000 rows'),
194
- ('lớn', '>10MB / >1000 records'),
195
- ('nhanh', '<2s / <100ms'),
196
- ]
197
-
198
-
199
- def analyze_step(step):
200
- """Phân tích chất lượng 1 bước."""
201
- issues = []
202
- text = step['text'].lower()
203
- all_text = text + ' ' + ' '.join(s.lower() for s in step['sub_steps'])
204
-
205
- # Check conditional logic
206
- step['has_condition'] = any(kw in all_text for kw in ['nếu', 'if', 'khi', 'when', 'trường hợp'])
207
-
208
- # Check actionable
209
- action_verbs = ['đọc', 'ghi', 'chạy', 'tạo', 'xóa', 'kiểm', 'gửi', 'parse', 'scan',
210
- 'hỏi', 'hiển thị', 'output', 'lưu', 'copy', 'move', 'validate',
211
- 'generate', 'deploy', 'build', 'test', 'review', 'format',
212
- 'trích xuất', 'phân tích', 'so sánh', 'merge', 'sort',
213
- 'kích hoạt', 'báo', 'cảnh báo', 'confirm', 'xác nhận']
214
- step['has_action'] = any(verb in all_text for verb in action_verbs)
215
-
216
- # Check error handling
217
- error_keywords = ['lỗi', 'fail', 'error', 'exception', 'không tìm', 'không có',
218
- 'nếu fail', 'nếu lỗi', 'trường hợp xấu', 'fallback']
219
- step['has_error_handling'] = any(kw in all_text for kw in error_keywords)
220
-
221
- # Check ambiguous words
222
- for word, suggestion in AMBIGUOUS_WORDS:
223
- if word in text:
224
- issues.append(f'Từ mơ hồ "{word}" → Nên cụ thể hơn: {suggestion}')
225
-
226
- # Check too short
227
- if len(step['text'].split()) < 4 and len(step['sub_steps']) == 0:
228
- issues.append('Bước quá ngắn, thiếu chi tiết')
229
-
230
- return issues
231
-
232
-
233
- def simulate(skill_path):
234
- """Chạy mô phỏng toàn bộ skill."""
235
- Colors.enable_windows()
236
-
237
- path = Path(skill_path)
238
- if path.is_dir():
239
- path = path / 'SKILL.md'
240
-
241
- if not path.exists():
242
- print(f"{Colors.FAIL}❌ Không tìm thấy: {path}{Colors.RESET}")
243
- return False
244
-
245
- content = path.read_text(encoding='utf-8', errors='ignore')
246
- frontmatter, body = parse_frontmatter(content)
247
- steps = extract_steps(body)
248
- examples = extract_examples(body)
249
- constraints = extract_constraints(body)
250
-
251
- print(f"\n{Colors.BOLD}{'='*60}{Colors.RESET}")
252
- print(f"{Colors.BOLD}🧪 SKILL SIMULATOR — Mô phỏng chạy thử{Colors.RESET}")
253
- print(f"{Colors.BOLD}{'='*60}{Colors.RESET}")
254
-
255
- name = frontmatter.get('name', path.parent.name)
256
- desc = frontmatter.get('description', '(không có)')
257
- print(f"\n{Colors.INFO}📌 Skill: {name}{Colors.RESET}")
258
- print(f"{Colors.DIM}📝 {desc[:100]}{'...' if len(desc) > 100 else ''}{Colors.RESET}\n")
259
-
260
- # ---- Simulate Steps ----
261
- print(f"{Colors.BOLD}🔄 DRY RUN — Đi qua từng bước:{Colors.RESET}\n")
262
-
263
- total_issues = 0
264
- actionable_steps = 0
265
- conditional_steps = 0
266
- error_handled_steps = 0
267
-
268
- for step in steps:
269
- issues = analyze_step(step)
270
- total_issues += len(issues)
271
-
272
- if step['has_action']:
273
- actionable_steps += 1
274
- if step['has_condition']:
275
- conditional_steps += 1
276
- if step['has_error_handling']:
277
- error_handled_steps += 1
278
-
279
- # Status icon
280
- if issues:
281
- icon = f"{Colors.WARN}⚠️{Colors.RESET}"
282
- elif step['has_action']:
283
- icon = f"{Colors.PASS}✅{Colors.RESET}"
284
- else:
285
- icon = f"{Colors.WARN}🔸{Colors.RESET}"
286
-
287
- # Flags
288
- flags = []
289
- if step['has_condition']:
290
- flags.append('🔀 Rẽ nhánh')
291
- if step['has_error_handling']:
292
- flags.append('🛡️ Error handling')
293
- if not step['has_action']:
294
- flags.append(f'{Colors.WARN}⚠️ Thiếu hành động cụ thể{Colors.RESET}')
295
-
296
- flag_str = f" [{', '.join(flags)}]" if flags else ""
297
-
298
- print(f" {icon} Bước {step['number']}: {step['text'][:70]}{flag_str}")
299
-
300
- for sub in step['sub_steps'][:3]:
301
- print(f" {Colors.DIM} └─ {sub[:65]}{Colors.RESET}")
302
-
303
- for issue in issues:
304
- print(f" {Colors.WARN} ⚠️ {issue}{Colors.RESET}")
305
-
306
- print()
307
-
308
- # ---- Examples Analysis ----
309
- print(f"{Colors.BOLD}📋 Examples Analysis:{Colors.RESET}")
310
- if examples:
311
- for i, ex in enumerate(examples, 1):
312
- input_icon = f"{Colors.PASS}✅{Colors.RESET}" if ex['has_input'] else f"{Colors.FAIL}❌{Colors.RESET}"
313
- output_icon = f"{Colors.PASS}✅{Colors.RESET}" if ex['has_output'] else f"{Colors.FAIL}❌{Colors.RESET}"
314
- print(f" Ví dụ {i}: {ex['title'][:50]}")
315
- print(f" Input: {input_icon} Output: {output_icon}")
316
- else:
317
- print(f" {Colors.WARN}⚠️ Không tìm thấy ví dụ nào!{Colors.RESET}")
318
- print()
319
-
320
- # ---- Constraints Analysis ----
321
- print(f"{Colors.BOLD}🚧 Constraints Analysis:{Colors.RESET}")
322
- neg_count = sum(1 for c in constraints if c['type'] == 'negative')
323
- pos_count = sum(1 for c in constraints if c['type'] == 'positive')
324
- neu_count = sum(1 for c in constraints if c['type'] == 'neutral')
325
-
326
- if constraints:
327
- print(f" 🚫 Negative (KHÔNG ĐƯỢC): {neg_count}")
328
- print(f" ✅ Positive (LUÔN LUÔN): {pos_count}")
329
- print(f" 🔸 Neutral: {neu_count}")
330
- else:
331
- print(f" {Colors.WARN}⚠️ Không tìm thấy constraints!{Colors.RESET}")
332
- print()
333
-
334
- # ---- Overall Score ----
335
- print(f"{Colors.BOLD}{'='*60}{Colors.RESET}")
336
- print(f"{Colors.BOLD}📊 SIMULATION REPORT:{Colors.RESET}\n")
337
-
338
- metrics = [
339
- ('Tổng bước', len(steps), None),
340
- ('Bước có hành động cụ thể', actionable_steps, len(steps)),
341
- ('Bước có logic rẽ nhánh', conditional_steps, None),
342
- ('Bước có error handling', error_handled_steps, len(steps)),
343
- ('Ví dụ có Input+Output', sum(1 for e in examples if e['has_input'] and e['has_output']), len(examples)),
344
- ('Constraints (negative)', neg_count, None),
345
- ('Issues phát hiện', total_issues, None),
346
- ]
347
-
348
- for label, value, total in metrics:
349
- if total:
350
- pct = value / total * 100 if total > 0 else 0
351
- color = Colors.PASS if pct >= 80 else Colors.WARN if pct >= 50 else Colors.FAIL
352
- print(f" {color}{label}: {value}/{total} ({pct:.0f}%){Colors.RESET}")
353
- else:
354
- print(f" {Colors.INFO}{label}: {value}{Colors.RESET}")
355
-
356
- # Grade
357
- print()
358
- score = 0
359
- if len(steps) > 0:
360
- score += min(30, actionable_steps / len(steps) * 30) # 30 pts for actionable
361
- score += min(20, error_handled_steps / len(steps) * 20) # 20 pts for error handling
362
- score += min(20, len(examples) * 10) # 20 pts for examples (2=full)
363
- score += min(15, neg_count * 5) # 15 pts for constraints
364
- score -= total_issues * 3 # -3 pts per issue
365
- score = max(0, min(100, score))
366
-
367
- if score >= 90:
368
- grade, msg = 'A+', '🏆 Skill mô phỏng hoàn hảo!'
369
- elif score >= 80:
370
- grade, msg = 'A', '👍 Skill rất tốt, sẵn sàng deploy!'
371
- elif score >= 65:
372
- grade, msg = 'B', '⚠️ Khá tốt, cần cải thiện một số bước.'
373
- elif score >= 50:
374
- grade, msg = 'C', '⚠️ Cần sửa đáng kể trước khi deploy.'
375
- else:
376
- grade, msg = 'F', '❌ Cần viết lại phần lớn skill.'
377
-
378
- color = Colors.PASS if score >= 80 else Colors.WARN if score >= 50 else Colors.FAIL
379
- print(f" {color}{Colors.BOLD}Score: {score:.0f}/100 — Grade: {grade}{Colors.RESET}")
380
- print(f" {color}{msg}{Colors.RESET}")
381
- print(f"\n{Colors.BOLD}{'='*60}{Colors.RESET}\n")
382
-
383
- return score >= 65
384
-
385
-
386
- if __name__ == '__main__':
387
- if len(sys.argv) < 2:
388
- print("Sử dụng: python simulate_skill.py <path-to-SKILL.md-or-skill-folder>")
389
- print("Ví dụ: python simulate_skill.py ./my-skill/")
390
- sys.exit(1)
391
-
392
- target = sys.argv[1]
393
- if not os.path.exists(target):
394
- print(f"❌ Không tìm thấy: {target}")
395
- sys.exit(1)
396
-
397
- success = simulate(target)
398
- sys.exit(0 if success else 1)