skill-seekers 2.7.3__py3-none-any.whl

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 (79) hide show
  1. skill_seekers/__init__.py +22 -0
  2. skill_seekers/cli/__init__.py +39 -0
  3. skill_seekers/cli/adaptors/__init__.py +120 -0
  4. skill_seekers/cli/adaptors/base.py +221 -0
  5. skill_seekers/cli/adaptors/claude.py +485 -0
  6. skill_seekers/cli/adaptors/gemini.py +453 -0
  7. skill_seekers/cli/adaptors/markdown.py +269 -0
  8. skill_seekers/cli/adaptors/openai.py +503 -0
  9. skill_seekers/cli/ai_enhancer.py +310 -0
  10. skill_seekers/cli/api_reference_builder.py +373 -0
  11. skill_seekers/cli/architectural_pattern_detector.py +525 -0
  12. skill_seekers/cli/code_analyzer.py +1462 -0
  13. skill_seekers/cli/codebase_scraper.py +1225 -0
  14. skill_seekers/cli/config_command.py +563 -0
  15. skill_seekers/cli/config_enhancer.py +431 -0
  16. skill_seekers/cli/config_extractor.py +871 -0
  17. skill_seekers/cli/config_manager.py +452 -0
  18. skill_seekers/cli/config_validator.py +394 -0
  19. skill_seekers/cli/conflict_detector.py +528 -0
  20. skill_seekers/cli/constants.py +72 -0
  21. skill_seekers/cli/dependency_analyzer.py +757 -0
  22. skill_seekers/cli/doc_scraper.py +2332 -0
  23. skill_seekers/cli/enhance_skill.py +488 -0
  24. skill_seekers/cli/enhance_skill_local.py +1096 -0
  25. skill_seekers/cli/enhance_status.py +194 -0
  26. skill_seekers/cli/estimate_pages.py +433 -0
  27. skill_seekers/cli/generate_router.py +1209 -0
  28. skill_seekers/cli/github_fetcher.py +534 -0
  29. skill_seekers/cli/github_scraper.py +1466 -0
  30. skill_seekers/cli/guide_enhancer.py +723 -0
  31. skill_seekers/cli/how_to_guide_builder.py +1267 -0
  32. skill_seekers/cli/install_agent.py +461 -0
  33. skill_seekers/cli/install_skill.py +178 -0
  34. skill_seekers/cli/language_detector.py +614 -0
  35. skill_seekers/cli/llms_txt_detector.py +60 -0
  36. skill_seekers/cli/llms_txt_downloader.py +104 -0
  37. skill_seekers/cli/llms_txt_parser.py +150 -0
  38. skill_seekers/cli/main.py +558 -0
  39. skill_seekers/cli/markdown_cleaner.py +132 -0
  40. skill_seekers/cli/merge_sources.py +806 -0
  41. skill_seekers/cli/package_multi.py +77 -0
  42. skill_seekers/cli/package_skill.py +241 -0
  43. skill_seekers/cli/pattern_recognizer.py +1825 -0
  44. skill_seekers/cli/pdf_extractor_poc.py +1166 -0
  45. skill_seekers/cli/pdf_scraper.py +617 -0
  46. skill_seekers/cli/quality_checker.py +519 -0
  47. skill_seekers/cli/rate_limit_handler.py +438 -0
  48. skill_seekers/cli/resume_command.py +160 -0
  49. skill_seekers/cli/run_tests.py +230 -0
  50. skill_seekers/cli/setup_wizard.py +93 -0
  51. skill_seekers/cli/split_config.py +390 -0
  52. skill_seekers/cli/swift_patterns.py +560 -0
  53. skill_seekers/cli/test_example_extractor.py +1081 -0
  54. skill_seekers/cli/test_unified_simple.py +179 -0
  55. skill_seekers/cli/unified_codebase_analyzer.py +572 -0
  56. skill_seekers/cli/unified_scraper.py +932 -0
  57. skill_seekers/cli/unified_skill_builder.py +1605 -0
  58. skill_seekers/cli/upload_skill.py +162 -0
  59. skill_seekers/cli/utils.py +432 -0
  60. skill_seekers/mcp/__init__.py +33 -0
  61. skill_seekers/mcp/agent_detector.py +316 -0
  62. skill_seekers/mcp/git_repo.py +273 -0
  63. skill_seekers/mcp/server.py +231 -0
  64. skill_seekers/mcp/server_fastmcp.py +1249 -0
  65. skill_seekers/mcp/server_legacy.py +2302 -0
  66. skill_seekers/mcp/source_manager.py +285 -0
  67. skill_seekers/mcp/tools/__init__.py +115 -0
  68. skill_seekers/mcp/tools/config_tools.py +251 -0
  69. skill_seekers/mcp/tools/packaging_tools.py +826 -0
  70. skill_seekers/mcp/tools/scraping_tools.py +842 -0
  71. skill_seekers/mcp/tools/source_tools.py +828 -0
  72. skill_seekers/mcp/tools/splitting_tools.py +212 -0
  73. skill_seekers/py.typed +0 -0
  74. skill_seekers-2.7.3.dist-info/METADATA +2027 -0
  75. skill_seekers-2.7.3.dist-info/RECORD +79 -0
  76. skill_seekers-2.7.3.dist-info/WHEEL +5 -0
  77. skill_seekers-2.7.3.dist-info/entry_points.txt +19 -0
  78. skill_seekers-2.7.3.dist-info/licenses/LICENSE +21 -0
  79. skill_seekers-2.7.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,230 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Test Runner for Skill Seeker
