@rfxlamia/skillkit 1.1.0 → 1.2.0

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 (247) hide show
  1. package/agents/agents/creative-copywriter.md +212 -0
  2. package/agents/agents/dario-amodei.md +135 -0
  3. package/agents/agents/doc-simplifier.md +63 -0
  4. package/agents/agents/kotlin-pro.md +433 -0
  5. package/agents/agents/red-team.md +136 -0
  6. package/agents/agents/sam-altman.md +121 -0
  7. package/agents/agents/seo-manager.md +184 -0
  8. package/package.json +1 -1
  9. package/skills/skillkit-help/SKILL.md +81 -0
  10. package/skills/skillkit-help/knowledge/application/09-case-studies.md +257 -0
  11. package/skills/skillkit-help/knowledge/application/12-testing-and-validation.md +276 -0
  12. package/skills/skillkit-help/knowledge/foundation/01-why-skills-exist.md +246 -0
  13. package/skills/skillkit-help/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
  14. package/skills/skillkit-help/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
  15. package/skills/skillkit-help/knowledge/foundation/06-platform-constraints.md +237 -0
  16. package/skills/skillkit-help/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
  17. package/skills/skillkit-help/template/SKILL.md +52 -0
  18. package/skills/skills/adversarial-review/SKILL.md +219 -0
  19. package/skills/skills/baby-education/SKILL.md +260 -0
  20. package/skills/skills/baby-education/references/advanced-techniques.md +323 -0
  21. package/skills/skills/baby-education/references/transformations.md +345 -0
  22. package/skills/skills/been-there-done-that/SKILL.md +455 -0
  23. package/skills/skills/been-there-done-that/references/analysis-patterns.md +162 -0
  24. package/skills/skills/been-there-done-that/references/git-commands.md +132 -0
  25. package/skills/skills/been-there-done-that/references/tree-insertion-logic.md +145 -0
  26. package/skills/skills/coolhunter/SKILL.md +270 -0
  27. package/skills/skills/coolhunter/assets/elicitation-methods.csv +51 -0
  28. package/skills/skills/coolhunter/knowledge/elicitation-methods.md +312 -0
  29. package/skills/skills/coolhunter/references/workflow-execution.md +238 -0
  30. package/skills/skills/coolhunter/workflow-plan-coolhunter.md +232 -0
  31. package/skills/skills/creative-copywriting/SKILL.md +324 -0
  32. package/skills/skills/creative-copywriting/databases/README.md +60 -0
  33. package/skills/skills/creative-copywriting/databases/carousel-structures.csv +16 -0
  34. package/skills/skills/creative-copywriting/databases/emotional-arcs.csv +11 -0
  35. package/skills/skills/creative-copywriting/databases/hook-formulas.csv +51 -0
  36. package/skills/skills/creative-copywriting/databases/power-words.csv +201 -0
  37. package/skills/skills/creative-copywriting/databases/psychological-triggers.csv +21 -0
  38. package/skills/skills/creative-copywriting/databases/read-more-patterns.csv +26 -0
  39. package/skills/skills/creative-copywriting/databases/swipe-triggers.csv +31 -0
  40. package/skills/skills/creative-copywriting/references/carousel-psychology.md +223 -0
  41. package/skills/skills/creative-copywriting/references/hook-anatomy.md +169 -0
  42. package/skills/skills/creative-copywriting/references/power-word-science.md +134 -0
  43. package/skills/skills/creative-copywriting/references/storytelling-frameworks.md +157 -0
  44. package/skills/skills/diverse-content-gen/SKILL.md +201 -0
  45. package/skills/skills/diverse-content-gen/references/advanced-techniques.md +320 -0
  46. package/skills/skills/diverse-content-gen/references/research-findings.md +379 -0
  47. package/skills/skills/diverse-content-gen/references/task-workflows.md +241 -0
  48. package/skills/skills/diverse-content-gen/references/tool-integration.md +419 -0
  49. package/skills/skills/diverse-content-gen/references/troubleshooting.md +426 -0
  50. package/skills/skills/diverse-content-gen/references/vs-core-technique.md +240 -0
  51. package/skills/skills/framework-critical-thinking/SKILL.md +220 -0
  52. package/skills/skills/framework-critical-thinking/references/bias_detector.md +375 -0
  53. package/skills/skills/framework-critical-thinking/references/fallback_handler.md +239 -0
  54. package/skills/skills/framework-critical-thinking/references/memory_curator.md +161 -0
  55. package/skills/skills/framework-critical-thinking/references/metacognitive_monitor.md +297 -0
  56. package/skills/skills/framework-critical-thinking/references/producer_critic_orchestrator.md +333 -0
  57. package/skills/skills/framework-critical-thinking/references/reasoning_router.md +235 -0
  58. package/skills/skills/framework-critical-thinking/references/reasoning_validator.md +97 -0
  59. package/skills/skills/framework-critical-thinking/references/reflection_trigger.md +78 -0
  60. package/skills/skills/framework-critical-thinking/references/self_verification.md +388 -0
  61. package/skills/skills/framework-critical-thinking/references/uncertainty_quantifier.md +207 -0
  62. package/skills/skills/framework-initiative/SKILL.md +231 -0
  63. package/skills/skills/framework-initiative/references/examples.md +150 -0
  64. package/skills/skills/framework-initiative/references/impact-analysis.md +157 -0
  65. package/skills/skills/framework-initiative/references/intent-patterns.md +145 -0
  66. package/skills/skills/framework-initiative/references/star-framework.md +165 -0
  67. package/skills/skills/humanize-docs/SKILL.md +203 -0
  68. package/skills/skills/humanize-docs/references/advanced-techniques.md +13 -0
  69. package/skills/skills/humanize-docs/references/core-transformations.md +368 -0
  70. package/skills/skills/humanize-docs/references/detection-patterns.md +400 -0
  71. package/skills/skills/humanize-docs/references/examples-gallery.md +374 -0
  72. package/skills/skills/imagine/SKILL.md +190 -0
  73. package/skills/skills/imagine/references/artstyle-corporate-memphis.md +625 -0
  74. package/skills/skills/imagine/references/artstyle-crewdson-hyperrealism.md +295 -0
  75. package/skills/skills/imagine/references/artstyle-iphone-social-media.md +426 -0
  76. package/skills/skills/imagine/references/artstyle-sciencesaru.md +276 -0
  77. package/skills/skills/pre-deploy-checklist/README.md +26 -0
  78. package/skills/skills/pre-deploy-checklist/SKILL.md +153 -0
  79. package/skills/skills/pre-deploy-checklist/references/checklist-categories.md +174 -0
  80. package/skills/skills/pre-deploy-checklist/references/domain-prompts.md +216 -0
  81. package/skills/skills/prompt-engineering/SKILL.md +209 -0
  82. package/skills/skills/prompt-engineering/references/advanced-combinations.md +444 -0
  83. package/skills/skills/prompt-engineering/references/chain-of-thought.md +140 -0
  84. package/skills/skills/prompt-engineering/references/decision_matrix.md +220 -0
  85. package/skills/skills/prompt-engineering/references/few-shot.md +346 -0
  86. package/skills/skills/prompt-engineering/references/json-format.md +270 -0
  87. package/skills/skills/prompt-engineering/references/natural-language.md +420 -0
  88. package/skills/skills/prompt-engineering/references/pitfalls.md +365 -0
  89. package/skills/skills/prompt-engineering/references/prompt-chaining.md +498 -0
  90. package/skills/skills/prompt-engineering/references/react.md +108 -0
  91. package/skills/skills/prompt-engineering/references/self-consistency.md +322 -0
  92. package/skills/skills/prompt-engineering/references/tree-of-thoughts.md +386 -0
  93. package/skills/skills/prompt-engineering/references/xml-format.md +220 -0
  94. package/skills/skills/prompt-engineering/references/yaml-format.md +488 -0
  95. package/skills/skills/prompt-engineering/references/zero-shot.md +74 -0
  96. package/skills/skills/quick-spec/SKILL.md +280 -0
  97. package/skills/skills/quick-spec/assets/tech-spec-template.md +74 -0
  98. package/skills/skills/quick-spec/references/step-01-understand.md +189 -0
  99. package/skills/skills/quick-spec/references/step-02-investigate.md +144 -0
  100. package/skills/skills/quick-spec/references/step-03-generate.md +128 -0
  101. package/skills/skills/quick-spec/references/step-04-review.md +173 -0
  102. package/skills/skills/quick-spec/tests/__pycache__/test_skill.cpython-314-pytest-9.0.2.pyc +0 -0
  103. package/skills/skills/quick-spec/tests/test_scenarios.md +83 -0
  104. package/skills/skills/quick-spec/tests/test_skill.py +136 -0
  105. package/skills/skills/readme-expert/SKILL.md +538 -0
  106. package/skills/skills/readme-expert/knowledge/INDEX.md +192 -0
  107. package/skills/skills/readme-expert/knowledge/application/quality-standards.md +470 -0
  108. package/skills/skills/readme-expert/knowledge/application/script-executor.md +604 -0
  109. package/skills/skills/readme-expert/knowledge/application/template-library.md +822 -0
  110. package/skills/skills/readme-expert/knowledge/foundation/codebase-scanner.md +361 -0
  111. package/skills/skills/readme-expert/knowledge/foundation/validation-checklist.md +481 -0
  112. package/skills/skills/red-teaming/SKILL.md +321 -0
  113. package/skills/skills/red-teaming/references/ai-llm-redteam.md +517 -0
  114. package/skills/skills/red-teaming/references/attack-techniques.md +410 -0
  115. package/skills/skills/red-teaming/references/cybersecurity-redteam.md +383 -0
  116. package/skills/skills/red-teaming/references/tools-frameworks.md +446 -0
  117. package/skills/skills/releasing/.skillkit-mode +1 -0
  118. package/skills/skills/releasing/SKILL.md +225 -0
  119. package/skills/skills/releasing/references/version-detection.md +108 -0
  120. package/skills/skills/screenwriter/SKILL.md +273 -0
  121. package/skills/skills/screenwriter/references/advanced-techniques.md +216 -0
  122. package/skills/skills/screenwriter/references/pipeline-integration.md +266 -0
  123. package/skills/skills/skillkit/.claude/settings.local.json +7 -0
  124. package/skills/skills/skillkit/.claude-plugin/plugin.json +27 -0
  125. package/skills/skills/skillkit/CHANGELOG.md +484 -0
  126. package/skills/skills/skillkit/SKILL.md +511 -0
  127. package/skills/skills/skillkit/commands/skillkit.md +6 -0
  128. package/skills/skills/skillkit/commands/validate-plan.md +6 -0
  129. package/skills/skills/skillkit/commands/verify.md +6 -0
  130. package/skills/skills/skillkit/knowledge/INDEX.md +352 -0
  131. package/skills/skills/skillkit/knowledge/application/09-case-studies.md +257 -0
  132. package/skills/skills/skillkit/knowledge/application/10-technical-architecture.md +324 -0
  133. package/skills/skills/skillkit/knowledge/application/11-adoption-strategy.md +267 -0
  134. package/skills/skills/skillkit/knowledge/application/12-testing-and-validation.md +276 -0
  135. package/skills/skills/skillkit/knowledge/application/13-competitive-landscape.md +198 -0
  136. package/skills/skills/skillkit/knowledge/foundation/01-why-skills-exist.md +246 -0
  137. package/skills/skills/skillkit/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
  138. package/skills/skills/skillkit/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
  139. package/skills/skills/skillkit/knowledge/foundation/04-hybrid-patterns.md +308 -0
  140. package/skills/skills/skillkit/knowledge/foundation/05-token-economics.md +275 -0
  141. package/skills/skills/skillkit/knowledge/foundation/06-platform-constraints.md +237 -0
  142. package/skills/skills/skillkit/knowledge/foundation/07-security-concerns.md +322 -0
  143. package/skills/skills/skillkit/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
  144. package/skills/skills/skillkit/knowledge/plugin-guide.md +614 -0
  145. package/skills/skills/skillkit/knowledge/tools/14-validation-tools-guide.md +150 -0
  146. package/skills/skills/skillkit/knowledge/tools/15-cost-tools-guide.md +157 -0
  147. package/skills/skills/skillkit/knowledge/tools/16-security-tools-guide.md +122 -0
  148. package/skills/skills/skillkit/knowledge/tools/17-pattern-tools-guide.md +161 -0
  149. package/skills/skills/skillkit/knowledge/tools/18-decision-helper-guide.md +243 -0
  150. package/skills/skills/skillkit/knowledge/tools/19-test-generator-guide.md +275 -0
  151. package/skills/skills/skillkit/knowledge/tools/20-split-skill-guide.md +149 -0
  152. package/skills/skills/skillkit/knowledge/tools/21-quality-scorer-guide.md +226 -0
  153. package/skills/skills/skillkit/knowledge/tools/22-migration-helper-guide.md +356 -0
  154. package/skills/skills/skillkit/knowledge/tools/23-subagent-creation-guide.md +448 -0
  155. package/skills/skills/skillkit/knowledge/tools/24-behavioral-testing-guide.md +122 -0
  156. package/skills/skills/skillkit/references/proposal-generation.md +982 -0
  157. package/skills/skills/skillkit/references/rationalization-catalog.md +75 -0
  158. package/skills/skills/skillkit/references/research-methodology.md +661 -0
  159. package/skills/skills/skillkit/references/section-2-full-creation-workflow.md +452 -0
  160. package/skills/skills/skillkit/references/section-3-validation-workflow-existing-skill.md +63 -0
  161. package/skills/skills/skillkit/references/section-4-decision-workflow-skills-vs-subagents.md +64 -0
  162. package/skills/skills/skillkit/references/section-5-migration-workflow-doc-to-skill.md +58 -0
  163. package/skills/skills/skillkit/references/section-6-subagent-creation-workflow.md +499 -0
  164. package/skills/skills/skillkit/references/section-7-knowledge-reference-map.md +72 -0
  165. package/skills/skills/skillkit/scripts/__pycache__/decision_helper.cpython-314.pyc +0 -0
  166. package/skills/skills/skillkit/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
  167. package/skills/skills/skillkit/scripts/__pycache__/quick_validate.cpython-314.pyc +0 -0
  168. package/skills/skills/skillkit/scripts/__pycache__/test_generator.cpython-314-pytest-9.0.2.pyc +0 -0
  169. package/skills/skills/skillkit/scripts/decision_helper.py +799 -0
  170. package/skills/skills/skillkit/scripts/init_skill.py +400 -0
  171. package/skills/skills/skillkit/scripts/init_subagent.py +231 -0
  172. package/skills/skills/skillkit/scripts/migration_helper.py +669 -0
  173. package/skills/skills/skillkit/scripts/package_skill.py +211 -0
  174. package/skills/skills/skillkit/scripts/pattern_detector.py +381 -0
  175. package/skills/skills/skillkit/scripts/pattern_detector_new.py +382 -0
  176. package/skills/skills/skillkit/scripts/pressure_tester.py +157 -0
  177. package/skills/skills/skillkit/scripts/quality_scorer.py +999 -0
  178. package/skills/skills/skillkit/scripts/quick_validate.py +100 -0
  179. package/skills/skills/skillkit/scripts/security_scanner.py +474 -0
  180. package/skills/skills/skillkit/scripts/split_skill.py +540 -0
  181. package/skills/skills/skillkit/scripts/test_generator.py +695 -0
  182. package/skills/skills/skillkit/scripts/token_estimator.py +493 -0
  183. package/skills/skills/skillkit/scripts/utils/__init__.py +49 -0
  184. package/skills/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-312.pyc +0 -0
  185. package/skills/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-314.pyc +0 -0
  186. package/skills/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-312.pyc +0 -0
  187. package/skills/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-314.pyc +0 -0
  188. package/skills/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-312.pyc +0 -0
  189. package/skills/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-314.pyc +0 -0
  190. package/skills/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-312.pyc +0 -0
  191. package/skills/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-314.pyc +0 -0
  192. package/skills/skills/skillkit/scripts/utils/budget_tracker.py +388 -0
  193. package/skills/skills/skillkit/scripts/utils/output_formatter.py +263 -0
  194. package/skills/skills/skillkit/scripts/utils/reference_validator.py +401 -0
  195. package/skills/skills/skillkit/scripts/validate_skill.py +594 -0
  196. package/skills/skills/skillkit/tests/test_behavioral.py +39 -0
  197. package/skills/skills/skillkit/tests/test_scenarios.md +83 -0
  198. package/skills/skills/skillkit/tests/test_skill.py +136 -0
  199. package/skills/skills/skillkit-help/SKILL.md +81 -0
  200. package/skills/skills/skillkit-help/knowledge/application/09-case-studies.md +257 -0
  201. package/skills/skills/skillkit-help/knowledge/application/12-testing-and-validation.md +276 -0
  202. package/skills/skills/skillkit-help/knowledge/foundation/01-why-skills-exist.md +246 -0
  203. package/skills/skills/skillkit-help/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
  204. package/skills/skills/skillkit-help/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
  205. package/skills/skills/skillkit-help/knowledge/foundation/06-platform-constraints.md +237 -0
  206. package/skills/skills/skillkit-help/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
  207. package/skills/skills/skillkit-help/template/SKILL.md +52 -0
  208. package/skills/skills/social-media-seo/SKILL.md +278 -0
  209. package/skills/skills/social-media-seo/databases/caption-styles.csv +31 -0
  210. package/skills/skills/social-media-seo/databases/engagement-tactics.csv +16 -0
  211. package/skills/skills/social-media-seo/databases/hashtag-strategies.csv +21 -0
  212. package/skills/skills/social-media-seo/databases/hook-formulas.csv +26 -0
  213. package/skills/skills/social-media-seo/databases/keyword-clusters.csv +11 -0
  214. package/skills/skills/social-media-seo/databases/thread-structures.csv +26 -0
  215. package/skills/skills/social-media-seo/databases/viral-patterns.csv +21 -0
  216. package/skills/skills/social-media-seo/references/analytics-guide.md +321 -0
  217. package/skills/skills/social-media-seo/references/instagram-seo.md +235 -0
  218. package/skills/skills/social-media-seo/references/threads-seo.md +305 -0
  219. package/skills/skills/social-media-seo/references/x-twitter-seo.md +337 -0
  220. package/skills/skills/social-media-seo/scripts/query_database.py +191 -0
  221. package/skills/skills/storyteller/SKILL.md +241 -0
  222. package/skills/skills/storyteller/references/transformation-methodology.md +293 -0
  223. package/skills/skills/storyteller/references/visual-vocabulary.md +177 -0
  224. package/skills/skills/thread-pro/SKILL.md +162 -0
  225. package/skills/skills/thread-pro/anti-ai-patterns.md +120 -0
  226. package/skills/skills/thread-pro/hook-formulas.md +138 -0
  227. package/skills/skills/thread-pro/references/anti-ai-patterns.md +120 -0
  228. package/skills/skills/thread-pro/references/hook-formulas.md +138 -0
  229. package/skills/skills/thread-pro/references/thread-structures.md +240 -0
  230. package/skills/skills/thread-pro/references/voice-injection.md +130 -0
  231. package/skills/skills/thread-pro/thread-structures.md +240 -0
  232. package/skills/skills/thread-pro/voice-injection.md +130 -0
  233. package/skills/skills/tinkering/SKILL.md +251 -0
  234. package/skills/skills/tinkering/references/graduation-checklist.md +100 -0
  235. package/skills/skills/validate-plan/.skillkit-mode +1 -0
  236. package/skills/skills/validate-plan/SKILL.md +406 -0
  237. package/skills/skills/validate-plan/references/dry-principles.md +251 -0
  238. package/skills/skills/validate-plan/references/gap-analysis-guide.md +320 -0
  239. package/skills/skills/validate-plan/references/tdd-patterns.md +413 -0
  240. package/skills/skills/validate-plan/references/yagni-checklist.md +330 -0
  241. package/skills/skills/verify-before-ship/.skillkit-mode +1 -0
  242. package/skills/skills/verify-before-ship/SKILL.md +116 -0
  243. package/skills/skills/verify-before-ship/references/anti-rationalization.md +212 -0
  244. package/skills/skills/verify-before-ship/references/verification-gates.md +305 -0
  245. package/skills-manifest.json +8 -2
  246. package/src/picker.js +11 -5
  247. package/src/picker.test.js +36 -1
