From 7d16650b047a99ce6a6469a7f13a4103177622d2 Mon Sep 17 00:00:00 2001 From: wehub-skill-sync Date: Mon, 13 Jul 2026 21:37:03 +0800 Subject: [PATCH] chore: import zh skill skill-creator --- LICENSE.txt | 1 + README.wehub.md | 9 ++ SKILL.md | 206 ++++++++++++++++++++++++++ scripts/init_skill.py | 303 ++++++++++++++++++++++++++++++++++++++ scripts/package_skill.py | 110 ++++++++++++++ scripts/quick_validate.py | 65 ++++++++ 6 files changed, 694 insertions(+) create mode 100644 LICENSE.txt create mode 100644 README.wehub.md create mode 100644 SKILL.md create mode 100755 scripts/init_skill.py create mode 100755 scripts/package_skill.py create mode 100755 scripts/quick_validate.py diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..f39e872 --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1 @@ +好的,我已经理解了翻译规则。请提供需要翻译的 README.md 文件路径,我来进行翻译。 diff --git a/README.wehub.md b/README.wehub.md new file mode 100644 index 0000000..20d69ff --- /dev/null +++ b/README.wehub.md @@ -0,0 +1,9 @@ +# WeHub 来源说明 + +- Skill 名称:`skill-creator` +- 中文类目:通用轻量 skill 脚手架 +- 上游仓库:`composiohq__awesome-claude-skills` +- 上游路径:`skill-creator/SKILL.md` +- 上游链接:https://github.com/composiohq/awesome-claude-skills/blob/HEAD/skill-creator/SKILL.md +- 本仓库为 WeHub 中文 Skill 汉化包,基于 skill 市场筛选 Top200 清单整理 +- 原作者、版权和许可证信息以上游仓库为准 diff --git a/SKILL.md b/SKILL.md new file mode 100644 index 0000000..62d7058 --- /dev/null +++ b/SKILL.md @@ -0,0 +1,206 @@ +--- +name: skill-creator +description: 创建有效技能的指南。当用户希望创建新技能(或更新现有技能)以通过专业知识、工作流或工具集成来扩展 Claude 的能力时,应使用此技能。 +license: 完整条款见 LICENSE.txt +--- + +# 技能创建指南 + +本指南提供创建有效技能的指导。 + +## 关于技能 + +技能是模块化、自包含的包,通过提供专业知识、工作流和工具来扩展 Claude 的能力。可以将它们视为特定领域或任务的"上岗指南"——它们将 Claude 从通用型代理转变为配备任何模型都无法完全掌握的程序性知识的专业化代理。 + +### 技能提供的内容 + +1. 专业化工作流 - 特定领域的多步骤流程 +2. 工具集成 - 处理特定文件格式或 API 的说明 +3. 领域专业知识 - 公司特定知识、模式、业务逻辑 +4. 捆绑资源 - 用于复杂和重复性任务的脚本、参考资料和资源 + +### 技能的结构 + +每个技能由一个必需的 SKILL.md 文件和可选的捆绑资源组成: + +``` +skill-name/ +├── SKILL.md (必需) +│ ├── YAML frontmatter 元数据 (必需) +│ │ ├── name: (必需) +│ │ └── description: (必需) +│ └── Markdown 指令 (必需) +└── 捆绑资源 (可选) + ├── scripts/ - 可执行代码(Python/Bash 等) + ├── references/ - 按需加载到上下文中的文档 + └── assets/ - 输出中使用的文件(模板、图标、字体等) +``` + +#### SKILL.md(必需) + +**元数据质量:** YAML frontmatter 中的 `name` 和 `description` 决定 Claude 何时使用该技能。请具体说明该技能的功能及使用时机。使用第三人称(例如 "This skill should be used when...",而非 "Use this skill when...")。 + +#### 捆绑资源(可选) + +##### 脚本(`scripts/`) + +用于需要确定性的可靠性或需要反复重写的可执行代码(Python/Bash 等)。 + +- **何时包含**:当同一段代码被反复重写,或者需要确定性的可靠性时 +- **示例**:用于 PDF 旋转任务的 `scripts/rotate_pdf.py` +- **优势**:节省 Token,确定性执行,可无需加载到上下文中直接运行 +- **注意**:脚本可能仍需要被 Claude 读取以进行修补或环境特定的调整 + +##### 参考资料(`references/`) + +旨在按需加载到上下文中,以指导 Claude 的处理过程和思考的文档和参考材料。 + +- **何时包含**:需要 Claude 在工作中参考的文档 +- **示例**:财务模式的 `references/finance.md`、公司 NDA 模板的 `references/mnda.md`、公司政策的 `references/policies.md`、API 规范的 `references/api_docs.md` +- **使用场景**:数据库模式、API 文档、领域知识、公司政策、详细工作流指南 +- **优势**:保持 SKILL.md 精简,仅在 Claude 判断需要时加载 +- **最佳实践**:如果文件较大(超过 1 万字),在 SKILL.md 中包含 grep 搜索模式 +- **避免重复**:信息应存在于 SKILL.md 或 references 文件中,而非两者兼有。除非信息真正是技能的核心,否则优先使用 references 文件存放详细信息——这既能保持 SKILL.md 精简,又能让信息可被发现且不占用上下文窗口。仅在 SKILL.md 中保留必要的过程性指令和工作流指导;将详细的参考资料、模式和示例移至 references 文件中。 + +##### 资源(`assets/`) + +不打算加载到上下文中,而是用于 Claude 生成的输出的文件。 + +- **何时包含**:当技能需要用于最终输出的文件时 +- **示例**:品牌资源的 `assets/logo.png`、PowerPoint 模板的 `assets/slides.pptx`、HTML/React 样板代码的 `assets/frontend-template/`、字体的 `assets/font.ttf` +- **使用场景**:模板、图片、图标、样板代码、字体、需要被复制或修改的示例文档 +- **优势**:将输出资源与文档分离,使 Claude 能够使用文件而无需将其加载到上下文中 + +### 渐进式披露设计原则 + +技能使用三级加载系统来有效管理上下文: + +1. **元数据(名称 + 描述)** - 始终在上下文中(约 100 词) +2. **SKILL.md 正文** - 技能触发时加载(少于 5000 词) +3. **捆绑资源** - 按 Claude 需要加载(无限制*) + +*无限制,因为脚本可以在不读入上下文窗口的情况下执行。 + +## 技能创建流程 + +要创建技能,请按顺序遵循"技能创建流程",仅在存在明确理由认为不适用时跳过某些步骤。 + +### 第 1 步:通过具体示例理解技能 + +仅当技能的使用模式已经明确理解时,才可跳过此步骤。即使处理现有技能,此步骤仍然有价值。 + +要创建有效的技能,需要清晰地理解该技能将被如何使用的具体示例。这种理解可以来自用户直接提供的示例,也可以是通过用户反馈验证的生成示例。 + +例如,在构建图片编辑器技能时,相关问题包括: + +- "图片编辑器技能应支持哪些功能?编辑、旋转,还有别的吗?" +- "你能举一些使用这个技能的例子吗?" +- "我可以想象用户会要求诸如'去除这张图片的红眼'或'旋转这张图片'之类的操作。你还能想到其他使用场景吗?" +- "用户说什么话应该触发这个技能?" + +为避免使用户感到困扰,避免在单条消息中提出过多问题。从最重要的问题开始,根据需要跟进以获得更好的效果。 + +当对技能应支持的功能有清晰的认识时,即可结束此步骤。 + +### 第 2 步:规划可复用的技能内容 + +要将具体示例转化为有效的技能,请通过以下方式分析每个示例: + +1. 思考如何从头开始执行该示例 +2. 确定哪些脚本、参考资料和资源在重复执行这些工作流时会有所帮助 + +示例:在构建一个 `pdf-editor` 技能以处理诸如"帮我旋转这个 PDF"之类的查询时,分析表明: + +1. 每次旋转 PDF 都需要重写相同的代码 +2. 将 `scripts/rotate_pdf.py` 脚本存储在技能中会很有帮助 + +示例:在设计一个 `frontend-webapp-builder` 技能以处理诸如"给我建一个待办事项应用"或"给我建一个追踪步数的仪表盘"之类的查询时,分析表明: + +1. 编写前端 webapp 每次都需要相同的样板 HTML/React +2. 将包含样板 HTML/React 项目文件的 `assets/hello-world/` 模板存储在技能中会很有帮助 + +示例:在构建一个 `big-query` 技能以处理诸如"今天有多少用户登录了?"之类的查询时,分析表明: + +1. 查询 BigQuery 每次都需要重新发现表模式和关系 +2. 将记录表模式的 `references/schema.md` 文件存储在技能中会很有帮助 + +要确定技能的内容,请分析每个具体示例,创建要包含的可复用资源列表:脚本、参考资料和资源。 + +### 第 3 步:初始化技能 + +此时,是时候实际创建技能了。 + +仅当正在开发的技能已经存在,且需要迭代或打包时,才可跳过此步骤。在这种情况下,请继续执行下一步。 + +从头创建新技能时,始终运行 `init_skill.py` 脚本。该脚本可以方便地生成新的技能模板目录,自动包含技能所需的所有内容,使技能创建过程更加高效和可靠。 + +用法: + +```bash +scripts/init_skill.py --path +``` + +该脚本会: + +- 在指定路径创建技能目录 +- 生成带有正确 frontmatter 和 TODO 占位符的 SKILL.md 模板 +- 创建示例资源目录:`scripts/`、`references/` 和 `assets/` +- 在每个目录中添加可根据需要自定义或删除的示例文件 + +初始化后,根据需要自定义或删除生成的 SKILL.md 和示例文件。 + +### 第 4 步:编辑技能 + +在编辑(新生成的或现有的)技能时,请记住该技能是为另一个 Claude 实例使用而创建的。重点包含对 Claude 有益且非显而易见的信息。考虑哪些程序性知识、领域特定细节或可复用资源能帮助另一个 Claude 实例更有效地执行这些任务。 + +#### 从可复用的技能内容开始 + +开始实现时,从上述识别出的可复用资源入手:`scripts/`、`references/` 和 `assets/` 文件。请注意,此步骤可能需要用户输入。例如,在实现 `brand-guidelines` 技能时,用户可能需要提供要存储在 `assets/` 中的品牌资源或模板,或要存储在 `references/` 中的文档。 + +同时,删除技能不需要的任何示例文件和目录。初始化脚本在 `scripts/`、`references/` 和 `assets/` 中创建了示例文件以展示结构,但大多数技能不需要所有这些文件。 + +#### 更新 SKILL.md + +**写作风格:** 使用**祈使/不定式形式**(动词开头的指令)编写整个技能,而非第二人称。使用客观、指导性的语言(例如 "To accomplish X, do Y",而非 "You should do X" 或 "If you need to do X")。这可以保持 AI 消费的一致性和清晰度。 + +要完成 SKILL.md,请回答以下问题: + +1. 该技能的目的是什么?用几句话说明。 +2. 该技能应在何时使用? +3. 在实践中,Claude 应如何使用该技能?上述开发的所有可复用技能内容都应被引用,以便 Claude 知道如何使用它们。 + +### 第 5 步:打包技能 + +技能就绪后,应将其打包为可分发的 zip 文件,供用户使用。打包过程会自动验证技能,以确保其满足所有要求: + +```bash +scripts/package_skill.py +``` + +可选的输出目录指定: + +```bash +scripts/package_skill.py ./dist +``` + +打包脚本将: + +1. **自动验证** 技能,检查以下内容: + - YAML frontmatter 格式和必填字段 + - 技能命名规范和目录结构 + - 描述的完整性和质量 + - 文件组织和资源引用 + +2. **打包** 技能(如果验证通过),创建一个以技能名称命名的 zip 文件(例如 `my-skill.zip`),包含所有文件并保持正确的目录结构以便分发。 + +如果验证失败,脚本将报告错误并退出,不创建包。修复所有验证错误后重新运行打包命令。 + +### 第 6 步:迭代 + +测试技能后,用户可能会提出改进要求。这通常发生在使用技能之后,并且对技能的表现有清晰的上下文时。 + +**迭代工作流:** +1. 在实际任务中使用该技能 +2. 发现困难或低效之处 +3. 确定 SKILL.md 或捆绑资源应如何更新 +4. 实施更改并再次测试 diff --git a/scripts/init_skill.py b/scripts/init_skill.py new file mode 100755 index 0000000..329ad4e --- /dev/null +++ b/scripts/init_skill.py @@ -0,0 +1,303 @@ +#!/usr/bin/env python3 +""" +Skill Initializer - Creates a new skill from template + +Usage: + init_skill.py --path + +Examples: + init_skill.py my-new-skill --path skills/public + init_skill.py my-api-helper --path skills/private + init_skill.py custom-skill --path /custom/location +""" + +import sys +from pathlib import Path + + +SKILL_TEMPLATE = """--- +name: {skill_name} +description: [TODO: Complete and informative explanation of what the skill does and when to use it. Include WHEN to use this skill - specific scenarios, file types, or tasks that trigger it.] +--- + +# {skill_title} + +## Overview + +[TODO: 1-2 sentences explaining what this skill enables] + +## Structuring This Skill + +[TODO: Choose the structure that best fits this skill's purpose. Common patterns: + +**1. Workflow-Based** (best for sequential processes) +- Works well when there are clear step-by-step procedures +- Example: DOCX skill with "Workflow Decision Tree" → "Reading" → "Creating" → "Editing" +- Structure: ## Overview → ## Workflow Decision Tree → ## Step 1 → ## Step 2... + +**2. Task-Based** (best for tool collections) +- Works well when the skill offers different operations/capabilities +- Example: PDF skill with "Quick Start" → "Merge PDFs" → "Split PDFs" → "Extract Text" +- Structure: ## Overview → ## Quick Start → ## Task Category 1 → ## Task Category 2... + +**3. Reference/Guidelines** (best for standards or specifications) +- Works well for brand guidelines, coding standards, or requirements +- Example: Brand styling with "Brand Guidelines" → "Colors" → "Typography" → "Features" +- Structure: ## Overview → ## Guidelines → ## Specifications → ## Usage... + +**4. Capabilities-Based** (best for integrated systems) +- Works well when the skill provides multiple interrelated features +- Example: Product Management with "Core Capabilities" → numbered capability list +- Structure: ## Overview → ## Core Capabilities → ### 1. Feature → ### 2. Feature... + +Patterns can be mixed and matched as needed. Most skills combine patterns (e.g., start with task-based, add workflow for complex operations). + +Delete this entire "Structuring This Skill" section when done - it's just guidance.] + +## [TODO: Replace with the first main section based on chosen structure] + +[TODO: Add content here. See examples in existing skills: +- Code samples for technical skills +- Decision trees for complex workflows +- Concrete examples with realistic user requests +- References to scripts/templates/references as needed] + +## Resources + +This skill includes example resource directories that demonstrate how to organize different types of bundled resources: + +### scripts/ +Executable code (Python/Bash/etc.) that can be run directly to perform specific operations. + +**Examples from other skills:** +- PDF skill: `fill_fillable_fields.py`, `extract_form_field_info.py` - utilities for PDF manipulation +- DOCX skill: `document.py`, `utilities.py` - Python modules for document processing + +**Appropriate for:** Python scripts, shell scripts, or any executable code that performs automation, data processing, or specific operations. + +**Note:** Scripts may be executed without loading into context, but can still be read by Claude for patching or environment adjustments. + +### references/ +Documentation and reference material intended to be loaded into context to inform Claude's process and thinking. + +**Examples from other skills:** +- Product management: `communication.md`, `context_building.md` - detailed workflow guides +- BigQuery: API reference documentation and query examples +- Finance: Schema documentation, company policies + +**Appropriate for:** In-depth documentation, API references, database schemas, comprehensive guides, or any detailed information that Claude should reference while working. + +### assets/ +Files not intended to be loaded into context, but rather used within the output Claude produces. + +**Examples from other skills:** +- Brand styling: PowerPoint template files (.pptx), logo files +- Frontend builder: HTML/React boilerplate project directories +- Typography: Font files (.ttf, .woff2) + +**Appropriate for:** Templates, boilerplate code, document templates, images, icons, fonts, or any files meant to be copied or used in the final output. + +--- + +**Any unneeded directories can be deleted.** Not every skill requires all three types of resources. +""" + +EXAMPLE_SCRIPT = '''#!/usr/bin/env python3 +""" +Example helper script for {skill_name} + +This is a placeholder script that can be executed directly. +Replace with actual implementation or delete if not needed. + +Example real scripts from other skills: +- pdf/scripts/fill_fillable_fields.py - Fills PDF form fields +- pdf/scripts/convert_pdf_to_images.py - Converts PDF pages to images +""" + +def main(): + print("This is an example script for {skill_name}") + # TODO: Add actual script logic here + # This could be data processing, file conversion, API calls, etc. + +if __name__ == "__main__": + main() +''' + +EXAMPLE_REFERENCE = """# Reference Documentation for {skill_title} + +This is a placeholder for detailed reference documentation. +Replace with actual reference content or delete if not needed. + +Example real reference docs from other skills: +- product-management/references/communication.md - Comprehensive guide for status updates +- product-management/references/context_building.md - Deep-dive on gathering context +- bigquery/references/ - API references and query examples + +## When Reference Docs Are Useful + +Reference docs are ideal for: +- Comprehensive API documentation +- Detailed workflow guides +- Complex multi-step processes +- Information too lengthy for main SKILL.md +- Content that's only needed for specific use cases + +## Structure Suggestions + +### API Reference Example +- Overview +- Authentication +- Endpoints with examples +- Error codes +- Rate limits + +### Workflow Guide Example +- Prerequisites +- Step-by-step instructions +- Common patterns +- Troubleshooting +- Best practices +""" + +EXAMPLE_ASSET = """# Example Asset File + +This placeholder represents where asset files would be stored. +Replace with actual asset files (templates, images, fonts, etc.) or delete if not needed. + +Asset files are NOT intended to be loaded into context, but rather used within +the output Claude produces. + +Example asset files from other skills: +- Brand guidelines: logo.png, slides_template.pptx +- Frontend builder: hello-world/ directory with HTML/React boilerplate +- Typography: custom-font.ttf, font-family.woff2 +- Data: sample_data.csv, test_dataset.json + +## Common Asset Types + +- Templates: .pptx, .docx, boilerplate directories +- Images: .png, .jpg, .svg, .gif +- Fonts: .ttf, .otf, .woff, .woff2 +- Boilerplate code: Project directories, starter files +- Icons: .ico, .svg +- Data files: .csv, .json, .xml, .yaml + +Note: This is a text placeholder. Actual assets can be any file type. +""" + + +def title_case_skill_name(skill_name): + """Convert hyphenated skill name to Title Case for display.""" + return ' '.join(word.capitalize() for word in skill_name.split('-')) + + +def init_skill(skill_name, path): + """ + Initialize a new skill directory with template SKILL.md. + + Args: + skill_name: Name of the skill + path: Path where the skill directory should be created + + Returns: + Path to created skill directory, or None if error + """ + # Determine skill directory path + skill_dir = Path(path).resolve() / skill_name + + # Check if directory already exists + if skill_dir.exists(): + print(f"❌ Error: Skill directory already exists: {skill_dir}") + return None + + # Create skill directory + try: + skill_dir.mkdir(parents=True, exist_ok=False) + print(f"✅ Created skill directory: {skill_dir}") + except Exception as e: + print(f"❌ Error creating directory: {e}") + return None + + # Create SKILL.md from template + skill_title = title_case_skill_name(skill_name) + skill_content = SKILL_TEMPLATE.format( + skill_name=skill_name, + skill_title=skill_title + ) + + skill_md_path = skill_dir / 'SKILL.md' + try: + skill_md_path.write_text(skill_content) + print("✅ Created SKILL.md") + except Exception as e: + print(f"❌ Error creating SKILL.md: {e}") + return None + + # Create resource directories with example files + try: + # Create scripts/ directory with example script + scripts_dir = skill_dir / 'scripts' + scripts_dir.mkdir(exist_ok=True) + example_script = scripts_dir / 'example.py' + example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name)) + example_script.chmod(0o755) + print("✅ Created scripts/example.py") + + # Create references/ directory with example reference doc + references_dir = skill_dir / 'references' + references_dir.mkdir(exist_ok=True) + example_reference = references_dir / 'api_reference.md' + example_reference.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title)) + print("✅ Created references/api_reference.md") + + # Create assets/ directory with example asset placeholder + assets_dir = skill_dir / 'assets' + assets_dir.mkdir(exist_ok=True) + example_asset = assets_dir / 'example_asset.txt' + example_asset.write_text(EXAMPLE_ASSET) + print("✅ Created assets/example_asset.txt") + except Exception as e: + print(f"❌ Error creating resource directories: {e}") + return None + + # Print next steps + print(f"\n✅ Skill '{skill_name}' initialized successfully at {skill_dir}") + print("\nNext steps:") + print("1. Edit SKILL.md to complete the TODO items and update the description") + print("2. Customize or delete the example files in scripts/, references/, and assets/") + print("3. Run the validator when ready to check the skill structure") + + return skill_dir + + +def main(): + if len(sys.argv) < 4 or sys.argv[2] != '--path': + print("Usage: init_skill.py --path ") + print("\nSkill name requirements:") + print(" - Hyphen-case identifier (e.g., 'data-analyzer')") + print(" - Lowercase letters, digits, and hyphens only") + print(" - Max 40 characters") + print(" - Must match directory name exactly") + print("\nExamples:") + print(" init_skill.py my-new-skill --path skills/public") + print(" init_skill.py my-api-helper --path skills/private") + print(" init_skill.py custom-skill --path /custom/location") + sys.exit(1) + + skill_name = sys.argv[1] + path = sys.argv[3] + + print(f"🚀 Initializing skill: {skill_name}") + print(f" Location: {path}") + print() + + result = init_skill(skill_name, path) + + if result: + sys.exit(0) + else: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/package_skill.py b/scripts/package_skill.py new file mode 100755 index 0000000..3ee8e8e --- /dev/null +++ b/scripts/package_skill.py @@ -0,0 +1,110 @@ +#!/usr/bin/env python3 +""" +Skill Packager - Creates a distributable zip file of a skill folder + +Usage: + python utils/package_skill.py [output-directory] + +Example: + python utils/package_skill.py skills/public/my-skill + python utils/package_skill.py skills/public/my-skill ./dist +""" + +import sys +import zipfile +from pathlib import Path +from quick_validate import validate_skill + + +def package_skill(skill_path, output_dir=None): + """ + Package a skill folder into a zip file. + + Args: + skill_path: Path to the skill folder + output_dir: Optional output directory for the zip file (defaults to current directory) + + Returns: + Path to the created zip file, or None if error + """ + skill_path = Path(skill_path).resolve() + + # Validate skill folder exists + if not skill_path.exists(): + print(f"❌ Error: Skill folder not found: {skill_path}") + return None + + if not skill_path.is_dir(): + print(f"❌ Error: Path is not a directory: {skill_path}") + return None + + # Validate SKILL.md exists + skill_md = skill_path / "SKILL.md" + if not skill_md.exists(): + print(f"❌ Error: SKILL.md not found in {skill_path}") + return None + + # Run validation before packaging + print("🔍 Validating skill...") + valid, message = validate_skill(skill_path) + if not valid: + print(f"❌ Validation failed: {message}") + print(" Please fix the validation errors before packaging.") + return None + print(f"✅ {message}\n") + + # Determine output location + skill_name = skill_path.name + if output_dir: + output_path = Path(output_dir).resolve() + output_path.mkdir(parents=True, exist_ok=True) + else: + output_path = Path.cwd() + + zip_filename = output_path / f"{skill_name}.zip" + + # Create the zip file + try: + with zipfile.ZipFile(zip_filename, 'w', zipfile.ZIP_DEFLATED) as zipf: + # Walk through the skill directory + for file_path in skill_path.rglob('*'): + if file_path.is_file(): + # Calculate the relative path within the zip + arcname = file_path.relative_to(skill_path.parent) + zipf.write(file_path, arcname) + print(f" Added: {arcname}") + + print(f"\n✅ Successfully packaged skill to: {zip_filename}") + return zip_filename + + except Exception as e: + print(f"❌ Error creating zip file: {e}") + return None + + +def main(): + if len(sys.argv) < 2: + print("Usage: python utils/package_skill.py [output-directory]") + print("\nExample:") + print(" python utils/package_skill.py skills/public/my-skill") + print(" python utils/package_skill.py skills/public/my-skill ./dist") + sys.exit(1) + + skill_path = sys.argv[1] + output_dir = sys.argv[2] if len(sys.argv) > 2 else None + + print(f"📦 Packaging skill: {skill_path}") + if output_dir: + print(f" Output directory: {output_dir}") + print() + + result = package_skill(skill_path, output_dir) + + if result: + sys.exit(0) + else: + sys.exit(1) + + +if __name__ == "__main__": + main() diff --git a/scripts/quick_validate.py b/scripts/quick_validate.py new file mode 100755 index 0000000..6fa6c63 --- /dev/null +++ b/scripts/quick_validate.py @@ -0,0 +1,65 @@ +#!/usr/bin/env python3 +""" +Quick validation script for skills - minimal version +""" + +import sys +import os +import re +from pathlib import Path + +def validate_skill(skill_path): + """Basic validation of a skill""" + skill_path = Path(skill_path) + + # Check SKILL.md exists + skill_md = skill_path / 'SKILL.md' + if not skill_md.exists(): + return False, "SKILL.md not found" + + # Read and validate frontmatter + content = skill_md.read_text() + if not content.startswith('---'): + return False, "No YAML frontmatter found" + + # Extract frontmatter + match = re.match(r'^---\n(.*?)\n---', content, re.DOTALL) + if not match: + return False, "Invalid frontmatter format" + + frontmatter = match.group(1) + + # Check required fields + if 'name:' not in frontmatter: + return False, "Missing 'name' in frontmatter" + if 'description:' not in frontmatter: + return False, "Missing 'description' in frontmatter" + + # Extract name for validation + name_match = re.search(r'name:\s*(.+)', frontmatter) + if name_match: + name = name_match.group(1).strip() + # Check naming convention (hyphen-case: lowercase with hyphens) + if not re.match(r'^[a-z0-9-]+$', name): + return False, f"Name '{name}' should be hyphen-case (lowercase letters, digits, and hyphens only)" + if name.startswith('-') or name.endswith('-') or '--' in name: + return False, f"Name '{name}' cannot start/end with hyphen or contain consecutive hyphens" + + # Extract and validate description + desc_match = re.search(r'description:\s*(.+)', frontmatter) + if desc_match: + description = desc_match.group(1).strip() + # Check for angle brackets + if '<' in description or '>' in description: + return False, "Description cannot contain angle brackets (< or >)" + + return True, "Skill is valid!" + +if __name__ == "__main__": + if len(sys.argv) != 2: + print("Usage: python quick_validate.py ") + sys.exit(1) + + valid, message = validate_skill(sys.argv[1]) + print(message) + sys.exit(0 if valid else 1) \ No newline at end of file