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,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()