4
+ Runs all test suites and generates a comprehensive test report
5
+ """
6
+
7
+ import sys
8
+ import unittest
9
+
10
+
11
+ class ColoredTextTestResult(unittest.TextTestResult):
12
+ """Custom test result class with colored output"""
13
+
14
+ # ANSI color codes
15
+ GREEN = "\033[92m"
16
+ RED = "\033[91m"
17
+ YELLOW = "\033[93m"
18
+ BLUE = "\033[94m"
19
+ RESET = "\033[0m"
20
+ BOLD = "\033[1m"
21
+
22
+ def __init__(self, *args, **kwargs):
23
+ super().__init__(*args, **kwargs)
24
+ self.test_results = []
25
+
26
+ def addSuccess(self, test):
27
+ super().addSuccess(test)
28
+ self.test_results.append(("PASS", test))
29
+ if self.showAll:
30
+ self.stream.write(f"{self.GREEN}✓ PASS{self.RESET}\n")
31
+ elif self.dots:
32
+ self.stream.write(f"{self.GREEN}.{self.RESET}")
33
+ self.stream.flush()
34
+
35
+ def addError(self, test, err):
36
+ super().addError(test, err)
37
+ self.test_results.append(("ERROR", test))
38
+ if self.showAll:
39
+ self.stream.write(f"{self.RED}✗ ERROR{self.RESET}\n")
40
+ elif self.dots:
41
+ self.stream.write(f"{self.RED}E{self.RESET}")
42
+ self.stream.flush()
43
+
44
+ def addFailure(self, test, err):
45
+ super().addFailure(test, err)
46
+ self.test_results.append(("FAIL", test))
47
+ if self.showAll:
48
+ self.stream.write(f"{self.RED}✗ FAIL{self.RESET}\n")
49
+ elif self.dots:
50
+ self.stream.write(f"{self.RED}F{self.RESET}")
51
+ self.stream.flush()
52
+
53
+ def addSkip(self, test, reason):
54
+ super().addSkip(test, reason)
55
+ self.test_results.append(("SKIP", test))
56
+ if self.showAll:
57
+ self.stream.write(f"{self.YELLOW}⊘ SKIP{self.RESET}\n")
58
+ elif self.dots:
59
+ self.stream.write(f"{self.YELLOW}s{self.RESET}")
60
+ self.stream.flush()
61
+
62
+
63
+ class ColoredTextTestRunner(unittest.TextTestRunner):
64
+ """Custom test runner with colored output"""
65
+
66
+ resultclass = ColoredTextTestResult
67
+
68
+
69
+ def discover_tests(test_dir="tests"):
70
+ """Discover all test files in the tests directory"""
71
+ loader = unittest.TestLoader()
72
+ start_dir = test_dir
73
+ pattern = "test_*.py"
74
+
75
+ suite = loader.discover(start_dir, pattern=pattern)
76
+ return suite
77
+
78
+
79
+ def run_specific_suite(suite_name):
80
+ """Run a specific test suite"""
81
+ loader = unittest.TestLoader()
82
+
83
+ suite_map = {
84
+ "config": "tests.test_config_validation",
85
+ "features": "tests.test_scraper_features",
86
+ "integration": "tests.test_integration",
87
+ }
88
+
89
+ if suite_name not in suite_map:
90
+ print(f"Unknown test suite: {suite_name}")
91
+ print(f"Available suites: {', '.join(suite_map.keys())}")
92
+ return None
93
+
94
+ module_name = suite_map[suite_name]
95
+ try:
96
+ suite = loader.loadTestsFromName(module_name)
97
+ return suite
98
+ except Exception as e:
99
+ print(f"Error loading test suite '{suite_name}': {e}")
100
+ return None
101
+
102
+
103
+ def print_summary(result):
104
+ """Print a detailed test summary"""
105
+ total = result.testsRun
106
+ passed = total - len(result.failures) - len(result.errors) - len(result.skipped)
107
+ failed = len(result.failures)
108
+ errors = len(result.errors)
109
+ skipped = len(result.skipped)
110
+
111
+ print("\n" + "=" * 70)
112
+ print("TEST SUMMARY")
113
+ print("=" * 70)
114
+
115
+ # Overall stats
116
+ print(f"\n{ColoredTextTestResult.BOLD}Total Tests:{ColoredTextTestResult.RESET} {total}")
117
+ print(f"{ColoredTextTestResult.GREEN}✓ Passed:{ColoredTextTestResult.RESET} {passed}")
118
+ if failed > 0:
119
+ print(f"{ColoredTextTestResult.RED}✗ Failed:{ColoredTextTestResult.RESET} {failed}")
120
+ if errors > 0:
121
+ print(f"{ColoredTextTestResult.RED}✗ Errors:{ColoredTextTestResult.RESET} {errors}")
122
+ if skipped > 0:
123
+ print(f"{ColoredTextTestResult.YELLOW}⊘ Skipped:{ColoredTextTestResult.RESET} {skipped}")
124
+
125
+ # Success rate
126
+ if total > 0:
127
+ success_rate = (passed / total) * 100
128
+ color = (
129
+ ColoredTextTestResult.GREEN
130
+ if success_rate == 100
131
+ else ColoredTextTestResult.YELLOW
132
+ if success_rate >= 80
133
+ else ColoredTextTestResult.RED
134
+ )
135
+ print(f"\n{color}Success Rate: {success_rate:.1f}%{ColoredTextTestResult.RESET}")
136
+
137
+ # Category breakdown
138
+ if hasattr(result, "test_results"):
139
+ print(
140
+ f"\n{ColoredTextTestResult.BOLD}Test Breakdown by Category:{ColoredTextTestResult.RESET}"
141
+ )
142
+
143
+ categories = {}
144
+ for status, test in result.test_results:
145
+ test_name = str(test)
146
+ # Extract test class name
147
+ if "." in test_name:
148
+ class_name = test_name.split(".")[0].split()[-1]
149
+ if class_name not in categories:
150
+ categories[class_name] = {"PASS": 0, "FAIL": 0, "ERROR": 0, "SKIP": 0}
151
+ categories[class_name][status] += 1
152
+
153
+ for category, stats in sorted(categories.items()):
154
+ total_cat = sum(stats.values())
155
+ passed_cat = stats["PASS"]
156
+ print(f" {category}: {passed_cat}/{total_cat} passed")
157
+
158
+ print("\n" + "=" * 70)
159
+
160
+ # Return status
161
+ return failed == 0 and errors == 0
162
+
163
+
164
+ def main():
165
+ """Main test runner"""
166
+ import argparse
167
+
168
+ parser = argparse.ArgumentParser(
169
+ description="Run tests for Skill Seeker",
170
+ formatter_class=argparse.RawDescriptionHelpFormatter,
171
+ )
172
+
173
+ parser.add_argument(
174
+ "--suite", "-s", type=str, help="Run specific test suite (config, features, integration)"
175
+ )
176
+ parser.add_argument(
177
+ "--verbose", "-v", action="store_true", help="Verbose output (show each test)"
178
+ )
179
+ parser.add_argument("--quiet", "-q", action="store_true", help="Quiet output (minimal output)")
180
+ parser.add_argument("--failfast", "-f", action="store_true", help="Stop on first failure")
181
+ parser.add_argument("--list", "-l", action="store_true", help="List all available tests")
182
+
183
+ args = parser.parse_args()
184
+
185
+ # Set verbosity
186
+ verbosity = 1
187
+ if args.verbose:
188
+ verbosity = 2
189
+ elif args.quiet:
190
+ verbosity = 0
191
+
192
+ print(f"\n{ColoredTextTestResult.BOLD}{'=' * 70}{ColoredTextTestResult.RESET}")
193
+ print(f"{ColoredTextTestResult.BOLD}SKILL SEEKER TEST SUITE{ColoredTextTestResult.RESET}")
194
+ print(f"{ColoredTextTestResult.BOLD}{'=' * 70}{ColoredTextTestResult.RESET}\n")
195
+
196
+ # Discover or load specific suite
197
+ if args.suite:
198
+ print(
199
+ f"Running test suite: {ColoredTextTestResult.BLUE}{args.suite}{ColoredTextTestResult.RESET}\n"
200
+ )
201
+ suite = run_specific_suite(args.suite)
202
+ if suite is None:
203
+ return 1
204
+ else:
205
+ print(f"Running {ColoredTextTestResult.BLUE}all tests{ColoredTextTestResult.RESET}\n")
206
+ suite = discover_tests()
207
+
208
+ # List tests
209
+ if args.list:
210
+ print("\nAvailable tests:\n")
211
+ for test_group in suite:
212
+ for test in test_group:
213
+ print(f" - {test}")
214
+ print()
215
+ return 0
216
+
217
+ # Run tests
218
+ runner = ColoredTextTestRunner(verbosity=verbosity, failfast=args.failfast)
219
+
220
+ result = runner.run(suite)
221
+
222
+ # Print summary
223
+ success = print_summary(result)
224
+
225
+ # Return appropriate exit code
226
+ return 0 if success else 1
227
+
228
+
229
+ if __name__ == "__main__":
230
+ sys.exit(main())
@@ -0,0 +1,93 @@
1
+ """
2
+ Interactive Setup Wizard for Skill Seekers
3
+
4
+ Guides users through installation options on first run.
5
+ """
6
+
7
+ from pathlib import Path
8
+
9
+
10
+ def show_installation_guide():
11
+ """Show installation options"""
12
+ print("""
13
+ ╔═══════════════════════════════════════════════════════════╗
14
+ ║ ║
15
+ ║ Skill Seekers Setup Guide ║
16
+ ║ ║
17
+ ╚═══════════════════════════════════════════════════════════╝
18
+
19
+ Choose your installation profile:
20
+
21
+ 1️⃣ CLI Only (Skill Generation)
22
+ pip install skill-seekers
23
+
24
+ Features:
25
+ • Scrape documentation websites
26
+ • Analyze GitHub repositories
27
+ • Extract from PDFs
28
+ • Package skills for all platforms
29
+
30
+ 2️⃣ MCP Integration (Claude Code, Cursor, Windsurf)
31
+ pip install skill-seekers[mcp]
32
+
33
+ Features:
34
+ • Everything from CLI Only
35
+ • MCP server for Claude Code
36
+ • One-command skill installation
37
+ • HTTP/stdio transport modes
38
+
39
+ 3️⃣ Multi-LLM Support (Gemini, OpenAI)
40
+ pip install skill-seekers[all-llms]
41
+
42
+ Features:
43
+ • Everything from CLI Only
44
+ • Google Gemini support
45
+ • OpenAI ChatGPT support
46
+ • Enhanced AI features
47
+
48
+ 4️⃣ Everything
49
+ pip install skill-seekers[all]
50
+
51
+ Features:
52
+ • All features enabled
53
+ • Maximum flexibility
54
+
55
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
56
+
57
+ Current installation: pip install skill-seekers
58
+ Upgrade with: pip install -U skill-seekers[mcp]
59
+
60
+ For configuration wizard:
61
+ skill-seekers config
62
+
63
+ For help:
64
+ skill-seekers --help
65
+
66
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
67
+ """)
68
+
69
+
70
+ def check_first_run():
71
+ """Check if this is first run"""
72
+ flag_file = Path.home() / ".config" / "skill-seekers" / ".setup_shown"
73
+
74
+ if not flag_file.exists():
75
+ show_installation_guide()
76
+
77
+ # Create flag to not show again
78
+ flag_file.parent.mkdir(parents=True, exist_ok=True)
79
+ flag_file.touch()
80
+
81
+ input("\nPress Enter to continue...")
82
+ return True
83
+
84
+ return False
85
+
86
+
87
+ def main():
88
+ """Show wizard"""
89
+ show_installation_guide()
90
+
91
+
92
+ if __name__ == "__main__":
93
+ main()