@rfxlamia/skillkit 1.0.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 (225) hide show
  1. package/README.md +16 -0
  2. package/agents/creative-copywriter.md +212 -0
  3. package/agents/dario-amodei.md +135 -0
  4. package/agents/doc-simplifier.md +63 -0
  5. package/agents/kotlin-pro.md +433 -0
  6. package/agents/red-team.md +136 -0
  7. package/agents/sam-altman.md +121 -0
  8. package/agents/seo-manager.md +184 -0
  9. package/bin/skillkit.js +3 -0
  10. package/package.json +35 -0
  11. package/skills/adversarial-review/SKILL.md +219 -0
  12. package/skills/baby-education/SKILL.md +260 -0
  13. package/skills/baby-education/references/advanced-techniques.md +323 -0
  14. package/skills/baby-education/references/transformations.md +345 -0
  15. package/skills/been-there-done-that/SKILL.md +455 -0
  16. package/skills/been-there-done-that/references/analysis-patterns.md +162 -0
  17. package/skills/been-there-done-that/references/git-commands.md +132 -0
  18. package/skills/been-there-done-that/references/tree-insertion-logic.md +145 -0
  19. package/skills/coolhunter/SKILL.md +270 -0
  20. package/skills/coolhunter/assets/elicitation-methods.csv +51 -0
  21. package/skills/coolhunter/knowledge/elicitation-methods.md +312 -0
  22. package/skills/coolhunter/references/workflow-execution.md +238 -0
  23. package/skills/coolhunter/workflow-plan-coolhunter.md +232 -0
  24. package/skills/creative-copywriting/SKILL.md +324 -0
  25. package/skills/creative-copywriting/databases/README.md +60 -0
  26. package/skills/creative-copywriting/databases/carousel-structures.csv +16 -0
  27. package/skills/creative-copywriting/databases/emotional-arcs.csv +11 -0
  28. package/skills/creative-copywriting/databases/hook-formulas.csv +51 -0
  29. package/skills/creative-copywriting/databases/power-words.csv +201 -0
  30. package/skills/creative-copywriting/databases/psychological-triggers.csv +21 -0
  31. package/skills/creative-copywriting/databases/read-more-patterns.csv +26 -0
  32. package/skills/creative-copywriting/databases/swipe-triggers.csv +31 -0
  33. package/skills/creative-copywriting/references/carousel-psychology.md +223 -0
  34. package/skills/creative-copywriting/references/hook-anatomy.md +169 -0
  35. package/skills/creative-copywriting/references/power-word-science.md +134 -0
  36. package/skills/creative-copywriting/references/storytelling-frameworks.md +157 -0
  37. package/skills/diverse-content-gen/SKILL.md +201 -0
  38. package/skills/diverse-content-gen/references/advanced-techniques.md +320 -0
  39. package/skills/diverse-content-gen/references/research-findings.md +379 -0
  40. package/skills/diverse-content-gen/references/task-workflows.md +241 -0
  41. package/skills/diverse-content-gen/references/tool-integration.md +419 -0
  42. package/skills/diverse-content-gen/references/troubleshooting.md +426 -0
  43. package/skills/diverse-content-gen/references/vs-core-technique.md +240 -0
  44. package/skills/framework-critical-thinking/SKILL.md +220 -0
  45. package/skills/framework-critical-thinking/references/bias_detector.md +375 -0
  46. package/skills/framework-critical-thinking/references/fallback_handler.md +239 -0
  47. package/skills/framework-critical-thinking/references/memory_curator.md +161 -0
  48. package/skills/framework-critical-thinking/references/metacognitive_monitor.md +297 -0
  49. package/skills/framework-critical-thinking/references/producer_critic_orchestrator.md +333 -0
  50. package/skills/framework-critical-thinking/references/reasoning_router.md +235 -0
  51. package/skills/framework-critical-thinking/references/reasoning_validator.md +97 -0
  52. package/skills/framework-critical-thinking/references/reflection_trigger.md +78 -0
  53. package/skills/framework-critical-thinking/references/self_verification.md +388 -0
  54. package/skills/framework-critical-thinking/references/uncertainty_quantifier.md +207 -0
  55. package/skills/framework-initiative/SKILL.md +231 -0
  56. package/skills/framework-initiative/references/examples.md +150 -0
  57. package/skills/framework-initiative/references/impact-analysis.md +157 -0
  58. package/skills/framework-initiative/references/intent-patterns.md +145 -0
  59. package/skills/framework-initiative/references/star-framework.md +165 -0
  60. package/skills/humanize-docs/SKILL.md +203 -0
  61. package/skills/humanize-docs/references/advanced-techniques.md +13 -0
  62. package/skills/humanize-docs/references/core-transformations.md +368 -0
  63. package/skills/humanize-docs/references/detection-patterns.md +400 -0
  64. package/skills/humanize-docs/references/examples-gallery.md +374 -0
  65. package/skills/imagine/SKILL.md +190 -0
  66. package/skills/imagine/references/artstyle-corporate-memphis.md +625 -0
  67. package/skills/imagine/references/artstyle-crewdson-hyperrealism.md +295 -0
  68. package/skills/imagine/references/artstyle-iphone-social-media.md +426 -0
  69. package/skills/imagine/references/artstyle-sciencesaru.md +276 -0
  70. package/skills/pre-deploy-checklist/README.md +26 -0
  71. package/skills/pre-deploy-checklist/SKILL.md +153 -0
  72. package/skills/pre-deploy-checklist/references/checklist-categories.md +174 -0
  73. package/skills/pre-deploy-checklist/references/domain-prompts.md +216 -0
  74. package/skills/prompt-engineering/SKILL.md +209 -0
  75. package/skills/prompt-engineering/references/advanced-combinations.md +444 -0
  76. package/skills/prompt-engineering/references/chain-of-thought.md +140 -0
  77. package/skills/prompt-engineering/references/decision_matrix.md +220 -0
  78. package/skills/prompt-engineering/references/few-shot.md +346 -0
  79. package/skills/prompt-engineering/references/json-format.md +270 -0
  80. package/skills/prompt-engineering/references/natural-language.md +420 -0
  81. package/skills/prompt-engineering/references/pitfalls.md +365 -0
  82. package/skills/prompt-engineering/references/prompt-chaining.md +498 -0
  83. package/skills/prompt-engineering/references/react.md +108 -0
  84. package/skills/prompt-engineering/references/self-consistency.md +322 -0
  85. package/skills/prompt-engineering/references/tree-of-thoughts.md +386 -0
  86. package/skills/prompt-engineering/references/xml-format.md +220 -0
  87. package/skills/prompt-engineering/references/yaml-format.md +488 -0
  88. package/skills/prompt-engineering/references/zero-shot.md +74 -0
  89. package/skills/quick-spec/SKILL.md +280 -0
  90. package/skills/quick-spec/assets/tech-spec-template.md +74 -0
  91. package/skills/quick-spec/references/step-01-understand.md +189 -0
  92. package/skills/quick-spec/references/step-02-investigate.md +144 -0
  93. package/skills/quick-spec/references/step-03-generate.md +128 -0
  94. package/skills/quick-spec/references/step-04-review.md +173 -0
  95. package/skills/quick-spec/tests/test_scenarios.md +83 -0
  96. package/skills/quick-spec/tests/test_skill.py +136 -0
  97. package/skills/readme-expert/SKILL.md +538 -0
  98. package/skills/readme-expert/knowledge/INDEX.md +192 -0
  99. package/skills/readme-expert/knowledge/application/quality-standards.md +470 -0
  100. package/skills/readme-expert/knowledge/application/script-executor.md +604 -0
  101. package/skills/readme-expert/knowledge/application/template-library.md +822 -0
  102. package/skills/readme-expert/knowledge/foundation/codebase-scanner.md +361 -0
  103. package/skills/readme-expert/knowledge/foundation/validation-checklist.md +481 -0
  104. package/skills/red-teaming/SKILL.md +321 -0
  105. package/skills/red-teaming/references/ai-llm-redteam.md +517 -0
  106. package/skills/red-teaming/references/attack-techniques.md +410 -0
  107. package/skills/red-teaming/references/cybersecurity-redteam.md +383 -0
  108. package/skills/red-teaming/references/tools-frameworks.md +446 -0
  109. package/skills/releasing/.skillkit-mode +1 -0
  110. package/skills/releasing/SKILL.md +225 -0
  111. package/skills/releasing/references/version-detection.md +108 -0
  112. package/skills/screenwriter/SKILL.md +273 -0
  113. package/skills/screenwriter/references/advanced-techniques.md +216 -0
  114. package/skills/screenwriter/references/pipeline-integration.md +266 -0
  115. package/skills/skillkit/.claude-plugin/plugin.json +27 -0
  116. package/skills/skillkit/CHANGELOG.md +484 -0
  117. package/skills/skillkit/SKILL.md +511 -0
  118. package/skills/skillkit/commands/skillkit.md +6 -0
  119. package/skills/skillkit/commands/validate-plan.md +6 -0
  120. package/skills/skillkit/commands/verify.md +6 -0
  121. package/skills/skillkit/knowledge/INDEX.md +352 -0
  122. package/skills/skillkit/knowledge/application/09-case-studies.md +257 -0
  123. package/skills/skillkit/knowledge/application/10-technical-architecture.md +324 -0
  124. package/skills/skillkit/knowledge/application/11-adoption-strategy.md +267 -0
  125. package/skills/skillkit/knowledge/application/12-testing-and-validation.md +276 -0
  126. package/skills/skillkit/knowledge/application/13-competitive-landscape.md +198 -0
  127. package/skills/skillkit/knowledge/foundation/01-why-skills-exist.md +246 -0
  128. package/skills/skillkit/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
  129. package/skills/skillkit/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
  130. package/skills/skillkit/knowledge/foundation/04-hybrid-patterns.md +308 -0
  131. package/skills/skillkit/knowledge/foundation/05-token-economics.md +275 -0
  132. package/skills/skillkit/knowledge/foundation/06-platform-constraints.md +237 -0
  133. package/skills/skillkit/knowledge/foundation/07-security-concerns.md +322 -0
  134. package/skills/skillkit/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
  135. package/skills/skillkit/knowledge/plugin-guide.md +614 -0
  136. package/skills/skillkit/knowledge/tools/14-validation-tools-guide.md +150 -0
  137. package/skills/skillkit/knowledge/tools/15-cost-tools-guide.md +157 -0
  138. package/skills/skillkit/knowledge/tools/16-security-tools-guide.md +122 -0
  139. package/skills/skillkit/knowledge/tools/17-pattern-tools-guide.md +161 -0
  140. package/skills/skillkit/knowledge/tools/18-decision-helper-guide.md +243 -0
  141. package/skills/skillkit/knowledge/tools/19-test-generator-guide.md +275 -0
  142. package/skills/skillkit/knowledge/tools/20-split-skill-guide.md +149 -0
  143. package/skills/skillkit/knowledge/tools/21-quality-scorer-guide.md +226 -0
  144. package/skills/skillkit/knowledge/tools/22-migration-helper-guide.md +356 -0
  145. package/skills/skillkit/knowledge/tools/23-subagent-creation-guide.md +448 -0
  146. package/skills/skillkit/knowledge/tools/24-behavioral-testing-guide.md +122 -0
  147. package/skills/skillkit/references/proposal-generation.md +982 -0
  148. package/skills/skillkit/references/rationalization-catalog.md +75 -0
  149. package/skills/skillkit/references/research-methodology.md +661 -0
  150. package/skills/skillkit/references/section-2-full-creation-workflow.md +452 -0
  151. package/skills/skillkit/references/section-3-validation-workflow-existing-skill.md +63 -0
  152. package/skills/skillkit/references/section-4-decision-workflow-skills-vs-subagents.md +64 -0
  153. package/skills/skillkit/references/section-5-migration-workflow-doc-to-skill.md +58 -0
  154. package/skills/skillkit/references/section-6-subagent-creation-workflow.md +499 -0
  155. package/skills/skillkit/references/section-7-knowledge-reference-map.md +72 -0
  156. package/skills/skillkit/scripts/decision_helper.py +799 -0
  157. package/skills/skillkit/scripts/init_skill.py +400 -0
  158. package/skills/skillkit/scripts/init_subagent.py +231 -0
  159. package/skills/skillkit/scripts/migration_helper.py +669 -0
  160. package/skills/skillkit/scripts/package_skill.py +211 -0
  161. package/skills/skillkit/scripts/pattern_detector.py +381 -0
  162. package/skills/skillkit/scripts/pattern_detector_new.py +382 -0
  163. package/skills/skillkit/scripts/pressure_tester.py +157 -0
  164. package/skills/skillkit/scripts/quality_scorer.py +999 -0
  165. package/skills/skillkit/scripts/quick_validate.py +100 -0
  166. package/skills/skillkit/scripts/security_scanner.py +474 -0
  167. package/skills/skillkit/scripts/split_skill.py +540 -0
  168. package/skills/skillkit/scripts/test_generator.py +695 -0
  169. package/skills/skillkit/scripts/token_estimator.py +493 -0
  170. package/skills/skillkit/scripts/utils/__init__.py +49 -0
  171. package/skills/skillkit/scripts/utils/budget_tracker.py +388 -0
  172. package/skills/skillkit/scripts/utils/output_formatter.py +263 -0
  173. package/skills/skillkit/scripts/utils/reference_validator.py +401 -0
  174. package/skills/skillkit/scripts/validate_skill.py +594 -0
  175. package/skills/skillkit/tests/test_behavioral.py +39 -0
  176. package/skills/skillkit/tests/test_scenarios.md +83 -0
  177. package/skills/skillkit/tests/test_skill.py +136 -0
  178. package/skills/social-media-seo/SKILL.md +278 -0
  179. package/skills/social-media-seo/databases/caption-styles.csv +31 -0
  180. package/skills/social-media-seo/databases/engagement-tactics.csv +16 -0
  181. package/skills/social-media-seo/databases/hashtag-strategies.csv +21 -0
  182. package/skills/social-media-seo/databases/hook-formulas.csv +26 -0
  183. package/skills/social-media-seo/databases/keyword-clusters.csv +11 -0
  184. package/skills/social-media-seo/databases/thread-structures.csv +26 -0
  185. package/skills/social-media-seo/databases/viral-patterns.csv +21 -0
  186. package/skills/social-media-seo/references/analytics-guide.md +321 -0
  187. package/skills/social-media-seo/references/instagram-seo.md +235 -0
  188. package/skills/social-media-seo/references/threads-seo.md +305 -0
  189. package/skills/social-media-seo/references/x-twitter-seo.md +337 -0
  190. package/skills/social-media-seo/scripts/query_database.py +191 -0
  191. package/skills/storyteller/SKILL.md +241 -0
  192. package/skills/storyteller/references/transformation-methodology.md +293 -0
  193. package/skills/storyteller/references/visual-vocabulary.md +177 -0
  194. package/skills/thread-pro/SKILL.md +162 -0
  195. package/skills/thread-pro/anti-ai-patterns.md +120 -0
  196. package/skills/thread-pro/hook-formulas.md +138 -0
  197. package/skills/thread-pro/references/anti-ai-patterns.md +120 -0
  198. package/skills/thread-pro/references/hook-formulas.md +138 -0
  199. package/skills/thread-pro/references/thread-structures.md +240 -0
  200. package/skills/thread-pro/references/voice-injection.md +130 -0
  201. package/skills/thread-pro/thread-structures.md +240 -0
  202. package/skills/thread-pro/voice-injection.md +130 -0
  203. package/skills/tinkering/SKILL.md +251 -0
  204. package/skills/tinkering/references/graduation-checklist.md +100 -0
  205. package/skills/validate-plan/.skillkit-mode +1 -0
  206. package/skills/validate-plan/SKILL.md +406 -0
  207. package/skills/validate-plan/references/dry-principles.md +251 -0
  208. package/skills/validate-plan/references/gap-analysis-guide.md +320 -0
  209. package/skills/validate-plan/references/tdd-patterns.md +413 -0
  210. package/skills/validate-plan/references/yagni-checklist.md +330 -0
  211. package/skills/verify-before-ship/.skillkit-mode +1 -0
  212. package/skills/verify-before-ship/SKILL.md +116 -0
  213. package/skills/verify-before-ship/references/anti-rationalization.md +212 -0
  214. package/skills/verify-before-ship/references/verification-gates.md +305 -0
  215. package/skills-manifest.json +217 -0
  216. package/src/banner.js +10 -0
  217. package/src/cli.js +30 -0
  218. package/src/install.js +53 -0
  219. package/src/install.test.js +40 -0
  220. package/src/picker.js +74 -0
  221. package/src/picker.test.js +21 -0
  222. package/src/scope.js +57 -0
  223. package/src/scope.test.js +19 -0
  224. package/src/update.js +34 -0
  225. package/src/update.test.js +24 -0
