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