@rfxlamia/skillkit 1.0.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.
- package/agents/agents/creative-copywriter.md +212 -0
- package/agents/agents/dario-amodei.md +135 -0
- package/agents/agents/doc-simplifier.md +63 -0
- package/agents/agents/kotlin-pro.md +433 -0
- package/agents/agents/red-team.md +136 -0
- package/agents/agents/sam-altman.md +121 -0
- package/agents/agents/seo-manager.md +184 -0
- package/package.json +7 -2
- package/skills/quick-spec/tests/__pycache__/test_skill.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/skillkit/.claude/settings.local.json +7 -0
- package/skills/skillkit/scripts/__pycache__/decision_helper.cpython-314.pyc +0 -0
- package/skills/skillkit/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/skills/skillkit/scripts/__pycache__/quick_validate.cpython-314.pyc +0 -0
- package/skills/skillkit/scripts/__pycache__/test_generator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-312.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-314.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-312.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-314.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-312.pyc +0 -0
- package/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-314.pyc +0 -0
- package/skills/skillkit-help/SKILL.md +81 -0
- package/skills/skillkit-help/knowledge/application/09-case-studies.md +257 -0
- package/skills/skillkit-help/knowledge/application/12-testing-and-validation.md +276 -0
- package/skills/skillkit-help/knowledge/foundation/01-why-skills-exist.md +246 -0
- package/skills/skillkit-help/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
- package/skills/skillkit-help/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
- package/skills/skillkit-help/knowledge/foundation/06-platform-constraints.md +237 -0
- package/skills/skillkit-help/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
- package/skills/skillkit-help/template/SKILL.md +52 -0
- package/skills/skills/adversarial-review/SKILL.md +219 -0
- package/skills/skills/baby-education/SKILL.md +260 -0
- package/skills/skills/baby-education/references/advanced-techniques.md +323 -0
- package/skills/skills/baby-education/references/transformations.md +345 -0
- package/skills/skills/been-there-done-that/SKILL.md +455 -0
- package/skills/skills/been-there-done-that/references/analysis-patterns.md +162 -0
- package/skills/skills/been-there-done-that/references/git-commands.md +132 -0
- package/skills/skills/been-there-done-that/references/tree-insertion-logic.md +145 -0
- package/skills/skills/coolhunter/SKILL.md +270 -0
- package/skills/skills/coolhunter/assets/elicitation-methods.csv +51 -0
- package/skills/skills/coolhunter/knowledge/elicitation-methods.md +312 -0
- package/skills/skills/coolhunter/references/workflow-execution.md +238 -0
- package/skills/skills/coolhunter/workflow-plan-coolhunter.md +232 -0
- package/skills/skills/creative-copywriting/SKILL.md +324 -0
- package/skills/skills/creative-copywriting/databases/README.md +60 -0
- package/skills/skills/creative-copywriting/databases/carousel-structures.csv +16 -0
- package/skills/skills/creative-copywriting/databases/emotional-arcs.csv +11 -0
- package/skills/skills/creative-copywriting/databases/hook-formulas.csv +51 -0
- package/skills/skills/creative-copywriting/databases/power-words.csv +201 -0
- package/skills/skills/creative-copywriting/databases/psychological-triggers.csv +21 -0
- package/skills/skills/creative-copywriting/databases/read-more-patterns.csv +26 -0
- package/skills/skills/creative-copywriting/databases/swipe-triggers.csv +31 -0
- package/skills/skills/creative-copywriting/references/carousel-psychology.md +223 -0
- package/skills/skills/creative-copywriting/references/hook-anatomy.md +169 -0
- package/skills/skills/creative-copywriting/references/power-word-science.md +134 -0
- package/skills/skills/creative-copywriting/references/storytelling-frameworks.md +157 -0
- package/skills/skills/diverse-content-gen/SKILL.md +201 -0
- package/skills/skills/diverse-content-gen/references/advanced-techniques.md +320 -0
- package/skills/skills/diverse-content-gen/references/research-findings.md +379 -0
- package/skills/skills/diverse-content-gen/references/task-workflows.md +241 -0
- package/skills/skills/diverse-content-gen/references/tool-integration.md +419 -0
- package/skills/skills/diverse-content-gen/references/troubleshooting.md +426 -0
- package/skills/skills/diverse-content-gen/references/vs-core-technique.md +240 -0
- package/skills/skills/framework-critical-thinking/SKILL.md +220 -0
- package/skills/skills/framework-critical-thinking/references/bias_detector.md +375 -0
- package/skills/skills/framework-critical-thinking/references/fallback_handler.md +239 -0
- package/skills/skills/framework-critical-thinking/references/memory_curator.md +161 -0
- package/skills/skills/framework-critical-thinking/references/metacognitive_monitor.md +297 -0
- package/skills/skills/framework-critical-thinking/references/producer_critic_orchestrator.md +333 -0
- package/skills/skills/framework-critical-thinking/references/reasoning_router.md +235 -0
- package/skills/skills/framework-critical-thinking/references/reasoning_validator.md +97 -0
- package/skills/skills/framework-critical-thinking/references/reflection_trigger.md +78 -0
- package/skills/skills/framework-critical-thinking/references/self_verification.md +388 -0
- package/skills/skills/framework-critical-thinking/references/uncertainty_quantifier.md +207 -0
- package/skills/skills/framework-initiative/SKILL.md +231 -0
- package/skills/skills/framework-initiative/references/examples.md +150 -0
- package/skills/skills/framework-initiative/references/impact-analysis.md +157 -0
- package/skills/skills/framework-initiative/references/intent-patterns.md +145 -0
- package/skills/skills/framework-initiative/references/star-framework.md +165 -0
- package/skills/skills/humanize-docs/SKILL.md +203 -0
- package/skills/skills/humanize-docs/references/advanced-techniques.md +13 -0
- package/skills/skills/humanize-docs/references/core-transformations.md +368 -0
- package/skills/skills/humanize-docs/references/detection-patterns.md +400 -0
- package/skills/skills/humanize-docs/references/examples-gallery.md +374 -0
- package/skills/skills/imagine/SKILL.md +190 -0
- package/skills/skills/imagine/references/artstyle-corporate-memphis.md +625 -0
- package/skills/skills/imagine/references/artstyle-crewdson-hyperrealism.md +295 -0
- package/skills/skills/imagine/references/artstyle-iphone-social-media.md +426 -0
- package/skills/skills/imagine/references/artstyle-sciencesaru.md +276 -0
- package/skills/skills/pre-deploy-checklist/README.md +26 -0
- package/skills/skills/pre-deploy-checklist/SKILL.md +153 -0
- package/skills/skills/pre-deploy-checklist/references/checklist-categories.md +174 -0
- package/skills/skills/pre-deploy-checklist/references/domain-prompts.md +216 -0
- package/skills/skills/prompt-engineering/SKILL.md +209 -0
- package/skills/skills/prompt-engineering/references/advanced-combinations.md +444 -0
- package/skills/skills/prompt-engineering/references/chain-of-thought.md +140 -0
- package/skills/skills/prompt-engineering/references/decision_matrix.md +220 -0
- package/skills/skills/prompt-engineering/references/few-shot.md +346 -0
- package/skills/skills/prompt-engineering/references/json-format.md +270 -0
- package/skills/skills/prompt-engineering/references/natural-language.md +420 -0
- package/skills/skills/prompt-engineering/references/pitfalls.md +365 -0
- package/skills/skills/prompt-engineering/references/prompt-chaining.md +498 -0
- package/skills/skills/prompt-engineering/references/react.md +108 -0
- package/skills/skills/prompt-engineering/references/self-consistency.md +322 -0
- package/skills/skills/prompt-engineering/references/tree-of-thoughts.md +386 -0
- package/skills/skills/prompt-engineering/references/xml-format.md +220 -0
- package/skills/skills/prompt-engineering/references/yaml-format.md +488 -0
- package/skills/skills/prompt-engineering/references/zero-shot.md +74 -0
- package/skills/skills/quick-spec/SKILL.md +280 -0
- package/skills/skills/quick-spec/assets/tech-spec-template.md +74 -0
- package/skills/skills/quick-spec/references/step-01-understand.md +189 -0
- package/skills/skills/quick-spec/references/step-02-investigate.md +144 -0
- package/skills/skills/quick-spec/references/step-03-generate.md +128 -0
- package/skills/skills/quick-spec/references/step-04-review.md +173 -0
- package/skills/skills/quick-spec/tests/__pycache__/test_skill.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/skills/quick-spec/tests/test_scenarios.md +83 -0
- package/skills/skills/quick-spec/tests/test_skill.py +136 -0
- package/skills/skills/readme-expert/SKILL.md +538 -0
- package/skills/skills/readme-expert/knowledge/INDEX.md +192 -0
- package/skills/skills/readme-expert/knowledge/application/quality-standards.md +470 -0
- package/skills/skills/readme-expert/knowledge/application/script-executor.md +604 -0
- package/skills/skills/readme-expert/knowledge/application/template-library.md +822 -0
- package/skills/skills/readme-expert/knowledge/foundation/codebase-scanner.md +361 -0
- package/skills/skills/readme-expert/knowledge/foundation/validation-checklist.md +481 -0
- package/skills/skills/red-teaming/SKILL.md +321 -0
- package/skills/skills/red-teaming/references/ai-llm-redteam.md +517 -0
- package/skills/skills/red-teaming/references/attack-techniques.md +410 -0
- package/skills/skills/red-teaming/references/cybersecurity-redteam.md +383 -0
- package/skills/skills/red-teaming/references/tools-frameworks.md +446 -0
- package/skills/skills/releasing/.skillkit-mode +1 -0
- package/skills/skills/releasing/SKILL.md +225 -0
- package/skills/skills/releasing/references/version-detection.md +108 -0
- package/skills/skills/screenwriter/SKILL.md +273 -0
- package/skills/skills/screenwriter/references/advanced-techniques.md +216 -0
- package/skills/skills/screenwriter/references/pipeline-integration.md +266 -0
- package/skills/skills/skillkit/.claude/settings.local.json +7 -0
- package/skills/skills/skillkit/.claude-plugin/plugin.json +27 -0
- package/skills/skills/skillkit/CHANGELOG.md +484 -0
- package/skills/skills/skillkit/SKILL.md +511 -0
- package/skills/skills/skillkit/commands/skillkit.md +6 -0
- package/skills/skills/skillkit/commands/validate-plan.md +6 -0
- package/skills/skills/skillkit/commands/verify.md +6 -0
- package/skills/skills/skillkit/knowledge/INDEX.md +352 -0
- package/skills/skills/skillkit/knowledge/application/09-case-studies.md +257 -0
- package/skills/skills/skillkit/knowledge/application/10-technical-architecture.md +324 -0
- package/skills/skills/skillkit/knowledge/application/11-adoption-strategy.md +267 -0
- package/skills/skills/skillkit/knowledge/application/12-testing-and-validation.md +276 -0
- package/skills/skills/skillkit/knowledge/application/13-competitive-landscape.md +198 -0
- package/skills/skills/skillkit/knowledge/foundation/01-why-skills-exist.md +246 -0
- package/skills/skills/skillkit/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
- package/skills/skills/skillkit/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
- package/skills/skills/skillkit/knowledge/foundation/04-hybrid-patterns.md +308 -0
- package/skills/skills/skillkit/knowledge/foundation/05-token-economics.md +275 -0
- package/skills/skills/skillkit/knowledge/foundation/06-platform-constraints.md +237 -0
- package/skills/skills/skillkit/knowledge/foundation/07-security-concerns.md +322 -0
- package/skills/skills/skillkit/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
- package/skills/skills/skillkit/knowledge/plugin-guide.md +614 -0
- package/skills/skills/skillkit/knowledge/tools/14-validation-tools-guide.md +150 -0
- package/skills/skills/skillkit/knowledge/tools/15-cost-tools-guide.md +157 -0
- package/skills/skills/skillkit/knowledge/tools/16-security-tools-guide.md +122 -0
- package/skills/skills/skillkit/knowledge/tools/17-pattern-tools-guide.md +161 -0
- package/skills/skills/skillkit/knowledge/tools/18-decision-helper-guide.md +243 -0
- package/skills/skills/skillkit/knowledge/tools/19-test-generator-guide.md +275 -0
- package/skills/skills/skillkit/knowledge/tools/20-split-skill-guide.md +149 -0
- package/skills/skills/skillkit/knowledge/tools/21-quality-scorer-guide.md +226 -0
- package/skills/skills/skillkit/knowledge/tools/22-migration-helper-guide.md +356 -0
- package/skills/skills/skillkit/knowledge/tools/23-subagent-creation-guide.md +448 -0
- package/skills/skills/skillkit/knowledge/tools/24-behavioral-testing-guide.md +122 -0
- package/skills/skills/skillkit/references/proposal-generation.md +982 -0
- package/skills/skills/skillkit/references/rationalization-catalog.md +75 -0
- package/skills/skills/skillkit/references/research-methodology.md +661 -0
- package/skills/skills/skillkit/references/section-2-full-creation-workflow.md +452 -0
- package/skills/skills/skillkit/references/section-3-validation-workflow-existing-skill.md +63 -0
- package/skills/skills/skillkit/references/section-4-decision-workflow-skills-vs-subagents.md +64 -0
- package/skills/skills/skillkit/references/section-5-migration-workflow-doc-to-skill.md +58 -0
- package/skills/skills/skillkit/references/section-6-subagent-creation-workflow.md +499 -0
- package/skills/skills/skillkit/references/section-7-knowledge-reference-map.md +72 -0
- package/skills/skills/skillkit/scripts/__pycache__/decision_helper.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/__pycache__/quick_validate.cpython-312.pyc +0 -0
- package/skills/skills/skillkit/scripts/__pycache__/quick_validate.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/__pycache__/test_generator.cpython-314-pytest-9.0.2.pyc +0 -0
- package/skills/skills/skillkit/scripts/decision_helper.py +799 -0
- package/skills/skills/skillkit/scripts/init_skill.py +400 -0
- package/skills/skills/skillkit/scripts/init_subagent.py +231 -0
- package/skills/skills/skillkit/scripts/migration_helper.py +669 -0
- package/skills/skills/skillkit/scripts/package_skill.py +211 -0
- package/skills/skills/skillkit/scripts/pattern_detector.py +381 -0
- package/skills/skills/skillkit/scripts/pattern_detector_new.py +382 -0
- package/skills/skills/skillkit/scripts/pressure_tester.py +157 -0
- package/skills/skills/skillkit/scripts/quality_scorer.py +999 -0
- package/skills/skills/skillkit/scripts/quick_validate.py +100 -0
- package/skills/skills/skillkit/scripts/security_scanner.py +474 -0
- package/skills/skills/skillkit/scripts/split_skill.py +540 -0
- package/skills/skills/skillkit/scripts/test_generator.py +695 -0
- package/skills/skills/skillkit/scripts/token_estimator.py +493 -0
- package/skills/skills/skillkit/scripts/utils/__init__.py +49 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-312.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/__init__.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-312.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/budget_tracker.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-312.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/output_formatter.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-312.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/__pycache__/reference_validator.cpython-314.pyc +0 -0
- package/skills/skills/skillkit/scripts/utils/budget_tracker.py +388 -0
- package/skills/skills/skillkit/scripts/utils/output_formatter.py +263 -0
- package/skills/skills/skillkit/scripts/utils/reference_validator.py +401 -0
- package/skills/skills/skillkit/scripts/validate_skill.py +594 -0
- package/skills/skills/skillkit/tests/test_behavioral.py +39 -0
- package/skills/skills/skillkit/tests/test_scenarios.md +83 -0
- package/skills/skills/skillkit/tests/test_skill.py +136 -0
- package/skills/skills/skillkit-help/SKILL.md +81 -0
- package/skills/skills/skillkit-help/knowledge/application/09-case-studies.md +257 -0
- package/skills/skills/skillkit-help/knowledge/application/12-testing-and-validation.md +276 -0
- package/skills/skills/skillkit-help/knowledge/foundation/01-why-skills-exist.md +246 -0
- package/skills/skills/skillkit-help/knowledge/foundation/02-skills-vs-subagents-comparison.md +312 -0
- package/skills/skills/skillkit-help/knowledge/foundation/03-skills-vs-subagents-decision-tree.md +346 -0
- package/skills/skills/skillkit-help/knowledge/foundation/06-platform-constraints.md +237 -0
- package/skills/skills/skillkit-help/knowledge/foundation/08-when-not-to-use-skills.md +270 -0
- package/skills/skills/skillkit-help/template/SKILL.md +52 -0
- package/skills/skills/social-media-seo/SKILL.md +278 -0
- package/skills/skills/social-media-seo/databases/caption-styles.csv +31 -0
- package/skills/skills/social-media-seo/databases/engagement-tactics.csv +16 -0
- package/skills/skills/social-media-seo/databases/hashtag-strategies.csv +21 -0
- package/skills/skills/social-media-seo/databases/hook-formulas.csv +26 -0
- package/skills/skills/social-media-seo/databases/keyword-clusters.csv +11 -0
- package/skills/skills/social-media-seo/databases/thread-structures.csv +26 -0
- package/skills/skills/social-media-seo/databases/viral-patterns.csv +21 -0
- package/skills/skills/social-media-seo/references/analytics-guide.md +321 -0
- package/skills/skills/social-media-seo/references/instagram-seo.md +235 -0
- package/skills/skills/social-media-seo/references/threads-seo.md +305 -0
- package/skills/skills/social-media-seo/references/x-twitter-seo.md +337 -0
- package/skills/skills/social-media-seo/scripts/query_database.py +191 -0
- package/skills/skills/storyteller/SKILL.md +241 -0
- package/skills/skills/storyteller/references/transformation-methodology.md +293 -0
- package/skills/skills/storyteller/references/visual-vocabulary.md +177 -0
- package/skills/skills/thread-pro/SKILL.md +162 -0
- package/skills/skills/thread-pro/anti-ai-patterns.md +120 -0
- package/skills/skills/thread-pro/hook-formulas.md +138 -0
- package/skills/skills/thread-pro/references/anti-ai-patterns.md +120 -0
- package/skills/skills/thread-pro/references/hook-formulas.md +138 -0
- package/skills/skills/thread-pro/references/thread-structures.md +240 -0
- package/skills/skills/thread-pro/references/voice-injection.md +130 -0
- package/skills/skills/thread-pro/thread-structures.md +240 -0
- package/skills/skills/thread-pro/voice-injection.md +130 -0
- package/skills/skills/tinkering/SKILL.md +251 -0
- package/skills/skills/tinkering/references/graduation-checklist.md +100 -0
- package/skills/skills/validate-plan/.skillkit-mode +1 -0
- package/skills/skills/validate-plan/SKILL.md +406 -0
- package/skills/skills/validate-plan/references/dry-principles.md +251 -0
- package/skills/skills/validate-plan/references/gap-analysis-guide.md +320 -0
- package/skills/skills/validate-plan/references/tdd-patterns.md +413 -0
- package/skills/skills/validate-plan/references/yagni-checklist.md +330 -0
- package/skills/skills/verify-before-ship/.skillkit-mode +1 -0
- package/skills/skills/verify-before-ship/SKILL.md +116 -0
- package/skills/skills/verify-before-ship/references/anti-rationalization.md +212 -0
- package/skills/skills/verify-before-ship/references/verification-gates.md +305 -0
- package/skills-manifest.json +8 -2
- package/src/banner.js +1 -1
- package/src/cli.js +15 -4
- package/src/install.js +45 -29
- package/src/install.test.js +75 -7
- package/src/picker.js +15 -4
- package/src/picker.test.js +36 -1
- package/src/scope.js +8 -39
- package/src/scope.test.js +9 -13
- package/src/tools.js +76 -0
- package/src/tools.test.js +80 -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())
|