@@ -0,0 +1,540 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Auto-split large SKILL.md for progressive disclosure optimization.
4
+ Based on token economics from File 05 and architecture from File 10.
5
+
6
+ References: Files 05, 10 (token optimization, architecture)
7
+ """
8
+
9
+ import re
10
+ import json
11
+ import argparse
12
+ import sys
13
+ from pathlib import Path
14
+ from typing import List, Dict, Optional
15
+
16
+ # Import shared utilities for standardized output
17
+ try:
18
+ from utils.output_formatter import add_format_argument, format_success_response, format_error_response, output_json
19
+ except ImportError:
20
+ # Fallback if utils not in path
21
+ sys.path.insert(0, str(Path(__file__).parent))
22
+ from utils.output_formatter import add_format_argument, format_success_response, format_error_response, output_json
23
+
24
+ class SkillSplitter:
25
+ """Intelligently split SKILL.md into main + references."""
26
+
27
+ def __init__(self,
28
+ skill_path: str,
29
+ threshold: int = 500,
30
+ preview: bool = False,
31
+ auto: bool = False,
32
+ output_format: str = 'text'):
33
+ """
34
+ Initialize splitter.
35
+
36
+ Args:
37
+ skill_path: Path to skill directory
38
+ threshold: Line count threshold for splitting
39
+ preview: If True, show changes without applying
40
+ auto: If True, split without confirmation
41
+ output_format: 'text' or 'json' for agent-layer
42
+
43
+ References: File 10 (progressive disclosure architecture)
44
+ """
45
+ self.skill_path = Path(skill_path)
46
+ self.threshold = threshold
47
+ self.preview = preview
48
+ self.auto = auto
49
+ self.output_format = output_format
50
+ self.skill_md_content = None
51
+ self.frontmatter = ''
52
+ self.sections = []
53
+ self.core_sections = []
54
+ self.reference_sections = []
55
+
56
+ # ========== ANALYSIS ==========
57
+
58
+ def analyze_skill(self) -> Dict:
59
+ """
60
+ Analyze SKILL.md structure and identify split candidates.
61
+
62
+ Returns:
63
+ Dict with analysis results including:
64
+ - needs_split: bool
65
+ - total_lines: int
66
+ - sections: int
67
+ - core_sections: int
68
+ - reference_sections: int
69
+
70
+ Raises:
71
+ FileNotFoundError: If SKILL.md doesn't exist
72
+
73
+ References: File 05 (token optimization strategies)
74
+ """
75
+ skill_md = self.skill_path / "SKILL.md"
76
+ if not skill_md.exists():
77
+ raise FileNotFoundError(f"SKILL.md not found in {self.skill_path}")
78
+
79
+ with open(skill_md, encoding='utf-8') as f:
80
+ self.skill_md_content = f.read()
81
+ lines = self.skill_md_content.split('\n')
82
+
83
+ total_lines = len(lines)
84
+
85
+ if self.output_format == 'text':
86
+ print(f"\nAnalyzing SKILL.md...")
87
+ print(f" Current size: {total_lines} lines")
88
+ print(f" Threshold: {self.threshold} lines")
89
+
90
+ if total_lines < self.threshold:
91
+ if self.output_format == 'text':
92
+ print(f"\n✔ SKILL.md already optimal (<{self.threshold} lines)")
93
+ print(" No split needed.")
94
+ return {
95
+ 'needs_split': False,
96
+ 'total_lines': total_lines,
97
+ 'threshold': self.threshold
98
+ }
99
+
100
+ if self.output_format == 'text':
101
+ print(f"\n⚠️ SKILL.md exceeds threshold ({total_lines} > {self.threshold})")
102
+
103
+ # Parse structure
104
+ self._parse_structure()
105
+ self._classify_sections()
106
+
107
+ core_lines = sum(s['lines'] for s in self.core_sections)
108
+ ref_lines = sum(s['lines'] for s in self.reference_sections)
109
+
110
+ return {
111
+ 'needs_split': True,
112
+ 'total_lines': total_lines,
113
+ 'threshold': self.threshold,
114
+ 'core_sections': len(self.core_sections),
115
+ 'reference_sections': len(self.reference_sections),
116
+ 'core_lines': core_lines,
117
+ 'reference_lines': ref_lines,
118
+ 'reduction_percent': (ref_lines / total_lines * 100) if total_lines > 0 else 0
119
+ }
120
+
121
+ def _parse_structure(self):
122
+ """Parse SKILL.md into sections."""
123
+ lines = self.skill_md_content.split('\n')
124
+
125
+ # Extract frontmatter
126
+ in_frontmatter = False
127
+ frontmatter_lines = []
128
+ content_start = 0
129
+
130
+ for i, line in enumerate(lines):
131
+ if line.strip() == '---':
132
+ if not in_frontmatter:
133
+ in_frontmatter = True
134
+ frontmatter_lines.append(line)
135
+ elif in_frontmatter:
136
+ frontmatter_lines.append(line)
137
+ self.frontmatter = '\n'.join(frontmatter_lines)
138
+ content_start = i + 1
139
+ break
140
+ elif in_frontmatter:
141
+ frontmatter_lines.append(line)
142
+
143
+ # Parse sections (## headers)
144
+ current_section = None
145
+
146
+ for i in range(content_start, len(lines)):
147
+ line = lines[i]
148
+
149
+ # Check for ## header
150
+ if line.startswith('## '):
151
+ # Save previous section
152
+ if current_section:
153
+ self.sections.append(current_section)
154
+
155
+ # Start new section
156
+ current_section = {
157
+ 'header': line,
158
+ 'title': line.strip('# ').strip(),
159
+ 'content': '',
160
+ 'lines': 0,
161
+ 'type': 'unknown'
162
+ }
163
+ elif current_section:
164
+ current_section['content'] += line + '\n'
165
+ current_section['lines'] += 1
166
+
167
+ # Save last section
168
+ if current_section:
169
+ self.sections.append(current_section)
170
+
171
+ def _classify_sections(self):
172
+ """Classify sections as core or reference."""
173
+ # Core section patterns
174
+ core_patterns = [
175
+ r'overview',
176
+ r'quick start',
177
+ r'installation',
178
+ r'usage',
179
+ r'basic',
180
+ r'getting started',
181
+ r'introduction'
182
+ ]
183
+
184
+ # Reference section patterns
185
+ reference_patterns = [
186
+ r'advanced',
187
+ r'detailed',
188
+ r'examples',
189
+ r'reference',
190
+ r'appendix',
191
+ r'troubleshooting',
192
+ r'faq',
193
+ r'api',
194
+ r'configuration'
195
+ ]
196
+
197
+ for section in self.sections:
198
+ title_lower = section['title'].lower()
199
+
200
+ # Check if core
201
+ if any(re.search(pattern, title_lower) for pattern in core_patterns):
202
+ section['type'] = 'core'
203
+ self.core_sections.append(section)
204
+ # Check if reference
205
+ elif any(re.search(pattern, title_lower) for pattern in reference_patterns):
206
+ section['type'] = 'reference'
207
+ self.reference_sections.append(section)
208
+ # Default: keep in core if short, move to reference if long
209
+ elif section['lines'] < 50:
210
+ section['type'] = 'core'
211
+ self.core_sections.append(section)
212
+ else:
213
+ section['type'] = 'reference'
214
+ self.reference_sections.append(section)
215
+
216
+ # ========== SPLITTING ==========
217
+
218
+ def perform_split(self) -> Dict:
219
+ """
220
+ Perform the actual split operation.
221
+
222
+ Returns:
223
+ Dict with split results
224
+ """
225
+ if not self.sections:
226
+ raise ValueError("No sections found. Run analyze_skill() first.")
227
+
228
+ core_lines = sum(s['lines'] for s in self.core_sections)
229
+ ref_lines = sum(s['lines'] for s in self.reference_sections)
230
+ total_lines = core_lines + ref_lines
231
+
232
+ # Show preview if requested
233
+ if self.preview:
234
+ if self.output_format == 'text':
235
+ self._show_split_preview()
236
+ return {
237
+ 'executed': False,
238
+ 'preview_mode': True,
239
+ 'core_lines': core_lines,
240
+ 'reference_lines': ref_lines,
241
+ 'total_lines': total_lines,
242
+ 'core_sections': [{'title': s['title'], 'lines': s['lines']} for s in self.core_sections],
243
+ 'reference_sections': [{'title': s['title'], 'lines': s['lines']} for s in self.reference_sections],
244
+ 'reduction_percent': (ref_lines / total_lines * 100) if total_lines > 0 else 0
245
+ }
246
+
247
+ # Confirm with user (unless auto mode or JSON output)
248
+ if not self.auto and self.output_format == 'text':
249
+ print()
250
+ response = input("Proceed with split? [y/n]: ")
251
+ if response.lower() != 'y':
252
+ print("Split cancelled.")
253
+ return {
254
+ 'executed': False,
255
+ 'cancelled': True
256
+ }
257
+
258
+ # Execute split
259
+ if self.output_format == 'text':
260
+ print("\nExecuting split...")
261
+
262
+ # Create references directory
263
+ refs_dir = self.skill_path / "references"
264
+ refs_dir.mkdir(exist_ok=True)
265
+ if self.output_format == 'text':
266
+ print(f" • Created directory: references/")
267
+
268
+ # Move reference sections
269
+ created_files = []
270
+ for section in self.reference_sections:
271
+ filename = self._create_reference_file(section, refs_dir)
272
+ created_files.append(filename)
273
+
274
+ # Update SKILL.md
275
+ self._update_skill_md()
276
+
277
+ # Generate report
278
+ self._generate_split_report(core_lines, ref_lines, total_lines)
279
+
280
+ if self.output_format == 'text':
281
+ print(f"\n✔ Split completed successfully!")
282
+
283
+ return {
284
+ 'executed': True,
285
+ 'core_lines': core_lines,
286
+ 'reference_lines': ref_lines,
287
+ 'total_lines': total_lines,
288
+ 'files_created': created_files,
289
+ 'core_sections': [{'title': s['title'], 'lines': s['lines']} for s in self.core_sections],
290
+ 'reference_sections': [{'title': s['title'], 'lines': s['lines'], 'file': s.get('reference_file', '')} for s in self.reference_sections],
291
+ 'reduction_percent': (ref_lines / total_lines * 100) if total_lines > 0 else 0
292
+ }
293
+
294
+ def _create_reference_file(self, section: Dict, refs_dir: Path) -> str:
295
+ """
296
+ Create a reference file from a section.
297
+
298
+ Args:
299
+ section: Section dictionary
300
+ refs_dir: References directory path
301
+
302
+ Returns:
303
+ Filename created
304
+ """
305
+ # Generate filename from title
306
+ filename = self._sanitize_filename(section['title']) + '.md'
307
+ filepath = refs_dir / filename
308
+
309
+ # Write content
310
+ with open(filepath, 'w', encoding='utf-8') as f:
311
+ f.write(f"# {section['title']}\n\n")
312
+ f.write(section['content'].strip())
313
+ f.write('\n') # Ensure trailing newline
314
+
315
+ if self.output_format == 'text':
316
+ print(f" • Created: references/{filename} ({section['lines']} lines)")
317
+
318
+ # Store reference for updating SKILL.md
319
+ section['reference_file'] = filename
320
+
321
+ return filename
322
+
323
+ def _sanitize_filename(self, title: str) -> str:
324
+ """
325
+ Convert section title to valid filename.
326
+
327
+ Args:
328
+ title: Section title
329
+
330
+ Returns:
331
+ Sanitized filename (lowercase, hyphens, no special chars)
332
+ """
333
+ # Remove special chars, convert spaces to hyphens
334
+ filename = re.sub(r'[^a-zA-Z0-9\s-]', '', title)
335
+ filename = filename.lower().replace(' ', '-')
336
+ # Remove multiple consecutive hyphens
337
+ filename = re.sub(r'-+', '-', filename)
338
+ # Remove leading/trailing hyphens
339
+ filename = filename.strip('-')
340
+ return filename
341
+
342
+ def _update_skill_md(self):
343
+ """
344
+ Update SKILL.md with core sections and cross-references.
345
+
346
+ New structure:
347
+ 1. Frontmatter (preserved)
348
+ 2. Core sections (preserved)
349
+ 3. Additional Resources section (new, with links)
350
+ """
351
+ # Build new SKILL.md
352
+ new_content = []
353
+
354
+ # Add frontmatter
355
+ if self.frontmatter:
356
+ new_content.append(self.frontmatter.rstrip())
357
+
358
+ # Add core sections
359
+ for section in self.core_sections:
360
+ new_content.append(f"\n{section['header']}")
361
+ new_content.append(section['content'].strip())
362
+
363
+ # Add reference links section
364
+ new_content.append("\n## Additional Resources")
365
+ new_content.append("\nFor detailed information, see:")
366
+ new_content.append("")
367
+
368
+ for section in self.reference_sections:
369
+ ref_file = section['reference_file']
370
+ new_content.append(f"- [{section['title']}](references/{ref_file})")
371
+
372
+ # Write updated SKILL.md
373
+ skill_md = self.skill_path / "SKILL.md"
374
+ with open(skill_md, 'w', encoding='utf-8') as f:
375
+ f.write('\n'.join(new_content))
376
+ f.write('\n') # Ensure trailing newline
377
+
378
+ if self.output_format == 'text':
379
+ print(f" • Updated: SKILL.md")
380
+
381
+ def _show_split_preview(self):
382
+ """Show preview of split without applying changes."""
383
+ print("\n" + "="*70)
384
+ print("SPLIT PREVIEW")
385
+ print("="*70)
386
+
387
+ print("\n📄 Core Sections (will remain in SKILL.md):")
388
+ for i, section in enumerate(self.core_sections, 1):
389
+ print(f" {i}. {section['title']} ({section['lines']} lines)")
390
+
391
+ print(f"\n📚 Reference Sections (will move to references/):")
392
+ for i, section in enumerate(self.reference_sections, 1):
393
+ filename = self._sanitize_filename(section['title']) + '.md'
394
+ print(f" {i}. {section['title']}")
395
+ print(f" → references/{filename} ({section['lines']} lines)")
396
+
397
+ print("\n" + "="*70)
398
+ core_lines = sum(s['lines'] for s in self.core_sections)
399
+ ref_lines = sum(s['lines'] for s in self.reference_sections)
400
+ total_lines = core_lines + ref_lines
401
+
402
+ print(f"Summary:")
403
+ print(f" Current SKILL.md: {total_lines} lines")
404
+ print(f" After split: {core_lines} lines (SKILL.md)")
405
+ print(f" References: {len(self.reference_sections)} files, {ref_lines} lines total")
406
+ print(f" Reduction: {ref_lines/total_lines*100:.1f}%")
407
+ print("="*70)
408
+
409
+ def _generate_split_report(self, core_lines: int, ref_lines: int, total_lines: int):
410
+ """
411
+ Generate and save split report.
412
+
413
+ Args:
414
+ core_lines: Lines remaining in SKILL.md
415
+ ref_lines: Lines moved to references
416
+ total_lines: Original total lines
417
+ """
418
+ report_path = self.skill_path / "split_report.md"
419
+
420
+ with open(report_path, 'w', encoding='utf-8') as f:
421
+ f.write("# Skill Split Report\n\n")
422
+ f.write(f"**Date:** {self._get_date()}\n")
423
+ f.write(f"**Threshold:** {self.threshold} lines\n\n")
424
+
425
+ f.write("## Summary\n\n")
426
+ f.write(f"- **Original size:** {total_lines} lines\n")
427
+ f.write(f"- **New SKILL.md size:** {core_lines} lines\n")
428
+ f.write(f"- **References created:** {len(self.reference_sections)} files\n")
429
+ f.write(f"- **Total reference lines:** {ref_lines} lines\n")
430
+ f.write(f"- **Size reduction:** {ref_lines/total_lines*100:.1f}%\n\n")
431
+
432
+ f.write("## Core Sections (in SKILL.md)\n\n")
433
+ for section in self.core_sections:
434
+ f.write(f"- {section['title']} ({section['lines']} lines)\n")
435
+
436
+ f.write("\n## Reference Sections (in references/)\n\n")
437
+ for section in self.reference_sections:
438
+ f.write(f"- [{section['title']}](references/{section['reference_file']}) ")
439
+ f.write(f"({section['lines']} lines)\n")
440
+
441
+ if self.output_format == 'text':
442
+ print(f" • Generated: split_report.md")
443
+
444
+ def _get_date(self) -> str:
445
+ """Get current date in YYYY-MM-DD format."""
446
+ from datetime import datetime
447
+ return datetime.now().strftime("%Y-%m-%d")
448
+
449
+ def main():
450
+ """CLI entry point."""
451
+ parser = argparse.ArgumentParser(
452
+ description="Auto-split large SKILL.md for progressive disclosure",
453
+ epilog="References: Files 05, 10 for optimization strategies"
454
+ )
455
+ parser.add_argument(
456
+ 'skill_path',
457
+ type=str,
458
+ help='Path to skill directory'
459
+ )
460
+ parser.add_argument(
461
+ '--threshold',
462
+ type=int,
463
+ default=500,
464
+ help='Line count threshold for splitting (default: 500)'
465
+ )
466
+ parser.add_argument(
467
+ '--preview',
468
+ action='store_true',
469
+ help='Preview changes without applying'
470
+ )
471
+ parser.add_argument(
472
+ '--auto',
473
+ action='store_true',
474
+ help='Automatic split without confirmation'
475
+ )
476
+ add_format_argument(parser) # Standardized --format argument
477
+
478
+ args = parser.parse_args()
479
+
480
+ try:
481
+ splitter = SkillSplitter(
482
+ args.skill_path,
483
+ threshold=args.threshold,
484
+ preview=args.preview,
485
+ auto=args.auto,
486
+ output_format=args.format
487
+ )
488
+
489
+ analysis = splitter.analyze_skill()
490
+
491
+ if args.format == 'json':
492
+ # JSON output mode
493
+ if analysis.get('needs_split'):
494
+ result = splitter.perform_split()
495
+ output = {
496
+ 'status': 'success',
497
+ 'analysis': analysis,
498
+ 'split_result': result
499
+ }
500
+ else:
501
+ output = {
502
+ 'status': 'success',
503
+ 'analysis': analysis,
504
+ 'message': 'No split needed - skill already optimal'
505
+ }
506
+ print(json.dumps(output, indent=2))
507
+ else:
508
+ # Text output mode (existing behavior)
509
+ if analysis.get('needs_split'):
510
+ splitter.perform_split()
511
+
512
+ return 0
513
+
514
+ except FileNotFoundError as e:
515
+ if args.format == 'json':
516
+ response = format_error_response(
517
+ error_type='FileNotFoundError',
518
+ message=str(e),
519
+ tool_name='split_skill',
520
+ help_text='Ensure skill directory exists and contains SKILL.md'
521
+ )
522
+ output_json(response)
523
+ else:
524
+ print(f"\n✗ Error: {e}")
525
+ return 1
526
+ except Exception as e:
527
+ if args.format == 'json':
528
+ response = format_error_response(
529
+ error_type=type(e).__name__,
530
+ message=str(e),
531
+ tool_name='split_skill',
532
+ help_text='Check skill structure and permissions'
533
+ )
534
+ output_json(response)
535
+ else:
536
+ print(f"\n✗ Unexpected error: {e}")
537
+ return 2
538
+
539
+ if __name__ == "__main__":
540
+ exit(main())