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.
Files changed (190) 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 +7 -1
  16. package/skills/_shared/helpers.md +50 -14
  17. package/skills/cm-autopilot/SKILL.md +29 -0
  18. package/skills/cm-autopilot/scripts/autopilot.py +190 -0
  19. package/skills/cm-continuity/SKILL.md +90 -28
  20. package/skills/cm-quality-gate/SKILL.md +11 -1
  21. package/skills/cm-safe-deploy/SKILL.md +38 -2
  22. package/skills/cm-security-gate/SKILL.md +158 -34
  23. package/skills/cm-skill-chain/SKILL.md +47 -1
  24. package/skills/cm-start/SKILL.md +11 -2
  25. package/skills/cm-test-gate/SKILL.md +3 -0
  26. package/skills/boxme-git-config/SKILL.md +0 -56
  27. package/skills/boxme-local-dev/SKILL.md +0 -66
  28. package/skills/jobs-to-be-done/SKILL.md +0 -266
  29. package/skills/jobs-to-be-done/references/case-studies.md +0 -154
  30. package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
  31. package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
  32. package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
  33. package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
  34. package/skills/marketplace-report-crawler/SKILL.md +0 -176
  35. package/skills/marketplace-report-crawler/config/accounts.json +0 -41
  36. package/skills/marketplace-report-crawler/config/report-types.json +0 -422
  37. package/skills/marketplace-report-crawler/config/sessions.json +0 -3
  38. package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
  39. package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
  40. package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
  41. package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
  42. package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
  43. package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
  44. package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
  45. package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
  46. package/skills/medical-research/SKILL.md +0 -194
  47. package/skills/medical-research/scripts/evidence_checker.py +0 -288
  48. package/skills/mom-test/SKILL.md +0 -267
  49. package/skills/mom-test/references/avoiding-bad-data.md +0 -221
  50. package/skills/mom-test/references/case-studies.md +0 -306
  51. package/skills/mom-test/references/commitment-advancement.md +0 -219
  52. package/skills/mom-test/references/finding-conversations.md +0 -251
  53. package/skills/mom-test/references/processing-learning.md +0 -256
  54. package/skills/mom-test/references/question-patterns.md +0 -198
  55. package/skills/pandasai-analytics/SKILL.md +0 -251
  56. package/skills/release-it/SKILL.md +0 -235
  57. package/skills/release-it/references/anti-patterns.md +0 -279
  58. package/skills/release-it/references/capacity-planning.md +0 -285
  59. package/skills/release-it/references/chaos-engineering.md +0 -325
  60. package/skills/release-it/references/deployment-strategies.md +0 -331
  61. package/skills/release-it/references/observability.md +0 -301
  62. package/skills/release-it/references/stability-patterns.md +0 -355
  63. package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
  64. package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
  65. package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
  66. package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
  67. package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
  68. package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
  69. package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
  70. package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
  71. package/skills/skill-creator-ultra/README.md +0 -1242
  72. package/skills/skill-creator-ultra/SKILL.md +0 -388
  73. package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
  74. package/skills/skill-creator-ultra/agents/comparator.md +0 -202
  75. package/skills/skill-creator-ultra/agents/grader.md +0 -223
  76. package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
  77. package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
  78. package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
  79. package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
  80. package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
  81. package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
  82. package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
  83. package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
  84. package/skills/skill-creator-ultra/install.ps1 +0 -289
  85. package/skills/skill-creator-ultra/install.sh +0 -313
  86. package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
  87. package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
  88. package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
  89. package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
  90. package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
  91. package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
  92. package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
  93. package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
  94. package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
  95. package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
  96. package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
  97. package/skills/skill-creator-ultra/resources/checklist.md +0 -243
  98. package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
  99. package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
  100. package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
  101. package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
  102. package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
  103. package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
  104. package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
  105. package/skills/skill-creator-ultra/resources/schemas.md +0 -430
  106. package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
  107. package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
  108. package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
  109. package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
  110. package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
  111. package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
  112. package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
  113. package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
  114. package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
  115. package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
  116. package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
  117. package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
  118. package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
  119. package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
  120. package/skills/tailwind-mastery/SKILL.md +0 -229
  121. package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
  122. package/skills/vercel-react-best-practices/README.md +0 -123
  123. package/skills/vercel-react-best-practices/SKILL.md +0 -143
  124. package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
  125. package/skills/vercel-react-best-practices/rules/_template.md +0 -28
  126. package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  127. package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  128. package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  129. package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  130. package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  131. package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  132. package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  133. package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  134. package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  135. package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  136. package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  137. package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  138. package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  139. package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  140. package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  141. package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  142. package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  143. package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  144. package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  145. package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  146. package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  147. package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  148. package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  149. package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
  150. package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  151. package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  152. package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  153. package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  154. package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  155. package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  156. package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  157. package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  158. package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  159. package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  160. package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  161. package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  162. package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  163. package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
  164. package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
  165. package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  166. package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  167. package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  168. package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  169. package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  170. package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  171. package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  172. package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  173. package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  174. package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  175. package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  176. package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
  177. package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  178. package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
  179. package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  180. package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
  181. package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  182. package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  183. package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  184. package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  185. package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  186. package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  187. package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
  188. package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  189. package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  190. 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)