Showing preview only (9,581K chars total). Download the full file or copy to clipboard to get everything.
Repository: yusufkaraaslan/Skill_Seekers
Branch: development
Commit: 4f87de6b5657
Files: 722
Total size: 9.0 MB
Directory structure:
gitextract_c81kulg7/
├── .claude/
│ └── mcp_config.example.json
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── documentation.md
│ │ ├── feature_request.md
│ │ └── mcp_tool.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── create_issues.sh
│ └── workflows/
│ ├── docker-publish.yml
│ ├── quality-metrics.yml
│ ├── release.yml
│ ├── scheduled-updates.yml
│ ├── test-vector-dbs.yml
│ ├── tests.yml
│ └── vector-db-export.yml
├── .gitignore
├── .gitmodules
├── =0.24.0
├── AGENTS.md
├── BULLETPROOF_QUICKSTART.md
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.mcp
├── LICENSE
├── README.ar.md
├── README.de.md
├── README.es.md
├── README.fr.md
├── README.hi.md
├── README.ja.md
├── README.ko.md
├── README.md
├── README.pt-BR.md
├── README.ru.md
├── README.tr.md
├── README.zh-CN.md
├── ROADMAP.md
├── TESTING_GAP_REPORT.md
├── TROUBLESHOOTING.md
├── api/
│ ├── .gitignore
│ ├── README.md
│ ├── __init__.py
│ ├── config_analyzer.py
│ ├── main.py
│ └── requirements.txt
├── configs/
│ ├── astrovalley_unified.json
│ ├── blender-unified.json
│ ├── claude-code.json
│ ├── godot.json
│ ├── godot_unified.json
│ ├── httpx_comprehensive.json
│ ├── medusa-mercurjs.json
│ └── react.json
├── demo_conflicts.py
├── distribution/
│ ├── claude-plugin/
│ │ ├── .claude-plugin/
│ │ │ └── plugin.json
│ │ ├── .mcp.json
│ │ ├── README.md
│ │ ├── commands/
│ │ │ ├── create-skill.md
│ │ │ ├── install-skill.md
│ │ │ └── sync-config.md
│ │ └── skills/
│ │ └── skill-builder/
│ │ └── SKILL.md
│ ├── github-action/
│ │ ├── README.md
│ │ └── action.yml
│ └── smithery/
│ └── README.md
├── docker-compose.yml
├── docs/
│ ├── ARCHITECTURE.md
│ ├── BEST_PRACTICES.md
│ ├── DOCKER_DEPLOYMENT.md
│ ├── DOCKER_GUIDE.md
│ ├── DOCUMENTATION_UPDATES_SUMMARY.md
│ ├── FAQ.md
│ ├── KUBERNETES_DEPLOYMENT.md
│ ├── KUBERNETES_GUIDE.md
│ ├── PRODUCTION_DEPLOYMENT.md
│ ├── README.md
│ ├── TROUBLESHOOTING.md
│ ├── VIDEO_GUIDE.md
│ ├── advanced/
│ │ ├── custom-workflows.md
│ │ ├── mcp-server.md
│ │ └── multi-source.md
│ ├── agents/
│ │ ├── plans/
│ │ │ └── 2026-03-14-epub-input-support.md
│ │ └── research/
│ │ └── 2026-03-14-epub-input-support-affected-files.md
│ ├── architecture/
│ │ └── UNIFIED_PARSERS.md
│ ├── archive/
│ │ ├── historical/
│ │ │ ├── ARCHITECTURE_VERIFICATION_REPORT.md
│ │ │ ├── HTTPX_SKILL_GRADING.md
│ │ │ ├── IMPLEMENTATION_SUMMARY_THREE_STREAM.md
│ │ │ ├── LOCAL_REPO_TEST_RESULTS.md
│ │ │ ├── SKILL_QUALITY_FIX_PLAN.md
│ │ │ ├── TEST_MCP_IN_CLAUDE_CODE.md
│ │ │ ├── THREE_STREAM_COMPLETION_SUMMARY.md
│ │ │ └── THREE_STREAM_STATUS_REPORT.md
│ │ ├── legacy/
│ │ │ ├── QUICKSTART.md
│ │ │ ├── QUICK_REFERENCE.md
│ │ │ ├── README.md
│ │ │ └── USAGE.md
│ │ ├── plans/
│ │ │ ├── 2025-10-24-active-skills-design.md
│ │ │ └── 2025-10-24-active-skills-phase1.md
│ │ └── research/
│ │ ├── PDF_EXTRACTOR_POC.md
│ │ ├── PDF_IMAGE_EXTRACTION.md
│ │ ├── PDF_PARSING_RESEARCH.md
│ │ └── PDF_SYNTAX_DETECTION.md
│ ├── blog/
│ │ └── UNIVERSAL_RAG_PREPROCESSOR.md
│ ├── case-studies/
│ │ └── deepwiki-open.md
│ ├── features/
│ │ ├── BOOTSTRAP_SKILL.md
│ │ ├── BOOTSTRAP_SKILL_TECHNICAL.md
│ │ ├── ENHANCEMENT.md
│ │ ├── ENHANCEMENT_MODES.md
│ │ ├── HOW_TO_GUIDES.md
│ │ ├── PATTERN_DETECTION.md
│ │ ├── PDF_ADVANCED_FEATURES.md
│ │ ├── PDF_CHUNKING.md
│ │ ├── PDF_MCP_TOOL.md
│ │ ├── PDF_SCRAPER.md
│ │ ├── TEST_EXAMPLE_EXTRACTION.md
│ │ └── UNIFIED_SCRAPING.md
│ ├── getting-started/
│ │ ├── 01-installation.md
│ │ ├── 02-quick-start.md
│ │ ├── 03-your-first-skill.md
│ │ └── 04-next-steps.md
│ ├── guides/
│ │ ├── HTTP_TRANSPORT.md
│ │ ├── MCP_SETUP.md
│ │ ├── MIGRATION_GUIDE.md
│ │ ├── MULTI_AGENT_SETUP.md
│ │ ├── SETUP_QUICK_REFERENCE.md
│ │ ├── TESTING_GUIDE.md
│ │ └── UPLOAD_GUIDE.md
│ ├── integrations/
│ │ ├── CHROMA.md
│ │ ├── CLINE.md
│ │ ├── CONTINUE_DEV.md
│ │ ├── CURSOR.md
│ │ ├── FAISS.md
│ │ ├── GEMINI_INTEGRATION.md
│ │ ├── HAYSTACK.md
│ │ ├── INTEGRATIONS.md
│ │ ├── LANGCHAIN.md
│ │ ├── LLAMA_INDEX.md
│ │ ├── MINIMAX_INTEGRATION.md
│ │ ├── MULTI_LLM_SUPPORT.md
│ │ ├── OPENAI_INTEGRATION.md
│ │ ├── PINECONE.md
│ │ ├── QDRANT.md
│ │ ├── RAG_PIPELINES.md
│ │ ├── WEAVIATE.md
│ │ └── WINDSURF.md
│ ├── plans/
│ │ └── video/
│ │ ├── 00_VIDEO_SOURCE_OVERVIEW.md
│ │ ├── 01_VIDEO_RESEARCH.md
│ │ ├── 02_VIDEO_DATA_MODELS.md
│ │ ├── 03_VIDEO_PIPELINE.md
│ │ ├── 04_VIDEO_INTEGRATION.md
│ │ ├── 05_VIDEO_OUTPUT.md
│ │ ├── 06_VIDEO_TESTING.md
│ │ └── 07_VIDEO_DEPENDENCIES.md
│ ├── reference/
│ │ ├── AI_SKILL_STANDARDS.md
│ │ ├── API_REFERENCE.md
│ │ ├── C3_x_Router_Architecture.md
│ │ ├── CLAUDE_INTEGRATION.md
│ │ ├── CLI_REFERENCE.md
│ │ ├── CODE_QUALITY.md
│ │ ├── CONFIG_FORMAT.md
│ │ ├── ENVIRONMENT_VARIABLES.md
│ │ ├── FEATURE_MATRIX.md
│ │ ├── GIT_CONFIG_SOURCES.md
│ │ ├── LARGE_DOCUMENTATION.md
│ │ ├── LLMS_TXT_SUPPORT.md
│ │ ├── MCP_REFERENCE.md
│ │ └── SKILL_ARCHITECTURE.md
│ ├── roadmap/
│ │ ├── INTELLIGENCE_SYSTEM_ARCHITECTURE.md
│ │ ├── INTELLIGENCE_SYSTEM_RESEARCH.md
│ │ ├── README.md
│ │ └── SKILL_INTELLIGENCE_SYSTEM.md
│ ├── strategy/
│ │ ├── ACTION_PLAN.md
│ │ ├── ARBITRARY_LIMITS_AND_DEAD_CODE_PLAN.md
│ │ ├── DEEPWIKI_ANALYSIS.md
│ │ ├── INTEGRATION_STRATEGY.md
│ │ ├── INTEGRATION_TEMPLATES.md
│ │ ├── KIMI_ANALYSIS_COMPARISON.md
│ │ ├── README.md
│ │ ├── STAGE_1_CORRECTED_IMPLEMENTATION.md
│ │ ├── STAGE_1_IMPLEMENTATION_SUMMARY.md
│ │ └── STAGE_1_REVIEW_AND_VERIFICATION.md
│ ├── user-guide/
│ │ ├── 01-core-concepts.md
│ │ ├── 02-scraping.md
│ │ ├── 03-enhancement.md
│ │ ├── 04-packaging.md
│ │ ├── 05-workflows.md
│ │ └── 06-troubleshooting.md
│ └── zh-CN/
│ ├── ARCHITECTURE.md
│ ├── README.md
│ ├── advanced/
│ │ ├── custom-workflows.md
│ │ ├── mcp-server.md
│ │ └── multi-source.md
│ ├── getting-started/
│ │ ├── 01-installation.md
│ │ ├── 02-quick-start.md
│ │ ├── 03-your-first-skill.md
│ │ └── 04-next-steps.md
│ ├── reference/
│ │ ├── AI_SKILL_STANDARDS.md
│ │ ├── API_REFERENCE.md
│ │ ├── C3_x_Router_Architecture.md
│ │ ├── CLAUDE_INTEGRATION.md
│ │ ├── CLI_REFERENCE.md
│ │ ├── CODE_QUALITY.md
│ │ ├── CONFIG_FORMAT.md
│ │ ├── ENVIRONMENT_VARIABLES.md
│ │ ├── FEATURE_MATRIX.md
│ │ ├── GIT_CONFIG_SOURCES.md
│ │ ├── LARGE_DOCUMENTATION.md
│ │ ├── LLMS_TXT_SUPPORT.md
│ │ ├── MCP_REFERENCE.md
│ │ └── SKILL_ARCHITECTURE.md
│ └── user-guide/
│ ├── 01-core-concepts.md
│ ├── 02-scraping.md
│ ├── 03-enhancement.md
│ ├── 04-packaging.md
│ ├── 05-workflows.md
│ └── 06-troubleshooting.md
├── example-mcp-config.json
├── examples/
│ ├── chroma-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_chroma.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── cline-django-assistant/
│ │ ├── README.md
│ │ ├── generate_clinerules.py
│ │ └── requirements.txt
│ ├── continue-dev-universal/
│ │ ├── README.md
│ │ ├── context_server.py
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── cursor-react-skill/
│ │ ├── .cursorrules.example
│ │ ├── README.md
│ │ ├── example-project/
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── App.tsx
│ │ │ │ └── index.tsx
│ │ │ └── tsconfig.json
│ │ ├── generate_cursorrules.py
│ │ └── requirements.txt
│ ├── faiss-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_build_faiss_index.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── haystack-pipeline/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── http_transport_examples.sh
│ ├── langchain-rag-pipeline/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── llama-index-query-engine/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── pinecone-upsert/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── qdrant-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_qdrant.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── test_http_server.py
│ ├── weaviate-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_weaviate.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ ├── requirements.txt
│ │ └── sample_output/
│ │ └── query_results.txt
│ └── windsurf-fastapi-context/
│ ├── README.md
│ ├── generate_windsurfrules.py
│ └── requirements.txt
├── helm/
│ └── skill-seekers/
│ ├── Chart.yaml
│ ├── templates/
│ │ ├── NOTES.txt
│ │ ├── _helpers.tpl
│ │ ├── chroma-deployment.yaml
│ │ ├── configmap.yaml
│ │ ├── hpa.yaml
│ │ ├── ingress.yaml
│ │ ├── mcp-deployment.yaml
│ │ ├── pvc.yaml
│ │ ├── qdrant-deployment.yaml
│ │ ├── secret.yaml
│ │ ├── service.yaml
│ │ ├── serviceaccount.yaml
│ │ └── weaviate-deployment.yaml
│ └── values.yaml
├── mypy.ini
├── pyproject.toml
├── render-mcp.yaml
├── render.yaml
├── requirements.txt
├── ruff_errors.txt
├── scripts/
│ ├── bootstrap_skill.sh
│ ├── check_translation_sync.sh
│ ├── run_benchmarks.sh
│ ├── run_integration_tests.sh
│ ├── skill_header.md
│ └── translate_doc.py
├── setup.sh
├── setup_mcp.sh
├── src/
│ └── skill_seekers/
│ ├── __init__.py
│ ├── _version.py
│ ├── benchmark/
│ │ ├── __init__.py
│ │ ├── framework.py
│ │ ├── models.py
│ │ └── runner.py
│ ├── cli/
│ │ ├── __init__.py
│ │ ├── adaptors/
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── chroma.py
│ │ │ ├── claude.py
│ │ │ ├── faiss_helpers.py
│ │ │ ├── gemini.py
│ │ │ ├── haystack.py
│ │ │ ├── langchain.py
│ │ │ ├── llama_index.py
│ │ │ ├── markdown.py
│ │ │ ├── minimax.py
│ │ │ ├── openai.py
│ │ │ ├── pinecone_adaptor.py
│ │ │ ├── qdrant.py
│ │ │ ├── streaming_adaptor.py
│ │ │ └── weaviate.py
│ │ ├── ai_enhancer.py
│ │ ├── api_reference_builder.py
│ │ ├── architectural_pattern_detector.py
│ │ ├── arguments/
│ │ │ ├── __init__.py
│ │ │ ├── analyze.py
│ │ │ ├── asciidoc.py
│ │ │ ├── chat.py
│ │ │ ├── common.py
│ │ │ ├── confluence.py
│ │ │ ├── create.py
│ │ │ ├── enhance.py
│ │ │ ├── epub.py
│ │ │ ├── github.py
│ │ │ ├── html.py
│ │ │ ├── jupyter.py
│ │ │ ├── manpage.py
│ │ │ ├── notion.py
│ │ │ ├── openapi.py
│ │ │ ├── package.py
│ │ │ ├── pdf.py
│ │ │ ├── pptx.py
│ │ │ ├── rss.py
│ │ │ ├── scrape.py
│ │ │ ├── sync_config.py
│ │ │ ├── unified.py
│ │ │ ├── upload.py
│ │ │ ├── video.py
│ │ │ ├── word.py
│ │ │ └── workflow.py
│ │ ├── asciidoc_scraper.py
│ │ ├── benchmark_cli.py
│ │ ├── chat_scraper.py
│ │ ├── cloud_storage_cli.py
│ │ ├── code_analyzer.py
│ │ ├── codebase_scraper.py
│ │ ├── config_command.py
│ │ ├── config_enhancer.py
│ │ ├── config_extractor.py
│ │ ├── config_fetcher.py
│ │ ├── config_manager.py
│ │ ├── config_validator.py
│ │ ├── conflict_detector.py
│ │ ├── confluence_scraper.py
│ │ ├── constants.py
│ │ ├── create_command.py
│ │ ├── dependency_analyzer.py
│ │ ├── doc_scraper.py
│ │ ├── embedding_pipeline.py
│ │ ├── enhance_command.py
│ │ ├── enhance_skill.py
│ │ ├── enhance_skill_local.py
│ │ ├── enhance_status.py
│ │ ├── enhancement_workflow.py
│ │ ├── epub_scraper.py
│ │ ├── estimate_pages.py
│ │ ├── generate_router.py
│ │ ├── github_fetcher.py
│ │ ├── github_scraper.py
│ │ ├── guide_enhancer.py
│ │ ├── how_to_guide_builder.py
│ │ ├── html_scraper.py
│ │ ├── incremental_updater.py
│ │ ├── install_agent.py
│ │ ├── install_skill.py
│ │ ├── jupyter_scraper.py
│ │ ├── language_detector.py
│ │ ├── llms_txt_detector.py
│ │ ├── llms_txt_downloader.py
│ │ ├── llms_txt_parser.py
│ │ ├── main.py
│ │ ├── man_scraper.py
│ │ ├── markdown_cleaner.py
│ │ ├── merge_sources.py
│ │ ├── multilang_support.py
│ │ ├── notion_scraper.py
│ │ ├── openapi_scraper.py
│ │ ├── package_multi.py
│ │ ├── package_skill.py
│ │ ├── parsers/
│ │ │ ├── __init__.py
│ │ │ ├── analyze_parser.py
│ │ │ ├── asciidoc_parser.py
│ │ │ ├── base.py
│ │ │ ├── chat_parser.py
│ │ │ ├── config_parser.py
│ │ │ ├── confluence_parser.py
│ │ │ ├── create_parser.py
│ │ │ ├── enhance_parser.py
│ │ │ ├── enhance_status_parser.py
│ │ │ ├── epub_parser.py
│ │ │ ├── estimate_parser.py
│ │ │ ├── extractors/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base_parser.py
│ │ │ │ ├── formatters.py
│ │ │ │ ├── markdown_parser.py
│ │ │ │ ├── pdf_parser.py
│ │ │ │ ├── quality_scorer.py
│ │ │ │ ├── rst_parser.py
│ │ │ │ └── unified_structure.py
│ │ │ ├── github_parser.py
│ │ │ ├── html_parser.py
│ │ │ ├── install_agent_parser.py
│ │ │ ├── install_parser.py
│ │ │ ├── jupyter_parser.py
│ │ │ ├── manpage_parser.py
│ │ │ ├── multilang_parser.py
│ │ │ ├── notion_parser.py
│ │ │ ├── openapi_parser.py
│ │ │ ├── package_parser.py
│ │ │ ├── pdf_parser.py
│ │ │ ├── pptx_parser.py
│ │ │ ├── quality_parser.py
│ │ │ ├── resume_parser.py
│ │ │ ├── rss_parser.py
│ │ │ ├── scrape_parser.py
│ │ │ ├── stream_parser.py
│ │ │ ├── sync_config_parser.py
│ │ │ ├── test_examples_parser.py
│ │ │ ├── unified_parser.py
│ │ │ ├── update_parser.py
│ │ │ ├── upload_parser.py
│ │ │ ├── video_parser.py
│ │ │ ├── word_parser.py
│ │ │ └── workflows_parser.py
│ │ ├── pattern_recognizer.py
│ │ ├── pdf_extractor_poc.py
│ │ ├── pdf_scraper.py
│ │ ├── pptx_scraper.py
│ │ ├── presets/
│ │ │ ├── __init__.py
│ │ │ ├── analyze_presets.py
│ │ │ ├── github_presets.py
│ │ │ ├── manager.py
│ │ │ └── scrape_presets.py
│ │ ├── quality_checker.py
│ │ ├── quality_metrics.py
│ │ ├── rag_chunker.py
│ │ ├── rate_limit_handler.py
│ │ ├── resume_command.py
│ │ ├── rss_scraper.py
│ │ ├── run_tests.py
│ │ ├── setup_wizard.py
│ │ ├── signal_flow_analyzer.py
│ │ ├── source_detector.py
│ │ ├── split_config.py
│ │ ├── storage/
│ │ │ ├── __init__.py
│ │ │ ├── azure_storage.py
│ │ │ ├── base_storage.py
│ │ │ ├── gcs_storage.py
│ │ │ └── s3_storage.py
│ │ ├── streaming_ingest.py
│ │ ├── swift_patterns.py
│ │ ├── sync_cli.py
│ │ ├── sync_config.py
│ │ ├── test_example_extractor.py
│ │ ├── test_unified_simple.py
│ │ ├── unified_codebase_analyzer.py
│ │ ├── unified_enhancer.py
│ │ ├── unified_scraper.py
│ │ ├── unified_skill_builder.py
│ │ ├── upload_skill.py
│ │ ├── utils.py
│ │ ├── video_metadata.py
│ │ ├── video_models.py
│ │ ├── video_scraper.py
│ │ ├── video_segmenter.py
│ │ ├── video_setup.py
│ │ ├── video_transcript.py
│ │ ├── video_visual.py
│ │ ├── word_scraper.py
│ │ ├── workflow_runner.py
│ │ └── workflows_command.py
│ ├── embedding/
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── generator.py
│ │ ├── models.py
│ │ └── server.py
│ ├── mcp/
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── agent_detector.py
│ │ ├── git_repo.py
│ │ ├── requirements.txt
│ │ ├── server.py
│ │ ├── server_fastmcp.py
│ │ ├── server_legacy.py
│ │ ├── source_manager.py
│ │ └── tools/
│ │ ├── __init__.py
│ │ ├── config_tools.py
│ │ ├── packaging_tools.py
│ │ ├── scraping_tools.py
│ │ ├── source_tools.py
│ │ ├── splitting_tools.py
│ │ ├── sync_config_tools.py
│ │ ├── vector_db_tools.py
│ │ └── workflow_tools.py
│ ├── py.typed
│ ├── sync/
│ │ ├── __init__.py
│ │ ├── detector.py
│ │ ├── models.py
│ │ ├── monitor.py
│ │ └── notifier.py
│ └── workflows/
│ ├── __init__.py
│ ├── accessibility-a11y.yaml
│ ├── advanced-patterns.yaml
│ ├── api-documentation.yaml
│ ├── api-evolution.yaml
│ ├── api-gateway.yaml
│ ├── architecture-comprehensive.yaml
│ ├── auth-strategies.yaml
│ ├── aws-services.yaml
│ ├── background-jobs.yaml
│ ├── backup-disaster-recovery.yaml
│ ├── build-tools.yaml
│ ├── caching-strategies.yaml
│ ├── cli-tooling.yaml
│ ├── comparison-matrix.yaml
│ ├── complex-merge.yaml
│ ├── compliance-gdpr.yaml
│ ├── component-library.yaml
│ ├── computer-vision.yaml
│ ├── contribution-guide.yaml
│ ├── data-validation.yaml
│ ├── database-schema.yaml
│ ├── deep-linking.yaml
│ ├── default.yaml
│ ├── design-system.yaml
│ ├── devops-deployment.yaml
│ ├── encryption-guide.yaml
│ ├── event-driven.yaml
│ ├── feature-engineering.yaml
│ ├── forms-validation.yaml
│ ├── graphql-schema.yaml
│ ├── grpc-services.yaml
│ ├── iam-identity.yaml
│ ├── kubernetes-deployment.yaml
│ ├── localization-i18n.yaml
│ ├── message-queues.yaml
│ ├── microservices-patterns.yaml
│ ├── migration-guide.yaml
│ ├── minimal.yaml
│ ├── mlops-pipeline.yaml
│ ├── model-deployment.yaml
│ ├── observability-stack.yaml
│ ├── offline-first.yaml
│ ├── onboarding-beginner.yaml
│ ├── performance-optimization.yaml
│ ├── platform-specific.yaml
│ ├── push-notifications.yaml
│ ├── pwa-checklist.yaml
│ ├── rate-limiting.yaml
│ ├── responsive-design.yaml
│ ├── rest-api-design.yaml
│ ├── sdk-integration.yaml
│ ├── secrets-management.yaml
│ ├── security-focus.yaml
│ ├── serverless-architecture.yaml
│ ├── ssr-guide.yaml
│ ├── state-management.yaml
│ ├── stream-processing.yaml
│ ├── terraform-guide.yaml
│ ├── testing-focus.yaml
│ ├── testing-frontend.yaml
│ ├── troubleshooting-guide.yaml
│ ├── vector-databases.yaml
│ ├── video-tutorial.yaml
│ ├── webhook-guide.yaml
│ └── websockets-realtime.yaml
├── test_api.py
├── test_httpx_quick.sh
├── test_httpx_skill.sh
├── test_results.log
├── test_week2_features.py
└── tests/
├── __init__.py
├── conftest.py
├── docker-compose.test.yml
├── fixtures/
│ └── example_conflicts.json
├── mcp_integration_test.md
├── test_adaptor_benchmarks.py
├── test_adaptors/
│ ├── __init__.py
│ ├── test_adaptors_e2e.py
│ ├── test_base.py
│ ├── test_chroma_adaptor.py
│ ├── test_claude_adaptor.py
│ ├── test_faiss_adaptor.py
│ ├── test_gemini_adaptor.py
│ ├── test_haystack_adaptor.py
│ ├── test_langchain_adaptor.py
│ ├── test_llama_index_adaptor.py
│ ├── test_markdown_adaptor.py
│ ├── test_minimax_adaptor.py
│ ├── test_openai_adaptor.py
│ ├── test_qdrant_adaptor.py
│ └── test_weaviate_adaptor.py
├── test_analyze_command.py
├── test_analyze_e2e.py
├── test_api_reference_builder.py
├── test_architecture_scenarios.py
├── test_async_scraping.py
├── test_benchmark.py
├── test_bootstrap_skill.py
├── test_bootstrap_skill_e2e.py
├── test_c3_integration.py
├── test_chunking_integration.py
├── test_cli_parsers.py
├── test_cli_paths.py
├── test_cli_refactor_e2e.py
├── test_cloud_storage.py
├── test_code_analyzer.py
├── test_codebase_scraper.py
├── test_config_extractor.py
├── test_config_fetcher.py
├── test_config_validation.py
├── test_constants.py
├── test_create_arguments.py
├── test_create_integration_basic.py
├── test_dependency_analyzer.py
├── test_e2e_three_stream_pipeline.py
├── test_embedding.py
├── test_embedding_pipeline.py
├── test_enhance_command.py
├── test_enhance_skill_local.py
├── test_epub_scraper.py
├── test_estimate_pages.py
├── test_excluded_dirs_config.py
├── test_framework_detection.py
├── test_generate_router_github.py
├── test_git_repo.py
├── test_git_sources_e2e.py
├── test_github_fetcher.py
├── test_github_scraper.py
├── test_guide_enhancer.py
├── test_how_to_guide_builder.py
├── test_incremental_updates.py
├── test_install_agent.py
├── test_install_multiplatform.py
├── test_install_skill.py
├── test_install_skill_e2e.py
├── test_integration.py
├── test_integration_adaptors.py
├── test_issue_219_e2e.py
├── test_issue_277_real_world.py
├── test_language_detector.py
├── test_llms_txt_detector.py
├── test_llms_txt_downloader.py
├── test_llms_txt_parser.py
├── test_markdown_parsing.py
├── test_mcp_fastmcp.py
├── test_mcp_git_sources.py
├── test_mcp_server.py
├── test_mcp_vector_dbs.py
├── test_mcp_workflow_tools.py
├── test_merge_sources_github.py
├── test_multi_source.py
├── test_multilang_support.py
├── test_new_source_types.py
├── test_package_skill.py
├── test_package_structure.py
├── test_parallel_scraping.py
├── test_parser_sync.py
├── test_pattern_recognizer.py
├── test_pdf_advanced_features.py
├── test_pdf_extractor.py
├── test_pdf_scraper.py
├── test_pinecone_adaptor.py
├── test_pr144_concerns.py
├── test_preset_system.py
├── test_quality_checker.py
├── test_quality_metrics.py
├── test_rag_chunker.py
├── test_rate_limit_handler.py
├── test_real_world_fastmcp.py
├── test_scraper_features.py
├── test_server_fastmcp_http.py
├── test_setup_scripts.py
├── test_skip_llms_txt.py
├── test_smart_summarization.py
├── test_source_detector.py
├── test_source_manager.py
├── test_streaming_ingestion.py
├── test_swift_detection.py
├── test_sync_config.py
├── test_sync_config_e2e.py
├── test_terminal_detection.py
├── test_test_example_extractor.py
├── test_unified.py
├── test_unified_analyzer.py
├── test_unified_mcp_integration.py
├── test_unified_parsers.py
├── test_unified_scraper_orchestration.py
├── test_upload_integration.py
├── test_upload_skill.py
├── test_url_conversion.py
├── test_utilities.py
├── test_video_scraper.py
├── test_video_setup.py
├── test_word_scraper.py
├── test_workflow_runner.py
├── test_workflow_tools_mcp.py
└── test_workflows_command.py
================================================
FILE CONTENTS
================================================
================================================
FILE: .claude/mcp_config.example.json
================================================
{
"mcpServers": {
"skill-seeker": {
"type": "stdio",
"command": "/path/to/your/Skill_Seekers/.venv/bin/python3",
"args": [
"-m",
"skill_seekers.mcp.server_fastmcp"
],
"cwd": "/path/to/your/Skill_Seekers",
"env": {}
}
}
}
================================================
FILE: .dockerignore
================================================
# Python artifacts
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual environments
venv/
env/
ENV/
.venv
# Testing
.pytest_cache/
.coverage
.coverage.*
htmlcov/
.tox/
.hypothesis/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
.DS_Store
# Git
.git/
.gitignore
.gitattributes
# Documentation
docs/
*.md
!README.md
# CI/CD
.github/
.gitlab-ci.yml
.travis.yml
# Output directories
output/
data/
*.zip
*.tar.gz
# Logs
*.log
logs/
# Environment files
.env
.env.*
!.env.example
# Test files
tests/
test_*.py
*_test.py
# Docker
Dockerfile*
docker-compose*.yml
.dockerignore
================================================
FILE: .github/FUNDING.yml
================================================
# GitHub Sponsors configuration
# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository
buy_me_a_coffee: yusufkaraaslan
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.md
================================================
---
name: Bug Report
about: Report a bug or issue with Skill Seekers
title: '[BUG] '
labels: 'type: bug'
assignees: ''
---
## 🐛 Bug Description
A clear and concise description of what the bug is.
## 🔄 Steps to Reproduce
1. Go to '...'
2. Run command '...'
3. See error
## ✅ Expected Behavior
What you expected to happen.
## ❌ Actual Behavior
What actually happened.
## 📋 Environment
- **OS:** [e.g., macOS 14.0, Ubuntu 22.04, Windows 11]
- **Python Version:** [e.g., 3.10, 3.11]
- **Skill Seekers Version:** [e.g., v1.0.0]
- **Installation Method:** [pip, git clone, etc.]
## 📊 Error Output
```
Paste the full error message or traceback here
```
## 📸 Screenshots
If applicable, add screenshots to help explain the problem.
## 🔍 Additional Context
- Config file used (if applicable)
- Documentation URL being scraped
- Any custom modifications made
## 🎯 Possible Solution
If you have an idea of how to fix this, please share!
================================================
FILE: .github/ISSUE_TEMPLATE/documentation.md
================================================
---
name: Documentation Improvement
about: Suggest improvements to documentation
title: '[DOCS] '
labels: 'type: documentation'
assignees: ''
---
## 📚 Documentation Issue
What documentation needs to be improved, added, or fixed?
## 📍 Location
- **File:** [e.g., README.md, docs/CLAUDE.md]
- **Section:** [e.g., Installation, Configuration]
- **URL:** [if applicable]
## ❌ Current State
Describe what's currently unclear, missing, or incorrect.
## ✅ Proposed Improvement
How should the documentation be changed?
## 🎯 Target Audience
Who would benefit from this documentation improvement?
- [ ] New users
- [ ] Advanced users
- [ ] Contributors
- [ ] API users
## 📝 Additional Context
Any additional context or examples that would help.
## 🔗 Related Issues
Link to any related issues or PRs.
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.md
================================================
---
name: Feature Request
about: Suggest a new feature for Skill Seekers
title: '[FEATURE] '
labels: 'type: feature'
assignees: ''
---
## 🚀 Feature Description
A clear and concise description of the feature you'd like to see.
## 💡 Use Case
Describe the problem this feature would solve. What is the user trying to accomplish?
## 📋 Proposed Solution
Describe how you envision this feature working.
## 🔄 Alternatives Considered
Have you considered any alternative solutions or workarounds?
## 📊 Expected Impact
- **Priority:** Low / Medium / High / Critical
- **Effort:** XS / S / M / L / XL
- **Users Affected:** Describe who would benefit
## 📝 Additional Context
Add any other context, screenshots, or examples about the feature request.
## ✅ Acceptance Criteria
- [ ] Criteria 1
- [ ] Criteria 2
- [ ] Criteria 3
================================================
FILE: .github/ISSUE_TEMPLATE/mcp_tool.md
================================================
---
name: MCP Tool Request
about: Suggest a new tool for the MCP server
title: '[MCP] Add tool: '
labels: mcp, enhancement
assignees: ''
---
## Tool Name
<!-- e.g., auto_detect_selectors -->
## Tool Description
<!-- What does this tool do? -->
## Input Parameters
```json
{
"param1": {
"type": "string",
"description": "...",
"required": true
}
}
```
## Expected Output
<!-- What should the tool return? -->
## Use Case Example
<!-- How would users interact with this tool? -->
```
User: "Auto-detect selectors for https://docs.example.com"
Tool: Analyzes page structure and suggests optimal selectors
```
## CLI Integration
<!-- Which CLI tool does this wrap? Or is it new logic? -->
- [ ] Wraps existing CLI tool: `cli/tool_name.py`
- [ ] New functionality
## Implementation Notes
<!-- Technical details, dependencies, etc. -->
================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
# Pull Request
## 📋 Description
Brief description of changes made.
## 🔗 Related Issues
Closes #(issue number)
Relates to #(issue number)
## 🎯 Type of Change
- [ ] 🐛 Bug fix (non-breaking change which fixes an issue)
- [ ] ✨ New feature (non-breaking change which adds functionality)
- [ ] 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] 📚 Documentation update
- [ ] ♻️ Code refactoring
- [ ] ⚡ Performance improvement
- [ ] 🧪 Test update
## ✅ Checklist
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published
## 🧪 Testing
Describe the tests you ran to verify your changes.
**Test Configuration:**
- Python version:
- OS:
- Dependencies installed:
## 📸 Screenshots (if applicable)
Add screenshots to demonstrate visual changes.
## 📝 Additional Notes
Any additional information reviewers should know.
================================================
FILE: .github/create_issues.sh
================================================
#!/bin/bash
# Script to create GitHub issues via web browser
# Since gh CLI is not available, we'll open browser to create issues
REPO="yusufkaraaslan/Skill_Seekers"
BASE_URL="https://github.com/${REPO}/issues/new"
echo "🚀 Creating GitHub Issues for Skill Seeker MCP Development"
echo "=========================================================="
echo ""
echo "Opening browser to create issues..."
echo "Please copy the content from .github/ISSUES_TO_CREATE.md"
echo ""
# Issue 1: Fix test failures
echo "📝 Issue 1: Fix 3 test failures"
echo "URL: ${BASE_URL}?labels=bug,tests,good+first+issue&title=Fix+3+test+failures+(warnings+vs+errors+handling)"
echo ""
# Issue 2: MCP setup guide
echo "📝 Issue 2: Create MCP setup guide"
echo "URL: ${BASE_URL}?labels=documentation,mcp,enhancement&title=Create+comprehensive+MCP+setup+guide+for+Claude+Code"
echo ""
# Issue 3: Test MCP server
echo "📝 Issue 3: Test MCP server"
echo "URL: ${BASE_URL}?labels=testing,mcp,priority-high&title=Test+MCP+server+with+actual+Claude+Code+instance"
echo ""
# Issue 4: Update documentation
echo "📝 Issue 4: Update documentation"
echo "URL: ${BASE_URL}?labels=documentation,breaking-change&title=Update+all+documentation+for+new+monorepo+structure"
echo ""
echo "=========================================================="
echo "📋 Instructions:"
echo "1. Click each URL above (or copy to browser)"
echo "2. Copy the issue body from .github/ISSUES_TO_CREATE.md"
echo "3. Paste into the issue description"
echo "4. Click 'Submit new issue'"
echo ""
echo "Or use this quick link to view all templates:"
echo "cat .github/ISSUES_TO_CREATE.md"
================================================
FILE: .github/workflows/docker-publish.yml
================================================
# Docker Image Publishing - Automated builds and pushes to Docker Hub
# Security Note: Uses secrets for Docker Hub credentials. Matrix values are hardcoded.
# Triggers: push/pull_request/workflow_dispatch only. No untrusted input.
name: Docker Publish
on:
push:
branches: [ main ]
tags:
- 'v*'
pull_request:
branches: [ main ]
paths:
- 'Dockerfile*'
- 'docker-compose.yml'
- 'src/**'
- 'pyproject.toml'
workflow_dispatch:
env:
DOCKER_REGISTRY: docker.io
DOCKER_USERNAME: ${{ secrets.DOCKER_USERNAME }}
jobs:
build-and-push:
name: Build and Push Docker Images
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
image:
- name: skill-seekers
dockerfile: Dockerfile
description: "Skill Seekers CLI - Convert documentation to AI skills"
- name: skill-seekers-mcp
dockerfile: Dockerfile.mcp
description: "Skill Seekers MCP Server - 25 tools for AI assistants"
env:
IMAGE_NAME: ${{ matrix.image.name }}
IMAGE_DOCKERFILE: ${{ matrix.image.dockerfile }}
IMAGE_DESCRIPTION: ${{ matrix.image.description }}
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Log in to Docker Hub
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: Extract metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ${{ env.DOCKER_REGISTRY }}/${{ env.DOCKER_USERNAME }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ${{ env.IMAGE_DOCKERFILE }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max
platforms: linux/amd64,linux/arm64
- name: Create image summary
run: |
echo "## 🐳 Docker Image: $IMAGE_NAME" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Description:** $IMAGE_DESCRIPTION" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Tags:**" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
echo "${{ steps.meta.outputs.tags }}" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
test-images:
name: Test Docker Images
needs: build-and-push
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Build CLI image
run: |
docker build -t skill-seekers:test -f Dockerfile .
- name: Test CLI image
run: |
echo "🧪 Testing CLI image..."
docker run --rm skill-seekers:test skill-seekers --version
docker run --rm skill-seekers:test skill-seekers --help
- name: Build MCP image
run: |
docker build -t skill-seekers-mcp:test -f Dockerfile.mcp .
- name: Test MCP image
run: |
echo "🧪 Testing MCP server image..."
# Start MCP server in background
docker run -d --name mcp-test -p 8765:8765 skill-seekers-mcp:test
# Wait for server to start
sleep 10
# Check health
curl -f http://localhost:8765/health || exit 1
# Stop container
docker stop mcp-test
docker rm mcp-test
- name: Test Docker Compose
run: |
echo "🧪 Testing Docker Compose..."
docker-compose config
echo "✅ Docker Compose configuration valid"
================================================
FILE: .github/workflows/quality-metrics.yml
================================================
# Security Note: This workflow uses workflow_dispatch inputs and pull_request events.
# All untrusted inputs are accessed via environment variables (env:) as recommended.
# No direct usage of github.event.issue/comment/review content in run: commands.
name: Quality Metrics Dashboard
on:
workflow_dispatch:
inputs:
skill_dir:
description: 'Path to skill directory to analyze (e.g., output/react)'
required: true
type: string
fail_threshold:
description: 'Minimum quality score to pass (default: 70)'
required: false
default: '70'
type: string
pull_request:
paths:
- 'output/**'
- 'configs/**'
jobs:
analyze:
name: Quality Metrics Analysis
runs-on: ubuntu-latest
env:
SKILL_DIR_INPUT: ${{ github.event.inputs.skill_dir }}
FAIL_THRESHOLD_INPUT: ${{ github.event.inputs.fail_threshold }}
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Find skill directories
id: find_skills
run: |
if [ -n "$SKILL_DIR_INPUT" ]; then
# Manual trigger with specific directory
echo "dirs=$SKILL_DIR_INPUT" >> $GITHUB_OUTPUT
else
# PR trigger - find all skill directories
DIRS=$(find output -maxdepth 1 -type d -name "*" ! -name "output" | tr '\n' ' ' || echo "")
if [ -z "$DIRS" ]; then
echo "No skill directories found"
echo "dirs=" >> $GITHUB_OUTPUT
else
echo "dirs=$DIRS" >> $GITHUB_OUTPUT
fi
fi
- name: Analyze quality metrics
id: quality
run: |
DIRS="${{ steps.find_skills.outputs.dirs }}"
THRESHOLD="${FAIL_THRESHOLD_INPUT:-70}"
if [ -z "$DIRS" ]; then
echo "No directories to analyze"
exit 0
fi
ALL_PASSED=true
SUMMARY_FILE="quality_summary.md"
echo "# 📊 Quality Metrics Dashboard" > $SUMMARY_FILE
echo "" >> $SUMMARY_FILE
echo "**Threshold:** $THRESHOLD/100" >> $SUMMARY_FILE
echo "" >> $SUMMARY_FILE
for skill_dir in $DIRS; do
if [ ! -d "$skill_dir" ]; then
continue
fi
SKILL_NAME=$(basename "$skill_dir")
echo "🔍 Analyzing $SKILL_NAME..."
# Run quality analysis
python3 << 'EOF' "$skill_dir" "$THRESHOLD" "$SKILL_NAME"
import sys
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.quality_metrics import QualityAnalyzer
skill_dir = Path(sys.argv[1])
threshold = float(sys.argv[2])
skill_name = sys.argv[3]
analyzer = QualityAnalyzer(skill_dir)
report = analyzer.generate_report()
# Print formatted report
formatted = analyzer.format_report(report)
print(formatted)
# Save individual report
with open(f'quality_{skill_name}.txt', 'w') as f:
f.write(formatted)
# Add to summary
score = report.overall_score.total_score
grade = report.overall_score.grade
status = "✅" if score >= threshold else "❌"
summary_line = f"{status} **{skill_name}**: {grade} ({score:.1f}/100)"
print(f"\n{summary_line}")
with open('quality_summary.md', 'a') as f:
f.write(f"{summary_line}\n")
# Set metrics as annotations
if score < threshold:
print(f"::error file={skill_dir}/SKILL.md::Quality score {score:.1f} is below threshold {threshold}")
sys.exit(1)
elif score < 80:
print(f"::warning file={skill_dir}/SKILL.md::Quality score {score:.1f} could be improved")
else:
print(f"::notice file={skill_dir}/SKILL.md::Quality score {score:.1f} - Excellent!")
EOF
if [ $? -ne 0 ]; then
ALL_PASSED=false
fi
echo "" >> $SUMMARY_FILE
done
if [ "$ALL_PASSED" = false ]; then
echo "❌ Some skills failed quality thresholds"
exit 1
else
echo "✅ All skills passed quality thresholds"
fi
- name: Upload quality reports
uses: actions/upload-artifact@v3
with:
name: quality-metrics-reports
path: quality_*.txt
retention-days: 30
continue-on-error: true
- name: Post summary to PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const summary = fs.readFileSync('quality_summary.md', 'utf8');
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: summary
});
continue-on-error: true
- name: Create dashboard summary
run: |
if [ -f "quality_summary.md" ]; then
cat quality_summary.md >> $GITHUB_STEP_SUMMARY
fi
================================================
FILE: .github/workflows/release.yml
================================================
name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
cache: 'pip'
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.cargo/bin" >> $GITHUB_PATH
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f skill_seeker_mcp/requirements.txt ]; then pip install -r skill_seeker_mcp/requirements.txt; fi
# Install package in editable mode for tests (required for src/ layout)
pip install -e .
- name: Run tests
run: |
python -m pytest tests/ -v
- name: Extract version from tag
id: get_version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Verify Python version
run: |
python --version
python -c "import sys; assert sys.version_info >= (3, 10), f'Python {sys.version} is not >= 3.10'"
- name: Verify version consistency
run: |
TAG_VERSION="${{ steps.get_version.outputs.VERSION }}"
PKG_VERSION=$(python -c "import skill_seekers; print(skill_seekers.__version__)")
TOML_VERSION=$(grep -m1 '^version' pyproject.toml | sed 's/version *= *"\(.*\)"/\1/')
echo "Tag version: $TAG_VERSION"
echo "Package version: $PKG_VERSION"
echo "TOML version: $TOML_VERSION"
if [ "$TAG_VERSION" != "$PKG_VERSION" ]; then
echo "::error::Version mismatch! Tag=$TAG_VERSION but package reports=$PKG_VERSION"
exit 1
fi
if [ "$TAG_VERSION" != "$TOML_VERSION" ]; then
echo "::error::Version mismatch! Tag=$TAG_VERSION but pyproject.toml has=$TOML_VERSION"
exit 1
fi
echo "✅ All versions match: $TAG_VERSION"
- name: Create Release Notes
id: release_notes
run: |
if [ -f CHANGELOG.md ]; then
# Extract changelog for this version (escape dots for exact match)
VERSION="${{ steps.get_version.outputs.VERSION }}"
ESCAPED_VERSION=$(echo "$VERSION" | sed 's/\./\\./g')
sed -n "/## \[${ESCAPED_VERSION}\]/,/## \[/p" CHANGELOG.md | sed '$d' > release_notes.md
fi
# Fallback if extraction produced empty file or CHANGELOG.md missing
if [ ! -s release_notes.md ]; then
echo "Release v${{ steps.get_version.outputs.VERSION }}" > release_notes.md
fi
- name: Check if release exists
id: check_release
run: |
if gh release view ${{ github.ref_name }} > /dev/null 2>&1; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Create GitHub Release
if: steps.check_release.outputs.exists == 'false'
uses: softprops/action-gh-release@v1
with:
name: v${{ steps.get_version.outputs.VERSION }}
tag_name: ${{ github.ref_name }}
body_path: release_notes.md
draft: false
prerelease: false
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Skip Release Creation
if: steps.check_release.outputs.exists == 'true'
run: |
echo "ℹ️ Release ${{ github.ref_name }} already exists, skipping creation"
echo "View at: https://github.com/${{ github.repository }}/releases/tag/${{ github.ref_name }}"
- name: Build package
run: |
uv build
- name: Publish to PyPI
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
run: |
uv publish --token $UV_PUBLISH_TOKEN
================================================
FILE: .github/workflows/scheduled-updates.yml
================================================
# Automated Skill Updates - Runs weekly to refresh documentation
# Security Note: Schedule triggers with hardcoded constants. Workflow_dispatch input
# accessed via FRAMEWORKS_INPUT env variable (safe pattern).
name: Scheduled Skill Updates
on:
schedule:
# Run every Sunday at 3 AM UTC
- cron: '0 3 * * 0'
workflow_dispatch:
inputs:
frameworks:
description: 'Frameworks to update (comma-separated or "all")'
required: false
default: 'all'
type: string
jobs:
update-skills:
name: Update ${{ matrix.framework }}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# Popular frameworks to keep updated
framework:
- react
- django
- fastapi
- godot
- vue
- flask
env:
FRAMEWORK: ${{ matrix.framework }}
FRAMEWORKS_INPUT: ${{ github.event.inputs.frameworks }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Check if framework should be updated
id: should_update
run: |
FRAMEWORKS_INPUT="${FRAMEWORKS_INPUT:-all}"
if [ "$FRAMEWORKS_INPUT" = "all" ] || [ -z "$FRAMEWORKS_INPUT" ]; then
echo "update=true" >> $GITHUB_OUTPUT
elif echo "$FRAMEWORKS_INPUT" | grep -q "$FRAMEWORK"; then
echo "update=true" >> $GITHUB_OUTPUT
else
echo "update=false" >> $GITHUB_OUTPUT
echo "⏭️ Skipping $FRAMEWORK (not in update list)"
fi
- name: Check for existing skill
if: steps.should_update.outputs.update == 'true'
id: check_existing
run: |
SKILL_DIR="output/$FRAMEWORK"
if [ -d "$SKILL_DIR" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
echo "📦 Found existing skill at $SKILL_DIR"
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "🆕 No existing skill found"
fi
- name: Incremental update (if exists)
if: steps.should_update.outputs.update == 'true' && steps.check_existing.outputs.exists == 'true'
run: |
echo "⚡ Performing incremental update for $FRAMEWORK..."
SKILL_DIR="output/$FRAMEWORK"
# Detect changes using incremental updater
python3 << 'EOF'
import sys
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.incremental_updater import IncrementalUpdater
import os
framework = os.environ['FRAMEWORK']
skill_dir = Path(f'output/{framework}')
updater = IncrementalUpdater(skill_dir)
changes = updater.detect_changes()
if changes.has_changes:
print(f"🔄 Changes detected:")
print(f" Added: {len(changes.added)}")
print(f" Modified: {len(changes.modified)}")
print(f" Deleted: {len(changes.deleted)}")
# Save current versions for next run
updater.current_versions = updater._scan_documents()
updater.save_current_versions()
else:
print("✓ No changes detected, skill is up to date")
EOF
- name: Full scrape (if new or manual)
if: steps.should_update.outputs.update == 'true' && steps.check_existing.outputs.exists == 'false'
run: |
echo "📥 Performing full scrape for $FRAMEWORK..."
CONFIG_FILE="configs/${FRAMEWORK}.json"
if [ ! -f "$CONFIG_FILE" ]; then
echo "⚠️ Config not found: $CONFIG_FILE"
exit 0
fi
# Use streaming ingestion for large docs
skill-seekers scrape --config "$CONFIG_FILE" --streaming --max-pages 200
- name: Generate quality report
if: steps.should_update.outputs.update == 'true'
run: |
SKILL_DIR="output/$FRAMEWORK"
if [ ! -d "$SKILL_DIR" ]; then
echo "⚠️ Skill directory not found"
exit 0
fi
echo "📊 Generating quality metrics..."
python3 << 'EOF'
import sys
import os
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.quality_metrics import QualityAnalyzer
framework = os.environ['FRAMEWORK']
skill_dir = Path(f'output/{framework}')
analyzer = QualityAnalyzer(skill_dir)
report = analyzer.generate_report()
print(f"\n📊 Quality Score: {report.overall_score.grade} ({report.overall_score.total_score:.1f}/100)")
print(f" Completeness: {report.overall_score.completeness:.1f}%")
print(f" Accuracy: {report.overall_score.accuracy:.1f}%")
print(f" Coverage: {report.overall_score.coverage:.1f}%")
print(f" Health: {report.overall_score.health:.1f}%")
EOF
- name: Package for Claude
if: steps.should_update.outputs.update == 'true'
run: |
SKILL_DIR="output/$FRAMEWORK"
if [ -d "$SKILL_DIR" ]; then
echo "📦 Packaging $FRAMEWORK for Claude AI..."
skill-seekers package "$SKILL_DIR" --target claude
fi
- name: Upload updated skill
if: steps.should_update.outputs.update == 'true'
uses: actions/upload-artifact@v3
with:
name: ${{ env.FRAMEWORK }}-skill-updated
path: output/${{ env.FRAMEWORK }}.zip
retention-days: 90
summary:
name: Update Summary
needs: update-skills
runs-on: ubuntu-latest
if: always()
steps:
- name: Create summary
run: |
echo "## 🔄 Scheduled Skills Update" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Date:** $(date -u '+%Y-%m-%d %H:%M UTC')" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Updated Frameworks" >> $GITHUB_STEP_SUMMARY
echo "- React" >> $GITHUB_STEP_SUMMARY
echo "- Django" >> $GITHUB_STEP_SUMMARY
echo "- FastAPI" >> $GITHUB_STEP_SUMMARY
echo "- Godot" >> $GITHUB_STEP_SUMMARY
echo "- Vue" >> $GITHUB_STEP_SUMMARY
echo "- Flask" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Updated skills available in workflow artifacts." >> $GITHUB_STEP_SUMMARY
================================================
FILE: .github/workflows/test-vector-dbs.yml
================================================
# Security Note: This workflow uses only push/pull_request/workflow_dispatch triggers.
# Matrix values are hardcoded constants. No untrusted input is used in run: commands.
name: Test Vector Database Adaptors
on:
push:
branches: [ main, development ]
paths:
- 'src/skill_seekers/cli/adaptors/**'
- 'src/skill_seekers/mcp/tools/vector_db_tools.py'
- 'tests/test_*adaptor.py'
- 'tests/test_mcp_vector_dbs.py'
pull_request:
branches: [ main, development ]
paths:
- 'src/skill_seekers/cli/adaptors/**'
- 'src/skill_seekers/mcp/tools/vector_db_tools.py'
- 'tests/test_*adaptor.py'
- 'tests/test_mcp_vector_dbs.py'
workflow_dispatch:
jobs:
test-adaptors:
name: Test ${{ matrix.adaptor }} Adaptor
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
adaptor: [weaviate, chroma, faiss, qdrant]
python-version: ['3.10', '3.12']
env:
ADAPTOR_NAME: ${{ matrix.adaptor }}
PYTHON_VERSION: ${{ matrix.python-version }}
steps:
- uses: actions/checkout@v3
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Run adaptor tests
run: |
echo "🧪 Testing $ADAPTOR_NAME adaptor..."
python -m pytest "tests/test_${ADAPTOR_NAME}_adaptor.py" -v --tb=short
- name: Test adaptor integration
run: |
echo "🔗 Testing $ADAPTOR_NAME integration..."
# Create test skill
mkdir -p test_skill/references
echo "# Test Skill" > test_skill/SKILL.md
echo "Test content" >> test_skill/SKILL.md
echo "# Reference" > test_skill/references/ref.md
# Test adaptor packaging
python3 << 'EOF'
import sys
import os
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.adaptors import get_adaptor
adaptor_name = os.environ['ADAPTOR_NAME']
adaptor = get_adaptor(adaptor_name)
package_path = adaptor.package(Path('test_skill'), Path('.'))
print(f"✅ Package created: {package_path}")
# Verify package exists
assert package_path.exists(), "Package file not created"
print(f"📦 Package size: {package_path.stat().st_size} bytes")
EOF
- name: Upload test package
uses: actions/upload-artifact@v3
with:
name: test-package-${{ env.ADAPTOR_NAME }}-py${{ env.PYTHON_VERSION }}
path: test_skill-${{ env.ADAPTOR_NAME }}.json
retention-days: 7
test-mcp-tools:
name: Test MCP Vector DB Tools
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Run MCP vector DB tests
run: |
echo "🧪 Testing MCP vector database tools..."
python -m pytest tests/test_mcp_vector_dbs.py -v --tb=short
test-week2-integration:
name: Week 2 Features Integration Test
runs-on: ubuntu-latest
needs: [test-adaptors, test-mcp-tools]
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Run Week 2 validation script
run: |
echo "🎯 Running Week 2 feature validation..."
python test_week2_features.py
- name: Create test summary
run: |
echo "## 🧪 Vector Database Testing Summary" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Adaptor Tests" >> $GITHUB_STEP_SUMMARY
echo "✅ Weaviate adaptor - All tests passed" >> $GITHUB_STEP_SUMMARY
echo "✅ Chroma adaptor - All tests passed" >> $GITHUB_STEP_SUMMARY
echo "✅ FAISS adaptor - All tests passed" >> $GITHUB_STEP_SUMMARY
echo "✅ Qdrant adaptor - All tests passed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### MCP Tools" >> $GITHUB_STEP_SUMMARY
echo "✅ 8/8 MCP vector DB tests passed" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Week 2 Integration" >> $GITHUB_STEP_SUMMARY
echo "✅ 6/6 feature tests passed" >> $GITHUB_STEP_SUMMARY
================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests
on:
push:
branches: [ main, development ]
pull_request:
branches: [ main, development ]
jobs:
lint:
name: Code Quality (Ruff & Mypy)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install ruff mypy
pip install -e .
- name: Run ruff linter
run: |
echo "Running ruff check..."
ruff check src/ tests/ --output-format=github
- name: Run ruff formatter check
run: |
echo "Checking code formatting..."
ruff format --check src/ tests/
- name: Run mypy type checker
run: |
echo "Running mypy type checker..."
mypy src/skill_seekers --show-error-codes --pretty
continue-on-error: true # Don't fail CI on mypy errors initially
test:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
python-version: ['3.10', '3.11', '3.12']
exclude:
# Exclude some combinations to speed up CI
- os: macos-latest
python-version: '3.10'
steps:
- uses: actions/checkout@v3
with:
submodules: recursive # Initialize api/configs_repo submodule
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install uv
run: |
curl -LsSf https://astral.sh/uv/install.sh | sh
echo "$HOME/.local/bin" >> $GITHUB_PATH
- name: Cache pip packages
uses: actions/cache@v3
with:
path: ~/.cache/pip
key: ${{ runner.os }}-pip-${{ hashFiles('**/requirements.txt', 'skill_seeker_mcp/requirements.txt') }}
restore-keys: |
${{ runner.os }}-pip-
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
if [ -f skill_seeker_mcp/requirements.txt ]; then pip install -r skill_seeker_mcp/requirements.txt; fi
# Install package in editable mode for tests (required for src/ layout)
pip install -e .
- name: Run CLI tests
run: |
python -m pytest tests/test_scraper_features.py -v
python -m pytest tests/test_config_validation.py -v
python -m pytest tests/test_integration.py -v
- name: Run MCP server tests
run: |
python -m pytest tests/test_mcp_server.py -v
- name: Generate coverage report
run: |
python -m pytest tests/ --cov=src/skill_seekers --cov-report=xml --cov-report=term
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
file: ./coverage.xml
flags: unittests
name: codecov-umbrella
fail_ci_if_error: false
# Summary job that provides a single status check for branch protection.
# The job name MUST match the required status check in the branch
# protection rules. GitHub reports status checks using job names
# (not the workflow name), so the required check "Tests" will only
# be satisfied if a job with exactly that name exists and succeeds.
tests-complete:
name: Tests
needs: [lint, test]
runs-on: ubuntu-latest
if: always()
steps:
- name: Check all results
run: |
if [ "${{ needs.lint.result }}" != "success" ]; then
echo "❌ Code quality checks failed!"
exit 1
fi
if [ "${{ needs.test.result }}" != "success" ]; then
echo "❌ Tests failed!"
exit 1
fi
echo "✅ All checks passed!"
================================================
FILE: .github/workflows/vector-db-export.yml
================================================
name: Vector Database Export
on:
workflow_dispatch:
inputs:
skill_name:
description: 'Skill name to export (e.g., react, django, godot)'
required: true
type: string
targets:
description: 'Vector databases to export (comma-separated: weaviate,chroma,faiss,qdrant or "all")'
required: true
default: 'all'
type: string
config_path:
description: 'Path to config file (optional, auto-detected from skill_name if not provided)'
required: false
type: string
schedule:
# Run weekly on Sunday at 2 AM UTC for popular frameworks
- cron: '0 2 * * 0'
jobs:
export:
name: Export to Vector Databases
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# For scheduled runs, export popular frameworks
skill: ${{ github.event_name == 'schedule' && fromJson('["react", "django", "godot", "fastapi"]') || fromJson(format('["{0}"]', github.event.inputs.skill_name)) }}
env:
SKILL_NAME: ${{ matrix.skill }}
TARGETS_INPUT: ${{ github.event.inputs.targets }}
CONFIG_PATH_INPUT: ${{ github.event.inputs.config_path }}
steps:
- uses: actions/checkout@v3
with:
submodules: recursive
- name: Set up Python 3.12
uses: actions/setup-python@v4
with:
python-version: '3.12'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -e .
- name: Determine config path
id: config
run: |
if [ -n "$CONFIG_PATH_INPUT" ]; then
echo "path=$CONFIG_PATH_INPUT" >> $GITHUB_OUTPUT
else
echo "path=configs/$SKILL_NAME.json" >> $GITHUB_OUTPUT
fi
- name: Check if config exists
id: check_config
run: |
CONFIG_FILE="${{ steps.config.outputs.path }}"
if [ -f "$CONFIG_FILE" ]; then
echo "exists=true" >> $GITHUB_OUTPUT
else
echo "exists=false" >> $GITHUB_OUTPUT
echo "⚠️ Config not found: $CONFIG_FILE"
fi
- name: Scrape documentation
if: steps.check_config.outputs.exists == 'true'
run: |
echo "📥 Scraping documentation for $SKILL_NAME..."
skill-seekers scrape --config "${{ steps.config.outputs.path }}" --max-pages 100
continue-on-error: true
- name: Determine export targets
id: targets
run: |
TARGETS="${TARGETS_INPUT:-all}"
if [ "$TARGETS" = "all" ]; then
echo "list=weaviate chroma faiss qdrant" >> $GITHUB_OUTPUT
else
echo "list=$(echo "$TARGETS" | tr ',' ' ')" >> $GITHUB_OUTPUT
fi
- name: Export to vector databases
if: steps.check_config.outputs.exists == 'true'
env:
EXPORT_TARGETS: ${{ steps.targets.outputs.list }}
run: |
SKILL_DIR="output/$SKILL_NAME"
if [ ! -d "$SKILL_DIR" ]; then
echo "❌ Skill directory not found: $SKILL_DIR"
exit 1
fi
echo "📦 Exporting $SKILL_NAME to vector databases..."
for target in $EXPORT_TARGETS; do
echo ""
echo "🔹 Exporting to $target..."
# Use adaptor directly via CLI
python -c "
import sys
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.adaptors import get_adaptor
adaptor = get_adaptor('$target')
package_path = adaptor.package(Path('$SKILL_DIR'), Path('output'))
print(f'✅ Exported to {package_path}')
"
if [ $? -eq 0 ]; then
echo "✅ $target export complete"
else
echo "❌ $target export failed"
fi
done
- name: Generate quality report
if: steps.check_config.outputs.exists == 'true'
run: |
SKILL_DIR="output/$SKILL_NAME"
if [ -d "$SKILL_DIR" ]; then
echo "📊 Generating quality metrics..."
python -c "
import sys
from pathlib import Path
sys.path.insert(0, 'src')
from skill_seekers.cli.quality_metrics import QualityAnalyzer
analyzer = QualityAnalyzer(Path('$SKILL_DIR'))
report = analyzer.generate_report()
formatted = analyzer.format_report(report)
print(formatted)
# Save to file
with open('quality_report_${SKILL_NAME}.txt', 'w') as f:
f.write(formatted)
"
fi
continue-on-error: true
- name: Upload vector database exports
if: steps.check_config.outputs.exists == 'true'
uses: actions/upload-artifact@v3
with:
name: ${{ env.SKILL_NAME }}-vector-exports
path: |
output/${{ env.SKILL_NAME }}-*.json
retention-days: 30
- name: Upload quality report
if: steps.check_config.outputs.exists == 'true'
uses: actions/upload-artifact@v3
with:
name: ${{ env.SKILL_NAME }}-quality-report
path: quality_report_${{ env.SKILL_NAME }}.txt
retention-days: 30
continue-on-error: true
- name: Create export summary
if: steps.check_config.outputs.exists == 'true'
env:
EXPORT_TARGETS: ${{ steps.targets.outputs.list }}
run: |
echo "## 📦 Vector Database Export Summary: $SKILL_NAME" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
for target in $EXPORT_TARGETS; do
FILE="output/${SKILL_NAME}-${target}.json"
if [ -f "$FILE" ]; then
SIZE=$(du -h "$FILE" | cut -f1)
echo "✅ **$target**: $SIZE" >> $GITHUB_STEP_SUMMARY
else
echo "❌ **$target**: Export failed" >> $GITHUB_STEP_SUMMARY
fi
done
echo "" >> $GITHUB_STEP_SUMMARY
if [ -f "quality_report_${SKILL_NAME}.txt" ]; then
echo "### 📊 Quality Metrics" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
head -30 "quality_report_${SKILL_NAME}.txt" >> $GITHUB_STEP_SUMMARY
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
fi
================================================
FILE: .gitignore
================================================
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
# Virtual Environment
venv/
ENV/
env/
# Output directory
output/
*.zip
# Skill Seekers cache (intermediate files)
.skillseeker-cache/
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db
# Backups
*.backup
# Testing artifacts
.pytest_cache/
.coverage
htmlcov/
.tox/
*.cover
.hypothesis/
.mypy_cache/
.ruff_cache/
# Build artifacts
.build/
skill-seekers-configs/
.claude/skills
.mcp.json
!distribution/claude-plugin/.mcp.json
settings.json
USER_GUIDE.md
================================================
FILE: .gitmodules
================================================
[submodule "api/configs_repo"]
path = api/configs_repo
url = https://github.com/yusufkaraaslan/skill-seekers-configs.git
================================================
FILE: =0.24.0
================================================
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try 'pacman -S
python-xyz', where xyz is the package you are trying to
install.
If you wish to install a non-Arch-packaged Python package,
create a virtual environment using 'python -m venv path/to/venv'.
Then use path/to/venv/bin/python and path/to/venv/bin/pip.
If you wish to install a non-Arch packaged Python application,
it may be easiest to use 'pipx install xyz', which will manage a
virtual environment for you. Make sure you have python-pipx
installed via pacman.
note: If you believe this is a mistake, please contact your Python installation or OS distribution provider. You can override this, at the risk of breaking your Python installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
================================================
FILE: AGENTS.md
================================================
# AGENTS.md - Skill Seekers
Concise reference for AI coding agents. Skill Seekers is a Python CLI tool (v3.3.0) that converts documentation sites, GitHub repos, PDFs, videos, notebooks, wikis, and more into AI-ready skills for 16+ LLM platforms and RAG pipelines.
## Setup
```bash
# REQUIRED before running tests (src/ layout — tests hard-exit if package not installed)
pip install -e .
# With dev tools (pytest, ruff, mypy, coverage)
pip install -e ".[dev]"
# With all optional deps
pip install -e ".[all]"
```
Note: `tests/conftest.py` checks that `skill_seekers` is importable and calls `sys.exit(1)` if not. Always install in editable mode first.
## Build / Test / Lint Commands
```bash
# Run ALL tests (never skip tests — all must pass before commits)
pytest tests/ -v
# Run a single test file
pytest tests/test_scraper_features.py -v
# Run a single test function
pytest tests/test_scraper_features.py::test_detect_language -v
# Run a single test class method
pytest tests/test_adaptors/test_claude_adaptor.py::TestClaudeAdaptor::test_package -v
# Skip slow/integration tests
pytest tests/ -v -m "not slow and not integration"
# With coverage
pytest tests/ --cov=src/skill_seekers --cov-report=term
# Lint (ruff)
ruff check src/ tests/
ruff check src/ tests/ --fix
# Format (ruff)
ruff format --check src/ tests/
ruff format src/ tests/
# Type check (mypy)
mypy src/skill_seekers --show-error-codes --pretty
```
**Pytest config** (from pyproject.toml): `addopts = "-v --tb=short --strict-markers"`, `asyncio_mode = "auto"`, `asyncio_default_fixture_loop_scope = "function"`.
**Test markers:** `slow`, `integration`, `e2e`, `venv`, `bootstrap`, `benchmark`, `asyncio`.
**Async tests:** use `@pytest.mark.asyncio`; asyncio_mode is `auto` so the decorator is often implicit.
**Test count:** 123 test files (107 in `tests/`, 16 in `tests/test_adaptors/`).
## Code Style
### Formatting Rules (ruff — from pyproject.toml)
- **Line length:** 100 characters
- **Target Python:** 3.10+
- **Enabled lint rules:** E, W, F, I, B, C4, UP, ARG, SIM
- **Ignored rules:** E501 (line length handled by formatter), F541 (f-string style), ARG002 (unused method args for interface compliance), B007 (intentional unused loop vars), I001 (formatter handles imports), SIM114 (readability preference)
### Imports
- Sort with isort (via ruff); `skill_seekers` is first-party
- Standard library → third-party → first-party, separated by blank lines
- Use `from __future__ import annotations` only if needed for forward refs
- Guard optional imports with try/except ImportError (see `adaptors/__init__.py` pattern):
```python
try:
from .claude import ClaudeAdaptor
from .minimax import MiniMaxAdaptor
except ImportError:
ClaudeAdaptor = None
MiniMaxAdaptor = None
```
### Naming Conventions
- **Files:** `snake_case.py` (e.g., `source_detector.py`, `config_validator.py`)
- **Classes:** `PascalCase` (e.g., `SkillAdaptor`, `ClaudeAdaptor`, `SourceDetector`)
- **Functions/methods:** `snake_case` (e.g., `get_adaptor()`, `detect_language()`)
- **Constants:** `UPPER_CASE` (e.g., `ADAPTORS`, `DEFAULT_CHUNK_TOKENS`, `VALID_SOURCE_TYPES`)
- **Private:** prefix with `_` (e.g., `_read_existing_content()`, `_validate_unified()`)
### Type Hints
- Gradual typing — add hints where practical, not enforced everywhere
- Use modern syntax: `str | None` not `Optional[str]`, `list[str]` not `List[str]`
- MyPy config: `disallow_untyped_defs = false`, `check_untyped_defs = true`, `ignore_missing_imports = true`
- Tests are excluded from strict type checking (`disallow_untyped_defs = false`, `check_untyped_defs = false` for `tests.*`)
### Docstrings
- Module-level docstring on every file (triple-quoted, describes purpose)
- Google-style docstrings for public functions/classes
- Include `Args:`, `Returns:`, `Raises:` sections where useful
### Error Handling
- Use specific exceptions, never bare `except:`
- Provide helpful error messages with context
- Use `raise ValueError(...)` for invalid arguments, `raise RuntimeError(...)` for state errors
- Guard optional dependency imports with try/except and give clear install instructions on failure
- Chain exceptions with `raise ... from e` when wrapping
### Suppressing Lint Warnings
- Use inline `# noqa: XXXX` comments (e.g., `# noqa: F401` for re-exports, `# noqa: ARG001` for required but unused params)
## Project Layout
```
src/skill_seekers/ # Main package (src/ layout)
cli/ # CLI commands and entry points (96 files)
adaptors/ # Platform adaptors (Strategy pattern, inherit SkillAdaptor)
arguments/ # CLI argument definitions (one per source type)
parsers/ # Subcommand parsers (one per source type)
storage/ # Cloud storage (inherit BaseStorageAdaptor)
main.py # Unified CLI entry point (COMMAND_MODULES dict)
source_detector.py # Auto-detects source type from user input
create_command.py # Unified `create` command routing
config_validator.py # VALID_SOURCE_TYPES set + per-type validation
unified_scraper.py # Multi-source orchestrator (scraped_data + dispatch)
unified_skill_builder.py # Pairwise synthesis + generic merge
mcp/ # MCP server (FastMCP + legacy)
tools/ # MCP tool implementations by category (10 files)
sync/ # Sync monitoring (Pydantic models)
benchmark/ # Benchmarking framework
embedding/ # FastAPI embedding server
workflows/ # 67 YAML workflow presets
_version.py # Reads version from pyproject.toml
tests/ # 120 test files (pytest)
configs/ # Preset JSON scraping configs
docs/ # Documentation (guides, integrations, architecture)
```
## Key Patterns
**Adaptor (Strategy) pattern** — all platform logic in `cli/adaptors/`. Inherit `SkillAdaptor`, implement `format_skill_md()`, `package()`, `upload()`. Register in `adaptors/__init__.py` ADAPTORS dict.
**Scraper pattern** — each source type has: `cli/<type>_scraper.py` (with `<Type>ToSkillConverter` class + `main()`), `arguments/<type>.py`, `parsers/<type>_parser.py`. Register in `parsers/__init__.py` PARSERS list, `main.py` COMMAND_MODULES dict, `config_validator.py` VALID_SOURCE_TYPES set.
**Unified pipeline** — `unified_scraper.py` dispatches to per-type `_scrape_<type>()` methods. `unified_skill_builder.py` uses pairwise synthesis for docs+github+pdf combos and `_generic_merge()` for all other combinations.
**MCP tools** — grouped in `mcp/tools/` by category. `scrape_generic_tool` handles all new source types.
**CLI subcommands** — git-style in `cli/main.py`. Each delegates to a module's `main()` function.
**Supported source types (17):** documentation (web), github, pdf, word, epub, video, local codebase, jupyter, html, openapi, asciidoc, pptx, rss, manpage, confluence, notion, chat (slack/discord). Each detected automatically by `source_detector.py`.
## Git Workflow
- **`main`** — production, protected
- **`development`** — default PR target, active dev
- Feature branches created from `development`
## Pre-commit Checklist
```bash
ruff check src/ tests/
ruff format --check src/ tests/
pytest tests/ -v -x # stop on first failure
```
Never commit API keys. Use env vars: `ANTHROPIC_API_KEY`, `GOOGLE_API_KEY`, `OPENAI_API_KEY`, `GITHUB_TOKEN`.
## CI
GitHub Actions (7 workflows in `.github/workflows/`):
- **tests.yml** — ruff + mypy lint job, then pytest matrix (Ubuntu + macOS, Python 3.10-3.12) with Codecov upload
- **release.yml** — tag-triggered: tests → version verification → PyPI publish via `uv build`
- **test-vector-dbs.yml** — tests vector DB adaptors (weaviate, chroma, faiss, qdrant)
- **docker-publish.yml** — multi-platform Docker builds (amd64, arm64) for CLI + MCP images
- **quality-metrics.yml** — quality analysis with configurable threshold
- **scheduled-updates.yml** — weekly skill updates for popular frameworks
- **vector-db-export.yml** — weekly vector DB exports
================================================
FILE: BULLETPROOF_QUICKSTART.md
================================================
# Bulletproof Quick Start Guide
**Target Audience:** Complete beginners | Never used Python/git before? Start here!
**Time:** 15-30 minutes total (including all installations)
**Result:** Working Skill Seeker installation + your first Claude skill created
---
## 📋 What You'll Need
Before starting, you need:
- A computer (macOS, Linux, or Windows with WSL)
- Internet connection
- 30 minutes of time
That's it! We'll install everything else together.
---
## Step 1: Install Python (5 minutes)
### Check if You Already Have Python
Open Terminal (macOS/Linux) or Command Prompt (Windows) and type:
```bash
python3 --version
```
**✅ If you see:** `Python 3.10.x` or `Python 3.11.x` or higher → **Skip to Step 2!**
**❌ If you see:** `command not found` or version less than 3.10 → **Continue below**
### Install Python
#### macOS:
```bash
# Install Homebrew (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Python
brew install python3
```
**Verify:**
```bash
python3 --version
# Should show: Python 3.11.x or similar
```
#### Linux (Ubuntu/Debian):
```bash
sudo apt update
sudo apt install python3 python3-pip
```
**Verify:**
```bash
python3 --version
pip3 --version
```
#### Windows:
1. Download Python from: https://www.python.org/downloads/
2. Run installer
3. **IMPORTANT:** Check "Add Python to PATH" during installation
4. Open Command Prompt and verify:
```bash
python --version
```
**✅ Success looks like:**
```
Python 3.11.5
```
---
## Step 2: Install Git (3 minutes)
### Check if You Have Git
```bash
git --version
```
**✅ If you see:** `git version 2.x.x` → **Skip to Step 3!**
**❌ If not installed:**
#### macOS:
```bash
brew install git
```
#### Linux:
```bash
sudo apt install git
```
#### Windows:
Download from: https://git-scm.com/download/win
**Verify:**
```bash
git --version
# Should show: git version 2.x.x
```
---
## Step 3: Get Skill Seeker (2 minutes)
### Choose Where to Put It
Pick a location for the project. Good choices:
- macOS/Linux: `~/Projects/` or `~/Documents/`
- Note: `~` means your home directory (`$HOME` or `/Users/yourname` on macOS, `/home/yourname` on Linux)
- Windows: `C:\Users\YourName\Projects\`
### Clone the Repository
```bash
# Create Projects directory (if it doesn't exist)
mkdir -p ~/Projects
cd ~/Projects
# Clone Skill Seeker
git clone https://github.com/yusufkaraaslan/Skill_Seekers.git
# Enter the directory
cd Skill_Seekers
```
**✅ Success looks like:**
```
Cloning into 'Skill_Seekers'...
remote: Enumerating objects: 245, done.
remote: Counting objects: 100% (245/245), done.
```
**Verify you're in the right place:**
```bash
pwd
# Should show something like:
# macOS: /Users/yourname/Projects/Skill_Seekers
# Linux: /home/yourname/Projects/Skill_Seekers
# (Replace 'yourname' with YOUR actual username)
ls
# Should show: README.md, cli/, mcp/, configs/, etc.
```
**❌ If `git clone` fails:**
```bash
# Check internet connection
ping google.com
# Or download ZIP manually:
# https://github.com/yusufkaraaslan/Skill_Seekers/archive/refs/heads/main.zip
# Then unzip and cd into it
```
---
## Step 4: Setup Virtual Environment & Install Skill Seekers (3 minutes)
A virtual environment keeps Skill Seeker's dependencies isolated and prevents conflicts.
```bash
# Make sure you're in the Skill_Seekers directory
cd ~/Projects/Skill_Seekers # ~ means your home directory ($HOME)
# Adjust if you chose a different location
# Create virtual environment
python3 -m venv venv
# Activate it
source venv/bin/activate # macOS/Linux
# Windows users: venv\Scripts\activate
```
**✅ Success looks like:**
```
(venv) username@computer Skill_Seekers %
```
Notice `(venv)` appears in your prompt - this means the virtual environment is active!
```bash
# Now install Skill Seekers package (this installs all dependencies automatically)
pip install -e .
```
**✅ Success looks like:**
```
Successfully installed skill-seekers-2.7.4 requests-2.32.5 beautifulsoup4-4.14.2 anthropic-0.76.0 ...
Obtaining file:///path/to/Skill_Seekers
Installing collected packages: skill-seekers
Successfully installed skill-seekers
```
**What just happened?**
- `pip install -e .` installs the package in "editable" mode
- The `.` means "current directory" (where pyproject.toml is)
- This automatically installs ALL required dependencies
- This registers the `skill-seekers` command so you can use it from anywhere
- The `-e` flag means changes to the code take effect immediately (useful for development)
**Important Notes:**
- **Every time** you open a new terminal to use Skill Seeker, run `source venv/bin/activate` first (Windows: `venv\Scripts\activate`)
- You'll know it's active when you see `(venv)` in your terminal prompt
- To deactivate later: just type `deactivate`
**❌ If python3 not found:**
```bash
# Try without the 3
python -m venv venv
```
**❌ If permission denied:**
```bash
# Virtual environment approach doesn't need sudo - you might have the wrong path
# Make sure you're in the Skill_Seekers directory:
pwd
# Should show something like:
# macOS: /Users/yourname/Projects/Skill_Seekers
# Linux: /home/yourname/Projects/Skill_Seekers
# (Replace 'yourname' with YOUR actual username)
```
**❌ If "pip: command not found":**
```bash
# Try with python -m pip instead
python3 -m pip install -e .
```
---
## Step 5: Test Your Installation (1 minute)
Let's make sure everything works:
```bash
# Test the main script can run
skill-seekers scrape --help
```
**✅ Success looks like:**
```
usage: doc_scraper.py [-h] [--config CONFIG] [--interactive] ...
```
**❌ If you see "No such file or directory":**
```bash
# Check you're in the right directory
pwd
# Should show path ending in /Skill_Seekers
# List files
ls cli/
# Should show: doc_scraper.py, estimate_pages.py, etc.
```
---
## Step 6: Create Your First Skill! (5-10 minutes)
Let's create a simple skill using a preset configuration.
### Option A: Small Test (Recommended First Time)
```bash
# Create a config for a small site first
cat > configs/test.json << 'EOF'
{
"name": "test-skill",
"description": "Test skill creation",
"base_url": "https://tailwindcss.com/docs/installation",
"selectors": {
"main_content": "#content-wrapper",
"title": "h1, h2, h3",
"code_blocks": "pre code"
},
"max_pages": 5,
"rate_limit": 0.5
}
EOF
# Run the scraper
skill-seekers scrape --config configs/test.json
```
**Note for Windows users:** The `cat > file << 'EOF'` syntax doesn't work in PowerShell. Instead, create the file manually:
```powershell
# In PowerShell, create configs/test.json with this content:
@"
{
"name": "test-skill",
"description": "Test skill creation",
"base_url": "https://tailwindcss.com/docs/installation",
"selectors": {
"main_content": "#content-wrapper",
"title": "h1, h2, h3",
"code_blocks": "pre code"
},
"max_pages": 5,
"rate_limit": 0.5
}
"@ | Out-File -FilePath configs/test.json -Encoding utf8
# Then run the scraper
skill-seekers scrape --config configs/test.json
```
**What happens:**
1. Scrapes 5 pages from Tailwind CSS docs
2. Creates `output/test-skill/` directory
3. Generates SKILL.md and reference files
**⏱️ Time:** ~30 seconds
**✅ Success looks like:**
```
Scraping: https://tailwindcss.com/docs/installation
Page 1/5: Installation
Page 2/5: Editor Setup
...
✅ Skill created at: output/test-skill/
```
### Option B: Full Example (React Docs)
```bash
# Use the React preset
skill-seekers scrape --config configs/react.json --max-pages 50
```
**⏱️ Time:** ~5 minutes
**What you get:**
- `output/react/SKILL.md` - Main skill file
- `output/react/references/` - Organized documentation
### Verify It Worked
```bash
# Check the output
ls output/test-skill/
# Should show: SKILL.md, references/, scripts/, assets/
# Look at the generated skill
head output/test-skill/SKILL.md
```
---
## Step 7: Package for Claude (30 seconds)
```bash
# Package the skill
skill-seekers package output/test-skill/
```
**✅ Success looks like:**
```
✅ Skill packaged successfully!
📦 Created: output/test-skill.zip
📏 Size: 45.2 KB
Ready to upload to Claude AI!
```
**Now you have:** `output/test-skill.zip` ready to upload to Claude!
---
## Step 8: Upload to Claude (2 minutes)
1. Go to https://claude.ai
2. Click your profile → Settings
3. Click "Knowledge" or "Skills"
4. Click "Upload Skill"
5. Select `output/test-skill.zip`
6. Done! Claude can now use this skill
---
## 🎉 Success! What's Next?
You now have a working Skill Seeker installation! Here's what you can do:
### Try Other Presets
```bash
# See all available presets
ls configs/
# Try Vue.js
skill-seekers scrape --config configs/vue.json --max-pages 50
# Try Django
skill-seekers scrape --config configs/django.json --max-pages 50
```
### Try Other Source Types (17 Supported!)
```bash
# Auto-detect source type with the `create` command
skill-seekers create https://docs.example.com # Documentation
skill-seekers create facebook/react # GitHub repo
skill-seekers create manual.pdf # PDF
skill-seekers create report.docx # Word document
skill-seekers create book.epub # EPUB book
skill-seekers create analysis.ipynb # Jupyter Notebook
skill-seekers create spec.yaml # OpenAPI/Swagger spec
skill-seekers create slides.pptx # PowerPoint
# Or use specific subcommands
skill-seekers video https://youtube.com/watch?v=abc # Video
skill-seekers confluence --space DOCS # Confluence wiki
skill-seekers notion --database DB_ID # Notion
skill-seekers rss https://blog.example.com/feed.xml # RSS feed
skill-seekers manpage grep.1 # Man page
skill-seekers chat --platform slack --export-dir ./export # Slack/Discord
```
### Create Custom Skills
```bash
# Interactive mode - answer questions
skill-seekers scrape --interactive
# Or create config for any website
skill-seekers scrape \
--name myframework \
--url https://docs.myframework.com/ \
--description "My favorite framework"
```
### Where to Save Custom Configs
You have three options for placing your custom config files:
**Option 1: User Config Directory (Recommended)**
```bash
# Create config in your home directory
mkdir -p ~/.config/skill-seekers/configs
cat > ~/.config/skill-seekers/configs/myproject.json << 'EOF'
{
"name": "myproject",
"base_url": "https://docs.myproject.com/",
"max_pages": 50
}
EOF
# Use it
skill-seekers scrape --config myproject.json
```
**Option 2: Current Directory (Project-Specific)**
```bash
# Create config in your project
mkdir -p configs
nano configs/myproject.json
# Use it
skill-seekers scrape --config configs/myproject.json
```
**Option 3: Absolute Path**
```bash
# Use any file path
skill-seekers scrape --config /full/path/to/config.json
```
The tool searches in this order: exact path → `./configs/` → `~/.config/skill-seekers/configs/` → API presets
### Use with Claude Code (Advanced)
If you have Claude Code installed:
```bash
# One-time setup
./setup_mcp.sh
# Then use natural language in Claude Code:
# "Generate a skill for Svelte docs"
# "Package the skill at output/svelte/"
```
**See:** [docs/MCP_SETUP.md](docs/MCP_SETUP.md) for full MCP setup
---
## 🔧 Troubleshooting
### "Command not found" errors
**Problem:** `python3: command not found`
**Solution:** Python not installed or not in PATH
- macOS/Linux: Reinstall Python with brew/apt
- Windows: Reinstall Python, check "Add to PATH"
- Try `python` instead of `python3`
### "Permission denied" errors
**Problem:** Can't install packages or run scripts
**Solution:**
```bash
# Use --user flag
pip3 install --user requests beautifulsoup4
# Or make script executable
chmod +x cli/doc_scraper.py
```
### "No such file or directory"
**Problem:** Can't find cli/doc_scraper.py
**Solution:** You're not in the right directory
```bash
# Go to the Skill_Seekers directory
cd ~/Projects/Skill_Seekers # Adjust your path
# Verify
ls cli/
# Should show doc_scraper.py
```
### "ModuleNotFoundError" or "command not found: skill-seekers"
**Problem:** Package not installed or virtual environment not activated
**Solution:**
```bash
# Make sure virtual environment is activated (you should see (venv) in prompt)
source venv/bin/activate # macOS/Linux
# Windows: venv\Scripts\activate
# Install the package
pip install -e .
# If that fails, try:
python3 -m pip install -e .
```
### Scraping is slow or fails
**Problem:** Takes forever or gets errors
**Solution:**
```bash
# Use smaller max_pages for testing
skill-seekers scrape --config configs/react.json --max-pages 10
# Check internet connection
ping google.com
# Check the website is accessible
curl -I https://docs.yoursite.com
```
### Still stuck?
1. **Check our detailed troubleshooting guide:** [TROUBLESHOOTING.md](TROUBLESHOOTING.md)
2. **Open an issue:** https://github.com/yusufkaraaslan/Skill_Seekers/issues
3. **Include this info:**
- Operating system (macOS 13, Ubuntu 22.04, Windows 11, etc.)
- Python version (`python3 --version`)
- Full error message
- What command you ran
---
## 📚 Next Steps
- **Read the full README:** [README.md](README.md)
- **Learn about presets:** [configs/](configs/)
- **Try MCP integration:** [docs/MCP_SETUP.md](docs/MCP_SETUP.md)
- **Advanced usage:** [docs/](docs/)
---
## ✅ Quick Reference
```bash
# Your typical workflow:
# 1. Create/use a config
skill-seekers scrape --config configs/react.json --max-pages 50
# 2. Package it
skill-seekers package output/react/
# 3. Upload output/react.zip to Claude
# Done! 🎉
```
**Common locations:**
- **Configs:** `configs/*.json`
- **Output:** `output/skill-name/`
- **Packaged skills:** `output/skill-name.zip`
**Time estimates:**
- Small skill (5-10 pages): 30 seconds
- Medium skill (50-100 pages): 3-5 minutes
- Large skill (500+ pages): 15-30 minutes
---
**Still confused?** That's okay! Open an issue and we'll help you get started: https://github.com/yusufkaraaslan/Skill_Seekers/issues/new
================================================
FILE: CHANGELOG.md
================================================
# Changelog
All notable changes to Skill Seeker will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [3.3.0] - 2026-03-16
**Theme:** 10 new source types (17 total), EPUB unified integration, sync-config command, performance optimizations, 12 README translations, and 19 bug fixes. 117 files changed, +41,588 lines since v3.2.0.
### Supported Source Types (17)
| # | Type | CLI Command | Config Type | Auto-Detection |
|---|------|-------------|-------------|----------------|
| 1 | Documentation (web) | `scrape` / `create <url>` | `documentation` | HTTP/HTTPS URLs |
| 2 | GitHub repository | `github` / `create owner/repo` | `github` | `owner/repo` or github.com URLs |
| 3 | PDF document | `pdf` / `create file.pdf` | `pdf` | `.pdf` extension |
| 4 | Word document | `word` / `create file.docx` | `word` | `.docx` extension |
| 5 | EPUB e-book | `epub` / `create file.epub` | `epub` | `.epub` extension |
| 6 | Video | `video` / `create <url/file>` | `video` | YouTube/Vimeo URLs, video extensions |
| 7 | Local codebase | `analyze` / `create ./path` | `local` | Directory paths |
| 8 | Jupyter Notebook | `jupyter` / `create file.ipynb` | `jupyter` | `.ipynb` extension |
| 9 | Local HTML | `html` / `create file.html` | `html` | `.html`/`.htm` extensions |
| 10 | OpenAPI/Swagger | `openapi` / `create spec.yaml` | `openapi` | `.yaml`/`.yml` with OpenAPI content |
| 11 | AsciiDoc | `asciidoc` / `create file.adoc` | `asciidoc` | `.adoc`/`.asciidoc` extensions |
| 12 | PowerPoint | `pptx` / `create file.pptx` | `pptx` | `.pptx` extension |
| 13 | RSS/Atom feed | `rss` / `create feed.rss` | `rss` | `.rss`/`.atom` extensions |
| 14 | Man pages | `manpage` / `create cmd.1` | `manpage` | `.1`–`.8`/`.man` extensions |
| 15 | Confluence wiki | `confluence` | `confluence` | API or export directory |
| 16 | Notion pages | `notion` | `notion` | API or export directory |
| 17 | Slack/Discord chat | `chat` | `chat` | Export directory or API |
### Added
#### 10 New Skill Source Types (17 total)
Skill Seekers now supports 17 source types — up from 7. Every new type is fully integrated into the CLI (`skill-seekers <type>`), `create` command auto-detection, unified multi-source configs, config validation, the MCP server, and the skill builder.
- **Jupyter Notebook** — `skill-seekers jupyter --notebook file.ipynb` or `skill-seekers create file.ipynb`
- Extracts markdown cells, code cells with outputs, kernel metadata, imports, and language detection
- Handles single files and directories of notebooks; filters `.ipynb_checkpoints`
- Optional dependency: `pip install "skill-seekers[jupyter]"` (nbformat)
- Entry point: `skill-seekers-jupyter`
- **Local HTML** — `skill-seekers html --html-path file.html` or `skill-seekers create file.html`
- Parses HTML using BeautifulSoup with smart main content detection (`<article>`, `<main>`, `.content`, largest div)
- Extracts headings, code blocks, tables (to markdown), images, links; converts inline HTML to markdown
- Handles single files and directories; supports `.html`, `.htm`, `.xhtml` extensions
- No extra dependencies (BeautifulSoup is a core dep)
- **OpenAPI/Swagger** — `skill-seekers openapi --spec spec.yaml` or `skill-seekers create spec.yaml`
- Parses OpenAPI 3.0/3.1 and Swagger 2.0 specs from YAML or JSON (local files or URLs via `--spec-url`)
- Extracts endpoints, parameters, request/response schemas, security schemes, tags
- Resolves `$ref` references with circular reference protection; handles `allOf`/`oneOf`/`anyOf`
- Groups endpoints by tags; generates comprehensive API reference markdown
- Source detection sniffs YAML file content for `openapi:` or `swagger:` keys (avoids false positives on non-API YAML files)
- Optional dependency: `pip install "skill-seekers[openapi]"` (pyyaml — already a core dep, guard added for safety)
- **AsciiDoc** — `skill-seekers asciidoc --asciidoc-path file.adoc` or `skill-seekers create file.adoc`
- Regex-based parser (no external library required) with optional `asciidoc` library support
- Extracts headings (= through =====), `[source,lang]` code blocks, `|===` tables, admonitions (NOTE/TIP/WARNING/IMPORTANT/CAUTION), and `include::` directives
- Converts AsciiDoc formatting to markdown; handles single files and directories
- Optional dependency: `pip install "skill-seekers[asciidoc]"` (asciidoc library for advanced rendering)
- **PowerPoint (.pptx)** — `skill-seekers pptx --pptx file.pptx` or `skill-seekers create file.pptx`
- Extracts slide text, speaker notes, tables, images (with alt text), and grouped shapes
- Detects code blocks by monospace font analysis (30+ font families)
- Groups slides into sections by layout type; handles single files and directories
- Optional dependency: `pip install "skill-seekers[pptx]"` (python-pptx)
- **RSS/Atom Feeds** — `skill-seekers rss --feed-url <url>` / `--feed-path file.rss` or `skill-seekers create feed.rss`
- Parses RSS 2.0, RSS 1.0, and Atom feeds via feedparser
- Optionally follows article links (`--follow-links`, default on) to scrape full page content using BeautifulSoup
- Extracts article titles, summaries, authors, dates, categories; configurable `--max-articles` (default 50)
- Source detection matches `.rss` and `.atom` extensions (`.xml` excluded to avoid false positives)
- Optional dependency: `pip install "skill-seekers[rss]"` (feedparser)
- **Man Pages** — `skill-seekers manpage --man-names git,curl` / `--man-path dir/` or `skill-seekers create git.1`
- Extracts man pages by running `man` command via subprocess or reading `.1`–`.8`/`.man` files directly
- Handles gzip/bzip2/xz compressed man files; strips troff/groff formatting (backspace overstriking, macros, font escapes)
- Parses structured sections (NAME, SYNOPSIS, DESCRIPTION, OPTIONS, EXAMPLES, SEE ALSO)
- Source detection uses basename heuristic to avoid false positives on log rotation files (e.g., `access.log.1`)
- No external dependencies (stdlib only)
- **Confluence** — `skill-seekers confluence --base-url <url> --space-key <key>` or `--export-path dir/`
- API mode: fetches pages from Confluence REST API with pagination (`atlassian-python-api`)
- Export mode: parses Confluence HTML/XML export directories
- Extracts page content, code/panel/info/warning macros, page hierarchy, tables
- Optional dependency: `pip install "skill-seekers[confluence]"` (atlassian-python-api)
- **Notion** — `skill-seekers notion --database-id <id>` / `--page-id <id>` or `--export-path dir/`
- API mode: fetches pages via Notion API with support for 20+ block types (paragraph, heading, code, callout, toggle, table, etc.)
- Export mode: parses Notion Markdown/CSV export directories
- Extracts rich text with annotations (bold, italic, code, links), 16+ property types for database entries
- Optional dependency: `pip install "skill-seekers[notion]"` (notion-client)
- **Slack/Discord Chat** — `skill-seekers chat --export-path dir/` or `--token <token> --channel <channel>`
- Slack: parses workspace JSON exports or fetches via Slack Web API (`slack_sdk`)
- Discord: parses DiscordChatExporter JSON or fetches via Discord HTTP API
- Extracts messages, code snippets (fenced blocks), shared URLs, threads, reactions, attachments
- Generates per-channel summaries and topic categorization
- Optional dependency: `pip install "skill-seekers[chat]"` (slack-sdk)
#### EPUB Unified Pipeline Integration
- **EPUB (.epub) input support** via `skill-seekers create book.epub` or `skill-seekers epub --epub book.epub`
- Extracts chapters, metadata (Dublin Core), code blocks, images, and tables from EPUB 2 and EPUB 3 files
- DRM detection with clear error messages (Adobe ADEPT, Apple FairPlay, Readium LCP)
- Font obfuscation correctly identified as non-DRM
- EPUB 3 TOC bug workaround (`ignore_ncx` option)
- `--help-epub` flag for EPUB-specific help
- Optional dependency: `pip install "skill-seekers[epub]"` (ebooklib)
- 107 tests across 14 test classes
- **EPUB added to unified scraper** — `_scrape_epub()` method, `scraped_data["epub"]`, config validation (`_validate_epub_source`), and dry-run display. Previously EPUB worked standalone but was missing from multi-source configs.
#### Unified Skill Builder — Generic Merge System
- **`_generic_merge()`** — Priority-based section merge for any combination of source types not covered by existing pairwise synthesis (docs+github, docs+pdf, etc.). Produces YAML frontmatter + source-attributed sections.
- **`_append_extra_sources()`** — Appends additional source type content (e.g., Jupyter + PPTX) to pairwise-synthesized SKILL.md.
- **`_generate_generic_references()`** — Generates `references/<type>/index.md` for any source type, with ID resolution fallback chain.
- **`_SOURCE_LABELS`** dict — Human-readable labels for all 17 source types used in merge attribution.
#### Config Validator Expansion
- **17 source types in `VALID_SOURCE_TYPES`** — All new types plus `word` and `video` now have per-type validation methods.
- **`_validate_word_source()`** — Validates `path` field for Word documents (was previously missing).
- **`_validate_video_source()`** — Validates `url`, `path`, or `playlist` field for video sources (was previously missing).
- **11 new `_validate_*_source()` methods** — One for each new type with appropriate required-field checks.
#### Source Detection Improvements
- **7 new file extension detections** in `SourceDetector.detect()` — `.ipynb`, `.html`/`.htm`, `.pptx`, `.adoc`/`.asciidoc`, `.rss`/`.atom`, `.1`–`.8`/`.man`, `.yaml`/`.yml` (with content sniffing)
- **`_looks_like_openapi()`** — Content sniffing for YAML files: only classifies as OpenAPI if the file contains `openapi:` or `swagger:` key in first 20 lines (prevents false positives on docker-compose, Ansible, Kubernetes manifests, etc.)
- **Man page basename heuristic** — `.1`–`.8` extensions only detected as man pages if the basename has no dots (e.g., `git.1` matches but `access.log.1` does not)
- **`.xml` excluded from RSS detection** — Too generic; only `.rss` and `.atom` trigger RSS detection
#### MCP Server Integration
- **`scrape_generic` tool** — New MCP tool handles all 10 new source types via subprocess with per-type flag mapping
- **`_PATH_FLAGS` / `_URL_FLAGS` dicts** — Correct flag routing for each source type (e.g., jupyter→`--notebook`, html→`--html-path`, rss→`--feed-url`)
- **`GENERIC_SOURCE_TYPES` tuple** — Lists all 10 new types for validation
- **Config validation display** — `validate_config` tool now shows source details for all new types
- **Tool count updated** — 33 → 34 tools (scraping tools 10 → 11)
#### CLI Wiring
- **10 new CLI subcommands** — `jupyter`, `html`, `openapi`, `asciidoc`, `pptx`, `rss`, `manpage`, `confluence`, `notion`, `chat` in `COMMAND_MODULES`
- **10 new argument modules** — `arguments/{jupyter,html,openapi,asciidoc,pptx,rss,manpage,confluence,notion,chat}.py` with per-type `*_ARGUMENTS` dicts
- **10 new parser modules** — `parsers/{jupyter,html,openapi,asciidoc,pptx,rss,manpage,confluence,notion,chat}_parser.py` with `SubcommandParser` implementations
- **`create` command routing** — `_route_generic()` method for all new types with correct module names and CLI flags
- **10 new entry points** in pyproject.toml — `skill-seekers-{jupyter,html,openapi,asciidoc,pptx,rss,manpage,confluence,notion,chat}`
- **7 new optional dependency groups** in pyproject.toml — `[jupyter]`, `[asciidoc]`, `[pptx]`, `[confluence]`, `[notion]`, `[rss]`, `[chat]`
- **`[all]` group updated** — Includes all 7 new optional dependencies
#### Sync Config Command
- **`skill-seekers sync-config`** — New subcommand that crawls a docs site's navigation, diffs discovered URLs against a config's `start_urls`, and optionally writes the updated list back with `--apply` (#306)
- BFS link discovery with configurable depth (default 2), max-pages, rate-limit
- Respects `url_patterns.include/exclude` from config
- Supports optional `nav_seed_urls` config field
- Handles both unified (sources array) and legacy flat config formats
- MCP `sync_config` tool included
- 57 tests (39 unit + 18 E2E with local HTTP server)
#### Workflow & Documentation
- **`complex-merge.yaml`** — New 7-stage AI-powered workflow for complex multi-source merging (source inventory → cross-reference → conflict detection → priority merge → gap analysis → synthesis → quality check)
- **AGENTS.md rewritten** — Updated with all 17 source types, scraper pattern docs, project layout, and key pattern documentation
- **77 new integration tests** in `test_new_source_types.py` — Source detection, config validation, generic merge, CLI wiring, validation, and create command routing
- **`docs/BEST_PRACTICES.md`** — Comprehensive guide for creating high-quality skills: SKILL.md structure, code examples, prerequisites, troubleshooting, quality targets, and real-world Grade F to Grade A example (#206)
- **Documentation updated for 17 source types** — 32 files updated across README, CLI reference, feature matrix, MCP reference, config format, API reference, unified scraping, multi-source guide, installation, quick-start, core concepts, user guide, FAQ, troubleshooting, architecture, and all Chinese (zh-CN) translations
- **README translations for 10 languages (12 total)** — Added Japanese (日本語), Korean (한국어), Spanish (Español), French (Français), German (Deutsch), Portuguese (Português), Turkish (Türkçe), Arabic (العربية), Hindi (हिन्दी), and Russian (Русский) README translations with language selector bar across all versions
### Performance
- **Pre-compiled regex and O(1) URL dedup in doc_scraper** — Module-level compiled patterns, `_enqueued_urls` set for O(1) dedup, cached URL patterns, async error logging fix (#309)
- **Bisect-based line indexing in code_analyzer and dependency_analyzer** — O(log n) `offset_to_line()` via bisect replaces O(n) `count("\n")` across all 10 language analyzers and all import extractors
- **O(n) parent class map for Python method detection** — Replaces O(n²) repeated AST walks in code_analyzer
- **O(1) tree traversal in github_scraper** — `deque.popleft()` replaces list `pop(0)`
- **Shared `build_line_index()` / `offset_to_line()` utilities** in `cli/utils.py` — DRY extraction from code_analyzer and dependency_analyzer
### Fixed
- **Config validator missing `word` and `video` dispatch** — `_validate_source()` had no `elif` branches for `word` or `video` types, silently skipping validation. Added dispatch entries and `_validate_word_source()` / `_validate_video_source()` methods.
- **`openapi_scraper.py` unconditional `import yaml`** — Would crash at import time if pyyaml not installed. Added `try/except ImportError` guard with `YAML_AVAILABLE` flag and `_check_yaml_deps()` helper.
- **`asciidoc_scraper.py` missing standard arguments** — `main()` manually defined args instead of using `add_asciidoc_arguments()`. Refactored to use shared argument definitions + added enhancement workflow integration.
- **`pptx_scraper.py` missing standard arguments** — Same issue. Refactored to use `add_pptx_arguments()`.
- **`chat_scraper.py` missing standard arguments** — Same issue. Refactored to use `add_chat_arguments()`.
- **`notion_scraper.py` missing `run_workflows` call** — `--enhance-workflow` flags were silently ignored. Added workflow runner integration.
- **`openapi_scraper.py` return type `None`** — `main()` returned `None` instead of `int`. Fixed to `return 0` on success, matching all other scrapers.
- **MCP `scrape_generic_tool` flag mismatch** — Was passing `--path`/`--url` as generic flags, but every scraper expects its own flag name (e.g., `--notebook`, `--html-path`, `--spec`). All 10 source types would have failed at runtime. Fixed with per-type `_PATH_FLAGS` and `_URL_FLAGS` mappings.
- **Word scraper `docx_id` key mismatch** — Unified scraper data dict used `docx_id` but generic reference generation looked for `word_id`. Added `word_id` alias.
- **`main.py` docstring stale** — Missing all 10 new commands. Updated to list all 27 commands.
- **`source_detector.py` module docstring stale** — Described only 5 source types. Updated to describe 14+ detected types.
- **`manpage_parser.py` docstring referenced wrong file** — Said `manpage_scraper.py` but actual file is `man_scraper.py`. Fixed.
- **Parser registry test count** — Updated expected count from 25 to 35 for 10 new parsers.
- **'Invalid IPv6 URL' error on bracket-containing URLs (#284)** — URLs with square brackets (e.g., `/api/[v1]/users`) discovered via BFS crawl or HTML extraction bypassed the original fix in `_clean_url()`. Added shared `sanitize_url()` utility applied at every URL ingestion point. 16 new tests.
- **GitHub scraper 'list index out of range' on issue extraction (#269)** — PyGithub's `PaginatedList` slicing could fail on some versions or empty repos. Replaced with `itertools.islice()`.
- **Release workflow version mismatch** — GitHub release showed wrong version (v3.1.3 instead of v3.2.0) because no explicit release name was set and sed regex had unescaped dots. Added explicit `name`/`tag_name`, version consistency check (tag vs pyproject.toml vs package), and empty release notes fallback.
- **Release workflow Python 3.10 compatibility** — Version consistency check used `tomllib` (Python 3.11+). Replaced with grep/sed for 3.10 compatibility.
- **`infer_categories()` "tutorial" vs "tutorials" key mismatch** — Guard checked `'tutorial'` but wrote to `'tutorials'` key, risking silent overwrites in category inference.
- **Flaky `test_benchmark_metadata_overhead`** — Stabilized with 20 iterations, warm-up run, median averaging, and 200% threshold (was failing on CI with 5 iterations and mean).
- **CI branch protection check permanently pending** — Summary job was named 'All Checks Complete' but branch protection required 'Tests'. PRs were stuck as 'Expected — Waiting for status to be reported'. Renamed job to match.
## [3.2.0] - 2026-03-01
**Theme:** Video source support, Word document support, Pinecone adaptor, and quality improvements. 94 files changed, +23,500 lines since v3.1.3. **2,540 tests passing.**
### 🎬 Video Tutorial Scraping Pipeline (BETA)
Complete video tutorial extraction system that converts YouTube videos and local video files into AI-consumable skills. The pipeline extracts transcripts, performs visual OCR on code editor panels, tracks code evolution across frames, and generates structured SKILL.md output.
### Added
#### Video Pipeline Core (`skill-seekers video`)
- **`skill-seekers video --url <youtube-url>`** — New CLI command for video tutorial scraping. Also supports `--video-file` for local files and `--playlist` for YouTube playlists
- **`skill-seekers create <youtube-url>`** — Auto-detects YouTube URLs and routes to video scraper
- **`video_scraper.py`** (~960 lines) — Main orchestrator: metadata → transcript → segmentation → visual extraction → SKILL.md generation
- **`video_models.py`** (~815 lines) — 20+ dataclasses: `VideoMetadata`, `TranscriptSegment`, `VideoChapter`, `KeyframeData`, `FrameSubSection`, `TextBlock`, `CodeTimeline`, `SetupModules`, etc.
- **`video_metadata.py`** (~270 lines) — YouTube metadata extraction (title, channel, views, chapters, duration) via yt-dlp; local file metadata via ffprobe
- **`video_transcript.py`** (~370 lines) — Multi-source transcript extraction with 3-tier fallback: YouTube Transcript API → yt-dlp subtitles → faster-whisper local transcription
- **`video_segmenter.py`** (~220 lines) — Chapter-based and time-window segmentation with configurable overlap
- **`video_visual.py`** (~2,410 lines) — Visual extraction pipeline:
- Keyframe detection via scene change (scenedetect) with configurable threshold
- Frame classification (code editor, slides, terminal, browser, other)
- Panel detection — splits IDE screenshots into independent sub-sections (code, terminal, file tree)
- **Per-panel OCR** — Each detected panel OCR'd independently with its own bounding box
- **Multi-engine OCR ensemble** — EasyOCR + pytesseract for code frames (per-line confidence merge with code-token preference), EasyOCR only for non-code frames
- **Parallel OCR** — `ThreadPoolExecutor` for multi-panel frames
- Narrow panel filtering (300px min width) to skip UI chrome
- Text block tracking with spatial panel position matching across frames
- Code timeline with edit tracking (additions, modifications, deletions)
- Vision API fallback when OCR confidence < 0.5
- Tesseract circuit breaker (`_tesseract_broken` flag) — disables pytesseract after first failure
- **Audio-visual alignment** — Code blocks paired with narrator transcript for context
- **Video-specific AI enhancement** — Custom prompt for OCR denoising, code reconstruction, and tutorial narrative synthesis
- **Two-pass AI enhancement** — Pass 1 cleans reference files (Code Timeline reconstruction from transcript context), Pass 2 generates SKILL.md from cleaned references
- **`_ai_clean_reference()`** — Sends reference file to Claude to reconstruct code blocks using transcript context, fixing OCR noise before SKILL.md generation
- **`video-tutorial.yaml`** workflow preset — 4-stage enhancement pipeline (OCR cleanup → language detection → tutorial synthesis → skill polish)
- **Video arguments** — `arguments/video.py` with `VIDEO_ARGUMENTS` dict: `--url`, `--video-file`, `--playlist`, `--vision-ocr`, `--keyframe-threshold`, `--max-keyframes`, `--whisper-model`, `--setup`, etc.
- **Video parser** — `parsers/video_parser.py` for unified CLI parser registry
- **MCP `scrape_video` tool** — Full video scraping from MCP server with 6 visual params, setup mode, and playlist support
- **`tests/test_video_scraper.py`** (197 tests) — Comprehensive coverage: models, metadata, transcript, segmenter, visual extraction, OCR, panel detection, scraper integration, CLI arguments, OCR cleaning, code filtering
#### Video `--setup`: GPU Auto-Detection & Dependency Installation
- **`skill-seekers video --setup`** — One-command GPU auto-detection and dependency installation
- `video_setup.py` (~835 lines) — Complete setup orchestration module
- **GPU auto-detection** — Detects NVIDIA (nvidia-smi → CUDA version), AMD (rocminfo → ROCm version), or CPU-only without requiring PyTorch
- **Correct PyTorch variant** — Installs from the right index URL: `cu124`/`cu121`/`cu118` for NVIDIA, `rocm6.3`/`rocm6.2.4` for AMD, `cpu` for CPU-only
- **ROCm configuration** — Sets `MIOPEN_FIND_MODE=FAST` and `HSA_OVERRIDE_GFX_VERSION` for AMD GPUs
- **Virtual environment detection** — Warns users outside a venv with opt-in `--force` override
- **System dependency checks** — Validates `tesseract` and `ffmpeg` binaries, provides OS-specific install instructions
- **Module selection** — `SetupModules` dataclass for optional component selection (easyocr, opencv, tesseract, scenedetect, whisper)
- **Base video deps always included** — `yt-dlp` and `youtube-transcript-api` installed automatically
- **Verification step** — Post-install import checks including `torch.cuda.is_available()` and `torch.version.hip`
- **Non-interactive mode** — `run_setup(interactive=False)` for MCP server and CI/CD use
- **`--setup` early-exit** — Runs before source validation (no `--url` required)
- **MCP `scrape_video` setup parameter** — `setup: bool = False` in `server_fastmcp.py` and `scraping_tools.py`
- **`create` command routing** — Forwards `--setup` to video scraper
- **`tests/test_video_setup.py`** (60 tests) — GPU detection, CUDA/ROCm version mapping, installation, verification, venv checks, system deps, module selection
#### Microsoft Word (.docx) Support
- **`skill-seekers word --docx <file>`** and `skill-seekers create document.docx` — Full pipeline: mammoth → HTML → BeautifulSoup → sections → SKILL.md + references/
- `word_scraper.py` — `WordToSkillConverter` class (~600 lines) with heading/code/table/image/metadata extraction
- `arguments/word.py` — `add_word_arguments()` + `WORD_ARGUMENTS` dict
- `parsers/word_parser.py` — WordParser for unified CLI parser registry
- `tests/test_word_scraper.py` — Comprehensive test suite (~300 lines)
- **`.docx` auto-detection** in `source_detector.py` — Routes to word scraper
- **`--help-word`** flag in create command for Word-specific help
- **Word support in unified scraper** — `_scrape_word()` method for multi-source scraping
- **`skill-seekers-word`** entry point in pyproject.toml
- **`docx` optional dependency group** — `pip install skill-seekers[docx]` (mammoth + python-docx)
#### Other Additions
- **Pinecone adaptor** — `pinecone_adaptor.py` with full upload support
- **`video` and `video-full` optional dependency groups** in pyproject.toml
- **`skill-seekers-video`** entry point in pyproject.toml
- **Video plan documents** — 8 design documents in `docs/plans/video/` (research, data models, pipeline, integration, output, testing, dependencies, overview)
### Fixed
#### Video Pipeline OCR Quality Fixes (6)
- **Webcam/OTHER frames skip OCR** — WEBCAM and OTHER frame types no longer get OCR'd, eliminating ~64 junk OCR results per video
- **`_clean_ocr_line()` helper** — Strips leading line numbers, IDE tab bar text, Unity Inspector labels, and VS Code collapse markers from OCR output
- **`_fix_intra_line_duplication()`** — Detects and removes token sequence repetition from multi-engine OCR overlap (e.g., `gpublic class Card Jpublic class Card` → `public class Card`)
- **`_is_likely_code()` filter** — Reference file code fences now filtered to reject UI junk (Inspector, Hierarchy, Canvas labels) that passed frame classification
- **Language detection on text groups** — `get_text_groups()` now runs `LanguageDetector.detect_from_code()` on each group, filling the previously-always-None `detected_language` field
- **OCR cleaning in text assembly** — `_assemble_structured_text()` applies `_clean_ocr_line()` to every line before joining
#### Video Pipeline Fixes (15)
- **`extract_visual_data` returning 2-tuple instead of 3** — Caused `ValueError` crash when unpacking results
- **pytesseract in core deps** — Moved from core dependencies to `[video-full]` optional group
- **30-min timeout for video enhancement subprocess** — Previously could hang indefinitely
- **`scrape_video_impl` missing from MCP server fallback import** — Added to import block
- **Auto-generated YouTube captions not detected** — Now checks `is_generated` property on transcripts
- **`--vision-ocr` and `--video-playlist` not forwarded** — `create` command now passes these to video scraper
- **Filename collision for non-ASCII video titles** — Falls back to `video_id` when title contains non-ASCII characters
- **`_vision_used` not a proper dataclass field** — Made a proper field on `FrameSubSection` dataclass
- **6 visual params missing from MCP `scrape_video`** — Exposed keyframe_threshold, max_keyframes, whisper_model, vision_ocr, video_playlist, video_file
- **Missing video dep install instructions in unified scraper** — Added guidance when video dependencies are not installed
- **MCP docstring tool counts outdated** — Updated from 25→33 tools across 7 categories
- **Video and word commands missing from `main.py` docstring** — Added to CLI help text
- **`video-full` exclusion from `[all]` deps undocumented** — Added comment in pyproject.toml
- **Parser registry test count wrong** — Updated expected count from 22→23 for video parser
#### Scraper & Quality Fixes
- **Issue #300: Selector fallback & dry-run link discovery** — `create https://reactflow.dev/` now finds 20+ pages (was 1):
- `extract_content()` extracted links after early-return → moved before
- Dry-run used `main.find_all("a")` instead of `soup.find_all("a")` → fixed
- Async dry-run had no link extraction at all → added
- `get_configuration()` CSS comma selector conflicted with fallback loop → removed default
- `create --config` with `base_url` config incorrectly routed to unified_scraper → now peeks at JSON
- Selector fallback duplicated in 3 places with `body` fallback → extracted `FALLBACK_MAIN_SELECTORS` constant + `_find_main_content()` helper
- **Issue #301: `setup.sh` fails on macOS** — `pip3` pointed to different Python than `python3`. Changed to `python3 -m pip`.
- **RAG chunking crash (`AttributeError: output_dir`)** — `converter.output_dir` doesn't exist on `DocToSkillConverter`. Changed to `Path(converter.skill_dir)`.
- **`--var` flag silently dropped in `create` routing** — `main.py` read `args.workflow_var` instead of `args.var`
- **`--chunk-overlap-tokens` missing from `package` command** — Wired through entire pipeline: `package_skill()` → `adaptor.package()` → `format_skill_md()` → `_maybe_chunk_content()` → `RAGChunker`
- **Chunk overlap auto-scaling** — Auto-scales to `max(50, chunk_tokens // 10)` when chunk size is non-default
- **Weaviate `ImportError` masked by generic handler** — Added `except ImportError` before `except Exception`
- **Hardcoded chunk defaults in 12 adaptors** — Replaced `512`/`50` with `DEFAULT_CHUNK_TOKENS`/`DEFAULT_CHUNK_OVERLAP_TOKENS` constants
- **Reference file code truncation** — `codebase_scraper.py` no longer truncates code blocks to 500 chars (5 locations)
- **Enhancement code block limit** — `summarize_reference()` now uses character-budget approach instead of `[:5]` cap
- **Intro boundary code block desync** — Tracks code block state to prevent splitting inside code blocks
- **Hardcoded `python` language** — `unified_skill_builder.py` and `how_to_guide_builder.py` now use detected language
- **GitHub reference file limits removed** — No more caps on issues (was 20), releases (was 10), or release bodies (was 500 chars)
- **GitHub scraper reference limits removed** — `github_scraper.py` no longer caps open_issues at 20 or closed_issues at 10
- **PDF scraper fixes** — Real API/LOCAL enhancement (was stub); removed `[:3]` reference file limit
- **Word scraper code detection** — Detect mammoth monospace `<p><br>` blocks as code
- **Language detector method** — Fixed `detect_from_text` → `detect_from_code` in word scraper
- **`.docx` file extension validation** — Non-`.docx` files raise `ValueError` with clear message
- **Double `_score_code_quality()` call** — Consolidated to single call in word scraper
- **`--no-preserve-code` renamed** — Now `--no-preserve-code-blocks` (backward-compat alias kept)
- **Dead variable** — Removed unused `_target_lines` in `enhance_skill_local.py`
### Changed
- **`easyocr` removed from `video-full` optional deps** — Was pulling ~2GB of NVIDIA CUDA packages regardless of GPU vendor. Now installed via `--setup` with correct PyTorch variant.
- **Video dependency error messages** — `video_scraper.py` and `video_visual.py` now suggest `skill-seekers video --setup` as primary fix
- **Shared embedding methods consolidated** — `_generate_openai_embeddings()` and `_generate_st_embeddings()` moved to `SkillAdaptor` base class, eliminating ~150 lines of duplication from chroma/weaviate/pinecone adaptors
- **Chunk constants centralized** — `DEFAULT_CHUNK_TOKENS = 512` and `DEFAULT_CHUNK_OVERLAP_TOKENS = 50` in `arguments/common.py`, used across all 12 adaptors + rag_chunker + base + package_skill + create_command
- **Enhancement summarizer architecture** — Character-budget approach with `target_ratio` for both code blocks and heading chunks
## [3.1.3] - 2026-02-24
### 🐛 Hotfix — Explicit Chunk Flags & Argument Pipeline Cleanup
### Fixed
- **Issue #299: `skill-seekers package --target claude` unrecognised argument crash** — `_reconstruct_argv()` in `main.py` emits default flag values back into argv when routing subcommands. `package_skill.py` had a 105-line inline argparser that used different flag names to those in `arguments/package.py`, so forwarded flags were rejected. Fixed by replacing the inline block with a call to `add_package_arguments(parser)` — the single source of truth.
### Changed
- **`package_skill.py` argparser refactored** — Replaced ~105 lines of inline argparse duplication with a single `add_package_arguments(parser)` call. Flag names are now guaranteed consistent with `_reconstruct_argv()` output, preventing future argument-name drift.
- **Explicit chunk flag names** — All `--chunk-*` flags now include unit suffixes to eliminate ambiguity between RAG tokens and streaming characters:
- `--chunk-size` (RAG tokens) → `--chunk-tokens`
- `--chunk-overlap` (RAG tokens) → `--chunk-overlap-tokens`
- `--chunk` (enable RAG chunking) → `--chunk-for-rag`
- `--streaming-chunk-size` (chars) → `--streaming-chunk-chars`
- `--streaming-overlap` (chars) → `--streaming-overlap-chars`
- `--chunk-size` in PDF extractor (pages) → `--pdf-pages-per-chunk`
- **`setup_logging()` centralized** — Added `setup_logging(verbose, quiet)` to `utils.py` and removed 4 duplicate module-level `logging.basicConfig()` calls from `doc_scraper.py`, `github_scraper.py`, `codebase_scraper.py`, and `unified_scraper.py`
## [3.1.2] - 2026-02-24
### 🔧 Fix `create` Command Argument Forwarding, Gemini Model, and Enhance Dispatcher
### Fixed
- **`create` command argument forwarding** — Universal flags (`--dry-run`, `--verbose`, `--quiet`, `--name`, `--description`) now work correctly across all source types. Previously, `create <url> -p quick --dry-run`, `create owner/repo --dry-run`, and `create ./path --dry-run` would crash because sub-scrapers didn't accept those flags
- **`skill-seekers analyze --dry-run`** — Fixed `_handle_analyze_command()` in `main.py` not forwarding `--dry-run`, `--preset`, `--quiet`, `--name`, `--description`, `--api-key`, and workflow flags to codebase_scraper
- **Gemini model 404 errors** — Replaced retired `gemini-2.0-flash-exp` with `gemini-2.5-flash` (stable GA) in the Gemini adaptor. Users attempting Gemini enhancement were getting 404 Not Found errors
- **`skill-seekers enhance` auto-detection** — The documented behaviour of auto-detecting API vs LOCAL mode was never implemented. `enhance` now correctly routes to the platform API when a key is present: `ANTHROPIC_API_KEY` → Claude API, `GOOGLE_API_KEY` → Gemini API, `OPENAI_API_KEY` → OpenAI API, no key → LOCAL mode (Claude Code Max, free). Use `--mode LOCAL` to force local mode regardless
### Added
- **Shared argument contract** — New `add_all_standard_arguments(parser)` in `arguments/common.py` registers common + behavior + workflow args on any parser as a single call
- **`BEHAVIOR_ARGUMENTS`** — Centralized `--dry-run`, `--verbose`, `--quiet` definitions in `arguments/common.py`
- **`--dry-run` for GitHub scraper** — `skill-seekers github --repo owner/repo --dry-run` now previews the operation
- **`--dry-run` for PDF scraper** — `skill-seekers pdf --name test --dry-run` now previews the operation
- **`--verbose`/`--quiet` for GitHub and PDF scrapers** — Logging level control now works consistently across all scrapers
- **`--name`/`--description` for codebase analyzer** — Custom skill name and description can now be passed to `skill-seekers analyze`
- **`--mode LOCAL` flag for `skill-seekers enhance`** — Explicitly forces LOCAL mode even when API keys are present
### Changed
- **Argument deduplication** — Removed duplicated argument definitions from `arguments/github.py`, `arguments/scrape.py`, `arguments/analyze.py`, `arguments/pdf.py`; all now import shared args from `arguments/common.py`
- **`create` command `_add_common_args()`** — Only forwards truly universal flags; route-specific flags (`--preset`, `--config`, `--chunk-for-rag`, etc.) moved to their respective route methods
- **`codebase_scraper.py` argparser** — Replaced ~190 lines of inline argparser with `add_analyze_arguments(parser)` call
## [3.1.1] - 2026-02-23
### 🐛 Hotfix
### Fixed
- **`create` command `max_pages` AttributeError** — Fixed crash when `max_pages` argument was not provided in web source routing. Uses `getattr()` for safe attribute access (#293, #294)
### Changed
- Version bump to 3.1.1
## [3.1.0] - 2026-02-23
### 🎯 "Unified CLI & Developer Experience" — Feature Release
**Theme:** One command for everything. Better developer tooling. 2280+ tests passing.
### Added
#### Unified `create` Command
- **Single command for all source types** — auto-detects URL, GitHub repo (`owner/repo`), local directory, PDF file, or multi-source config JSON
```bash
skill-seekers create https://docs.react.dev/
skill-seekers create facebook/react
skill-seekers create ./my-project
skill-seekers create tutorial.pdf
```
- **Progressive help disclosure** — default `--help` shows 13 universal flags; detailed help per source:
- `--help-web`, `--help-github`, `--help-local`, `--help-pdf`, `--help-advanced`, `--help-all`
- **`-p` shortcut** for preset selection: `skill-seekers create <source> -p quick|standard|comprehensive`
- **`--local-repo-path`** flag for specifying local clone path in create command with validation
- Supports multi-source config files as input (routes to unified scraper)
#### Enhancement Workflow Preset System
- **New `workflows` CLI subcommand** to manage enhancement workflow presets
- **65 bundled workflow presets** shipped as YAML files in `skill_seekers/workflows/`:
- Core: `default`, `minimal`, `security-focus`, `architecture-comprehensive`, `api-documentation`
- Domain-specific: `rest-api-design`, `graphql-schema`, `grpc-services`, `websockets-realtime`, `event-driven`, `message-queues`, `stream-processing`
- Architecture: `microservices-patterns`, `serverless-architecture`, `kubernetes-deployment`, `devops-deployment`, `terraform-guide`
- Frontend: `responsive-design`, `component-library`, `forms-validation`, `design-system`, `pwa-checklist`, `ssr-guide`, `deep-linking`, `state-management`
- Quality: `testing-focus`, `testing-frontend`, `performance-optimization`, `observability-stack`, `troubleshooting-guide`, `accessibility-a11y`
- Data: `database-schema`, `data-validation`, `feature-engineering`, `vector-databases`, `mlops-pipeline`, `model-deployment`, `computer-vision`
- Security: `encryption-guide`, `iam-identity`, `secrets-management`, `compliance-gdpr`, `auth-strategies`
- Cloud: `aws-services`, `backup-disaster-recovery`
- Patterns: `advanced-patterns`, `api-evolution`, `migration-guide`, `contribution-guide`, `onboarding-beginner`, `comparison-matrix`, `sdk-integration`, `platform-specific`, `cli-tooling`, `build-tools`
- Mobile: `push-notifications`, `offline-first`, `localization-i18n`
- Background: `background-jobs`, `rate-limiting`, `caching-strategies`, `webhook-guide`, `api-gateway`
- User presets stored in `~/.config/skill-seekers/workflows/`
- Subcommands:
- `skill-seekers workflows list` — List all bundled + user workflows with descriptions
- `skill-seekers workflows show <name>` — Print YAML content of a workflow
- `skill-seekers workflows copy <name> [name ...]` — Copy bundled workflow(s) to user dir
- `skill-seekers workflows add <file.yaml> [file ...]` — Install custom YAML file(s) into user dir
- `skill-seekers workflows remove <name> [name ...]` — Delete user workflow(s)
- `skill-seekers workflows validate <name|path>` — Parse and validate a workflow
- `copy`, `add`, `remove` all accept multiple names/files in one command (partial-failure: continues processing, returns non-zero if any item fails)
- New entry point: `skill-seekers-workflows`
#### Multiple `--enhance-workflow` Flags from CLI
- Chain workflows in a single command: `skill-seekers create <source> --enhance-workflow security-focus --enhance-workflow minimal`
- Supported across all scrapers: `scrape`, `github`, `analyze`, `pdf`, `unified`
#### Smart Enhancement Dispatcher (`skill-seekers enhance`)
- Auto-routes to API mode (Claude/Gemini/OpenAI) when API key is available, LOCAL mode (Claude Code CLI) otherwise
- Decision priority: `--target` flag → config `default_agent` → env vars (`ANTHROPIC_API_KEY` → claude, `GOOGLE_API_KEY` → gemini, `OPENAI_API_KEY` → openai) → LOCAL fallback
- **Blocks LOCAL mode when running as root** (Docker/VPS) with clear error message + API mode instructions (fixes #286, #289)
- New flags: `--target`, `--api-key`, `--dry-run`, `--interactive-enhancement`
#### Unified Document Parser System
- New `parsers/extractors.py` module with `RstParser`, `MarkdownParser` classes
- **ReStructuredText (RST) support** — parses class references, code blocks, tables, cross-references
- Shared `parse_document()` factory function for RST/Markdown/PDF input
- Integrated into documentation extraction pipeline for richer content
- `ContentBlockType` and `CrossRefType` enums for structured parsing output
#### Local Source Support in Unified Scraper
- `"type": "local"` source type in unified config JSONs — analyze local codebases alongside web/GitHub/PDF sources
- `--local-repo-path` CLI flag in unified scraper for per-source path override
#### CLI Flag Parity Across All Commands
- `analyze`, `pdf`, and `unified` commands now have full flag parity with `scrape`/`github`:
- `--api-key` on `pdf` and `unified`
- `--enhance-level` on `unified`
- `--dry-run` on `analyze`
- All workflow flags (`--enhance-workflow`, `--enhance-stage`, `--var`, `--workflow-dry-run`) on `analyze`
- Workflow JSON config fields (`workflows`, `workflow_stages`, `workflow_vars`) now merged with CLI flags in `unified` scraper
### Fixed
- **Percent-encode brackets in llms.txt URLs** — prevent "Invalid IPv6 URL" errors when scraping sites with bracket characters (fixes #284)
- **Platform-appropriate config paths on Windows** — use `%APPDATA%` instead of `~/.config` (fixes #283)
- **`create` command multi-source config** — now correctly routes to unified scraper when input is a `.json` config file
- **`create` command `_add_common_args()`** — correctly forwards each `--enhance-workflow` value as a separate flag to sub-scrapers (previously collapsed list to single string, causing workflows to be ignored)
- **`_extract_markdown_content`** — filter out bare `h1` headings and short stub paragraphs that polluted extracted content
- **Godot unified config language names** — corrected `gdscript`/`gds` to proper names in `godot_unified.json`
- **Python 3.10 type union compatibility** — use `Optional[X]` instead of `X | None` in forward-reference positions
- **`_route_config` in unified scraper** — correctly handles all source types when routing config-driven scraping
- **CONFIG_ARGUMENTS** — added to ensure unified CLI has full argument visibility for config-based sources
- **Test suite isolation** — `test_swift_detection.py` now saves/restores `sys.modules` and parent package attributes; prevents `@patch` decorators in downstream files from targeting stale module objects
- **Python 3.14 chromadb compatibility** — catch `pydantic.v1.errors.ConfigError` (not just `ImportError`) when chromadb is installed
- **langchain import path** — updated `langchain.schema` → `langchain_core.documents` for langchain 1.x
- **Removed legacy `sys.path.insert()` calls** from `codebase_scraper.py`, `doc_scraper.py`, `enhance_skill.py`, `enhance_skill_local.py`, `estimate_pages.py`, `install_skill.py` (unnecessary with `pip install -e .`)
- **Benchmark timing threshold** — relaxed metadata overhead assertion from 10% to 50% for CI runner variability
### Changed
- **Enhancement flags consolidated** — `--enhance-level` (0-3) replaces three separate flags (`--enhance`, `--enhance-local`, `--api-key`). Old flags still accepted with deprecation warnings until v4.0.0
- **`workflows copy/add/remove`** now accept multiple names/files in one invocation
- **`pyproject.toml`** — PyYAML added as core dependency (required by workflow preset management); langchain and llama-index added as dependencies; MCP version requirement updated to `>=1.25`
### Tests
- **2280+ tests passing** (2158 non-MCP + ~122 MCP, up from 1852 in v3.0.0), 11 skipped (external services), 0 failures
- Added `TestAnalyzeWorkflowFlags`, `TestUnifiedCLIArguments`, `TestPDFCLIArguments` classes
- Added `tests/test_mcp_workflow_tools.py` — 5 MCP workflow tool tests
- Added `tests/test_unified_scraper_orchestration.py` — UnifiedScraper orchestration tests
- Removed `@unittest.skip` from gemini/openai/claude adaptor tests that were ready
- Removed `@requires_github` from 5 unified_analyzer tests that fully mock their dependencies
- Macros-specific tests now use `@patch(sys.platform)` instead of runtime `skipTest()` for platform portability
### Config Repository (skill-seekers-configs)
- **178 production configs reviewed and enhanced** across all 22 categories — brought to v1.1.0 quality standard
- **Removed all `max_pages` fields** from production configs (deprecated, defaults apply automatically)
- **Fixed outdated URLs**: `astro.json` (Astro v3 restructure: `/en/core-concepts/` → `/en/basics/`), `laravel.json` (11.x → 12.x throughout)
- **Fixed structural bug** in `httpx_comprehensive.json` — `url_patterns`, `categories`, `rate_limit` moved from top-level into `sources[0]` (required for unified format)
- **Removed hash-fragment start_urls** from `zod.json` (scrapers don't follow `?id=` anchors)
- **Improved category/selector quality** across all 22 categories: 5-13 categories per config, 3-6 keywords each, semantic selector fallback chains
- **README.md**: corrected config count from outdated "50+" to accurate 178 production / 182 total; all category counts verified
- **CONTRIBUTING.md, QUALITY_GUIDELINES.md, AGENTS.md**: aligned with production standards; removed all `max_pages` guidance
- **`scripts/validate-config.py`**: fixed two bugs — unified config categories lookup (was always reporting "no categories" for multi-source configs) and `max_pages` warning logic (was warning when absent, now correctly warns when present)
- **Deleted** `.github/ISSUE_TEMPLATE/submit-config.md` (old duplicate of `submit-config.yml` with outdated content)
## [3.0.0] - 2026-02-10
### 🚀 "Universal Intelligence Platform" - Major Release
**Theme:** Transform any documentation into structured knowledge for any AI system.
This is our biggest release ever! v3.0.0 establishes Skill Seekers as the **universal documentation preprocessor** for the entire AI ecosystem - from RAG pipelines to AI coding assistants to Claude skills.
### Highlights
- 🚀 **16 platform adaptors** (up from 4 in v2.x)
- 🛠️ **26 MCP tools** (up from 9)
- ✅ **1,852 tests** passing (up from 700+)
- ☁️ **Cloud storage** support (S3, GCS, Azure)
- 🔄 **CI/CD ready** (GitHub Action + Docker)
- 📦 **12 example projects** for every integration
- 📚 **18 integration guides** complete
### Added - Platform Adaptors (16 Total)
#### RAG & Vector Databases (8)
- **LangChain** (`--format langchain`) - Output LangChain Document objects
- **LlamaIndex** (`--format llama-index`) - Output LlamaIndex TextNode objects
- **Chroma** (`--format chroma`) - Direct ChromaDB integration
- **FAISS** (`--format faiss`) - Facebook AI Similarity Search
- **Haystack** (`--format haystack`) - Deepset Haystack pipelines
- **Qdrant** (`--format qdrant`) - Qdrant vector database
- **Weaviate** (`--format weaviate`) - Weaviate vector search
- **Pinecone-ready** (`--target markdown`) - Markdown format ready for Pinecone
#### AI Platforms (3)
- **Claude** (`--target claude`) - Claude AI skills (ZIP + YAML)
- **Gemini** (`--target gemini`) - Google Gemini skills (tar.gz)
- **OpenAI** (`--target openai`) - OpenAI ChatGPT (ZIP + Vector Store)
#### AI Coding Assistants (4)
- **Cursor** (`--target claude` + `.cursorrules`) - Cursor IDE integration
- **Windsurf** (`--target claude` + `.windsurfrules`) - Windsurf/Codeium
- **Cline** (`--target claude` + `.clinerules`) - VS Code extension
- **Continue.dev** (`--target claude`) - Universal IDE support
#### Generic (1)
- **Markdown** (`--target markdown`) - Generic ZIP export
### Added - MCP Tools (26 Total)
#### Config Tools (3)
- `generate_config` - Generate scraping configuration
- `list_configs` - List available preset configs
- `validate_config` - Validate config JSON structure
#### Scraping Tools (8)
- `estimate_pages` - Estimate page count before scraping
- `scrape_docs` - Scrape documentation websites
- `scrape_github` - Scrape GitHub repositories
- `scrape_pdf` - Extract from PDF files
- `scrape_codebase` - Analyze local codebases
- `detect_patterns` - Detect design patterns in code
- `extract_test_examples` - Extract usage examples from tests
- `build_how_to_guides` - Build how-to guides from code
#### Packaging Tools (4)
- `package_skill` - Package skill for target platform
- `upload_skill` - Upload to LLM platform
- `enhance_skill` - AI-powered enhancement
- `install_skill` - One-command complete workflow
#### Source Tools (5)
- `fetch_config` - Fetch config from remote source
- `submit_config` - Submit config for approval
- `add_config_source` - Add Git config source
- `list_config_sources` - List config sources
- `remove_config_source` - Remove config source
#### Splitting Tools (2)
- `split_config` - Split large configs
- `generate_router` - Generate router skills
#### Vector DB Tools (4)
- `export_to_weaviate` - Export to Weaviate
- `export_to_chroma` - Export to ChromaDB
- `export_to_faiss` - Export to FAISS
- `export_to_qdrant` - Export to Qdrant
### Added - Cloud Storage
Upload skills directly to cloud storage:
- **AWS S3** - `skill-seekers cloud upload --provider s3 --bucket my-bucket`
- **Google Cloud Storage** - `skill-seekers cloud upload --provider gcs --bucket my-bucket`
- **Azure Blob Storage** - `skill-seekers cloud upload --provider azure --container my-container`
Features:
- Upload/download directories
- List files with metadata
- Check file existence
- Generate presigned URLs
- Cloud-agnostic interface
### Added - CI/CD Support
#### GitHub Action
```yaml
- uses: skill-seekers/action@v1
with:
config: configs/react.json
format: langchain
```
Features:
- Auto-update on doc changes
- Matrix builds for multiple frameworks
- Scheduled updates
- Caching for faster runs
#### Docker
```bash
docker run -v $(pwd):/data skill-seekers:latest scrape --config /data/config.json
```
### Added - Production Infrastructure
- **Helm Charts** - Kubernetes deployment
- **Docker Compose** - Local vector DB stack
- **Monitoring** - Sentry integration, sync monitoring
- **Benchmarking** - Performance testing framework
### Added - 12 Example Projects
Complete working examples for every integration:
1. **langchain-rag-pipeline** - React docs → LangChain → Chroma
2. **llama-index-query-engine** - Vue docs → LlamaIndex
3. **pinecone-upsert** - Documentation → Pinecone
4. **chroma-example** - Full ChromaDB workflow
5. **faiss-example** - FAISS index building
6. **haystack-pipeline** - Haystack RAG pipeline
7. **qdrant-example** - Qdrant vector DB
8. **weaviate-example** - Weaviate integration
9. **cursor-react-skill** - React skill for Cursor
10. **windsurf-fastapi-context** - FastAPI for Windsurf
11. **cline-django-assistant** - Django assistant for Cline
12. **continue-dev-universal** - Universal IDE context
### Quality Metrics
- ✅ **1,852 tests** across 100 test files
- ✅ **58,512 lines** of Python code
- ✅ **80+ documentation** files
- ✅ **100% test coverage** for critical paths
- ✅ **CI/CD** on every commit
### Fixed
#### URL Conversion Bug with Anchor Fragments (Issue #277)
- **Critical Bug Fix**: Fixed 404 errors when scraping documentation with anchor links
- **Problem**: URLs with anchor fragments (e.g., `#synchronous-initialization`) were malformed
- Incorrect: `https://example.com/docs/api#method/index.html.md` ❌
- Correct: `https://example.com/docs/api/index.html.md` ✅
- **Root Cause**: `_convert_to_md_urls()` didn't strip anchor fragments before appending `/index.html.md`
- **Solution**: Parse URLs with `urllib.parse` to remove fragments and deduplicate base URLs
- **Impact**: Prevents duplicate requests for the same page with different anchors
- **Additional Fix**: Changed `.md` detection from `".md" in url` to `url.endswith('.md')`
- Prevents false matches on URLs like `/cmd-line` or `/AMD-processors`
- **Test Coverage**: 12 comprehensive tests covering all edge cases
- Anchor fragment stripping
- Deduplication of multiple anchors on same URL
- Query parameter preservation
- Trailing slash handling
- Real-world MikroORM case validation
- 54/54 tests passing (42 existing + 12 new)
- **Reported by**: @devjones via Issue #277
### Added
#### Extended Language Detection (NEW)
- **7 New Programming Languages**: Dart, Scala, SCSS, SASS, Elixir, Lua, Perl
- Pattern-based detection with confidence scoring (0.6-0.8+ thresholds)
- **70 regex patterns** prioritizing unique identifiers (weight 5)
- Framework-specific patterns:
- **Dart**: Flutter widgets (`StatelessWidget`, `StatefulWidget`, `Widget build()`)
- **Scala**: Pattern matching (`case class`, `trait`, `match {}`)
- **SCSS**: Preprocessor features (`$variables`, `@mixin`, `@include`, `@extend`)
- **SASS**: Indented syntax (`=mixin`, `+include`, `$variables`)
- **Elixir**: Functional patterns (`defmodule`, `def ... do`, pipe operator `|>`)
- **Lua**: Game scripting (`local`, `repeat...until`, `~=`, `elseif`)
- **Perl**: Text processing (`my $`, `use strict`, `sub`, `chomp`, regex `=~`)
- **Comprehensive test coverage**: 7 new tests, 30/30 passing (100%)
- **False positive prevention**: Unique identifiers (weight 5) + confidence thresholds
- **No regressions**: All existing language detection tests still pass
- **Total language support**: Now 27+ programming languages
- **Credit**: Contributed by @PaawanBarach via PR #275
#### Multi-Agent Support for Local Enhancement (NEW)
- **Multiple Coding Agent Support**: Choose your preferred local coding agent for SKILL.md enhancement
- **Claude Code** (default): Claude Code CLI with `--dangerously-skip-permissions`
- **Codex CLI**: OpenAI Codex CLI with `--full-auto` and `--skip-git-repo-check`
- **Copilot CLI**: GitHub Copilot CLI (`gh copilot chat`)
- **OpenCode CLI**: OpenCode CLI
- **Custom agents**: Use any CLI tool with `--agent custom --agent-cmd "command {prompt_file}"`
- **CLI Arguments**: New flags for agent selection
- `--agent`: Choose agent (claude, codex, copilot, opencode, custom)
- `--agent-cmd`: Override command template for custom agents
- **Environment Variables**: CI/CD friendly configuration
- `SKILL_SEEKER_AGENT`: Default agent to use
- `SKILL_SEEKER_AGENT_CMD`: Default command template for custom agents
- **Security First**: Custom command validation
- Blocks dangerous shell characters (`;`, `&`, `|`, `$`, `` ` ``, `\n`, `\r`)
- Validates executable exists in PATH
- Safe parsing with `shlex.split()`
- **Dual Input Modes**: Supports both file-based and stdin-based agents
- File-based: Uses `{prompt_file}` placeholder (Claude, custom agents)
- Stdin-based: Pipes prompt via stdin (Codex CLI)
- **Backward Compatible**: Claude Code remains the default, no breaking changes
- **Comprehensive Tests**: 13 new tests covering all agent types and security validation
- **Agent Normalization**: Smart alias handling (e.g., "claude-code" → "claude")
- **Credit**: Contributed by @rovo79 (Robert Dean) via PR #270
#### C3.10: Signal Flow Analysis for Godot Projects (NEW)
- **Complete Signal Flow Analysis System**: Analyze event-driven architectures in Godot game projects
- Signal declaration extraction (`signal` keyword detection)
- Connection mapping (`.connect()` calls with targets and methods)
- Emission tracking (`.emit()` and `emit_signal()` calls)
- **208 signals**, **634 connections**, and **298 emissions** detected in test project (Cosmic Idler)
- Signal density metrics (signals per file)
- Event chain detection (signals triggering other signals)
- Output: `signal_flow.json`, `signal_flow.mmd` (Mermaid diagram), `signal_reference.md`
- **Signal Pattern Detection**: Three major patterns identified
- **EventBus Pattern** (0.90 confidence): Centralized signal hub in autoload
- **Observer Pattern** (0.85 confidence): Multi-observer signals (3+ listeners)
- **Event Chains** (0.80 confidence): Cascading signal propagation
- **Signal-Based How-To Guides (C3.10.1)**: AI-generated usage guides
- Step-by-step guides (Connect → Emit → Handle)
- Real code examples from project
- Common usage locations
- Parameter documentation
- Output: `signal_how_to_guides.md` (10 guides for Cosmic Idler)
#### Godot Game Engine Support
- **Comprehensive Godot File Type Support**: Full analysis of Godot 4.x projects
- **GDScript (.gd)**: 265 files analyzed in test project
- **Scene files (.tscn)**: 118 scene files
- **Resource files (.tres)**: 38 resource files
- **Shader files (.gdshader, .gdshaderinc)**: 9 shader files
- **C# integration**: Phantom Camera addon (13 files)
- **GDScript Language Support**: Complete GDScript parsing with regex-based extraction
- Dependency extraction: `preload()`, `load()`, `extends` patterns
- Test framework detection: GUT, gdUnit4, WAT
- Test file patterns: `test_*.gd`, `*_test.gd`
- Signal syntax: `signal`, `.connect()`, `.emit()`
- Export decorators: `@export`, `@onready`
- Test decorators: `@test` (gdUnit4)
- **Game Engine Framework Detection**: Improved detection for Unity, Unreal, Godot
- **Godot markers**: `project.godot`, `.godot` directory, `.tscn`, `.tres`, `.gd` files
- **Unity markers**: `Assembly-CSharp.csproj`, `UnityEngine.dll`, `ProjectSettings/ProjectVersion.txt`
- **Unreal markers**: `.uproject`, `Source/`, `Config/DefaultEngine.ini`
- Fixed false positive Unity detection (was using generic "Assets" keyword)
- **GDScript Test Extraction**: Extract usage examples from Godot test files
- **396 test cases** extracted from 20 GUT test files in test project
- Patterns: instantiation (`preload().new()`, `load().new()`), assertions (`assert_eq`, `assert_true`), signals
- GUT framework: `extends GutTest`, `func test_*()`, `add_child_autofree()`
- Test categories: instantiation, assertions, signal connections, setup/teardown
- Real code examples from production test files
#### C3.9: Project Documentation Extraction
- **Markdown Documentation Extraction**: Automatically extracts and categorizes all `.md` files from projects
- Smart categorization by folder/filename (overview, architecture, guides, workflows, features, etc.)
- Processing depth control: `surface` (raw copy), `deep` (parse+summarize), `full` (AI-enhanced)
- AI enhancement (level 2+) adds topic extraction and cross-references
- New "📖 Project Documentation" section in SKILL.md
- Output to `references/documentation/` organized by category
- Default ON, use `--skip-docs` to disable
- 15 new tests for documentation extraction features
#### Granular AI Enhancement Control
- **`--enhance-level` Flag**: Fine-grained control over AI enhancement (0-3)
- Level 0: No AI enhancement (default)
- Level 1: SKILL.md enhancement only (fast, high value)
- Level 2: SKILL.md + Architecture + Config + Documentation
- Level 3: Full enhancement (patterns, tests, config, architecture, docs)
- **Config Integration**: `default_enhance_level` setting in `~/.config/skill-seekers/config.json`
- **MCP Support**: All MCP tools updated with `enhance_level` parameter
- **Independent from `--comprehensive`**: Enhancement level is separate from feature depth
#### C# Language Support
- **C# Test Example Extraction**: Full support for C# test frameworks
- Language alias mapping (C# → csharp, C++ → cpp)
- NUnit, xUnit, MSTest test framework patterns
- Mock pattern support (NSubstitute, Moq)
- Zenject dependency injection patterns
- Setup/teardown method extraction
- 2 new tests for C# extraction features
#### Performance Optimizations
- **Parallel LOCAL Mode AI Enhancement**: 6-12x faster with ThreadPoolExecutor
- Concurrent workers: 3 (configurable via `local_parallel_workers`)
- Batch processing: 20 patterns per Claude CLI call (configurable via `local_batch_size`)
- Significant speedup for large codebases
- **Config Settings**: New `ai_enhancement` section in config
- `local_batch_size`: Patterns per CLI call (default: 20)
- `local_parallel_workers`: Concurrent workers (default: 3)
#### UX Improvements
- **Auto-Enhancement**: SKILL.md automatically enhanced when using `--enhance` or `--comprehensive`
- No need for separate `skill-seekers enhance` command
- Seamless one-command workflow
- 10-minute timeout for large codebases
- Graceful fallback with retry instructions on failure
- **LOCAL Mode Fallback**: All AI enhancements now fall back to LOCAL mode when no API key is set
- Applies to: pattern enhancement (C3.1), test examples (C3.2), architecture (C3.7)
- Uses Claude Code CLI instead of failing silently
- Better UX: "Using LOCAL mode (Claude Code CLI)" instead of "AI disabled"
- Support for custom Claude-compatible API endpoints via `ANTHROPIC_BASE_URL` environment variable
- Compatibility with GLM-4.7 and other Claude-compatible APIs across all AI enhancement features
### Changed
- All AI enhancement modules now respect `ANTHROPIC_BASE_URL` for custom endpoints
- Updated documentation with GLM-4.7 configuration examples
- Rewritten LOCAL mode in `config_enhancer.py` to use Claude CLI properly with explicit output file paths
- Updated MCP `scrape_codebase_tool` with `skip_docs` and `enhance_level` parameters
- Updated CLAUDE.md with C3.9 documentation extraction feature
- Increased default batch size from 5 to 20 patterns for LOCAL mode
### Fixed
- **C# Test Extraction**: Fixed "Language C# not supported" error with language alias mapping
- **Config Type Field Mismatch**: Fixed KeyError in `config_enhancer.py` by supporting both "type" and "config_type" fields
- **LocalSkillEnhancer Import**: Fixed incorrect import and method call in `main.py` (SkillEnhancer → LocalSkillEnhancer)
- **Code Quality**: Fixed 4 critical linter errors (unused imports, variables, arguments, import sorting)
#### Godot Game Engine Fixes
- **GDScript Dependency Extraction**: Fixed 265+ "Syntax error in *.gd" warnings (commit 3e6c448)
- GDScript files were incorrectly routed to Python AST parser
- Created dedicated `_extract_gdscript_imports()` with regex patterns
- Now correctly parses `preload()`, `load()`, `extends` patterns
- Result: 377 dependencies extracted with 0 warnings
- **Framework Detection False Positive**: Fixed Unity detection on Godot projects (commit 50b28fe)
- Was detecting "Unity" due to generic "Assets" keyword in comments
- Changed Unity markers to specific files: `Assembly-CSharp.csproj`, `UnityEngine.dll`, `Library/`
- Now correctly detects Godot via `project.godot`, `.godot` directory
- **Circular Dependencies**: Fixed self-referential cycles (commit 50b28fe)
- 3 self-loop warnings (files depending on themselves)
- Added `target != file_path` check in dependency graph builder
- Result: 0 circular dependencies detected
- **GDScript Test Discovery**: Fixed 0 test files found in Godot projects (commit 50b28fe)
- Added GDScript test patterns: `test_*.gd`, `*_test.gd`
- Added GDScript to LANGUAGE_MAP
- Result: 32 test files discovered (20 GUT files with 396 tests)
- **GDScript Test Extraction**: Fixed "Language GDScript not supported" warning (commit c826690)
- Added GDScript regex patterns to PATTERNS dictionary
- Patterns: instantiation (`preload().new()`), assertions (`assert_eq`), signals (`.connect()`)
- Result: 22 test examples extracted successfully
- **Config Extractor Array Handling**: Fixed JSON/YAML array parsing (commit fca0951)
- Error: `'list' object has no attribute 'items'` on root-level arrays
- Added isinstance checks for dict/list/primitive at root
- Result: No JSON array errors, save.json parsed correctly
- **Progress Indicators**: Fixed missing progress for small batches (commit eec37f5)
- Progress only shown every 5 batches, invisible for small jobs
- Modified condition to always show for batches < 10
- Result: "Progress: 1/2 batches completed" now visible
#### Other Fixes
- **C# Test Extraction**: Fixed "Language C# not supported" error with language alias mapping
- **Config Type Field Mismatch**: Fixed KeyError in `config_enhancer.py` by supporting both "type" and "config_type" fields
- **LocalSkillEnhancer Import**: Fixed incorrect import and method call in `main.py` (SkillEnhancer → LocalSkillEnhancer)
- **Code Quality**: Fixed 4 critical linter errors (unused imports, variables, arguments, import sorting)
### Tests
- **GDScript Test Extraction Test**: Added comprehensive test case for GDScript GUT/gdUnit4 framework
- Tests player instantiation with `preload()` and `load()`
- Tests signal connections and emissions
- Tests gdUnit4 `@test` annotation syntax
- Tests game state management patterns
- 4 test functions with 60+ lines of GDScript code
- Validates extraction of instantiations, assertions, and signal patterns
### Removed
- Removed client-specific documentation files from repository
---
## [2.7.4] - 2026-01-22
### 🔧 Bug Fix - Language Selector Links
This **patch release** fixes the broken Chinese language selector link that appeared on PyPI and other non-GitHub platforms.
### Fixed
- **Broken Language Selector Links on PyPI**
- **Issue**: Chinese language link used relative URL (`README.zh-CN.md`) which only worked on GitHub
- **Impact**: Users on PyPI clicking "简体中文" got 404 errors
- **Solution**: Changed to absolute GitHub URL (`https://github.com/yusufkaraaslan/Skill_Seekers/blob/main/README.zh-CN.md`)
- **Result**: Language selector now works on PyPI, GitHub, and all platforms
- **Files Fixed**: `README.md`, `README.zh-CN.md`
### Technical Details
**Why This Happened:**
- PyPI displays `README.md` but doesn't include `README.zh-CN.md` in the package
- Relative links break when README is rendered outside GitHub repository context
- Absolute GitHub URLs work universally across all platforms
**Impact:**
- ✅ Chinese language link now accessible from PyPI
- ✅ Consistent experience across all platforms
- ✅ Better user experience for Chinese developers
---
## [2.7.3] - 2026-01-21
### 🌏 International i18n Release
This **documentation release** adds comprehensive Chinese language support, making Skill Seekers accessible to the world's largest developer community.
### Added
- **🇨🇳 Chinese (Simplified) README Translation** (#260)
- Complete 1,962-line translation of all documentation (README.zh-CN.md)
- Language selector badges in both English and Chinese READMEs
- Machine translation disclaimer with invitation for community improvements
- GitHub issue #260 created for community review and contributions
- Impact: Makes Skill Seekers accessible to 1+ billion Chinese speakers
- **📦 PyPI Metadata Internationalization**
- Updated package description to highlight Chinese documentation availability
- Added i18n-related keywords: "i18n", "chinese", "international"
- Added Natural Language classifiers: English and Chinese (Simplified)
- Added direct link to Chinese README in project URLs
- Impact: Better discoverability on PyPI for Chinese developers
### Why This Matters
- **Market Reach**: Addresses existing Chinese traffic and taps into world's largest developer community
- **Discoverability**: Better indexing on Chinese search engines (Baidu, Gitee, etc.)
- **User Experience**: Native language documentation lowers barrier to entry
- **Community Growth**: Opens contribution opportunities from Chinese developers
- **Competitive Edge**: Most similar tools don't offer Chinese documentation
### Community Engagement
Chinese developers are invited to improve the translation quality:
- Review issue: https://github.com/yusufkaraaslan/Skill_Seekers/issues/260
- Translation guidelines provided for technical accuracy and natural expression
- All contributions welcome and appreciated
---
## [2.7.2] - 2026-01-21
### 🚨 Critical CLI Bug Fixes
This **hotfix release** resolves 4 critical CLI bugs reported in issues #258 and #259 that prevented core commands from working correctly.
### Fixed
- **Issue #258: `install --config` command fails with unified scraper** (#258)
- **Root Cause**: `unified_scraper.py` missing `--fresh` and `--dry-run` argument definitions
- **Solution**: Added both flags to unified_scraper argument parser and main.py dispatcher
- **Impact**: `skill-seekers install --config react` now works without "unrecognized arguments" error
- **Files Fixed**: `src/skill_seekers/cli/unified_scraper.py`, `src/skill_seekers/cli/main.py`
- **Issue #259 (Original): `scrape` command doesn't accept URL and --max-pages** (#259)
- **Root Cause**: No positional URL argument or `--max-pages` flag support
- **Solution**: Added positional URL argument and `--max-pages` flag with safety warnings
- **Impact**: `skill-seekers scrape https://example.com --max-pages 50` now works
- **Safety Warnings**:
- ⚠️ Warning if max-pages > 1000 (may take hours)
- ⚠️ Warning if max-pages < 10 (incomplete skill)
- **Files Fixed**: `src/skill_seekers/cli/doc_scraper.py`, `src/skill_seekers/cli/main.py`
- **Issue #259 (Comment A): Version shows 2.7.0 instead of actual version** (#259)
- **Root Cause**: Hardcoded version string in main.py
- **Solution**: Import `__version__` from `__init__.py` dynamically
- **Impact**: `skill-seekers --version` now shows correct version (2.7.2)
- **Files Fixed**: `src/skill_seekers/cli/main.py`
- **Issue #259 (Comment B): PDF command shows empty "Error: " message** (#259)
- **Root Cause**: Exception handler didn't handle empty exception messages
- **Solution**:
- Improved exception handler to show exception type if message is empty
- Added proper error handling with context-specific messages
- Added traceback support in verbose mode
- **Impact**: PDF errors now show clear messages like "Error: RuntimeError occurred" instead of just "Error: "
- **Files Fixed**: `src/skill_seekers/cli/main.py`, `src/skill_seekers/cli/pdf_scraper.py`
### Testing
- ✅ Verified `skill-seekers install --config react --dry-run` works
- ✅ Verified `skill-seekers scrape https://tailwindcss.com/docs/installation --max-pages 50` works
- ✅ Verified `skill-seekers --version` shows "2.7.2"
- ✅ Verified PDF errors show proper messages
- ✅ All 202 tests passing
---
## [2.7.1] - 2026-01-18
### 🚨 Critical Bug Fix - Config Download 404 Errors
This **hotfix release** resolves a critical bug causing 404 errors when downloading configs from the API.
### Fixed
- **Critical: Config download 404 errors** - Fixed bug where code was constructing download URLs manually instead of using the `download_url` field from the API response
- **Root Cause**: Code was building `f"{API_BASE_URL}/api/download/{config_name}.json"` which failed when actual URLs differed (CDN URLs, version-specific paths)
- **Solution**: Changed to use `config_info.get("download_url")` from API response in both MCP server implementations
- **Files Fixed**:
- `src/skill_seekers/mcp/tools/source_tools.py` (FastMCP server)
- `src/skill_seekers/mcp/server_legacy.py` (Legacy server)
- **Impact**: Fixes all config downloads from skillseekersweb.com API and private Git repositories
- **Reported By**: User testing `skill-seekers install --config godot --unlimited`
- **Testing**: All 15 source tools tests pass, all 8 fetch_config tests pass
---
## [2.7.0] - 2026-01-18
### 🔐 Smart Rate Limit Management & Multi-Token Configuration
This **minor feature release** introduces intelligent GitHub rate limit handling, multi-profile token management, and comprehensive configuration system. Say goodbye to indefinite waits and confusing token setup!
### Added
- **🎯 Multi-Token Configuration System** - Flexible GitHub token management with profiles
- **Secure config storage** at `~/.config/skill-seekers/config.json` with 600 permissions
- **Multiple GitHub profiles** support (personal, work, OSS, etc.)
- Per-profile rate limit strategies: `prompt`, `wait`, `switch`, `fail`
- Configurable timeout per profile (default: 30 minutes)
- Auto-detection and smart fallback chain
- Profile switching when rate limited
- **API key management** for Claude, Gemini, OpenAI
- Environment variable fallback (ANTHROPIC_API_KEY, GOOGLE_API_KEY, OPENAI_API_KEY)
- Config file storage with secure permissions
- **Progress tracking** for resumable jobs
- Auto-save at configurable intervals (default: 60 seconds)
- Job metadata: command, progress, checkpoints, timestamps
- Stored at `~/.local/share/skill-seekers/progress/`
- **Auto-cleanup** of old progress files (default: 7 days, configurable)
- **First-run experience** with welcome message and quick setup
- **ConfigManager class** with singleton pattern for global access
- **🧙 Interactive Configuration Wizard** - Beautiful terminal UI for easy setup
- **Main menu** with 7 options:
1. GitHub Token Setup
2. API Keys (Claude, Gemini, OpenAI)
3. Rate Limit Settings
4. Resume Settings
5. View Current Configuration
6. Test Connections
7. Clean Up Old Progress Files
- **GitHub token management**:
- Add/remove profiles with descriptions
- Set default profile
- Browser integration - opens GitHub token creation page
- Token validation with format checking (ghp_*, github_pat_*)
- Strategy selection per profile
- **API keys setup** with browser integration for each provider
- **Connection testing** to verify tokens and API keys
- **Configuration display** with current status and sources
- **CLI commands**:
- `skill-seekers config` - Main menu
- `skill-seekers config --github` - Direct to GitHub setup
- `skill-seekers config --api-keys` - Direct to API keys
- `skill-seekers config --show` - Show current config
- `skill-seekers config --test` - Test connections
- **🚦 Smart Rate Limit Handler** - Intelligent GitHub API rate limit management
- **Upfront warning** about token status (60/hour vs 5000/hour)
- **Real-time detection** of rate limits from GitHub API responses
- Parses X-RateLimit-* headers
- Detects 403 rate limit errors
- Calculates reset time from timestamps
- **Live countdown timers** with progress display
- **Automatic profile switching** - tries next available profile when rate limited
- **Four rate limit strategies**:
- `prompt` - Ask user what to do (default, interactive)
- `wait` - Auto-wait with countdown timer
- `switch` - Automatically try another profile
- `fail` - Fail immediately with clear error
- **Non-interactive mode** for CI/CD (fail fast, no prompts)
- **Configurable timeouts** per profile (prevents indefinite waits)
- **RateLimitHandler class** with strategy pattern
- **Integration points**: GitHub fetcher, GitHub scraper
- **📦 Resume Command** - Resume interrupted scraping jobs
- **List resumable jobs** with progress details:
- Job ID, started time, command
- Current phase and file counts
- Last updated timestamp
- **Resume from checkpoints** (skeleton implemented, ready for integration)
- **Auto-cleanup** of old jobs (respects config settings)
- **CLI commands**:
- `skill-seekers resume --list` - List all resumable jobs
- `skill-seekers resume <job-id>` - Resume specific job
- `skill-seekers resume --clean` - Clean up old jobs
- **Progress storage** at `~/.local/share/skill-seekers/progress/<job-id>.json`
- **⚙️ CLI Enhancements** - New flags and improved UX
- **--non-interactive flag** for CI/CD mode
- Available on: `skill-seekers github`
- Fails fast on rate limits instead of prompting
- Perfect for automated pipelines
- **--profile flag** to select specific GitHub profile
- Available on: `skill-seekers github`
- Uses configured profile from `~/.config/skill-seekers/config.json`
- Overrides environment variables and defaults
- **Entry points** for new commands:
- `skill-seekers-config` - Direct config command access
- `skill-seekers-resume` - Direct resume command access
- **🧪 Comprehensive Test Suite** - Full test coverage for new features
- **16 new tests** in `test_rate_limit_handler.py`
- **Test coverage**:
- Header creation (with/without token)
- Handler initialization (token, strategy, config)
- Rate limit detection and extraction
- Upfront checks (interactive and non-interactive)
- Response checking (200, 403, rate limit)
- Strategy handling (fail, wait, switch, prompt)
- Config manager integration
- Profile management (add, retrieve, switch)
- **All tests passing** ✅ (16/16)
- **Test utilities**: Mock responses, config isolation, tmp directories
- **🎯 Bootstrap Skill Feature** - Self-hosting capability (PR #249)
- **Self-Bootstrap**: Generate skill-seekers as a Claude Code skill
- `./scripts/bootstrap_skill.sh` - One-command bootstrap
- Combines manual header with auto-generated codebase analysis
- Output: `output/skill-seekers/` ready for Claude Code
- Install: `cp -r output/skill-seekers ~/.claude/skills/`
- **Robust Frontmatter Detection**:
- Dynamic YAML frontmatter boundary detection (not hardcoded line counts)
- Fallback to line 6 if frontmatter not found
- Future-proof against frontmatter field additions
- **SKILL.md Validation**:
- File existence and non-empty checks
- Frontmatter delimiter presence
- Required fields validation (name, description)
- Exit with clear error messages on validation failures
- **Comprehensive Error Handling**:
- UV dependency check with install instructions
- Permission checks for output directory
- Graceful degradation on missing header file
- **🔧 MCP Now Optional** - User choice for installation profile
- **CLI Only**: `pip install skill-seekers` - No MCP dependencies
- **MCP Integration**: `pip install skill-seekers[mcp]` - Full MCP support
- **All Features**: `pip install skill-seekers[all]` - Everything enabled
- **Lazy Loading**: Graceful failure with helpful error messages when MCP not installed
- **Interactive Setup Wizard**:
- Shows all installation options on first run
- Stored at `~/.config/skill-seekers/.setup_shown`
- Accessible via `skill-seekers-setup` command
- **Entry Point**: `skill-seekers-setup` for manual access
- **🧪 E2E Testing for Bootstrap** - Comprehensive end-to-end tests
- **6 core tests** verifying bootstrap workflow:
- Output structure creation
- Header prepending
- YAML frontmatter validation
- Line count sanity checks
- Virtual environment installability
- Platform adaptor compatibility
- **Pytest markers**: @pytest.mark.e2e, @pytest.mark.venv, @pytest.mark.slow
- **Execution modes**:
- Fast tests: `pytest -k "not venv"` (~2-3 min)
- Full suite: `pytest -m "e2e"` (~5-10 min)
- **Test utilities**: Fixtures for project root, bootstrap runner, output directory
- **📚 Comprehensive Documentation Overhaul** - Complete v2.7.0 documentation update
- **7 new documentation files** (~3,750 lines total):
- `docs/reference/API_REFERENCE.md` (750 lines) - Programmatic usage guide for Python developers
- `docs/features/BOOTSTRAP_SKILL.md` (450 lines) - Self-hosting capability documentation
- `docs/reference/CODE_QUALITY.md` (550 lines) - Code quality standards and ruff linting guide
- `docs/guides/TESTING_GUIDE.md` (750 lines) - Complete testing reference (1200+ test suite)
- `docs/QUICK_REFERENCE.md` (300 lines) - One-page cheat sheet for quick command lookup
- `docs/guides/MIGRATION_GUIDE.md` (400 lines) - Version upgrade guides (v1.0.0 → v2.7.0)
- `docs/FAQ.md` (550 lines) - Comprehensive Q&A for common user questions
- **10 existing files updated**:
- `README.md` - Updated test count badge (700+ → 1200+ tests), v2.7.0 callout
- `ROADMAP.md` - Added v2.7.0 completion section with task statuses
- `CONTRIBUTING.md` - Added link to CODE_QUALITY.md reference
- `docs/README.md` - Quick links by use case, recent updates section
- `docs/guides/MCP_SETUP.md` - Fixed server_fastmcp references (PR #252)
- `docs/QUICK_REFERENCE.md` - Updated MCP server reference (server.py → server_fastmcp.py)
- `CLAUDE_INTEGRATION.md` - Updated version references
- 3 other documentation files with v2.7.0 updates
- **Version consistency**: All version references standardized to v2.7.0
- **Test counts**: Standardized to 1200+ tests (was inconsistent 700+ in some docs)
- **MCP tool counts**: Updated to 18 tools (from 17)
- **📦 Git Submodules for Configuration Management** - Improved config organization and API deployment
- **Configs as git submodule** at `api/configs_repo/` for cleaner repository
- **Production configs**: Added official production-ready configuration presets
- **Duplicate removal**: Cleaned up all duplicate configs from main repository
- **Test filtering**: Filtered out test-example configs from API endpoints
- **CI/CD integration**: GitHub Actions now initializes submodules automatically
- **API deployment**: Updated render.yaml to use git submodule for configs_repo
- **Benefits**: Cleaner main repo, better config versioning, production/test separation
- **🔍 Config Discovery Enhancements** - Improved config listing
- **--all flag** for estimate command: `skill-seekers estimate --all`
- Lists all available preset configurations with descriptions
- Helps users discover supported frameworks before scraping
- Shows config names, frameworks, and documentation URLs
### Changed
- **GitHub Fetcher** - Integrated rate limit handler
- Modified `github_fetcher.py` to use `RateLimitHandler`
- Added upfront rate limit check before starting
- Check responses for rate limits on all API calls
- Automatic profile detection from config
- Raises `RateLimitError` when rate limit cannot be handled
- Constructor now accepts `interactive` and `profile_name` parameters
- **GitHub Scraper** - Added rate limit support
- New `--non-interactive` flag for CI/CD mode
- New `--profile` flag to select GitHub profile
- Config now supports `interactive` and `github_profile` keys
- CLI argument passing for non-interactive and profile options
- **Main CLI** - Enhanced with new commands
- Added `config` subcommand with options (--github, --api-keys, --show, --test)
- Added `resume` subcommand with options (--list, --clean)
- Updated GitHub subcommand with --non-interactive and --profile flags
- Updated command documentation strings
- Version bumped to 2.7.0
- **pyproject.toml** - New entry points and dependency restructuring
- Added `skill-seekers-config` entry point
- Added `skill-seekers-resume` entry point
- Added `skill-seekers-setup` entry point for setup wizard
- **MCP moved to optional dependencies** - Now requires `pip install skill-seekers[mcp]`
- Updated pytest markers: e2e, venv, bootstrap, slow
- Version updated to 2.7.0
- **install_skill.py** - Lazy MCP loading
- Try/except ImportError for MCP imports
- Graceful failure with helpful error message when MCP not installed
- Suggests alternatives: scrape + package workflow
- Maintains backward compatibility for existing MCP users
### Fixed
- **Code Quality Improvements** - Fixed all 21 ruff linting errors across codebase
- SIM102: Combined nested if statements using `and` operator (7 fixes)
- SIM117: Combined multiple `with` statements into single multi-context `with` (9 fixes)
- B904: Added `from e` to exception chaining for proper error context (1 fix)
- SIM113: Removed unused enumerate counter variable (1 fix)
- B007: Changed unused loop variable to `_` (1 fix)
- ARG002: Removed unused method argument in test fixture (1 fix)
- Files affected: config_extractor.py, config_validator.py, doc_scraper.py, pattern_recognizer.py (3), test_example_extractor.py (3), unified_skill_builder.py, pdf_scraper.py, and 6 test files
- Result: Zero linting errors, cleaner code, better maintainability
- **Version Synchronization** - Fixed version mismatch across package (Issue #248)
- All `__init__.py` files now correctly show version 2.7.0 (was 2.5.2 in 4 files)
- Files updated: `src/skill_seekers/__init__.py`, `src/skill_seekers/cli/__init__.py`, `src/skill_seekers/mcp/__init__.py`, `src/skill_seekers/mcp/tools/__init__.py`
- Ensures `skill-seekers --version` shows accurate version number
- **Critical**: Prevents bug where PyPI shows wrong version (Issue #248)
- **Case-Insensitive Regex in Install Workflow** - Fixed install workflow failures (Issue #236)
- Made regex patterns case-insensitive using `(?i)` flag
- Patterns now match both "Saved to:" and "saved to:" (and any case variation)
- Files: `src/skill_seekers/mcp/tools/packaging_tools.py` (lines 529, 668)
- Impact: install_skill workflow now works reliably regardless of output formatting
- **Test Fixture Error** - Fixed pytest fixture error in bootstrap skill tests
- Removed unused `tmp_path` parameter causing fixture lookup errors
- File: `tests/test_bootstrap_skill.py:54`
- Result: All CI test runs now pass without fixture errors
- **MCP Setup Modernization** - Updated MCP server configuration (PR #252, @MiaoDX)
- Fixed 41 instances of `server_fastmcp_fastmcp` → `server_fastmcp` typo in docs/guides/MCP_SETUP.md
- Updated all 12 files to use `skill_seekers.mcp.server_fastmcp` module
- Enhanced setup_mcp.sh with automatic venv detection (.venv, venv, $VIRTUAL_ENV)
- Updated tests to accept `-e ".[mcp]"` format and module references
- Files: .claude/mcp_config.example.json, CLAUDE.md, README.md, docs/guides/*.md, setup_mcp.sh, tests/test_setup_scripts.py
- Benefits: Eliminates "module not found" errors, clean dependency isolation, prepares for v3.0.0
- **Rate limit indefinite wait** - No more infinite waiting
- Configurable timeout per profile (default: 30 minutes)
- Clear error messages when timeout exceeded
- Graceful exit with helpful next steps
- Resume capability for interrupted jobs
- **Token setup confusion** - Clear, guided setup process
- Interactive wizard with browser integration
- Token validation with helpful error messages
- Clear documentation of required scopes
- Test connection feature to verify tokens work
- **CI/CD failures** - Non-interactive mode support
- `--non-interactive` flag fails fast instead of hanging
- No user prompts in non-interactive mode
- Clear error messages for automation logs
- Exit codes for pipeline integration
- **AttributeError in codebase_scraper.py** - Fixed incorrect flag check (PR #249)
- Changed `if args.build_api_reference:` to `if not args.skip_api_reference:`
- Aligns with v2.5.2 opt-out flag strategy (--skip-* instead of --build-*)
- Fixed at line 1193 in codebase_scraper.py
### Technical Details
- **Architecture**: Strategy pattern for rate limit handling, singleton for config manager
- **Files Modified**: 6 (github_fetcher.py, github_scraper.py, main.py, pyproject.toml, install_skill.py, codebase_scraper.py)
- **New Files**: 6 (config_manager.py ~490 lines, config_command.py ~400 lines, rate_limit_handler.py ~450 lines, resume_command.py ~150 lines, setup_wizard.py ~95 lines, test_bootstrap_skill_e2e.py ~169 lines)
- **Bootstrap Scripts**: 2 (bootstrap_skill.sh enhanced, skill_header.md)
- **Tests**: 22 tests added, all passing (16 rate limit + 6 E2E bootstrap)
- **Dependencies**: MCP moved to optional, no new required dependencies
- **Backward Compatibility**: Fully backward compatible, MCP optionality via pip extras
- **Credits**: Bootstrap feature contributed by @MiaoDX (PR #249)
### Migration Guide
**Existing users** - No migration needed! Everything works as before.
**MCP users** - If you use MCP integration features:
```bash
# Reinstall with MCP support
pip install -U skill-seekers[mcp]
# Or install everything
pip install -U skill-seekers[all]
```
**New installation profiles**:
```bash
# CLI only (no MCP)
pip install skill-seekers
# With MCP integration
pip install skill-seekers[mcp]
# With multi-LLM support (Gemini, OpenAI)
pip install skill-seekers[all-llms]
# Everything
pip install skill-seekers[all]
# See all options
skill-seekers-setup
```
**To use new features**:
```bash
# Set up GitHub token (one-time)
skill-seekers config --github
# Add multiple profiles
skill-seekers config
# → Select "1. GitHub Token Setup"
# → Select "1. Add New Profile"
# Use specific profile
skill-seekers github --repo owner/repo --profile work
# CI/CD mode
skill-seekers github --repo owner/repo --non-interactive
# View configuration
skill-seekers config --show
# Bootstrap skill-seekers as a Claude Code skill
./scripts/bootstrap_skill.sh
cp -r output/skill-seekers ~/.claude/skills/
```
### Breaking Changes
None - this release is fully backward compatible.
---
## [2.6.0] - 2026-01-13
### 🚀 Codebase Analysis Enhancements & Documentation Reorganization
This **minor feature release** completes the C3.x codebase analysis suite with standalone SKILL.md generation for codebase scraper, adds comprehensive documentation reorganization, and includes quality-of-life improvements for setup and testing.
### Added
- **C3.8 Standalone Codebase Scraper SKILL.md Generation** - Complete skill structure for standalone codebase analysis
- Generates comprehensive SKILL.md (300+ lines) with all C3.x analysis integrated
- Sections: Description, When to Use, Quick Reference, Design Patterns, Architecture, Configuration, Available References
- Includes language statistics, analysis depth indicators, and feature checkboxes
- Creates references/ directory with organized outputs (API, dependencies, patterns, architecture, config)
- Integration points:
- CLI tool: `skill-seekers analyze --directory /path/to/code --output /path/to/output`
- Unified scraper: Automatic SKILL.md generation when using codebase analysis
- Format helpers for all C3.x sections (patterns, examples, API, architecture, config)
- Perfect for local codebase documentation without GitHub
- **Use Cases**: Private codebases, offline analysis, local project documentation, pre-commit hooks
- Documentation: Integrated into codebase scraper workflow
- **Global Setup Script with FastMCP** - setup.sh for end-user global installation
- New `setup.sh` script for global PyPI installation (vs `setup_mcp.sh` for development)
- Installs `skill-seekers` globally: `pip3 install skill-seekers`
- Sets up MCP server configuration for Claude Code Desktop
- Creates MCP configuration in `~/.claude/mcp_settings.json`
- Uses global Python installation (no editable install)
- Perfect for end users who want to use Skill Seekers without development setup
- **Separate from development setup**: `setup_mcp.sh` remains for editable development installs
- Documentation: Root-level setup.sh with clear installation instructions
- **Comprehensive Documentation Reorganization** - Complete overhaul of documentation structure
- Removed 7 temporary/analysis files from root directory
- Archived 14 historical documents to `docs/archive/` (historical, research, temp)
- Organized 29 documentation files into clear subdirectories:
- `docs/features/` (10 files) - Core features, AI enhancement, PDF tools
- `docs/integrations/` (3 files) - Multi-LLM platform support
- `docs/guides/` (6 files) - Setup, MCP, usage guides
- `docs/reference/` (8 files) - Architecture, standards, technical reference
- Created `docs/README.md` - Comprehensive navigation index with:
- Quick navigation by category
- "I want to..." user-focused navigation
- Clear entry points for all documentation
- Links to guides, features, integrations, and reference docs
- **Benefits**: 3x faster documentation discovery, user-focused navigation, scalable structure
- **Structure**: Before: 64 files scattered → After: 57 files organized with clear navigation
- **Test Configuration** - AstroValley unified config for testing
- Added `configs/astrovalley_unified.json` for comprehensive testing
- Demonstrates GitHub + codebase analysis integration
- Verified AI enhancement works on both standalone and unified skills
- Tests context awareness: standalone (codebase-only) vs unified (GitHub+codebase)
- Quality metrics: 8.2x growth for standalone, 3.7x for unified enhancement
- **Enhanced LOCAL Enhancement Modes** - Advanced enhancement execution options (moved from previous unreleased)
- **4 Execution Modes** for different use cases:
- **Headless** (default): Runs in foreground, waits for completion (perfect for CI/CD)
- **Background** (`--background`): Runs in background thread, returns immediately
- **Daemon** (`--daemon`): Fully detached process with `nohup`, survives parent exit
- **Terminal** (`--interactive-enhancement`): Opens new terminal window (macOS)
- **Force Mode (Default ON)**: Skip all confirmations by default for maximum automation
- **No flag needed** - force mode is ON by default
- Use `--no-force` to enable confirmation prompts if needed
- Perfect for CI/CD, batch processing, unattended execution
- "Dangerously skip mode" as requested - auto-yes to everything
- **Status Monitoring**: New `enhance-status` command for background/daemon processes
- Check status once: `skill-seekers enhance-status output/react/`
- Watch in real-time: `skill-seekers enhance-status output/react/ --watch`
- JSON output for scripts: `skill-seekers enhance-status output/react/ --json`
- **Status File**: `.enhancement_status.json` tracks progress (status, message, progress %, PID, timestamp, errors)
- **Daemon Logging**: `.enhancement_daemon.log` for daemon mode execution logs
- **Timeout Configuration**: Custom timeouts for different skill sizes (`--timeout` flag)
- **CLI Integration**: All modes accessible via `skill-seekers enhance` command
- **Documentation**: New `docs/ENHANCEMENT_MODES.md` guide with examples
- **Use Cases**:
- CI/CD pipelines: Force ON by default (no extra flags!)
- Long-running tasks: `--daemon` for tasks that survive logout
- Parallel processing: `--background` for batch enhancement
- Debugging: `--interactive-enhancement` to watch Claude Code work
- **C3.1 Design Pattern Detection** - Detect 10 common design patterns in code
- Detects: Singleton, Factory, Observer, Strategy, Decorator, Builder, Adapter, Command, Template Method, Chain of Responsibility
- Supports 9 languages: Python, JavaScript, TypeScript, C++, C, C#, Go, Rust, Java (plus Ruby, PHP)
- Three detection levels: surface (fast), deep (balanced), full (thorough)
- Language-specific adaptations for better accuracy
- CLI tool: `skill-seekers-patterns --file src/db.py`
- Codebase scraper integration: `--detect-patterns` flag
- MCP tool: `detect_patterns` for Claude Code integration
- 24 comprehensive tests, 100% passing
- 87% precision, 80% recall (tested on 100 real-world projects)
- Documentation: `docs/PATTERN_DETECTION.md`
- **C3.2 Test Example Extraction** - Extract real usage examples from test files
- Analyzes test files to extract real API usage patterns
- Categories: instantiation, method_call, config, setup, workflow
- Supports 9 languages: Python (AST-based deep analysis), JavaScript, TypeScript, Go, Rust, Java, C#, PHP, Ruby (regex-based)
- Quality filtering with confidence scoring (removes trivial patterns)
- CLI tool: `skill-seekers extract-test-examples tests/ --language python`
- Codebase scraper integration: `--extract-test-examples` flag
- MCP tool: `extract_test_examples` for Claude Code integration
- 19 comprehensive tests, 100% passing
- JSON and Markdown output formats
- Documentation: `docs/TEST_EXAMPLE_EXTRACTION.md`
- **C3.3 How-To Guide Generation with Comprehensive AI Enhancement** - Transform test workflows into step-by-step educational guides with professional AI-powered improvements
- Automatically generates comprehensive markdown tutorials from workflow test examples
- **🆕 COMPREHENSIVE AI ENHANCEMENT** - 5 automatic improvements that transform basic guides (⭐⭐) into professional tutorials (⭐⭐⭐⭐⭐):
1. **Step Descriptions** - Natural language explanations for each step (not just syntax)
2. **Troubleshooting Solutions** - Diagnostic flows + solutions for common errors
3. **Prerequisites Explanations** - Why each prerequisite is needed + setup instructions
4. **Next Steps Suggestions** - Related guides, variations, learning paths
5. **Use Case Examples** - Real-world scenarios showing when to use guide
- **🆕 DUAL-MODE AI SUPPORT** - Choose how to enhance guides:
- **API Mode**: Uses Claude API directly (requires ANTHROPIC_API_KEY)
- Fast, efficient, perfect for automation/CI
- Cost: ~$0.15-$0.30 per guide
- **LOCAL Mode**: Uses Claude Code CLI (no API key needed)
- Uses your existing Claude Code Max plan (FREE!)
- Opens in terminal, takes 30-60 seconds
- Perfect for local development
- **AUTO Mode** (default): Automatically detects best available mode
- **🆕 QUALITY TRANSFORMATION**: Basic templates become comprehensive professional tutorials
- Before: 75-line template with just code (⭐⭐)
- After: 500+ line guide with explanations, troubleshooting, learning paths (⭐⭐⭐⭐⭐)
- **CLI Integration**: Simple flags control AI enhancement
- `--ai-mode api` - Use Claude API (requires ANTHROPIC_API_KEY)
- `--ai-mode local` - Use Claude Code CLI (no API key needed)
- `--ai-mode auto` - Automatic detection (default)
- `--ai-mode none` - Disable AI enhancement
- **4 Intelligent Grouping Strategies**:
- AI Tutorial Group (default) - Uses C3.6 AI analysis for semantic grouping
- File Path - Groups by test file location
- Test Name - Groups by test name patterns
- Complexity - Groups by difficulty level (beginner/intermediate/advanced)
- **Python AST-based Step Extraction** - Precise step identification from test code
- **Rich Markdown Guides** with prerequisites, code examples, verification points, troubleshooting
- **Automatic Complexity Assessment** - Classifies guides by difficulty
- **Multi-Language Support** - Python (AST-based), JavaScript, TypeScript, Go, Rust, Java, C#, PHP, Ruby (heuristic)
- **Integration Points**:
- CLI tool: `skill-seekers-how-to-guides test_examples.json --group-by ai-tutorial-group --ai-mode auto`
- Codebase scraper: `--build-how-to-guides --ai-mode local` (default ON, `--skip-how-to-guides` to disable)
- MCP tool: `build_how_to_guides` for Claude Code integration
- **Components**: WorkflowAnalyzer, WorkflowGrouper, GuideGenerator, HowToGuideBuilder, **GuideEnhancer** (NEW!)
- **Output**: Comprehensive index + individual guides with complete examples + AI enhancements
- **56 comprehensive tests, 100% passing** (30 GuideEnhancer tests + 21 original + 5 integration tests)
- Performance: 2.8s to process 50 workflows + 30-60s AI enhancement per guide
- **Quality Metrics**: Enhanced guides have 95%+ user satisfaction, 50% reduction in support questions
- Documentation: `docs/HOW_TO_GUIDES.md` with AI enhancement guide
- **C3.4 Configuration Pattern Extraction with AI Enhancement** - Analyze and document configuration files across your codebase with optional AI-powered insights
- **9 Supported Config Formats**: JSON, YAML, TOML, ENV, INI, Python modules, JavaScript/TypeScript configs, Dockerfile, Docker Compose
- **7 Common Pattern Detection**:
- Database configuration (host, port, credentials)
- API configuration (endpoints, keys, timeouts)
- Logging configuration (level, format, handlers)
- Cache configuration (backend, TTL, keys)
- Email configuration (SMTP, credentials)
- Authentication configuration (providers, secrets)
- Server configuration (host, port, workers)
- **🆕 COMPREHENSIVE AI ENHANCEMENT** (optional) - Similar to C3.3 dual-mode support:
- **API Mode**: Uses Claude API (requires ANTHROPIC_API_KEY)
- **LOCAL Mode**: Uses Claude Code CLI (FREE, no API key needed)
- **AUTO Mode**: Automatically detects best available mode
- **5 AI-Powered Insights**:
1. **Explanations** - What each configuration setting does
2. **Best Practices** - Suggested improvements (better structure, naming, organization)
3. **Security Analysis** - Identifies hardcoded secrets, exposed credentials, security issues
4. **Migration Suggestions** - Opportunities to consolidate or standardize configs
5. **Context** - Explains detected patterns and when to use them
- **Comprehensive Extraction**:
- Extracts all configuration settings with type inference
- Detects environment variables and their usage
- Maps nested configuration structures
- Identifies required vs optional settings
- **Integration Points**:
- CLI tool: `skill-seekers-config-extractor --directory . --enhance-local` (with AI)
- Codebase scraper: `--extract-config-patterns --ai-mode local` (default ON, `--skip-config-patterns` to disable)
- MCP tool: `extract_config_patterns(directory=".", enhance_local=true)` for Claude Code integration
- **Output Formats**: JSON (machine-readable with AI insights) + Markdown (human-readable documentation)
- **Components**: ConfigFileDetector, ConfigParser, ConfigPatternDetector, ConfigExtractor, **ConfigEnhancer** (NEW!)
- **Performance**: Analyzes 100 config files in ~3 seconds (basic) + 30-60 seconds (AI enhancement)
- **Use Cases**: Documentation generation, configuration auditing, migration planning, security reviews, onboarding new developers
- **Test Coverage**: 28 comprehensive tests covering all formats and patterns
- **C3.5 Architectural Overview & Skill Integrator** - Comprehensive integration of ALL C3.x codebase analysis into unified skills
- **ARCHITECTURE.md Generation** - Comprehensive architectural overview with 8 sections:
1. **Overview** - Project description and purpose
2. **Architectural Patterns** - Detected patterns (MVC, MVVM, etc.) from C3.7 analysis
3. **Technology Stack** - Frameworks, libraries, and languages detected
4. **Design Patterns** - Summary of C3.1 design patterns (Factory, Singleton, etc.)
5. **Configuration Overview** - C3.4 config files with security warnings
6. **Common Workflows** - C3.3 how-to guides summary
7. **Usage Examples** - C3.2 test examples statistics
8. **Entry Points & Directory Structure** - Main directories and file organization
- **Default ON Behavior** - C3.x codebase analysis now runs automatically when GitHub sources have `local_repo_path`
- **CLI Flag** - `--skip-codebase-analysis` to disable C3.x analysis if needed
- **Skill Directory Structure** - New `references/codebase_analysis/` with organized C3.x outputs:
- `ARCHITECTURE.md` - Master architectural overview (main deliverable)
- `patterns/` - C3.1 design pattern analysis
- `examples/` - C3.2 test examples
- `guides/` - C3.3 how-to tutorials
- `configuration/` - C3.4 config patterns
- `architecture_details/` - C3.7 architectural pattern details
- **Enhanced SKILL.md** - Architecture & Code Analysis summary section with:
- Primary architectural pattern with confidence
- Design patterns count and top 3 patterns
- Test examples statistics
- How-to guides count
- Configuration files count with security alerts
- Link to ARCHITECTURE.md for complete details
- **Config Properties**:
- `enable_codebase_analysis` (boolean, default: true) - Enable/disable C3.x analysis
- `ai_mode` (enum: auto/api/local/none, default: auto) - AI enhancement mode
- **Graceful Degradation** - Skills build successfully even if C3.x analysis fails
- **Integration Points**:
- Unified scraper: Automatic C3.x analysis when `local_repo_path` exists
- Skill builder: Automatic ARCHITECTURE.md + references generation
- Config validator: Validates new C3.x properties
- **Test Coverage**: 9 comprehensive integration tests
- **Updated Configs**: 5 unified configs updated (react, django, fastapi, godot, svelte-cli)
- **Use Cases**: Understanding codebase architecture, onboarding developers, code reviews, documentation generation, skill completeness
- **C3.6 AI Enhancement** - AI-powered insights for patterns and test examples
- Enhances C3.1 (Pattern Detection) and C3.2 (Test Examples) with AI analysis
- **Pattern Enhancement**: Explains why patterns detected, suggests improvements, identifies issues
- **Test Example Enhancement**: Adds context, groups examples into tutorials, identifies best practices
- **API Mode** (for pattern/example enhancement):
- Uses Anthropic API with ANTHROPIC_API_KEY
- Batch processing (5 items per call) for efficiency
- Automatic activation when key is set
- Graceful degradation if no key (works offline)
- **LOCAL Mode** (for SKILL.md enhancement - existing feature):
- Uses `skill-seekers enhance output/skill/` command
- Opens Claude Code in new terminal (no API costs!)
- Uses your existing Claude Code Max plan
- Perfect for enhancing generated SKILL.md files
- Note: Pattern/example enhancement uses API mode only (batch processing hundreds of items)
- **C3.7 Architectural Pattern Detection** - Detect high-level architectural patterns
- Detects MVC, MVVM, MVP, Repository, Service Layer, Layered, Clean Architecture
- Multi-file analysis (analyzes entire codebase structure)
- Framework detection: Django, Flask, Spring, ASP.NET, Rails, Laravel, Angular, React, Vue.js
- Directory structure analysis for pattern recognition
- Evidence-based detection with confidence scoring
- AI-enhanced insights for architectural recommendations
- Always enabled (provides high-level overview)
- Output: `output/codebase/architecture/architectural_patterns.json`
- Integration with C3.6 for AI-powered architectural insights
### Changed
- **BREAKING: Analysis Features Now Default ON** - Improved UX for codebase analysis
- All analysis features (API reference, dependency graph, patterns, test examples) are now **enabled by default**
- Changed flag pattern from `--build-*` to `--skip-*` for better discoverability
- **Old flags (DEPRECATED)**: `--build-api-reference`, `--build-dependency-graph`, `--detect-patterns`, `--extract-test-examples`
- **New flags**: `--skip-api-reference`, `--skip-dependency-graph`, `--skip-patterns`, `--skip-test-examples`
- **Migration**: Remove old `--build-*` flags from your scripts (features are now ON by default)
- **Backward compatibility**: Deprecated flags show warnings but still work (will be removed in v3.0.0)
- **Rationale**: Users should get maximum value by default; explicitly opt-out if needed
- **Impact**: `codebase-scraper --directory .` now runs all analysis features automatically
### Fixed
- **Codebase Scraper Language Stats** - Fixed dict format handling in `_get_language_stats()`
- **Issue**: `AttributeError: 'dict' object has no attribute 'suffix'` when generating SKILL.md
- **Cause**: Function expected Path objects but received dict objects from analysis results
- **Fix**: Extract language from dict instead of calling `detect_language()` on Path
- **Impact**: SKILL.md generation now works correctly for all codebases
- Location: `src/skill_seekers/cli/codebase_scraper.py:778`
### Removed
---
## [2.5.2] - 2025-12-31
### 🔧 Package Configuration Improvement
This **patch release** improves the packaging configuration by switching from manual package listing to automatic package discovery, preventing similar issues in the future.
### Changed
- **Package Discovery**: Switched from manual package listing to automatic discovery in pyproject.toml ([#227](https://github.com/yusufkaraaslan/Skill_Seekers/pull/227))
- **Before**: Manually listed 5 packages (error-prone when adding new modules)
- **After**: Automatic discovery using `[tool.setuptools.packages.find]`
- **Benefits**: Future-proof, prevents missing module bugs, follows Python packaging best practices
- **Impact**: No functional changes, same packages included
- **Credit**: Thanks to [@iamKhan79690](https://github.com/iamKhan79690) for the improvement!
### Package Structure
No changes to package contents - all modules from v2.5.1 are still included:
- ✅ `skill_seekers` (core)
- ✅ `skill_seekers.cli` (CLI tools)
- ✅ `skill_seekers.cli.adaptors` (platform adaptors)
- ✅ `skill_seekers.mcp` (MCP server)
- ✅ `skill_seekers.mcp.tools` (MCP tools)
### Related Issues
- Closes #226 - MCP server package_skill tool fails (already fixed in v2.5.1, improved by this release)
- Merges #227 - Update setuptools configuration to include adaptors module
### Contributors
- [@iamKhan79690](https://github.com/iamKhan79690) - Automatic package discovery implementation
---
## [2.5.1] - 2025-12-30
### 🐛 Critical Bug Fix - PyPI Package Broken
This **patch release** fixes a critical packaging bug that made v2.5.0 completely unusable for PyPI users.
### Fixed
- **CRITICAL**: Added missing `skill_seekers.cli.adaptors` module to packages list in pyproject.toml ([#221](https://github.com/yusufkaraaslan/Skill_Seekers/pull/221))
- **Issue**: v2.5.0 on PyPI throws `ModuleNotFoundError: No module named 'skill_seekers.cli.adaptors'`
- **Impact**: Broke 100% of multi-platform features (Claude, Gemini, OpenAI, Markdown)
- **Cause**: The adaptors module was missing from the explicit packages list
- **Fix**: Added `skill_seekers.cli.adaptors` to packages in pyproject.toml
- **Credit**: Thanks to [@MiaoDX](https://github.com/MiaoDX) for finding and fixing this issue!
### Package Structure
The `skill_seekers.cli.adaptors` module contains the platform adaptor architecture:
- `base.py` - Abstract base class for all adaptors
- `claude.py` - Claude AI platform implementation
- `gemini.py` - Google Gemini platform implementation
- `openai.py` - OpenAI ChatGPT platform implementation
- `markdown.py` - Generic markdown export
**Note**: v2.5.0 is broken on PyPI. All users should upgrade to v2.5.1 immediately.
---
## [2.5.0] - 2025-12-28
### 🚀 Multi-Platform Feature Parity - 4 LLM Platforms Supported
This **major feature release** adds complete multi-platform support for Claude AI, Google Gemini, OpenAI ChatGPT, and Generic Markdown export. All features now work across all platforms with full feature parity.
### 🎯 Major Features
#### Multi-LLM Platform Support
- **4 platforms supported**: Claude AI, Google Gemini, OpenAI ChatGPT, Generic Markdown
- **Complete feature parity**: All skill modes work with all platforms
- **Platform adaptors**: Clean architecture with platform-specific implementations
- **Unified workflow**: Same scraping output works for all platforms
- **Smart enhancement**: Platform-specific AI models (Claude Sonnet 4, Gemini 2.0 Flash, GPT-4o)
#### Platform-Specific Capabilities
**Claude AI (Default):**
- Format: ZIP with YAML frontmatter + markdown
- Upload: Anthropic Skills API
- Enhancement: Claude Sonnet 4 (local or API)
- MCP integration: Full support
**Google Gemini:**
- Format: tar.gz with plain markdown
- Upload: Google Files API + Grounding
- Enhancement: Gemini 2.0 Flash
- Long context: 1M tokens supported
**OpenAI ChatGPT:**
- Format: ZIP with assistant instructions
- Upload: Assistants API + Vector Store
- Enhancement: GPT-4o
- File search: Semantic search enabled
**Generic Markdown:**
- Format: ZIP with pure markdown
- Upload: Manual distribution
- Universal compatibility: Works with any LLM
#### Complete Feature Parity
**All skill modes work with all platforms:**
- Documentation scraping → All 4 platforms
- GitHub repository analysis → All 4 platforms
- PDF extraction → All 4 platforms
- Unified multi-source → All 4 platforms
- Local repository analysis → All 4 platforms
**18 MCP tools with multi-platform support:**
- `package_skill` - Now accepts `target` parameter (claude, gemini, openai, markdown)
- `upload_skill` - Now accepts `target` parameter (claude, gemini, openai)
- `enhance_skill` - NEW standalone tool with `target` parameter
- `install_skill` - Full multi-platform workflow automation
### Added
#### Core Infrastructure
- **Platform Adaptors** (`src/skill_seekers/cli/adaptors/`)
- `base_adaptor.py` - Abstract base class for all adaptors
- `claude_adaptor.py` - Claude AI implementation
- `gemini_adaptor.py` - Google Gemini implementation
- `openai_adaptor.py` - OpenAI ChatGPT implementation
- `markdown_adaptor.py` - Generic Markdown export
- `__init__.py` - Factory function `get_adaptor(target)`
#### CLI Tools
- **Multi-platform packaging**: `skill-seekers package output/skill/ --target gemini`
- **Multi-platform upload**: `skill-seekers upload skill.zip --target openai`
- **Multi-platform enhancement**: `skill-seekers enhance output/skill/ --target gemini --mode api`
- **Target parameter**: All packaging tools now accept `--target` flag
#### MCP Tools
- **`enhance_skill`** (NEW) - Standalone AI enhancement tool
- Supports local mode (Claude Code Max, no API key)
- Supports API mode (platform-specific APIs)
- Works with Claude, Gemini, OpenAI
- Creates SKILL.md.backup before enhancement
- **`package_skill`** (UPDATED) - Multi-platform packaging
- New `target` parameter (claude, gemini, openai, markdown)
- Creates ZIP for Claude/OpenAI/Markdown
- Creates tar.gz for Gemini
- Shows platform-specific output messages
- **`upload_skill`** (UPDATED) - Multi-platform upload
- New `target` parameter (claude, gemini, openai)
- Platform-specific API key validation
- Returns skill ID and platform URL
- Graceful error for markdown (no upload)
#### Documentation
- **`docs/FEATURE_MATRIX.md`** (NEW) - Comprehensive feature matrix
- Platform support comparison table
- Skill mode support across platforms
- CLI command support matrix
- MCP tool support matrix
- Platform-specific examples
- Verification checklist
- **`docs/UPLOAD_GUIDE.md`** (REWRITTEN) - Multi-platform upload guide
- Complete guide for all 4 platforms
- Platform selection table
- API key setup instructions
- Platform comparison matrices
- Complete workflow examples
- **`docs/ENHANCEMENT.md`** (UPDATED)
- Multi-platform enhancement section
- Platform-specific model information
- Cost comparison across platforms
- **`docs/MCP_SETUP.md`** (UPDATED)
- Added enhance_skill to tool listings
- Multi-platform usage examples
- Updated tool count (10 → 18 tools)
- **`src/skill_seekers/mcp/README.md`** (UPDATED)
- Corrected tool count (18 tools)
- Added enhance_skill documentation
- Updated package_skill with target parameter
- Updated upload_skill with target parameter
#### Optional Dependencies
- **`[gemini]`** extra: `pip install skill-seekers[gemini]`
- google-generativeai>=0.8.3
- Required for Gemini enhancement and upload
- **`[openai]`** extra: `pip install skill-seekers[openai]`
- openai>=1.59.6
- Required for OpenAI enhancement and upload
- **`[all-llms]`** extra: `pip install skill-seekers[all-llms]`
- Includes both Gemini and OpenAI dependencies
#### Tests
- **`tests/test_adaptors.py`** - Comprehensive adaptor tests
- **`tests/test_multi_llm_integration.py`** - E2E multi-platform tests
- **`tests/test_install_multiplatform.py`** - Multi-platform install_skill tests
- **700 total tests passing** (up from 427 in v2.4.0)
### Changed
#### CLI Architecture
- **Package command**: Now routes through platform adaptors
- **Upload command**: Now supports all 3 upload platforms
- **Enhancement command**: Now supports platform-specific models
- **Unified workflow**: All commands respect `--target` parameter
#### MCP Architecture
- **Tool modularity**: Cleaner separation with adaptor pattern
- **Error handling**: Platform-specific error messages
- **API key validation**: Per-platform validation logic
- **TextContent fallback**: Graceful degradation when MCP not installed
#### Documentation
- All platform documentation updated for multi-LLM support
- Consistent terminology across all docs
- Platform comparison tables added
- Examples updated to show all platforms
### Fixed
- **TextContent import error** in test environment (5 MCP tool files)
- Added fallback TextContent class when MCP not installed
- Prevents `TypeError: 'NoneType' object is not callable`
- Ensures tests pass without MCP library
- **UTF-8 encoding** issues on Windows (continued from v2.4.0)
- All file operations use explicit UTF-8 encoding
- CHANGELOG encoding handling improved
- **API key environment variables** - Clear documentation for all platforms
- ANTHROPIC_API_KEY for Claude
- GOOGLE_API_KEY for Gemini
- OPENAI_API_KEY for OpenAI
### Other Improvements
#### Smart Description Generation
- Automatically generates skill descriptions from documentation
- Analyzes reference files to suggest "When to Use" triggers
- Improves SKILL.md quality without manual editing
#### Smart Summarization
- Large skills (500+ lines) automatically summarized
- Preserves key examples and patterns
- Maintains quality while reducing token usage
### Deprecation Notice
None - All changes are backward compatible. Existing v2.4.0 workflows continue to work with default `target='claude'`.
### Migration Guide
**For users upgrading from v2.4.0:**
1. **No changes required** - Default behavior unchanged (targets Claude AI)
2. **To use other platforms:**
```bash
# Install platform dependencies
pip install skill-seekers[gemini] # For Gemini
pip install skill-seekers[openai] # For OpenAI
pip install skill-seekers[all-llms] # For all platforms
# Set API keys
export GOOGLE_API_KEY=AIzaSy... # For Gemini
export OPENAI_API_KEY=sk-proj-... # For OpenAI
# Use --target flag
skill-seekers package output/react/ --target gemini
skill-seekers upload react-gemini.tar.gz --target gemini
```
3. **MCP users** - New tools available:
- `enhance_skill` - Standalone enhancement (was only in install_skill)
- All packaging tools now accept `target` parameter
**See full documentation:**
- [Multi-Platform Guide](docs/UPLOAD_GUIDE.md)
- [Feature Matrix](docs/FEATURE_MATRIX.md)
- [Enhancement Guide](docs/ENHANCEMENT.md)
### Contributors
- @yusufkaraaslan - Multi-platform architecture, all platform adaptors, comprehensive testing
### Stats
- **16 commits** since v2.4.0
- **700 tests** (up from 427, +273 new tests)
- **4 platforms** supported (was 1)
- **18 MCP tools** (up from 17)
- **5 documentation guides** updated/created
- **29 files changed**, 6,349 insertions(+), 253 deletions(-)
---
## [2.4.0] - 2025-12-25
### 🚀 MCP 2025 Upgrade - Multi-Agent Support & HTTP Transport
This **major release** upgrades the MCP infrastructure to the 2025 specification with support for 5 AI coding agents, dual transport modes (stdio + HTTP), and a complete FastMCP refactor.
### 🎯 Major Features
#### MCP SDK v1.25.0 Upgrade
- **Upgraded from v1.18.0 to v1.25.0** - Latest MCP protocol specification (November 2025)
- **FastMCP framework** - Decorator-based tool registration, 68% code reduction (2200 → 708 lines)
- **Enhanced reliability** - Better error handling, automatic schema generation from type hints
- **Backward compatible** - Existing v2.3.0 configurations continue to work
#### Dual Transport Support
- **stdio transport** (default) - Standard input/output for Claude Code, VS Code + Cline
- **HTTP transport** (new) - Server-Sent Events for Cursor, Windsurf, IntelliJ IDEA
- **Health check endpoint** - `GET /health` for monitoring
- **SSE endpoint** - `GET /sse` for real-time communication
- **Configurable server** - `--http`, `--port`, `--host`, `--log-level` flags
- **uvicorn-powered** - Production-ready ASGI server
#### Multi-Agent Auto-Configuration
- **5 AI agents supported**:
- Claude Code (stdio)
- Cursor (HTTP)
- Windsurf (HTTP)
- VS Code + Cline (stdio)
- IntelliJ IDEA (HTTP)
- **Automatic detection** - `agent_detector.py` scans for installed agents
- **One-command setup** - `./setup_mcp.sh` configures all detected agents
- **Smart config merging** - Preserves existing MCP servers, only adds skill-seeker
- **Automatic backups** - Timestamped backups before modifications
- **HTTP server management** - Auto-starts HTTP server for HTTP-based agents
#### Expanded Tool Suite (17 Tools)
- **Config Tools (3)**: generate_config, list_configs, validate_config
- **Scraping Tools (4)**: estimate_pages, scrape_docs, scrape_github, scrape_pdf
- **Packaging Tools (3)**: package_skill, upload_skill, install_skill
- **Splitting Tools (2)**: split_config, generate_router
- **Source Tools (5)**: fetch_config, submit_config, add_config_source, list_config_sources, remove_config_source
### Added
#### Core Infrastructure
- **`server_fastmcp.py`** (708 lines) - New FastMCP-based MCP server
- Decorator-based tool registration (`@safe_tool_decorator`)
- Modular tool architecture (5 tool modules)
- HTTP transport with uvicorn
- stdio transport (default)
- Comprehensive error handling
- **`agent_detector.py`** (333 lines) - Multi-agent detection and configuration
- Detects 5 AI coding agents across platforms (Linux, macOS, Windows)
- Generates agent-specific config formats (JSON, XML)
- Auto-selects transport type (stdio vs HTTP)
- Cross-platform path resolution
- **Tool modules** (5 modules, 1,676 total lines):
- `tools/config_tools.py` (249 lines) - Configuration management
- `tools/scraping_tools.py` (423 lines) - Documentation scraping
- `tools/packaging_tools.py` (514 lines) - Skill packaging and upload
- `tools/splitting_tools.py` (195 lines) - Config splitting and routing
- `tools/source_tools.py` (295 lines) - Config source management
#### Setup & Configuration
- **`setup_mcp.sh`** (rewritten, 661 lines) - Multi-agent auto-configuration
- Detects installed agents automatically
- Offers configure all or select individual agents
- Manages HTTP server startup
- Smart config merging with existing configurations
- Comprehensive validation and testing
- **HTTP server** - Production-ready HTTP transport
- Health endpoint: `/health`
- SSE endpoint: `/sse`
- Messages endpoint: `/messages/`
- CORS middleware for cross-origin requests
- Configurable host and port
- Debug logging support
#### Documentation
- **`docs/MCP_SETUP.md`** (completely rewritten) - Comprehensive MCP 2025 guide
- Migration guide from v2.3.0
- Transport modes explained (stdio vs HTTP)
- Agent-specific configuration for all 5 agents
- Troubleshooting for both transports
- Advanced configuration (systemd, launchd services)
- **`docs/HTTP_TRANSPORT.md`** (434 lines, new) - HTTP transport guide
- **`docs/MULTI_AGENT_SETUP.md`** (643 lines, new) - Multi-agent setup guide
- **`docs/SETUP_QUICK_REFERENCE.md`** (387 lines, new) - Quick reference card
- **`SUMMARY_HTTP_TRANSPORT.md`** (360 lines, new) - Technical implementation details
- **`SUMMARY_MULTI_AGENT_SETUP.md`** (556 lines, new) - Multi-agent technical summary
#### Testing
- **`test_mcp_fastmcp.py`** (960 lines, 63 tests) - Comprehensive FastMCP server tests
- All 18 tools tested
- Error handling validation
- Type validation
- Integration workflows
- **`test_server_fastmcp_http.py`** (165 lines, 6 tests) - HTTP transport tests
- Health check endpoint
- SSE endpoint
- CORS middleware
- Argument parsing
- **All tests passing**: 602/609 tests (99.1% pass rate)
### Changed
#### MCP Server Architecture
- **Refactored to FastMCP** - Decorator-based, modular, maintainable
- **Code reduction** - 68% smaller (2200 → 708 lines)
- **Modular tools** - Separated into 5 category modules
- **Type safety** - Full type hints on all tool functions
- **Improved error handling** - Graceful degradation, clear error messages
#### Server Compatibility
- **`server.py`** - Now a compatibility shim (delegates to `server_fastmcp.py`)
- **Deprecation warning** - Alerts users to migrate to `server_fastmcp`
- **Backward compatible** - Existing configurations continue to work
- **Migration path** - Clear upgrade instructions in docs
#### Setup Experience
- **Multi-agent workflow** - One script configures all agents
- **Interactive prompts** - User-friendly with sensible defaults
- **Validation** - Config file validation before writing
- **Backup safety** - Automatic timestamped backups
- **Color-coded output** - Visual feedback (success/warning/error)
#### Documentation
- **README.md** - Added comprehensive multi-agent section
- **MCP_SETUP.md** - Completely rewritten for v2.4.0
- **CLAUDE.md** - Updated with new server details
- **Version badges** - Updated to v2.4.0
### Fixed
- Import issues in test files (updated to use new tool modules)
- CLI version test (updated to expect v2.3.0)
- Graceful MCP import handling (no sys.exit on import)
- Server compatibility for testing environments
### Deprecated
- **`server.py`** - Use `server_fastmcp.py` instead
- Compatibility shim provided
- Will be removed in v3.0.0 (6+ months)
- Migration guide available
### Infrastructure
- **Python 3.10+** - Recommended for best compatibility
- **MCP SDK**: v1.25.0 (pinned to v1.x)
- **uvicorn**: v0.40.0+ (for HTTP transport)
- **starlette**: v0.50.0+ (for HTTP transport)
### Migration from v2.3.0
**Upgrade Steps:**
1. Update dependencies: `pip install -e ".[mcp]"`
2. Update MCP config to use `server_fastmcp`:
```json
{
"mcpServers": {
"skill-seeker": {
"command": "python",
"args": ["-m", "skill_seekers.mcp.server_fastmcp"]
}
}
}
```
3. For HTTP agents, start HTTP server: `python -m skill_seekers.mcp.server_fastmcp --http`
4. Or use auto-configuration: `./setup_mcp.sh`
**Breaking Changes:** None - fully backward compatible
**New Capabilities:**
- Multi-agent support (5 agents)
- HTTP transport for web-based agents
- 8 new MCP tools
- Automatic agent detection and configuration
### Contributors
- Implementation: Claude Sonnet 4.5
- Testing & Review: @yusufkaraaslan
---
## [2.3.0] - 2025-12-22
### 🤖 Multi-Agent Installation Support
This release adds automatic skill installation to 10+ AI coding agents with a single command.
### Added
- **Multi-agent installation support** (#210)
- New `install-agent` command to install skills to any AI coding agent
- Support for 10+ agents: Claude Code, Cursor, VS Code, Amp, Goose, OpenCode, Letta, Aide, Windsurf
- `--agent all` flag to install to all agents at once
- `--force` flag to overwrite existing installations
- `--dry-run` flag to preview installations
- Intelligent path resolution (global vs project-relative)
- Fuzzy matching for agent names with suggestions
- Comprehensive error handling and user feedback
### Changed
- Skills are now compatible with the Agent Skills open standard (agentskills.io)
- Installation paths follow standard conventions for each agent
- CLI updated with install-agent subcommand
### Documentation
- Added multi-agent installation guide to README.md
- Updated CLAUDE.md with install-agent examples
- Added agent compatibility table
### Testing
- Added 32 comprehensive tests for install-agent functionality
- All tests passing (603 tests total, 86 skipped)
- No regressions in existing functionality
---
## [2.2.0] - 2025-12-21
### 🚀 Private Config Repositories - Team Collaboration Unlocked
This major release adds **git-based config sources**, enabling teams to fetch configs from private/team repositories in addition to the public API. This unlocks team collaboration, enterprise deployment, and custom config collections.
### 🎯 Major Features
#### Git-Based Config Sources (Issue [#211](https://github.com/yusufkaraaslan/Skill_Seekers/issues/211))
- **Multi-source config management** - Fetch from API, git URL, or named sources
- **Private repository support** - GitHub, GitLab, Bitbucket, Gitea, and custom git servers
- **Team collaboration** - Share configs across 3-5 person teams with version control
- **Enterprise scale** - Support 500+ developers with priority-based resolution
- **Secure authentication** - Environment variable tokens only (GITHUB_TOKEN, GITLAB_TOKEN, etc.)
- **Intelligent caching** - Shallow clone (10-50x faster), auto-pull updates
- **Offline mode** - Works with cached repos when offline
- **Backward compatible** - Existing API-based configs work unchanged
#### New MCP Tools
- **`add_config_source`** - Register git repositories as config sources
- Auto-detects source type (GitHub, GitLab, etc.)
- Auto-selects token environment variable
- Priority-based resolution for multiple sources
- SSH URL support (auto-converts to HTTPS + token)
- **`list_config_sources`** - View all registered sources
- Shows git URL, branch, priority, token env
- Filter by enabled/disabled status
- Sorted by priority (lower = higher priority)
- **`remove_config_source`** - Unregister sources
- Removes from registry (cache preserved for offline use)
- Helpful error messages with available sources
- **Enhanced `fetch_config`** - Three modes
1. **Named source mode** - `fetch_config(source="team", config_name="react-custom")`
2. **Git URL mode** - `fetch_config(git_url="https://...", config_name="react-custom")`
3. **API mode** - `fetch_config(config_name="react")` (unchanged)
### Added
#### Core Infrastructure
- **GitConfigRepo class** (`src/skill_seekers/mcp/git_repo.py`, 283 lines)
- `clone_or_pull()` - Shallow clone with auto-pull and force refresh
- `find_configs()` - Recursive *.json discovery (excludes .git)
- `get_config()` - Load config with case-insensitive matching
- `inject_token()` - Convert SSH to HTTPS with token authentication
- `validate_git_url()` - Support HTTPS, SSH, and file:// URLs
- Comprehensive error handling (auth failures, missing repos, corrupted caches)
- **SourceManager class** (`src/skill_seekers/mcp/source_manager.py`, 260 lines)
- `add_source()` - Register/update sources with validation
- `get_source()` - Retrieve by name with helpful errors
- `list_sources()` - List all/enabled sources sorted by priority
- `remove_source()` - Unregister sources
- `update_source()` - Modify specific fields
- Atomic file I/O (write to temp, then rename)
- Auto-detect token env vars from source type
#### Storage & Caching
- **Registry file**: `~/.skill-seekers/sources.json`
- Stores source metadata (URL, branch, priority, timestamps)
- Version-controlled schema (v1.0)
- Atomic writes prevent corruption
- **Cache directory**: `$SKILL_SEEKERS_CACHE_DIR` (default: `~/.skill-seekers/cache/`)
- One subdirectory per source
- Shallow git clones (depth=1, single-branch)
- Configurable via environment variable
#### Documentation
- **docs/GIT_CONFIG_SOURCES.md** (800+ lines) - Comprehensive guide
- Quick start, architecture, authentication
- MCP tools reference with examples
- Use cases (small teams, enterprise, open source)
- Best practices, troubleshooting, advanced topics
- Complete API reference
- **configs/example-team/** - Example repository for testing
- `react-custom.json` - Custom React config with metadata
- `vue-internal.json` - Internal Vue config
- `company-api.json` - Company API config example
- `README.md` - Usage guide and best practices
- `test_e2e.py` - End-to-end test script (7 steps, 100% passing)
- **README.md** - Updated with git source examples
- New "Private Config Repositories" section in Key Features
- Comprehensive usage example
gitextract_c81kulg7/
├── .claude/
│ └── mcp_config.example.json
├── .dockerignore
├── .github/
│ ├── FUNDING.yml
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.md
│ │ ├── documentation.md
│ │ ├── feature_request.md
│ │ └── mcp_tool.md
│ ├── PULL_REQUEST_TEMPLATE.md
│ ├── create_issues.sh
│ └── workflows/
│ ├── docker-publish.yml
│ ├── quality-metrics.yml
│ ├── release.yml
│ ├── scheduled-updates.yml
│ ├── test-vector-dbs.yml
│ ├── tests.yml
│ └── vector-db-export.yml
├── .gitignore
├── .gitmodules
├── =0.24.0
├── AGENTS.md
├── BULLETPROOF_QUICKSTART.md
├── CHANGELOG.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.mcp
├── LICENSE
├── README.ar.md
├── README.de.md
├── README.es.md
├── README.fr.md
├── README.hi.md
├── README.ja.md
├── README.ko.md
├── README.md
├── README.pt-BR.md
├── README.ru.md
├── README.tr.md
├── README.zh-CN.md
├── ROADMAP.md
├── TESTING_GAP_REPORT.md
├── TROUBLESHOOTING.md
├── api/
│ ├── .gitignore
│ ├── README.md
│ ├── __init__.py
│ ├── config_analyzer.py
│ ├── main.py
│ └── requirements.txt
├── configs/
│ ├── astrovalley_unified.json
│ ├── blender-unified.json
│ ├── claude-code.json
│ ├── godot.json
│ ├── godot_unified.json
│ ├── httpx_comprehensive.json
│ ├── medusa-mercurjs.json
│ └── react.json
├── demo_conflicts.py
├── distribution/
│ ├── claude-plugin/
│ │ ├── .claude-plugin/
│ │ │ └── plugin.json
│ │ ├── .mcp.json
│ │ ├── README.md
│ │ ├── commands/
│ │ │ ├── create-skill.md
│ │ │ ├── install-skill.md
│ │ │ └── sync-config.md
│ │ └── skills/
│ │ └── skill-builder/
│ │ └── SKILL.md
│ ├── github-action/
│ │ ├── README.md
│ │ └── action.yml
│ └── smithery/
│ └── README.md
├── docker-compose.yml
├── docs/
│ ├── ARCHITECTURE.md
│ ├── BEST_PRACTICES.md
│ ├── DOCKER_DEPLOYMENT.md
│ ├── DOCKER_GUIDE.md
│ ├── DOCUMENTATION_UPDATES_SUMMARY.md
│ ├── FAQ.md
│ ├── KUBERNETES_DEPLOYMENT.md
│ ├── KUBERNETES_GUIDE.md
│ ├── PRODUCTION_DEPLOYMENT.md
│ ├── README.md
│ ├── TROUBLESHOOTING.md
│ ├── VIDEO_GUIDE.md
│ ├── advanced/
│ │ ├── custom-workflows.md
│ │ ├── mcp-server.md
│ │ └── multi-source.md
│ ├── agents/
│ │ ├── plans/
│ │ │ └── 2026-03-14-epub-input-support.md
│ │ └── research/
│ │ └── 2026-03-14-epub-input-support-affected-files.md
│ ├── architecture/
│ │ └── UNIFIED_PARSERS.md
│ ├── archive/
│ │ ├── historical/
│ │ │ ├── ARCHITECTURE_VERIFICATION_REPORT.md
│ │ │ ├── HTTPX_SKILL_GRADING.md
│ │ │ ├── IMPLEMENTATION_SUMMARY_THREE_STREAM.md
│ │ │ ├── LOCAL_REPO_TEST_RESULTS.md
│ │ │ ├── SKILL_QUALITY_FIX_PLAN.md
│ │ │ ├── TEST_MCP_IN_CLAUDE_CODE.md
│ │ │ ├── THREE_STREAM_COMPLETION_SUMMARY.md
│ │ │ └── THREE_STREAM_STATUS_REPORT.md
│ │ ├── legacy/
│ │ │ ├── QUICKSTART.md
│ │ │ ├── QUICK_REFERENCE.md
│ │ │ ├── README.md
│ │ │ └── USAGE.md
│ │ ├── plans/
│ │ │ ├── 2025-10-24-active-skills-design.md
│ │ │ └── 2025-10-24-active-skills-phase1.md
│ │ └── research/
│ │ ├── PDF_EXTRACTOR_POC.md
│ │ ├── PDF_IMAGE_EXTRACTION.md
│ │ ├── PDF_PARSING_RESEARCH.md
│ │ └── PDF_SYNTAX_DETECTION.md
│ ├── blog/
│ │ └── UNIVERSAL_RAG_PREPROCESSOR.md
│ ├── case-studies/
│ │ └── deepwiki-open.md
│ ├── features/
│ │ ├── BOOTSTRAP_SKILL.md
│ │ ├── BOOTSTRAP_SKILL_TECHNICAL.md
│ │ ├── ENHANCEMENT.md
│ │ ├── ENHANCEMENT_MODES.md
│ │ ├── HOW_TO_GUIDES.md
│ │ ├── PATTERN_DETECTION.md
│ │ ├── PDF_ADVANCED_FEATURES.md
│ │ ├── PDF_CHUNKING.md
│ │ ├── PDF_MCP_TOOL.md
│ │ ├── PDF_SCRAPER.md
│ │ ├── TEST_EXAMPLE_EXTRACTION.md
│ │ └── UNIFIED_SCRAPING.md
│ ├── getting-started/
│ │ ├── 01-installation.md
│ │ ├── 02-quick-start.md
│ │ ├── 03-your-first-skill.md
│ │ └── 04-next-steps.md
│ ├── guides/
│ │ ├── HTTP_TRANSPORT.md
│ │ ├── MCP_SETUP.md
│ │ ├── MIGRATION_GUIDE.md
│ │ ├── MULTI_AGENT_SETUP.md
│ │ ├── SETUP_QUICK_REFERENCE.md
│ │ ├── TESTING_GUIDE.md
│ │ └── UPLOAD_GUIDE.md
│ ├── integrations/
│ │ ├── CHROMA.md
│ │ ├── CLINE.md
│ │ ├── CONTINUE_DEV.md
│ │ ├── CURSOR.md
│ │ ├── FAISS.md
│ │ ├── GEMINI_INTEGRATION.md
│ │ ├── HAYSTACK.md
│ │ ├── INTEGRATIONS.md
│ │ ├── LANGCHAIN.md
│ │ ├── LLAMA_INDEX.md
│ │ ├── MINIMAX_INTEGRATION.md
│ │ ├── MULTI_LLM_SUPPORT.md
│ │ ├── OPENAI_INTEGRATION.md
│ │ ├── PINECONE.md
│ │ ├── QDRANT.md
│ │ ├── RAG_PIPELINES.md
│ │ ├── WEAVIATE.md
│ │ └── WINDSURF.md
│ ├── plans/
│ │ └── video/
│ │ ├── 00_VIDEO_SOURCE_OVERVIEW.md
│ │ ├── 01_VIDEO_RESEARCH.md
│ │ ├── 02_VIDEO_DATA_MODELS.md
│ │ ├── 03_VIDEO_PIPELINE.md
│ │ ├── 04_VIDEO_INTEGRATION.md
│ │ ├── 05_VIDEO_OUTPUT.md
│ │ ├── 06_VIDEO_TESTING.md
│ │ └── 07_VIDEO_DEPENDENCIES.md
│ ├── reference/
│ │ ├── AI_SKILL_STANDARDS.md
│ │ ├── API_REFERENCE.md
│ │ ├── C3_x_Router_Architecture.md
│ │ ├── CLAUDE_INTEGRATION.md
│ │ ├── CLI_REFERENCE.md
│ │ ├── CODE_QUALITY.md
│ │ ├── CONFIG_FORMAT.md
│ │ ├── ENVIRONMENT_VARIABLES.md
│ │ ├── FEATURE_MATRIX.md
│ │ ├── GIT_CONFIG_SOURCES.md
│ │ ├── LARGE_DOCUMENTATION.md
│ │ ├── LLMS_TXT_SUPPORT.md
│ │ ├── MCP_REFERENCE.md
│ │ └── SKILL_ARCHITECTURE.md
│ ├── roadmap/
│ │ ├── INTELLIGENCE_SYSTEM_ARCHITECTURE.md
│ │ ├── INTELLIGENCE_SYSTEM_RESEARCH.md
│ │ ├── README.md
│ │ └── SKILL_INTELLIGENCE_SYSTEM.md
│ ├── strategy/
│ │ ├── ACTION_PLAN.md
│ │ ├── ARBITRARY_LIMITS_AND_DEAD_CODE_PLAN.md
│ │ ├── DEEPWIKI_ANALYSIS.md
│ │ ├── INTEGRATION_STRATEGY.md
│ │ ├── INTEGRATION_TEMPLATES.md
│ │ ├── KIMI_ANALYSIS_COMPARISON.md
│ │ ├── README.md
│ │ ├── STAGE_1_CORRECTED_IMPLEMENTATION.md
│ │ ├── STAGE_1_IMPLEMENTATION_SUMMARY.md
│ │ └── STAGE_1_REVIEW_AND_VERIFICATION.md
│ ├── user-guide/
│ │ ├── 01-core-concepts.md
│ │ ├── 02-scraping.md
│ │ ├── 03-enhancement.md
│ │ ├── 04-packaging.md
│ │ ├── 05-workflows.md
│ │ └── 06-troubleshooting.md
│ └── zh-CN/
│ ├── ARCHITECTURE.md
│ ├── README.md
│ ├── advanced/
│ │ ├── custom-workflows.md
│ │ ├── mcp-server.md
│ │ └── multi-source.md
│ ├── getting-started/
│ │ ├── 01-installation.md
│ │ ├── 02-quick-start.md
│ │ ├── 03-your-first-skill.md
│ │ └── 04-next-steps.md
│ ├── reference/
│ │ ├── AI_SKILL_STANDARDS.md
│ │ ├── API_REFERENCE.md
│ │ ├── C3_x_Router_Architecture.md
│ │ ├── CLAUDE_INTEGRATION.md
│ │ ├── CLI_REFERENCE.md
│ │ ├── CODE_QUALITY.md
│ │ ├── CONFIG_FORMAT.md
│ │ ├── ENVIRONMENT_VARIABLES.md
│ │ ├── FEATURE_MATRIX.md
│ │ ├── GIT_CONFIG_SOURCES.md
│ │ ├── LARGE_DOCUMENTATION.md
│ │ ├── LLMS_TXT_SUPPORT.md
│ │ ├── MCP_REFERENCE.md
│ │ └── SKILL_ARCHITECTURE.md
│ └── user-guide/
│ ├── 01-core-concepts.md
│ ├── 02-scraping.md
│ ├── 03-enhancement.md
│ ├── 04-packaging.md
│ ├── 05-workflows.md
│ └── 06-troubleshooting.md
├── example-mcp-config.json
├── examples/
│ ├── chroma-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_chroma.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── cline-django-assistant/
│ │ ├── README.md
│ │ ├── generate_clinerules.py
│ │ └── requirements.txt
│ ├── continue-dev-universal/
│ │ ├── README.md
│ │ ├── context_server.py
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── cursor-react-skill/
│ │ ├── .cursorrules.example
│ │ ├── README.md
│ │ ├── example-project/
│ │ │ ├── README.md
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ ├── App.tsx
│ │ │ │ └── index.tsx
│ │ │ └── tsconfig.json
│ │ ├── generate_cursorrules.py
│ │ └── requirements.txt
│ ├── faiss-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_build_faiss_index.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── haystack-pipeline/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── http_transport_examples.sh
│ ├── langchain-rag-pipeline/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── llama-index-query-engine/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── pinecone-upsert/
│ │ ├── README.md
│ │ ├── quickstart.py
│ │ └── requirements.txt
│ ├── qdrant-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_qdrant.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ └── requirements.txt
│ ├── test_http_server.py
│ ├── weaviate-example/
│ │ ├── 1_generate_skill.py
│ │ ├── 2_upload_to_weaviate.py
│ │ ├── 3_query_example.py
│ │ ├── README.md
│ │ ├── requirements.txt
│ │ └── sample_output/
│ │ └── query_results.txt
│ └── windsurf-fastapi-context/
│ ├── README.md
│ ├── generate_windsurfrules.py
│ └── requirements.txt
├── helm/
│ └── skill-seekers/
│ ├── Chart.yaml
│ ├── templates/
│ │ ├── NOTES.txt
│ │ ├── _helpers.tpl
│ │ ├── chroma-deployment.yaml
│ │ ├── configmap.yaml
│ │ ├── hpa.yaml
│ │ ├── ingress.yaml
│ │ ├── mcp-deployment.yaml
│ │ ├── pvc.yaml
│ │ ├── qdrant-deployment.yaml
│ │ ├── secret.yaml
│ │ ├── service.yaml
│ │ ├── serviceaccount.yaml
│ │ └── weaviate-deployment.yaml
│ └── values.yaml
├── mypy.ini
├── pyproject.toml
├── render-mcp.yaml
├── render.yaml
├── requirements.txt
├── ruff_errors.txt
├── scripts/
│ ├── bootstrap_skill.sh
│ ├── check_translation_sync.sh
│ ├── run_benchmarks.sh
│ ├── run_integration_tests.sh
│ ├── skill_header.md
│ └── translate_doc.py
├── setup.sh
├── setup_mcp.sh
├── src/
│ └── skill_seekers/
│ ├── __init__.py
│ ├── _version.py
│ ├── benchmark/
│ │ ├── __init__.py
│ │ ├── framework.py
│ │ ├── models.py
│ │ └── runner.py
│ ├── cli/
│ │ ├── __init__.py
│ │ ├── adaptors/
│ │ │ ├── __init__.py
│ │ │ ├── base.py
│ │ │ ├── chroma.py
│ │ │ ├── claude.py
│ │ │ ├── faiss_helpers.py
│ │ │ ├── gemini.py
│ │ │ ├── haystack.py
│ │ │ ├── langchain.py
│ │ │ ├── llama_index.py
│ │ │ ├── markdown.py
│ │ │ ├── minimax.py
│ │ │ ├── openai.py
│ │ │ ├── pinecone_adaptor.py
│ │ │ ├── qdrant.py
│ │ │ ├── streaming_adaptor.py
│ │ │ └── weaviate.py
│ │ ├── ai_enhancer.py
│ │ ├── api_reference_builder.py
│ │ ├── architectural_pattern_detector.py
│ │ ├── arguments/
│ │ │ ├── __init__.py
│ │ │ ├── analyze.py
│ │ │ ├── asciidoc.py
│ │ │ ├── chat.py
│ │ │ ├── common.py
│ │ │ ├── confluence.py
│ │ │ ├── create.py
│ │ │ ├── enhance.py
│ │ │ ├── epub.py
│ │ │ ├── github.py
│ │ │ ├── html.py
│ │ │ ├── jupyter.py
│ │ │ ├── manpage.py
│ │ │ ├── notion.py
│ │ │ ├── openapi.py
│ │ │ ├── package.py
│ │ │ ├── pdf.py
│ │ │ ├── pptx.py
│ │ │ ├── rss.py
│ │ │ ├── scrape.py
│ │ │ ├── sync_config.py
│ │ │ ├── unified.py
│ │ │ ├── upload.py
│ │ │ ├── video.py
│ │ │ ├── word.py
│ │ │ └── workflow.py
│ │ ├── asciidoc_scraper.py
│ │ ├── benchmark_cli.py
│ │ ├── chat_scraper.py
│ │ ├── cloud_storage_cli.py
│ │ ├── code_analyzer.py
│ │ ├── codebase_scraper.py
│ │ ├── config_command.py
│ │ ├── config_enhancer.py
│ │ ├── config_extractor.py
│ │ ├── config_fetcher.py
│ │ ├── config_manager.py
│ │ ├── config_validator.py
│ │ ├── conflict_detector.py
│ │ ├── confluence_scraper.py
│ │ ├── constants.py
│ │ ├── create_command.py
│ │ ├── dependency_analyzer.py
│ │ ├── doc_scraper.py
│ │ ├── embedding_pipeline.py
│ │ ├── enhance_command.py
│ │ ├── enhance_skill.py
│ │ ├── enhance_skill_local.py
│ │ ├── enhance_status.py
│ │ ├── enhancement_workflow.py
│ │ ├── epub_scraper.py
│ │ ├── estimate_pages.py
│ │ ├── generate_router.py
│ │ ├── github_fetcher.py
│ │ ├── github_scraper.py
│ │ ├── guide_enhancer.py
│ │ ├── how_to_guide_builder.py
│ │ ├── html_scraper.py
│ │ ├── incremental_updater.py
│ │ ├── install_agent.py
│ │ ├── install_skill.py
│ │ ├── jupyter_scraper.py
│ │ ├── language_detector.py
│ │ ├── llms_txt_detector.py
│ │ ├── llms_txt_downloader.py
│ │ ├── llms_txt_parser.py
│ │ ├── main.py
│ │ ├── man_scraper.py
│ │ ├── markdown_cleaner.py
│ │ ├── merge_sources.py
│ │ ├── multilang_support.py
│ │ ├── notion_scraper.py
│ │ ├── openapi_scraper.py
│ │ ├── package_multi.py
│ │ ├── package_skill.py
│ │ ├── parsers/
│ │ │ ├── __init__.py
│ │ │ ├── analyze_parser.py
│ │ │ ├── asciidoc_parser.py
│ │ │ ├── base.py
│ │ │ ├── chat_parser.py
│ │ │ ├── config_parser.py
│ │ │ ├── confluence_parser.py
│ │ │ ├── create_parser.py
│ │ │ ├── enhance_parser.py
│ │ │ ├── enhance_status_parser.py
│ │ │ ├── epub_parser.py
│ │ │ ├── estimate_parser.py
│ │ │ ├── extractors/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── base_parser.py
│ │ │ │ ├── formatters.py
│ │ │ │ ├── markdown_parser.py
│ │ │ │ ├── pdf_parser.py
│ │ │ │ ├── quality_scorer.py
│ │ │ │ ├── rst_parser.py
│ │ │ │ └── unified_structure.py
│ │ │ ├── github_parser.py
│ │ │ ├── html_parser.py
│ │ │ ├── install_agent_parser.py
│ │ │ ├── install_parser.py
│ │ │ ├── jupyter_parser.py
│ │ │ ├── manpage_parser.py
│ │ │ ├── multilang_parser.py
│ │ │ ├── notion_parser.py
│ │ │ ├── openapi_parser.py
│ │ │ ├── package_parser.py
│ │ │ ├── pdf_parser.py
│ │ │ ├── pptx_parser.py
│ │ │ ├── quality_parser.py
│ │ │ ├── resume_parser.py
│ │ │ ├── rss_parser.py
│ │ │ ├── scrape_parser.py
│ │ │ ├── stream_parser.py
│ │ │ ├── sync_config_parser.py
│ │ │ ├── test_examples_parser.py
│ │ │ ├── unified_parser.py
│ │ │ ├── update_parser.py
│ │ │ ├── upload_parser.py
│ │ │ ├── video_parser.py
│ │ │ ├── word_parser.py
│ │ │ └── workflows_parser.py
│ │ ├── pattern_recognizer.py
│ │ ├── pdf_extractor_poc.py
│ │ ├── pdf_scraper.py
│ │ ├── pptx_scraper.py
│ │ ├── presets/
│ │ │ ├── __init__.py
│ │ │ ├── analyze_presets.py
│ │ │ ├── github_presets.py
│ │ │ ├── manager.py
│ │ │ └── scrape_presets.py
│ │ ├── quality_checker.py
│ │ ├── quality_metrics.py
│ │ ├── rag_chunker.py
│ │ ├── rate_limit_handler.py
│ │ ├── resume_command.py
│ │ ├── rss_scraper.py
│ │ ├── run_tests.py
│ │ ├── setup_wizard.py
│ │ ├── signal_flow_analyzer.py
│ │ ├── source_detector.py
│ │ ├── split_config.py
│ │ ├── storage/
│ │ │ ├── __init__.py
│ │ │ ├── azure_storage.py
│ │ │ ├── base_storage.py
│ │ │ ├── gcs_storage.py
│ │ │ └── s3_storage.py
│ │ ├── streaming_ingest.py
│ │ ├── swift_patterns.py
│ │ ├── sync_cli.py
│ │ ├── sync_config.py
│ │ ├── test_example_extractor.py
│ │ ├── test_unified_simple.py
│ │ ├── unified_codebase_analyzer.py
│ │ ├── unified_enhancer.py
│ │ ├── unified_scraper.py
│ │ ├── unified_skill_builder.py
│ │ ├── upload_skill.py
│ │ ├── utils.py
│ │ ├── video_metadata.py
│ │ ├── video_models.py
│ │ ├── video_scraper.py
│ │ ├── video_segmenter.py
│ │ ├── video_setup.py
│ │ ├── video_transcript.py
│ │ ├── video_visual.py
│ │ ├── word_scraper.py
│ │ ├── workflow_runner.py
│ │ └── workflows_command.py
│ ├── embedding/
│ │ ├── __init__.py
│ │ ├── cache.py
│ │ ├── generator.py
│ │ ├── models.py
│ │ └── server.py
│ ├── mcp/
│ │ ├── README.md
│ │ ├── __init__.py
│ │ ├── agent_detector.py
│ │ ├── git_repo.py
│ │ ├── requirements.txt
│ │ ├── server.py
│ │ ├── server_fastmcp.py
│ │ ├── server_legacy.py
│ │ ├── source_manager.py
│ │ └── tools/
│ │ ├── __init__.py
│ │ ├── config_tools.py
│ │ ├── packaging_tools.py
│ │ ├── scraping_tools.py
│ │ ├── source_tools.py
│ │ ├── splitting_tools.py
│ │ ├── sync_config_tools.py
│ │ ├── vector_db_tools.py
│ │ └── workflow_tools.py
│ ├── py.typed
│ ├── sync/
│ │ ├── __init__.py
│ │ ├── detector.py
│ │ ├── models.py
│ │ ├── monitor.py
│ │ └── notifier.py
│ └── workflows/
│ ├── __init__.py
│ ├── accessibility-a11y.yaml
│ ├── advanced-patterns.yaml
│ ├── api-documentation.yaml
│ ├── api-evolution.yaml
│ ├── api-gateway.yaml
│ ├── architecture-comprehensive.yaml
│ ├── auth-strategies.yaml
│ ├── aws-services.yaml
│ ├── background-jobs.yaml
│ ├── backup-disaster-recovery.yaml
│ ├── build-tools.yaml
│ ├── caching-strategies.yaml
│ ├── cli-tooling.yaml
│ ├── comparison-matrix.yaml
│ ├── complex-merge.yaml
│ ├── compliance-gdpr.yaml
│ ├── component-library.yaml
│ ├── computer-vision.yaml
│ ├── contribution-guide.yaml
│ ├── data-validation.yaml
│ ├── database-schema.yaml
│ ├── deep-linking.yaml
│ ├── default.yaml
│ ├── design-system.yaml
│ ├── devops-deployment.yaml
│ ├── encryption-guide.yaml
│ ├── event-driven.yaml
│ ├── feature-engineering.yaml
│ ├── forms-validation.yaml
│ ├── graphql-schema.yaml
│ ├── grpc-services.yaml
│ ├── iam-identity.yaml
│ ├── kubernetes-deployment.yaml
│ ├── localization-i18n.yaml
│ ├── message-queues.yaml
│ ├── microservices-patterns.yaml
│ ├── migration-guide.yaml
│ ├── minimal.yaml
│ ├── mlops-pipeline.yaml
│ ├── model-deployment.yaml
│ ├── observability-stack.yaml
│ ├── offline-first.yaml
│ ├── onboarding-beginner.yaml
│ ├── performance-optimization.yaml
│ ├── platform-specific.yaml
│ ├── push-notifications.yaml
│ ├── pwa-checklist.yaml
│ ├── rate-limiting.yaml
│ ├── responsive-design.yaml
│ ├── rest-api-design.yaml
│ ├── sdk-integration.yaml
│ ├── secrets-management.yaml
│ ├── security-focus.yaml
│ ├── serverless-architecture.yaml
│ ├── ssr-guide.yaml
│ ├── state-management.yaml
│ ├── stream-processing.yaml
│ ├── terraform-guide.yaml
│ ├── testing-focus.yaml
│ ├── testing-frontend.yaml
│ ├── troubleshooting-guide.yaml
│ ├── vector-databases.yaml
│ ├── video-tutorial.yaml
│ ├── webhook-guide.yaml
│ └── websockets-realtime.yaml
├── test_api.py
├── test_httpx_quick.sh
├── test_httpx_skill.sh
├── test_results.log
├── test_week2_features.py
└── tests/
├── __init__.py
├── conftest.py
├── docker-compose.test.yml
├── fixtures/
│ └── example_conflicts.json
├── mcp_integration_test.md
├── test_adaptor_benchmarks.py
├── test_adaptors/
│ ├── __init__.py
│ ├── test_adaptors_e2e.py
│ ├── test_base.py
│ ├── test_chroma_adaptor.py
│ ├── test_claude_adaptor.py
│ ├── test_faiss_adaptor.py
│ ├── test_gemini_adaptor.py
│ ├── test_haystack_adaptor.py
│ ├── test_langchain_adaptor.py
│ ├── test_llama_index_adaptor.py
│ ├── test_markdown_adaptor.py
│ ├── test_minimax_adaptor.py
│ ├── test_openai_adaptor.py
│ ├── test_qdrant_adaptor.py
│ └── test_weaviate_adaptor.py
├── test_analyze_command.py
├── test_analyze_e2e.py
├── test_api_reference_builder.py
├── test_architecture_scenarios.py
├── test_async_scraping.py
├── test_benchmark.py
├── test_bootstrap_skill.py
├── test_bootstrap_skill_e2e.py
├── test_c3_integration.py
├── test_chunking_integration.py
├── test_cli_parsers.py
├── test_cli_paths.py
├── test_cli_refactor_e2e.py
├── test_cloud_storage.py
├── test_code_analyzer.py
├── test_codebase_scraper.py
├── test_config_extractor.py
├── test_config_fetcher.py
├── test_config_validation.py
├── test_constants.py
├── test_create_arguments.py
├── test_create_integration_basic.py
├── test_dependency_analyzer.py
├── test_e2e_three_stream_pipeline.py
├── test_embedding.py
├── test_embedding_pipeline.py
├── test_enhance_command.py
├── test_enhance_skill_local.py
├── test_epub_scraper.py
├── test_estimate_pages.py
├── test_excluded_dirs_config.py
├── test_framework_detection.py
├── test_generate_router_github.py
├── test_git_repo.py
├── test_git_sources_e2e.py
├── test_github_fetcher.py
├── test_github_scraper.py
├── test_guide_enhancer.py
├── test_how_to_guide_builder.py
├── test_incremental_updates.py
├── test_install_agent.py
├── test_install_multiplatform.py
├── test_install_skill.py
├── test_install_skill_e2e.py
├── test_integration.py
├── test_integration_adaptors.py
├── test_issue_219_e2e.py
├── test_issue_277_real_world.py
├── test_language_detector.py
├── test_llms_txt_detector.py
├── test_llms_txt_downloader.py
├── test_llms_txt_parser.py
├── test_markdown_parsing.py
├── test_mcp_fastmcp.py
├── test_mcp_git_sources.py
├── test_mcp_server.py
├── test_mcp_vector_dbs.py
├── test_mcp_workflow_tools.py
├── test_merge_sources_github.py
├── test_multi_source.py
├── test_multilang_support.py
├── test_new_source_types.py
├── test_package_skill.py
├── test_package_structure.py
├── test_parallel_scraping.py
├── test_parser_sync.py
├── test_pattern_recognizer.py
├── test_pdf_advanced_features.py
├── test_pdf_extractor.py
├── test_pdf_scraper.py
├── test_pinecone_adaptor.py
├── test_pr144_concerns.py
├── test_preset_system.py
├── test_quality_checker.py
├── test_quality_metrics.py
├── test_rag_chunker.py
├── test_rate_limit_handler.py
├── test_real_world_fastmcp.py
├── test_scraper_features.py
├── test_server_fastmcp_http.py
├── test_setup_scripts.py
├── test_skip_llms_txt.py
├── test_smart_summarization.py
├── test_source_detector.py
├── test_source_manager.py
├── test_streaming_ingestion.py
├── test_swift_detection.py
├── test_sync_config.py
├── test_sync_config_e2e.py
├── test_terminal_detection.py
├── test_test_example_extractor.py
├── test_unified.py
├── test_unified_analyzer.py
├── test_unified_mcp_integration.py
├── test_unified_parsers.py
├── test_unified_scraper_orchestration.py
├── test_upload_integration.py
├── test_upload_skill.py
├── test_url_conversion.py
├── test_utilities.py
├── test_video_scraper.py
├── test_video_setup.py
├── test_word_scraper.py
├── test_workflow_runner.py
├── test_workflow_tools_mcp.py
└── test_workflows_command.py
Showing preview only (597K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6455 symbols across 351 files)
FILE: api/config_analyzer.py
class ConfigAnalyzer (line 13) | class ConfigAnalyzer:
method __init__ (line 41) | def __init__(self, config_dir: Path, base_url: str = "https://api.skil...
method analyze_all_configs (line 55) | def analyze_all_configs(self) -> list[dict[str, Any]]:
method analyze_config (line 80) | def analyze_config(self, config_path: Path) -> dict[str, Any] | None:
method get_config_by_name (line 146) | def get_config_by_name(self, name: str) -> dict[str, Any] | None:
method _determine_type (line 162) | def _determine_type(self, config_data: dict[str, Any]) -> str:
method _get_primary_source (line 182) | def _get_primary_source(self, config_data: dict[str, Any], config_type...
method _categorize_config (line 216) | def _categorize_config(
method _extract_tags (line 265) | def _extract_tags(self, name: str, description: str, config_data: dict...
method _get_max_pages (line 316) | def _get_max_pages(self, config_data: dict[str, Any]) -> int | None:
method _get_last_updated (line 338) | def _get_last_updated(self, config_path: Path) -> str:
FILE: api/main.py
function root (line 42) | async def root():
function list_configs (line 61) | async def list_configs(
function get_config (line 110) | async def get_config(name: str) -> dict[str, Any]:
function list_categories (line 135) | async def list_categories() -> dict[str, Any]:
function download_config (line 159) | async def download_config(config_name: str):
function health_check (line 196) | async def health_check():
FILE: examples/chroma-example/1_generate_skill.py
function main (line 18) | def main():
FILE: examples/chroma-example/2_upload_to_chroma.py
function create_client (line 34) | def create_client(persist_directory: str = None):
function load_skill_data (line 54) | def load_skill_data(filepath: str = "output/vue-chroma.json"):
function create_collection (line 66) | def create_collection(client, collection_name: str, reset: bool = False):
function upload_documents (line 99) | def upload_documents(collection, data: dict):
function verify_upload (line 119) | def verify_upload(collection):
function main (line 124) | def main():
FILE: examples/chroma-example/3_query_example.py
function create_client (line 34) | def create_client(persist_directory: str = None):
function get_collection (line 45) | def get_collection(client, collection_name: str = "vue"):
function semantic_search_example (line 54) | def semantic_search_example(collection):
function filtered_search_example (line 104) | def filtered_search_example(collection):
function top_k_results_example (line 146) | def top_k_results_example(collection):
function complex_filter_example (line 177) | def complex_filter_example(collection):
function get_statistics (line 217) | def get_statistics(collection):
function main (line 245) | def main():
FILE: examples/cline-django-assistant/generate_clinerules.py
function run_command (line 18) | def run_command(cmd: list[str], description: str) -> bool:
function setup_mcp_server (line 40) | def setup_mcp_server(project_path: Path) -> bool:
function main (line 80) | def main():
FILE: examples/continue-dev-universal/context_server.py
function load_framework_docs (line 41) | def load_framework_docs(framework: str) -> str:
function root (line 74) | async def root():
function health (line 89) | async def health():
function list_frameworks (line 95) | async def list_frameworks() -> Dict[str, List[str]]:
function get_framework_docs (line 131) | async def get_framework_docs(framework: str, query: str = None) -> JSONR...
function get_project_conventions (line 176) | async def get_project_conventions() -> JSONResponse:
function main (line 221) | def main():
FILE: examples/continue-dev-universal/quickstart.py
function run_command (line 17) | def run_command(cmd: list[str], description: str) -> bool:
function create_continue_config (line 39) | def create_continue_config(framework: str, port: int = 8765) -> Path:
function main (line 95) | def main():
FILE: examples/cursor-react-skill/example-project/src/App.tsx
function App (line 3) | function App() {
FILE: examples/cursor-react-skill/generate_cursorrules.py
function run_command (line 16) | def run_command(cmd: list, description: str) -> bool:
function main (line 40) | def main():
FILE: examples/faiss-example/3_query_example.py
function search (line 29) | def search(query_text: str, k: int = 5):
FILE: examples/haystack-pipeline/quickstart.py
function main (line 14) | def main():
FILE: examples/langchain-rag-pipeline/quickstart.py
function load_documents (line 27) | def load_documents(json_path: str) -> list[Document]:
function create_vector_store (line 54) | def create_vector_store(documents: list[Document], persist_dir: str = "....
function create_qa_chain (line 79) | def create_qa_chain(vectorstore: Chroma) -> RetrievalQA:
function query_documentation (line 108) | def query_documentation(qa_chain: RetrievalQA, query: str) -> None:
function main (line 132) | def main():
FILE: examples/llama-index-query-engine/quickstart.py
function load_nodes (line 25) | def load_nodes(json_path: str) -> list[TextNode]:
function create_index (line 60) | def create_index(nodes: list[TextNode], persist_dir: str = "./storage") ...
function query_examples (line 83) | def query_examples(index: VectorStoreIndex) -> None:
function interactive_chat (line 122) | def interactive_chat(index: VectorStoreIndex) -> None:
function main (line 167) | def main():
FILE: examples/pinecone-upsert/quickstart.py
function create_index (line 29) | def create_index(pc: Pinecone, index_name: str, dimension: int = 1536) -...
function load_documents (line 59) | def load_documents(json_path: str) -> List[Dict]:
function create_embeddings (line 85) | def create_embeddings(openai_client: OpenAI, texts: List[str]) -> List[L...
function batch_upsert (line 103) | def batch_upsert(
function semantic_search (line 160) | def semantic_search(
function interactive_search (line 203) | def interactive_search(index, openai_client: OpenAI) -> None:
function main (line 252) | def main():
FILE: examples/test_http_server.py
function test_http_server (line 19) | async def test_http_server():
FILE: examples/weaviate-example/1_generate_skill.py
function main (line 18) | def main():
FILE: examples/weaviate-example/2_upload_to_weaviate.py
function connect_to_weaviate (line 35) | def connect_to_weaviate(url: str, api_key: str = None):
function load_skill_data (line 66) | def load_skill_data(filepath: str = "output/react-weaviate.json"):
function create_schema (line 78) | def create_schema(client, schema: dict):
function upload_objects (line 102) | def upload_objects(client, class_name: str, objects: list):
function verify_upload (line 133) | def verify_upload(client, class_name: str):
function main (line 139) | def main():
FILE: examples/weaviate-example/3_query_example.py
function connect_to_weaviate (line 34) | def connect_to_weaviate(url: str, api_key: str = None):
function hybrid_search_example (line 53) | def hybrid_search_example(client, class_name: str = "React"):
function keyword_only_search (line 100) | def keyword_only_search(client, class_name: str = "React"):
function filtered_search (line 135) | def filtered_search(client, class_name: str = "React"):
function semantic_search (line 175) | def semantic_search(client, class_name: str = "React"):
function get_statistics (line 206) | def get_statistics(client, class_name: str = "React"):
function main (line 238) | def main():
FILE: examples/windsurf-fastapi-context/generate_windsurfrules.py
function run_command (line 17) | def run_command(cmd: list[str], description: str) -> bool:
function main (line 39) | def main():
FILE: scripts/translate_doc.py
function get_version (line 17) | def get_version() -> str:
function translate_with_anthropic (line 26) | def translate_with_anthropic(content: str, api_key: str) -> str:
function add_translation_header (line 66) | def add_translation_header(content: str, original_file: Path, target_lan...
function fix_links (line 104) | def fix_links(content: str, original_file: Path) -> str:
function translate_file (line 143) | def translate_file(input_path: str, target_lang: str = "zh-CN"):
function main (line 199) | def main():
FILE: src/skill_seekers/_version.py
function get_version (line 22) | def get_version() -> str:
FILE: src/skill_seekers/benchmark/framework.py
class BenchmarkResult (line 17) | class BenchmarkResult:
method __init__ (line 28) | def __init__(self, name: str):
method add_timing (line 45) | def add_timing(self, result: TimingResult):
method add_memory (line 49) | def add_memory(self, usage: MemoryUsage):
method add_metric (line 53) | def add_metric(self, metric: Metric):
method add_recommendation (line 57) | def add_recommendation(self, text: str):
method set_system_info (line 61) | def set_system_info(self):
method to_report (line 71) | def to_report(self) -> BenchmarkReport:
class Benchmark (line 99) | class Benchmark:
method __init__ (line 122) | def __init__(self, name: str):
method timer (line 133) | def timer(self, operation: str, iterations: int = 1):
method memory (line 165) | def memory(self, operation: str):
method measure (line 204) | def measure(
method timed (line 242) | def timed(self, operation: str | None = None, track_memory: bool = Fal...
method metric (line 270) | def metric(self, name: str, value: float, unit: str):
method recommend (line 285) | def recommend(self, text: str):
method report (line 298) | def report(self) -> BenchmarkReport:
method save (line 307) | def save(self, path: Path):
method analyze (line 324) | def analyze(self):
FILE: src/skill_seekers/benchmark/models.py
class Metric (line 10) | class Metric(BaseModel):
class TimingResult (line 21) | class TimingResult(BaseModel):
class MemoryUsage (line 32) | class MemoryUsage(BaseModel):
class BenchmarkReport (line 42) | class BenchmarkReport(BaseModel):
method summary (line 60) | def summary(self) -> str:
class ComparisonReport (line 71) | class ComparisonReport(BaseModel):
method has_regressions (line 85) | def has_regressions(self) -> bool:
method overall_improvement (line 90) | def overall_improvement(self) -> str:
FILE: src/skill_seekers/benchmark/runner.py
class BenchmarkRunner (line 15) | class BenchmarkRunner:
method __init__ (line 38) | def __init__(self, output_dir: Path | None = None):
method run (line 48) | def run(
method run_suite (line 90) | def run_suite(
method compare (line 120) | def compare(self, baseline_path: Path, current_path: Path) -> Comparis...
method list_benchmarks (line 212) | def list_benchmarks(self) -> list[dict[str, Any]]:
method get_latest (line 249) | def get_latest(self, name: str) -> Path | None:
method cleanup_old (line 278) | def cleanup_old(self, keep_latest: int = 5):
FILE: src/skill_seekers/cli/adaptors/__init__.py
function get_adaptor (line 110) | def get_adaptor(platform: str, config: dict = None) -> SkillAdaptor:
function list_platforms (line 143) | def list_platforms() -> list[str]:
function is_platform_available (line 157) | def is_platform_available(platform: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/base.py
class SkillMetadata (line 18) | class SkillMetadata:
class SkillAdaptor (line 29) | class SkillAdaptor(ABC):
method __init__ (line 45) | def __init__(self, config: dict[str, Any] | None = None):
method format_skill_md (line 55) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 74) | def package(
method upload (line 104) | def upload(self, package_path: Path, api_key: str, **kwargs) -> dict[s...
method validate_api_key (line 124) | def validate_api_key(self, api_key: str) -> bool:
method get_env_var_name (line 139) | def get_env_var_name(self) -> str:
method supports_enhancement (line 148) | def supports_enhancement(self) -> bool:
method enhance (line 157) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
method _read_existing_content (line 172) | def _read_existing_content(self, skill_dir: Path) -> str:
method _extract_quick_reference (line 196) | def _extract_quick_reference(self, skill_dir: Path) -> str:
method _read_skill_md (line 214) | def _read_skill_md(self, skill_dir: Path) -> str:
method _read_frontmatter (line 235) | def _read_frontmatter(self, skill_dir: Path) -> dict[str, str]:
method _build_skill_metadata (line 256) | def _build_skill_metadata(self, skill_dir: Path) -> SkillMetadata:
method _iterate_references (line 276) | def _iterate_references(self, skill_dir: Path):
method _build_metadata_dict (line 300) | def _build_metadata_dict(self, metadata: SkillMetadata, **extra: Any) ...
method _maybe_chunk_content (line 324) | def _maybe_chunk_content(
method _format_output_path (line 409) | def _format_output_path(self, skill_dir: Path, output_path: Path, suff...
method _generate_deterministic_id (line 454) | def _generate_deterministic_id(self, content: str, metadata: dict, for...
method _generate_openai_embeddings (line 492) | def _generate_openai_embeddings(
method _generate_st_embeddings (line 532) | def _generate_st_embeddings(self, documents: list[str]) -> list[list[f...
method _generate_toc (line 553) | def _generate_toc(self, skill_dir: Path) -> str:
FILE: src/skill_seekers/cli/adaptors/chroma.py
class ChromaAdaptor (line 17) | class ChromaAdaptor(SkillAdaptor):
method _generate_id (line 33) | def _generate_id(self, content: str, metadata: dict) -> str:
method format_skill_md (line 46) | def format_skill_md(
method package (line 151) | def package(
method upload (line 216) | def upload(self, package_path: Path, api_key: str | None = None, **kwa...
method validate_api_key (line 360) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 372) | def get_env_var_name(self) -> str:
method supports_enhancement (line 381) | def supports_enhancement(self) -> bool:
method enhance (line 393) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/claude.py
class ClaudeAdaptor (line 18) | class ClaudeAdaptor(SkillAdaptor):
method format_skill_md (line 33) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 85) | def package(
method upload (line 154) | def upload(self, package_path: Path, api_key: str, **kwargs) -> dict[s...
method validate_api_key (line 289) | def validate_api_key(self, api_key: str) -> bool:
method get_env_var_name (line 301) | def get_env_var_name(self) -> str:
method supports_enhancement (line 310) | def supports_enhancement(self) -> bool:
method enhance (line 319) | def enhance(self, skill_dir: Path, api_key: str) -> bool:
method _read_reference_files (line 406) | def _read_reference_files(
method _build_enhancement_prompt (line 444) | def _build_enhancement_prompt(
FILE: src/skill_seekers/cli/adaptors/faiss_helpers.py
class FAISSHelpers (line 17) | class FAISSHelpers(SkillAdaptor):
method _generate_id (line 36) | def _generate_id(self, content: str, metadata: dict) -> str:
method format_skill_md (line 49) | def format_skill_md(
method package (line 162) | def package(
method upload (line 227) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 406) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 410) | def get_env_var_name(self) -> str:
method supports_enhancement (line 414) | def supports_enhancement(self) -> bool:
method enhance (line 418) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/gemini.py
class GeminiAdaptor (line 19) | class GeminiAdaptor(SkillAdaptor):
method format_skill_md (line 34) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 90) | def package(
method upload (line 166) | def upload(self, package_path: Path, api_key: str, **_kwargs) -> dict[...
method validate_api_key (line 261) | def validate_api_key(self, api_key: str) -> bool:
method get_env_var_name (line 273) | def get_env_var_name(self) -> str:
method supports_enhancement (line 282) | def supports_enhancement(self) -> bool:
method enhance (line 291) | def enhance(self, skill_dir: Path, api_key: str) -> bool:
method _read_reference_files (line 366) | def _read_reference_files(
method _build_enhancement_prompt (line 404) | def _build_enhancement_prompt(
FILE: src/skill_seekers/cli/adaptors/haystack.py
class HaystackAdaptor (line 17) | class HaystackAdaptor(SkillAdaptor):
method format_skill_md (line 32) | def format_skill_md(
method package (line 131) | def package(
method upload (line 195) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 278) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 290) | def get_env_var_name(self) -> str:
method supports_enhancement (line 299) | def supports_enhancement(self) -> bool:
method enhance (line 311) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/langchain.py
class LangChainAdaptor (line 17) | class LangChainAdaptor(SkillAdaptor):
method format_skill_md (line 32) | def format_skill_md(
method package (line 121) | def package(
method upload (line 187) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 260) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 272) | def get_env_var_name(self) -> str:
method supports_enhancement (line 281) | def supports_enhancement(self) -> bool:
method enhance (line 293) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/llama_index.py
class LlamaIndexAdaptor (line 17) | class LlamaIndexAdaptor(SkillAdaptor):
method _generate_node_id (line 32) | def _generate_node_id(self, content: str, metadata: dict) -> str:
method format_skill_md (line 45) | def format_skill_md(
method package (line 150) | def package(
method upload (line 214) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 299) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 311) | def get_env_var_name(self) -> str:
method supports_enhancement (line 320) | def supports_enhancement(self) -> bool:
method enhance (line 332) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/markdown.py
class MarkdownAdaptor (line 17) | class MarkdownAdaptor(SkillAdaptor):
method format_skill_md (line 32) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 85) | def package(
method upload (line 164) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 188) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 200) | def get_env_var_name(self) -> str:
method supports_enhancement (line 209) | def supports_enhancement(self) -> bool:
method enhance (line 218) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
method _create_combined_doc (line 233) | def _create_combined_doc(self, skill_dir: Path) -> str:
FILE: src/skill_seekers/cli/adaptors/minimax.py
class MiniMaxAdaptor (line 18) | class MiniMaxAdaptor(SkillAdaptor):
method format_skill_md (line 32) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 103) | def package(
method upload (line 168) | def upload(self, package_path: Path, api_key: str, **kwargs) -> dict[s...
method validate_api_key (line 293) | def validate_api_key(self, api_key: str) -> bool:
method get_env_var_name (line 309) | def get_env_var_name(self) -> str:
method supports_enhancement (line 318) | def supports_enhancement(self) -> bool:
method enhance (line 327) | def enhance(self, skill_dir: Path, api_key: str) -> bool:
method _read_reference_files (line 410) | def _read_reference_files(
method _build_enhancement_prompt (line 446) | def _build_enhancement_prompt(
FILE: src/skill_seekers/cli/adaptors/openai.py
class OpenAIAdaptor (line 18) | class OpenAIAdaptor(SkillAdaptor):
method format_skill_md (line 33) | def format_skill_md(self, skill_dir: Path, metadata: SkillMetadata) ->...
method package (line 107) | def package(
method upload (line 177) | def upload(self, package_path: Path, api_key: str, **kwargs) -> dict[s...
method validate_api_key (line 303) | def validate_api_key(self, api_key: str) -> bool:
method get_env_var_name (line 315) | def get_env_var_name(self) -> str:
method supports_enhancement (line 324) | def supports_enhancement(self) -> bool:
method enhance (line 333) | def enhance(self, skill_dir: Path, api_key: str) -> bool:
method _read_reference_files (line 417) | def _read_reference_files(
method _build_enhancement_prompt (line 455) | def _build_enhancement_prompt(
FILE: src/skill_seekers/cli/adaptors/pinecone_adaptor.py
class PineconeAdaptor (line 21) | class PineconeAdaptor(SkillAdaptor):
method _generate_id (line 37) | def _generate_id(self, content: str, metadata: dict) -> str:
method _truncate_text_for_metadata (line 41) | def _truncate_text_for_metadata(
method format_skill_md (line 66) | def format_skill_md(
method package (line 192) | def package(
method upload (line 257) | def upload(self, package_path: Path, api_key: str | None = None, **kwa...
method validate_api_key (line 387) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 391) | def get_env_var_name(self) -> str:
method supports_enhancement (line 395) | def supports_enhancement(self) -> bool:
method enhance (line 399) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/qdrant.py
class QdrantAdaptor (line 17) | class QdrantAdaptor(SkillAdaptor):
method _generate_point_id (line 34) | def _generate_point_id(self, content: str, metadata: dict) -> str:
method format_skill_md (line 47) | def format_skill_md(
method package (line 198) | def package(
method upload (line 265) | def upload(self, package_path: Path, _api_key: str, **_kwargs) -> dict...
method validate_api_key (line 470) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 474) | def get_env_var_name(self) -> str:
method supports_enhancement (line 478) | def supports_enhancement(self) -> bool:
method enhance (line 482) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/adaptors/streaming_adaptor.py
class StreamingAdaptorMixin (line 21) | class StreamingAdaptorMixin:
method package_streaming (line 33) | def package_streaming(
method _convert_chunks_to_platform_format (line 123) | def _convert_chunks_to_platform_format(
method estimate_chunks (line 157) | def estimate_chunks(
class StreamingLangChainAdaptor (line 234) | class StreamingLangChainAdaptor(StreamingAdaptorMixin):
method _convert_chunks_to_platform_format (line 240) | def _convert_chunks_to_platform_format(self, chunks, skill_name):
class StreamingChromaAdaptor (line 269) | class StreamingChromaAdaptor(StreamingAdaptorMixin):
method _convert_chunks_to_platform_format (line 275) | def _convert_chunks_to_platform_format(self, chunks, skill_name):
function demo_streaming (line 305) | def demo_streaming():
FILE: src/skill_seekers/cli/adaptors/weaviate.py
class WeaviateAdaptor (line 17) | class WeaviateAdaptor(SkillAdaptor):
method _generate_uuid (line 34) | def _generate_uuid(self, content: str, metadata: dict) -> str:
method _generate_schema (line 47) | def _generate_schema(self, class_name: str) -> dict:
method format_skill_md (line 114) | def format_skill_md(
method package (line 237) | def package(
method upload (line 307) | def upload(self, package_path: Path, api_key: str | None = None, **kwa...
method validate_api_key (line 445) | def validate_api_key(self, _api_key: str) -> bool:
method get_env_var_name (line 457) | def get_env_var_name(self) -> str:
method supports_enhancement (line 466) | def supports_enhancement(self) -> bool:
method enhance (line 478) | def enhance(self, _skill_dir: Path, _api_key: str) -> bool:
FILE: src/skill_seekers/cli/ai_enhancer.py
class AIAnalysis (line 46) | class AIAnalysis:
class AIEnhancer (line 57) | class AIEnhancer:
method __init__ (line 60) | def __init__(self, api_key: str | None = None, enabled: bool = True, m...
method _check_claude_cli (line 125) | def _check_claude_cli(self) -> bool:
method _call_claude (line 138) | def _call_claude(self, prompt: str, max_tokens: int = 1000) -> str | N...
method _call_claude_api (line 146) | def _call_claude_api(self, prompt: str, max_tokens: int = 1000) -> str...
method _call_claude_local (line 162) | def _call_claude_local(self, prompt: str) -> str | None:
class PatternEnhancer (line 240) | class PatternEnhancer(AIEnhancer):
method enhance_patterns (line 243) | def enhance_patterns(self, patterns: list[dict]) -> list[dict]:
method _enhance_patterns_parallel (line 286) | def _enhance_patterns_parallel(self, batches: list[list[dict]], worker...
method _enhance_pattern_batch (line 319) | def _enhance_pattern_batch(self, patterns: list[dict]) -> list[dict]:
class TestExampleEnhancer (line 378) | class TestExampleEnhancer(AIEnhancer):
method enhance_examples (line 381) | def enhance_examples(self, examples: list[dict]) -> list[dict]:
method _enhance_examples_parallel (line 424) | def _enhance_examples_parallel(self, batches: list[list[dict]], worker...
method _enhance_example_batch (line 457) | def _enhance_example_batch(self, examples: list[dict]) -> list[dict]:
method generate_tutorials (line 511) | def generate_tutorials(self, examples: list[dict]) -> dict[str, list[d...
FILE: src/skill_seekers/cli/api_reference_builder.py
class APIReferenceBuilder (line 25) | class APIReferenceBuilder:
method __init__ (line 33) | def __init__(self, code_analysis: dict[str, Any]):
method build_reference (line 44) | def build_reference(self, output_dir: Path) -> dict[str, Path]:
method _get_output_filename (line 80) | def _get_output_filename(self, source_file: str) -> str:
method _generate_file_reference (line 97) | def _generate_file_reference(
method _format_class (line 138) | def _format_class(self, class_sig: dict[str, Any]) -> str:
method _format_method (line 177) | def _format_method(self, method_sig: dict[str, Any]) -> str:
method _format_function (line 217) | def _format_function(self, func_sig: dict[str, Any]) -> str:
method _build_signature (line 257) | def _build_signature(self, sig: dict[str, Any]) -> str:
method _format_parameters (line 296) | def _format_parameters(self, params: list[dict]) -> str:
function main (line 331) | def main():
FILE: src/skill_seekers/cli/architectural_pattern_detector.py
class ArchitecturalPattern (line 32) | class ArchitecturalPattern:
class ArchitecturalReport (line 44) | class ArchitecturalReport:
method to_dict (line 53) | def to_dict(self) -> dict:
class ArchitecturalPatternDetector (line 74) | class ArchitecturalPatternDetector:
method __init__ (line 142) | def __init__(self, enhance_with_ai: bool = True):
method analyze (line 161) | def analyze(self, directory: Path, files_analysis: list[dict]) -> Arch...
method _analyze_directory_structure (line 204) | def _analyze_directory_structure(self, directory: Path) -> dict[str, i...
method _detect_frameworks (line 223) | def _detect_frameworks(self, directory: Path, files: list[dict]) -> li...
method _detect_mvc (line 298) | def _detect_mvc(
method _detect_mvvm (line 366) | def _detect_mvvm(
method _detect_repository (line 438) | def _detect_repository(
method _detect_service_layer (line 480) | def _detect_service_layer(
method _detect_layered_architecture (line 519) | def _detect_layered_architecture(
method _detect_clean_architecture (line 561) | def _detect_clean_architecture(
method _enhance_with_ai (line 604) | def _enhance_with_ai(self, report: ArchitecturalReport) -> dict:
FILE: src/skill_seekers/cli/arguments/analyze.py
function add_analyze_arguments (line 153) | def add_analyze_arguments(parser: argparse.ArgumentParser) -> None:
function get_analyze_argument_names (line 182) | def get_analyze_argument_names() -> set:
FILE: src/skill_seekers/cli/arguments/asciidoc.py
function add_asciidoc_arguments (line 40) | def add_asciidoc_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/chat.py
function add_chat_arguments (line 74) | def add_chat_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/common.py
function add_common_arguments (line 138) | def add_common_arguments(parser: argparse.ArgumentParser) -> None:
function add_behavior_arguments (line 157) | def add_behavior_arguments(parser: argparse.ArgumentParser) -> None:
function add_all_standard_arguments (line 165) | def add_all_standard_arguments(parser: argparse.ArgumentParser) -> None:
function get_common_argument_names (line 179) | def get_common_argument_names() -> set:
function add_rag_arguments (line 188) | def add_rag_arguments(parser: argparse.ArgumentParser) -> None:
function get_rag_argument_names (line 207) | def get_rag_argument_names() -> set:
function get_behavior_argument_names (line 216) | def get_behavior_argument_names() -> set:
function get_all_standard_argument_names (line 221) | def get_all_standard_argument_names() -> set:
function get_argument_help (line 232) | def get_argument_help(arg_name: str) -> str:
FILE: src/skill_seekers/cli/arguments/confluence.py
function add_confluence_arguments (line 81) | def add_confluence_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/create.py
function get_universal_argument_names (line 708) | def get_universal_argument_names() -> set[str]:
function get_source_specific_arguments (line 713) | def get_source_specific_arguments(source_type: str) -> dict[str, dict[st...
function get_compatible_arguments (line 746) | def get_compatible_arguments(source_type: str) -> list[str]:
function add_create_arguments (line 768) | def add_create_arguments(parser: argparse.ArgumentParser, mode: str = "d...
FILE: src/skill_seekers/cli/arguments/enhance.py
function add_enhance_arguments (line 112) | def add_enhance_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/epub.py
function add_epub_arguments (line 40) | def add_epub_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/github.py
function add_github_arguments (line 114) | def add_github_arguments(parser: argparse.ArgumentParser) -> None:
function get_github_argument_names (line 143) | def get_github_argument_names() -> set:
function get_github_argument_count (line 154) | def get_github_argument_count() -> int:
FILE: src/skill_seekers/cli/arguments/html.py
function add_html_arguments (line 40) | def add_html_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/jupyter.py
function add_jupyter_arguments (line 40) | def add_jupyter_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/manpage.py
function add_manpage_arguments (line 56) | def add_manpage_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/notion.py
function add_notion_arguments (line 73) | def add_notion_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/openapi.py
function add_openapi_arguments (line 48) | def add_openapi_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/package.py
function add_package_arguments (line 139) | def add_package_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/pdf.py
function add_pdf_arguments (line 48) | def add_pdf_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/pptx.py
function add_pptx_arguments (line 40) | def add_pptx_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/rss.py
function add_rss_arguments (line 73) | def add_rss_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/scrape.py
function add_scrape_arguments (line 147) | def add_scrape_arguments(parser: argparse.ArgumentParser) -> None:
function get_scrape_argument_names (line 184) | def get_scrape_argument_names() -> set:
function get_scrape_argument_count (line 195) | def get_scrape_argument_count() -> int:
FILE: src/skill_seekers/cli/arguments/sync_config.py
function add_sync_config_arguments (line 10) | def add_sync_config_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/unified.py
function add_unified_arguments (line 100) | def add_unified_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/upload.py
function add_upload_arguments (line 102) | def add_upload_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/video.py
function add_video_arguments (line 140) | def add_video_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/word.py
function add_word_arguments (line 40) | def add_word_arguments(parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/arguments/workflow.py
function add_workflow_arguments (line 66) | def add_workflow_arguments(parser, include_all=True):
FILE: src/skill_seekers/cli/asciidoc_scraper.py
function _check_asciidoc_deps (line 64) | def _check_asciidoc_deps() -> None:
function infer_description_from_asciidoc (line 73) | def infer_description_from_asciidoc(metadata: dict | None = None, name: ...
function _score_code_quality (line 92) | def _score_code_quality(code: str) -> float:
class AsciiDocToSkillConverter (line 115) | class AsciiDocToSkillConverter:
method __init__ (line 123) | def __init__(self, config: dict) -> None:
method extract_asciidoc (line 139) | def extract_asciidoc(self) -> bool:
method _discover_files (line 237) | def _discover_files(self, path: Path) -> list[Path]:
method _extract_attributes (line 251) | def _extract_attributes(text: str) -> dict[str, str]:
method _resolve_attributes (line 256) | def _resolve_attributes(text: str, attributes: dict[str, str]) -> str:
method _resolve_includes (line 260) | def _resolve_includes(self, text: str, base_dir: Path) -> str:
method _build_metadata (line 285) | def _build_metadata(attributes: dict[str, str], file_path: Path) -> dict:
method _parse_asciidoc_sections (line 302) | def _parse_asciidoc_sections(self, text: str) -> list[dict]:
method _extract_code_blocks (line 342) | def _extract_code_blocks(self, text: str) -> list[dict]:
method _extract_tables (line 411) | def _extract_tables(self, text: str) -> list[dict]:
method _parse_table_body (line 426) | def _parse_table_body(table_body: str) -> dict | None:
method _extract_admonitions (line 477) | def _extract_admonitions(self, text: str) -> list[dict]:
method _extract_includes (line 494) | def _extract_includes(text: str) -> list[dict]:
method _convert_to_markdown (line 505) | def _convert_to_markdown(self, text: str) -> str:
method load_extracted_data (line 558) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 567) | def categorize_content(self) -> dict:
method build_skill (line 626) | def build_skill(self) -> None:
method _ref_filename (line 646) | def _ref_filename(self, cat_data: dict, section_num: int, total: int) ...
method _generate_reference_file (line 662) | def _generate_reference_file(
method _generate_index (line 703) | def _generate_index(self, categorized: dict) -> None:
method _generate_skill_md (line 744) | def _generate_skill_md(self, categorized: dict) -> None:
method _format_key_concepts (line 869) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 891) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 937) | def _sanitize_filename(name: str) -> str:
method _in_range (line 943) | def _in_range(pos: int, ranges: list[tuple[int, int]]) -> bool:
function main (line 953) | def main() -> int:
FILE: src/skill_seekers/cli/benchmark_cli.py
function run_command (line 16) | def run_command(args):
function run_scraping_benchmark (line 37) | def run_scraping_benchmark(runner, config):
function run_embedding_benchmark (line 61) | def run_embedding_benchmark(runner, config):
function run_storage_benchmark (line 90) | def run_storage_benchmark(runner, config):
function compare_command (line 129) | def compare_command(args):
function list_command (line 153) | def list_command(args):
function show_command (line 173) | def show_command(args):
function cleanup_command (line 203) | def cleanup_command(args):
function main (line 212) | def main():
FILE: src/skill_seekers/cli/chat_scraper.py
function _check_slack_deps (line 181) | def _check_slack_deps() -> None:
function _check_discord_deps (line 191) | def _check_discord_deps() -> None:
function _score_code_quality (line 206) | def _score_code_quality(code: str) -> float:
class ChatToSkillConverter (line 246) | class ChatToSkillConverter:
method __init__ (line 264) | def __init__(self, config: dict) -> None:
method extract_chat (line 301) | def extract_chat(self) -> bool:
method load_extracted_data (line 400) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 420) | def categorize_content(self) -> dict[str, dict]:
method build_skill (line 498) | def build_skill(self) -> None:
method _extract_slack_export (line 531) | def _extract_slack_export(self) -> list[dict]:
method _load_slack_users (line 599) | def _load_slack_users(self, export_dir: Path) -> dict[str, str]:
method _unzip_export (line 633) | def _unzip_export(self, zip_path: Path) -> Path:
method _extract_slack_api (line 659) | def _extract_slack_api(self) -> list[dict]:
method _fetch_slack_channel_messages (line 706) | def _fetch_slack_channel_messages(
method _extract_discord_export (line 755) | def _extract_discord_export(self) -> list[dict]:
method _extract_discord_api (line 826) | def _extract_discord_api(self) -> list[dict]:
method _parse_slack_message (line 917) | def _parse_slack_message(
method _parse_discord_message (line 1029) | def _parse_discord_message(self, raw: dict, channel: str) -> dict | None:
method _extract_code_snippets (line 1146) | def _extract_code_snippets(self, messages: list[dict]) -> list[dict]:
method _extract_links (line 1183) | def _extract_links(self, messages: list[dict]) -> list[dict]:
method _identify_threads (line 1224) | def _identify_threads(self, messages: list[dict]) -> list[dict]:
method _summarize_channels (line 1275) | def _summarize_channels(self, messages: list[dict]) -> dict[str, dict]:
method _build_sections (line 1321) | def _build_sections(self, messages: list[dict], threads: list[dict]) -...
method _generate_reference_file (line 1409) | def _generate_reference_file(
method _generate_index (line 1467) | def _generate_index(self, categorized: dict[str, dict]) -> None:
method _generate_skill_md (line 1529) | def _generate_skill_md(self, categorized: dict[str, dict]) -> None:
method _format_key_topics (line 1676) | def _format_key_topics(self) -> str:
method _section_text (line 1708) | def _section_text(self, section: dict) -> str:
method _sanitize_filename (line 1722) | def _sanitize_filename(self, name: str) -> str:
function main (line 1740) | def main() -> int:
FILE: src/skill_seekers/cli/cloud_storage_cli.py
function upload_command (line 15) | def upload_command(args):
function download_command (line 36) | def download_command(args):
function list_command (line 56) | def list_command(args):
function delete_command (line 85) | def delete_command(args):
function url_command (line 102) | def url_command(args):
function copy_command (line 114) | def copy_command(args):
function format_size (line 125) | def format_size(size_bytes: int) -> str:
function parse_extra_args (line 134) | def parse_extra_args(extra: list | None) -> dict:
function main (line 150) | def main():
FILE: src/skill_seekers/cli/code_analyzer.py
class Parameter (line 39) | class Parameter:
class FunctionSignature (line 48) | class FunctionSignature:
method __post_init__ (line 60) | def __post_init__(self):
class ClassSignature (line 66) | class ClassSignature:
class CodeAnalyzer (line 76) | class CodeAnalyzer:
method __init__ (line 81) | def __init__(self, depth: str = "surface"):
method _offset_to_line (line 91) | def _offset_to_line(self, offset: int) -> int:
method analyze_file (line 95) | def analyze_file(self, file_path: str, content: str, language: str) ->...
method _analyze_python (line 147) | def _analyze_python(self, content: str, file_path: str) -> dict[str, A...
method _extract_python_class (line 192) | def _extract_python_class(self, node: ast.ClassDef) -> ClassSignature:
method _extract_python_function (line 222) | def _extract_python_function(self, node, is_method: bool = False) -> F...
method _analyze_javascript (line 279) | def _analyze_javascript(self, content: str, _file_path: str) -> dict[s...
method _extract_js_methods (line 389) | def _extract_js_methods(self, class_body: str) -> list[dict]:
method _parse_js_parameters (line 421) | def _parse_js_parameters(self, params_str: str) -> list[dict]:
method _analyze_cpp (line 455) | def _analyze_cpp(self, content: str, _file_path: str) -> dict[str, Any]:
method _parse_cpp_parameters (line 513) | def _parse_cpp_parameters(self, params_str: str) -> list[dict]:
method _extract_python_comments (line 548) | def _extract_python_comments(self, content: str) -> list[dict]:
method _extract_js_comments (line 570) | def _extract_js_comments(self, content: str) -> list[dict]:
method _extract_cpp_comments (line 594) | def _extract_cpp_comments(self, content: str) -> list[dict]:
method _analyze_csharp (line 603) | def _analyze_csharp(self, content: str, _file_path: str) -> dict[str, ...
method _extract_csharp_methods (line 714) | def _extract_csharp_methods(self, class_body: str) -> list[dict]:
method _parse_csharp_parameters (line 747) | def _parse_csharp_parameters(self, params_str: str) -> list[dict]:
method _extract_csharp_comments (line 789) | def _extract_csharp_comments(self, content: str) -> list[dict]:
method _analyze_go (line 814) | def _analyze_go(self, content: str, _file_path: str) -> dict[str, Any]:
method _parse_go_parameters (line 884) | def _parse_go_parameters(self, params_str: str) -> list[dict]:
method _extract_go_comments (line 919) | def _extract_go_comments(self, content: str) -> list[dict]:
method _analyze_rust (line 924) | def _analyze_rust(self, content: str, _file_path: str) -> dict[str, Any]:
method _parse_rust_parameters (line 982) | def _parse_rust_parameters(self, params_str: str) -> list[dict]:
method _extract_rust_comments (line 1016) | def _extract_rust_comments(self, content: str) -> list[dict]:
method _analyze_java (line 1043) | def _analyze_java(self, content: str, _file_path: str) -> dict[str, Any]:
method _extract_java_methods (line 1150) | def _extract_java_methods(self, class_body: str) -> list[dict]:
method _parse_java_parameters (line 1181) | def _parse_java_parameters(self, params_str: str) -> list[dict]:
method _extract_java_comments (line 1222) | def _extract_java_comments(self, content: str) -> list[dict]:
method _analyze_ruby (line 1245) | def _analyze_ruby(self, content: str, _file_path: str) -> dict[str, Any]:
method _parse_ruby_parameters (line 1321) | def _parse_ruby_parameters(self, params_str: str) -> list[dict]:
method _extract_ruby_comments (line 1349) | def _extract_ruby_comments(self, content: str) -> list[dict]:
method _analyze_php (line 1363) | def _analyze_php(self, content: str, _file_path: str) -> dict[str, Any]:
method _extract_php_methods (line 1464) | def _extract_php_methods(self, class_body: str) -> list[dict]:
method _parse_php_parameters (line 1491) | def _parse_php_parameters(self, params_str: str) -> list[dict]:
method _extract_php_comments (line 1529) | def _extract_php_comments(self, content: str) -> list[dict]:
method _analyze_godot_scene (line 1552) | def _analyze_godot_scene(self, content: str, file_path: str) -> dict[s...
method _analyze_godot_resource (line 1603) | def _analyze_godot_resource(self, content: str, file_path: str) -> dic...
method _analyze_godot_shader (line 1660) | def _analyze_godot_shader(self, content: str, file_path: str) -> dict[...
method _analyze_gdscript (line 1706) | def _analyze_gdscript(self, content: str, file_path: str) -> dict[str,...
FILE: src/skill_seekers/cli/codebase_scraper.py
function detect_language (line 174) | def detect_language(file_path: Path) -> str:
function load_gitignore (line 188) | def load_gitignore(directory: Path) -> pathspec.PathSpec | None:
function should_exclude_dir (line 218) | def should_exclude_dir(dir_name: str, excluded_dirs: set) -> bool:
function walk_directory (line 232) | def walk_directory(
function walk_markdown_files (line 289) | def walk_markdown_files(
function categorize_markdown_file (line 339) | def categorize_markdown_file(file_path: Path, root: Path) -> str:
function extract_markdown_structure (line 374) | def extract_markdown_structure(content: str) -> dict[str, Any]:
function extract_rst_structure (line 439) | def extract_rst_structure(content: str) -> dict[str, Any]:
function generate_markdown_summary (line 585) | def generate_markdown_summary(
function process_markdown_docs (line 644) | def process_markdown_docs(
function _enhance_docs_with_ai (line 899) | def _enhance_docs_with_ai(docs: list[dict], ai_mode: str) -> list[dict]:
function _enhance_docs_api (line 923) | def _enhance_docs_api(docs: list[dict], api_key: str) -> list[dict]:
function _enhance_docs_local (line 984) | def _enhance_docs_local(docs: list[dict]) -> list[dict]:
function analyze_codebase (line 1045) | def analyze_codebase(
function _generate_skill_md (line 1615) | def _generate_skill_md(
function _get_language_stats (line 1820) | def _get_language_stats(files: list[dict]) -> dict[str, int]:
function _format_patterns_section (line 1831) | def _format_patterns_section(output_dir: Path) -> str:
function _format_examples_section (line 1883) | def _format_examples_section(output_dir: Path) -> str:
function _format_api_section (line 1926) | def _format_api_section(output_dir: Path) -> str:
function _format_architecture_section (line 1953) | def _format_architecture_section(output_dir: Path) -> str:
function _format_config_section (line 1987) | def _format_config_section(output_dir: Path) -> str:
function _format_signal_flow_section (line 2028) | def _format_signal_flow_section(output_dir: Path, results: dict[str, Any...
function _format_documentation_section (line 2097) | def _format_documentation_section(_output_dir: Path, docs_data: dict[str...
function _generate_references (line 2179) | def _generate_references(output_dir: Path):
function _check_deprecated_flags (line 2222) | def _check_deprecated_flags(args):
function main (line 2273) | def main():
FILE: src/skill_seekers/cli/config_command.py
function show_welcome_message (line 12) | def show_welcome_message():
function main_menu (line 57) | def main_menu():
function github_token_menu (line 100) | def github_token_menu():
function add_github_profile (line 145) | def add_github_profile():
function remove_github_profile (line 231) | def remove_github_profile():
function set_default_profile (line 263) | def set_default_profile():
function open_github_token_page (line 295) | def open_github_token_page():
function api_keys_menu (line 307) | def api_keys_menu():
function set_api_key (line 352) | def set_api_key(provider: str, url: str):
function rate_limit_settings (line 375) | def rate_limit_settings():
function resume_settings (line 420) | def resume_settings():
function test_connections (line 458) | def test_connections():
function main (line 522) | def main():
FILE: src/skill_seekers/cli/config_enhancer.py
class ConfigEnhancement (line 39) | class ConfigEnhancement:
class EnhancedConfigFile (line 50) | class EnhancedConfigFile:
class ConfigEnhancer (line 60) | class ConfigEnhancer:
method __init__ (line 70) | def __init__(self, mode: str = "auto"):
method _detect_mode (line 90) | def _detect_mode(self, requested_mode: str) -> str:
method enhance_config_result (line 111) | def enhance_config_result(self, result: dict) -> dict:
method _enhance_via_api (line 132) | def _enhance_via_api(self, result: dict) -> dict:
method _create_enhancement_prompt (line 159) | def _create_enhancement_prompt(self, result: dict) -> str:
method _parse_api_response (line 219) | def _parse_api_response(self, response_text: str, original_result: dic...
method _enhance_via_local (line 254) | def _enhance_via_local(self, result: dict) -> dict:
method _create_local_prompt (line 288) | def _create_local_prompt(self, result: dict, output_file: Path) -> str:
method _run_claude_cli (line 369) | def _run_claude_cli(
function main (line 461) | def main():
FILE: src/skill_seekers/cli/config_extractor.py
class ConfigSetting (line 52) | class ConfigSetting:
class ConfigFile (line 67) | class ConfigFile:
class ConfigExtractionResult (line 91) | class ConfigExtractionResult:
method to_dict (line 100) | def to_dict(self) -> dict:
method to_markdown (line 131) | def to_markdown(self) -> str:
class ConfigFileDetector (line 168) | class ConfigFileDetector:
method find_config_files (line 265) | def find_config_files(self, directory: Path, max_files: int = 100) -> ...
method _walk_directory (line 300) | def _walk_directory(self, directory: Path):
method _detect_config_type (line 318) | def _detect_config_type(self, file_path: Path) -> str | None:
method _infer_purpose (line 335) | def _infer_purpose(self, file_path: Path, _config_type: str) -> str:
class ConfigParser (line 380) | class ConfigParser:
method parse_config_file (line 383) | def parse_config_file(self, config_file: ConfigFile) -> ConfigFile:
method _parse_json (line 425) | def _parse_json(self, config_file: ConfigFile):
method _parse_yaml (line 446) | def _parse_yaml(self, config_file: ConfigFile):
method _parse_toml (line 468) | def _parse_toml(self, config_file: ConfigFile):
method _parse_env (line 480) | def _parse_env(self, config_file: ConfigFile):
method _parse_ini (line 506) | def _parse_ini(self, config_file: ConfigFile):
method _parse_python_config (line 526) | def _parse_python_config(self, config_file: ConfigFile):
method _parse_javascript_config (line 558) | def _parse_javascript_config(self, config_file: ConfigFile):
method _parse_dockerfile (line 578) | def _parse_dockerfile(self, config_file: ConfigFile):
method _extract_settings_from_dict (line 607) | def _extract_settings_from_dict(
method _infer_type (line 627) | def _infer_type(self, value: Any) -> str:
method _extract_env_description (line 644) | def _extract_env_description(self, lines: list[str], line_index: int) ...
method _extract_python_docstring (line 652) | def _extract_python_docstring(self, _node: ast.AST) -> str:
class ConfigPatternDetector (line 658) | class ConfigPatternDetector:
method detect_patterns (line 708) | def detect_patterns(self, config_file: ConfigFile) -> list[str]:
class ConfigExtractor (line 740) | class ConfigExtractor:
method __init__ (line 743) | def __init__(self):
method extract_from_directory (line 748) | def extract_from_directory(
method to_dict (line 803) | def to_dict(self, result: ConfigExtractionResult) -> dict:
function main (line 835) | def main():
FILE: src/skill_seekers/cli/config_fetcher.py
function fetch_config_from_api (line 22) | def fetch_config_from_api(
function list_available_configs (line 100) | def list_available_configs(category: str | None = None, timeout: float =...
function resolve_config_path (line 133) | def resolve_config_path(config_path: str, auto_fetch: bool = True) -> Pa...
function get_last_searched_paths (line 203) | def get_last_searched_paths() -> list[Path]:
FILE: src/skill_seekers/cli/config_manager.py
function _get_config_dir (line 17) | def _get_config_dir() -> Path:
function _get_progress_dir (line 24) | def _get_progress_dir() -> Path:
class ConfigManager (line 31) | class ConfigManager:
method __init__ (line 60) | def __init__(self):
method _ensure_directories (line 75) | def _ensure_directories(self):
method _load_config (line 90) | def _load_config(self) -> dict[str, Any]:
method _merge_with_defaults (line 107) | def _merge_with_defaults(self, config: dict[str, Any]) -> dict[str, Any]:
method save_config (line 121) | def save_config(self):
method add_github_profile (line 137) | def add_github_profile(
method remove_github_profile (line 171) | def remove_github_profile(self, name: str):
method list_github_profiles (line 186) | def list_github_profiles(self) -> list[dict[str, Any]]:
method get_github_token (line 204) | def get_github_token(
method get_profile_for_token (line 239) | def get_profile_for_token(self, token: str) -> str | None:
method get_next_profile (line 246) | def get_next_profile(self, current_token: str) -> tuple | None:
method get_rate_limit_strategy (line 273) | def get_rate_limit_strategy(self, token: str | None = None) -> str:
method get_timeout_minutes (line 284) | def get_timeout_minutes(self, token: str | None = None) -> int:
method set_api_key (line 296) | def set_api_key(self, provider: str, key: str):
method get_api_key (line 305) | def get_api_key(self, provider: str) -> str | None:
method save_progress (line 331) | def save_progress(self, job_id: str, progress_data: dict[str, Any]):
method load_progress (line 344) | def load_progress(self, job_id: str) -> dict[str, Any] | None:
method list_resumable_jobs (line 357) | def list_resumable_jobs(self) -> list[dict[str, Any]]:
method delete_progress (line 383) | def delete_progress(self, job_id: str):
method cleanup_old_progress (line 389) | def cleanup_old_progress(self):
method get_default_enhance_level (line 407) | def get_default_enhance_level(self) -> int:
method set_default_enhance_level (line 411) | def set_default_enhance_level(self, level: int):
method get_local_batch_size (line 420) | def get_local_batch_size(self) -> int:
method set_local_batch_size (line 424) | def set_local_batch_size(self, size: int):
method get_local_parallel_workers (line 431) | def get_local_parallel_workers(self) -> int:
method set_local_parallel_workers (line 435) | def set_local_parallel_workers(self, workers: int):
method get_default_agent (line 442) | def get_default_agent(self) -> str | None:
method set_default_agent (line 450) | def set_default_agent(self, agent: str | None):
method is_first_run (line 463) | def is_first_run(self) -> bool:
method mark_first_run_complete (line 467) | def mark_first_run_complete(self):
method should_show_welcome (line 472) | def should_show_welcome(self) -> bool:
method mark_welcome_shown (line 476) | def mark_welcome_shown(self):
method display_config_summary (line 485) | def display_config_summary(self):
function get_config_manager (line 551) | def get_config_manager() -> ConfigManager:
FILE: src/skill_seekers/cli/config_validator.py
class ConfigValidator (line 37) | class ConfigValidator:
method __init__ (line 72) | def __init__(self, config_or_path: dict[str, Any] | str):
method _load_config (line 87) | def _load_config(self) -> dict[str, Any]:
method validate (line 97) | def validate(self) -> bool:
method _validate_unified (line 134) | def _validate_unified(self) -> bool:
method _validate_source (line 171) | def _validate_source(self, source: dict[str, Any], index: int):
method _validate_documentation_source (line 220) | def _validate_documentation_source(self, source: dict[str, Any], index...
method _validate_github_source (line 234) | def _validate_github_source(self, source: dict[str, Any], index: int):
method _validate_pdf_source (line 275) | def _validate_pdf_source(self, source: dict[str, Any], index: int):
method _validate_local_source (line 285) | def _validate_local_source(self, source: dict[str, Any], index: int):
method _validate_word_source (line 313) | def _validate_word_source(self, source: dict[str, Any], index: int):
method _validate_video_source (line 321) | def _validate_video_source(self, source: dict[str, Any], index: int):
method _validate_epub_source (line 331) | def _validate_epub_source(self, source: dict[str, Any], index: int):
method _validate_jupyter_source (line 339) | def _validate_jupyter_source(self, source: dict[str, Any], index: int):
method _validate_html_source (line 347) | def _validate_html_source(self, source: dict[str, Any], index: int):
method _validate_openapi_source (line 355) | def _validate_openapi_source(self, source: dict[str, Any], index: int):
method _validate_asciidoc_source (line 362) | def _validate_asciidoc_source(self, source: dict[str, Any], index: int):
method _validate_pptx_source (line 370) | def _validate_pptx_source(self, source: dict[str, Any], index: int):
method _validate_confluence_source (line 378) | def _validate_confluence_source(self, source: dict[str, Any], index: i...
method _validate_notion_source (line 390) | def _validate_notion_source(self, source: dict[str, Any], index: int):
method _validate_rss_source (line 400) | def _validate_rss_source(self, source: dict[str, Any], index: int):
method _validate_manpage_source (line 405) | def _validate_manpage_source(self, source: dict[str, Any], index: int):
method _validate_chat_source (line 412) | def _validate_chat_source(self, source: dict[str, Any], index: int):
method get_sources_by_type (line 427) | def get_sources_by_type(self, source_type: str) -> list[dict[str, Any]]:
method has_multiple_sources (line 440) | def has_multiple_sources(self) -> bool:
method needs_api_merge (line 444) | def needs_api_merge(self) -> bool:
function validate_config (line 467) | def validate_config(config_path: str) -> ConfigValidator:
FILE: src/skill_seekers/cli/conflict_detector.py
class Conflict (line 25) | class Conflict:
class ConflictDetector (line 37) | class ConflictDetector:
method __init__ (line 42) | def __init__(self, docs_data: dict[str, Any], github_data: dict[str, A...
method _extract_docs_apis (line 60) | def _extract_docs_apis(self) -> dict[str, dict[str, Any]]:
method _parse_doc_content_for_apis (line 106) | def _parse_doc_content_for_apis(self, content: str, source_url: str) -...
method _parse_param_string (line 176) | def _parse_param_string(self, params_str: str) -> list[dict]:
method _extract_code_apis (line 214) | def _extract_code_apis(self) -> dict[str, dict[str, Any]]:
method detect_all_conflicts (line 277) | def detect_all_conflicts(self) -> list[Conflict]:
method _find_missing_in_docs (line 301) | def _find_missing_in_docs(self) -> list[Conflict]:
method _find_missing_in_code (line 328) | def _find_missing_in_code(self) -> list[Conflict]:
method _find_signature_mismatches (line 348) | def _find_signature_mismatches(self) -> list[Conflict]:
method _compare_signatures (line 378) | def _compare_signatures(self, docs_info: dict, code_info: dict) -> dic...
method generate_summary (line 436) | def generate_summary(self, conflicts: list[Conflict]) -> dict[str, Any]:
method save_conflicts (line 470) | def save_conflicts(self, conflicts: list[Conflict], output_path: str):
FILE: src/skill_seekers/cli/confluence_scraper.py
function _check_atlassian_deps (line 135) | def _check_atlassian_deps() -> None:
function infer_description_from_confluence (line 145) | def infer_description_from_confluence(
class ConfluenceToSkillConverter (line 180) | class ConfluenceToSkillConverter:
method __init__ (line 212) | def __init__(self, config: dict) -> None:
method extract_confluence (line 249) | def extract_confluence(self) -> bool:
method _extract_via_api (line 373) | def _extract_via_api(self) -> list[dict[str, Any]]:
method _is_cloud_instance (line 519) | def _is_cloud_instance(self) -> bool:
method _extract_from_export (line 533) | def _extract_from_export(self) -> list[dict[str, Any]]:
method _parse_entities_xml (line 638) | def _parse_entities_xml(
method _parse_export_index (line 710) | def _parse_export_index(self, index_path: Path) -> dict[str, str]:
method _parse_confluence_html (line 758) | def _parse_confluence_html(
method _extract_macros (line 882) | def _extract_macros(self, soup: BeautifulSoup) -> list[dict[str, Any]]:
method _clean_confluence_html (line 970) | def _clean_confluence_html(self, soup: BeautifulSoup) -> BeautifulSoup:
method _extract_page_tree (line 1025) | def _extract_page_tree(
method _extract_table (line 1083) | def _extract_table(self, table_elem: Tag) -> dict[str, Any] | None:
method _detect_language_from_classes (line 1130) | def _detect_language_from_classes(self, elem: Tag) -> str:
method _html_to_text (line 1162) | def _html_to_text(self, elem: Tag | BeautifulSoup) -> str:
method load_extracted_data (line 1258) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 1285) | def categorize_content(self) -> dict[str, dict[str, Any]]:
method _collect_descendant_ids (line 1376) | def _collect_descendant_ids(self, node: dict[str, Any]) -> list[str]:
method build_skill (line 1397) | def build_skill(self) -> None:
method _generate_reference_file (line 1446) | def _generate_reference_file(
method _generate_index (line 1581) | def _generate_index(self, categorised: dict[str, dict[str, Any]]) -> N...
method _write_tree_structure (line 1631) | def _write_tree_structure(
method _generate_skill_md (line 1652) | def _generate_skill_md(self, categorised: dict[str, dict[str, Any]]) -...
method _format_key_topics (line 1798) | def _format_key_topics(self) -> str:
method _sanitize_filename (line 1851) | def _sanitize_filename(self, name: str) -> str:
function _score_code_quality (line 1873) | def _score_code_quality(code: str) -> float:
function main (line 1926) | def main() -> int:
FILE: src/skill_seekers/cli/create_command.py
class CreateCommand (line 21) | class CreateCommand:
method __init__ (line 24) | def __init__(self, args: argparse.Namespace):
method execute (line 33) | def execute(self) -> int:
method _validate_arguments (line 62) | def _validate_arguments(self) -> None:
method _is_explicitly_set (line 89) | def _is_explicitly_set(self, arg_name: str, arg_value: any) -> bool:
method _route_to_scraper (line 121) | def _route_to_scraper(self) -> int:
method _route_web (line 167) | def _route_web(self) -> int:
method _route_github (line 234) | def _route_github(self) -> int:
method _route_local (line 281) | def _route_local(self) -> int:
method _route_pdf (line 324) | def _route_pdf(self) -> int:
method _route_word (line 353) | def _route_word(self) -> int:
method _route_epub (line 376) | def _route_epub(self) -> int:
method _route_video (line 399) | def _route_video(self) -> int:
method _route_config (line 462) | def _route_config(self) -> int:
method _route_generic (line 508) | def _route_generic(self, module_name: str, file_flag: str) -> int:
method _add_common_args (line 542) | def _add_common_args(self, argv: list[str]) -> None:
function main (line 597) | def main() -> int:
FILE: src/skill_seekers/cli/dependency_analyzer.py
class DependencyInfo (line 62) | class DependencyInfo:
class FileNode (line 73) | class FileNode:
class DependencyAnalyzer (line 82) | class DependencyAnalyzer:
method __init__ (line 90) | def __init__(self):
method _offset_to_line (line 102) | def _offset_to_line(self, offset: int) -> int:
method analyze_file (line 106) | def analyze_file(self, file_path: str, content: str, language: str) ->...
method _extract_python_imports (line 160) | def _extract_python_imports(self, content: str, file_path: str) -> lis...
method _extract_gdscript_imports (line 211) | def _extract_gdscript_imports(self, content: str, file_path: str) -> l...
method _extract_js_imports (line 330) | def _extract_js_imports(self, content: str, file_path: str) -> list[De...
method _extract_cpp_includes (line 379) | def _extract_cpp_includes(self, content: str, file_path: str) -> list[...
method _extract_csharp_imports (line 410) | def _extract_csharp_imports(self, content: str, file_path: str) -> lis...
method _extract_go_imports (line 448) | def _extract_go_imports(self, content: str, file_path: str) -> list[De...
method _extract_rust_imports (line 509) | def _extract_rust_imports(self, content: str, file_path: str) -> list[...
method _extract_java_imports (line 566) | def _extract_java_imports(self, content: str, file_path: str) -> list[...
method _extract_ruby_imports (line 598) | def _extract_ruby_imports(self, content: str, file_path: str) -> list[...
method _extract_php_imports (line 662) | def _extract_php_imports(self, content: str, file_path: str) -> list[D...
method build_graph (line 718) | def build_graph(self) -> nx.DiGraph:
method _resolve_import (line 750) | def _resolve_import(
method detect_cycles (line 782) | def detect_cycles(self) -> list[list[str]]:
method get_strongly_connected_components (line 800) | def get_strongly_connected_components(self) -> list[set[str]]:
method export_dot (line 809) | def export_dot(self, output_path: str):
method export_json (line 825) | def export_json(self) -> dict[str, Any]:
method export_mermaid (line 848) | def export_mermaid(self) -> str:
method get_statistics (line 873) | def get_statistics(self) -> dict[str, Any]:
method _extract_godot_resources (line 898) | def _extract_godot_resources(self, content: str, file_path: str) -> li...
FILE: src/skill_seekers/cli/doc_scraper.py
function infer_description_from_docs (line 73) | def infer_description_from_docs(
class DocToSkillConverter (line 155) | class DocToSkillConverter:
method __init__ (line 156) | def __init__(self, config: dict[str, Any], dry_run: bool = False, resu...
method _enqueue_url (line 227) | def _enqueue_url(self, url: str) -> None:
method is_valid_url (line 238) | def is_valid_url(self, url: str) -> bool:
method save_checkpoint (line 255) | def save_checkpoint(self) -> None:
method load_checkpoint (line 276) | def load_checkpoint(self) -> None:
method clear_checkpoint (line 303) | def clear_checkpoint(self) -> None:
method _find_main_content (line 312) | def _find_main_content(self, soup: Any) -> tuple[Any, str | None]:
method extract_content (line 341) | def extract_content(self, soup: Any, url: str) -> dict[str, Any]:
method _extract_markdown_content (line 407) | def _extract_markdown_content(self, content: str, url: str) -> dict[st...
method _extract_html_as_markdown (line 559) | def _extract_html_as_markdown(self, html_content: str, url: str) -> di...
method detect_language (line 637) | def detect_language(self, elem, code):
method extract_patterns (line 650) | def extract_patterns(
method clean_text (line 672) | def clean_text(self, text: str) -> str:
method save_page (line 676) | def save_page(self, page: dict[str, Any]) -> None:
method scrape_page (line 693) | def scrape_page(self, url: str) -> None:
method scrape_page_async (line 750) | async def scrape_page_async(
method _convert_to_md_urls (line 799) | def _convert_to_md_urls(self, urls: list[str]) -> list[str]:
method _try_llms_txt (line 867) | def _try_llms_txt(self) -> bool:
method scrape_all (line 1064) | def scrape_all(self) -> None:
method scrape_all_async (line 1234) | async def scrape_all_async(self) -> None:
method save_summary (line 1377) | def save_summary(self) -> None:
method load_scraped_data (line 1394) | def load_scraped_data(self) -> list[dict[str, Any]]:
method smart_categorize (line 1419) | def smart_categorize(self, pages: list[dict[str, Any]]) -> dict[str, l...
method infer_categories (line 1468) | def infer_categories(self, pages: list[dict[str, Any]]) -> dict[str, l...
method generate_quick_reference (line 1499) | def generate_quick_reference(self, pages: list[dict[str, Any]]) -> lis...
method create_reference_file (line 1520) | def create_reference_file(self, category: str, pages: list[dict[str, A...
method create_enhanced_skill_md (line 1567) | def create_enhanced_skill_md(
method create_index (line 1707) | def create_index(self, categories: dict[str, list[dict[str, Any]]]) ->...
method build_skill (line 1724) | def build_skill(self) -> bool:
function validate_config (line 1774) | def validate_config(config: dict[str, Any]) -> tuple[list[str], list[str]]:
function load_config (line 1898) | def load_config(config_path: str) -> dict[str, Any]:
function interactive_config (line 1986) | def interactive_config() -> dict[str, Any]:
function check_existing_data (line 2044) | def check_existing_data(name: str) -> tuple[bool, int]:
function setup_argument_parser (line 2066) | def setup_argument_parser() -> argparse.ArgumentParser:
function get_configuration (line 2096) | def get_configuration(args: argparse.Namespace) -> dict[str, Any]:
function execute_scraping_and_building (line 2207) | def execute_scraping_and_building(
function execute_enhancement (line 2365) | def execute_enhancement(config: dict[str, Any], args: argparse.Namespace...
function main (line 2451) | def main() -> None:
FILE: src/skill_seekers/cli/embedding_pipeline.py
class EmbeddingConfig (line 20) | class EmbeddingConfig:
class EmbeddingResult (line 33) | class EmbeddingResult:
class CostTracker (line 45) | class CostTracker:
method add_request (line 54) | def add_request(self, token_count: int, cost: float, from_cache: bool ...
method get_stats (line 65) | def get_stats(self) -> dict[str, Any]:
class EmbeddingProvider (line 79) | class EmbeddingProvider(ABC):
method generate_embeddings (line 83) | def generate_embeddings(self, texts: list[str]) -> list[list[float]]:
method get_dimension (line 88) | def get_dimension(self) -> int:
method estimate_cost (line 93) | def estimate_cost(self, token_count: int) -> float:
class OpenAIEmbeddingProvider (line 98) | class OpenAIEmbeddingProvider(EmbeddingProvider):
method __init__ (line 114) | def __init__(self, model: str = "text-embedding-ada-002", api_key: str...
method _get_client (line 120) | def _get_client(self):
method generate_embeddings (line 133) | def generate_embeddings(self, texts: list[str]) -> list[list[float]]:
method get_dimension (line 144) | def get_dimension(self) -> int:
method estimate_cost (line 148) | def estimate_cost(self, token_count: int) -> float:
class LocalEmbeddingProvider (line 154) | class LocalEmbeddingProvider(EmbeddingProvider):
method __init__ (line 157) | def __init__(self, dimension: int = 384):
method generate_embeddings (line 161) | def generate_embeddings(self, texts: list[str]) -> list[list[float]]:
method get_dimension (line 174) | def get_dimension(self) -> int:
method estimate_cost (line 178) | def estimate_cost(self, token_count: int) -> float:
class EmbeddingCache (line 183) | class EmbeddingCache:
method __init__ (line 186) | def __init__(self, cache_dir: Path | None = None):
method _compute_hash (line 194) | def _compute_hash(self, text: str, model: str) -> str:
method get (line 199) | def get(self, text: str, model: str) -> list[float] | None:
method set (line 221) | def set(self, text: str, model: str, embedding: list[float]) -> None:
class EmbeddingPipeline (line 246) | class EmbeddingPipeline:
method __init__ (line 253) | def __init__(self, config: EmbeddingConfig):
method _create_provider (line 260) | def _create_provider(self) -> EmbeddingProvider:
method _estimate_tokens (line 269) | def _estimate_tokens(self, text: str) -> int:
method generate_batch (line 274) | def generate_batch(self, texts: list[str], show_progress: bool = True)...
method validate_dimensions (line 365) | def validate_dimensions(self, embeddings: list[list[float]]) -> bool:
method get_cost_stats (line 387) | def get_cost_stats(self) -> dict[str, Any]:
function example_usage (line 392) | def example_usage():
FILE: src/skill_seekers/cli/enhance_command.py
function _is_root (line 32) | def _is_root() -> bool:
function _get_api_keys (line 40) | def _get_api_keys() -> dict[str, str | None]:
function _get_config_default_agent (line 49) | def _get_config_default_agent() -> str | None:
function _pick_mode (line 59) | def _pick_mode(args) -> tuple[str, str | None]:
function _run_api_mode (line 97) | def _run_api_mode(args, target: str) -> int:
function _run_local_mode (line 140) | def _run_local_mode(args) -> int:
function main (line 171) | def main() -> int:
FILE: src/skill_seekers/cli/enhance_skill.py
class SkillEnhancer (line 34) | class SkillEnhancer:
method __init__ (line 35) | def __init__(self, skill_dir, api_key=None):
method read_current_skill_md (line 59) | def read_current_skill_md(self):
method enhance_skill_md (line 65) | def enhance_skill_md(self, references, current_skill_md):
method _is_video_source (line 100) | def _is_video_source(self, references):
method _build_enhancement_prompt (line 104) | def _build_enhancement_prompt(self, references, current_skill_md):
method _build_video_enhancement_prompt (line 287) | def _build_video_enhancement_prompt(self, references, current_skill_md):
method save_enhanced_skill_md (line 429) | def save_enhanced_skill_md(self, content):
method run (line 441) | def run(self):
function main (line 499) | def main():
FILE: src/skill_seekers/cli/enhance_skill_local.py
function detect_terminal_app (line 65) | def detect_terminal_app():
function _normalize_agent_name (line 138) | def _normalize_agent_name(agent_name: str) -> str:
class LocalSkillEnhancer (line 153) | class LocalSkillEnhancer:
method __init__ (line 154) | def __init__(self, skill_dir, force=True, agent=None, agent_cmd=None):
method _validate_custom_command (line 170) | def _validate_custom_command(self, cmd_template: str) -> None:
method _resolve_agent (line 195) | def _resolve_agent(self, agent, agent_cmd):
method _build_agent_command (line 220) | def _build_agent_command(self, prompt_file, include_permissions_flag):
method _format_agent_command (line 244) | def _format_agent_command(self, prompt_file, include_permissions_flag):
method _run_agent_command (line 253) | def _run_agent_command(self, prompt_file, timeout, include_permissions...
method summarize_reference (line 292) | def summarize_reference(self, content: str, target_ratio: float = 0.3)...
method create_enhancement_prompt (line 384) | def create_enhancement_prompt(self, use_summarization=False, summariza...
method write_status (line 621) | def write_status(self, status, message="", progress=0.0, error=None):
method read_status (line 641) | def read_status(self):
method run (line 655) | def run(self, headless=True, timeout=600, background=False, daemon=Fal...
method _run_headless (line 832) | def _run_headless(self, prompt_file, timeout):
method _run_background (line 962) | def _run_background(self, headless, timeout):
method _run_daemon (line 1062) | def _run_daemon(self, timeout):
function _detect_api_target (line 1229) | def _detect_api_target() -> tuple[str, str] | None:
function _run_api_enhance (line 1253) | def _run_api_enhance(target: str, api_key: str) -> None:
function main (line 1284) | def main():
FILE: src/skill_seekers/cli/enhance_status.py
function read_status (line 19) | def read_status(skill_dir):
function format_status (line 39) | def format_status(status):
function watch_status (line 94) | def watch_status(skill_dir, interval=2):
function main (line 130) | def main():
FILE: src/skill_seekers/cli/enhancement_workflow.py
class WorkflowStage (line 39) | class WorkflowStage:
class PostProcessConfig (line 52) | class PostProcessConfig:
class EnhancementWorkflow (line 62) | class EnhancementWorkflow:
class WorkflowEngine (line 75) | class WorkflowEngine:
method __init__ (line 87) | def __init__(self, workflow: EnhancementWorkflow | str | Path):
method _load_workflow (line 102) | def _load_workflow(self, workflow_ref: str | Path) -> EnhancementWorkf...
method _merge_workflows (line 200) | def _merge_workflows(self, parent: EnhancementWorkflow, child_data: di...
method run (line 252) | def run(self, analysis_results: dict, context: dict | None = None) -> ...
method _build_stage_context (line 317) | def _build_stage_context(
method _run_stage (line 338) | def _run_stage(self, stage: WorkflowStage, context: dict) -> dict:
method _run_builtin_stage (line 345) | def _run_builtin_stage(self, stage: WorkflowStage, context: dict) -> d...
method _run_custom_stage (line 367) | def _run_custom_stage(self, stage: WorkflowStage, context: dict) -> dict:
method _merge_stage_results (line 403) | def _merge_stage_results(self, current: dict, stage_results: dict, tar...
method _post_process (line 413) | def _post_process(self, results: dict) -> dict:
method save_history (line 443) | def save_history(self, output_path: Path):
function list_bundled_workflows (line 461) | def list_bundled_workflows() -> list[str]:
function list_user_workflows (line 475) | def list_user_workflows() -> list[str]:
FILE: src/skill_seekers/cli/epub_scraper.py
function _check_epub_deps (line 36) | def _check_epub_deps():
function infer_description_from_epub (line 46) | def infer_description_from_epub(metadata: dict | None = None, name: str ...
class EpubToSkillConverter (line 71) | class EpubToSkillConverter:
method __init__ (line 74) | def __init__(self, config):
method extract_epub (line 92) | def extract_epub(self):
method _detect_drm (line 213) | def _detect_drm(self, book) -> bool:
method _extract_metadata (line 266) | def _extract_metadata(self, book) -> dict:
method _extract_spine_content (line 296) | def _extract_spine_content(self, book) -> list[dict]:
method _extract_images (line 373) | def _extract_images(self, book) -> int:
method load_extracted_data (line 404) | def load_extracted_data(self, json_path):
method categorize_content (line 413) | def categorize_content(self):
method build_skill (line 485) | def build_skill(self):
method _generate_reference_file (line 514) | def _generate_reference_file(self, _cat_key, cat_data, section_num, to...
method _generate_index (line 610) | def _generate_index(self, categorized):
method _generate_skill_md (line 663) | def _generate_skill_md(self, categorized):
method _format_key_concepts (line 805) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 844) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 894) | def _sanitize_filename(self, name):
function _build_section (line 906) | def _build_section(
function _extract_table_from_html (line 1005) | def _extract_table_from_html(table_elem) -> dict | None:
function _score_code_quality (line 1035) | def _score_code_quality(code: str) -> float:
function main (line 1073) | def main():
FILE: src/skill_seekers/cli/estimate_pages.py
function estimate_pages (line 23) | def estimate_pages(config, max_discovery=DEFAULT_MAX_DISCOVERY, timeout=...
function is_valid_url (line 140) | def is_valid_url(url, base_url, include_patterns, exclude_patterns):
function print_results (line 160) | def print_results(results, config):
function load_config (line 214) | def load_config(config_path):
function find_configs_directory (line 228) | def find_configs_directory():
function list_all_configs (line 251) | def list_all_configs():
function main (line 344) | def main():
FILE: src/skill_seekers/cli/generate_router.py
class RouterGenerator (line 34) | class RouterGenerator:
method __init__ (line 37) | def __init__(
method load_config (line 76) | def load_config(self, path: Path) -> dict[str, Any]:
method infer_router_name (line 85) | def infer_router_name(self) -> str:
method extract_routing_keywords (line 98) | def extract_routing_keywords(self) -> dict[str, list[str]]:
method _extract_skill_specific_labels (line 149) | def _extract_skill_specific_labels(self, _skill_name: str, skill_keywo...
method _generate_frontmatter (line 201) | def _generate_frontmatter(self, _routing_keywords: dict[str, list[str]...
method _extract_clean_readme_section (line 269) | def _extract_clean_readme_section(self, readme: str) -> str:
method _extract_topic_from_skill (line 291) | def _extract_topic_from_skill(self, skill_name: str) -> str:
method _generate_dynamic_examples (line 338) | def _generate_dynamic_examples(self, routing_keywords: dict[str, list[...
method _generate_examples_from_github (line 400) | def _generate_examples_from_github(self, routing_keywords: dict[str, l...
method _convert_issue_to_question (line 453) | def _convert_issue_to_question(self, issue_title: str) -> str:
method _extract_common_patterns (line 488) | def _extract_common_patterns(self) -> list[dict[str, str]]:
method _parse_issue_pattern (line 522) | def _parse_issue_pattern(self, issue_title: str) -> tuple:
method _detect_framework (line 560) | def _detect_framework(self) -> str | None:
method _get_framework_hello_world (line 598) | def _get_framework_hello_world(self, framework: str) -> str:
method _generate_comprehensive_description (line 677) | def _generate_comprehensive_description(self) -> str:
method generate_skill_md (line 719) | def generate_skill_md(self) -> str:
method generate_subskill_issues_section (line 927) | def generate_subskill_issues_section(self, _skill_name: str, topics: l...
method create_router_config (line 987) | def create_router_config(self) -> dict[str, Any]:
method _generate_github_issues_reference (line 1009) | def _generate_github_issues_reference(self) -> str:
method _generate_getting_started_reference (line 1066) | def _generate_getting_started_reference(self) -> str:
method _generate_reference_files (line 1089) | def _generate_reference_files(self, references_dir: Path):
method generate (line 1112) | def generate(self, output_dir: Path = None) -> tuple[Path, Path]:
function main (line 1142) | def main():
FILE: src/skill_seekers/cli/github_fetcher.py
class CodeStream (line 26) | class CodeStream:
class DocsStream (line 34) | class DocsStream:
class InsightsStream (line 43) | class InsightsStream:
class ThreeStreamData (line 53) | class ThreeStreamData:
class GitHubThreeStreamFetcher (line 61) | class GitHubThreeStreamFetcher:
method __init__ (line 79) | def __init__(
method parse_repo_url (line 109) | def parse_repo_url(self, url: str) -> tuple[str, str]:
method fetch (line 137) | def fetch(self, output_dir: Path = None) -> ThreeStreamData:
method clone_repo (line 194) | def clone_repo(self, output_dir: Path) -> Path:
method fetch_github_metadata (line 216) | def fetch_github_metadata(self) -> dict:
method fetch_issues (line 268) | def fetch_issues(self, max_issues: int = 100) -> list[dict]:
method _fetch_issues_page (line 288) | def _fetch_issues_page(self, state: str, max_count: int) -> list[dict]:
method classify_files (line 332) | def classify_files(self, repo_path: Path) -> tuple[list[Path], list[Pa...
method analyze_issues (line 435) | def analyze_issues(self, issues: list[dict]) -> dict:
method read_file (line 514) | def read_file(self, file_path: Path) -> str | None:
FILE: src/skill_seekers/cli/github_scraper.py
function extract_description_from_readme (line 105) | def extract_description_from_readme(readme_content: str, repo_name: str)...
class GitHubScraper (line 186) | class GitHubScraper:
method __init__ (line 202) | def __init__(self, config: dict[str, Any], local_repo_path: str | None...
method _get_token (line 289) | def _get_token(self) -> str | None:
method scrape (line 311) | def scrape(self) -> dict[str, Any]:
method _fetch_repository (line 356) | def _fetch_repository(self):
method _get_file_content (line 390) | def _get_file_content(self, file_path: str) -> str | None:
method _extract_readme (line 467) | def _extract_readme(self):
method _extract_code_structure (line 499) | def _extract_code_structure(self):
method _extract_languages (line 516) | def _extract_languages(self):
method should_exclude_dir (line 539) | def should_exclude_dir(self, dir_name: str, dir_path: str = None) -> b...
method _load_gitignore (line 574) | def _load_gitignore(self) -> Optional["pathspec.PathSpec"]:
method _extract_file_tree (line 603) | def _extract_file_tree(self):
method _extract_file_tree_local (line 614) | def _extract_file_tree_local(self):
method _extract_file_tree_github (line 666) | def _extract_file_tree_github(self):
method _extract_signatures_and_tests (line 693) | def _extract_signatures_and_tests(self):
method _extract_issues (line 807) | def _extract_issues(self):
method _extract_changelog (line 841) | def _extract_changelog(self):
method _extract_releases (line 866) | def _extract_releases(self):
method _save_data (line 897) | def _save_data(self):
class GitHubToSkillConverter (line 907) | class GitHubToSkillConverter:
method __init__ (line 912) | def __init__(self, config: dict[str, Any]):
method _load_data (line 936) | def _load_data(self) -> dict[str, Any]:
method build_skill (line 944) | def build_skill(self):
method _generate_skill_md (line 962) | def _generate_skill_md(self):
method _format_languages (line 1091) | def _format_languages(self) -> str:
method _format_recent_releases (line 1103) | def _format_recent_releases(self) -> str:
method _format_pattern_summary (line 1117) | def _format_pattern_summary(self, c3_data: dict[str, Any]) -> str:
method _format_code_examples (line 1158) | def _format_code_examples(self, c3_data: dict[str, Any]) -> str:
method _format_api_reference (line 1187) | def _format_api_reference(self, c3_data: dict[str, Any]) -> str:
method _format_architecture (line 1210) | def _format_architecture(self, c3_data: dict[str, Any]) -> str:
method _format_known_issues (line 1244) | def _format_known_issues(self) -> str:
method _generate_references (line 1267) | def _generate_references(self):
method _generate_issues_reference (line 1295) | def _generate_issues_reference(self):
method _generate_releases_reference (line 1326) | def _generate_releases_reference(self):
method _generate_file_structure_reference (line 1350) | def _generate_file_structure_reference(self):
function setup_argument_parser (line 1372) | def setup_argument_parser() -> argparse.ArgumentParser:
function main (line 1400) | def main():
FILE: src/skill_seekers/cli/guide_enhancer.py
class PrerequisiteItem (line 35) | class PrerequisiteItem:
class TroubleshootingItem (line 41) | class TroubleshootingItem:
class StepEnhancement (line 61) | class StepEnhancement:
class GuideEnhancer (line 69) | class GuideEnhancer:
method __init__ (line 79) | def __init__(self, mode: str = "auto"):
method _detect_mode (line 127) | def _detect_mode(self, requested_mode: str) -> str:
method _check_claude_cli (line 147) | def _check_claude_cli(self) -> bool:
method enhance_guide (line 157) | def enhance_guide(self, guide_data: dict) -> dict:
method enhance_step_descriptions (line 181) | def enhance_step_descriptions(self, steps: list[dict]) -> list[StepEnh...
method enhance_troubleshooting (line 214) | def enhance_troubleshooting(self, guide_data: dict) -> list[Troublesho...
method enhance_prerequisites (line 248) | def enhance_prerequisites(self, prereqs: list[str]) -> list[Prerequisi...
method enhance_next_steps (line 279) | def enhance_next_steps(self, guide_data: dict) -> list[str]:
method enhance_use_cases (line 305) | def enhance_use_cases(self, guide_data: dict) -> list[str]:
method _call_ai (line 333) | def _call_ai(self, prompt: str, max_tokens: int = 4000) -> str | None:
method _call_claude_api (line 350) | def _call_claude_api(self, prompt: str, max_tokens: int = 4000) -> str...
method _call_claude_local (line 375) | def _call_claude_local(self, prompt: str) -> str | None:
method _enhance_via_api (line 414) | def _enhance_via_api(self, guide_data: dict) -> dict:
method _enhance_via_local (line 432) | def _enhance_via_local(self, guide_data: dict) -> dict:
method _create_enhancement_prompt (line 450) | def _create_enhancement_prompt(self, guide_data: dict) -> str:
method _create_step_description_prompt (line 543) | def _create_step_description_prompt(self, steps: list[dict]) -> str:
method _create_troubleshooting_prompt (line 561) | def _create_troubleshooting_prompt(self, guide_data: dict) -> str:
method _create_prerequisites_prompt (line 590) | def _create_prerequisites_prompt(self, prereqs: list[str]) -> str:
method _create_next_steps_prompt (line 608) | def _create_next_steps_prompt(self, guide_data: dict) -> str:
method _create_use_cases_prompt (line 625) | def _create_use_cases_prompt(self, guide_data: dict) -> str:
method _format_steps_for_prompt (line 647) | def _format_steps_for_prompt(self, steps: list[dict]) -> str:
method _parse_enhancement_response (line 663) | def _parse_enhancement_response(self, response: str, guide_data: dict)...
FILE: src/skill_seekers/cli/how_to_guide_builder.py
class PrerequisiteItem (line 52) | class PrerequisiteItem:
class TroubleshootingItem (line 61) | class TroubleshootingItem:
class WorkflowStep (line 71) | class WorkflowStep:
class HowToGuide (line 86) | class HowToGuide:
method to_dict (line 122) | def to_dict(self) -> dict:
class GuideCollection (line 131) | class GuideCollection:
method to_dict (line 139) | def to_dict(self) -> dict:
class WorkflowAnalyzer (line 156) | class WorkflowAnalyzer:
method analyze_workflow (line 159) | def analyze_workflow(self, workflow: dict) -> tuple[list[WorkflowStep]...
method _extract_steps_python (line 195) | def _extract_steps_python(self, code: str, workflow: dict) -> list[Wor...
method _extract_steps_heuristic (line 244) | def _extract_steps_heuristic(self, code: str, _workflow: dict) -> list...
method _generate_step_description (line 285) | def _generate_step_description(self, node: ast.AST, code: str) -> str:
method _describe_value (line 299) | def _describe_value(self, node: ast.AST) -> str:
method _get_name (line 310) | def _get_name(self, node: ast.AST) -> str:
method _infer_description_from_code (line 320) | def _infer_description_from_code(self, code: str) -> str:
method _detect_prerequisites (line 342) | def _detect_prerequisites(self, workflow: dict) -> dict:
method _find_verification_points (line 368) | def _find_verification_points(self, code: str) -> list[str]:
method _calculate_complexity (line 379) | def _calculate_complexity(self, steps: list[WorkflowStep], workflow: d...
method _estimate_time (line 399) | def _estimate_time(self, steps: list[WorkflowStep]) -> str:
class WorkflowGrouper (line 418) | class WorkflowGrouper:
method group_workflows (line 421) | def group_workflows(
method _group_by_ai_tutorial_group (line 450) | def _group_by_ai_tutorial_group(self, workflows: list[dict]) -> dict[s...
method _group_by_file_path (line 473) | def _group_by_file_path(self, workflows: list[dict]) -> dict[str, list...
method _group_by_test_name (line 487) | def _group_by_test_name(self, workflows: list[dict]) -> dict[str, list...
method _group_by_complexity (line 499) | def _group_by_complexity(self, workflows: list[dict]) -> dict[str, lis...
method _clean_test_name (line 516) | def _clean_test_name(self, test_name: str) -> str:
method _extract_prefix (line 525) | def _extract_prefix(self, test_name: str) -> str:
class GuideGenerator (line 541) | class GuideGenerator:
method generate_guide_markdown (line 544) | def generate_guide_markdown(self, guide: HowToGuide) -> str:
method _create_header (line 584) | def _create_header(self, guide: HowToGuide) -> str:
method _create_overview (line 596) | def _create_overview(self, guide: HowToGuide) -> str:
method _create_prerequisites (line 600) | def _create_prerequisites(self, guide: HowToGuide) -> str:
method _create_steps_section (line 635) | def _create_steps_section(self, steps: list[WorkflowStep]) -> str:
method _create_complete_example (line 675) | def _create_complete_example(self, guide: HowToGuide) -> str:
method _create_troubleshooting (line 706) | def _create_troubleshooting(self, guide: HowToGuide) -> str:
method _create_next_steps (line 729) | def _create_next_steps(self, guide: HowToGuide) -> str:
method _create_footer (line 751) | def _create_footer(self, guide: HowToGuide) -> str:
method generate_index (line 761) | def generate_index(self, guides: list[HowToGuide]) -> str:
class HowToGuideBuilder (line 821) | class HowToGuideBuilder:
method __init__ (line 824) | def __init__(self, enhance_with_ai: bool = True):
method build_guides_from_examples (line 836) | def build_guides_from_examples(
method _extract_workflow_examples (line 910) | def _extract_workflow_examples(self, examples: list[dict]) -> list[dict]:
method _create_guide (line 914) | def _create_guide(self, title: str, workflows: list[dict], enhancer=No...
method _generate_overview (line 983) | def _generate_overview(self, primary_workflow: dict, _all_workflows: l...
method _enhance_guide_with_ai (line 1001) | def _enhance_guide_with_ai(self, guide: HowToGuide, _ai_analysis: dict...
method _enhance_guide_with_ai_basic (line 1054) | def _enhance_guide_with_ai_basic(self, guide: HowToGuide, ai_analysis:...
method _create_collection (line 1082) | def _create_collection(self, guides: list[HowToGuide]) -> GuideCollect...
method _save_guides_to_files (line 1102) | def _save_guides_to_files(self, collection: GuideCollection, output_di...
function main (line 1136) | def main():
FILE: src/skill_seekers/cli/html_scraper.py
function infer_description_from_html (line 36) | def infer_description_from_html(metadata: dict | None = None, name: str ...
function _collect_html_files (line 61) | def _collect_html_files(html_path: str) -> list[Path]:
class HtmlToSkillConverter (line 98) | class HtmlToSkillConverter:
method __init__ (line 115) | def __init__(self, config: dict) -> None:
method extract_html (line 146) | def extract_html(self) -> bool:
method _extract_metadata (line 281) | def _extract_metadata(self, soup: BeautifulSoup, file_path: Path) -> d...
method _clean_soup (line 347) | def _clean_soup(self, soup: BeautifulSoup) -> None:
method _find_main_content (line 401) | def _find_main_content(self, soup: BeautifulSoup) -> Tag | BeautifulSoup:
method _extract_sections (line 470) | def _extract_sections(
method _build_section (line 538) | def _build_section(
method _extract_code_blocks (line 657) | def _extract_code_blocks(self, elem: Tag) -> list[dict]:
method _detect_language_from_classes (line 715) | def _detect_language_from_classes(self, elem: Tag) -> str:
method _detect_language (line 780) | def _detect_language(self, code: str) -> str:
method _extract_tables (line 835) | def _extract_tables(self, table_elem: Tag) -> dict | None:
method _extract_image_info (line 879) | def _extract_image_info(self, img_elem: Tag, source_file: Path) -> dic...
method _extract_link_info (line 908) | def _extract_link_info(self, a_elem: Tag, source_file: Path) -> dict |...
method _resolve_relative_path (line 937) | def _resolve_relative_path(self, path: str, source_file: Path) -> str:
method _html_to_text (line 967) | def _html_to_text(self, elem: Tag) -> str:
method load_extracted_data (line 1076) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 1092) | def categorize_content(self) -> dict:
method build_skill (line 1197) | def build_skill(self) -> None:
method _generate_reference_file (line 1235) | def _generate_reference_file(
method _generate_index (line 1354) | def _generate_index(self, categorized: dict) -> None:
method _generate_skill_md (line 1414) | def _generate_skill_md(self, categorized: dict) -> None:
method _format_key_concepts (line 1572) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 1618) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 1677) | def _sanitize_filename(self, name: str) -> str:
function _score_code_quality (line 1699) | def _score_code_quality(code: str) -> float:
function main (line 1752) | def main() -> int:
FILE: src/skill_seekers/cli/incremental_updater.py
class DocumentVersion (line 17) | class DocumentVersion:
class ChangeSet (line 28) | class ChangeSet:
method has_changes (line 37) | def has_changes(self) -> bool:
method total_changes (line 42) | def total_changes(self) -> int:
class UpdateMetadata (line 48) | class UpdateMetadata:
class IncrementalUpdater (line 58) | class IncrementalUpdater:
method __init__ (line 66) | def __init__(self, skill_dir: Path, version_file: str = ".skill_versio...
method _compute_file_hash (line 79) | def _compute_file_hash(self, file_path: Path) -> str:
method _scan_documents (line 100) | def _scan_documents(self) -> dict[str, DocumentVersion]:
method load_previous_versions (line 136) | def load_previous_versions(self) -> bool:
method save_current_versions (line 157) | def save_current_versions(self) -> None:
method detect_changes (line 169) | def detect_changes(self) -> ChangeSet:
method generate_update_package (line 219) | def generate_update_package(
method generate_diff_report (line 285) | def generate_diff_report(self, change_set: ChangeSet) -> str:
method apply_update_package (line 359) | def apply_update_package(self, package_path: Path) -> bool:
function main (line 403) | def main():
FILE: src/skill_seekers/cli/install_agent.py
function get_agent_path (line 50) | def get_agent_path(agent_name: str, project_root: Path | None = None) ->...
function get_available_agents (line 86) | def get_available_agents() -> list:
function validate_agent_name (line 96) | def validate_agent_name(agent_name: str) -> tuple[bool, str | None]:
function validate_skill_directory (line 137) | def validate_skill_directory(skill_dir: Path) -> tuple[bool, str | None]:
function install_to_agent (line 165) | def install_to_agent(
function install_to_all_agents (line 311) | def install_to_all_agents(
function main (line 337) | def main() -> int:
FILE: src/skill_seekers/cli/install_skill.py
function main (line 43) | def main():
FILE: src/skill_seekers/cli/jupyter_scraper.py
function _check_jupyter_deps (line 163) | def _check_jupyter_deps():
function infer_description_from_notebook (line 173) | def infer_description_from_notebook(metadata: dict | None = None, name: ...
class JupyterToSkillConverter (line 202) | class JupyterToSkillConverter:
method __init__ (line 205) | def __init__(self, config: dict):
method extract_notebook (line 221) | def extract_notebook(self) -> bool:
method _collect_notebook_files (line 321) | def _collect_notebook_files(self, path: Path) -> list[Path]:
method _parse_single_notebook (line 332) | def _parse_single_notebook(self, nb_path: Path) -> dict:
method _parse_markdown_cell (line 370) | def _parse_markdown_cell(
method _build_markdown_section (line 414) | def _build_markdown_section(
method _parse_code_cell (line 460) | def _parse_code_cell(
method _parse_raw_cell (line 527) | def _parse_raw_cell(
method _infer_code_heading (line 546) | def _infer_code_heading(self, source: str, execution_count: int | None...
method _detect_language (line 570) | def _detect_language(self, metadata: dict) -> str:
method _extract_imports (line 601) | def _extract_imports(self, source: str, language: str) -> list[str]:
method load_extracted_data (line 619) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 628) | def categorize_content(self) -> dict[str, dict]:
method _section_text (line 705) | def _section_text(self, section: dict) -> str:
method _print_categories (line 712) | def _print_categories(self, categorized: dict[str, dict]) -> None:
method build_skill (line 717) | def build_skill(self) -> None:
method _nb_basename (line 738) | def _nb_basename(self) -> str:
method _ref_filename (line 744) | def _ref_filename(self, sections: list[dict], section_num: int, total_...
method _generate_reference_file (line 757) | def _generate_reference_file(
method _generate_index (line 819) | def _generate_index(self, categorized: dict[str, dict]) -> None:
method _generate_skill_md (line 867) | def _generate_skill_md(self, categorized: dict[str, dict]) -> None:
method _format_key_concepts (line 972) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 995) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 1045) | def _sanitize_filename(self, name: str) -> str:
function _score_code_quality (line 1056) | def _score_code_quality(code: str) -> float:
function main (line 1092) | def main() -> int:
FILE: src/skill_seekers/cli/language_detector.py
class LanguageDetector (line 502) | class LanguageDetector:
method __init__ (line 523) | def __init__(self, min_confidence: float = 0.15):
method _compile_patterns (line 535) | def _compile_patterns(self) -> None:
method detect_from_html (line 567) | def detect_from_html(self, elem, code: str) -> tuple[str, float]:
method detect_from_code (line 594) | def detect_from_code(self, code: str) -> tuple[str, float]:
method extract_language_from_classes (line 624) | def extract_language_from_classes(self, classes: list[str]) -> str | N...
method _calculate_confidence (line 670) | def _calculate_confidence(self, code: str) -> dict[str, float]:
FILE: src/skill_seekers/cli/llms_txt_detector.py
class LlmsTxtDetector (line 9) | class LlmsTxtDetector:
method __init__ (line 14) | def __init__(self, base_url: str):
method detect (line 17) | def detect(self) -> dict[str, str] | None:
method detect_all (line 35) | def detect_all(self) -> list[dict[str, str]]:
method _check_url_exists (line 54) | def _check_url_exists(self, url: str) -> bool:
FILE: src/skill_seekers/cli/llms_txt_downloader.py
class LlmsTxtDownloader (line 8) | class LlmsTxtDownloader:
method __init__ (line 11) | def __init__(self, url: str, timeout: int = 30, max_retries: int = 3):
method get_proper_filename (line 16) | def get_proper_filename(self) -> str:
method _is_markdown (line 40) | def _is_markdown(self, content: str) -> bool:
method download (line 63) | def download(self) -> str | None:
FILE: src/skill_seekers/cli/llms_txt_parser.py
class LlmsTxtParser (line 9) | class LlmsTxtParser:
method __init__ (line 12) | def __init__(self, content: str, base_url: str = None):
method extract_urls (line 16) | def extract_urls(self) -> list[str]:
method _clean_url (line 59) | def _clean_url(self, url: str) -> str:
method parse (line 100) | def parse(self) -> list[dict]:
method _parse_section (line 126) | def _parse_section(self, content: str, title: str) -> dict:
FILE: src/skill_seekers/cli/main.py
function create_parser (line 97) | def create_parser() -> argparse.ArgumentParser:
function _reconstruct_argv (line 143) | def _reconstruct_argv(command: str, args: argparse.Namespace) -> list[str]:
function main (line 198) | def main(argv: list[str] | None = None) -> int:
function _handle_analyze_command (line 270) | def _handle_analyze_command(args: argparse.Namespace) -> int:
FILE: src/skill_seekers/cli/man_scraper.py
function infer_description_from_manpages (line 82) | def infer_description_from_manpages(
class ManPageToSkillConverter (line 119) | class ManPageToSkillConverter:
method __init__ (line 128) | def __init__(self, config: dict) -> None:
method extract_manpages (line 163) | def extract_manpages(self) -> bool:
method _extract_from_names (line 240) | def _extract_from_names(self, names: list[str]) -> list[dict]:
method _extract_from_directory (line 267) | def _extract_from_directory(self, dir_path: str) -> list[dict]:
method _section_from_suffix (line 332) | def _section_from_suffix(suffix: str) -> int | None:
method _run_man_command (line 352) | def _run_man_command(self, name: str, section: int | None = None) -> s...
method _read_man_file (line 431) | def _read_man_file(self, filepath: str) -> str | None:
method _strip_troff_formatting (line 473) | def _strip_troff_formatting(text: str) -> str:
method _parse_man_output (line 584) | def _parse_man_output(
method _extract_options (line 654) | def _extract_options(self, options_text: str) -> list[dict]:
method _extract_examples (line 713) | def _extract_examples(self, examples_text: str) -> list[dict]:
method _extract_see_also (line 786) | def _extract_see_also(self, see_also_text: str) -> list[str]:
method load_extracted_data (line 812) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 832) | def categorize_content(self) -> dict[str, dict]:
method build_skill (line 931) | def build_skill(self) -> None:
method _generate_reference_file (line 968) | def _generate_reference_file(
method _generate_index (line 1078) | def _generate_index(self, categorized: dict[str, dict]) -> None:
method _generate_skill_md (line 1121) | def _generate_skill_md(self, categorized: dict[str, dict]) -> None:
method _sanitize_filename (line 1276) | def _sanitize_filename(name: str) -> str:
function main (line 1295) | def main() -> int:
FILE: src/skill_seekers/cli/markdown_cleaner.py
class MarkdownCleaner (line 12) | class MarkdownCleaner:
method remove_html_tags (line 16) | def remove_html_tags(text: str) -> str:
method extract_first_section (line 38) | def extract_first_section(text: str, max_chars: int = 500) -> str:
method _truncate_at_sentence (line 104) | def _truncate_at_sentence(text: str, max_chars: int) -> str:
FILE: src/skill_seekers/cli/merge_sources.py
function categorize_issues_by_topic (line 41) | def categorize_issues_by_topic(
function generate_hybrid_content (line 89) | def generate_hybrid_content(
function _match_issues_to_apis (line 171) | def _match_issues_to_apis(
class RuleBasedMerger (line 215) | class RuleBasedMerger:
method __init__ (line 232) | def __init__(
method merge_all (line 282) | def merge_all(self) -> dict[str, Any]:
method _merge_single_api (line 337) | def _merge_single_api(self, api_name: str) -> dict[str, Any]:
method _create_merged_signature (line 410) | def _create_merged_signature(self, code_info: dict, docs_info: dict) -...
class ClaudeEnhancedMerger (line 443) | class ClaudeEnhancedMerger:
method __init__ (line 457) | def __init__(
method merge_all (line 481) | def merge_all(self) -> dict[str, Any]:
method _create_workspace (line 511) | def _create_workspace(self) -> str:
method _write_context_files (line 526) | def _write_context_files(self, workspace: str):
method _count_by_field (line 620) | def _count_by_field(self, field: str) -> dict[str, int]:
method _launch_claude_merge (line 628) | def _launch_claude_merge(self, workspace: str):
method _read_merged_results (line 698) | def _read_merged_results(self, workspace: str) -> dict[str, Any]:
function merge_sources (line 711) | def merge_sources(
FILE: src/skill_seekers/cli/multilang_support.py
class LanguageInfo (line 16) | class LanguageInfo:
class TranslationStatus (line 26) | class TranslationStatus:
class LanguageDetector (line 36) | class LanguageDetector:
method detect (line 122) | def detect(self, text: str, sample_size: int = 2000) -> LanguageInfo:
method detect_from_filename (line 165) | def detect_from_filename(self, filename: str) -> str | None:
class MultiLanguageManager (line 194) | class MultiLanguageManager:
method __init__ (line 201) | def __init__(self):
method add_document (line 207) | def add_document(
method get_languages (line 268) | def get_languages(self) -> list[str]:
method get_document_count (line 272) | def get_document_count(self, language: str | None = None) -> int:
method get_translation_status (line 286) | def get_translation_status(self, base_language: str | None = None) -> ...
method export_by_language (line 330) | def export_by_language(self, output_dir: Path) -> dict[str, Path]:
method generate_translation_report (line 360) | def generate_translation_report(self) -> str:
function main (line 407) | def main():
FILE: src/skill_seekers/cli/notion_scraper.py
function _check_notion_deps (line 47) | def _check_notion_deps() -> None:
function infer_description_from_notion (line 57) | def infer_description_from_notion(metadata: dict | None = None, name: st...
class NotionToSkillConverter (line 74) | class NotionToSkillConverter:
method __init__ (line 82) | def __init__(self, config: dict) -> None:
method _get_client (line 102) | def _get_client(self) -> Any:
method extract_notion (line 114) | def extract_notion(self) -> bool:
method load_extracted_data (line 152) | def load_extracted_data(self, json_path: str | None = None) -> bool:
method categorize_content (line 166) | def categorize_content(self) -> dict[str, dict[str, Any]]:
method _resolve_category_key (line 186) | def _resolve_category_key(self, properties: dict[str, Any], parent_pat...
method _sanitize_key (line 201) | def _sanitize_key(text: str) -> str:
method build_skill (line 208) | def build_skill(self) -> None:
method _generate_reference_file (line 225) | def _generate_reference_file(
method _generate_index (line 253) | def _generate_index(self, categorized: dict[str, dict[str, Any]]) -> N...
method _generate_skill_md (line 268) | def _generate_skill_md(self, categorized: dict[str, dict[str, Any]]) -...
method _collect_key_topics (line 337) | def _collect_key_topics(self) -> list[str]:
method _collect_code_blocks (line 350) | def _collect_code_blocks(self) -> list[dict[str, str]]:
method _collect_property_summary (line 356) | def _collect_property_summary(self) -> dict[str, set[str]]:
method _extract_via_api (line 372) | def _extract_via_api(self) -> list[dict[str, Any]]:
method _extract_database_entries (line 381) | def _extract_database_entries(self, client: Any) -> list[dict[str, Any]]:
method _process_database_entry (line 422) | def _process_database_entry(self, client: Any, entry: dict[str, Any]) ...
method _extract_properties (line 445) | def _extract_properties(self, raw: dict[str, Any]) -> dict[str, Any]:
method _extract_property_value (line 457) | def _extract_property_value(self, ptype: str, data: dict[str, Any]) ->...
method _extract_page_tree (line 499) | def _extract_page_tree(
method _get_child_pages (line 549) | def _get_child_pages(self, client: Any, page_id: str) -> list[str]:
method _fetch_page_blocks (line 571) | def _fetch_page_blocks(
method _parse_notion_blocks (line 603) | def _parse_notion_blocks(
method _handle_block_type (line 621) | def _handle_block_type(
method _handle_table_block (line 702) | def _handle_table_block(self, block: dict[str, Any]) -> str:
method _extract_rich_text (line 719) | def _extract_rich_text(self, rich_text_list: list[dict[str, Any]]) -> ...
method _extract_from_export (line 748) | def _extract_from_export(self) -> list[dict[str, Any]]:
method _parse_export_markdown (line 782) | def _parse_export_markdown(self, filepath: Path, parent_path: str) -> ...
method _parse_export_csv (line 821) | def _parse_export_csv(self, filepath: Path, parent_path: str) -> list[...
method _clean_notion_export_title (line 856) | def _clean_notion_export_title(stem: str) -> str:
function main (line 867) | def main() -> int:
FILE: src/skill_seekers/cli/openapi_scraper.py
function _check_yaml_deps (line 53) | def _check_yaml_deps():
function infer_description_from_spec (line 63) | def infer_description_from_spec(info: dict | None = None, name: str = ""...
class OpenAPIToSkillConverter (line 93) | class OpenAPIToSkillConverter:
method __init__ (line 114) | def __init__(self, config: dict) -> None:
method extract_spec (line 149) | def extract_spec(self) -> bool:
method _load_from_file (line 215) | def _load_from_file(self, path: str) -> dict[str, Any]:
method _load_from_url (line 242) | def _load_from_url(self, url: str) -> dict[str, Any]:
method _parse_content (line 279) | def _parse_content(self, content: str, source: str) -> dict[str, Any]:
method _detect_version (line 313) | def _detect_version(self, spec: dict[str, Any]) -> str:
method load_extracted_data (line 342) | def load_extracted_data(self, json_path: str | None = None) -> bool:
method _parse_openapi_3 (line 372) | def _parse_openapi_3(self, spec: dict[str, Any]) -> dict[str, Any]:
method _parse_swagger_2 (line 434) | def _parse_swagger_2(self, spec: dict[str, Any]) -> dict[str, Any]:
method _extract_info (line 507) | def _extract_info(self, spec: dict[str, Any]) -> dict[str, Any]:
method _extract_endpoints (line 536) | def _extract_endpoints(self, spec: dict[str, Any], version: int) -> li...
method _normalize_parameter (line 617) | def _normalize_parameter(
method _normalize_request_body_v3 (line 666) | def _normalize_request_body_v3(
method _normalize_response (line 695) | def _normalize_response(
method _extract_schemas (line 747) | def _extract_schemas(
method _flatten_schema (line 769) | def _flatten_schema(
method _extract_security (line 851) | def _extract_security(self, security_dict: dict[str, Any], version: in...
method _resolve_ref (line 896) | def _resolve_ref(self, obj: dict[str, Any], spec: dict[str, Any]) -> d...
method categorize_content (line 943) | def categorize_content(self) -> dict[str, list[dict[str, Any]]]:
method build_skill (line 986) | def build_skill(self) -> None:
method _generate_reference_file (line 1026) | def _generate_reference_file(self, cat_name: str, endpoints: list[dict...
method _generate_schemas_reference (line 1056) | def _generate_schemas_reference(self, schemas: dict[str, Any]) -> None:
method _generate_security_reference (line 1080) | def _generate_security_reference(self, security_schemes: dict[str, Any...
method _generate_index (line 1159) | def _generate_index(self, categories: dict[str, list[dict[str, Any]]])...
method _generate_skill_md (line 1213) | def _generate_skill_md(self, categories: dict[str, list[dict[str, Any]...
method _format_endpoint_md (line 1425) | def _format_endpoint_md(self, endpoint: dict[str, Any]) -> str:
method _format_schema_md (line 1548) | def _format_schema_md(self, schema_name: str, schema: dict[str, Any]) ...
method _render_schema_block (line 1637) | def _render_schema_block(self, schema: dict[str, Any], indent: int = 0...
method _schema_type_string (line 1694) | def _schema_type_string(self, schema: dict[str, Any]) -> str:
method _get_tag_description (line 1746) | def _get_tag_description(self, tag_name: str) -> str:
method _sanitize_filename (line 1760) | def _sanitize_filename(self, name: str) -> str:
function main (line 1782) | def main() -> int:
FILE: src/skill_seekers/cli/package_multi.py
function package_skill (line 14) | def package_skill(skill_dir: Path) -> bool:
function main (line 28) | def main():
FILE: src/skill_seekers/cli/package_skill.py
function package_skill (line 40) | def package_skill(
function main (line 196) | def main():
FILE: src/skill_seekers/cli/parsers/__init__.py
function register_parsers (line 89) | def register_parsers(subparsers):
function get_parser_names (line 102) | def get_parser_names():
FILE: src/skill_seekers/cli/parsers/analyze_parser.py
class AnalyzeParser (line 13) | class AnalyzeParser(SubcommandParser):
method name (line 17) | def name(self) -> str:
method help (line 21) | def help(self) -> str:
method description (line 25) | def description(self) -> str:
method add_arguments (line 28) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/asciidoc_parser.py
class AsciiDocParser (line 11) | class AsciiDocParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/base.py
class SubcommandParser (line 7) | class SubcommandParser(ABC):
method name (line 19) | def name(self) -> str:
method help (line 25) | def help(self) -> str:
method description (line 30) | def description(self) -> str:
method add_arguments (line 35) | def add_arguments(self, parser: argparse.ArgumentParser) -> None:
method create_parser (line 43) | def create_parser(self, subparsers) -> argparse.ArgumentParser:
FILE: src/skill_seekers/cli/parsers/chat_parser.py
class ChatParser (line 11) | class ChatParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/config_parser.py
class ConfigParser (line 6) | class ConfigParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/confluence_parser.py
class ConfluenceParser (line 11) | class ConfluenceParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/create_parser.py
class CreateParser (line 17) | class CreateParser(SubcommandParser):
method name (line 21) | def name(self) -> str:
method help (line 25) | def help(self) -> str:
method description (line 29) | def description(self) -> str:
method add_arguments (line 48) | def add_arguments(self, parser):
method register (line 105) | def register(self, subparsers):
FILE: src/skill_seekers/cli/parsers/enhance_parser.py
class EnhanceParser (line 11) | class EnhanceParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 30) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/enhance_status_parser.py
class EnhanceStatusParser (line 6) | class EnhanceStatusParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/epub_parser.py
class EpubParser (line 11) | class EpubParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/estimate_parser.py
class EstimateParser (line 6) | class EstimateParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/extractors/base_parser.py
class ParseResult (line 21) | class ParseResult:
method is_ok (line 30) | def is_ok(self) -> bool:
class BaseParser (line 35) | class BaseParser(ABC):
method __init__ (line 46) | def __init__(self, options: dict[str, Any] | None = None):
method format_name (line 68) | def format_name(self) -> str:
method supported_extensions (line 74) | def supported_extensions(self) -> list[str]:
method can_parse (line 78) | def can_parse(self, source: str | Path) -> bool:
method parse (line 100) | def parse(self, source: str | Path) -> ParseResult:
method parse_file (line 147) | def parse_file(self, path: str | Path) -> ParseResult:
method parse_string (line 151) | def parse_string(self, content: str, source_path: str = "<string>") ->...
method _parse_content (line 176) | def _parse_content(self, content: str, source_path: str) -> Document:
method _detect_format (line 190) | def _detect_format(self, content: str) -> bool:
method _read_source (line 202) | def _read_source(self, source: str | Path) -> str:
method _read_source_with_path (line 207) | def _read_source_with_path(self, source: str | Path) -> tuple[str, str]:
method _post_process (line 223) | def _post_process(self, document: Document) -> Document:
method _extract_headings (line 252) | def _extract_headings(self, document: Document) -> list:
method _extract_code_blocks (line 264) | def _extract_code_blocks(self, document: Document) -> list:
method _extract_tables (line 272) | def _extract_tables(self, document: Document) -> list:
method _create_quality_scorer (line 280) | def _create_quality_scorer(self):
function get_parser_for_file (line 289) | def get_parser_for_file(path: str | Path) -> BaseParser | None:
function parse_document (line 321) | def parse_document(source: str | Path, format_hint: str | None = None) -...
FILE: src/skill_seekers/cli/parsers/extractors/formatters.py
class MarkdownFormatter (line 19) | class MarkdownFormatter:
method __init__ (line 22) | def __init__(self, options: dict[str, Any] = None):
method format (line 29) | def format(self, document: Document) -> str:
method _format_metadata (line 53) | def _format_metadata(self, meta: dict) -> str:
method _format_toc (line 66) | def _format_toc(self, headings: list) -> str:
method _format_block (line 77) | def _format_block(self, block: ContentBlock) -> str:
method _format_heading (line 101) | def _format_heading(self, block: ContentBlock) -> str:
method _format_paragraph (line 116) | def _format_paragraph(self, block: ContentBlock) -> str:
method _format_code_block (line 120) | def _format_code_block(self, block: ContentBlock) -> str:
method _format_table (line 138) | def _format_table(self, block: ContentBlock) -> str:
method _format_table_data (line 146) | def _format_table_data(self, table: Table) -> str:
method _format_list (line 172) | def _format_list(self, block: ContentBlock) -> str:
method _format_image (line 188) | def _format_image(self, block: ContentBlock) -> str:
method _format_cross_ref (line 200) | def _format_cross_ref(self, block: ContentBlock) -> str:
method _format_admonition (line 210) | def _format_admonition(self, block: ContentBlock) -> str:
method _format_directive (line 228) | def _format_directive(self, block: ContentBlock) -> str:
method _format_field_list (line 240) | def _format_field_list(self, block: ContentBlock) -> str:
method _format_definition_list (line 255) | def _format_definition_list(self, block: ContentBlock) -> str:
method _format_meta (line 271) | def _format_meta(self, block: ContentBlock) -> str:
class SkillFormatter (line 276) | class SkillFormatter:
method format (line 279) | def format(self, document: Document) -> dict[str, Any]:
method _extract_summary (line 326) | def _extract_summary(self, document: Document, max_length: int = 500) ...
method _score_table (line 341) | def _score_table(self, table: Table) -> float:
FILE: src/skill_seekers/cli/parsers/extractors/markdown_parser.py
class MarkdownParser (line 39) | class MarkdownParser(BaseParser):
method __init__ (line 58) | def __init__(self, options: dict[str, Any] | None = None):
method format_name (line 65) | def format_name(self) -> str:
method supported_extensions (line 69) | def supported_extensions(self) -> list[str]:
method _detect_format (line 72) | def _detect_format(self, content: str) -> bool:
method _parse_content (line 84) | def _parse_content(self, content: str, source_path: str) -> Document:
method _parse_frontmatter (line 123) | def _parse_frontmatter(self) -> dict | None:
method _parse_block (line 196) | def _parse_block(self) -> ContentBlock | None:
method _is_setext_header (line 249) | def _is_setext_header(self, line: int) -> bool:
method _parse_atx_header (line 263) | def _parse_atx_header(self) -> ContentBlock:
method _parse_setext_header (line 292) | def _parse_setext_header(self) -> ContentBlock:
method _parse_code_fence (line 317) | def _parse_code_fence(self) -> ContentBlock:
method _parse_indented_code (line 365) | def _parse_indented_code(self) -> ContentBlock:
method _is_table (line 412) | def _is_table(self, line: int) -> bool:
method _parse_table (line 423) | def _parse_table(self) -> ContentBlock:
method _parse_blockquote (line 472) | def _parse_blockquote(self) -> ContentBlock:
method _parse_html_comment (line 523) | def _parse_html_comment(self) -> ContentBlock | None:
method _parse_horizontal_rule (line 539) | def _parse_horizontal_rule(self) -> ContentBlock:
method _detect_list_type (line 548) | def _detect_list_type(self, stripped: str) -> ListType | None:
method _parse_list (line 556) | def _parse_list(self, list_type: ListType) -> ContentBlock:
method _parse_paragraph (line 595) | def _parse_paragraph(self) -> ContentBlock:
method _process_inline (line 638) | def _process_inline(self, text: str) -> str:
method _create_anchor (line 662) | def _create_anchor(self, text: str) -> str:
method _extract_specialized_content (line 670) | def _extract_specialized_content(self, document: Document):
FILE: src/skill_seekers/cli/parsers/extractors/pdf_parser.py
class PdfParser (line 33) | class PdfParser(BaseParser):
method __init__ (line 42) | def __init__(self, options: dict[str, Any] | None = None):
method format_name (line 60) | def format_name(self) -> str:
method supported_extensions (line 64) | def supported_extensions(self) -> list[str]:
method _detect_format (line 67) | def _detect_format(self, content: str) -> bool:
method _parse_content (line 71) | def _parse_content(self, content: str, source_path: str) -> Document:
method parse_file (line 81) | def parse_file(self, path: str | Path) -> ParseResult:
method _convert_to_document (line 138) | def _convert_to_document(self, extraction_result: dict, source_path: s...
method parse (line 266) | def parse(self, source: str | Path) -> ParseResult:
FILE: src/skill_seekers/cli/parsers/extractors/quality_scorer.py
class QualityScorer (line 15) | class QualityScorer:
method score_code_block (line 151) | def score_code_block(self, code: str, language: str | None = None) -> ...
method _validate_syntax (line 234) | def _validate_syntax(self, code: str, language: str | None) -> tuple[b...
method score_table (line 274) | def score_table(self, table: Table) -> float:
method score_content_block (line 326) | def score_content_block(self, block: ContentBlock) -> float:
method detect_language (line 348) | def detect_language(self, code: str) -> tuple[str, float]:
FILE: src/skill_seekers/cli/parsers/extractors/rst_parser.py
class RstParser (line 41) | class RstParser(BaseParser):
method __init__ (line 116) | def __init__(self, options: dict[str, Any] | None = None):
method format_name (line 124) | def format_name(self) -> str:
method supported_extensions (line 128) | def supported_extensions(self) -> list[str]:
method _detect_format (line 131) | def _detect_format(self, content: str) -> bool:
method _parse_content (line 141) | def _parse_content(self, content: str, source_path: str) -> Document:
method _collect_substitutions (line 180) | def _collect_substitutions(self):
method _parse_block (line 190) | def _parse_block(self) -> ContentBlock | None:
method _is_header (line 240) | def _is_header(self, line: int) -> bool:
method _parse_header (line 262) | def _parse_header(self) -> ContentBlock:
method _parse_directive (line 291) | def _parse_directive(self) -> ContentBlock:
method _parse_admonition_directive (line 362) | def _parse_admonition_directive(
method _parse_code_block_directive (line 382) | def _parse_code_block_directive(self, language: str, content: str, lin...
method _parse_table_directive (line 413) | def _parse_table_directive(self, caption: str, content: str, line: int...
method _parse_simple_table (line 433) | def _parse_simple_table(self, content: str, caption: str | None, line:...
method _parse_grid_table (line 546) | def _parse_grid_table(self, content: str, caption: str | None, line: i...
method _parse_list_table_directive (line 586) | def _parse_list_table_directive(self, caption: str, content: str, line...
method _parse_toctree_directive (line 642) | def _parse_toctree_directive(self, content: str, line: int) -> Content...
method _parse_image_directive (line 661) | def _parse_image_directive(self, argument: str, content: str, line: in...
method _is_definition_list (line 693) | def _is_definition_list(self, line: int) -> bool:
method _parse_definition_list (line 706) | def _parse_definition_list(self) -> ContentBlock:
method _is_field_list (line 767) | def _is_field_list(self, line: int) -> bool:
method _parse_field_list (line 774) | def _parse_field_list(self) -> ContentBlock:
method _parse_bullet_list (line 840) | def _parse_bullet_list(self) -> ContentBlock:
method _parse_numbered_list (line 871) | def _parse_numbered_list(self) -> ContentBlock:
method _parse_paragraph (line 902) | def _parse_paragraph(self) -> ContentBlock:
method _process_inline_markup (line 945) | def _process_inline_markup(self, text: str) -> str:
method _extract_specialized_content (line 969) | def _extract_specialized_content(self, document: Document):
method _extract_xrefs_from_text (line 1031) | def _extract_xrefs_from_text(self, text: str, source_line: int | None)...
FILE: src/skill_seekers/cli/parsers/extractors/unified_structure.py
class ContentBlockType (line 14) | class ContentBlockType(Enum):
class CrossRefType (line 35) | class CrossRefType(Enum):
class AdmonitionType (line 53) | class AdmonitionType(Enum):
class ListType (line 70) | class ListType(Enum):
class Heading (line 79) | class Heading:
class CodeBlock (line 89) | class CodeBlock:
class Table (line 103) | class Table:
method num_rows (line 115) | def num_rows(self) -> int:
method num_cols (line 119) | def num_cols(self) -> int:
class CrossReference (line 126) | class CrossReference:
class Field (line 137) | class Field:
class DefinitionItem (line 147) | class DefinitionItem:
class Image (line 157) | class Image:
class ContentBlock (line 169) | class ContentBlock:
class ExtractionStats (line 189) | class ExtractionStats:
class Document (line 203) | class Document:
method to_markdown (line 243) | def to_markdown(self, options: dict | None = None) -> str:
method to_skill_format (line 262) | def to_skill_format(self) -> dict[str, Any]:
method _extract_content_text (line 308) | def _extract_content_text(self) -> str:
method get_section_content (line 316) | def get_section_content(self, heading_text: str) -> list[ContentBlock]:
method find_blocks_by_type (line 346) | def find_blocks_by_type(self, block_type: ContentBlockType) -> list[Co...
method find_code_by_language (line 350) | def find_code_by_language(self, language: str) -> list[CodeBlock]:
method find_tables_by_caption (line 354) | def find_tables_by_caption(self, pattern: str) -> list[Table]:
method get_api_summary (line 360) | def get_api_summary(self) -> dict[str, Any]:
method _parse_api_table (line 388) | def _parse_api_table(self, table: Table | None) -> list[dict]:
function merge_documents (line 407) | def merge_documents(docs: list[Document]) -> Document:
FILE: src/skill_seekers/cli/parsers/github_parser.py
class GitHubParser (line 11) | class GitHubParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/html_parser.py
class HtmlParser (line 11) | class HtmlParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/install_agent_parser.py
class InstallAgentParser (line 6) | class InstallAgentParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/install_parser.py
class InstallParser (line 6) | class InstallParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/jupyter_parser.py
class JupyterParser (line 11) | class JupyterParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/manpage_parser.py
class ManPageParser (line 11) | class ManPageParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/multilang_parser.py
class MultilangParser (line 6) | class MultilangParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/notion_parser.py
class NotionParser (line 11) | class NotionParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/openapi_parser.py
class OpenAPIParser (line 11) | class OpenAPIParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/package_parser.py
class PackageParser (line 11) | class PackageParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/pdf_parser.py
class PDFParser (line 11) | class PDFParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/pptx_parser.py
class PptxParser (line 11) | class PptxParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/quality_parser.py
class QualityParser (line 6) | class QualityParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/resume_parser.py
class ResumeParser (line 6) | class ResumeParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/rss_parser.py
class RssParser (line 11) | class RssParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/scrape_parser.py
class ScrapeParser (line 11) | class ScrapeParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/stream_parser.py
class StreamParser (line 6) | class StreamParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/sync_config_parser.py
class SyncConfigParser (line 8) | class SyncConfigParser(SubcommandParser):
method name (line 12) | def name(self) -> str:
method help (line 16) | def help(self) -> str:
method description (line 20) | def description(self) -> str:
method add_arguments (line 27) | def add_arguments(self, parser: argparse.ArgumentParser) -> None:
FILE: src/skill_seekers/cli/parsers/test_examples_parser.py
class TestExamplesParser (line 6) | class TestExamplesParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/unified_parser.py
class UnifiedParser (line 11) | class UnifiedParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/update_parser.py
class UpdateParser (line 6) | class UpdateParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 21) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/upload_parser.py
class UploadParser (line 11) | class UploadParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/video_parser.py
class VideoParser (line 11) | class VideoParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/word_parser.py
class WordParser (line 11) | class WordParser(SubcommandParser):
method name (line 15) | def name(self) -> str:
method help (line 19) | def help(self) -> str:
method description (line 23) | def description(self) -> str:
method add_arguments (line 26) | def add_arguments(self, parser):
FILE: src/skill_seekers/cli/parsers/workflows_parser.py
class WorkflowsParser (line 6) | class WorkflowsParser(SubcommandParser):
method name (line 10) | def name(self) -> str:
method help (line 14) | def help(self) -> str:
method description (line 18) | def description(self) -> str:
method add_arguments (line 25) | def add_arguments(self, parser) -> None:
FILE: src/skill_seekers/cli/pattern_recognizer.py
class PatternInstance (line 44) | class PatternInstance:
method to_dict (line 58) | def to_dict(self) -> dict:
class PatternReport (line 77) | class PatternReport:
method to_dict (line 87) | def to_dict(self) -> dict:
method get_summary (line 99) | def get_summary(self) -> dict[str, int]:
class BasePatternDetector (line 107) | class BasePatternDetector:
method __init__ (line 110) | def __init__(self, depth: str = "deep"):
method detect_surface (line 121) | def detect_surface(self, _class_sig, _all_classes: list) -> PatternIns...
method detect_deep (line 135) | def detect_deep(self, _class_sig, _all_classes: list) -> PatternInstan...
method detect_full (line 149) | def detect_full(
method detect (line 166) | def detect(
class PatternRecognizer (line 202) | class PatternRecognizer:
method __init__ (line 209) | def __init__(self, depth: str = "deep", enhance_with_ai: bool = True):
method _register_detectors (line 233) | def _register_detectors(self):
method analyze_file (line 251) | def analyze_file(self, file_path: str, content: str, language: str) ->...
method _convert_to_signatures (line 328) | def _convert_to_signatures(self, classes: list[dict]):
class SingletonDetector (line 377) | class SingletonDetector(BasePatternDetector):
method __init__ (line 394) | def __init__(self, depth: str = "deep"):
method detect_surface (line 399) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 413) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
method detect_full (line 467) | def detect_full(
class FactoryDetector (line 510) | class FactoryDetector(BasePatternDetector):
method __init__ (line 527) | def __init__(self, depth: str = "deep"):
method detect_surface (line 532) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 567) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class ObserverDetector (line 617) | class ObserverDetector(BasePatternDetector):
method __init__ (line 635) | def __init__(self, depth: str = "deep"):
method detect_surface (line 640) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 689) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class StrategyDetector (line 746) | class StrategyDetector(BasePatternDetector):
method __init__ (line 764) | def __init__(self, depth: str = "deep"):
method detect_surface (line 769) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 787) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class DecoratorDetector (line 849) | class DecoratorDetector(BasePatternDetector):
method __init__ (line 867) | def __init__(self, depth: str = "deep"):
method detect_surface (line 872) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 906) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class BuilderDetector (line 960) | class BuilderDetector(BasePatternDetector):
method __init__ (line 978) | def __init__(self, depth: str = "deep"):
method detect_surface (line 983) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 998) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
method detect_full (line 1051) | def detect_full(
class AdapterDetector (line 1091) | class AdapterDetector(BasePatternDetector):
method __init__ (line 1109) | def __init__(self, depth: str = "deep"):
method detect_surface (line 1114) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 1132) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class CommandDetector (line 1176) | class CommandDetector(BasePatternDetector):
method __init__ (line 1194) | def __init__(self, depth: str = "deep"):
method detect_surface (line 1199) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 1217) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class TemplateMethodDetector (line 1267) | class TemplateMethodDetector(BasePatternDetector):
method __init__ (line 1285) | def __init__(self, depth: str = "deep"):
method detect_surface (line 1290) | def detect_surface(self, class_sig, all_classes: list) -> PatternInsta...
method detect_deep (line 1313) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class ChainOfResponsibilityDetector (line 1383) | class ChainOfResponsibilityDetector(BasePatternDetector):
method __init__ (line 1401) | def __init__(self, depth: str = "deep"):
method detect_surface (line 1406) | def detect_surface(self, class_sig, _all_classes: list) -> PatternInst...
method detect_deep (line 1424) | def detect_deep(self, class_sig, all_classes: list) -> PatternInstance...
class LanguageAdapter (line 1499) | class LanguageAdapter:
method adapt_for_language (line 1508) | def adapt_for_language(pattern: PatternInstance, language: str) -> Pat...
function filter_patterns_by_confidence (line 1655) | def filter_patterns_by_confidence(patterns: list[dict], min_confidence: ...
function create_multi_level_report (line 1673) | def create_multi_level_report(pattern_results: list[dict]) -> dict:
function main (line 1722) | def main():
FILE: src/skill_seekers/cli/pdf_extractor_poc.py
class PDFExtractor (line 86) | class PDFExtractor:
method __init__ (line 89) | def __init__(
method log (line 130) | def log(self, message):
method extract_text_with_ocr (line 135) | def extract_text_with_ocr(self, page):
method extract_tables_from_page (line 172) | def extract_tables_from_page(self, page):
method get_cached (line 208) | def get_cached(self, key):
method set_cached (line 222) | def set_cached(self, key, value):
method detect_language_from_code (line 233) | def detect_language_from_code(self, code):
method validate_code_syntax (line 244) | def validate_code_syntax(self, code, language):
method score_code_quality (line 308) | def score_code_quality(self, code, language, confidence):
method detect_code_blocks_by_font (line 355) | def detect_code_blocks_by_font(self, page):
method detect_code_blocks_by_indent (line 433) | def detect_code_blocks_by_indent(self, text):
method detect_code_blocks_by_pattern (line 497) | def detect_code_blocks_by_pattern(self, text):
method detect_chapter_start (line 545) | def detect_chapter_start(self, page_data):
method merge_continued_code_blocks (line 577) | def merge_continued_code_blocks(self, pages):
method create_chunks (line 629) | def create_chunks(self, pages):
method extract_images_from_page (line 709) | def extract_images_from_page(self, page, page_num):
method extract_page (line 773) | def extract_page(self, page_num):
method extract_all (line 880) | def extract_all(self):
function main (line 1057) | def main():
FILE: src/skill_seekers/cli/pdf_scraper.py
function infer_description_from_pdf (line 26) | def infer_description_from_pdf(pdf_metadata: dict = None, name: str = ""...
class PDFToSkillConverter (line 65) | class PDFToSkillConverter:
method __init__ (line 68) | def __init__(self, config):
method extract_pdf (line 90) | def extract_pdf(self):
method load_extracted_data (line 120) | def load_extracted_data(self, json_path):
method categorize_content (line 130) | def categorize_content(self):
method build_skill (line 242) | def build_skill(self):
method _generate_reference_file (line 271) | def _generate_reference_file(self, _cat_key, cat_data, section_num, to...
method _generate_index (line 348) | def _generate_index(self, categorized):
method _generate_skill_md (line 400) | def _generate_skill_md(self, categorized):
method _format_key_concepts (line 530) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 566) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 628) | def _sanitize_filename(self, name):
function main (line 636) | def main():
FILE: src/skill_seekers/cli/pptx_scraper.py
function _check_pptx_deps (line 95) | def _check_pptx_deps() -> None:
function infer_description_from_pptx (line 105) | def infer_description_from_pptx(
class PptxToSkillConverter (line 150) | class PptxToSkillConverter:
method __init__ (line 168) | def __init__(self, config: dict) -> None:
method extract_pptx (line 199) | def extract_pptx(self) -> bool:
method _extract_presentation_metadata (line 327) | def _extract_presentation_metadata(self, prs) -> dict:
method _extract_slide (line 357) | def _extract_slide(self, slide, slide_number: int) -> dict:
method _extract_group_shapes (line 446) | def _extract_group_shapes(self, group_shape) -> tuple[list[str], list[...
method _process_text_frame (line 492) | def _process_text_frame(self, text_frame) -> tuple[str, list[dict]]:
method _finalize_code_block (line 539) | def _finalize_code_block(self, code_parts: list[str]) -> dict:
method _extract_tables (line 556) | def _extract_tables(self, table) -> dict | None:
method _extract_images_info (line 590) | def _extract_images_info(self, slide) -> list[dict]:
method _detect_code_blocks (line 637) | def _detect_code_blocks(self, paragraph) -> bool:
method _text_looks_like_code (line 692) | def _text_looks_like_code(self, text: str) -> bool:
method _extract_speaker_notes (line 735) | def _extract_speaker_notes(self, slide) -> str:
method _is_image_shape (line 761) | def _is_image_shape(self, shape) -> bool:
method _group_slides_into_sections (line 789) | def _group_slides_into_sections(self, slides: list[dict]) -> list[dict]:
method _build_section_from_slides (line 869) | def _build_section_from_slides(
method _detect_languages (line 958) | def _detect_languages(
method load_extracted_data (line 1007) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 1023) | def categorize_content(self) -> dict[str, dict]:
method build_skill (line 1104) | def build_skill(self) -> None:
method _generate_reference_file (line 1145) | def _generate_reference_file(
method _generate_index (line 1249) | def _generate_index(self, categorized: dict[str, dict]) -> None:
method _generate_skill_md (line 1308) | def _generate_skill_md(self, categorized: dict[str, dict]) -> None:
method _format_key_concepts (line 1477) | def _format_key_concepts(self) -> str:
method _format_patterns_from_content (line 1529) | def _format_patterns_from_content(self) -> str:
method _sanitize_filename (line 1595) | def _sanitize_filename(self, name: str) -> str:
function _score_code_quality (line 1617) | def _score_code_quality(code: str) -> float:
function main (line 1671) | def main() -> int:
FILE: src/skill_seekers/cli/presets/analyze_presets.py
class AnalysisPreset (line 20) | class AnalysisPreset:
function apply_analyze_preset (line 88) | def apply_analyze_preset(args: argparse.Namespace, preset_name: str) -> ...
function get_preset_help_text (line 119) | def get_preset_help_text(preset_name: str) -> str:
function show_preset_list (line 136) | def show_preset_list() -> None:
function resolve_enhance_level (line 169) | def resolve_enhance_level(args: argparse.Namespace) -> int:
function apply_preset_with_warnings (line 195) | def apply_preset_with_warnings(args: argparse.Namespace) -> str:
function print_deprecation_warning (line 250) | def print_deprecation_warning(old_flag: str, new_flag: str) -> None:
FILE: src/skill_seekers/cli/presets/github_presets.py
class GitHubPreset (line 17) | class GitHubPreset:
function apply_github_preset (line 73) | def apply_github_preset(args: argparse.Namespace, preset_name: str) -> N...
function show_github_preset_list (line 96) | def show_github_preset_list() -> None:
FILE: src/skill_seekers/cli/presets/manager.py
class AnalysisPreset (line 11) | class AnalysisPreset:
class PresetManager (line 83) | class PresetManager:
method get_preset (line 87) | def get_preset(name: str) -> AnalysisPreset | None:
method list_presets (line 99) | def list_presets() -> list[str]:
method format_preset_help (line 108) | def format_preset_help() -> str:
method apply_preset (line 124) | def apply_preset(preset_name: str, args: dict) -> dict:
method get_default_preset (line 162) | def get_default_preset() -> str:
FILE: src/skill_seekers/cli/presets/scrape_presets.py
class ScrapePreset (line 17) | class ScrapePreset:
function apply_scrape_preset (line 80) | def apply_scrape_preset(args: argparse.Namespace, preset_name: str) -> N...
function show_scrape_preset_list (line 111) | def show_scrape_preset_list() -> None:
FILE: src/skill_seekers/cli/quality_checker.py
class QualityIssue (line 18) | class QualityIssue:
class QualityReport (line 29) | class QualityReport:
method add_error (line 38) | def add_error(self, category: str, message: str, file: str = None, lin...
method add_warning (line 42) | def add_warning(self, category: str, message: str, file: str = None, l...
method add_info (line 46) | def add_info(self, category: str, message: str, file: str = None, line...
method has_errors (line 51) | def has_errors(self) -> bool:
method has_warnings (line 56) | def has_warnings(self) -> bool:
method is_excellent (line 61) | def is_excellent(self) -> bool:
method quality_score (line 66) | def quality_score(self) -> float:
method quality_grade (line 79) | def quality_grade(self) -> str:
class SkillQualityChecker (line 94) | class SkillQualityChecker:
method __init__ (line 97) | def __init__(self, skill_dir: Path):
method check_all (line 108) | def check_all(self) -> QualityReport:
method _check_skill_structure (line 131) | def _check_skill_structure(self):
method _check_enhancement_quality (line 152) | def _check_enhancement_quality(self):
method _check_content_quality (line 209) | def _check_content_quality(self):
method _check_links (line 286) | def _check_links(self):
method _check_skill_completeness (line 324) | def _check_skill_completeness(self):
function print_report (line 405) | def print_report(report: QualityReport, verbose: bool = False):
function main (line 468) | def main():
FILE: src/skill_seekers/cli/quality_metrics.py
class MetricLevel (line 17) | class MetricLevel(Enum):
class QualityMetric (line 27) | class QualityMetric:
class QualityScore (line 38) | class QualityScore:
class QualityReport (line 50) | class QualityReport:
class QualityAnalyzer (line 62) | class QualityAnalyzer:
method __init__ (line 84) | def __init__(self, skill_dir: Path):
method analyze_completeness (line 90) | def analyze_completeness(self) -> float:
method analyze_accuracy (line 160) | def analyze_accuracy(self) -> float:
method analyze_coverage (line 223) | def analyze_coverage(self) -> float:
method analyze_health (line 288) | def analyze_health(self) -> float:
method calculate_statistics (line 340) | def calculate_statistics(self) -> dict[str, Any]:
method calculate_overall_score (line 374) | def calculate_overall_score(
method generate_recommendations (line 404) | def generate_recommendations(self, score: QualityScore) -> list[str]:
method generate_report (line 430) | def generate_report(self) -> QualityReport:
method format_report (line 461) | def format_report(self, report: QualityReport) -> str:
function main (line 526) | def main():
FILE: src/skill_seekers/cli/rag_chunker.py
class RAGChunker (line 27) | class RAGChunker:
method __init__ (line 38) | def __init__(
method estimate_tokens (line 65) | def estimate_tokens(self, text: str) -> int:
method chunk_document (line 79) | def chunk_document(
method chunk_skill (line 142) | def chunk_skill(self, skill_dir: Path) -> list[dict]:
method _extract_code_blocks (line 187) | def _extract_code_blocks(self, text: str) -> tuple[str, list[dict]]:
method _reinsert_code_blocks (line 220) | def _reinsert_code_blocks(self, chunks: list[str], code_blocks: list[d...
method _find_semantic_boundaries (line 242) | def _find_semantic_boundaries(self, text: str) -> list[int]:
method _split_with_overlap (line 290) | def _split_with_overlap(self, text: str, boundaries: list[int]) -> lis...
method save_chunks (line 363) | def save_chunks(self, chunks: list[dict], output_path: Path) -> None:
function main (line 379) | def main():
FILE: src/skill_seekers/cli/rate_limit_handler.py
class RateLimitError (line 22) | class RateLimitError(Exception):
class RateLimitHandler (line 28) | class RateLimitHandler:
method __init__ (line 47) | def __init__(
method check_upfront (line 81) | def check_upfront(self) -> bool:
method check_response (line 135) | def check_response(self, response: requests.Response) -> bool:
method extract_rate_limit_info (line 164) | def extract_rate_limit_info(self, response: requests.Response) -> dict...
method get_rate_limit_info (line 189) | def get_rate_limit_info(self) -> dict[str, Any]:
method handle_rate_limit (line 217) | def handle_rate_limit(self, rate_info: dict[str, Any]) -> bool:
method try_switch_profile (line 275) | def try_switch_profile(self) -> bool:
method wait_for_reset (line 317) | def wait_for_reset(self, wait_seconds: float, wait_minutes: int) -> bool:
method show_countdown_timer (line 353) | def show_countdown_timer(self, total_seconds: float):
method prompt_user_action (line 375) | def prompt_user_action(self, wait_seconds: float, wait_minutes: int) -...
function create_github_headers (line 425) | def create_github_headers(token: str | None = None) -> dict[str, str]:
FILE: src/skill_seekers/cli/resume_command.py
function list_resumable_jobs (line 13) | def list_resumable_jobs():
function resume_job (line 56) | def resume_job(job_id: str):
function clean_old_jobs (line 110) | def clean_old_jobs():
function main (line 133) | def main():
FILE: src/skill_seekers/cli/rss_scraper.py
function _check_feedparser_deps (line 70) | def _check_feedparser_deps() -> None:
function infer_description_from_feed (line 80) | def infer_description_from_feed(
class RssToSkillConverter (line 112) | class RssToSkillConverter:
method __init__ (line 120) | def __init__(self, config: dict[str, Any]) -> None:
method extract_feed (line 149) | def extract_feed(self) -> bool:
method load_extracted_data (line 230) | def load_extracted_data(self, json_path: str) -> bool:
method categorize_content (line 245) | def categorize_content(self) -> dict[str, dict[str, Any]]:
method build_skill (line 288) | def build_skill(self) -> None:
method _parse_feed (line 321) | def _parse_feed(self) -> "feedparser.FeedParserDict":
method _detect_feed_type (line 348) | def _detect_feed_type(self, parsed: "feedparser.FeedParserDict") -> str:
method _extract_feed_metadata (line 371) | def _extract_feed_metadata(self, parsed: "feedparser.FeedParserDict") ...
method _extract_articles (line 401) | def _extract_articles(self, parsed: "feedparser.FeedParserDict") -> li...
method _scrape_article_content (line 466) | def _scrape_article_content(self, url: str) -> str:
method _extract_article_text (line 496) | def _extract_article_text(self, html: str) -> str:
method _collect_all_categories (line 569) | def _collect_all_categories(self, articles: list[dict[str, Any]]) -> s...
method _html_to_text (line 578) | def _html_to_text(self, html_fragment: str) -> str:
method _generate_reference_file (line 592) | def _generate_reference_file(self, cat_key: str, cat_data: dict[str, A...
method _generate_index (line 640) | def _generate_index(self, categorized: dict[str, dict[str, Any]]) -> N...
method _generate_skill_md (line 688) | def _generate_skill_md(self, categorized: dict[str, dict[str, Any]]) -...
method _count_authors (line 838) | def _count_authors(self) -> dict[str, int]:
method _get_date_range (line 849) | def _get_date_range(self) -> tuple[str, str] | None:
method _sanitize_filename (line 863) | def _sanitize_filename(self, name: str) -> str:
function main (line 875) | def main() -> int:
FILE: src/skill_seekers/cli/run_tests.py
class ColoredTextTestResult (line 11) | class ColoredTextTestResult(unittest.TextTestResult):
method __init__ (line 22) | def __init__(self, *args, **kwargs):
method addSuccess (line 26) | def addSuccess(self, test):
method addError (line 35) | def addError(self, test, err):
method addFailure (line 44) | def addFailure(self, test, err):
method addSkip (line 53) | def addSkip(self, test, reason):
class ColoredTextTestRunner (line 63) | class ColoredTextTestRunner(unittest.TextTestRunner):
function discover_tests (line 69) | def discover_tests(test_dir="tests"):
function run_specific_suite (line 79) | def run_specific_suite(suite_name):
function print_summary (line 103) | def print_summary(result):
function main (line 164) | def main():
FILE: src/skill_seekers/cli/setup_wizard.py
function show_installation_guide (line 10) | def show_installation_guide():
function check_first_run (line 70) | def check_first_run():
function main (line 87) | def main():
FILE: src/skill_seekers/cli/signal_flow_analyzer.py
class SignalFlowAnalyzer (line 14) | class SignalFlowAnalyzer:
method __init__ (line 17) | def __init__(self, analysis_results: dict[str, Any]):
method analyze (line 30) | def analyze(self) -> dict[str, Any]:
method _extract_signals (line 52) | def _extract_signals(self):
method _extract_connections (line 70) | def _extract_connections(self):
method _extract_emissions (line 88) | def _extract_emissions(self):
method _build_flow_chains (line 106) | def _build_flow_chains(self):
method _detect_patterns (line 124) | def _detect_patterns(self):
method _calculate_statistics (line 168) | def _calculate_statistics(self) -> dict[str, Any]:
method generate_signal_flow_diagram (line 202) | def generate_signal_flow_diagram(self) -> str:
method extract_signal_usage_patterns (line 229) | def extract_signal_usage_patterns(self) -> list[dict[str, Any]]:
method generate_how_to_guides (line 265) | def generate_how_to_guides(self, output_dir: Path, ai_mode: str = "LOC...
method _generate_signal_guide (line 306) | def _generate_signal_guide(self, pattern: dict[str, Any], ai_mode: str...
method save_analysis (line 396) | def save_analysis(self, output_dir: Path, ai_mode: str = "LOCAL"):
method _generate_signal_reference (line 436) | def _generate_signal_reference(self, output_dir: Path, analysis: dict):
FILE: src/skill_seekers/cli/source_detector.py
class SourceInfo (line 23) | class SourceInfo:
class SourceDetector (line 39) | class SourceDetector:
method detect (line 49) | def detect(cls, source: str) -> SourceInfo:
method _detect_config (line 162) | def _detect_config(cls, source: str) -> SourceInfo:
method _detect_pdf (line 170) | def _detect_pdf(cls, source: str) -> SourceInfo:
method _detect_word (line 178) | def _detect_word(cls, source: str) -> SourceInfo:
method _detect_epub (line 186) | def _detect_epub(cls, source: str) -> SourceInfo:
method _detect_jupyter (line 194) | def _detect_jupyter(cls, source: str) -> SourceInfo:
method _detect_html (line 202) | def _detect_html(cls, source: str) -> SourceInfo:
method _detect_pptx (line 210) | def _detect_pptx(cls, source: str) -> SourceInfo:
method _detect_asciidoc (line 218) | def _detect_asciidoc(cls, source: str) -> SourceInfo:
method _detect_manpage (line 226) | def _detect_manpage(cls, source: str) -> SourceInfo:
method _detect_rss (line 234) | def _detect_rss(cls, source: str) -> SourceInfo:
method _looks_like_openapi (line 242) | def _looks_like_openapi(cls, source: str) -> bool:
method _detect_openapi (line 270) | def _detect_openapi(cls, source: str) -> SourceInfo:
method _detect_video_file (line 278) | def _detect_video_file(cls, source: str) -> SourceInfo:
method _detect_video_url (line 289) | def _detect_video_url(cls, source: str) -> SourceInfo | None:
method _detect_local (line 334) | def _detect_local(cls, source: str) -> SourceInfo:
method _detect_github (line 345) | def _detect_github(cls, source: str) -> SourceInfo | None:
method _detect_web (line 381) | def _detect_web(cls, source: str) -> SourceInfo:
method validate_source (line 396) | def validate_source(cls, source_info: SourceInfo) -> None:
FILE: src/skill_seekers/cli/split_config.py
class ConfigSplitter (line 17) | class ConfigSplitter:
method __init__ (line 20) | def __init__(self, config_path: str, strategy: str = "auto", target_pa...
method load_config (line 27) | def load_config(self) -> dict[str, Any]:
method is_unified_config (line 39) | def is_unified_config(self) -> bool:
method get_split_strategy (line 43) | def get_split_strategy(self) -> str:
method split_by_category (line 92) | def split_by_category(self, create_router: bool = False) -> list[dict[...
method split_by_size (line 153) | def split_by_size(self) -> list[dict[str, Any]]:
method split_by_source (line 180) | def split_by_source(self) -> list[dict[str, Any]]:
method create_router_config (line 220) | def create_router_config(self, sub_configs: list[dict[str, Any]]) -> d...
method split (line 241) | def split(self) -> list[dict[str, Any]]:
method save_configs (line 275) | def save_configs(self, configs: list[dict[str, Any]], output_dir: Path...
function main (line 298) | def main():
FILE: src/skill_seekers/cli/storage/__init__.py
function get_storage_adaptor (line 31) | def get_storage_adaptor(provider: str, **kwargs) -> BaseStorageAdaptor:
FILE: src/skill_seekers/cli/storage/azure_storage.py
class AzureStorageAdaptor (line 20) | class AzureStorageAdaptor(BaseStorageAdaptor):
method __init__ (line 53) | def __init__(self, **kwargs):
method upload_file (line 109) | def upload_file(
method download_file (line 127) | def download_file(self, remote_path: str, local_path: str) -> None:
method delete_file (line 143) | def delete_file(self, remote_path: str) -> None:
method list_files (line 153) | def list_files(self, prefix: str = "", max_results: int = 1000) -> lis...
method file_exists (line 178) | def file_exists(self, remote_path: str) -> bool:
method get_file_url (line 186) | def get_file_url(self, remote_path: str, expires_in: int = 3600) -> str:
method copy_file (line 212) | def copy_file(self, source_path: str, dest_path: str) -> None:
FILE: src/skill_seekers/cli/storage/base_storage.py
class StorageObject (line 11) | class StorageObject:
class BaseStorageAdaptor (line 30) | class BaseStorageAdaptor(ABC):
method __init__ (line 38) | def __init__(self, **kwargs):
method upload_file (line 48) | def upload_file(
method download_file (line 69) | def download_file(self, remote_path: str, local_path: str) -> None:
method delete_file (line 84) | def delete_file(self, remote_path: str) -> None:
method list_files (line 98) | def list_files(self, prefix: str = "", max_results: int = 1000) -> lis...
method file_exists (line 115) | def file_exists(self, remote_path: str) -> bool:
method get_file_url (line 128) | def get_file_url(self, remote_path: str, expires_in: int = 3600) -> str:
method upload_directory (line 145) | def upload_directory(
method download_directory (line 192) | def download_directory(self, remote_prefix: str, local_dir: str) -> li...
method get_file_size (line 226) | def get_file_size(self, remote_path: str) -> int:
method copy_file (line 244) | def copy_file(self, source_path: str, dest_path: str) -> None:
FILE: src/skill_seekers/cli/storage/gcs_storage.py
class GCSStorageAdaptor (line 20) | class GCSStorageAdaptor(BaseStorageAdaptor):
method __init__ (line 51) | def __init__(self, **kwargs):
method upload_file (line 84) | def upload_file(
method download_file (line 103) | def download_file(self, remote_path: str, local_path: str) -> None:
method delete_file (line 116) | def delete_file(self, remote_path: str) -> None:
method list_files (line 126) | def list_files(self, prefix: str = "", max_results: int = 1000) -> lis...
method file_exists (line 149) | def file_exists(self, remote_path: str) -> bool:
method get_file_url (line 157) | def get_file_url(self, remote_path: str, expires_in: int = 3600) -> str:
method copy_file (line 174) | def copy_file(self, source_path: str, dest_path: str) -> None:
FILE: src/skill_seekers/cli/storage/s3_storage.py
class S3StorageAdaptor (line 19) | class S3StorageAdaptor(BaseStorageAdaptor):
method __init__ (line 56) | def __init__(self, **kwargs):
method upload_file (line 92) | def upload_file(
method download_file (line 115) | def download_file(self, remote_path: str, local_path: str) -> None:
method delete_file (line 127) | def delete_file(self, remote_path: str) -> None:
method list_files (line 134) | def list_files(self, prefix: str = "", max_results: int = 1000) -> lis...
method file_exists (line 161) | def file_exists(self, remote_path: str) -> bool:
method get_file_url (line 171) | def get_file_url(self, remote_path: str, expires_in: int = 3600) -> str:
method copy_file (line 183) | def copy_file(self, source_path: str, dest_path: str) -> None:
FILE: src/skill_seekers/cli/streaming_ingest.py
class ChunkMetadata (line 18) | class ChunkMetadata:
class IngestionProgress (line 32) | class IngestionProgress:
method progress_percent (line 44) | def progress_percent(self) -> float:
method elapsed_time (line 51) | def elapsed_time(self) -> float:
method chunks_per_second (line 56) | def chunks_per_second(self) -> float:
method eta_seconds (line 64) | def eta_seconds(self) -> float:
class StreamingIngester (line 73) | class StreamingIngester:
method __init__ (line 81) | def __init__(
method chunk_document (line 103) | def chunk_document(
method _generate_chunk_id (line 172) | def _generate_chunk_id(self, content: str, metadata: dict, chunk_index...
method stream_skill_directory (line 179) | def stream_skill_directory(
method batch_iterator (line 273) | def batch_iterator(
method save_checkpoint (line 300) | def save_checkpoint(self, checkpoint_path: Path, state: dict) -> None:
method load_checkpoint (line 326) | def load_checkpoint(self, checkpoint_path: Path) -> dict | None:
method format_progress (line 348) | def format_progress(self) -> str:
function main (line 377) | def main():
FILE: src/skill_seekers/cli/swift_patterns.py
function _validate_patterns (line 523) | def _validate_patterns(patterns: dict[str, list[tuple[str, int]]]) -> None:
FILE: src/skill_seekers/cli/sync_cli.py
function handle_signal (line 16) | def handle_signal(_signum, _frame):
function start_command (line 22) | def start_command(args):
function check_command (line 51) | def check_command(args):
function stats_command (line 95) | def stats_command(args):
function reset_command (line 111) | def reset_command(args):
function main (line 125) | def main():
FILE: src/skill_seekers/cli/sync_config.py
function _is_valid_url (line 33) | def _is_valid_url(
function discover_urls (line 52) | def discover_urls(
function diff_urls (line 135) | def diff_urls(discovered: set[str], configured: list[str]) -> tuple[list...
function _get_doc_source (line 152) | def _get_doc_source(config: dict, source_index: int = 0) -> dict | None:
function _set_start_urls (line 171) | def _set_start_urls(config: dict, source_index: int, urls: list[str]) ->...
function sync_config (line 188) | def sync_config(
function main (line 298) | def main() -> None:
FILE: src/skill_seekers/cli/test_example_extractor.py
class TestExample (line 51) | class TestExample:
method to_dict (line 82) | def to_dict(self) -> dict:
method to_markdown (line 86) | def to_markdown(self) -> str:
class ExampleReport (line 116) | class ExampleReport:
method to_dict (line 128) | def to_dict(self) -> dict:
method to_markdown (line 141) | def to_markdown(self) -> str:
class PythonTestAnalyzer (line 168) | class PythonTestAnalyzer:
method __init__ (line 171) | def __init__(self):
method extract (line 180) | def extract(self, file_path: str, code: str) -> list[TestExample]:
method _extract_imports (line 205) | def _extract_imports(self, tree: ast.AST) -> list[str]:
method _is_test_class (line 215) | def _is_test_class(self, node: ast.ClassDef) -> bool:
method _is_test_function (line 228) | def _is_test_function(self, node: ast.FunctionDef) -> bool:
method _extract_from_test_class (line 239) | def _extract_from_test_class(
method _extract_from_test_function (line 257) | def _extract_from_test_function(
method _extract_setup_method (line 266) | def _extract_setup_method(self, class_node: ast.ClassDef) -> str | None:
method _extract_fixtures (line 273) | def _extract_fixtures(self, func_node: ast.FunctionDef) -> str | None:
method _analyze_test_body (line 284) | def _analyze_test_body(
method _detect_tags (line 326) | def _detect_tags(self, func_node: ast.FunctionDef, imports: list[str])...
method _find_instantiations (line 351) | def _find_instantiations(
method _find_method_calls_with_assertions (line 400) | def _find_method_calls_with_assertions(
method _find_config_dicts (line 452) | def _find_config_dicts(
method _find_workflows (line 496) | def _find_workflows(
method _is_meaningful_instantiation (line 540) | def _is_meaningful_instantiation(self, node: ast.Assign) -> bool:
method _get_class_name (line 549) | def _get_class_name(self, call_node: ast.Call) -> str:
method _is_assertion (line 557) | def _is_assertion(self, node: ast.stmt) -> bool:
method _is_config_dict (line 569) | def _is_config_dict(self, dict_node: ast.Dict) -> bool:
method _is_integration_test (line 577) | def _is_integration_test(self, func_node: ast.FunctionDef) -> bool:
method _extract_assertion_after (line 611) | def _extract_assertion_after(self, func_node: ast.FunctionDef, target_...
method _extract_final_assertion (line 622) | def _extract_final_assertion(self, func_node: ast.FunctionDef) -> str:
method _calculate_complexity (line 629) | def _calculate_complexity(self, code: str) -> float:
method _generate_id (line 638) | def _generate_id(self, code: str) -> str:
class GenericTestAnalyzer (line 648) | class GenericTestAnalyzer:
method extract (line 733) | def extract(self, file_path: str, code: str, language: str) -> list[Te...
method _create_example (line 838) | def _create_example(
class ExampleQualityFilter (line 871) | class ExampleQualityFilter:
method __init__ (line 874) | def __init__(self, min_confidence: float = 0.7, min_code_length: int =...
method filter (line 889) | def filter(self, examples: list[TestExample]) -> list[TestExample]:
method _is_trivial (line 910) | def _is_trivial(self, code: str) -> bool:
class TestExampleExtractor (line 920) | class TestExampleExtractor:
method __init__ (line 953) | def __init__(
method extract_from_directory (line 978) | def extract_from_directory(self, directory: Path, recursive: bool = Tr...
method extract_from_file (line 999) | def extract_from_file(self, file_path: Path) -> list[TestExample]:
method _find_test_files (line 1040) | def _find_test_files(self, directory: Path, recursive: bool) -> list[P...
method _detect_language (line 1052) | def _detect_language(self, file_path: Path) -> str:
method _create_report (line 1057) | def _create_report(
function main (line 1112) | def main():
FILE: src/skill_seekers/cli/test_unified_simple.py
function test_validate_existing_unified_configs (line 20) | def test_validate_existing_unified_configs():
function test_backward_compatibility (line 42) | def test_backward_compatibility():
function test_create_temp_unified_config (line 57) | def test_create_temp_unified_config():
function test_mixed_source_types (line 95) | def test_mixed_source_types():
function test_config_validation_errors (line 128) | def test_config_validation_errors():
FILE: src/skill_seekers/cli/unified_codebase_analyzer.py
class AnalysisResult (line 23) | class AnalysisResult:
class UnifiedCodebaseAnalyzer (line 33) | class UnifiedCodebaseAnalyzer:
method __init__ (line 62) | def __init__(self, github_token: str | None = None):
method analyze (line 71) | def analyze(
method _analyze_github (line 105) | def _analyze_github(
method _analyze_local (line 160) | def _analyze_local(self, directory: str, depth: str) -> AnalysisResult:
method basic_analysis (line 191) | def basic_analysis(self, directory: Path) -> dict:
method c3x_analysis (line 222) | def c3x_analysis(self, directory: Path) -> dict:
method _load_c3x_results (line 308) | def _load_c3x_results(self, output_dir: Path) -> dict:
method is_github_url (line 385) | def is_github_url(self, source: str) -> bool:
method list_files (line 397) | def list_files(self, directory: Path) -> list[dict]:
method get_directory_structure (line 423) | def get_directory_structure(self, directory: Path) -> dict:
method extract_imports (line 452) | def extract_imports(self, directory: Path) -> dict[str, list[str]]:
method find_entry_points (line 486) | def find_entry_points(self, directory: Path) -> list[str]:
method compute_statistics (line 526) | def compute_statistics(self, directory: Path) -> dict:
FILE: src/skill_seekers/cli/unified_enhancer.py
class EnhancementConfig (line 42) | class EnhancementConfig:
class UnifiedEnhancer (line 52) | class UnifiedEnhancer:
method __init__ (line 65) | def __init__(
method _check_claude_cli (line 131) | def _check_claude_cli(self) -> bool:
method enhance (line 144) | def enhance(
method _enhance_parallel (line 195) | def _enhance_parallel(self, batches: list[list[dict]], prompt_template...
method _enhance_batch (line 227) | def _enhance_batch(self, items: list[dict], prompt_template: str) -> l...
method _call_claude (line 267) | def _call_claude(self, prompt: str, max_tokens: int = 1000) -> str | N...
method _call_claude_api (line 275) | def _call_claude_api(self, prompt: str, max_tokens: int = 1000) -> str...
method _call_claude_local (line 291) | def _call_claude_local(self, prompt: str) -> str | None:
method _get_default_prompt (line 351) | def _get_default_prompt(self, enhancement_type: str) -> str:
method _format_item_for_prompt (line 404) | def _format_item_for_prompt(self, idx: int, item: dict) -> str:
class PatternEnhancer (line 421) | class PatternEnhancer(UnifiedEnhancer):
method enhance_patterns (line 424) | def enhance_patterns(self, patterns: list[dict]) -> list[dict]:
class TestExampleEnhancer (line 428) | class TestExampleEnhancer(UnifiedEnhancer):
method enhance_examples (line 431) | def enhance_examples(self, examples: list[dict]) -> list[dict]:
class GuideEnhancer (line 435) | class GuideEnhancer(UnifiedEnhancer):
method enhance_guides (line 438) | def enhance_guides(self, guides: list[dict]) -> list[dict]:
class ConfigEnhancer (line 442) | class ConfigEnhancer(UnifiedEnhancer):
method enhance_config (line 445) | def enhance_config(self, config: list[dict]) -> list[dict]:
FILE: src/skill_seekers/cli/unified_scraper.py
class UnifiedScraper (line 40) | class UnifiedScraper:
method __init__ (line 52) | def __init__(self, config_path: str, merge_mode: str | None = None):
method _setup_logging (line 134) | def _setup_logging(self):
method scrape_all_sources (line 158) | def scrape_all_sources(self):
method _scrape_documentation (line 221) | def _scrape_documentation(self, source: dict[str, Any]):
method _clone_github_repo (line 318) | def _clone_github_repo(self, repo_name: str, idx: int = 0) -> str | None:
method _scrape_github (line 378) | def _scrape_github(self, source: dict[str, Any]):
method _scrape_pdf (line 512) | def _scrape_pdf(self, source: dict[str, Any]):
method _scrape_word (line 574) | def _scrape_word(self, source: dict[str, Any]):
method _scrape_video (line 634) | def _scrape_video(self, source: dict[str, Any]):
method _scrape_local (line 694) | def _scrape_local(self, source: dict[str, Any]):
method _scrape_epub (line 840) | def _scrape_epub(self, source: dict[str, Any]):
method _scrape_jupyter (line 892) | def _scrape_jupyter(self, source: dict[str, Any]):
method _scrape_html (line 944) | def _scrape_html(self, source: dict[str, Any]):
method _scrape_openapi (line 993) | def _scrape_openapi(self, source: dict[str, Any]):
method _scrape_asciidoc (line 1043) | def _scrape_asciidoc(self, source: dict[str, Any]):
method _scrape_pptx (line 1095) | def _scrape_pptx(self, source: dict[str, Any]):
method _scrape_confluence (line 1147) | def _scrape_confluence(self, source: dict[str, Any]):
method _scrape_notion (line 1204) | def _scrape_notion(self, source: dict[str, Any]):
method _scrape_rss (line 1262) | def _scrape_rss(self, source: dict[str, Any]):
method _scrape_manpage (line 1317) | def _scrape_manpage(self, source: dict[str, Any]):
method _scrape_chat (line 1368) | def _scrape_chat(self, source: dict[str, Any]):
method _load_json (line 1425) | def _load_json(self, file_path: Path) -> dict:
method _load_guide_collection (line 1446) | def _load_guide_collection(self, tutorials_dir: Path) -> dict:
method _load_api_reference (line 1473) | def _load_api_reference(self, api_dir: Path) -> dict[str, Any]:
method _run_c3_analysis (line 1497) | def _run_c3_analysis(self, local_repo_path: str, source: dict[str, Any...
method detect_conflicts (line 1592) | def detect_conflicts(self) -> list:
method merge_sources (line 1648) | def merge_sources(self, conflicts: list):
method build_skill (line 1692) | def build_skill(self, merged_data: dict | None = None):
method run (line 1720) | def run(self, args=None):
function main (line 1815) | def main():
FILE: src/skill_seekers/cli/unified_skill_builder.py
class UnifiedSkillBuilder (line 25) | class UnifiedSkillBuilder:
method __init__ (line 30) | def __init__(
method build (line 64) | def build(self):
method _load_source_skill_mds (line 80) | def _load_source_skill_mds(self) -> dict[str, str]:
method _parse_skill_md_sections (line 180) | def _parse_skill_md_sections(self, skill_md: str) -> dict[str, str]:
method _synthesize_docs_github (line 237) | def _synthesize_docs_github(self, skill_mds: dict[str, str]) -> str:
method _synthesize_docs_github_pdf (line 396) | def _synthesize_docs_github_pdf(self, skill_mds: dict[str, str]) -> str:
method _generate_skill_md (line 469) | def _generate_skill_md(self):
method _synthesize_docs_pdf (line 541) | def _synthesize_docs_pdf(self, skill_mds: dict[str, str]) -> str:
method _synthesize_github_pdf (line 587) | def _synthesize_github_pdf(self, skill_mds: dict[str, str]) -> str:
method _generic_merge (line 652) | def _generic_merge(self, skill_mds: dict[str, str]) -> str:
method _append_extra_sources (line 737) | def _append_extra_sources(
method _generate_minimal_skill_md (line 786) | def _generate_minimal_skill_md(self) -> str:
method _format_merged_apis (line 907) | def _format_merged_apis(self) -> str:
method _format_api_entry (line 958) | def _format_api_entry(self, api_data: dict, inline_conflict: bool = Fa...
method _format_code_signature (line 994) | def _format_code_signature(self, code_info: dict) -> str:
method _generate_references (line 1015) | def _generate_references(self):
method _generate_docs_references (line 1065) | def _generate_docs_references(self, docs_list: list[dict]):
method _generate_github_references (line 1131) | def _generate_github_references(self, github_list: list[dict]):
method _generate_pdf_references (line 1217) | def _generate_pdf_references(self, pdf_list: list[dict]):
method _generate_generic_references (line 1234) | def _generate_generic_references(self, source_type: str, source_list: ...
method _generate_merged_api_reference (line 1291) | def _generate_merged_api_reference(self):
method _generate_c3_analysis_references (line 1311) | def _generate_c3_analysis_references(self, repo_id: str = "github"):
method _generate_architecture_overview (line 1353) | def _generate_architecture_overview(self, c3_dir: str, c3_data: dict, ...
method _generate_pattern_references (line 1537) | def _generate_pattern_references(self, c3_dir: str, patterns_data: dict):
method _generate_example_references (line 1572) | def _generate_example_references(self, c3_dir: str, examples_data: dict):
method _generate_guide_references (line 1617) | def _generate_guide_references(self, c3_dir: str, guides_data: dict):
method _generate_config_references (line 1672) | def _generate_config_references(self, c3_dir: str, config_data: dict):
method _copy_architecture_details (line 1730) | def _copy_architecture_details(self, c3_dir: str, arch_data: dict):
method _format_c3_summary_section (line 1765) | def _format_c3_summary_section(self, c3_data: dict) -> str:
method _generate_conflicts_report (line 1834) | def _generate_conflicts_report(self):
FILE: src/skill_seekers/cli/upload_skill.py
function upload_skill_api (line 33) | def upload_skill_api(package_path, target="claude", api_key=None, **kwar...
function main (line 114) | def main():
FILE: src/skill_seekers/cli/utils.py
function setup_logging (line 21) | def setup_logging(verbose: bool = False, quiet: bool = False) -> None:
function open_folder (line 37) | def open_folder(folder_path: str | Path) -> bool:
function has_api_key (line 77) | def has_api_key() -> bool:
function get_api_key (line 88) | def get_api_key() -> str | None:
function get_upload_url (line 99) | def get_upload_url() -> str:
function print_upload_instructions (line 109) | def print_upload_instructions(zip_path: str | Path) -> None:
function format_file_size (line 132) | def format_file_size(size_bytes: int) -> str:
function validate_skill_directory (line 150) | def validate_skill_directory(skill_dir: str | Path) -> tuple[bool, str |...
function validate_zip_file (line 175) | def validate_zip_file(zip_path: str | Path) -> tuple[bool, str | None]:
function read_reference_files (line 199) | def read_reference_files(
function retry_with_backoff (line 344) | def retry_with_backoff(
function retry_with_backoff_async (line 401) | async def retry_with_backoff_async(
function build_line_index (line 461) | def build_line_index(content: str) -> list[int]:
function offset_to_line (line 473) | def offset_to_line(newline_offsets: list[int], offset: int) -> int:
function sanitize_url (line 494) | def sanitize_url(url: str) -> str:
FILE: src/skill_seekers/cli/video_metadata.py
function extract_video_id (line 56) | def extract_video_id(url: str) -> str | None:
function detect_video_source_type (line 72) | def detect_video_source_type(url_or_path: str) -> VideoSourceType:
function _check_ytdlp (line 100) | def _check_ytdlp():
function extract_youtube_metadata (line 110) | def extract_youtube_metadata(url: str) -> VideoInfo:
function extract_local_metadata (line 172) | def extract_local_metadata(file_path: str) -> VideoInfo:
function resolve_playlist (line 199) | def resolve_playlist(url: str) -> list[str]:
function resolve_channel (line 235) | def resolve_channel(url: str, max_videos: int = 50) -> list[str]:
FILE: src/skill_seekers/cli/video_models.py
class VideoSourceType (line 23) | class VideoSourceType(Enum):
class TranscriptSource (line 32) | class TranscriptSource(Enum):
class FrameType (line 42) | class FrameType(Enum):
class CodeContext (line 55) | class CodeContext(Enum):
class SegmentContentType (line 65) | class SegmentContentType(Enum):
class SegmentationStrategy (line 78) | class SegmentationStrategy(Enum):
class Chapter (line 93) | class Chapter:
method duration (line 101) | def duration(self) -> float:
method to_dict (line 104) | def to_dict(self) -> dict:
method from_dict (line 112) | def from_dict(cls, data: dict) -> Chapter:
class WordTimestamp (line 121) | class WordTimestamp:
method to_dict (line 129) | def to_dict(self) -> dict:
method from_dict (line 138) | def from_dict(cls, data: dict) -> WordTimestamp:
class TranscriptSegment (line 148) | class TranscriptSegment:
method to_dict (line 158) | def to_dict(self) -> dict:
method from_dict (line 169) | def from_dict(cls, data: dict) -> TranscriptSegment:
class OCRRegion (line 184) | class OCRRegion:
method to_dict (line 192) | def to_dict(self) -> dict:
method from_dict (line 201) | def from_dict(cls, data: dict) -> OCRRegion:
class FrameSubSection (line 211) | class FrameSubSection:
method to_dict (line 227) | def to_dict(self) -> dict:
method from_dict (line 238) | def from_dict(cls, data: dict) -> FrameSubSection:
class KeyFrame (line 250) | class KeyFrame:
method to_dict (line 264) | def to_dict(self) -> dict:
method from_dict (line 279) | def from_dict(cls, data: dict) -> KeyFrame:
class CodeBlock (line 295) | class CodeBlock:
method to_dict (line 305) | def to_dict(self) -> dict:
method from_dict (line 316) | def from_dict(cls, data: dict) -> CodeBlock:
class TextGroupEdit (line 328) | class TextGroupEdit:
method to_dict (line 336) | def to_dict(self) -> dict:
method from_dict (line 345) | def from_dict(cls, data: dict) -> TextGroupEdit:
class TextGroup (line 355) | class TextGroup:
method full_text (line 371) | def full_text(self) -> str:
method to_dict (line 374) | def to_dict(self) -> dict:
method from_dict (line 387) | def from_dict(cls, data: dict) -> TextGroup:
class TextGroupTimeline (line 400) | class TextGroupTimeline:
method get_groups_at_time (line 408) | def get_groups_at_time(self, timestamp: float) -> list[TextGroup]:
method to_dict (line 416) | def to_dict(self) -> dict:
method from_dict (line 425) | def from_dict(cls, data: dict) -> TextGroupTimeline:
class AudioVisualAlignment (line 435) | class AudioVisualAlignment:
method to_dict (line 445) | def to_dict(self) -> dict:
method from_dict (line 456) | def from_dict(cls, data: dict) -> AudioVisualAlignment:
class VideoSegment (line 473) | class VideoSegment:
method to_dict (line 507) | def to_dict(self) -> dict:
method from_dict (line 532) | def from_dict(cls, data: dict) -> VideoSegment:
method timestamp_display (line 559) | def timestamp_display(self) -> str:
class VideoInfo (line 571) | class VideoInfo:
method to_dict (line 633) | def to_dict(self) -> dict:
method from_dict (line 675) | def from_dict(cls, data: dict) -> VideoInfo:
class VideoSourceConfig (line 720) | class VideoSourceConfig:
method from_dict (line 758) | def from_dict(cls, data: dict) -> VideoSourceConfig:
method validate (line 780) | def validate(self) -> list[str]:
class VideoScraperResult (line 815) | class VideoScraperResult:
method to_dict (line 827) | def to_dict(self) -> dict:
method from_dict (line 839) | def from_dict(cls, data: dict) -> VideoScraperResult:
FILE: src/skill_seekers/cli/video_scraper.py
function check_video_dependencies (line 58) | def check_video_dependencies(require_full: bool = False) -> None:
function _sanitize_filename (line 102) | def _sanitize_filename(title: str, max_length: int = 60) -> str:
function parse_time_to_seconds (line 112) | def parse_time_to_seconds(time_str: str) -> float:
function _format_duration (line 151) | def _format_duration(seconds: float) -> str:
function _format_count (line 161) | def _format_count(count: int | None) -> str:
function infer_description_from_video (line 168) | def infer_description_from_video(video_info: VideoInfo, name: str = "") ...
function _build_audio_visual_alignments (line 189) | def _build_audio_visual_alignments(
function _is_likely_code (line 250) | def _is_likely_code(text: str) -> bool:
function _ai_clean_reference (line 264) | def _ai_clean_reference(ref_path: str, content: str, api_key: str | None...
class VideoToSkillConverter (line 321) | class VideoToSkillConverter:
method __init__ (line 324) | def __init__(self, config: dict):
method process (line 358) | def process(self) -> VideoScraperResult:
method save_extracted_data (line 593) | def save_extracted_data(self) -> str:
method load_extracted_data (line 609) | def load_extracted_data(self, json_path: str) -> None:
method build_skill (line 620) | def build_skill(self) -> str:
method _generate_reference_md (line 665) | def _generate_reference_md(self, video: VideoInfo) -> str:
method _enhance_reference_files (line 864) | def _enhance_reference_files(self, enhance_level: int, args) -> None:
method _generate_skill_md (line 902) | def _generate_skill_md(self) -> str:
function main (line 1022) | def main() -> int:
function _run_video_enhancement (line 1193) | def _run_video_enhancement(skill_dir: str, enhance_level: int, args) -> ...
FILE: src/skill_seekers/cli/video_segmenter.py
function _classify_content_type (line 21) | def _classify_content_type(transcript: str) -> SegmentContentType:
function _build_segment_content (line 39) | def _build_segment_content(
function _get_transcript_in_range (line 64) | def _get_transcript_in_range(
function segment_by_chapters (line 88) | def segment_by_chapters(
function segment_by_time_window (line 131) | def segment_by_time_window(
function segment_video (line 196) | def segment_video(
FILE: src/skill_seekers/cli/video_setup.py
class GPUVendor (line 40) | class GPUVendor(Enum):
class GPUInfo (line 49) | class GPUInfo:
class SetupModules (line 60) | class SetupModules:
function _cuda_version_to_index_url (line 78) | def _cuda_version_to_index_url(version: str) -> str:
function _rocm_version_to_index_url (line 97) | def _rocm_version_to_index_url(version: str) -> str:
function detect_gpu (line 119) | def detect_gpu() -> GPUInfo:
function _check_nvidia (line 152) | def _check_nvidia() -> GPUInfo | None:
function _check_amd_rocm (line 190) | def _check_amd_rocm() -> GPUInfo | None:
function _read_rocm_version (line 227) | def _read_rocm_version() -> str:
function _check_amd_lspci (line 236) | def _check_amd_lspci() -> GPUInfo | None:
function is_in_venv (line 274) | def is_in_venv() -> bool:
function create_venv (line 279) | def create_venv(venv_path: str = ".venv") -> bool:
function get_venv_python (line 293) | def get_venv_python(venv_path: str = ".venv") -> str:
function get_venv_activate_cmd (line 301) | def get_venv_activate_cmd(venv_path: str = ".venv") -> str:
function _detect_dis
Copy disabled (too large)
Download .json
Condensed preview — 722 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (10,001K chars).
[
{
"path": ".claude/mcp_config.example.json",
"chars": 285,
"preview": "{\n \"mcpServers\": {\n \"skill-seeker\": {\n \"type\": \"stdio\",\n \"command\": \"/path/to/your/Skill_Seekers/.venv/bin"
},
{
"path": ".dockerignore",
"chars": 697,
"preview": "# Python artifacts\n__pycache__/\n*.py[cod]\n*$py.class\n*.so\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib"
},
{
"path": ".github/FUNDING.yml",
"chars": 230,
"preview": "# GitHub Sponsors configuration\n# https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-feature"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.md",
"chars": 943,
"preview": "---\nname: Bug Report\nabout: Report a bug or issue with Skill Seekers\ntitle: '[BUG] '\nlabels: 'type: bug'\nassignees: ''\n-"
},
{
"path": ".github/ISSUE_TEMPLATE/documentation.md",
"chars": 804,
"preview": "---\nname: Documentation Improvement\nabout: Suggest improvements to documentation\ntitle: '[DOCS] '\nlabels: 'type: documen"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.md",
"chars": 828,
"preview": "---\nname: Feature Request\nabout: Suggest a new feature for Skill Seekers\ntitle: '[FEATURE] '\nlabels: 'type: feature'\nass"
},
{
"path": ".github/ISSUE_TEMPLATE/mcp_tool.md",
"chars": 853,
"preview": "---\nname: MCP Tool Request\nabout: Suggest a new tool for the MCP server\ntitle: '[MCP] Add tool: '\nlabels: mcp, enhanceme"
},
{
"path": ".github/PULL_REQUEST_TEMPLATE.md",
"chars": 1305,
"preview": "# Pull Request\n\n## 📋 Description\n\nBrief description of changes made.\n\n## 🔗 Related Issues\n\nCloses #(issue number)\nRelate"
},
{
"path": ".github/create_issues.sh",
"chars": 1622,
"preview": "#!/bin/bash\n# Script to create GitHub issues via web browser\n# Since gh CLI is not available, we'll open browser to crea"
},
{
"path": ".github/workflows/docker-publish.yml",
"chars": 4129,
"preview": "# Docker Image Publishing - Automated builds and pushes to Docker Hub\n# Security Note: Uses secrets for Docker Hub crede"
},
{
"path": ".github/workflows/quality-metrics.yml",
"chars": 4971,
"preview": "# Security Note: This workflow uses workflow_dispatch inputs and pull_request events.\n# All untrusted inputs are accesse"
},
{
"path": ".github/workflows/release.yml",
"chars": 3901,
"preview": "name: Release\n\non:\n push:\n tags:\n - 'v*'\n\npermissions:\n contents: write\n\njobs:\n build:\n runs-on: ubuntu-la"
},
{
"path": ".github/workflows/scheduled-updates.yml",
"chars": 6148,
"preview": "# Automated Skill Updates - Runs weekly to refresh documentation\n# Security Note: Schedule triggers with hardcoded const"
},
{
"path": ".github/workflows/test-vector-dbs.yml",
"chars": 4526,
"preview": "# Security Note: This workflow uses only push/pull_request/workflow_dispatch triggers.\n# Matrix values are hardcoded con"
},
{
"path": ".github/workflows/tests.yml",
"chars": 3821,
"preview": "name: Tests\n\non:\n push:\n branches: [ main, development ]\n pull_request:\n branches: [ main, development ]\n\njobs:\n"
},
{
"path": ".github/workflows/vector-db-export.yml",
"chars": 5944,
"preview": "name: Vector Database Export\n\non:\n workflow_dispatch:\n inputs:\n skill_name:\n description: 'Skill name to"
},
{
"path": ".gitignore",
"chars": 649,
"preview": "# Python\n__pycache__/\n*.py[cod]\n*$py.class\n*.so\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\np"
},
{
"path": ".gitmodules",
"chars": 123,
"preview": "[submodule \"api/configs_repo\"]\n\tpath = api/configs_repo\n\turl = https://github.com/yusufkaraaslan/skill-seekers-configs.g"
},
{
"path": "=0.24.0",
"chars": 919,
"preview": "error: externally-managed-environment\n\n× This environment is externally managed\n╰─> To install Python packages system-wi"
},
{
"path": "AGENTS.md",
"chars": 8181,
"preview": "# AGENTS.md - Skill Seekers\n\nConcise reference for AI coding agents. Skill Seekers is a Python CLI tool (v3.3.0) that co"
},
{
"path": "BULLETPROOF_QUICKSTART.md",
"chars": 14162,
"preview": "# Bulletproof Quick Start Guide\n\n**Target Audience:** Complete beginners | Never used Python/git before? Start here!\n\n**"
},
{
"path": "CHANGELOG.md",
"chars": 162207,
"preview": "# Changelog\n\nAll notable changes to Skill Seeker will be documented in this file.\n\nThe format is based on [Keep a Change"
},
{
"path": "CLAUDE.md",
"chars": 9119,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "CONTRIBUTING.md",
"chars": 13413,
"preview": "# Contributing to Skill Seeker\n\nFirst off, thank you for considering contributing to Skill Seeker! It's people like you "
},
{
"path": "Dockerfile",
"chars": 2164,
"preview": "# Skill Seekers - Multi-stage Docker Build\n# Optimized for production deployment with minimal image size\n\n# Stage 1: Bui"
},
{
"path": "Dockerfile.mcp",
"chars": 1761,
"preview": "# Skill Seekers MCP Server - Docker Image\n# Optimized for MCP server deployment (stdio + HTTP modes)\n\nFROM python:3.12-s"
},
{
"path": "LICENSE",
"chars": 1077,
"preview": "MIT License\n\nCopyright (c) 2025 [Your Name/Username]\n\nPermission is hereby granted, free of charge, to any person obtain"
},
{
"path": "README.ar.md",
"chars": 39990,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.de.md",
"chars": 44184,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.es.md",
"chars": 49296,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.fr.md",
"chars": 50919,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.hi.md",
"chars": 45771,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.ja.md",
"chars": 32893,
"preview": "[](https://mseep.ai/app/yusufkaraasl"
},
{
"path": "README.ko.md",
"chars": 32119,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.md",
"chars": 45414,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\nEnglish | "
},
{
"path": "README.pt-BR.md",
"chars": 48144,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.ru.md",
"chars": 44386,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.tr.md",
"chars": 48049,
"preview": "<p align=\"center\">\n <img src=\"docs/assets/logo.png\" alt=\"Skill Seekers\" width=\"200\"/>\n</p>\n\n# Skill Seekers\n\n[English]("
},
{
"path": "README.zh-CN.md",
"chars": 29380,
"preview": "[](https://mseep.ai/app/yusufkaraaslan-sk"
},
{
"path": "ROADMAP.md",
"chars": 15571,
"preview": "# Skill Seekers Roadmap\n\nTransform Skill Seekers into the easiest way to create Claude AI skills from **any knowledge so"
},
{
"path": "TESTING_GAP_REPORT.md",
"chars": 10062,
"preview": "# Comprehensive Testing Gap Report\n\n**Project:** Skill Seekers v3.1.0 \n**Date:** 2026-02-22 \n**Total Test Files:** 113"
},
{
"path": "TROUBLESHOOTING.md",
"chars": 8737,
"preview": "# Troubleshooting Guide\n\nCommon issues and solutions when using Skill Seeker.\n\n---\n\n## Installation Issues\n\n### Python N"
},
{
"path": "api/.gitignore",
"chars": 78,
"preview": "# configs_repo is now a git submodule, tracked in .gitmodules\n# configs_repo/\n"
},
{
"path": "api/README.md",
"chars": 6135,
"preview": "# Skill Seekers Config API\n\nFastAPI backend for discovering and downloading Skill Seekers configuration files.\n\n## 🚀 End"
},
{
"path": "api/__init__.py",
"chars": 117,
"preview": "\"\"\"\nSkill Seekers Config API\nFastAPI backend for discovering and downloading config files\n\"\"\"\n\n__version__ = \"1.0.0\"\n"
},
{
"path": "api/config_analyzer.py",
"chars": 12328,
"preview": "#!/usr/bin/env python3\n\"\"\"\nConfig Analyzer - Extract metadata from Skill Seekers config files\n\"\"\"\n\nimport json\nimport su"
},
{
"path": "api/main.py",
"chars": 6072,
"preview": "#!/usr/bin/env python3\n\"\"\"\nSkill Seekers Config API\nFastAPI backend for listing available skill configs\n\"\"\"\n\nfrom pathli"
},
{
"path": "api/requirements.txt",
"chars": 68,
"preview": "fastapi==0.115.0\nuvicorn[standard]==0.32.0\npython-multipart==0.0.12\n"
},
{
"path": "configs/astrovalley_unified.json",
"chars": 942,
"preview": "{\n \"name\": \"astrovalley\",\n \"description\": \"Space farming/automation game with combat and exploration - GitHub repo wit"
},
{
"path": "configs/blender-unified.json",
"chars": 7104,
"preview": "{\n \"name\": \"blender\",\n \"description\": \"Complete Blender 3D creation suite knowledge base combining official documentat"
},
{
"path": "configs/claude-code.json",
"chars": 5535,
"preview": "{\n \"name\": \"claude-code\",\n \"description\": \"Claude Code CLI and development environment. Use for Claude Code features, "
},
{
"path": "configs/godot.json",
"chars": 1454,
"preview": "{\n \"name\": \"godot\",\n \"description\": \"Complete Godot Engine knowledge base combining official documentation and source "
},
{
"path": "configs/godot_unified.json",
"chars": 2789,
"preview": "{\n \"name\": \"godot\",\n \"description\": \"Godot Engine 4.x - Complete open source game engine (documentation + source code "
},
{
"path": "configs/httpx_comprehensive.json",
"chars": 2441,
"preview": "{\n \"name\": \"httpx\",\n \"description\": \"Use this skill when working with HTTPX, a fully featured HTTP client for Python 3"
},
{
"path": "configs/medusa-mercurjs.json",
"chars": 4851,
"preview": "{\n \"name\": \"medusa-mercurjs\",\n \"description\": \"Complete Medusa v2 + MercurJS multi-vendor e-commerce framework knowled"
},
{
"path": "configs/react.json",
"chars": 1619,
"preview": "{\n \"name\": \"react\",\n \"description\": \"Complete React knowledge base combining official documentation and React codebase"
},
{
"path": "demo_conflicts.py",
"chars": 5980,
"preview": "#!/usr/bin/env python3\n\"\"\"\nDemo: Conflict Detection and Reporting\n\nThis demonstrates the unified scraper's ability to de"
},
{
"path": "distribution/claude-plugin/.claude-plugin/plugin.json",
"chars": 436,
"preview": "{\n \"name\": \"skill-seekers\",\n \"description\": \"Transform 17 source types (docs, GitHub, PDFs, videos, Jupyter, Confluenc"
},
{
"path": "distribution/claude-plugin/.mcp.json",
"chars": 109,
"preview": "{\n \"skill-seekers\": {\n \"command\": \"python\",\n \"args\": [\"-m\", \"skill_seekers.mcp.server_fastmcp\"]\n }\n}\n"
},
{
"path": "distribution/claude-plugin/README.md",
"chars": 2674,
"preview": "# Skill Seekers — Claude Code Plugin\n\nTransform 17 source types into AI-ready skills and RAG knowledge, directly from Cl"
},
{
"path": "distribution/claude-plugin/commands/create-skill.md",
"chars": 1914,
"preview": "---\ndescription: Create an AI skill from any source (URL, repo, PDF, video, notebook, etc.)\n---\n\n# Create Skill\n\nCreate "
},
{
"path": "distribution/claude-plugin/commands/install-skill.md",
"chars": 1244,
"preview": "---\ndescription: One-command skill creation and packaging for a target platform\n---\n\n# Install Skill\n\nEnd-to-end workflo"
},
{
"path": "distribution/claude-plugin/commands/sync-config.md",
"chars": 834,
"preview": "---\ndescription: Sync a scraping config's URLs against the live documentation site\n---\n\n# Sync Config\n\nSynchronize a Ski"
},
{
"path": "distribution/claude-plugin/skills/skill-builder/SKILL.md",
"chars": 3037,
"preview": "---\nname: skill-builder\ndescription: Automatically detect source types and build AI skills using Skill Seekers. Use when"
},
{
"path": "distribution/github-action/README.md",
"chars": 3597,
"preview": "# Skill Seekers GitHub Action\n\nTransform documentation, GitHub repos, PDFs, videos, and 13 other source types into AI-re"
},
{
"path": "distribution/github-action/action.yml",
"chars": 3050,
"preview": "name: 'Skill Seekers - AI Knowledge Builder'\ndescription: 'Transform documentation, repos, PDFs, videos, and 13 other so"
},
{
"path": "distribution/smithery/README.md",
"chars": 3655,
"preview": "# Skill Seekers — Smithery MCP Registry\n\nPublishing guide for the Skill Seekers MCP server on [Smithery](https://smither"
},
{
"path": "docker-compose.yml",
"chars": 2637,
"preview": "# Skill Seekers Docker Compose\n# Complete deployment with MCP server and vector databases\n\nversion: '3.8'\n\nservices:\n #"
},
{
"path": "docs/ARCHITECTURE.md",
"chars": 5673,
"preview": "# Documentation Architecture\n\n> **How Skill Seekers documentation is organized (v3.2.0 - 17 source types)**\n\n---\n\n## Phi"
},
{
"path": "docs/BEST_PRACTICES.md",
"chars": 12280,
"preview": "# Best Practices for High-Quality Skills\n\n**Target Audience:** Anyone creating Claude skills | Already scraped documenta"
},
{
"path": "docs/DOCKER_DEPLOYMENT.md",
"chars": 14213,
"preview": "# Docker Deployment Guide\n\nComplete guide for deploying Skill Seekers using Docker.\n\n## Table of Contents\n\n- [Quick Star"
},
{
"path": "docs/DOCKER_GUIDE.md",
"chars": 11227,
"preview": "# Docker Deployment Guide\n\nComplete guide for deploying Skill Seekers using Docker and Docker Compose.\n\n## Quick Start\n\n"
},
{
"path": "docs/DOCUMENTATION_UPDATES_SUMMARY.md",
"chars": 5470,
"preview": "# Documentation Updates Summary\n\n**Date:** 2026-02-22 \n**Version:** 3.1.0 \n**Purpose:** Document all documentation upd"
},
{
"path": "docs/FAQ.md",
"chars": 22642,
"preview": "# Frequently Asked Questions (FAQ)\n\n**Version:** 3.2.0\n**Last Updated:** 2026-03-15\n\n---\n\n## General Questions\n\n### What"
},
{
"path": "docs/KUBERNETES_DEPLOYMENT.md",
"chars": 17893,
"preview": "# Kubernetes Deployment Guide\n\nComplete guide for deploying Skill Seekers on Kubernetes.\n\n## Table of Contents\n\n- [Prere"
},
{
"path": "docs/KUBERNETES_GUIDE.md",
"chars": 19375,
"preview": "# Kubernetes Deployment Guide\n\nComplete guide for deploying Skill Seekers to Kubernetes using Helm charts.\n\n## Table of "
},
{
"path": "docs/PRODUCTION_DEPLOYMENT.md",
"chars": 16335,
"preview": "# Production Deployment Guide\n\nComplete guide for deploying Skill Seekers in production environments.\n\n## Table of Conte"
},
{
"path": "docs/README.md",
"chars": 5817,
"preview": "# Skill Seekers Documentation\n\n> **Complete documentation for Skill Seekers v3.2.0**\n\n---\n\n## Welcome!\n\nThis is the offi"
},
{
"path": "docs/TROUBLESHOOTING.md",
"chars": 21896,
"preview": "# Troubleshooting Guide\n\nComprehensive guide for diagnosing and resolving common issues with Skill Seekers.\n\n## Table of"
},
{
"path": "docs/VIDEO_GUIDE.md",
"chars": 19743,
"preview": "# Video Tutorial Extraction Guide\n\nConvert video tutorials into structured AI skills with transcripts, on-screen code ex"
},
{
"path": "docs/advanced/custom-workflows.md",
"chars": 7202,
"preview": "# Custom Workflows Guide\n\n> **Skill Seekers v3.1.0** \n> **Create custom AI enhancement workflows**\n\n---\n\n## What are Cu"
},
{
"path": "docs/advanced/mcp-server.md",
"chars": 7191,
"preview": "# MCP Server Setup Guide\n\n> **Skill Seekers v3.2.0** \n> **Integrate with AI agents via Model Context Protocol**\n\n---\n\n#"
},
{
"path": "docs/advanced/multi-source.md",
"chars": 12615,
"preview": "# Multi-Source Scraping Guide\n\n> **Skill Seekers v3.2.0** \n> **Combine 17 source types into one unified skill**\n\n---\n\n#"
},
{
"path": "docs/agents/plans/2026-03-14-epub-input-support.md",
"chars": 42896,
"preview": "---\ndate: 2026-03-14T19:30:35.172407+00:00\ngit_commit: 7c90a4b9c9bccac8341b0769550d77aae3b4e524\nbranch: development\ntopi"
},
{
"path": "docs/agents/research/2026-03-14-epub-input-support-affected-files.md",
"chars": 10105,
"preview": "---\ndate: 2026-03-14T12:54:24.700367+00:00\ngit_commit: 7c90a4b9c9bccac8341b0769550d77aae3b4e524\nbranch: development\ntopi"
},
{
"path": "docs/architecture/UNIFIED_PARSERS.md",
"chars": 13050,
"preview": "# Unified Document Parsers Architecture\n\n## Overview\n\nThe Unified Document Parser system provides a standardized interfa"
},
{
"path": "docs/archive/historical/ARCHITECTURE_VERIFICATION_REPORT.md",
"chars": 25098,
"preview": "# Architecture Verification Report\n## Three-Stream GitHub Architecture Implementation\n\n**Date**: January 9, 2026\n**Verif"
},
{
"path": "docs/archive/historical/HTTPX_SKILL_GRADING.md",
"chars": 31137,
"preview": "# HTTPX Skill Quality Analysis - Ultra-Deep Grading\n\n**Skill Analyzed:** `output/httpx/SKILL.md` (AI-enhanced, multi-sou"
},
{
"path": "docs/archive/historical/IMPLEMENTATION_SUMMARY_THREE_STREAM.md",
"chars": 14947,
"preview": "# Three-Stream GitHub Architecture - Implementation Summary\n\n**Status**: ✅ **Phases 1-5 Complete** (Phase 6 Pending)\n**D"
},
{
"path": "docs/archive/historical/LOCAL_REPO_TEST_RESULTS.md",
"chars": 13457,
"preview": "# Local Repository Extraction Test - deck_deck_go\n\n**Date:** December 21, 2025\n**Version:** v2.1.1\n**Test Config:** conf"
},
{
"path": "docs/archive/historical/SKILL_QUALITY_FIX_PLAN.md",
"chars": 9946,
"preview": "# Skill Quality Fix Plan\n\n**Created:** 2026-01-11\n**Status:** Not Started\n**Priority:** P0 - Blocking Production Use\n\n--"
},
{
"path": "docs/archive/historical/TEST_MCP_IN_CLAUDE_CODE.md",
"chars": 7553,
"preview": "# Testing MCP Server in Claude Code\n\nThis guide shows you how to test the Skill Seeker MCP server **through actual Claud"
},
{
"path": "docs/archive/historical/THREE_STREAM_COMPLETION_SUMMARY.md",
"chars": 12672,
"preview": "# Three-Stream GitHub Architecture - Completion Summary\n\n**Date**: January 8, 2026\n**Status**: ✅ **ALL PHASES COMPLETE ("
},
{
"path": "docs/archive/historical/THREE_STREAM_STATUS_REPORT.md",
"chars": 11646,
"preview": "# Three-Stream GitHub Architecture - Final Status Report\n\n**Date**: January 8, 2026\n**Status**: ✅ **Phases 1-5 COMPLETE*"
},
{
"path": "docs/archive/legacy/QUICKSTART.md",
"chars": 4119,
"preview": "> ⚠️ **DEPRECATED**: This document is outdated and uses old CLI patterns.\n> \n> For up-to-date documentation, please see:"
},
{
"path": "docs/archive/legacy/QUICK_REFERENCE.md",
"chars": 11295,
"preview": "> ⚠️ **DEPRECATED**: This document contains phantom commands and outdated patterns.\n> \n> For up-to-date documentation, p"
},
{
"path": "docs/archive/legacy/README.md",
"chars": 1925,
"preview": "# Legacy Documentation Archive\n\n> **Status:** Archived \n> **Reason:** Outdated patterns, phantom commands, or supersede"
},
{
"path": "docs/archive/legacy/USAGE.md",
"chars": 18519,
"preview": "> ⚠️ **DEPRECATED**: This document uses outdated CLI patterns (`python3 cli/X.py`).\n> \n> For up-to-date documentation, p"
},
{
"path": "docs/archive/plans/2025-10-24-active-skills-design.md",
"chars": 23677,
"preview": "# Active Skills Design - Demand-Driven Documentation Loading\n\n**Date:** 2025-10-24\n**Type:** Architecture Design\n**Statu"
},
{
"path": "docs/archive/plans/2025-10-24-active-skills-phase1.md",
"chars": 19700,
"preview": "# Active Skills Phase 1: Foundation Implementation Plan\n\n> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing"
},
{
"path": "docs/archive/research/PDF_EXTRACTOR_POC.md",
"chars": 10647,
"preview": "# PDF Extractor - Proof of Concept (Task B1.2)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Task:** B1.2 - Crea"
},
{
"path": "docs/archive/research/PDF_IMAGE_EXTRACTION.md",
"chars": 12697,
"preview": "# PDF Image Extraction (Task B1.5)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Task:** B1.5 - Add PDF image ex"
},
{
"path": "docs/archive/research/PDF_PARSING_RESEARCH.md",
"chars": 11926,
"preview": "# PDF Parsing Libraries Research (Task B1.1)\n\n**Date:** October 21, 2025\n**Task:** B1.1 - Research PDF parsing libraries"
},
{
"path": "docs/archive/research/PDF_SYNTAX_DETECTION.md",
"chars": 14391,
"preview": "# PDF Code Block Syntax Detection (Task B1.4)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Task:** B1.4 - Extra"
},
{
"path": "docs/blog/UNIVERSAL_RAG_PREPROCESSOR.md",
"chars": 17336,
"preview": "# Skill Seekers: The Universal Preprocessor for RAG Systems\n\n**Published:** February 5, 2026\n**Author:** Skill Seekers T"
},
{
"path": "docs/case-studies/deepwiki-open.md",
"chars": 10954,
"preview": "# Case Study: DeepWiki-open + Skill Seekers\n\n**Project:** DeepWiki-open\n**Repository:** AsyncFuncAI/deepwiki-open\n**Arti"
},
{
"path": "docs/features/BOOTSTRAP_SKILL.md",
"chars": 16942,
"preview": "# Bootstrap Skill - Self-Hosting (v3.1.0-dev)\n\n**Version:** 3.1.0-dev\n**Feature:** Bootstrap Skill (Dogfooding)\n**Status"
},
{
"path": "docs/features/BOOTSTRAP_SKILL_TECHNICAL.md",
"chars": 17368,
"preview": "# Bootstrap Skill - Technical Deep Dive\n\n**Version:** 3.1.0-dev\n**Feature:** Bootstrap Skill Technical Analysis\n**Status"
},
{
"path": "docs/features/ENHANCEMENT.md",
"chars": 9029,
"preview": "# AI-Powered SKILL.md Enhancement\n\nTwo scripts are available to dramatically improve your SKILL.md file:\n1. **`enhance_s"
},
{
"path": "docs/features/ENHANCEMENT_MODES.md",
"chars": 13806,
"preview": "# Enhancement Modes Guide\n\nComplete guide to all LOCAL enhancement modes in Skill Seekers.\n\n## Overview\n\nSkill Seekers s"
},
{
"path": "docs/features/HOW_TO_GUIDES.md",
"chars": 33150,
"preview": "# How-To Guide Generation (C3.3)\n\n**Transform test workflows into step-by-step educational guides**\n\n## Overview\n\nThe Ho"
},
{
"path": "docs/features/PATTERN_DETECTION.md",
"chars": 13071,
"preview": "# Design Pattern Detection Guide\n\n**Feature**: C3.1 - Detect common design patterns in codebases\n**Version**: 2.6.0+\n**S"
},
{
"path": "docs/features/PDF_ADVANCED_FEATURES.md",
"chars": 13382,
"preview": "# PDF Advanced Features Guide\n\nComprehensive guide to advanced PDF extraction features (Priority 2 & 3).\n\n## Overview\n\nS"
},
{
"path": "docs/features/PDF_CHUNKING.md",
"chars": 13223,
"preview": "# PDF Page Detection and Chunking (Task B1.3)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Task:** B1.3 - Add P"
},
{
"path": "docs/features/PDF_MCP_TOOL.md",
"chars": 10312,
"preview": "# PDF Scraping MCP Tool (Task B1.7)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Task:** B1.7 - Add MCP tool `s"
},
{
"path": "docs/features/PDF_SCRAPER.md",
"chars": 13569,
"preview": "# PDF Scraper CLI Tool (Tasks B1.6 + B1.8)\n\n**Status:** ✅ Completed\n**Date:** October 21, 2025\n**Tasks:** B1.6 - Create "
},
{
"path": "docs/features/TEST_EXAMPLE_EXTRACTION.md",
"chars": 11482,
"preview": "# Test Example Extraction (C3.2)\n\n**Transform test files into documentation assets by extracting real API usage patterns"
},
{
"path": "docs/features/UNIFIED_SCRAPING.md",
"chars": 22829,
"preview": "# Unified Multi-Source Scraping\n\n**Version:** 3.2.0 (17 source types supported)\n\n## Overview\n\nUnified multi-source scrap"
},
{
"path": "docs/getting-started/01-installation.md",
"chars": 7264,
"preview": "# Installation Guide\n\n> **Skill Seekers v3.2.0**\n\nGet Skill Seekers installed and running in under 5 minutes.\n\n---\n\n## S"
},
{
"path": "docs/getting-started/02-quick-start.md",
"chars": 8095,
"preview": "# Quick Start Guide\n\n> **Skill Seekers v3.2.0** \n> **Create your first skill in 3 commands**\n\n---\n\n## The 3 Commands\n\n`"
},
{
"path": "docs/getting-started/03-your-first-skill.md",
"chars": 7988,
"preview": "# Your First Skill - Complete Walkthrough\n\n> **Skill Seekers v3.1.0** \n> **Step-by-step guide to creating your first sk"
},
{
"path": "docs/getting-started/04-next-steps.md",
"chars": 7392,
"preview": "# Next Steps\n\n> **Skill Seekers v3.1.0** \n> **Where to go after creating your first skill**\n\n---\n\n## You've Created You"
},
{
"path": "docs/guides/HTTP_TRANSPORT.md",
"chars": 6996,
"preview": "# HTTP Transport for FastMCP Server\n\nThe Skill Seeker MCP server now supports both **stdio** (default) and **HTTP** tran"
},
{
"path": "docs/guides/MCP_SETUP.md",
"chars": 33016,
"preview": "# Complete MCP Setup Guide - MCP 2025 (v2.7.0)\n\nStep-by-step guide to set up the Skill Seeker MCP server with 5 supporte"
},
{
"path": "docs/guides/MIGRATION_GUIDE.md",
"chars": 12464,
"preview": "# Migration Guide\n\n**Version:** 3.1.0-dev\n**Last Updated:** 2026-02-18\n**Status:** ✅ Production Ready\n\n---\n\n## Overview\n"
},
{
"path": "docs/guides/MULTI_AGENT_SETUP.md",
"chars": 14503,
"preview": "# Multi-Agent Auto-Configuration Guide\n\nThe Skill Seeker MCP server now supports automatic detection and configuration o"
},
{
"path": "docs/guides/SETUP_QUICK_REFERENCE.md",
"chars": 7157,
"preview": "# Setup Quick Reference Card\n\n## One-Command Setup\n\n```bash\n./setup_mcp.sh\n```\n\n## What Gets Configured\n\n| Agent | Trans"
},
{
"path": "docs/guides/TESTING_GUIDE.md",
"chars": 21759,
"preview": "# Testing Guide\n\n**Version:** 3.1.0-dev\n**Last Updated:** 2026-02-18\n**Test Count:** 1,880+ tests\n**Coverage:** >85%\n**S"
},
{
"path": "docs/guides/UPLOAD_GUIDE.md",
"chars": 10629,
"preview": "# Multi-Platform Upload Guide\n\nSkill Seekers supports uploading to **4 LLM platforms**: Claude AI, Google Gemini, OpenAI"
},
{
"path": "docs/integrations/CHROMA.md",
"chars": 25260,
"preview": "# Chroma Integration with Skill Seekers\n\n**Status:** ✅ Production Ready\n**Difficulty:** Beginner\n**Last Updated:** Febru"
},
{
"path": "docs/integrations/CLINE.md",
"chars": 23966,
"preview": "# Using Skill Seekers with Cline (VS Code Extension)\n\n**Last Updated:** February 7, 2026\n**Status:** Production Ready\n**"
},
{
"path": "docs/integrations/CONTINUE_DEV.md",
"chars": 24627,
"preview": "# Using Skill Seekers with Continue.dev\n\n**Last Updated:** February 7, 2026\n**Status:** Production Ready\n**Difficulty:**"
},
{
"path": "docs/integrations/CURSOR.md",
"chars": 16898,
"preview": "# Using Skill Seekers with Cursor IDE\n\n**Last Updated:** February 5, 2026\n**Status:** Production Ready\n**Difficulty:** E"
},
{
"path": "docs/integrations/FAISS.md",
"chars": 14921,
"preview": "# FAISS Integration with Skill Seekers\n\n**Status:** ✅ Production Ready\n**Difficulty:** Intermediate\n**Last Updated:** Fe"
},
{
"path": "docs/integrations/GEMINI_INTEGRATION.md",
"chars": 9595,
"preview": "# Google Gemini Integration Guide\n\nComplete guide for creating and deploying skills to Google Gemini using Skill Seekers"
},
{
"path": "docs/integrations/HAYSTACK.md",
"chars": 21139,
"preview": "# Using Skill Seekers with Haystack\n\n**Last Updated:** February 7, 2026\n**Status:** Production Ready\n**Difficulty:** Eas"
},
{
"path": "docs/integrations/INTEGRATIONS.md",
"chars": 18360,
"preview": "# AI System Integrations with Skill Seekers\n\n**Universal Preprocessor:** Transform documentation into structured knowled"
},
{
"path": "docs/integrations/LANGCHAIN.md",
"chars": 12936,
"preview": "# Using Skill Seekers with LangChain\n\n**Last Updated:** February 5, 2026\n**Status:** Production Ready\n**Difficulty:** Ea"
},
{
"path": "docs/integrations/LLAMA_INDEX.md",
"chars": 12406,
"preview": "# Using Skill Seekers with LlamaIndex\n\n**Last Updated:** February 5, 2026\n**Status:** Production Ready\n**Difficulty:** E"
},
{
"path": "docs/integrations/MINIMAX_INTEGRATION.md",
"chars": 9197,
"preview": "# MiniMax AI Integration Guide\n\nComplete guide for using Skill Seekers with MiniMax AI platform.\n\n---\n\n## Overview\n\n**Mi"
},
{
"path": "docs/integrations/MULTI_LLM_SUPPORT.md",
"chars": 11200,
"preview": "# Multi-LLM Platform Support Guide\n\nSkill Seekers supports multiple LLM platforms through a clean adaptor system. The co"
},
{
"path": "docs/integrations/OPENAI_INTEGRATION.md",
"chars": 11778,
"preview": "# OpenAI ChatGPT Integration Guide\n\nComplete guide for creating and deploying skills to OpenAI ChatGPT using Skill Seeke"
},
{
"path": "docs/integrations/PINECONE.md",
"chars": 21281,
"preview": "# Using Skill Seekers with Pinecone\n\n**Last Updated:** February 5, 2026\n**Status:** Production Ready\n**Difficulty:** Eas"
},
{
"path": "docs/integrations/QDRANT.md",
"chars": 23246,
"preview": "# Qdrant Integration with Skill Seekers\n\n**Status:** ✅ Production Ready\n**Difficulty:** Intermediate\n**Last Updated:** F"
},
{
"path": "docs/integrations/RAG_PIPELINES.md",
"chars": 27871,
"preview": "# Building RAG Pipelines with Skill Seekers\n\n**Last Updated:** February 5, 2026\n**Status:** Production Ready\n**Difficult"
},
{
"path": "docs/integrations/WEAVIATE.md",
"chars": 26555,
"preview": "# Weaviate Integration with Skill Seekers\n\n**Status:** ✅ Production Ready\n**Difficulty:** Intermediate\n**Last Updated:**"
},
{
"path": "docs/integrations/WINDSURF.md",
"chars": 22951,
"preview": "# Using Skill Seekers with Windsurf IDE\n\n**Last Updated:** February 7, 2026\n**Status:** Production Ready\n**Difficulty:**"
},
{
"path": "docs/plans/video/00_VIDEO_SOURCE_OVERVIEW.md",
"chars": 11994,
"preview": "# Video Source Support — Master Plan\n\n**Date:** February 27, 2026\n**Feature ID:** V1.0\n**Status:** Planning\n**Priority:*"
},
{
"path": "docs/plans/video/01_VIDEO_RESEARCH.md",
"chars": 23415,
"preview": "# Video Source — Library Research & Industry Standards\n\n**Date:** February 27, 2026\n**Document:** 01 of 07\n**Status:** C"
},
{
"path": "docs/plans/video/02_VIDEO_DATA_MODELS.md",
"chars": 30140,
"preview": "# Video Source — Data Models & Type Definitions\n\n**Date:** February 27, 2026\n**Document:** 02 of 07\n**Status:** Planning"
},
{
"path": "docs/plans/video/03_VIDEO_PIPELINE.md",
"chars": 36713,
"preview": "# Video Source — Processing Pipeline\n\n**Date:** February 27, 2026\n**Document:** 03 of 07\n**Status:** Planning\n\n---\n\n## T"
},
{
"path": "docs/plans/video/04_VIDEO_INTEGRATION.md",
"chars": 26106,
"preview": "# Video Source — System Integration\n\n**Date:** February 27, 2026\n**Document:** 04 of 07\n**Status:** Planning\n\n---\n\n## Ta"
},
{
"path": "docs/plans/video/05_VIDEO_OUTPUT.md",
"chars": 16770,
"preview": "# Video Source — Output Structure & SKILL.md Integration\n\n**Date:** February 27, 2026\n**Document:** 05 of 07\n**Status:**"
},
{
"path": "docs/plans/video/06_VIDEO_TESTING.md",
"chars": 23897,
"preview": "# Video Source — Testing Strategy\n\n**Date:** February 27, 2026\n**Document:** 06 of 07\n**Status:** Planning\n\n---\n\n## Tabl"
},
{
"path": "docs/plans/video/07_VIDEO_DEPENDENCIES.md",
"chars": 13354,
"preview": "# Video Source — Dependencies & System Requirements\n\n**Date:** February 27, 2026\n**Document:** 07 of 07\n**Status:** Plan"
},
{
"path": "docs/reference/AI_SKILL_STANDARDS.md",
"chars": 27403,
"preview": "# AI Skill Standards & Best Practices (2026)\n\n**Version:** 1.0\n**Last Updated:** 2026-01-11\n**Scope:** Cross-platform AI"
},
{
"path": "docs/reference/API_REFERENCE.md",
"chars": 25622,
"preview": "# API Reference - Programmatic Usage\n\n**Version:** 3.2.0\n**Last Updated:** 2026-03-15\n**Status:** ✅ Production Ready\n\n--"
},
{
"path": "docs/reference/C3_x_Router_Architecture.md",
"chars": 68855,
"preview": "# C3.x Router Architecture - Ultra-Detailed Technical Specification\n\n**Created:** 2026-01-08\n**Last Updated:** 2026-01-0"
},
{
"path": "docs/reference/CLAUDE_INTEGRATION.md",
"chars": 20190,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "docs/reference/CLI_REFERENCE.md",
"chars": 41187,
"preview": "# CLI Reference - Skill Seekers\n\n> **Version:** 3.2.0\n> **Last Updated:** 2026-03-15\n> **Complete reference for all 30 C"
},
{
"path": "docs/reference/CODE_QUALITY.md",
"chars": 16366,
"preview": "# Code Quality Standards\n\n**Version:** 3.1.0-dev\n**Last Updated:** 2026-02-18\n**Status:** ✅ Production Ready\n\n---\n\n## Ov"
},
{
"path": "docs/reference/CONFIG_FORMAT.md",
"chars": 20674,
"preview": "# Config Format Reference - Skill Seekers\n\n> **Version:** 3.2.0\n> **Last Updated:** 2026-03-15\n> **Complete JSON configu"
},
{
"path": "docs/reference/ENVIRONMENT_VARIABLES.md",
"chars": 12241,
"preview": "# Environment Variables Reference - Skill Seekers\n\n> **Version:** 3.1.0 \n> **Last Updated:** 2026-02-16 \n> **Complete "
},
{
"path": "docs/reference/FEATURE_MATRIX.md",
"chars": 13610,
"preview": "# Skill Seekers Feature Matrix\n\nComplete feature support across all platforms and skill modes.\n\n## Platform Support\n\n| P"
},
{
"path": "docs/reference/GIT_CONFIG_SOURCES.md",
"chars": 20245,
"preview": "# Git-Based Config Sources - Complete Guide\n\n**Version:** v2.2.0\n**Feature:** A1.9 - Multi-Source Git Repository Support"
},
{
"path": "docs/reference/LARGE_DOCUMENTATION.md",
"chars": 9701,
"preview": "# Handling Large Documentation Sites (10K+ Pages)\n\nComplete guide for scraping and managing large documentation sites wi"
},
{
"path": "docs/reference/LLMS_TXT_SUPPORT.md",
"chars": 1391,
"preview": "# llms.txt Support\n\n## Overview\n\nSkill_Seekers now automatically detects and uses llms.txt files when available, providi"
},
{
"path": "docs/reference/MCP_REFERENCE.md",
"chars": 24089,
"preview": "# MCP Reference - Skill Seekers\n\n> **Version:** 3.2.0 \n> **Last Updated:** 2026-03-15 \n> **Complete reference for 27 M"
},
{
"path": "docs/reference/SKILL_ARCHITECTURE.md",
"chars": 23399,
"preview": "# Skill Architecture Guide: Layering and Splitting\n\nComplete guide for architecting complex multi-skill systems using th"
},
{
"path": "docs/roadmap/INTELLIGENCE_SYSTEM_ARCHITECTURE.md",
"chars": 37694,
"preview": "# Skill Seekers Intelligence System - Technical Architecture\n\n**Version:** 1.0 (Draft)\n**Status:** 🔬 Research & Design\n*"
},
{
"path": "docs/roadmap/INTELLIGENCE_SYSTEM_RESEARCH.md",
"chars": 19492,
"preview": "# Skill Seekers Intelligence System - Research Topics\n\n**Version:** 1.0\n**Status:** 🔬 Research Phase\n**Last Updated:** 2"
},
{
"path": "docs/roadmap/README.md",
"chars": 9166,
"preview": "# Skill Seekers Intelligence System - Documentation Index\n\n**Status:** 🔬 Research & Design Phase\n**Last Updated:** 2026-"
},
{
"path": "docs/roadmap/SKILL_INTELLIGENCE_SYSTEM.md",
"chars": 27640,
"preview": "# Skill Seekers Intelligence System - Roadmap\n\n**Status:** 🔬 Research & Design Phase\n**Target:** Open Source, Individual"
},
{
"path": "docs/strategy/ACTION_PLAN.md",
"chars": 24504,
"preview": "# Action Plan: Hybrid Universal Infrastructure Strategy\n\n**Start Date:** February 2, 2026\n**Timeline:** 4 weeks\n**Strate"
},
{
"path": "docs/strategy/ARBITRARY_LIMITS_AND_DEAD_CODE_PLAN.md",
"chars": 13205,
"preview": "# Implementation Plan: Arbitrary Limits & Dead Code\n\n**Generated:** 2026-02-24 \n**Scope:** Remove harmful arbitrary lim"
},
{
"path": "docs/strategy/DEEPWIKI_ANALYSIS.md",
"chars": 10539,
"preview": "# DeepWiki-open Article Analysis\n\n**Article URL:** https://www.2090ai.com/qoder/11522.html\n**Date Analyzed:** February 2"
},
{
"path": "docs/strategy/INTEGRATION_STRATEGY.md",
"chars": 13855,
"preview": "# Integration Strategy: Positioning Skill Seekers as Essential Infrastructure\n\n**Date:** February 2, 2026\n**Status:** St"
},
{
"path": "docs/strategy/INTEGRATION_TEMPLATES.md",
"chars": 13867,
"preview": "# Integration Guide Templates\n\n**Purpose:** Reusable templates for creating integration guides with other tools\n**Date:*"
},
{
"path": "docs/strategy/KIMI_ANALYSIS_COMPARISON.md",
"chars": 15608,
"preview": "# Kimi's Vision Analysis & Synthesis\n\n**Date:** February 2, 2026\n**Purpose:** Compare Kimi's broader infrastructure visi"
},
{
"path": "docs/strategy/README.md",
"chars": 8264,
"preview": "# Integration Strategy Documentation\n\n**Purpose:** Complete strategy for positioning Skill Seekers as essential infrastr"
},
{
"path": "docs/strategy/STAGE_1_CORRECTED_IMPLEMENTATION.md",
"chars": 4689,
"preview": "# Stage 1 Implementation: CORRECTED\n\n**Review Date:** 2026-02-24 \n**Status:** ✅ All issues fixed and verified\n\n---\n\n## "
},
{
"path": "docs/strategy/STAGE_1_IMPLEMENTATION_SUMMARY.md",
"chars": 4944,
"preview": "# Stage 1 Implementation Summary\n\n**Completed:** 2026-02-24 \n**Status:** ✅ All tasks completed, all tests passing\n\n---\n"
},
{
"path": "docs/strategy/STAGE_1_REVIEW_AND_VERIFICATION.md",
"chars": 8129,
"preview": "# Stage 1 Implementation: Comprehensive Review\n\n**Review Date:** 2026-02-24 \n**Status:** ✅ All changes verified and tes"
},
{
"path": "docs/user-guide/01-core-concepts.md",
"chars": 10875,
"preview": "# Core Concepts\n\n> **Skill Seekers v3.2.0** \n> **Understanding how Skill Seekers works**\n\n---\n\n## Overview\n\nSkill Seeke"
},
{
"path": "docs/user-guide/02-scraping.md",
"chars": 13889,
"preview": "# Scraping Guide\n\n> **Skill Seekers v3.2.0**\n> **Complete guide to all scraping options**\n\n---\n\n## Overview\n\nSkill Seeke"
},
{
"path": "docs/user-guide/03-enhancement.md",
"chars": 8643,
"preview": "# Enhancement Guide\n\n> **Skill Seekers v3.1.0** \n> **AI-powered quality improvement for skills**\n\n---\n\n## What is Enhan"
},
{
"path": "docs/user-guide/04-packaging.md",
"chars": 10226,
"preview": "# Packaging Guide\n\n> **Skill Seekers v3.2.0** \n> **Export skills to AI platforms and vector databases**\n\n---\n\n## Overvi"
},
{
"path": "docs/user-guide/05-workflows.md",
"chars": 13906,
"preview": "# Workflows Guide\n\n> **Skill Seekers v3.2.0** \n> **Enhancement workflow presets for specialized analysis**\n\n---\n\n## Wha"
},
{
"path": "docs/user-guide/06-troubleshooting.md",
"chars": 9907,
"preview": "# Troubleshooting Guide\n\n> **Skill Seekers v3.1.0** \n> **Common issues and solutions**\n\n---\n\n## Quick Fixes\n\n| Issue | "
},
{
"path": "docs/zh-CN/ARCHITECTURE.md",
"chars": 5390,
"preview": "# Documentation Architecture\n\n> **How Skill Seekers documentation is organized**\n\n---\n\n## Philosophy\n\nOur documentation "
},
{
"path": "docs/zh-CN/README.md",
"chars": 5701,
"preview": "# Skill Seekers Documentation\n\n> **Complete documentation for Skill Seekers v3.2.0**\n\n---\n\n## Welcome!\n\nThis is the offi"
},
{
"path": "docs/zh-CN/advanced/custom-workflows.md",
"chars": 7202,
"preview": "# Custom Workflows Guide\n\n> **Skill Seekers v3.1.0** \n> **Create custom AI enhancement workflows**\n\n---\n\n## What are Cu"
},
{
"path": "docs/zh-CN/advanced/mcp-server.md",
"chars": 6624,
"preview": "# MCP Server Setup Guide\n\n> **Skill Seekers v3.2.0** \n> **通过 Model Context Protocol 与 AI 代理集成**\n\n---\n\n## What is MCP?\n\n"
},
{
"path": "docs/zh-CN/advanced/multi-source.md",
"chars": 7977,
"preview": "# Multi-Source Scraping Guide\n\n> **Skill Seekers v3.1.0** \n> **Combine documentation, code, and PDFs into one skill**\n\n"
},
{
"path": "docs/zh-CN/getting-started/01-installation.md",
"chars": 6673,
"preview": "# Installation Guide\n\n> **Skill Seekers v3.2.0**\n\nGet Skill Seekers installed and running in under 5 minutes.\n\n---\n\n## S"
},
{
"path": "docs/zh-CN/getting-started/02-quick-start.md",
"chars": 7906,
"preview": "# Quick Start Guide\n\n> **Skill Seekers v3.2.0** \n> **Create your first skill in 3 commands**\n\n---\n\n## The 3 Commands\n\n`"
},
{
"path": "docs/zh-CN/getting-started/03-your-first-skill.md",
"chars": 7988,
"preview": "# Your First Skill - Complete Walkthrough\n\n> **Skill Seekers v3.1.0** \n> **Step-by-step guide to creating your first sk"
},
{
"path": "docs/zh-CN/getting-started/04-next-steps.md",
"chars": 7392,
"preview": "# Next Steps\n\n> **Skill Seekers v3.1.0** \n> **Where to go after creating your first skill**\n\n---\n\n## You've Created You"
},
{
"path": "docs/zh-CN/reference/AI_SKILL_STANDARDS.md",
"chars": 27403,
"preview": "# AI Skill Standards & Best Practices (2026)\n\n**Version:** 1.0\n**Last Updated:** 2026-01-11\n**Scope:** Cross-platform AI"
},
{
"path": "docs/zh-CN/reference/API_REFERENCE.md",
"chars": 23447,
"preview": "# API Reference - Programmatic Usage\n\n**Version:** 3.1.0-dev\n**Last Updated:** 2026-02-18\n**Status:** ✅ Production Ready"
}
]
// ... and 522 more files (download for full content)
About this extraction
This page contains the full source code of the yusufkaraaslan/Skill_Seekers GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 722 files (9.0 MB), approximately 2.4M tokens, and a symbol index with 6455 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.