panopticon-cli 0.4.6 → 0.4.7

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 (102) hide show
  1. package/package.json +2 -1
  2. package/skills/beads/README.md +120 -0
  3. package/skills/beads/SKILL.md +214 -0
  4. package/skills/beads/adr/0001-bd-prime-as-source-of-truth.md +59 -0
  5. package/skills/beads/resources/AGENTS.md +62 -0
  6. package/skills/beads/resources/ASYNC_GATES.md +168 -0
  7. package/skills/beads/resources/BOUNDARIES.md +469 -0
  8. package/skills/beads/resources/CHEMISTRY_PATTERNS.md +197 -0
  9. package/skills/beads/resources/CLI_REFERENCE.md +558 -0
  10. package/skills/beads/resources/DEPENDENCIES.md +747 -0
  11. package/skills/beads/resources/INTEGRATION_PATTERNS.md +407 -0
  12. package/skills/beads/resources/ISSUE_CREATION.md +139 -0
  13. package/skills/beads/resources/MOLECULES.md +354 -0
  14. package/skills/beads/resources/PATTERNS.md +341 -0
  15. package/skills/beads/resources/RESUMABILITY.md +207 -0
  16. package/skills/beads/resources/STATIC_DATA.md +54 -0
  17. package/skills/beads/resources/TROUBLESHOOTING.md +489 -0
  18. package/skills/beads/resources/WORKFLOWS.md +623 -0
  19. package/skills/beads/resources/WORKTREES.md +94 -0
  20. package/skills/beads-completion-check/SKILL.md +90 -0
  21. package/skills/beads-panopticon-guide/SKILL.md +171 -0
  22. package/skills/bug-fix/SKILL.md +32 -0
  23. package/skills/clear-writing/SKILL.md +105 -0
  24. package/skills/clear-writing/references/elements-of-style/01-introductory.md +3 -0
  25. package/skills/clear-writing/references/elements-of-style/02-elementary-rules-of-usage.md +214 -0
  26. package/skills/clear-writing/references/elements-of-style/03-elementary-principles-of-composition.md +398 -0
  27. package/skills/clear-writing/references/elements-of-style/04-a-few-matters-of-form.md +89 -0
  28. package/skills/clear-writing/references/elements-of-style/05-words-and-expressions-commonly-misused.md +342 -0
  29. package/skills/clear-writing/references/signs-of-ai-writing.md +901 -0
  30. package/skills/code-review/SKILL.md +37 -0
  31. package/skills/code-review-performance/SKILL.md +53 -0
  32. package/skills/code-review-security/SKILL.md +35 -0
  33. package/skills/dependency-update/SKILL.md +30 -0
  34. package/skills/feature-work/SKILL.md +39 -0
  35. package/skills/incident-response/SKILL.md +32 -0
  36. package/skills/knowledge-capture/SKILL.md +463 -0
  37. package/skills/onboard-codebase/SKILL.md +34 -0
  38. package/skills/opus-plan/SKILL.md +400 -0
  39. package/skills/pan-approve/SKILL.md +136 -0
  40. package/skills/pan-code-review/SKILL.md +249 -0
  41. package/skills/pan-config/SKILL.md +164 -0
  42. package/skills/pan-convoy-synthesis/SKILL.md +249 -0
  43. package/skills/pan-diagnose/SKILL.md +360 -0
  44. package/skills/pan-docker/SKILL.md +279 -0
  45. package/skills/pan-docs/SKILL.md +113 -0
  46. package/skills/pan-down/SKILL.md +434 -0
  47. package/skills/pan-health/SKILL.md +240 -0
  48. package/skills/pan-help/SKILL.md +237 -0
  49. package/skills/pan-install/SKILL.md +339 -0
  50. package/skills/pan-issue/SKILL.md +596 -0
  51. package/skills/pan-kill/SKILL.md +172 -0
  52. package/skills/pan-logs/SKILL.md +255 -0
  53. package/skills/pan-network/SKILL.md +320 -0
  54. package/skills/pan-oversee/SKILL.md +290 -0
  55. package/skills/pan-plan/SKILL.md +521 -0
  56. package/skills/pan-projects/SKILL.md +239 -0
  57. package/skills/pan-quickstart/SKILL.md +440 -0
  58. package/skills/pan-reload/SKILL.md +44 -0
  59. package/skills/pan-rescue/SKILL.md +271 -0
  60. package/skills/pan-restart/SKILL.md +53 -0
  61. package/skills/pan-setup/SKILL.md +478 -0
  62. package/skills/pan-skill-creator/SKILL.md +168 -0
  63. package/skills/pan-skill-creator/references/output-patterns.md +141 -0
  64. package/skills/pan-skill-creator/references/workflows.md +90 -0
  65. package/skills/pan-skill-creator/scripts/init_skill.py +176 -0
  66. package/skills/pan-status/SKILL.md +493 -0
  67. package/skills/pan-subagent-creator/SKILL.md +295 -0
  68. package/skills/pan-subagent-creator/assets/validate-readonly-query.sh +35 -0
  69. package/skills/pan-subagent-creator/references/example-agents.md +308 -0
  70. package/skills/pan-subagent-creator/scripts/init_agent.py +126 -0
  71. package/skills/pan-sync/SKILL.md +272 -0
  72. package/skills/pan-tell/SKILL.md +157 -0
  73. package/skills/pan-test-config/SKILL.md +208 -0
  74. package/skills/pan-tracker/SKILL.md +288 -0
  75. package/skills/pan-up/SKILL.md +458 -0
  76. package/skills/pan-workspace-config/SKILL.md +303 -0
  77. package/skills/refactor/SKILL.md +30 -0
  78. package/skills/refactor-radar/SKILL.md +475 -0
  79. package/skills/release/SKILL.md +25 -0
  80. package/skills/send-feedback-to-agent/SKILL.md +98 -0
  81. package/skills/session-health/SKILL.md +76 -0
  82. package/skills/session-health/scripts/check_sessions.py +166 -0
  83. package/skills/skill-creator/SKILL.md +92 -0
  84. package/skills/skill-creator/scripts/init_skill.py +152 -0
  85. package/skills/skill-creator/scripts/package_skill.py +123 -0
  86. package/skills/stitch-design-md/README.md +34 -0
  87. package/skills/stitch-design-md/SKILL.md +172 -0
  88. package/skills/stitch-design-md/examples/DESIGN.md +154 -0
  89. package/skills/stitch-react-components/README.md +36 -0
  90. package/skills/stitch-react-components/SKILL.md +47 -0
  91. package/skills/stitch-react-components/examples/gold-standard-card.tsx +80 -0
  92. package/skills/stitch-react-components/package-lock.json +231 -0
  93. package/skills/stitch-react-components/package.json +16 -0
  94. package/skills/stitch-react-components/resources/architecture-checklist.md +15 -0
  95. package/skills/stitch-react-components/resources/component-template.tsx +37 -0
  96. package/skills/stitch-react-components/resources/stitch-api-reference.md +14 -0
  97. package/skills/stitch-react-components/resources/style-guide.json +27 -0
  98. package/skills/stitch-react-components/scripts/fetch-stitch.sh +30 -0
  99. package/skills/stitch-react-components/scripts/validate.js +68 -0
  100. package/skills/stitch-setup/SKILL.md +94 -0
  101. package/skills/web-design-guidelines/SKILL.md +39 -0
  102. package/skills/work-complete/SKILL.md +79 -0
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Session Health Checker - Detects stuck/corrupted Claude Code sessions
4
+
5
+ Usage:
6
+ python check_sessions.py [--fix] [--path PATH]
7
+
8
+ Detects:
9
+ - Warmup sidechain loops (tool calls returning "Warmup" errors)
10
+ - Excessive message counts (>500 messages)
11
+ - Infinite retry patterns (same command repeated >10 times)
12
+ """
13
+
14
+ import argparse
15
+ import json
16
+ import os
17
+ import sys
18
+ from collections import Counter
19
+ from pathlib import Path
20
+ from datetime import datetime
21
+
22
+
23
+ def analyze_session(jsonl_path: Path) -> dict:
24
+ """Analyze a single session file for health issues."""
25
+ issues = []
26
+ stats = {
27
+ "path": str(jsonl_path),
28
+ "name": jsonl_path.name,
29
+ "size_kb": jsonl_path.stat().st_size / 1024,
30
+ "message_count": 0,
31
+ "warmup_errors": 0,
32
+ "tool_calls": Counter(),
33
+ "is_sidechain": False,
34
+ "issues": [],
35
+ }
36
+
37
+ try:
38
+ with open(jsonl_path, 'r') as f:
39
+ for line in f:
40
+ stats["message_count"] += 1
41
+ try:
42
+ msg = json.loads(line)
43
+
44
+ # Check if sidechain
45
+ if msg.get("isSidechain"):
46
+ stats["is_sidechain"] = True
47
+
48
+ # Check for warmup errors
49
+ if msg.get("type") == "user":
50
+ content = msg.get("message", {}).get("content", [])
51
+ if isinstance(content, list):
52
+ for item in content:
53
+ if isinstance(item, dict):
54
+ if item.get("content") == "Warmup" and item.get("is_error"):
55
+ stats["warmup_errors"] += 1
56
+
57
+ # Track tool calls
58
+ if msg.get("type") == "assistant":
59
+ content = msg.get("message", {}).get("content", [])
60
+ if isinstance(content, list):
61
+ for item in content:
62
+ if isinstance(item, dict) and item.get("type") == "tool_use":
63
+ tool_input = item.get("input", {})
64
+ if isinstance(tool_input, dict):
65
+ cmd = tool_input.get("command", item.get("name", "unknown"))
66
+ stats["tool_calls"][cmd] += 1
67
+
68
+ except json.JSONDecodeError:
69
+ continue
70
+
71
+ except Exception as e:
72
+ stats["issues"].append(f"Error reading file: {e}")
73
+ return stats
74
+
75
+ # Detect issues
76
+ if stats["warmup_errors"] > 10:
77
+ stats["issues"].append(f"CRITICAL: Warmup loop detected ({stats['warmup_errors']} warmup errors)")
78
+
79
+ if stats["message_count"] > 500:
80
+ stats["issues"].append(f"WARNING: Excessive messages ({stats['message_count']})")
81
+
82
+ # Check for repeated commands
83
+ for cmd, count in stats["tool_calls"].most_common(5):
84
+ if count > 50:
85
+ stats["issues"].append(f"WARNING: Command repeated {count}x: {cmd[:50]}...")
86
+
87
+ if stats["size_kb"] > 2000: # > 2MB
88
+ stats["issues"].append(f"WARNING: Large session file ({stats['size_kb']:.0f}KB)")
89
+
90
+ return stats
91
+
92
+
93
+ def find_sessions(base_path: Path) -> list:
94
+ """Find all session files."""
95
+ sessions = []
96
+ for jsonl in base_path.rglob("*.jsonl"):
97
+ sessions.append(jsonl)
98
+ return sessions
99
+
100
+
101
+ def main():
102
+ parser = argparse.ArgumentParser(description="Check Claude Code session health")
103
+ parser.add_argument("--fix", action="store_true", help="Remove problematic sessions")
104
+ parser.add_argument("--path", default=os.path.expanduser("~/.claude/projects"),
105
+ help="Path to projects directory")
106
+ parser.add_argument("--json", action="store_true", help="Output as JSON")
107
+ args = parser.parse_args()
108
+
109
+ base_path = Path(args.path)
110
+ if not base_path.exists():
111
+ print(f"Path not found: {base_path}")
112
+ sys.exit(1)
113
+
114
+ sessions = find_sessions(base_path)
115
+ results = []
116
+ problematic = []
117
+
118
+ for session_path in sessions:
119
+ stats = analyze_session(session_path)
120
+ results.append(stats)
121
+ if stats["issues"]:
122
+ problematic.append(stats)
123
+
124
+ if args.json:
125
+ print(json.dumps(results, indent=2, default=str))
126
+ return
127
+
128
+ # Summary
129
+ print(f"\n{'='*60}")
130
+ print(f"SESSION HEALTH CHECK")
131
+ print(f"{'='*60}")
132
+ print(f"Total sessions: {len(sessions)}")
133
+ print(f"Problematic: {len(problematic)}")
134
+
135
+ if problematic:
136
+ print(f"\n{'='*60}")
137
+ print("ISSUES FOUND:")
138
+ print(f"{'='*60}")
139
+
140
+ for stats in problematic:
141
+ print(f"\n{stats['name']}")
142
+ print(f" Size: {stats['size_kb']:.0f}KB | Messages: {stats['message_count']}")
143
+ print(f" Warmup errors: {stats['warmup_errors']}")
144
+ print(f" Sidechain: {stats['is_sidechain']}")
145
+ for issue in stats["issues"]:
146
+ print(f" -> {issue}")
147
+
148
+ if args.fix:
149
+ print(f"\n{'='*60}")
150
+ print("CLEANING UP...")
151
+ print(f"{'='*60}")
152
+ for stats in problematic:
153
+ if any("CRITICAL" in i for i in stats["issues"]):
154
+ try:
155
+ os.remove(stats["path"])
156
+ print(f"Removed: {stats['name']}")
157
+ except Exception as e:
158
+ print(f"Failed to remove {stats['name']}: {e}")
159
+ else:
160
+ print("\nAll sessions healthy!")
161
+
162
+ return len(problematic)
163
+
164
+
165
+ if __name__ == "__main__":
166
+ sys.exit(main())
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: skill-creator
3
+ description: Guide for creating effective Claude Code skills. Use when users want to create a new skill, update an existing skill, or need guidance on skill best practices. Triggers on requests like "create a skill", "make a new skill", "help me build a skill", "skill development", or "extend Claude's capabilities".
4
+ license: Apache 2.0 (based on Anthropic's skills repo)
5
+ ---
6
+
7
+ # Skill Creator
8
+
9
+ Create effective skills that extend Claude's capabilities with specialized knowledge, workflows, and tools.
10
+
11
+ ## Core Principles
12
+
13
+ ### Concise is Key
14
+ The context window is shared. Only add what Claude doesn't already know. Challenge each piece: "Does this justify its token cost?"
15
+
16
+ ### Degrees of Freedom
17
+ - **High freedom** (text instructions): Multiple valid approaches, context-dependent decisions
18
+ - **Medium freedom** (pseudocode/parameterized scripts): Preferred pattern exists, some variation OK
19
+ - **Low freedom** (specific scripts): Fragile operations, consistency critical
20
+
21
+ ## Skill Anatomy
22
+
23
+ ```
24
+ skill-name/
25
+ ├── SKILL.md (required)
26
+ │ ├── YAML frontmatter (name, description - REQUIRED)
27
+ │ └── Markdown instructions
28
+ └── Bundled Resources (optional)
29
+ ├── scripts/ - Executable code (deterministic, reusable)
30
+ ├── references/ - Documentation loaded into context as needed
31
+ └── assets/ - Files used in output (templates, images)
32
+ ```
33
+
34
+ ### Frontmatter (Critical)
35
+ ```yaml
36
+ ---
37
+ name: my-skill
38
+ description: What it does AND when to use it. This is the ONLY thing Claude sees to decide if the skill triggers. Be comprehensive.
39
+ ---
40
+ ```
41
+
42
+ ### Progressive Disclosure
43
+ 1. **Metadata** (~100 words) - Always in context
44
+ 2. **SKILL.md body** (<5k words) - When skill triggers
45
+ 3. **Bundled resources** - As needed
46
+
47
+ Keep SKILL.md under 500 lines. Split into references when approaching limit.
48
+
49
+ ## Creation Process
50
+
51
+ ### Step 1: Understand with Examples
52
+ - What functionality should this skill support?
53
+ - What would users say to trigger it?
54
+ - Can you give concrete usage examples?
55
+
56
+ ### Step 2: Plan Reusable Contents
57
+ For each example, identify:
58
+ - Scripts for repetitive code
59
+ - References for documentation/schemas
60
+ - Assets for templates/boilerplate
61
+
62
+ ### Step 3: Initialize
63
+ ```bash
64
+ python scripts/init_skill.py <skill-name> --path <output-directory>
65
+ ```
66
+
67
+ ### Step 4: Implement
68
+ 1. Create scripts/, references/, assets/ files
69
+ 2. Test scripts by actually running them
70
+ 3. Write SKILL.md with:
71
+ - Comprehensive description in frontmatter
72
+ - Instructions referencing bundled resources
73
+ - Use imperative form ("Do X", not "You should do X")
74
+
75
+ ### Step 5: Package
76
+ ```bash
77
+ python scripts/package_skill.py <path/to/skill-folder> [output-dir]
78
+ ```
79
+
80
+ ### Step 6: Iterate
81
+ Use skill on real tasks → Notice struggles → Update → Test again
82
+
83
+ ## What NOT to Include
84
+ - README.md, CHANGELOG.md, INSTALLATION_GUIDE.md
85
+ - Setup/testing procedures
86
+ - User-facing documentation
87
+ - Anything not needed by the AI agent
88
+
89
+ ## Reference Files
90
+
91
+ - See `references/workflows.md` for multi-step process patterns
92
+ - See `references/output-patterns.md` for output format patterns
@@ -0,0 +1,152 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Skill Initializer - Creates a new skill from template
4
+
5
+ Usage:
6
+ python init_skill.py <skill-name> --path <output-directory>
7
+
8
+ Example:
9
+ python init_skill.py pdf-editor --path ./skills
10
+ """
11
+
12
+ import argparse
13
+ import re
14
+ import sys
15
+ from pathlib import Path
16
+
17
+ SKILL_MD_TEMPLATE = '''---
18
+ name: {skill_name}
19
+ description: TODO - Describe what this skill does AND when to use it. Include trigger phrases.
20
+ ---
21
+
22
+ # {skill_title}
23
+
24
+ TODO: Write instructions for using this skill.
25
+
26
+ ## Overview
27
+
28
+ TODO: Brief description of what this skill does.
29
+
30
+ ## Usage
31
+
32
+ TODO: How to use this skill.
33
+
34
+ ## Resources
35
+
36
+ - `scripts/` - Executable automation scripts
37
+ - `references/` - Documentation loaded as needed
38
+ - `assets/` - Templates and files for output
39
+ '''
40
+
41
+ EXAMPLE_SCRIPT = '''#!/usr/bin/env python3
42
+ """
43
+ Example script - replace with your actual script.
44
+ """
45
+
46
+ def main():
47
+ print("Hello from {skill_name}!")
48
+
49
+ if __name__ == "__main__":
50
+ main()
51
+ '''
52
+
53
+ EXAMPLE_REFERENCE = '''# {skill_title} Reference
54
+
55
+ This is an example reference file. Replace with actual documentation.
56
+
57
+ ## Section 1
58
+
59
+ TODO: Add reference content here.
60
+ '''
61
+
62
+
63
+ def validate_skill_name(name: str) -> bool:
64
+ """Validate skill name follows conventions."""
65
+ if not re.match(r'^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$', name):
66
+ return False
67
+ if len(name) > 40:
68
+ return False
69
+ if '--' in name:
70
+ return False
71
+ return True
72
+
73
+
74
+ def to_title(skill_name: str) -> str:
75
+ """Convert skill-name to Skill Name."""
76
+ return ' '.join(word.capitalize() for word in skill_name.split('-'))
77
+
78
+
79
+ def init_skill(skill_name: str, output_path: Path) -> bool:
80
+ """Initialize a new skill directory structure."""
81
+
82
+ if not validate_skill_name(skill_name):
83
+ print(f"Error: Invalid skill name '{skill_name}'")
84
+ print(" - Use lowercase letters, digits, and hyphens only")
85
+ print(" - Must start and end with letter or digit")
86
+ print(" - Maximum 40 characters")
87
+ print(" - No consecutive hyphens")
88
+ return False
89
+
90
+ skill_dir = output_path / skill_name
91
+
92
+ if skill_dir.exists():
93
+ print(f"Error: Directory already exists: {skill_dir}")
94
+ return False
95
+
96
+ skill_title = to_title(skill_name)
97
+
98
+ # Create directories
99
+ skill_dir.mkdir(parents=True)
100
+ (skill_dir / 'scripts').mkdir()
101
+ (skill_dir / 'references').mkdir()
102
+ (skill_dir / 'assets').mkdir()
103
+
104
+ # Create SKILL.md
105
+ skill_md = skill_dir / 'SKILL.md'
106
+ skill_md.write_text(SKILL_MD_TEMPLATE.format(
107
+ skill_name=skill_name,
108
+ skill_title=skill_title
109
+ ))
110
+
111
+ # Create example script
112
+ example_script = skill_dir / 'scripts' / 'example.py'
113
+ example_script.write_text(EXAMPLE_SCRIPT.format(skill_name=skill_name))
114
+ example_script.chmod(0o755)
115
+
116
+ # Create example reference
117
+ example_ref = skill_dir / 'references' / 'example.md'
118
+ example_ref.write_text(EXAMPLE_REFERENCE.format(skill_title=skill_title))
119
+
120
+ # Create .gitkeep in assets
121
+ (skill_dir / 'assets' / '.gitkeep').touch()
122
+
123
+ print(f"Created skill: {skill_dir}")
124
+ print()
125
+ print("Next steps:")
126
+ print(f" 1. Edit {skill_dir}/SKILL.md")
127
+ print(f" 2. Add scripts to {skill_dir}/scripts/")
128
+ print(f" 3. Add references to {skill_dir}/references/")
129
+ print(f" 4. Add assets to {skill_dir}/assets/")
130
+ print(f" 5. Delete example files you don't need")
131
+
132
+ return True
133
+
134
+
135
+ def main():
136
+ parser = argparse.ArgumentParser(description='Initialize a new skill')
137
+ parser.add_argument('skill_name', help='Name of the skill (hyphen-case)')
138
+ parser.add_argument('--path', required=True, help='Output directory')
139
+
140
+ args = parser.parse_args()
141
+
142
+ output_path = Path(args.path).resolve()
143
+
144
+ if not output_path.exists():
145
+ output_path.mkdir(parents=True)
146
+
147
+ success = init_skill(args.skill_name, output_path)
148
+ sys.exit(0 if success else 1)
149
+
150
+
151
+ if __name__ == "__main__":
152
+ main()
@@ -0,0 +1,123 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Skill Packager - Creates a distributable .skill file
4
+
5
+ Usage:
6
+ python package_skill.py <path/to/skill-folder> [output-directory]
7
+
8
+ Example:
9
+ python package_skill.py ./my-skill
10
+ python package_skill.py ./my-skill ./dist
11
+ """
12
+
13
+ import sys
14
+ import zipfile
15
+ import re
16
+ from pathlib import Path
17
+
18
+
19
+ def validate_skill(skill_path: Path) -> tuple[bool, str]:
20
+ """Validate skill structure and contents."""
21
+
22
+ skill_md = skill_path / "SKILL.md"
23
+ if not skill_md.exists():
24
+ return False, "SKILL.md not found"
25
+
26
+ content = skill_md.read_text()
27
+
28
+ # Check frontmatter
29
+ if not content.startswith('---'):
30
+ return False, "SKILL.md must start with YAML frontmatter (---)"
31
+
32
+ # Extract frontmatter
33
+ parts = content.split('---', 2)
34
+ if len(parts) < 3:
35
+ return False, "Invalid frontmatter format"
36
+
37
+ frontmatter = parts[1]
38
+
39
+ # Check required fields
40
+ if 'name:' not in frontmatter:
41
+ return False, "Frontmatter missing 'name' field"
42
+ if 'description:' not in frontmatter:
43
+ return False, "Frontmatter missing 'description' field"
44
+
45
+ # Check description isn't a TODO
46
+ if 'TODO' in frontmatter:
47
+ return False, "Frontmatter contains TODO - please complete the description"
48
+
49
+ # Check for body content
50
+ body = parts[2].strip()
51
+ if len(body) < 50:
52
+ return False, "SKILL.md body is too short"
53
+
54
+ return True, "Skill is valid"
55
+
56
+
57
+ def package_skill(skill_path: Path, output_dir: Path = None) -> Path:
58
+ """Package a skill folder into a .skill file."""
59
+
60
+ if not skill_path.exists():
61
+ print(f"Error: Skill folder not found: {skill_path}")
62
+ return None
63
+
64
+ if not skill_path.is_dir():
65
+ print(f"Error: Path is not a directory: {skill_path}")
66
+ return None
67
+
68
+ # Validate
69
+ print("Validating skill...")
70
+ valid, message = validate_skill(skill_path)
71
+ if not valid:
72
+ print(f"Validation failed: {message}")
73
+ return None
74
+ print(f" {message}")
75
+
76
+ # Determine output
77
+ skill_name = skill_path.name
78
+ if output_dir:
79
+ output_dir = Path(output_dir).resolve()
80
+ output_dir.mkdir(parents=True, exist_ok=True)
81
+ else:
82
+ output_dir = Path.cwd()
83
+
84
+ skill_filename = output_dir / f"{skill_name}.skill"
85
+
86
+ # Create zip
87
+ try:
88
+ with zipfile.ZipFile(skill_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
89
+ for file_path in skill_path.rglob('*'):
90
+ if file_path.is_file():
91
+ # Skip common exclusions
92
+ if file_path.name.startswith('.') and file_path.name != '.gitkeep':
93
+ continue
94
+ if '__pycache__' in str(file_path):
95
+ continue
96
+
97
+ arcname = file_path.relative_to(skill_path.parent)
98
+ zipf.write(file_path, arcname)
99
+ print(f" Added: {arcname}")
100
+
101
+ print(f"\nPackaged skill to: {skill_filename}")
102
+ return skill_filename
103
+
104
+ except Exception as e:
105
+ print(f"Error creating .skill file: {e}")
106
+ return None
107
+
108
+
109
+ def main():
110
+ if len(sys.argv) < 2:
111
+ print("Usage: python package_skill.py <path/to/skill-folder> [output-directory]")
112
+ sys.exit(1)
113
+
114
+ skill_path = Path(sys.argv[1]).resolve()
115
+ output_dir = Path(sys.argv[2]).resolve() if len(sys.argv) > 2 else None
116
+
117
+ print(f"Packaging skill: {skill_path}")
118
+ result = package_skill(skill_path, output_dir)
119
+ sys.exit(0 if result else 1)
120
+
121
+
122
+ if __name__ == "__main__":
123
+ main()
@@ -0,0 +1,34 @@
1
+ # Stitch Design System Documentation Skill
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npx add-skill google-labs-code/stitch-skills --skill design-md --global
7
+ ```
8
+
9
+ ## Example Prompt
10
+
11
+ ```text
12
+ Analyze my Furniture Collection project's Home screen and generate a comprehensive DESIGN.md file documenting the design system.
13
+ ```
14
+
15
+ ## Skill Structure
16
+
17
+ This repository follows the **Agent Skills** open standard. Each skill is self-contained with its own logic, workflow, and reference materials.
18
+
19
+ ```text
20
+ design-md/
21
+ ├── SKILL.md — Core instructions & workflow
22
+ ├── examples/ — Sample DESIGN.md outputs
23
+ └── README.md — This file
24
+ ```
25
+
26
+ ## How it Works
27
+
28
+ When activated, the agent follows a structured design analysis pipeline:
29
+
30
+ 1. **Retrieval**: Uses the Stitch MCP Server to fetch project screens, HTML code, and design metadata.
31
+ 2. **Extraction**: Identifies design tokens including colors, typography, spacing, and component patterns.
32
+ 3. **Translation**: Converts technical CSS/Tailwind values into descriptive, natural design language.
33
+ 4. **Synthesis**: Generates a comprehensive DESIGN.md following the semantic design system format.
34
+ 5. **Alignment**: Ensures output follows Stitch Effective Prompting Guide principles for optimal screen generation.