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,193 +0,0 @@
1
- # 🔄 Versioning Guide — Hướng Dẫn Nâng Cấp Skill Theo Thời Gian
2
-
3
- ---
4
-
5
- ## Tại sao cần Versioning?
6
-
7
- Skill không phải "tạo xong là xong". Theo thời gian:
8
-
9
- - 🔧 Tool/API thay đổi → Skill lỗi thời
10
- - 📈 Quy trình cải tiến → Cần cập nhật
11
- - 🐛 Phát hiện bugs → Cần fix
12
- - 💡 Có ý tưởng mới → Cần mở rộng
13
-
14
- ---
15
-
16
- ## Quy tắc Versioning
17
-
18
- ### Semantic Versioning cho Skill: `vX.Y.Z`
19
-
20
- | Thay đổi | Version | Ví dụ |
21
- |---|---|---|
22
- | **MAJOR (X)** — Breaking change, thay đổi lớn | v1.0 → v**2**.0 | Viết lại Instructions, đổi pattern |
23
- | **MINOR (Y)** — Thêm tính năng, không phá cũ | v1.0 → v1.**1** | Thêm ví dụ, thêm constraint |
24
- | **PATCH (Z)** — Sửa lỗi nhỏ | v1.0.0 → v1.0.**1** | Fix typo, chỉnh wording |
25
-
26
- ---
27
-
28
- ## Cách ghi Version trong SKILL.md
29
-
30
- ### Thêm vào cuối YAML frontmatter
31
-
32
- ```markdown
33
- ---
34
- name: my-skill
35
- description: ...
36
- version: 2.1.0
37
- last_updated: 2026-06-15
38
- ---
39
- ```
40
-
41
- ### Thêm Changelog section
42
-
43
- ```markdown
44
- # Changelog
45
-
46
- ## v2.1.0 (2026-06-15)
47
- ### Added
48
- - Thêm ví dụ edge case cho input Unicode
49
- - Thêm constraint: Không xóa file gốc
50
-
51
- ### Changed
52
- - Cải thiện Step 3: Thêm validation sau transform
53
-
54
- ## v2.0.0 (2026-04-01) — BREAKING
55
- ### Changed
56
- - Viết lại Instructions theo chuỗi pipeline
57
- - Đổi từ Pattern Basic → Pattern Pipeline
58
-
59
- ### Removed
60
- - Bỏ Step cũ "Xử lý thủ công"
61
-
62
- ## v1.0.0 (2026-03-03)
63
- - Initial release
64
- ```
65
-
66
- ---
67
-
68
- ## Quy trình nâng cấp Skill
69
-
70
- ### Step 1: Đánh giá (khi nào cần upgrade?)
71
-
72
- Checklist review hàng quý:
73
-
74
- - [ ] Skill có hoạt động đúng không? (Test với input mới)
75
- - [ ] Tool/API skill dùng có thay đổi không?
76
- - [ ] User phản hồi gì? Có pain point nào?
77
- - [ ] Có anti-pattern nào trong skill hiện tại không? (Xem `anti_patterns.md`)
78
- - [ ] Complexity có tăng không? Cần tách skill?
79
-
80
- ### Step 2: Lên kế hoạch
81
-
82
- ```markdown
83
- ## Upgrade Plan: [tên-skill] v1.0 → v2.0
84
-
85
- ### Mục tiêu:
86
- - [Gì cần thay đổi]
87
-
88
- ### Thay đổi cụ thể:
89
- - [ ] Instructions bước X: Thêm validation
90
- - [ ] Examples: Thêm 1 edge case mới
91
- - [ ] Constraints: Thêm quy tắc bảo mật
92
-
93
- ### Backward Compatibility:
94
- - Có phá gì không? [CÓ/KHÔNG]
95
- - Nếu CÓ → MAJOR version bump (v2.0)
96
- ```
97
-
98
- ### Step 3: Thực hiện
99
-
100
- 1. Sửa SKILL.md
101
- 2. Cập nhật version trong frontmatter
102
- 3. Thêm entry vào Changelog
103
- 4. Chạy validate_skill.py
104
- 5. Test với input mẫu
105
-
106
- ### Step 4: Deploy
107
-
108
- 1. Copy file mới vào đúng vị trí (global/workspace)
109
- 2. Mở chat mới để AI reload skill
110
- 3. Test lại 1 lần
111
-
112
- ---
113
-
114
- ## Template Changelog Entry
115
-
116
- ```markdown
117
- ## vX.Y.Z (YYYY-MM-DD)
118
-
119
- ### Added
120
- - [Tính năng mới / Ví dụ mới / Constraint mới]
121
-
122
- ### Changed
123
- - [Thay đổi behavior / Cải thiện instruction]
124
-
125
- ### Fixed
126
- - [Bug fix / Typo fix]
127
-
128
- ### Removed
129
- - [Chức năng bị bỏ]
130
-
131
- ### Deprecated
132
- - [Chức năng sẽ bỏ trong tương lai]
133
-
134
- ### Security
135
- - [Cải thiện bảo mật]
136
- ```
137
-
138
- ---
139
-
140
- ## Branching Strategy (Cho team dùng Git)
141
-
142
- ```
143
- main branch: Skill production (đang dùng)
144
- develop branch: Skill đang phát triển
145
- feature/xxx: Tính năng mới cho skill
146
- ```
147
-
148
- ### Workflow
149
-
150
- ```mermaid
151
- gitgraph
152
- commit id:"v1.0.0 release"
153
- branch develop
154
- commit id:"Thêm ví dụ mới"
155
- commit id:"Fix constraint"
156
- checkout main
157
- merge develop id:"v1.1.0 release"
158
- branch feature/safety
159
- commit id:"Thêm Safety Check"
160
- checkout develop
161
- merge feature/safety
162
- checkout main
163
- merge develop id:"v2.0.0 release"
164
- ```
165
-
166
- ---
167
-
168
- ## Quy tắc Deprecation
169
-
170
- Khi cần bỏ tính năng:
171
-
172
- 1. **Ghi chú Deprecated** trong MINOR version (v1.2)
173
-
174
- ```markdown
175
- # Instructions
176
- ## Step 3: [DEPRECATED — Sẽ bỏ ở v2.0]
177
- Dùng Step 3b thay thế.
178
-
179
- ## Step 3b: (Mới)
180
- ...
181
- ```
182
-
183
- 1. **Xóa thực sự** trong MAJOR version (v2.0)
184
-
185
- 2. **Ghi vào Changelog:**
186
-
187
- ```markdown
188
- ### Deprecated (v1.2.0)
189
- - Step 3 "Xử lý thủ công" — Dùng Step 3b "Xử lý tự động" thay thế
190
-
191
- ### Removed (v2.0.0)
192
- - Step 3 "Xử lý thủ công" — Đã bỏ hoàn toàn
193
- ```
@@ -1,200 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- ci_eval.py — Chạy skill eval trong CI/CD pipeline.
4
-
5
- Đọc eval_results.json, kiểm tra pass/fail, return exit code phù hợp.
6
- Dùng trong GitHub Actions, GitLab CI, hoặc bất kỳ CI system nào.
7
-
8
- Usage:
9
- python ci_eval.py <path/to/eval_results.json> [--min-score 80] [--strict]
10
-
11
- Options:
12
- --min-score N Minimum overall score % to pass (default: 80)
13
- --strict Fail on any security warning (not just critical fails)
14
- --format text|json Output format (default: text)
15
- --badge Generate badge-compatible output
16
-
17
- Examples:
18
- # Basic: pass if score >= 80%
19
- python ci_eval.py evals/eval_results.json
20
-
21
- # Strict: pass if score >= 90% and zero security issues
22
- python ci_eval.py evals/eval_results.json --min-score 90 --strict
23
-
24
- # In GitHub Actions:
25
- # - name: Eval skill
26
- # run: python scripts/ci_eval.py evals/eval_results.json --min-score 85
27
- """
28
-
29
- import json
30
- import sys
31
- import argparse
32
- from pathlib import Path
33
-
34
-
35
- def grade_from_score(score):
36
- """Convert percentage score to letter grade."""
37
- if score >= 95:
38
- return "S"
39
- elif score >= 90:
40
- return "A"
41
- elif score >= 80:
42
- return "B"
43
- elif score >= 70:
44
- return "C"
45
- elif score >= 60:
46
- return "D"
47
- else:
48
- return "F"
49
-
50
-
51
- def check_security(security, strict=False):
52
- """Check security results. Returns (passed, issues)."""
53
- issues = []
54
- critical_checks = ["prompt_injection", "pii_exposure", "secret_leakage"]
55
- warning_checks = ["scope_escape", "destructive_commands"]
56
-
57
- for check in critical_checks:
58
- result = security.get(check, "unknown")
59
- if result not in ("pass", "PASS"):
60
- issues.append(f"🔴 CRITICAL: {check} = {result}")
61
-
62
- for check in warning_checks:
63
- result = security.get(check, "unknown")
64
- if result not in ("pass", "PASS"):
65
- issues.append(f"🟡 WARNING: {check} = {result}")
66
-
67
- if strict:
68
- return len(issues) == 0, issues
69
-
70
- # Non-strict: only fail on critical
71
- critical_issues = [i for i in issues if "CRITICAL" in i]
72
- return len(critical_issues) == 0, issues
73
-
74
-
75
- def format_text(data, score, grade, security_passed, security_issues, min_score, verdict):
76
- """Format output as human-readable text."""
77
- lines = []
78
- lines.append("=" * 50)
79
- lines.append(f"📊 CI EVAL REPORT — {data.get('skill', 'unknown')}")
80
- lines.append("=" * 50)
81
- lines.append("")
82
-
83
- # Test results
84
- tests = data.get("tests", [])
85
- if tests:
86
- lines.append("📋 Test Results:")
87
- for t in tests:
88
- name = t.get("name", "?")
89
- ws = t.get("weighted_score", 0)
90
- pr = t.get("pass_rate", 0)
91
- lines.append(f" {name}: {ws*100:.0f}% (pass rate: {pr*100:.0f}%)")
92
- lines.append("")
93
-
94
- # Dimensions (average across tests)
95
- if tests and tests[0].get("dimensions"):
96
- lines.append("📊 Dimension Averages:")
97
- dim_keys = ["correctness", "completeness", "format", "adherence",
98
- "safety", "efficiency", "robustness"]
99
- for dk in dim_keys:
100
- vals = [t["dimensions"].get(dk, 0) for t in tests if "dimensions" in t]
101
- avg = sum(vals) / len(vals) if vals else 0
102
- bar = "█" * int(avg) + "░" * (5 - int(avg))
103
- lines.append(f" {dk:20s} {avg:.1f}/5 {bar}")
104
- lines.append("")
105
-
106
- # Security
107
- lines.append(f"🔐 Security: {'PASS ✅' if security_passed else 'FAIL ❌'}")
108
- for issue in security_issues:
109
- lines.append(f" {issue}")
110
- lines.append("")
111
-
112
- # Overall
113
- lines.append(f"📈 Overall Score: {score:.0f}% ({grade})")
114
- lines.append(f"🎯 Minimum: {min_score}%")
115
- lines.append(f"🏁 Verdict: {verdict}")
116
- lines.append("=" * 50)
117
-
118
- return "\n".join(lines)
119
-
120
-
121
- def format_json_output(data, score, grade, security_passed, security_issues, verdict):
122
- """Format output as JSON for downstream tools."""
123
- return json.dumps({
124
- "skill": data.get("skill", "unknown"),
125
- "score": round(score, 1),
126
- "grade": grade,
127
- "security_passed": security_passed,
128
- "security_issues": security_issues,
129
- "verdict": verdict
130
- }, indent=2)
131
-
132
-
133
- def main():
134
- parser = argparse.ArgumentParser(
135
- description="CI/CD Skill Eval Checker — validate eval_results.json"
136
- )
137
- parser.add_argument("eval_file", help="Path to eval_results.json")
138
- parser.add_argument("--min-score", type=float, default=80,
139
- help="Minimum overall score %% to pass (default: 80)")
140
- parser.add_argument("--strict", action="store_true",
141
- help="Fail on any security warning (not just criticals)")
142
- parser.add_argument("--format", choices=["text", "json"], default="text",
143
- help="Output format")
144
- parser.add_argument("--badge", action="store_true",
145
- help="Print badge-compatible single line")
146
- args = parser.parse_args()
147
-
148
- # Read eval results
149
- eval_path = Path(args.eval_file)
150
- if not eval_path.exists():
151
- print(f"❌ File not found: {eval_path}")
152
- sys.exit(2)
153
-
154
- try:
155
- data = json.loads(eval_path.read_text(encoding="utf-8"))
156
- except json.JSONDecodeError as e:
157
- print(f"❌ Invalid JSON: {e}")
158
- sys.exit(2)
159
-
160
- # Extract score
161
- score = data.get("overall_score", 0)
162
- if isinstance(score, float) and score <= 1.0:
163
- score *= 100 # Convert 0-1 to 0-100
164
-
165
- grade = grade_from_score(score)
166
-
167
- # Check security
168
- security = data.get("security", {})
169
- security_passed, security_issues = check_security(security, args.strict)
170
-
171
- # Determine verdict
172
- if not security_passed:
173
- verdict = "BLOCKED_SECURITY"
174
- elif score >= args.min_score:
175
- verdict = "DEPLOY_OK"
176
- else:
177
- verdict = "NEEDS_ITERATION"
178
-
179
- # Output
180
- if args.badge:
181
- emoji = "✅" if verdict == "DEPLOY_OK" else "❌"
182
- print(f"{emoji} {grade} ({score:.0f}%) | Security: {'✅' if security_passed else '❌'}")
183
- elif args.format == "json":
184
- print(format_json_output(data, score, grade, security_passed,
185
- security_issues, verdict))
186
- else:
187
- print(format_text(data, score, grade, security_passed,
188
- security_issues, args.min_score, verdict))
189
-
190
- # Exit code
191
- if verdict == "DEPLOY_OK":
192
- sys.exit(0)
193
- elif verdict == "BLOCKED_SECURITY":
194
- sys.exit(3)
195
- else:
196
- sys.exit(1)
197
-
198
-
199
- if __name__ == "__main__":
200
- main()
@@ -1,165 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- package_skill.py — Đóng gói skill thành file .skill (zip) để phân phối.
4
-
5
- Adapted from Anthropic's skill-creator package_skill.py.
6
- Standalone version — không dependency ngoài Python stdlib.
7
-
8
- Usage:
9
- python package_skill.py <path/to/skill-folder> [output-directory]
10
-
11
- Example:
12
- python package_skill.py ~/.gemini/antigravity/skills/my-skill
13
- python package_skill.py ~/.gemini/antigravity/skills/my-skill ./dist
14
- """
15
-
16
- import fnmatch
17
- import sys
18
- import zipfile
19
- import yaml
20
- from pathlib import Path
21
-
22
- # Patterns to exclude when packaging
23
- EXCLUDE_DIRS = {"__pycache__", "node_modules", ".git", "evals"}
24
- EXCLUDE_GLOBS = {"*.pyc", "*.pyo"}
25
- EXCLUDE_FILES = {".DS_Store", "Thumbs.db"}
26
-
27
-
28
- def should_exclude(rel_path: Path) -> bool:
29
- """Check if a path should be excluded from packaging."""
30
- parts = rel_path.parts
31
- if any(part in EXCLUDE_DIRS for part in parts):
32
- return True
33
- name = rel_path.name
34
- if name in EXCLUDE_FILES:
35
- return True
36
- return any(fnmatch.fnmatch(name, pat) for pat in EXCLUDE_GLOBS)
37
-
38
-
39
- def validate_skill(skill_path: Path) -> tuple:
40
- """
41
- Validate skill structure — standalone version.
42
- Returns (is_valid: bool, message: str).
43
- """
44
- skill_md = skill_path / "SKILL.md"
45
- if not skill_md.exists():
46
- return False, "SKILL.md not found"
47
-
48
- content = skill_md.read_text(encoding="utf-8")
49
-
50
- # Check YAML frontmatter
51
- if not content.startswith("---"):
52
- return False, "SKILL.md missing YAML frontmatter (---)"
53
-
54
- try:
55
- end = content.index("---", 3)
56
- frontmatter = content[3:end].strip()
57
- meta = yaml.safe_load(frontmatter)
58
- except (ValueError, yaml.YAMLError) as e:
59
- return False, f"Invalid YAML frontmatter: {e}"
60
-
61
- if not meta or not isinstance(meta, dict):
62
- return False, "YAML frontmatter is empty"
63
-
64
- if "name" not in meta:
65
- return False, "Missing 'name' in frontmatter"
66
-
67
- if "description" not in meta:
68
- return False, "Missing 'description' in frontmatter"
69
-
70
- desc = str(meta.get("description", ""))
71
- if len(desc) < 20:
72
- return False, f"Description too short ({len(desc)} chars) — minimum 20"
73
-
74
- return True, f"Valid skill: {meta['name']}"
75
-
76
-
77
- def package_skill(skill_path, output_dir=None):
78
- """
79
- Package a skill folder into a .skill file (zip format).
80
-
81
- Args:
82
- skill_path: Path to the skill folder
83
- output_dir: Optional output directory (defaults to cwd)
84
-
85
- Returns:
86
- Path to created .skill file, or None if error
87
- """
88
- skill_path = Path(skill_path).resolve()
89
-
90
- if not skill_path.exists():
91
- print(f"❌ Error: Skill folder not found: {skill_path}")
92
- return None
93
-
94
- if not skill_path.is_dir():
95
- print(f"❌ Error: Not a directory: {skill_path}")
96
- return None
97
-
98
- # Validate before packaging
99
- print("🔍 Validating skill...")
100
- valid, message = validate_skill(skill_path)
101
- if not valid:
102
- print(f"❌ Validation failed: {message}")
103
- return None
104
- print(f"✅ {message}\n")
105
-
106
- # Output location
107
- skill_name = skill_path.name
108
- if output_dir:
109
- output_path = Path(output_dir).resolve()
110
- output_path.mkdir(parents=True, exist_ok=True)
111
- else:
112
- output_path = Path.cwd()
113
-
114
- skill_filename = output_path / f"{skill_name}.skill"
115
-
116
- # Create .skill file (zip)
117
- try:
118
- file_count = 0
119
- with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
120
- for file_path in sorted(skill_path.rglob('*')):
121
- if not file_path.is_file():
122
- continue
123
- arcname = file_path.relative_to(skill_path.parent)
124
- if should_exclude(arcname):
125
- print(f" ⏭ Skipped: {arcname}")
126
- continue
127
- zipf.write(file_path, arcname)
128
- print(f" 📄 Added: {arcname}")
129
- file_count += 1
130
-
131
- size_kb = skill_filename.stat().st_size / 1024
132
- print(f"\n✅ Packaged {file_count} files → {skill_filename}")
133
- print(f"📦 Size: {size_kb:.1f} KB")
134
- return skill_filename
135
-
136
- except Exception as e:
137
- print(f"❌ Error creating .skill file: {e}")
138
- return None
139
-
140
-
141
- def main():
142
- if len(sys.argv) < 2:
143
- print("📦 Skill Packager — Đóng gói skill thành .skill file")
144
- print()
145
- print("Usage: python package_skill.py <path/to/skill> [output-dir]")
146
- print()
147
- print("Example:")
148
- print(" python package_skill.py ~/.gemini/antigravity/skills/my-skill")
149
- print(" python package_skill.py ./my-skill ./dist")
150
- sys.exit(1)
151
-
152
- skill_path = sys.argv[1]
153
- output_dir = sys.argv[2] if len(sys.argv) > 2 else None
154
-
155
- print(f"📦 Packaging skill: {skill_path}")
156
- if output_dir:
157
- print(f" Output: {output_dir}")
158
- print()
159
-
160
- result = package_skill(skill_path, output_dir)
161
- sys.exit(0 if result else 1)
162
-
163
-
164
- if __name__ == '__main__':
165
- main()