@opendirectory.dev/skills 0.1.44 → 0.1.45
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/package.json +1 -1
- package/registry.json +8 -0
- package/skills/oss-launch-kit/.env.example +2 -0
- package/skills/oss-launch-kit/PRD.md +122 -0
- package/skills/oss-launch-kit/README.md +27 -0
- package/skills/oss-launch-kit/SKILL.md +33 -0
- package/skills/oss-launch-kit/TECHNICAL_DESIGN.md +187 -0
- package/skills/oss-launch-kit/evals/cli-cli.full.md +49 -0
- package/skills/oss-launch-kit/evals/evals.json +44 -0
- package/skills/oss-launch-kit/evals/octocat-hello-world.full.md +53 -0
- package/skills/oss-launch-kit/evals/pydantic-pydantic.full.md +152 -0
- package/skills/oss-launch-kit/evals/vercel-next-js.full.md +152 -0
- package/skills/oss-launch-kit/hero.png +0 -0
- package/skills/oss-launch-kit/references/channel_rules.md +9 -0
- package/skills/oss-launch-kit/references/launch_framework.md +10 -0
- package/skills/oss-launch-kit/references/output_template.md +3 -0
- package/skills/oss-launch-kit/scripts/__pycache__/build_product_brief.cpython-313.pyc +0 -0
- package/skills/oss-launch-kit/scripts/__pycache__/generate_assets.cpython-313.pyc +0 -0
- package/skills/oss-launch-kit/scripts/build_product_brief.py +335 -0
- package/skills/oss-launch-kit/scripts/fetch_repo_context.py +169 -0
- package/skills/oss-launch-kit/scripts/generate_assets.py +526 -0
- package/skills/oss-launch-kit/scripts/run.py +41 -0
- package/skills/oss-launch-kit/scripts/test_logic.py +99 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""CLI entrypoint for oss-launch-kit.
|
|
2
|
+
|
|
3
|
+
This orchestrates GitHub repo fetching, brief building, and full launch-kit generation.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from build_product_brief import build_product_brief
|
|
12
|
+
from fetch_repo_context import fetch_repo_context
|
|
13
|
+
from generate_assets import render_full_launch_kit_markdown
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
17
|
+
parser = argparse.ArgumentParser(description="Generate a coordinated OSS launch strategy and readiness report from a GitHub repo.")
|
|
18
|
+
parser.add_argument("--repo-url", required=True, help="Public GitHub repository URL")
|
|
19
|
+
parser.add_argument("--output", default="launch-kit.md", help="Output Markdown file path")
|
|
20
|
+
return parser
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def run(repo_url: str) -> tuple[dict, dict, str]:
|
|
24
|
+
repo_context = fetch_repo_context(repo_url)
|
|
25
|
+
brief = build_product_brief(repo_context)
|
|
26
|
+
markdown = render_full_launch_kit_markdown(brief)
|
|
27
|
+
return repo_context, brief, markdown
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def main() -> None:
|
|
31
|
+
parser = build_parser()
|
|
32
|
+
args = parser.parse_args()
|
|
33
|
+
|
|
34
|
+
_, _, markdown = run(args.repo_url)
|
|
35
|
+
output_path = Path(args.output)
|
|
36
|
+
output_path.write_text(markdown, encoding="utf-8")
|
|
37
|
+
print(f"Wrote {output_path}")
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
main()
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import unittest
|
|
2
|
+
import sys
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
# Add the scripts directory to sys.path
|
|
6
|
+
sys.path.append(str(Path(__file__).parent))
|
|
7
|
+
|
|
8
|
+
from build_product_brief import build_product_brief
|
|
9
|
+
from generate_assets import render_full_launch_kit_markdown
|
|
10
|
+
|
|
11
|
+
class TestOSSLaunchKitLogic(unittest.TestCase):
|
|
12
|
+
def test_low_readiness_handling(self):
|
|
13
|
+
# Mock repo context for a very weak repo
|
|
14
|
+
low_context = {
|
|
15
|
+
"name": "octocat/Hello-World",
|
|
16
|
+
"description": "My first repository on GitHub!",
|
|
17
|
+
"stars": 2,
|
|
18
|
+
"readme_text": "Hello World!",
|
|
19
|
+
"language": "HTML",
|
|
20
|
+
"license": None,
|
|
21
|
+
"confidence": "low"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
brief = build_product_brief(low_context)
|
|
25
|
+
self.assertEqual(brief["launch_readiness"]["score"], "low")
|
|
26
|
+
self.assertTrue(len(brief["launch_readiness"]["fix_plan"]) > 0)
|
|
27
|
+
|
|
28
|
+
markdown = render_full_launch_kit_markdown(brief)
|
|
29
|
+
|
|
30
|
+
# Assertions for low readiness output
|
|
31
|
+
self.assertIn("Project Maturity**: LOW", markdown)
|
|
32
|
+
self.assertIn("> [!CAUTION]", markdown)
|
|
33
|
+
self.assertIn("This project is not launch-ready yet", markdown)
|
|
34
|
+
self.assertIn("## Launch Readiness Fix Plan", markdown)
|
|
35
|
+
|
|
36
|
+
# High friction sections and full checklist should be absent
|
|
37
|
+
self.assertNotIn("### [Show HN]", markdown)
|
|
38
|
+
self.assertNotIn("### [Product Hunt]", markdown)
|
|
39
|
+
self.assertNotIn("## Coordinated Launch Timeline", markdown)
|
|
40
|
+
self.assertNotIn("## Channel Strategy & Positioning", markdown)
|
|
41
|
+
|
|
42
|
+
def test_medium_readiness_handling(self):
|
|
43
|
+
# Mock repo context for a medium tool
|
|
44
|
+
medium_context = {
|
|
45
|
+
"full_name": "user/medium-tool",
|
|
46
|
+
"description": "A tool that does something useful",
|
|
47
|
+
"stars": 25,
|
|
48
|
+
"readme_text": "# Medium Tool\n\n## install\nnpm install medium-tool\n\n## usage\nmedium-tool --help\n\n## license\nMIT\n\n" + "Word " * 200, # > 1000 chars
|
|
49
|
+
"language": "JavaScript",
|
|
50
|
+
"license": "MIT",
|
|
51
|
+
"confidence": "medium"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
brief = build_product_brief(medium_context)
|
|
55
|
+
self.assertEqual(brief["launch_readiness"]["score"], "medium")
|
|
56
|
+
|
|
57
|
+
markdown = render_full_launch_kit_markdown(brief)
|
|
58
|
+
|
|
59
|
+
# Assertions for medium readiness output
|
|
60
|
+
self.assertIn("Project Maturity**: MEDIUM", markdown)
|
|
61
|
+
self.assertIn("## Soft Launch Strategy", markdown)
|
|
62
|
+
self.assertIn("## Launch Readiness Fix Plan", markdown)
|
|
63
|
+
self.assertIn("## Coordinated Launch Timeline", markdown)
|
|
64
|
+
self.assertIn("Step 1: Soft Launch", markdown)
|
|
65
|
+
self.assertIn("## Suggested Skills (Post-Fix)", markdown)
|
|
66
|
+
|
|
67
|
+
# Should still have handoffs but in the Post-Fix section
|
|
68
|
+
self.assertIn("use `producthunt-launch-kit`", markdown)
|
|
69
|
+
|
|
70
|
+
def test_high_readiness_handling(self):
|
|
71
|
+
# Mock repo context for a strong tool
|
|
72
|
+
high_context = {
|
|
73
|
+
"full_name": "cli/cli",
|
|
74
|
+
"description": "GitHub’s official command line tool helps developers solve github workflow issues",
|
|
75
|
+
"stars": 35000,
|
|
76
|
+
"readme_text": "# GitHub CLI\n\n## Quickstart\nbrew install gh\n\n## Usage\ngh issue list\n\n## License\nMIT\n\n## Contributing\nSee CONTRIBUTING.md\n\n## Demo\nVisit https://cli.github.com for a demo.\n\n" + "Long description about why this tool is amazing. " * 50,
|
|
77
|
+
"language": "Go",
|
|
78
|
+
"license": "MIT",
|
|
79
|
+
"confidence": "high"
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
brief = build_product_brief(high_context)
|
|
83
|
+
self.assertEqual(brief["launch_readiness"]["score"], "high")
|
|
84
|
+
|
|
85
|
+
markdown = render_full_launch_kit_markdown(brief)
|
|
86
|
+
|
|
87
|
+
# Assertions for high readiness output
|
|
88
|
+
self.assertIn("Project Maturity**: HIGH", markdown)
|
|
89
|
+
self.assertIn("## Coordinated Launch Timeline", markdown)
|
|
90
|
+
self.assertIn("- [ ] Day 1: Show HN", markdown)
|
|
91
|
+
self.assertIn("## Channel Strategy & Positioning", markdown)
|
|
92
|
+
self.assertIn("### [Show HN] - Fit: HIGH", markdown)
|
|
93
|
+
# cli/cli is a tool so PH is low, which is fine
|
|
94
|
+
self.assertIn("### [Twitter/X]", markdown)
|
|
95
|
+
self.assertNotIn("> [!CAUTION]", markdown)
|
|
96
|
+
self.assertNotIn("## Soft Launch Strategy", markdown)
|
|
97
|
+
|
|
98
|
+
if __name__ == "__main__":
|
|
99
|
+
unittest.main()
|