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.
- package/CHANGELOG.md +33 -0
- package/README.md +29 -14
- package/commands/demo.md +1 -1
- package/dist/context-bus.js +70 -0
- package/dist/context-db.js +265 -0
- package/dist/continuity.js +12 -0
- package/dist/file-watcher.js +79 -0
- package/dist/index.js +152 -1
- package/dist/l0-indexer.js +158 -0
- package/dist/mcp-context-server.js +400 -0
- package/dist/migrate-json-to-sqlite.js +126 -0
- package/dist/skill-chain.js +19 -3
- package/dist/token-budget.js +108 -0
- package/dist/uri-resolver.js +203 -0
- package/package.json +7 -1
- package/skills/_shared/helpers.md +50 -14
- package/skills/cm-autopilot/SKILL.md +29 -0
- package/skills/cm-autopilot/scripts/autopilot.py +190 -0
- package/skills/cm-continuity/SKILL.md +90 -28
- package/skills/cm-quality-gate/SKILL.md +11 -1
- package/skills/cm-safe-deploy/SKILL.md +38 -2
- package/skills/cm-security-gate/SKILL.md +158 -34
- package/skills/cm-skill-chain/SKILL.md +47 -1
- package/skills/cm-start/SKILL.md +11 -2
- package/skills/cm-test-gate/SKILL.md +3 -0
- package/skills/boxme-git-config/SKILL.md +0 -56
- package/skills/boxme-local-dev/SKILL.md +0 -66
- package/skills/jobs-to-be-done/SKILL.md +0 -266
- package/skills/jobs-to-be-done/references/case-studies.md +0 -154
- package/skills/jobs-to-be-done/references/competitive-strategy.md +0 -280
- package/skills/jobs-to-be-done/references/diagnostics.md +0 -158
- package/skills/jobs-to-be-done/references/innovation-process.md +0 -392
- package/skills/jobs-to-be-done/references/organizational-change.md +0 -328
- package/skills/marketplace-report-crawler/SKILL.md +0 -176
- package/skills/marketplace-report-crawler/config/accounts.json +0 -41
- package/skills/marketplace-report-crawler/config/report-types.json +0 -422
- package/skills/marketplace-report-crawler/config/sessions.json +0 -3
- package/skills/marketplace-report-crawler/scripts/ab-wrapper.sh +0 -102
- package/skills/marketplace-report-crawler/scripts/browser-actions/lazada/lazada-actions.js +0 -114
- package/skills/marketplace-report-crawler/scripts/browser-actions/shopee/shopee-actions.js +0 -94
- package/skills/marketplace-report-crawler/scripts/browser-actions/tiktok/tiktok-actions.js +0 -272
- package/skills/marketplace-report-crawler/scripts/crawl-runner.js +0 -281
- package/skills/marketplace-report-crawler/scripts/session-check.sh +0 -72
- package/skills/marketplace-report-crawler/scripts/session-manager.sh +0 -349
- package/skills/marketplace-report-crawler/scripts/setup-folders.sh +0 -83
- package/skills/medical-research/SKILL.md +0 -194
- package/skills/medical-research/scripts/evidence_checker.py +0 -288
- package/skills/mom-test/SKILL.md +0 -267
- package/skills/mom-test/references/avoiding-bad-data.md +0 -221
- package/skills/mom-test/references/case-studies.md +0 -306
- package/skills/mom-test/references/commitment-advancement.md +0 -219
- package/skills/mom-test/references/finding-conversations.md +0 -251
- package/skills/mom-test/references/processing-learning.md +0 -256
- package/skills/mom-test/references/question-patterns.md +0 -198
- package/skills/pandasai-analytics/SKILL.md +0 -251
- package/skills/release-it/SKILL.md +0 -235
- package/skills/release-it/references/anti-patterns.md +0 -279
- package/skills/release-it/references/capacity-planning.md +0 -285
- package/skills/release-it/references/chaos-engineering.md +0 -325
- package/skills/release-it/references/deployment-strategies.md +0 -331
- package/skills/release-it/references/observability.md +0 -301
- package/skills/release-it/references/stability-patterns.md +0 -355
- package/skills/skill-creator-ultra/.agents/workflows/skill-audit.md +0 -37
- package/skills/skill-creator-ultra/.agents/workflows/skill-compare.md +0 -34
- package/skills/skill-creator-ultra/.agents/workflows/skill-export.md +0 -51
- package/skills/skill-creator-ultra/.agents/workflows/skill-generate.md +0 -39
- package/skills/skill-creator-ultra/.agents/workflows/skill-scaffold.md +0 -52
- package/skills/skill-creator-ultra/.agents/workflows/skill-simulate.md +0 -25
- package/skills/skill-creator-ultra/.agents/workflows/skill-stats.md +0 -31
- package/skills/skill-creator-ultra/.agents/workflows/skill-validate.md +0 -25
- package/skills/skill-creator-ultra/README.md +0 -1242
- package/skills/skill-creator-ultra/SKILL.md +0 -388
- package/skills/skill-creator-ultra/agents/analyzer.md +0 -274
- package/skills/skill-creator-ultra/agents/comparator.md +0 -202
- package/skills/skill-creator-ultra/agents/grader.md +0 -223
- package/skills/skill-creator-ultra/assets/eval_review.html +0 -146
- package/skills/skill-creator-ultra/eval-viewer/generate_review.py +0 -471
- package/skills/skill-creator-ultra/eval-viewer/viewer.html +0 -1325
- package/skills/skill-creator-ultra/examples/example_anthropic_frontend.md +0 -109
- package/skills/skill-creator-ultra/examples/example_anthropic_pdf.md +0 -116
- package/skills/skill-creator-ultra/examples/example_api_docs.md +0 -189
- package/skills/skill-creator-ultra/examples/example_db_migration.md +0 -253
- package/skills/skill-creator-ultra/examples/example_git_commit.md +0 -111
- package/skills/skill-creator-ultra/install.ps1 +0 -289
- package/skills/skill-creator-ultra/install.sh +0 -313
- package/skills/skill-creator-ultra/phases/phase1_interview.md +0 -202
- package/skills/skill-creator-ultra/phases/phase2_extract.md +0 -55
- package/skills/skill-creator-ultra/phases/phase3_detect.md +0 -57
- package/skills/skill-creator-ultra/phases/phase4_generate.md +0 -543
- package/skills/skill-creator-ultra/phases/phase5_test.md +0 -319
- package/skills/skill-creator-ultra/phases/phase6_eval.md +0 -301
- package/skills/skill-creator-ultra/phases/phase7_iterate.md +0 -103
- package/skills/skill-creator-ultra/phases/phase8_optimize.md +0 -113
- package/skills/skill-creator-ultra/resources/advanced_patterns.md +0 -499
- package/skills/skill-creator-ultra/resources/anti_patterns.md +0 -376
- package/skills/skill-creator-ultra/resources/blueprints.md +0 -498
- package/skills/skill-creator-ultra/resources/checklist.md +0 -243
- package/skills/skill-creator-ultra/resources/composition_cookbook.md +0 -291
- package/skills/skill-creator-ultra/resources/description_optimization.md +0 -90
- package/skills/skill-creator-ultra/resources/eval_guide.md +0 -133
- package/skills/skill-creator-ultra/resources/industry_questions.md +0 -189
- package/skills/skill-creator-ultra/resources/interview_questions.md +0 -200
- package/skills/skill-creator-ultra/resources/pattern_detection.md +0 -200
- package/skills/skill-creator-ultra/resources/prompt_engineering.md +0 -531
- package/skills/skill-creator-ultra/resources/schemas.md +0 -430
- package/skills/skill-creator-ultra/resources/script_integration.md +0 -593
- package/skills/skill-creator-ultra/resources/scripts_guide.md +0 -339
- package/skills/skill-creator-ultra/resources/skill_template.md +0 -124
- package/skills/skill-creator-ultra/resources/skill_writing_guide.md +0 -634
- package/skills/skill-creator-ultra/resources/versioning_guide.md +0 -193
- package/skills/skill-creator-ultra/scripts/ci_eval.py +0 -200
- package/skills/skill-creator-ultra/scripts/package_skill.py +0 -165
- package/skills/skill-creator-ultra/scripts/simulate_skill.py +0 -398
- package/skills/skill-creator-ultra/scripts/skill_audit.py +0 -611
- package/skills/skill-creator-ultra/scripts/skill_compare.py +0 -265
- package/skills/skill-creator-ultra/scripts/skill_export.py +0 -334
- package/skills/skill-creator-ultra/scripts/skill_scaffold.py +0 -403
- package/skills/skill-creator-ultra/scripts/skill_stats.py +0 -339
- package/skills/skill-creator-ultra/scripts/validate_skill.py +0 -411
- package/skills/tailwind-mastery/SKILL.md +0 -229
- package/skills/vercel-react-best-practices/AGENTS.md +0 -3373
- package/skills/vercel-react-best-practices/README.md +0 -123
- package/skills/vercel-react-best-practices/SKILL.md +0 -143
- package/skills/vercel-react-best-practices/rules/_sections.md +0 -46
- package/skills/vercel-react-best-practices/rules/_template.md +0 -28
- package/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
- package/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
- package/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
- package/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
- package/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
- package/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
- package/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
- package/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
- package/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
- package/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
- package/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
- package/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
- package/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
- package/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
- package/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
- package/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
- package/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
- package/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
- package/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
- package/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
- package/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
- package/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
- package/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
- package/skills/vercel-react-best-practices/rules/js-flatmap-filter.md +0 -60
- package/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
- package/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
- package/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
- package/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
- package/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
- package/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
- package/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
- package/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
- package/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
- package/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
- package/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
- package/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
- package/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
- package/skills/vercel-react-best-practices/rules/rendering-resource-hints.md +0 -85
- package/skills/vercel-react-best-practices/rules/rendering-script-defer-async.md +0 -68
- package/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
- package/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
- package/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
- package/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
- package/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
- package/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
- package/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
- package/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
- package/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
- package/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
- package/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
- package/skills/vercel-react-best-practices/rules/rerender-no-inline-components.md +0 -82
- package/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
- package/skills/vercel-react-best-practices/rules/rerender-split-combined-hooks.md +0 -64
- package/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
- package/skills/vercel-react-best-practices/rules/rerender-use-deferred-value.md +0 -59
- package/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
- package/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
- package/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
- package/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
- package/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
- package/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
- package/skills/vercel-react-best-practices/rules/server-hoist-static-io.md +0 -142
- package/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
- package/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
- package/skills/web-design-guidelines/SKILL.md +0 -39
|
@@ -1,403 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env python3
|
|
2
|
-
"""
|
|
3
|
-
skill_scaffold.py — Tạo skeleton thư mục + files cho Skill mới
|
|
4
|
-
|
|
5
|
-
Sử dụng:
|
|
6
|
-
python skill_scaffold.py my-new-skill
|
|
7
|
-
python skill_scaffold.py my-new-skill --output ./path/to/skills/
|
|
8
|
-
python skill_scaffold.py my-new-skill --with-scripts
|
|
9
|
-
python skill_scaffold.py my-new-skill --full
|
|
10
|
-
python skill_scaffold.py my-new-skill --interactive
|
|
11
|
-
|
|
12
|
-
Modes:
|
|
13
|
-
(default) → Chỉ tạo SKILL.md cơ bản
|
|
14
|
-
--with-scripts → Thêm scripts/ với template
|
|
15
|
-
--full → Tạo đầy đủ: SKILL.md + scripts/ + resources/ + examples/
|
|
16
|
-
--interactive → Hỏi từng bước tên, mô tả, trigger...
|
|
17
|
-
|
|
18
|
-
Developed by Thân Công Hải — Skill Generator v3.2 Expert
|
|
19
|
-
"""
|
|
20
|
-
|
|
21
|
-
import sys
|
|
22
|
-
import os
|
|
23
|
-
import re
|
|
24
|
-
from datetime import datetime
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
class Colors:
|
|
28
|
-
PASS = '\033[92m'
|
|
29
|
-
FAIL = '\033[91m'
|
|
30
|
-
WARN = '\033[93m'
|
|
31
|
-
INFO = '\033[96m'
|
|
32
|
-
BOLD = '\033[1m'
|
|
33
|
-
DIM = '\033[2m'
|
|
34
|
-
RESET = '\033[0m'
|
|
35
|
-
|
|
36
|
-
@staticmethod
|
|
37
|
-
def enable_windows():
|
|
38
|
-
if os.name == 'nt':
|
|
39
|
-
try:
|
|
40
|
-
import ctypes
|
|
41
|
-
kernel32 = ctypes.windll.kernel32
|
|
42
|
-
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
|
|
43
|
-
except Exception:
|
|
44
|
-
pass
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
Colors.enable_windows()
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
# ============================================================
|
|
51
|
-
# TEMPLATES
|
|
52
|
-
# ============================================================
|
|
53
|
-
|
|
54
|
-
SKILL_TEMPLATE = '''---
|
|
55
|
-
name: {name}
|
|
56
|
-
description: |
|
|
57
|
-
{description}
|
|
58
|
-
Kích hoạt khi user yêu cầu "{trigger}".
|
|
59
|
-
---
|
|
60
|
-
|
|
61
|
-
# Goal
|
|
62
|
-
|
|
63
|
-
{goal}
|
|
64
|
-
|
|
65
|
-
# Instructions
|
|
66
|
-
|
|
67
|
-
## Bước 1: Tiếp nhận yêu cầu
|
|
68
|
-
|
|
69
|
-
Phân tích yêu cầu của user:
|
|
70
|
-
- Xác định input chính
|
|
71
|
-
- Xác nhận output mong muốn
|
|
72
|
-
- Hỏi lại nếu thiếu thông tin
|
|
73
|
-
|
|
74
|
-
## Bước 2: Xử lý
|
|
75
|
-
|
|
76
|
-
1. [Mô tả bước xử lý cụ thể]
|
|
77
|
-
2. [Bước tiếp theo]
|
|
78
|
-
3. [Bước cuối]
|
|
79
|
-
|
|
80
|
-
> 🛡️ **Error Recovery:**
|
|
81
|
-
> - Nếu input không hợp lệ → Hỏi lại user
|
|
82
|
-
> - Nếu kết quả không chắc chắn → Hiển thị cảnh báo
|
|
83
|
-
|
|
84
|
-
## Bước 3: Trả kết quả
|
|
85
|
-
|
|
86
|
-
Hiển thị kết quả theo format trong Examples.
|
|
87
|
-
|
|
88
|
-
# Examples
|
|
89
|
-
|
|
90
|
-
## Ví dụ 1: Happy Path
|
|
91
|
-
|
|
92
|
-
**Input:**
|
|
93
|
-
```
|
|
94
|
-
[Mô tả input mẫu]
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
**Thought Process:**
|
|
98
|
-
- Phân tích: [...]
|
|
99
|
-
- Quyết định: [...]
|
|
100
|
-
|
|
101
|
-
**Output:**
|
|
102
|
-
```
|
|
103
|
-
[Mô tả output mẫu]
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
## Ví dụ 2: Edge Case
|
|
107
|
-
|
|
108
|
-
**Input:**
|
|
109
|
-
```
|
|
110
|
-
[Input đặc biệt / thiếu thông tin]
|
|
111
|
-
```
|
|
112
|
-
|
|
113
|
-
**Output:**
|
|
114
|
-
```
|
|
115
|
-
[Cách xử lý edge case]
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
# Constraints
|
|
119
|
-
|
|
120
|
-
## DOs (Luôn luôn)
|
|
121
|
-
- LUÔN LUÔN xác nhận lại yêu cầu trước khi xử lý
|
|
122
|
-
- LUÔN LUÔN hiển thị kết quả theo format trong Examples
|
|
123
|
-
- LUÔN LUÔN thông báo nếu có uncertainty
|
|
124
|
-
|
|
125
|
-
## DON'Ts (Không được)
|
|
126
|
-
- KHÔNG ĐƯỢC bịa dữ liệu khi thiếu input
|
|
127
|
-
- KHÔNG ĐƯỢC bỏ qua edge cases
|
|
128
|
-
- KHÔNG ĐƯỢC thay đổi format output
|
|
129
|
-
|
|
130
|
-
<!-- Generated by Skill Generator v3.2 -->
|
|
131
|
-
'''
|
|
132
|
-
|
|
133
|
-
SCRIPT_TEMPLATE = '''#!/usr/bin/env python3
|
|
134
|
-
"""
|
|
135
|
-
{filename} — [Mô tả script]
|
|
136
|
-
|
|
137
|
-
Sử dụng:
|
|
138
|
-
python {filename} [arguments]
|
|
139
|
-
python {filename} --help
|
|
140
|
-
python {filename} --dry-run [arguments]
|
|
141
|
-
"""
|
|
142
|
-
|
|
143
|
-
import sys
|
|
144
|
-
import os
|
|
145
|
-
import argparse
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
def main():
|
|
149
|
-
parser = argparse.ArgumentParser(
|
|
150
|
-
description="{name} — Script hỗ trợ cho skill",
|
|
151
|
-
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
152
|
-
)
|
|
153
|
-
parser.add_argument('input', nargs='?', help='Input file hoặc data')
|
|
154
|
-
parser.add_argument('--dry-run', action='store_true', help='Chạy thử không thực thi')
|
|
155
|
-
parser.add_argument('--verbose', '-v', action='store_true', help='Hiển thị chi tiết')
|
|
156
|
-
|
|
157
|
-
args = parser.parse_args()
|
|
158
|
-
|
|
159
|
-
if args.dry_run:
|
|
160
|
-
print("[DRY RUN] Sẽ xử lý:", args.input)
|
|
161
|
-
return
|
|
162
|
-
|
|
163
|
-
# TODO: Implement logic
|
|
164
|
-
print(f"Processing: {{args.input}}")
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if __name__ == '__main__':
|
|
168
|
-
main()
|
|
169
|
-
'''
|
|
170
|
-
|
|
171
|
-
RESOURCE_TEMPLATE = '''# {title}
|
|
172
|
-
|
|
173
|
-
> Tài liệu tham khảo cho skill `{name}`
|
|
174
|
-
|
|
175
|
-
## Nội dung
|
|
176
|
-
|
|
177
|
-
[Thêm nội dung tham khảo ở đây]
|
|
178
|
-
|
|
179
|
-
## Nguồn tham khảo
|
|
180
|
-
|
|
181
|
-
- [Link 1]
|
|
182
|
-
- [Link 2]
|
|
183
|
-
'''
|
|
184
|
-
|
|
185
|
-
EXAMPLE_TEMPLATE = '''# Ví dụ: {title}
|
|
186
|
-
|
|
187
|
-
> Ví dụ chi tiết cho skill `{name}`
|
|
188
|
-
|
|
189
|
-
## Tình huống
|
|
190
|
-
|
|
191
|
-
[Mô tả tình huống]
|
|
192
|
-
|
|
193
|
-
## Input
|
|
194
|
-
|
|
195
|
-
```
|
|
196
|
-
[Dữ liệu input]
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
## Expected Output
|
|
200
|
-
|
|
201
|
-
```
|
|
202
|
-
[Kết quả mong đợi]
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
## Giải thích
|
|
206
|
-
|
|
207
|
-
[Tại sao output là như vậy]
|
|
208
|
-
'''
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
# ============================================================
|
|
212
|
-
# INTERACTIVE MODE
|
|
213
|
-
# ============================================================
|
|
214
|
-
|
|
215
|
-
def interactive_mode():
|
|
216
|
-
"""Hỏi user từng bước để tạo skill."""
|
|
217
|
-
print()
|
|
218
|
-
print(f"{Colors.BOLD} 🧩 Skill Scaffold — Chế độ tương tác{Colors.RESET}")
|
|
219
|
-
print(f" {Colors.DIM}Trả lời các câu hỏi để tạo skill mới{Colors.RESET}")
|
|
220
|
-
print()
|
|
221
|
-
|
|
222
|
-
name = input(f" 📌 Tên skill (kebab-case, ví dụ: price-quoter): ").strip()
|
|
223
|
-
if not name:
|
|
224
|
-
print(f" {Colors.FAIL}❌ Tên không được trống!{Colors.RESET}")
|
|
225
|
-
return None
|
|
226
|
-
|
|
227
|
-
# Validate name
|
|
228
|
-
if not re.match(r'^[a-z0-9][a-z0-9-]*$', name):
|
|
229
|
-
print(f" {Colors.WARN}⚠️ Tên nên dùng kebab-case (ví dụ: my-skill-name){Colors.RESET}")
|
|
230
|
-
name = re.sub(r'[^a-z0-9-]', '-', name.lower()).strip('-')
|
|
231
|
-
print(f" {Colors.INFO} → Đã sửa thành: {name}{Colors.RESET}")
|
|
232
|
-
|
|
233
|
-
description = input(f" 📝 Mô tả ngắn (1-2 câu): ").strip() or f"Skill {name}"
|
|
234
|
-
trigger = input(f" 🎯 Trigger phrase (user nói gì để kích hoạt?): ").strip() or name
|
|
235
|
-
goal = input(f" 🏁 Goal (skill làm gì — 1 câu): ").strip() or f"Thực hiện {name}"
|
|
236
|
-
|
|
237
|
-
with_scripts = input(f" 🔧 Có cần scripts không? (y/n, mặc định n): ").strip().lower() == 'y'
|
|
238
|
-
with_resources = input(f" 📚 Có cần resources không? (y/n, mặc định n): ").strip().lower() == 'y'
|
|
239
|
-
with_examples = input(f" 🎯 Có cần example files không? (y/n, mặc định n): ").strip().lower() == 'y'
|
|
240
|
-
|
|
241
|
-
return {
|
|
242
|
-
'name': name,
|
|
243
|
-
'description': description,
|
|
244
|
-
'trigger': trigger,
|
|
245
|
-
'goal': goal,
|
|
246
|
-
'with_scripts': with_scripts,
|
|
247
|
-
'with_resources': with_resources,
|
|
248
|
-
'with_examples': with_examples,
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
# ============================================================
|
|
253
|
-
# SCAFFOLD
|
|
254
|
-
# ============================================================
|
|
255
|
-
|
|
256
|
-
def scaffold_skill(name, output_dir=None, full=False, with_scripts=False,
|
|
257
|
-
interactive_data=None):
|
|
258
|
-
"""Tạo skeleton skill."""
|
|
259
|
-
|
|
260
|
-
if output_dir is None:
|
|
261
|
-
output_dir = '.'
|
|
262
|
-
|
|
263
|
-
skill_dir = os.path.join(output_dir, name)
|
|
264
|
-
|
|
265
|
-
if os.path.exists(skill_dir):
|
|
266
|
-
print(f"{Colors.FAIL}❌ Thư mục đã tồn tại: {skill_dir}{Colors.RESET}")
|
|
267
|
-
print(f" Xóa hoặc đổi tên thư mục cũ trước khi tạo mới.")
|
|
268
|
-
return False
|
|
269
|
-
|
|
270
|
-
# Get data
|
|
271
|
-
if interactive_data:
|
|
272
|
-
data = interactive_data
|
|
273
|
-
else:
|
|
274
|
-
data = {
|
|
275
|
-
'name': name,
|
|
276
|
-
'description': f'Skill {name} — [Mô tả ngắn]',
|
|
277
|
-
'trigger': name.replace('-', ' '),
|
|
278
|
-
'goal': f'[Mô tả goal cho {name}]',
|
|
279
|
-
'with_scripts': with_scripts or full,
|
|
280
|
-
'with_resources': full,
|
|
281
|
-
'with_examples': full,
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
created_files = []
|
|
285
|
-
|
|
286
|
-
# Create directories
|
|
287
|
-
os.makedirs(skill_dir, exist_ok=True)
|
|
288
|
-
|
|
289
|
-
# SKILL.md
|
|
290
|
-
skill_content = SKILL_TEMPLATE.format(
|
|
291
|
-
name=data['name'],
|
|
292
|
-
description=data['description'],
|
|
293
|
-
trigger=data['trigger'],
|
|
294
|
-
goal=data['goal'],
|
|
295
|
-
)
|
|
296
|
-
skill_path = os.path.join(skill_dir, 'SKILL.md')
|
|
297
|
-
with open(skill_path, 'w', encoding='utf-8') as f:
|
|
298
|
-
f.write(skill_content)
|
|
299
|
-
created_files.append(('SKILL.md', 'Bộ não chính của skill'))
|
|
300
|
-
|
|
301
|
-
# Scripts
|
|
302
|
-
if data.get('with_scripts') or full:
|
|
303
|
-
scripts_dir = os.path.join(skill_dir, 'scripts')
|
|
304
|
-
os.makedirs(scripts_dir, exist_ok=True)
|
|
305
|
-
|
|
306
|
-
script_content = SCRIPT_TEMPLATE.format(
|
|
307
|
-
filename=f'{name.replace("-", "_")}_helper.py',
|
|
308
|
-
name=name,
|
|
309
|
-
)
|
|
310
|
-
script_path = os.path.join(scripts_dir, f'{name.replace("-", "_")}_helper.py')
|
|
311
|
-
with open(script_path, 'w', encoding='utf-8') as f:
|
|
312
|
-
f.write(script_content)
|
|
313
|
-
created_files.append((f'scripts/{name.replace("-", "_")}_helper.py', 'Script hỗ trợ (template)'))
|
|
314
|
-
|
|
315
|
-
# Resources
|
|
316
|
-
if data.get('with_resources') or full:
|
|
317
|
-
resources_dir = os.path.join(skill_dir, 'resources')
|
|
318
|
-
os.makedirs(resources_dir, exist_ok=True)
|
|
319
|
-
|
|
320
|
-
resource_content = RESOURCE_TEMPLATE.format(title='Tài liệu tham khảo', name=name)
|
|
321
|
-
resource_path = os.path.join(resources_dir, 'reference.md')
|
|
322
|
-
with open(resource_path, 'w', encoding='utf-8') as f:
|
|
323
|
-
f.write(resource_content)
|
|
324
|
-
created_files.append(('resources/reference.md', 'Tài liệu tham khảo (template)'))
|
|
325
|
-
|
|
326
|
-
# Examples
|
|
327
|
-
if data.get('with_examples') or full:
|
|
328
|
-
examples_dir = os.path.join(skill_dir, 'examples')
|
|
329
|
-
os.makedirs(examples_dir, exist_ok=True)
|
|
330
|
-
|
|
331
|
-
example_content = EXAMPLE_TEMPLATE.format(title='Happy Path', name=name)
|
|
332
|
-
example_path = os.path.join(examples_dir, 'example_happy_path.md')
|
|
333
|
-
with open(example_path, 'w', encoding='utf-8') as f:
|
|
334
|
-
f.write(example_content)
|
|
335
|
-
created_files.append(('examples/example_happy_path.md', 'Ví dụ Happy Path (template)'))
|
|
336
|
-
|
|
337
|
-
# Output
|
|
338
|
-
print()
|
|
339
|
-
print(f"{Colors.BOLD}{'=' * 50}{Colors.RESET}")
|
|
340
|
-
print(f"{Colors.BOLD} 🧩 SKILL SCAFFOLD — Tạo skill mới{Colors.RESET}")
|
|
341
|
-
print(f"{Colors.BOLD}{'=' * 50}{Colors.RESET}")
|
|
342
|
-
print()
|
|
343
|
-
print(f" {Colors.PASS}✅ Đã tạo skill: {Colors.BOLD}{name}{Colors.RESET}")
|
|
344
|
-
print(f" {Colors.DIM}📁 Vị trí: {os.path.abspath(skill_dir)}{Colors.RESET}")
|
|
345
|
-
print()
|
|
346
|
-
|
|
347
|
-
# File tree
|
|
348
|
-
print(f" {Colors.BOLD}📂 Cấu trúc:{Colors.RESET}")
|
|
349
|
-
print(f" {name}/")
|
|
350
|
-
for i, (filepath, desc) in enumerate(created_files):
|
|
351
|
-
is_last = i == len(created_files) - 1
|
|
352
|
-
prefix = '└──' if is_last else '├──'
|
|
353
|
-
print(f" {prefix} {Colors.INFO}{filepath}{Colors.RESET} — {Colors.DIM}{desc}{Colors.RESET}")
|
|
354
|
-
print()
|
|
355
|
-
|
|
356
|
-
# Next steps
|
|
357
|
-
print(f" {Colors.BOLD}💡 Tiếp theo:{Colors.RESET}")
|
|
358
|
-
print(f" 1. Mở {Colors.INFO}{skill_dir}/SKILL.md{Colors.RESET} và điền nội dung")
|
|
359
|
-
print(f" 2. Chạy: {Colors.INFO}python skill_audit.py {skill_dir}/{Colors.RESET} để kiểm tra")
|
|
360
|
-
print(f" 3. Chạy: {Colors.INFO}python simulate_skill.py {skill_dir}/{Colors.RESET} để test")
|
|
361
|
-
print()
|
|
362
|
-
print(f"{Colors.BOLD}{'=' * 50}{Colors.RESET}")
|
|
363
|
-
print()
|
|
364
|
-
|
|
365
|
-
return True
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
if __name__ == '__main__':
|
|
369
|
-
if len(sys.argv) < 2:
|
|
370
|
-
print("Sử dụng: python skill_scaffold.py <skill-name> [options]")
|
|
371
|
-
print()
|
|
372
|
-
print("Options:")
|
|
373
|
-
print(" --output <dir> Thư mục output (mặc định: ./)")
|
|
374
|
-
print(" --with-scripts Thêm scripts/ với template")
|
|
375
|
-
print(" --full Tạo đầy đủ (scripts + resources + examples)")
|
|
376
|
-
print(" --interactive Chế độ tương tác hỏi từng bước")
|
|
377
|
-
print()
|
|
378
|
-
print("Ví dụ:")
|
|
379
|
-
print(" python skill_scaffold.py price-quoter")
|
|
380
|
-
print(" python skill_scaffold.py price-quoter --full")
|
|
381
|
-
print(" python skill_scaffold.py price-quoter --interactive")
|
|
382
|
-
print(" python skill_scaffold.py my-skill --output ./skills/")
|
|
383
|
-
sys.exit(1)
|
|
384
|
-
|
|
385
|
-
name = sys.argv[1]
|
|
386
|
-
output = None
|
|
387
|
-
full = '--full' in sys.argv
|
|
388
|
-
with_scripts = '--with-scripts' in sys.argv
|
|
389
|
-
interactive = '--interactive' in sys.argv
|
|
390
|
-
|
|
391
|
-
for i, arg in enumerate(sys.argv):
|
|
392
|
-
if arg == '--output' and i + 1 < len(sys.argv):
|
|
393
|
-
output = sys.argv[i + 1]
|
|
394
|
-
|
|
395
|
-
if interactive:
|
|
396
|
-
data = interactive_mode()
|
|
397
|
-
if data is None:
|
|
398
|
-
sys.exit(1)
|
|
399
|
-
success = scaffold_skill(data['name'], output, interactive_data=data)
|
|
400
|
-
else:
|
|
401
|
-
success = scaffold_skill(name, output, full=full, with_scripts=with_scripts)
|
|
402
|
-
|
|
403
|
-
sys.exit(0 if success else 1)
|