@@ -0,0 +1,594 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Comprehensive skill validation tool.
4
+ Validates skills against best practices from Files 02, 07, 10, 12.
5
+
6
+ v1.2 Update: Enhanced cross-reference validation
7
+ - Comprehensive file reference detection (markdown links, code refs, paths)
8
+ - File existence verification
9
+ - Orphaned file detection
10
+ - Uses CrossReferenceValidator utility
11
+
12
+ Usage:
13
+ python validate_skill.py <skill_path> [--strict] [--format text|json]
14
+
15
+ References:
16
+ - File 02: Description engineering patterns
17
+ - File 07: Security best practices
18
+ - File 10: Progressive disclosure architecture
19
+ - File 12: Testing and validation checklist
20
+ """
21
+
22
+ import os
23
+ import re
24
+ import sys
25
+ import json
26
+ import yaml
27
+ from pathlib import Path
28
+ from typing import Dict, List, Tuple
29
+ from dataclasses import dataclass
30
+ from enum import Enum
31
+
32
+ try:
33
+ from utils.reference_validator import CrossReferenceValidator
34
+ except ImportError:
35
+ CrossReferenceValidator = None # Graceful fallback
36
+
37
+
38
+ class Severity(Enum):
39
+ """Validation result severity levels."""
40
+ PASS = "pass"
41
+ WARNING = "warning"
42
+ FAIL = "fail"
43
+
44
+
45
+ @dataclass
46
+ class ValidationResult:
47
+ """Single validation check result."""
48
+ check_name: str
49
+ severity: Severity
50
+ message: str
51
+ suggestion: str = ""
52
+ line_number: int = None
53
+
54
+
55
+ class SkillValidator:
56
+ """Main validator implementing 10 comprehensive checks."""
57
+
58
+ def __init__(self, skill_path: str, strict: bool = False):
59
+ """
60
+ Initialize validator.
61
+
62
+ Args:
63
+ skill_path: Path to skill directory
64
+ strict: If True, warnings become failures
65
+ """
66
+ self.skill_path = Path(skill_path)
67
+ self.strict = strict
68
+ self.results: List[ValidationResult] = []
69
+
70
+ # Load SKILL.md content once
71
+ self.skill_md_path = self.skill_path / "SKILL.md"
72
+ self.skill_content = ""
73
+ self.frontmatter = {}
74
+
75
+ if self.skill_md_path.exists():
76
+ self.skill_content = self.skill_md_path.read_text(encoding='utf-8')
77
+ self._parse_frontmatter()
78
+
79
+ def _parse_frontmatter(self):
80
+ """Extract and parse YAML frontmatter."""
81
+ if self.skill_content.startswith('---'):
82
+ parts = self.skill_content.split('---', 2)
83
+ if len(parts) >= 3:
84
+ try:
85
+ self.frontmatter = yaml.safe_load(parts[1])
86
+ except yaml.YAMLError:
87
+ self.frontmatter = {}
88
+
89
+ # ========== STRUCTURAL VALIDATION ==========
90
+
91
+ def validate_yaml_frontmatter(self) -> ValidationResult:
92
+ """Validate YAML frontmatter structure and required fields."""
93
+ if not self.skill_md_path.exists():
94
+ return ValidationResult(
95
+ "YAML Frontmatter",
96
+ Severity.FAIL,
97
+ "SKILL.md not found",
98
+ "Create SKILL.md in skill directory"
99
+ )
100
+
101
+ if not self.frontmatter:
102
+ return ValidationResult(
103
+ "YAML Frontmatter",
104
+ Severity.FAIL,
105
+ "Invalid or missing YAML frontmatter",
106
+ "Add valid YAML frontmatter between --- markers"
107
+ )
108
+
109
+ # Check required fields
110
+ required_fields = ['name', 'description']
111
+ missing = [f for f in required_fields if f not in self.frontmatter]
112
+
113
+ if missing:
114
+ return ValidationResult(
115
+ "YAML Frontmatter",
116
+ Severity.FAIL,
117
+ f"Missing required fields: {', '.join(missing)}",
118
+ "Add required fields to frontmatter"
119
+ )
120
+
121
+ return ValidationResult(
122
+ "YAML Frontmatter",
123
+ Severity.PASS,
124
+ "Valid YAML frontmatter with required fields"
125
+ )
126
+
127
+ def validate_file_structure(self) -> ValidationResult:
128
+ """Validate skill directory structure."""
129
+ if not self.skill_md_path.exists():
130
+ return ValidationResult(
131
+ "File Structure",
132
+ Severity.FAIL,
133
+ "SKILL.md missing",
134
+ "Create SKILL.md file"
135
+ )
136
+
137
+ issues = []
138
+
139
+ # Check for scripts directory if any .py files exist
140
+ scripts_dir = self.skill_path / "scripts"
141
+ py_files = list(self.skill_path.glob("*.py"))
142
+
143
+ if py_files and not scripts_dir.exists():
144
+ issues.append("Python files found but no scripts/ directory")
145
+
146
+ # Check for references directory if SKILL.md is large
147
+ line_count = len(self.skill_content.splitlines())
148
+ references_dir = self.skill_path / "references"
149
+
150
+ if line_count > 500 and not references_dir.exists():
151
+ issues.append(f"SKILL.md has {line_count} lines (>500), consider using references/")
152
+
153
+ if issues:
154
+ severity = Severity.WARNING if not self.strict else Severity.FAIL
155
+ return ValidationResult(
156
+ "File Structure",
157
+ severity,
158
+ "; ".join(issues),
159
+ "Organize files according to progressive disclosure pattern (File 10)"
160
+ )
161
+
162
+ return ValidationResult(
163
+ "File Structure",
164
+ Severity.PASS,
165
+ "Proper file organization"
166
+ )
167
+
168
+ # ========== DESCRIPTION QUALITY ==========
169
+
170
+ def validate_description_quality(self) -> ValidationResult:
171
+ """Validate description includes WHAT + WHEN."""
172
+ description = self.frontmatter.get('description', '')
173
+
174
+ if not description:
175
+ return ValidationResult(
176
+ "Description Quality",
177
+ Severity.FAIL,
178
+ "Description is empty",
179
+ "Add description with WHAT (capability) and WHEN (triggers)"
180
+ )
181
+
182
+ # Check length
183
+ if len(description) < 20:
184
+ return ValidationResult(
185
+ "Description Quality",
186
+ Severity.WARNING,
187
+ f"Description too short ({len(description)} chars)",
188
+ "Expand to 20-100 words with clear capabilities"
189
+ )
190
+
191
+ if len(description) > 1024:
192
+ return ValidationResult(
193
+ "Description Quality",
194
+ Severity.FAIL,
195
+ f"Description too long ({len(description)} chars, max 1024)",
196
+ "Condense to essential WHAT and WHEN information"
197
+ )
198
+
199
+ # Check for trigger phrases (WHEN)
200
+ trigger_phrases = [
201
+ 'use when', 'trigger on', 'for tasks involving',
202
+ 'when claude needs to', 'activate when', 'applies to'
203
+ ]
204
+
205
+ has_trigger = any(phrase in description.lower() for phrase in trigger_phrases)
206
+
207
+ if not has_trigger:
208
+ severity = Severity.WARNING if not self.strict else Severity.FAIL
209
+ return ValidationResult(
210
+ "Description Quality",
211
+ severity,
212
+ "Description missing WHEN trigger phrases",
213
+ "Add phrases like 'Use when...' or 'Trigger on...' (File 02)"
214
+ )
215
+
216
+ return ValidationResult(
217
+ "Description Quality",
218
+ Severity.PASS,
219
+ "Description includes WHAT and WHEN triggers"
220
+ )
221
+
222
+ # ========== TOKEN EFFICIENCY ==========
223
+
224
+ def validate_token_count(self) -> ValidationResult:
225
+ """Validate token efficiency."""
226
+ line_count = len(self.skill_content.splitlines())
227
+
228
+ # Estimate tokens (average method: 1 line ≈ 8 tokens)
229
+ estimated_tokens = int(line_count * 8)
230
+
231
+ issues = []
232
+
233
+ # SKILL.md size checks
234
+ if line_count > 800:
235
+ issues.append(f"SKILL.md too large ({line_count} lines, max 800)")
236
+ elif line_count > 500:
237
+ issues.append(f"SKILL.md large ({line_count} lines), consider splitting at 500+")
238
+
239
+ # Token estimate checks
240
+ if estimated_tokens > 6000:
241
+ issues.append(f"Estimated {estimated_tokens} tokens (critical >6000)")
242
+ elif estimated_tokens > 4500:
243
+ issues.append(f"Estimated {estimated_tokens} tokens (warning >4500)")
244
+
245
+ if not issues:
246
+ return ValidationResult(
247
+ "Token Efficiency",
248
+ Severity.PASS,
249
+ f"Efficient: {line_count} lines (~{estimated_tokens} tokens)"
250
+ )
251
+
252
+ severity = Severity.FAIL if line_count > 800 else Severity.WARNING
253
+
254
+ return ValidationResult(
255
+ "Token Efficiency",
256
+ severity,
257
+ "; ".join(issues),
258
+ "Apply progressive disclosure: move details to references/ (File 10)"
259
+ )
260
+
261
+ # ========== SECURITY VALIDATION ==========
262
+
263
+ def validate_security_basics(self) -> ValidationResult:
264
+ """Basic security checks (see security_scanner.py for comprehensive audit)."""
265
+ issues = []
266
+
267
+ # Check SKILL.md for obvious secrets
268
+ secret_patterns = [
269
+ (r'api_key\s*=\s*["\'][^"\']+["\']', 'Hardcoded API key'),
270
+ (r'password\s*=\s*["\'][^"\']+["\']', 'Hardcoded password'),
271
+ (r'secret\s*=\s*["\'][^"\']+["\']', 'Hardcoded secret'),
272
+ (r'token\s*=\s*["\'][^"\']+["\']', 'Hardcoded token'),
273
+ ]
274
+
275
+ for pattern, desc in secret_patterns:
276
+ if re.search(pattern, self.skill_content, re.IGNORECASE):
277
+ issues.append(f"{desc} detected in SKILL.md")
278
+
279
+ # Check scripts for dangerous patterns
280
+ scripts_dir = self.skill_path / "scripts"
281
+ if scripts_dir.exists():
282
+ for script_file in scripts_dir.glob("*.py"):
283
+ script_content = script_file.read_text(encoding='utf-8')
284
+
285
+ if 'shell=True' in script_content:
286
+ issues.append(f"shell=True found in {script_file.name}")
287
+
288
+ if re.search(r'\beval\s*\(', script_content):
289
+ issues.append(f"eval() usage in {script_file.name}")
290
+
291
+ if re.search(r'\bexec\s*\(', script_content):
292
+ issues.append(f"exec() usage in {script_file.name}")
293
+
294
+ if issues:
295
+ return ValidationResult(
296
+ "Security Basics",
297
+ Severity.FAIL,
298
+ "; ".join(issues),
299
+ "Remove hardcoded secrets, avoid shell=True/eval/exec (File 07). Run security_scanner.py for full audit."
300
+ )
301
+
302
+ return ValidationResult(
303
+ "Security Basics",
304
+ Severity.PASS,
305
+ "No obvious security issues (run security_scanner.py for comprehensive audit)"
306
+ )
307
+
308
+ # ========== BEST PRACTICES ==========
309
+
310
+ def validate_writing_style(self) -> ValidationResult:
311
+ """Validate agent-layer writing style."""
312
+ body = self.skill_content.split('---', 2)[-1] if '---' in self.skill_content else self.skill_content
313
+
314
+ issues = []
315
+
316
+ # Check for non-imperative patterns
317
+ weak_patterns = [
318
+ 'you can', 'you may', 'you should', 'you might',
319
+ 'it is possible', 'one could', 'consider'
320
+ ]
321
+
322
+ weak_count = sum(body.lower().count(pattern) for pattern in weak_patterns)
323
+
324
+ if weak_count > 5:
325
+ issues.append(f"Too many weak phrases ({weak_count} instances)")
326
+
327
+ # Check for section headers (good sign of organization)
328
+ header_count = len(re.findall(r'^#+\s+', body, re.MULTILINE))
329
+
330
+ if header_count < 3 and len(body.splitlines()) > 100:
331
+ issues.append("Few section headers (improves scannability)")
332
+
333
+ if issues:
334
+ severity = Severity.WARNING
335
+ return ValidationResult(
336
+ "Writing Style",
337
+ severity,
338
+ "; ".join(issues),
339
+ "Use imperative form ('Use X' not 'You can use X'), add clear headers"
340
+ )
341
+
342
+ return ValidationResult(
343
+ "Writing Style",
344
+ Severity.PASS,
345
+ "Agent-layer writing style maintained"
346
+ )
347
+
348
+ def validate_progressive_disclosure(self) -> ValidationResult:
349
+ """Validate progressive disclosure implementation."""
350
+ line_count = len(self.skill_content.splitlines())
351
+ references_dir = self.skill_path / "references"
352
+
353
+ # If SKILL.md is large but no references, suggest splitting
354
+ if line_count > 350 and not references_dir.exists():
355
+ return ValidationResult(
356
+ "Progressive Disclosure",
357
+ Severity.WARNING,
358
+ f"SKILL.md has {line_count} lines, no references/ directory",
359
+ "Move optional details to references/ for better progressive disclosure (File 10)"
360
+ )
361
+
362
+ # Check reference files have TOC if >100 lines
363
+ if references_dir.exists():
364
+ for ref_file in references_dir.glob("*.md"):
365
+ ref_content = ref_file.read_text(encoding='utf-8')
366
+ ref_lines = len(ref_content.splitlines())
367
+
368
+ if ref_lines > 100:
369
+ # Simple TOC check: look for list of links to headers
370
+ has_toc = bool(re.search(r'\[.*\]\(#.*\)', ref_content[:500]))
371
+
372
+ if not has_toc:
373
+ return ValidationResult(
374
+ "Progressive Disclosure",
375
+ Severity.WARNING,
376
+ f"{ref_file.name} has {ref_lines} lines but no TOC",
377
+ "Add table of contents at top of reference files >100 lines"
378
+ )
379
+
380
+ return ValidationResult(
381
+ "Progressive Disclosure",
382
+ Severity.PASS,
383
+ "Progressive disclosure properly implemented"
384
+ )
385
+
386
+ def validate_cross_references(self) -> ValidationResult:
387
+ """
388
+ Validate cross-reference integrity with comprehensive file checking.
389
+
390
+ v1.2 Enhanced: Uses CrossReferenceValidator for:
391
+ - Markdown links: [text](path)
392
+ - Code references: `file.md`
393
+ - Path patterns: "file: path.md"
394
+ - File existence verification
395
+ - Orphaned file detection
396
+ """
397
+ # Try to use comprehensive CrossReferenceValidator
398
+ if CrossReferenceValidator:
399
+ try:
400
+ validator = CrossReferenceValidator(str(self.skill_path))
401
+ ref_result = validator.validate_skill_md()
402
+
403
+ if ref_result.status == 'fail':
404
+ # Comprehensive failure message with all issues
405
+ issues = []
406
+ if ref_result.missing_files:
407
+ issues.append(f"Missing: {', '.join(ref_result.missing_files[:3])}")
408
+ if ref_result.orphaned_files:
409
+ issues.append(f"Orphaned: {', '.join(ref_result.orphaned_files[:3])}")
410
+
411
+ return ValidationResult(
412
+ "Cross-References",
413
+ Severity.FAIL,
414
+ f"{'; '.join(issues)}{'...' if len(issues) > 2 else ''}",
415
+ ref_result.suggestion or "Fix or remove broken cross-references"
416
+ )
417
+ else:
418
+ return ValidationResult(
419
+ "Cross-References",
420
+ Severity.PASS,
421
+ f"All {len(ref_result.valid_references)} cross-references valid"
422
+ )
423
+ except Exception as e:
424
+ # Fallback to original simple validation
425
+ pass
426
+
427
+ # Fallback: Original simple validation (backward compatibility)
428
+ link_pattern = r'\[([^\]]+)\]\(([^)]+)\)'
429
+ links = re.findall(link_pattern, self.skill_content)
430
+
431
+ broken = []
432
+
433
+ for link_text, link_target in links:
434
+ # Skip external URLs
435
+ if link_target.startswith(('http://', 'https://', '#')):
436
+ continue
437
+
438
+ # Check if file exists
439
+ target_path = self.skill_path / link_target
440
+ if not target_path.exists():
441
+ broken.append(f"'{link_text}' -> {link_target}")
442
+
443
+ if broken:
444
+ return ValidationResult(
445
+ "Cross-References",
446
+ Severity.FAIL,
447
+ f"Broken links found: {'; '.join(broken[:3])}{'...' if len(broken) > 3 else ''}",
448
+ "Fix or remove broken cross-references"
449
+ )
450
+
451
+ return ValidationResult(
452
+ "Cross-References",
453
+ Severity.PASS,
454
+ "All cross-references valid"
455
+ )
456
+
457
+ # ========== UTILITY METHODS ==========
458
+
459
+ def run_all_validations(self) -> List[ValidationResult]:
460
+ """Run all validation checks."""
461
+ self.results = [
462
+ self.validate_yaml_frontmatter(),
463
+ self.validate_file_structure(),
464
+ self.validate_description_quality(),
465
+ self.validate_token_count(),
466
+ self.validate_security_basics(),
467
+ self.validate_writing_style(),
468
+ self.validate_progressive_disclosure(),
469
+ self.validate_cross_references(),
470
+ ]
471
+ return self.results
472
+
473
+ def generate_report(self, format: str = 'text') -> str:
474
+ """Generate validation report."""
475
+ if format == 'json':
476
+ return self._generate_json_report()
477
+ return self._generate_text_report()
478
+
479
+ def _generate_text_report(self) -> str:
480
+ """Generate human-readable text report."""
481
+ lines = []
482
+ lines.append(f"\n{'='*60}")
483
+ lines.append(f"Skill Validation Report: {self.skill_path.name}")
484
+ lines.append('='*60 + '\n')
485
+
486
+ # Categorize results
487
+ passed = [r for r in self.results if r.severity == Severity.PASS]
488
+ warnings = [r for r in self.results if r.severity == Severity.WARNING]
489
+ failed = [r for r in self.results if r.severity == Severity.FAIL]
490
+
491
+ # Display results
492
+ for result in self.results:
493
+ icon = {
494
+ Severity.PASS: '✓',
495
+ Severity.WARNING: 'âš ',
496
+ Severity.FAIL: '✗'
497
+ }[result.severity]
498
+
499
+ lines.append(f"{icon} {result.check_name}")
500
+
501
+ if result.severity != Severity.PASS:
502
+ lines.append(f" {result.message}")
503
+ if result.suggestion:
504
+ lines.append(f" → {result.suggestion}")
505
+
506
+ lines.append('')
507
+
508
+ # Summary
509
+ lines.append('-'*60)
510
+ lines.append(f"Validation Score: {len(passed)}/{len(self.results)} checks passed")
511
+ lines.append(f"Severity: {len(failed)} critical, {len(warnings)} warnings, {len(passed)} passed")
512
+ lines.append('')
513
+
514
+ if failed:
515
+ lines.append("❌ Fix critical issues before packaging.")
516
+ elif warnings:
517
+ lines.append("⚠️ Address warnings to improve quality.")
518
+ else:
519
+ lines.append("✅ All validations passed! Skill ready for deployment.")
520
+
521
+ return '\n'.join(lines)
522
+
523
+ def _generate_json_report(self) -> str:
524
+ """Generate machine-readable JSON report."""
525
+ report = {
526
+ 'skill_name': self.skill_path.name,
527
+ 'timestamp': str(Path.cwd()),
528
+ 'results': [
529
+ {
530
+ 'check': r.check_name,
531
+ 'severity': r.severity.value,
532
+ 'message': r.message,
533
+ 'suggestion': r.suggestion
534
+ }
535
+ for r in self.results
536
+ ],
537
+ 'summary': {
538
+ 'total': len(self.results),
539
+ 'passed': len([r for r in self.results if r.severity == Severity.PASS]),
540
+ 'warnings': len([r for r in self.results if r.severity == Severity.WARNING]),
541
+ 'failed': len([r for r in self.results if r.severity == Severity.FAIL])
542
+ }
543
+ }
544
+ return json.dumps(report, indent=2)
545
+
546
+ def get_exit_code(self) -> int:
547
+ """Get appropriate exit code based on results."""
548
+ if any(r.severity == Severity.FAIL for r in self.results):
549
+ return 2 # Critical failures
550
+ if any(r.severity == Severity.WARNING for r in self.results):
551
+ return 1 # Warnings only
552
+ return 0 # All passed
553
+
554
+
555
+ def main():
556
+ """CLI entry point."""
557
+ import argparse
558
+
559
+ parser = argparse.ArgumentParser(
560
+ description='Comprehensive skill validation tool',
561
+ epilog='References: Files 02, 07, 10, 12 for validation rules'
562
+ )
563
+ parser.add_argument('skill_path', help='Path to skill directory')
564
+ parser.add_argument('--strict', action='store_true',
565
+ help='Treat warnings as failures')
566
+ parser.add_argument('--format', choices=['text', 'json'], default='text',
567
+ help='Output format (default: text)')
568
+
569
+ args = parser.parse_args()
570
+
571
+ # Validate skill path
572
+ skill_path = Path(args.skill_path)
573
+ if not skill_path.exists():
574
+ print(f"Error: Skill path '{skill_path}' does not exist", file=sys.stderr)
575
+ sys.exit(2)
576
+
577
+ if not skill_path.is_dir():
578
+ print(f"Error: '{skill_path}' is not a directory", file=sys.stderr)
579
+ sys.exit(2)
580
+
581
+ # Run validation
582
+ validator = SkillValidator(skill_path, strict=args.strict)
583
+ validator.run_all_validations()
584
+
585
+ # Generate report
586
+ report = validator.generate_report(format=args.format)
587
+ print(report)
588
+
589
+ # Exit with appropriate code
590
+ sys.exit(validator.get_exit_code())
591
+
592
+
593
+ if __name__ == '__main__':
594
+ main()
@@ -0,0 +1,39 @@
1
+ """
2
+ Behavioral tests for
3
+ Generated by test_generator.py --behavioral
4
+ """
5
+
6
+ import pytest
7
+
8
+ # RED Phase: Baseline tests (run WITHOUT skill)
9
+ class TestBaselineBehavior:
10
+ """Document how agents behave without skill."""
11
+
12
+ def test_time_pressure_rationalization(self):
13
+ """Under time pressure, agents typically..."""
14
+ # Document expected failure
15
+ pass
16
+
17
+ def test_sunk_cost_rationalization(self):
18
+ """With sunk cost, agents typically..."""
19
+ pass
20
+
21
+ # GREEN Phase: Verification tests (run WITH skill)
22
+ class TestSkillCompliance:
23
+ """Verify agents comply WITH skill."""
24
+
25
+ def test_resists_time_pressure(self):
26
+ """Skill helps agent resist time pressure."""
27
+ pass
28
+
29
+ def test_resists_sunk_cost(self):
30
+ """Skill helps agent resist sunk cost fallacy."""
31
+ pass
32
+
33
+ # REFACTOR Phase: Combined pressure
34
+ class TestCombinedPressure:
35
+ """All pressures at once."""
36
+
37
+ def test_combined_pressure_compliance(self):
38
+ """Agent complies under maximum pressure."""
39
+ pass