Commit Graph

256 Commits

Author SHA1 Message Date
yusyus
6d37e43b83 feat: Grand Unification — one command, one interface, direct converters (#346)
* fix: resolve 8 pipeline bugs found during skill quality review

- Fix 0 APIs extracted from documentation by enriching summary.json
  with individual page file content before conflict detection
- Fix all "Unknown" entries in merged_api.md by injecting dict keys
  as API names and falling back to AI merger field names
- Fix frontmatter using raw slugs instead of config name by
  normalizing frontmatter after SKILL.md generation
- Fix leaked absolute filesystem paths in patterns/index.md by
  stripping .skillseeker-cache repo clone prefixes
- Fix ARCHITECTURE.md file count always showing "1 files" by
  counting files per language from code_analysis data
- Fix YAML parse errors on GitHub Actions workflows by converting
  boolean keys (on: true) to strings
- Fix false React/Vue.js framework detection in C# projects by
  filtering web frameworks based on primary language
- Improve how-to guide generation by broadening workflow example
  filter to include setup/config examples with sufficient complexity
- Fix test_git_sources_e2e failures caused by git init default
  branch being 'main' instead of 'master'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address 6 review issues in ExecutionContext implementation

Fixes from code review:

1. Mode resolution (#3 critical): _args_to_data no longer unconditionally
   overwrites mode. Only writes mode="api" when --api-key explicitly passed.
   Env-var-based mode detection moved to _default_data() as lowest priority.

2. Re-initialization warning (#4): initialize() now logs debug message
   when called a second time instead of silently returning stale instance.

3. _raw_args preserved in override (#5): temp context now copies _raw_args
   from parent so get_raw() works correctly inside override blocks.

4. test_local_mode_detection env cleanup (#7): test now saves/restores
   API key env vars to prevent failures when ANTHROPIC_API_KEY is set.

5. _load_config_file error handling (#8): wraps FileNotFoundError and
   JSONDecodeError with user-friendly ValueError messages.

6. Lint fixes: added logging import, fixed Generator import from
   collections.abc, fixed AgentClient return type annotation.

Remaining P2/P3 items (documented, not blocking):
- Lock TOCTOU in override() — safe on CPython, needs fix for no-GIL
- get() reads _instance without lock — same CPython caveat
- config_path not stored on instance
- AnalysisSettings.depth not Literal constrained

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address all remaining P2/P3 review issues in ExecutionContext

1. Thread safety: get() now acquires _lock before reading _instance (#2)
2. Thread safety: override() saves/restores _initialized flag to prevent
   re-init during override blocks (#10)
3. Config path stored: _config_path PrivateAttr + config_path property (#6)
4. Literal validation: AnalysisSettings.depth now uses
   Literal["surface", "deep", "full"] — rejects invalid values (#9)
5. Test updated: test_analysis_depth_choices now expects ValidationError
   for invalid depth, added test_analysis_depth_valid_choices
6. Lint cleanup: removed unused imports, fixed whitespace in tests

All 10 previously reported issues now resolved.
26 tests pass, lint clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: restore 5 truncated scrapers, migrate unified_scraper, fix context init

5 scrapers had main() truncated with "# Original main continues here..."
after Kimi's migration — business logic was never connected:
- html_scraper.py — restored HtmlToSkillConverter extraction + build
- pptx_scraper.py — restored PptxToSkillConverter extraction + build
- confluence_scraper.py — restored ConfluenceToSkillConverter with 3 modes
- notion_scraper.py — restored NotionToSkillConverter with 4 sources
- chat_scraper.py — restored ChatToSkillConverter extraction + build

unified_scraper.py — migrated main() to context-first pattern with argv fallback

Fixed context initialization chain:
- main.py no longer initializes ExecutionContext (was stealing init from commands)
- create_command.py now passes config_path from source_info.parsed
- execution_context.py handles SourceInfo.raw_input (not raw_source)

All 18 scrapers now genuinely migrated. 26 tests pass, lint clean.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve 7 data flow conflicts between ExecutionContext and legacy paths

Critical fixes (CLI args silently lost):
- unified_scraper Phase 6: reads ctx.enhancement.level instead of raw JSON
  when args=None (#3, #4)
- unified_scraper Phase 6 agent: reads ctx.enhancement.agent instead of
  3 independent env var lookups (#5)
- doc_scraper._run_enhancement: uses agent_client.api_key instead of raw
  os.environ.get() — respects config file api_key (#1)

Important fixes:
- main._handle_analyze_command: populates _fake_args from ExecutionContext
  so --agent and --api-key aren't lost in analyze→enhance path (#6)
- doc_scraper type annotations: replaced forward refs with Any to avoid
  F821 undefined name errors

All changes include RuntimeError fallback for backward compatibility when
ExecutionContext isn't initialized.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: 3 crashes + 1 stub in migrated scrapers found by deep scan

1. github_scraper.py: args.scrape_only and args.enhance_level crash when
   args=None (context path). Guarded with if args and getattr(). Also
   fixed agent fallback to read ctx.enhancement.agent.

2. codebase_scraper.py: args.output and args.skip_api_reference crash in
   summary block when args=None. Replaced with output_dir local var and
   ctx.analysis.skip_api_reference.

3. epub_scraper.py: main() was still a stub ending with "# Rest of main()
   continues..." — restored full extraction + build + enhancement logic
   using ctx values exclusively.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: complete ExecutionContext migration for remaining scrapers

Kimi's Phase 4 scraper migrations + Claude's review fixes.
All 18 scrapers now use context-first pattern with argv fallback.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Phase 1 — ExecutionContext.get() always returns context (no RuntimeError)

get() now returns a default context instead of raising RuntimeError when
not explicitly initialized. This eliminates the need for try/except
RuntimeError blocks in all 18 scrapers.

Components can always call ExecutionContext.get() safely — it returns
defaults if not initialized, or the explicitly initialized instance.

Updated tests: test_get_returns_defaults_when_not_initialized,
test_reset_clears_instance (no longer expects RuntimeError).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Phase 2a-c — remove 16 individual scraper CLI commands

Removed individual scraper commands from:
- COMMAND_MODULES in main.py (16 entries: scrape, github, pdf, word,
  epub, video, jupyter, html, openapi, asciidoc, pptx, rss, manpage,
  confluence, notion, chat)
- pyproject.toml entry points (16 skill-seekers-<type> binaries)
- parsers/__init__.py (16 parser registrations)

All source types now accessed via: skill-seekers create <source>
Kept: create, unified, analyze, enhance, package, upload, install,
      install-agent, config, doctor, and utility commands.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: create SkillConverter base class + converter registry

New base interface that all 17 converters will inherit:
- SkillConverter.run() — extract + build (same call for all types)
- SkillConverter.extract() — override in subclass
- SkillConverter.build_skill() — override in subclass
- get_converter(source_type, config) — factory from registry
- CONVERTER_REGISTRY — maps source type → (module, class)

create_command will use get_converter() instead of _call_module().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Grand Unification — one command, one interface, direct converters

Complete the Grand Unification refactor: `skill-seekers create` is now
the single entry point for all 18 source types. Individual scraper CLI
commands (scrape, github, pdf, analyze, unified, etc.) are removed.

## Architecture changes

- **18 SkillConverter subclasses**: Every scraper now inherits SkillConverter
  with extract() + build_skill() + SOURCE_TYPE. Factory via get_converter().
- **create_command.py rewritten**: _build_config() constructs config dicts
  from ExecutionContext for each source type. Direct converter.run() calls
  replace the old _build_argv() + sys.argv swap + _call_module() machinery.
- **main.py simplified**: create command bypasses _reconstruct_argv entirely,
  calls CreateCommand(args).execute() directly. analyze/unified commands
  removed (create handles both via auto-detection).
- **CreateParser mode="all"**: Top-level parser now accepts all 120+ flags
  (--browser, --max-pages, --depth, etc.) since create is the only entry.
- **Centralized enhancement**: Runs once in create_command after converter,
  not duplicated in each scraper.
- **MCP tools use converters**: 5 scraping tools call get_converter()
  directly instead of subprocess. Config type auto-detected from keys.
- **ConfigValidator → UniSkillConfigValidator**: Renamed with backward-
  compat alias.
- **Data flow**: AgentClient + LocalSkillEnhancer read ExecutionContext
  first, env vars as fallback.

## What was removed

- main() from all 18 scraper files (~3400 lines)
- 18 CLI commands from COMMAND_MODULES + pyproject.toml entry points
- analyze + unified parsers from parser registry
- _build_argv, _call_module, _SKIP_ARGS, _DEST_TO_FLAG, all _route_*()
- setup_argument_parser, get_configuration, _check_deprecated_flags
- Tests referencing removed commands/functions

## Net impact

51 files changed, ~6000 lines removed. 2996 tests pass, 0 failures.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: review fixes for Grand Unification PR

- Add autouse conftest fixture to reset ExecutionContext singleton between tests
- Replace hardcoded defaults in _is_explicitly_set() with parser-derived defaults
- Upgrade ExecutionContext double-init log from debug to info
- Use logger.exception() in SkillConverter.run() to preserve tracebacks
- Fix docstring "17 types" → "18 types" in skill_converter.py
- DRY up 10 copy-paste help handlers into dict + loop (~100 lines removed)
- Fix 2 CI workflows still referencing removed `skill-seekers scrape` command
- Remove broken pyproject.toml entry point for codebase_scraper:main

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve 12 logic/flow issues found in deep review

Critical fixes:
- UnifiedScraper.run(): replace sys.exit(1) with return 1, add return 0
- doc_scraper: use ExecutionContext.get() when already initialized instead
  of re-calling initialize() which silently discards new config
- unified_scraper: define enhancement_config before try/except to prevent
  UnboundLocalError in LOCAL enhancement timeout read

Important fixes:
- override(): cleaner tuple save/restore for singleton swap
- --agent without --api-key now sets mode="local" so env API key doesn't
  override explicit agent choice
- Remove DeprecationWarning from _reconstruct_argv (fires on every
  non-create command in production)
- Rewrite scrape_generic_tool to use get_converter() instead of subprocess
  calls to removed main() functions
- SkillConverter.run() checks build_skill() return value, returns 1 if False
- estimate_pages_tool uses -m module invocation instead of .py file path

Low-priority fixes:
- get_converter() raises descriptive ValueError on class name typo
- test_default_values: save/clear API key env vars before asserting mode
- test_get_converter_pdf: fix config key "path" → "pdf_path"

3056 passed, 4 failed (pre-existing dep version issues), 32 skipped.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update MCP server tests to mock converter instead of subprocess

scrape_docs_tool now uses get_converter() + _run_converter() in-process
instead of run_subprocess_with_streaming. Update 4 TestScrapeDocsTool
tests to mock the converter layer instead of the removed subprocess path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: YusufKaraaslanSpyke <yusuf@spykegames.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-05 23:00:52 +03:00
yusyus
c6a6db01bf feat: agent-agnostic refactor, smart SPA discovery, marketplace pipeline (#336)
* feat: fix unified scraper pipeline gaps, add multi-agent support, and Unity skill configs

Fix multiple bugs in the unified scraper pipeline discovered while creating Unity skills
(Spine, Addressables, DOTween):

- Fix doc scraper KeyError by passing base_url in temp config
- Fix scraped_data list-vs-dict bug in detect_conflicts() and merge_sources()
- Add Phase 6 auto-enhancement from config "enhancement" block (LOCAL + API mode)
- Add "browser": true config support for JavaScript SPA documentation sites
- Add Phase 3 skip message for better UX
- Add subprocess timeout (3600s) for doc scraper
- Fix SkillEnhancer missing skill_dir argument in API mode
- Fix browser renderer defaults (60s timeout, domcontentloaded wait condition)
- Fix C3.x JSON filename mismatch (design_patterns.json → all_patterns.json)
- Fix workflow builtin target handling when no pattern data available
- Make AI enhancement timeout configurable via SKILL_SEEKER_ENHANCE_TIMEOUT env var (300s default)
- Add C#, Go, Rust, Swift, Ruby, PHP, GDScript to GitHub scraper extension map
- Add multi-agent LOCAL mode support across all 17 scrapers (--agent flag)
- Add Kimi/Moonshot platform support (API keys, agent presets, config wizard)
- Add unity-game-dev.yaml workflow (7 stages covering Unity-specific patterns)
- Add 3 Unity skill configs (Spine, Addressables, DOTween)
- Add comprehensive Claude bias audit report

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: create AgentClient abstraction, remove hardcoded Claude from 5 enhancers (#334)

Phase 1 of the full agent-agnostic refactor. Creates a centralized AgentClient
that all enhancers use instead of hardcoded subprocess calls and model names.

New file:
- agent_client.py: Unified AI client supporting API mode (Anthropic, Moonshot,
  Google, OpenAI) and LOCAL mode (Claude Code, Kimi, Codex, Copilot, OpenCode,
  custom agents). Provides detect_api_key(), get_model(), detect_default_target().

Refactored (removed all hardcoded ["claude", ...] subprocess calls):
- ai_enhancer.py: -140 lines, delegates to AgentClient
- config_enhancer.py: -150 lines, removed _run_claude_cli()
- guide_enhancer.py: -120 lines, removed _check_claude_cli(), _call_claude_*()
- unified_enhancer.py: -100 lines, removed _check_claude_cli(), _call_claude_*()
- codebase_scraper.py: collapsed 3 functions into 1 using AgentClient

Fixed:
- utils.py: has_api_key()/get_api_key() now check all providers
- enhance_skill.py, video_scraper.py, video_visual.py: model names configurable
  via ANTHROPIC_MODEL env var
- enhancement_workflow.py: uses call() with _call_claude() fallback

Net: -153 lines of code while adding full multi-agent support.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Phase 2 agent-agnostic refactor — defaults, help text, merge mode, MCP (#334)

Phase 2 of the full agent-agnostic refactor:

Default targets:
- Changed default="claude" to auto-detect from API keys in 5 argument files
  and 3 CLI scripts (install_skill, upload_skill, enhance_skill)
- Added AgentClient.detect_default_target() for runtime resolution
- MCP server functions now use "auto" default with runtime detection

Help text (16+ argument files):
- Replaced "ANTHROPIC_API_KEY" / "Claude Code" with agent-neutral wording
- Now mentions all API keys (ANTHROPIC, MOONSHOT, etc.) and "AI coding agent"

Log messages:
- main.py, enhance_command.py: "Claude Code CLI" → dynamic agent name
- enhance_command.py docstring: "Claude Code" → "AI coding agent"

Merge mode rename:
- Added "ai-enhanced" as the preferred merge mode name
- "claude-enhanced" kept as backward-compatible alias
- Renamed ClaudeEnhancedMerger → AIEnhancedMerger (with alias)
- Updated choices, validators, and descriptions

MCP server descriptions:
- server_fastmcp.py: "Claude AI skills" → "LLM skills" in tool descriptions
- packaging_tools.py: Updated defaults and dry-run messages

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Phase 3 agent-agnostic refactor — docstrings, MCP descriptions, README (#334)

Phase 3 of the full agent-agnostic refactor:

Module docstrings (17+ scraper files):
- "Claude Skill Converter" → "AI Skill Converter"
- "Build Claude skill" → "Build AI/LLM skill"
- "Asking Claude" → "Asking AI"
- Updated doc_scraper, github_scraper, pdf_scraper, word_scraper,
  epub_scraper, video_scraper, enhance_skill, enhance_skill_local,
  unified_scraper, and others

MCP server_legacy.py (30+ fixes):
- All tool descriptions: "Claude skill" → "LLM skill"
- "Upload to Claude" → "Upload skill"
- "enhance with Claude Code" → "enhance with AI agent"
- Kept claude.ai/skills URLs (platform-specific, correct)

MCP README.md:
- Added multi-agent support note at top
- "Claude AI skills" → "LLM skills" throughout
- Updated examples to show multi-platform usage
- Kept Claude Code in supported agents list (accurate)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: Phase 3 continued — remaining docstring and comment fixes (#334)

Additional agent-neutral text fixes in 8 files missed from the initial
Phase 3 commit:
- config_extractor.py, config_manager.py, constants.py: comments
- enhance_command.py: docstring and print messages
- guide_enhancer.py: class/module docstrings
- parsers/enhance_parser.py, install_parser.py: help text
- signal_flow_analyzer.py: docstring

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* workflow added

* fix: address code review issues in AgentClient and Phase 6 (#334)

Fixes found during commit review:

1. AgentClient._call_local: Only append "Write your response to:" when
   caller explicitly passes output_file (was always appending)

2. Codex agent: Added uses_stdin flag to preset, pipe prompt via stdin
   instead of DEVNULL (codex reads from stdin with "-" arg)

3. Provider detection: Added _detect_provider_from_key() to detect
   provider from API key prefix (sk-ant- → anthropic, AIza → google)
   instead of always assuming anthropic

4. Phase 6 API mode: Replaced direct SkillEnhancer/ANTHROPIC_API_KEY
   with AgentClient for multi-provider support (Moonshot, Google, OpenAI)

5. config_enhancer: Removed output_file path from prompt — AgentClient
   manages temp files and output detection

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: make claude adaptor model name configurable via ANTHROPIC_MODEL env var

Missed in the Phase 1 refactor — adaptors/claude.py:381 had a hardcoded
model name without the os.environ.get() wrapper that all other files use.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add copilot stdin support, custom agent, and kimi aliases (#334)

Additional agent improvements from Kimi review:
- Added uses_stdin: True to copilot agent preset (reads from stdin like codex)
- Added custom agent support via SKILL_SEEKER_AGENT_CMD env var in _call_local()
- Added kimi_code/kimi-code aliases in normalize_agent_name()
- Added "kimi" to --target choices in enhance arguments
- Updated help text with MOONSHOT_API_KEY across argument files

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Kimi CLI integration — add uses_stdin and output parsing (#334)

Kimi CLI's --print mode requires stdin piping and outputs structured
protocol messages (TurnBegin, TextPart, etc.) instead of plain text.

Fixes:
- Added uses_stdin: True to kimi preset (was not piping prompt)
- Added parse_output: "kimi" flag to preset
- Added _parse_kimi_output() to extract text from TextPart lines
- Kimi now returns clean text instead of raw protocol dump

Tested: kimi returns '{"status": "ok"}' correctly via AgentClient.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: Kimi CLI in enhance_skill_local — remove wrong skip-permissions, use absolute path

Two bugs in enhance_skill_local.py AGENT_PRESETS for Kimi:
1. supports_skip_permissions was True — Kimi doesn't support
   --dangerously-skip-permissions, only Claude does. Fixed to False.
2. {skill_dir} was resolved as relative path — Kimi CLI requires
   absolute paths for --work-dir. Fixed with .resolve().

Tested: `skill-seekers enhance output/test-e2e/ --agent kimi`
now works end-to-end (107s, 9233 bytes output).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove invalid --enhance-level flag from enhance subprocess calls

doc_scraper.py and video_scraper.py were passing --enhance-level to
skill-seekers-enhance, which doesn't accept that flag. This caused
enhancement to fail silently after scraping completed.

Fixes:
- Removed --enhance-level from enhance subprocess calls
- Added --agent passthrough in doc_scraper.py
- Fixed log messages to show correct command

Tested: `skill-seekers create <url> --enhance-level 1` now chains
scrape → enhance successfully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add --agent and --agent-cmd to create command UNIVERSAL_ARGUMENTS

The --agent flag was defined in common.py but not imported into the
create command's UNIVERSAL_ARGUMENTS, so it wasn't available when using
`skill-seekers create <source> --agent kimi`. Now all 17 source types
support the --agent flag via the create command.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update docs data_file path after moving to cache directory

The scraped_data["documentation"] stored the original output/ path for
data_file, but the directory was moved to .skillseeker-cache/ afterward.
Phase 2 conflict detection then failed with FileNotFoundError trying to
read the old path.

Now updates data_file to point to the cache location after the move.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: multi-language code signature extraction in GitHub scraper

The GitHub scraper only analyzed files matching the primary language
(by bytes). For multi-language repos like spine-runtimes (C++ primary
but C# is the target), this meant 0 C# files were analyzed.

Fix: Analyze top 3 languages with known extension mappings instead of
just the primary. Also support "language" field in config source to
explicitly target specific languages (e.g., "language": "C#").

Updated Unity configs to specify language: "C#" for focused analysis.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: per-file language detection + remove artificial analysis limits

Rewrites GitHub scraper's _extract_signatures_and_tests() to detect
language per-file from extension instead of only analyzing the primary
language. This fixes multi-language repos like spine-runtimes (C++ primary)
where C# files were never analyzed.

Changes:
- Build reverse ext→language map, detect language per-file
- Analyze ALL files with known extensions (not just primary language)
- Config "language" field works as optional filter, not a workaround
- Store per-file language + languages_analyzed in output
- Remove 50-file API mode limit (rate limiting already handles this)
- Remove 100-file default config extraction limit (now unlimited by default)
- Fix unified scraper default max_pages from 100 to 500 (matches constants.py)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove remaining 100-file limit in config_extractor.extract_from_directory

The find_config_files default was changed to unlimited but
extract_from_directory and CLI --max-files still defaulted to 100.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: replace interactive terminal merge with automated AgentClient call

AIEnhancedMerger._launch_claude_merge() used to open a terminal window,
run a bash script, and poll for a file — requiring manual interaction.

Now uses AgentClient.call() to send the merge prompt directly and parse
the JSON response. Fully automated, no terminal needed, works with any
configured AI agent (Claude, Kimi, etc.).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add marketplace pipeline for publishing skills to Claude Code plugin repos

Connect the three-repo pipeline: configs repo → Skill Seekers engine → plugin
marketplace repos. Enables automated publishing of generated skills directly
into Claude Code plugin repositories with proper plugin.json and marketplace.json
structure.

New components:
- MarketplaceManager: Registry for plugin marketplace repos at
  ~/.skill-seekers/marketplaces.json with per-repo git tokens, branch config,
  and default author metadata
- MarketplacePublisher: Clones marketplace repo, creates plugin directory
  structure (skills/, .claude-plugin/plugin.json), updates marketplace.json,
  commits and pushes. Includes skill_name validation to prevent path traversal,
  and cleanup of partial state on git failures
- 4 MCP tools: add_marketplace, list_marketplaces, remove_marketplace,
  publish_to_marketplace — registered in FastMCP server
- Phase 6 in install workflow: automatic marketplace publishing after packaging,
  triggered by --marketplace CLI arg or marketplace_targets config field

CLI additions:
- --marketplace NAME: publish to registered marketplace after packaging
- --marketplace-category CAT: plugin category (default: development)
- --create-branch: create feature branch instead of committing to main

Security:
- Skill name regex validation (^[a-zA-Z0-9][a-zA-Z0-9._-]*$) prevents path
  traversal attacks via malicious SKILL.md frontmatter
- has_api_key variable scoping fix in install workflow summary
- try/finally cleanup of partial plugin directories on publish failure

Config schema:
- Optional marketplace_targets field in config JSON for multi-marketplace
  auto-publishing: [{"marketplace": "spyke", "category": "development"}]
- Backward compatible — ignored by older versions

Tests: 58 tests (36 manager + 22 publisher including 2 integration tests
using file:// git protocol for full publish success path)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: thread agent selection through entire enhancement pipeline

Propagates the --agent and --agent-cmd CLI parameters through all
enhancement components so users can use any supported coding agent
(kimi, claude, copilot, codex, opencode) consistently across the
full pipeline, not just in top-level enhancement.

Agent parameter threading:
- AIEnhancer: accepts agent param, passes to AgentClient
- ConfigEnhancer: accepts agent param, passes to AgentClient
- WorkflowEngine: accepts agent param, passes to sub-enhancers
  (PatternEnhancer, TestExampleEnhancer, AIEnhancer)
- ArchitecturalPatternDetector: accepts agent param for AI enhancement
- analyze_codebase(): accepts agent/agent_cmd, forwards to
  ConfigEnhancer, ArchitecturalPatternDetector, and doc processing
- UnifiedScraper: reads agent from CLI args, forwards to doc scraper
  subprocess, C3.x analysis, and LOCAL enhancement
- CreateCommand: forwards --agent and --agent-cmd to subprocess argv
- workflow_runner: passes agent to WorkflowEngine for inline/named workflows

Timeout improvements:
- Default enhancement timeout increased from 300s (5min) to 2700s (45min)
  to accommodate large skill generation with local agents
- New get_default_timeout() in agent_client.py with env var override
  (SKILL_SEEKER_ENHANCE_TIMEOUT) supporting 'unlimited' value
- Config enhancement block supports "timeout": "unlimited" field
- Removed hardcoded timeout=300 and timeout=600 calls in config_enhancer
  and merge_sources, now using centralized default

CLI additions (unified_scraper):
- --agent AGENT: select local coding agent for enhancement
- --agent-cmd CMD: override agent command template (advanced)

Config: unity-dotween.json updated with agent=kimi, timeout=unlimited,
removed unused file_patterns

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add claude-code unified config for Claude Code CLI skill generation

Unified config combining official Claude Code documentation and source
code analysis. Covers internals, architecture, tools, commands, IDE
integrations, MCP, plugins, skills, and development workflows.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add multi-agent support verification report and test artifacts

- AGENT_SUPPORT_VERIFICATION.md: verification report confirming agent
  parameter threading works across all enhancement components
- END_TO_END_EXAMPLES.md: complete workflows for all 17 source types
  with both Claude and Kimi agents
- test_agents.sh: shell script for real-world testing of agent support
  across major CLI commands with both agents
- test_realworld.md: real-world test scenarios for manual QA

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add .env to .gitignore to prevent secret exposure

The .env file containing API keys (ANTHROPIC_API_KEY, GITHUB_TOKEN, etc.)
was not in .gitignore, causing it to appear as untracked and risking
accidental commit. Added .env, .env.local, and .env.*.local patterns.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: URL filtering uses base directory instead of full page URL (#331)

is_valid_url() checked url.startswith(self.base_url) where base_url
could be a full page path like ".../manual/index.html". Sibling pages
like ".../manual/LoadingAssets.html" failed the check because they
don't start with ".../index.html".

Now strips the filename to get the directory prefix:
  "https://example.com/docs/index.html" → "https://example.com/docs/"

This fixes SPA sites like Unity's DocFX docs where browser mode renders
the page but sibling links were filtered out.

Closes #331

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: pass language config through to GitHub scraper in unified flow

The unified scraper built github_config from source fields but didn't
include the "language" field. The GitHub scraper's per-file detection
read self.config.get("language", "") which was always empty, so it
fell back to analyzing all languages instead of the focused C# filter.

For DOTween (C# only repo), this caused 0 files analyzed because
without the language filter, it analyzed top 3 languages but the
file tree matching failed silently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: centralize all enhancement timeouts to 45min default with unlimited support

All enhancement/AI timeouts now use get_default_timeout() from
agent_client.py instead of scattered hardcoded values (120s, 300s, 600s).

Default: 2700s (45 minutes)
Override: SKILL_SEEKER_ENHANCE_TIMEOUT env var
Unlimited: Set to "unlimited", "none", or "0"

Updated: agent_client.py, enhance_skill_local.py, arguments/enhance.py,
enhance_command.py, unified_enhancer.py, unified_scraper.py

Not changed (different purposes):
- Browser page load timeout (60s)
- API HTTP request timeout (120s)
- Doc scraper subprocess timeout (3600s)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add browser_wait_until and browser_extra_wait config for SPA docs

DocFX sites (Unity docs) render navigation via JavaScript after initial
page load. With domcontentloaded, only 1 link was found. With
networkidle + 5s extra wait, 95 content pages are discovered.

New config options for documentation sources:
- browser_wait_until: "networkidle" | "load" | "domcontentloaded"
- browser_extra_wait: milliseconds to wait after page load for lazy nav

Updated Addressables config to use networkidle + 5000ms extra wait.
Pass browser settings through unified scraper to doc scraper config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: three-layer smart discovery engine for SPA documentation sites

Replaces the browser_wait_until/browser_extra_wait config hacks with
a proper discovery engine that runs before the BFS crawl loop:

Layer 1: sitemap.xml — checks domain root for sitemap, parses <loc> tags
Layer 2: llms.txt — existing mechanism (unchanged)
Layer 3: SPA nav — renders index page with networkidle via Playwright,
         extracts all links from the fully-rendered DOM sidebar/TOC

The BFS crawl then uses domcontentloaded (fast) since all pages are
already discovered. No config hacks needed — browser mode automatically
triggers SPA discovery when only 1 page is found.

Tested: Unity Addressables DocFX site now discovers 95 pages (was 1).
Removed browser_wait_until/browser_extra_wait from Addressables config.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: replace manual arg forwarding with dynamic routing in create command

The create command manually hardcoded ~60% of scraper flags in _route_*()
methods, causing ~40 flags to be silently dropped. Every new flag required
edits in 2 places (arguments/create.py + create_command.py), guaranteed
to drift.

Replaced with _build_argv() — a dynamic forwarder that iterates
vars(self.args) and forwards all explicitly-set arguments automatically,
using the same pattern as main.py::_reconstruct_argv(). This eliminates
the root cause of all flag gaps.

Changes in create_command.py (-380 lines, +175 lines = net -205):
- Added _build_argv() dynamic arg forwarder with dest→flag translation
  map for mismatched names (async_mode→--async, video_playlist→--playlist,
  skip_config→--skip-config-patterns, workflow_var→--var)
- Added _call_module() helper (dedup sys.argv swap pattern)
- Simplified all _route_*() methods from 50-70 lines to 5-10 lines each
- Deleted _add_common_args() entirely (subsumed by _build_argv)
- _route_generic() now forwards ALL args, not just universal ones

New flags accessible via create command:
- --from-json: build skill from pre-extracted JSON (all source types)
- --skip-api-reference: skip API reference generation (local codebase)
- --skip-dependency-graph: skip dependency analysis (local codebase)
- --skip-config-patterns: skip config pattern extraction (local codebase)
- --no-comments: skip comment extraction (local codebase)
- --depth: analysis depth control (local codebase, deprecated)
- --setup: auto-detect GPU/install video deps (video)

Bug fix in unified_scraper.py:
- Fixed C3.x pattern data loss: unified_scraper read patterns/detected_patterns.json
  but codebase_scraper writes patterns/all_patterns.json. Changed both read
  locations (line 828 for local sources, line 1597 for GitHub C3.x) to use
  the correct filename. This was causing 100% loss of design pattern data
  (e.g., 905 patterns detected but 0 included in final skill).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address 5 code review issues in marketplace and package pipeline

Fixes found by automated code review of the marketplace feature and
package command:

1. --marketplace flag silently ignored in package_skill.py CLI
   Added MarketplacePublisher invocation after successful packaging
   when --marketplace is provided. Previously the flag was parsed
   but never acted on.

2. Missing 7 platform choices in --target (package.py)
   Added minimax, opencode, deepseek, qwen, openrouter, together,
   fireworks to the argparse choices list. These platforms have
   registered adaptors but were rejected by the argument parser.

3. is_update always True for new marketplace registrations
   Two separate datetime.now() calls produced different microsecond
   timestamps, making added_at != updated_at always. Fixed by
   assigning a single timestamp to both fields.

4. Shallow clone (depth=1) caused push failures for marketplace repos
   MarketplacePublisher now does full clones instead of using
   GitConfigRepo's shallow clone (which is designed for read-only
   config fetching). Full clone is required for commit+push workflow.

5. Partial plugin dir not cleaned on force=True failure
   Removed the `and not force` guard from cleanup logic — if an
   operation fails midway, the partial directory should be cleaned
   regardless of whether force was set.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address dynamic routing edge cases in create_command

Fixes from code review of the _build_argv() refactor:

1. Non-None defaults forwarded unconditionally — added enhance_level=2,
   doc_version="", video_languages="en", whisper_model="base",
   platform="slack", visual_interval=0.7, visual_min_gap=0.5,
   visual_similarity=3.0 to the defaults dict so they're only forwarded
   when the user explicitly overrides them. This fixes video sources
   incorrectly getting --enhance-level 2 (video default is 0).

2. video_url dest not translated — added "video_url": "--url" to
   _DEST_TO_FLAG so create correctly forwards --video-url as --url
   to video_scraper.py.

3. Video positional args double-forwarded — added video_url,
   video_playlist, video_file to _SKIP_ARGS since _route_video()
   already handles them via positional args from source detection.

4. Removed dead workflow_var entry from _DEST_TO_FLAG — the create
   parser uses key "var" not "workflow_var", so the translation
   was never triggered.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve 15 broken tests and --from-json crash bug in create command

Fixes found by Kimi code review of the dynamic routing refactor:

1. 3 test_create_arguments.py failures — UNIVERSAL_ARGUMENTS count
   changed from 19 to 21 (added agent, agent_cmd). Updated expected
   count and name set. Moved from_json out of UNIVERSAL to
   ADVANCED_ARGUMENTS since not all scrapers support it.

2. 12 test_create_integration_basic.py failures — tests called
   _add_common_args() which was deleted in the refactor. Rewrote
   _collect_argv() to use _build_argv() via CreateCommand with
   SourceDetector. Updated _make_args defaults to match new
   parameter set.

3. --from-json crash bug — was in UNIVERSAL_ARGUMENTS so create
   accepted it for all source types, but web/github/local scrapers
   don't support it. Forwarding it caused argparse "unrecognized
   arguments" errors. Moved to ADVANCED_ARGUMENTS with documentation
   listing which source types support it.

4. Additional _is_explicitly_set defaults — added enhance_level=2,
   doc_version="", video_languages="en", whisper_model="base",
   platform="slack", visual_interval/min_gap/similarity defaults to
   prevent unconditional forwarding of parser defaults.

5. Video arg handling — added video_url to _DEST_TO_FLAG translation
   map, added video_url/video_playlist/video_file to _SKIP_ARGS
   (handled as positionals by _route_video).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: C3.x analysis data loss — read from references/ after _generate_references() cleanup

Root cause: _generate_references() in codebase_scraper.py copies analysis
directories (patterns/, test_examples/, config_patterns/, architecture/,
dependencies/, api_reference/) into references/ then DELETES the originals
to avoid duplication (Issue #279). But unified_scraper.py reads from the
original paths after analyze_codebase() returns — by which time the
originals are gone.

This caused 100% data loss for all 6 C3.x data types (design patterns,
test examples, config patterns, architecture, dependencies, API reference)
in the unified scraper pipeline. The data was correctly detected (e.g.,
905 patterns in 510 files) but never made it into the final skill.

Fix: Added _load_json_fallback() method that checks references/{subdir}/
first (where _generate_references moves the data), falling back to the
original path. Applied to both GitHub C3.x analysis (line ~1599) and
local source analysis (line ~828).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add allowlist to _build_argv for config route to unified_scraper

_build_argv() was forwarding all CLI args (--name, --doc-version, etc.)
to unified_scraper which doesn't accept them. Added allowlist parameter
to _build_argv() — when provided, ONLY args in the allowlist are forwarded.

The config route now uses _UNIFIED_SCRAPER_ARGS allowlist with the exact
set of flags unified_scraper accepts.

This is a targeted patch — the proper fix is the ExecutionContext singleton
refactor planned separately.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add force=True to marketplace publish from package CLI

The package command's --marketplace flag didn't pass force=True to
MarketplacePublisher, so re-publishing an existing skill would fail
with "already exists" error instead of overwriting.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: add push_config tool for publishing configs to registered source repos

New ConfigPublisher class that validates configs, places them in the
correct category directory, commits, and pushes to registered source
repositories. Follows the MarketplacePublisher pattern.

Features:
- Auto-detect category from config name/description
- Validate via ConfigValidator + repo's validate-config.py
- Support feature branch or direct push
- Force overwrite existing configs
- MCP tool: push_config(config_path, source_name, category)

Usage:
  push_config(config_path="configs/unity-spine.json", source_name="spyke")

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: security hardening, error handling, tests, and cleanup

Security:
- Remove command injection via cloned repo script execution (config_publisher)
- Replace git add -A with targeted staging (marketplace_publisher)
- Clear auth tokens from cached .git/config after clone
- Use defusedxml for sitemap XML parsing (XXE protection)
- Add path traversal validation for config names

Error handling:
- AgentClient: specific exception handling for rate limit, auth, connection errors
- AgentClient: log subprocess stderr on non-zero exit, raise on explicit API mode failure
- config_publisher: only catch ValueError for validation warnings

Logic bugs:
- Fix _build_argv silently dropping --enhance-level 2 (matched default)
- Fix URL filtering over-broadening (strip to parent instead of adding /)
- Log warning when _call_module returns None exit code

Tests (134 new):
- test_agent_client.py: 71 tests for normalize, detect, init, timeout, model
- test_config_publisher.py: 23 tests for detect_category, publish, errors
- test_create_integration_basic.py: 20 tests for _build_argv routing
- Fix 11 pre-existing failures (guide_enhancer, doctor, install_skill, marketplace)

Cleanup:
- Remove 5 dev artifact files (-1405 lines)
- Rename _launch_claude_merge to _launch_ai_merge

All 3194 tests pass, 39 expected skips.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: pin ruff==0.15.8 in CI and reformat packaging_tools.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: add missing pytest install to vector DB adaptor test jobs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: reformat 7 files for ruff 0.15.8 and fix vector DB test path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove test-week2-integration job referencing missing script

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update e2e test to accept dynamic platform name in upload phase

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: YusufKaraaslanSpyke <yusuf@spykegames.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-02 04:50:15 +03:00
yusyus
00c72ea4a3 fix: resolve CI failures across all GitHub Actions workflows
- Fix ruff format issue in doc_scraper.py
- Add pytest skip markers for browser renderer tests when Playwright is
  not installed in CI
- Replace broken Python heredocs in 4 workflow YAML files
  (scheduled-updates, vector-db-export, quality-metrics, test-vector-dbs)
  with python3 -c calls to fix YAML parsing errors

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-29 20:40:45 +03:00
yusyus
6fded977dd feat: add Kotlin language support for codebase analysis (#287)
Adds full C3.x pipeline support for Kotlin (.kt, .kts):
- Language detection patterns (40+ weighted patterns for data/sealed classes, coroutines, companion objects, KMP, etc.)
- AST regex parser in code_analyzer.py (classes, objects, functions, extension functions, suspend functions)
- Dependency extraction for Kotlin import statements (with alias support)
- Design pattern adaptations (object→Singleton, companion→Factory, sealed→Strategy, data→Builder, Flow→Observer)
- Test example extraction for JUnit 4/5, Kotest, MockK, Spek
- Config detection for build.gradle.kts / settings.gradle.kts
- Extension maps registered in codebase_scraper, unified_codebase_analyzer, github_scraper, generate_router

Also fixes pre-existing parser count tests (35→36 for doctor command added in previous commit).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 23:25:12 +03:00
yusyus
ea4fed0be4 feat: add headless browser rendering for JavaScript SPA sites (#321)
New BrowserRenderer class uses Playwright to render JavaScript-heavy
documentation sites (React, Vue SPAs) that return empty HTML shells
with requests.get(). Activated via --browser flag on web scraping.

- browser_renderer.py: Playwright wrapper with lazy browser launch,
  auto-install Chromium on first use, context manager support
- doc_scraper.py: browser_mode config, _render_with_browser() helper,
  integrated into scrape_page() and scrape_page_async()
- SPA detection warnings now suggest --browser flag
- Optional dep: pip install "skill-seekers[browser]"
- 14 real e2e tests (actual Chromium, no mocks)
- UML updated: Scrapers class diagram (BrowserRenderer + dependency),
  Parsers (DoctorParser), Utilities (Doctor), Components, and new
  Browser Rendering sequence diagram (#20)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 22:06:14 +03:00
yusyus
006cccabae feat: add skill-seekers doctor health check command (#316)
8 diagnostic checks: Python version (3.10+), package install, git,
14 core deps, 10 optional deps, API keys, MCP server, output dir.
Each check reports pass/warn/fail with --verbose for extra detail.
Exit code 0 if no critical failures, 1 otherwise.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:27:17 +03:00
yusyus
43bdabb84f feat: add prompt injection check workflow for content security (#324)
New bundled workflow `prompt-injection-check` scans scraped content for
prompt injection patterns (role assumption, instruction overrides,
delimiter injection, hidden instructions, encoded payloads) using AI.

Flags suspicious content without removing it — preserves documentation
accuracy while warning about adversarial content. Added as first stage
in both `default` and `security-focus` workflows so it runs automatically
with --enhance-level >= 1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 21:17:57 +03:00
yusyus
6beff3d52f fix: add path traversal protection to get_workflow_tool + tests (#325)
PR #326 added _validate_name() to create/update/delete but missed
get_workflow_tool, which would raise an unhandled ValueError instead of
returning a user-friendly error. Added try/except handling and 6 tests
covering all 4 tool functions with malicious names.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 20:56:52 +03:00
yusyus
d381315340 fix: pass enhance_level instead of removed enhance_with_ai/ai_mode to analyze_codebase (#323)
Two call sites (_run_c3_analysis in unified_scraper.py and _analyze_c3x in
unified_codebase_analyzer.py) still passed the old enhance_with_ai and ai_mode
kwargs which were replaced by enhance_level. This caused a TypeError when
running C3.x codebase analysis.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 22:14:51 +03:00
yusyus
d71c1d3aa3 fix: filter non-integer metadata from GitHub languages API response (#322)
PyGithub's get_languages() returns raw API JSON which in some environments
includes non-integer metadata keys (e.g., "url"), causing a TypeError in
sum(). Now filters to integer values only before calculating percentages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 23:44:52 +03:00
yusyus
5a93003da4 chore: bump version to 3.4.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 21:58:57 +03:00
yusyus
d76ab1d9a4 fix: report accurate saved/skipped page counts and detect SPA sites (#320, #321)
The scraper previously reported len(visited_urls) as "Scraped N pages"
even when save_page() silently skipped pages with empty content (<50
chars). For JavaScript SPA sites this meant "Scraped 190 pages" followed
by "No scraped data found!" with no explanation.

Changes:
- Added pages_saved/pages_skipped counters to DocToSkillConverter
- save_page() now increments pages_skipped on skip, pages_saved on save
- New _log_scrape_completion() reports "(N saved, M skipped)" breakdown
- SPA detection warns when all/most pages have empty content
- build_skill() error now explains empty content cause when pages skipped
- Updated both sync and async scrape completion paths
- 14 new tests across 4 test classes (counting, messages, SPA, build)

Fixes #320

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-24 22:26:35 +03:00
yusyus
0fa99641aa style: fix pre-existing ruff format issues in 5 files
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 21:24:21 +03:00
yusyus
cd7b322b5e feat: expand platform coverage with 8 new adaptors, 7 new CLI agents, and OpenCode skill tools
Phase 1 - OpenCode Integration:
- Add OpenCodeAdaptor with directory-based packaging and dual-format YAML frontmatter
- Kebab-case name validation matching OpenCode's regex spec

Phase 2 - OpenAI-Compatible LLM Platforms:
- Extract OpenAICompatibleAdaptor base class from MiniMax (shared format/package/upload/enhance)
- Refactor MiniMax to ~20 lines of constants inheriting from base
- Add 6 new LLM adaptors: Kimi, DeepSeek, Qwen, OpenRouter, Together AI, Fireworks AI
- All use OpenAI-compatible API with platform-specific constants

Phase 3 - CLI Agent Expansion:
- Add 7 new install-agent paths: roo, cline, aider, bolt, kilo, continue, kimi-code
- Total agents: 11 -> 18

Phase 4 - Advanced Features:
- OpenCode skill splitter (auto-split large docs into focused sub-skills with router)
- Bi-directional skill format converter (import/export between OpenCode and any platform)
- GitHub Actions template for automated skill updates

Totals: 12 --target platforms, 18 --agent paths, 2915 tests passing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 20:31:51 +03:00
yusyus
1d3d7389d7 fix: sanitize_url crashes on Python 3.14 strict urlparse (#284)
Python 3.14's urlparse() raises ValueError on URLs with unencoded
brackets that look like malformed IPv6 (e.g. http://[fdaa:x:x:x::x
from docs.openclaw.ai llms-full.txt). sanitize_url() called urlparse()
BEFORE encoding brackets, so it crashed before it could fix them.

Fix: catch ValueError from urlparse, encode ALL brackets, then retry.
This is safe because if urlparse rejected the brackets, they are NOT
valid IPv6 host literals and should be encoded anyway.

Also fixed Discord e2e tests to skip gracefully on network issues.

Fixes #284

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 00:30:48 +03:00
yusyus
2ef6e59d06 fix: stop blindly appending /index.html.md to non-.md URLs (#277)
The previous fix (a82cf69) only addressed anchor fragment stripping but
left the fundamental problem: _convert_to_md_urls() blindly appended
/index.html.md to ALL non-.md URLs from llms.txt. This only works for
Docusaurus sites — for sites like Discord docs it generates mass 404s.

Changes:
- _convert_to_md_urls() now strips anchors and deduplicates only,
  preserving original URLs as-is instead of appending /index.html.md
- New _has_md_extension() helper uses urlparse().path.endswith(".md")
  instead of error-prone ".md" in url substring matching
- Fixed ".md" in url checks at 4 locations (lines 465, 554, 716, 775)
- Removed 24 lines of dead commented-out code
- Added real-world e2e test against docs.discord.com (no mocks)
- Updated unit tests for new behavior (32 tests)

Fixes #277

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 23:44:35 +03:00
yusyus
f6131c6798 fix: unified scraper temp config uses unified format for doc_scraper (#317)
The unified scraper's _scrape_documentation() was creating temp configs
in flat/legacy format (no "sources" key), causing doc_scraper's
ConfigValidator to reject them. Wrap the temp config in unified format
with a "sources" array. Also remove dead code branches and fix a
pre-existing test that didn't clear GITHUB_TOKEN from env.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:35:12 +03:00
yusyus
4f87de6b56 fix: improve MiniMax adaptor from PR #318 review (#319)
* feat: add MiniMax AI as LLM platform adaptor

Original implementation by octo-patch in PR #318.
This commit includes comprehensive improvements and documentation.

Code Improvements:
- Fix API key validation to properly check JWT format (eyJ prefix)
- Add specific exception handling for timeout and connection errors
- Remove unused variable in upload method

Dependencies:
- Add MiniMax to [all-llms] extra group in pyproject.toml

Tests:
- Remove duplicate setUp method in integration test class
- Add 4 new test methods:
  * test_package_excludes_backup_files
  * test_upload_success_mocked (with OpenAI mocking)
  * test_upload_network_error
  * test_upload_connection_error
  * test_validate_api_key_jwt_format
- Update test_validate_api_key_valid to use JWT format keys
- Fix test assertions for error message matching

Documentation:
- Create comprehensive MINIMAX_INTEGRATION.md guide (380+ lines)
- Update MULTI_LLM_SUPPORT.md with MiniMax platform entry
- Update 01-installation.md extras table
- Update INTEGRATIONS.md AI platforms table
- Update AGENTS.md adaptor import pattern example
- Fix README.md platform count from 4 to 5

All tests pass (33 passed, 3 skipped)
Lint checks pass

Co-authored-by: octo-patch <octo-patch@users.noreply.github.com>

* fix: improve MiniMax adaptor — typed exceptions, key validation, tests, docs

- Remove invalid "minimax" self-reference from all-llms dependency group
- Use typed OpenAI exceptions (APITimeoutError, APIConnectionError)
  instead of string-matching on generic Exception
- Replace incorrect JWT assumption in validate_api_key with length check
- Use DEFAULT_API_ENDPOINT constant instead of hardcoded URLs (3 sites)
- Add Path() cast for output_path before .is_dir() call
- Add sys.modules mock to test_enhance_missing_library
- Add mocked test_enhance_success with backup/content verification
- Update test assertions for new exception types and key validation
- Add MiniMax to __init__.py docstrings (module, get_adaptor, list_platforms)
- Add MiniMax sections to MULTI_LLM_SUPPORT.md (install, format, API key,
  workflow example, export-to-all)

Follows up on PR #318 by @octo-patch (feat: add MiniMax AI as LLM platform adaptor).

Co-Authored-By: Octopus <octo-patch@users.noreply.github.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: octo-patch <octo-patch@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-20 22:12:23 +03:00
yusyus
2b725aa8f7 fix: update version strings and test expectations from 3.2.0 to 3.3.0
Fix CI failures: version hardcoded in _version.py fallbacks and
test assertions (test_package_structure, test_cli_paths) still
referenced 3.2.0 after the version bump.
2026-03-16 00:53:35 +03:00
yusyus
53b911b697 feat: add 10 new skill source types (17 total) with full pipeline integration
Add Jupyter Notebook, Local HTML, OpenAPI/Swagger, AsciiDoc, PowerPoint,
RSS/Atom, Man Pages, Confluence, Notion, and Slack/Discord Chat as new
skill source types. Each type is fully integrated across:

- Standalone CLI commands (skill-seekers <type>)
- Auto-detection via 'skill-seekers create' (file extension + content sniffing)
- Unified multi-source configs (scraped_data, dispatch, config validation)
- Unified skill builder (generic merge + source-attributed synthesis)
- MCP server (scrape_generic tool with per-type flag mapping)
- pyproject.toml (entry points, optional deps, [all] group)

Also fixes: EPUB unified pipeline gap, missing word/video config validators,
OpenAPI yaml import guard, MCP flag mismatch for all 10 types, stale
docstrings, and adds 77 integration tests + complex-merge workflow.

50 files changed, +20,201 lines
2026-03-15 15:30:15 +03:00
yusyus
2e30970dfb feat: add EPUB input support (#310)
Adds EPUB as a first-class input source for skill generation.

- EpubToSkillConverter (epub_scraper.py, ~1200 lines) following PDF scraper pattern
- Dublin Core metadata, spine items, code blocks, tables, images extraction
- DRM detection (Adobe ADEPT, Apple FairPlay, Readium LCP) with fail-fast
- EPUB 3 NCX TOC bug workaround (ignore_ncx=True)
- ebooklib as optional dep: pip install skill-seekers[epub]
- Wired into create command with .epub auto-detection
- 104 tests, all passing

Review fixes: removed 3 empty test stubs, fixed SVG double-counting in
_extract_images(), added logger.debug to bare except pass.

Based on PR #310 by @christianbaumann.
Co-authored-by: Christian Baumann <mail@chriss-baumann.de>
2026-03-15 02:34:41 +03:00
yusyus
83b9a695ba feat: add sync-config command to detect and update config start_urls (#306)
## Summary

Add `skill-seekers sync-config` 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.

- 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 tool sync_config included
- 57 tests (39 unit + 18 E2E with local HTTP server)
- Fixed CI: renamed summary job to "Tests" to match branch protection rule

Closes #306
2026-03-15 02:16:32 +03:00
yusyus
b25a6f7f53 fix: centralize bracket-encoding to prevent 'Invalid IPv6 URL' on all code paths (#284)
The original fix (741daf1) only patched LlmsTxtParser._clean_url(),
which covers URLs extracted directly from llms.txt content. But URLs
discovered from .md files during BFS crawl (_extract_markdown_content)
and from HTML pages (extract_content) bypass _clean_url() entirely.
When those pages contain links with square brackets (e.g.
/api/[v1]/users), httpx raises 'Invalid IPv6 URL' on fetch.

Fix: add a shared sanitize_url() utility in cli/utils.py that
percent-encodes [ and ] in path/query components, and apply it at
every URL ingestion point:

- _enqueue_url(): main chokepoint — all discovered URLs pass through
- scrape_page(): safety net for start_urls that skip _enqueue_url
- scrape_page_async(): same for async mode
- dry-run sync/async paths: direct fetches that also bypass _enqueue_url

LlmsTxtParser._clean_url() now delegates bracket-encoding to the
shared sanitize_url() (DRY), keeping only its malformed-anchor
stripping logic.

Added 16 tests: sanitize_url unit tests, _clean_url bracket tests,
_enqueue_url sanitization tests, and integration test verifying
markdown content with bracket URLs is handled safely.

Fixes #284
2026-03-14 23:53:47 +03:00
yusyus
f214976ccd fix: apply review fixes from PR #309 and stabilize flaky benchmark test
Follow-up to PR #309 (perf: optimize with caching, pre-compiled regex,
O(1) lookups, and bisect line indexing). These fixes were committed to
the PR branch but missed the squash merge.

Review fixes (credit: PR #309 by copperlang2007):
1. Rename _pending_set -> _enqueued_urls to accurately reflect that the
   set tracks all ever-enqueued URLs, not just currently pending ones
2. Extract duplicated _build_line_index()/_offset_to_line() into shared
   build_line_index()/offset_to_line() in cli/utils.py (DRY)
3. Fix pre-existing bug: infer_categories() guard checked 'tutorial'
   but wrote to 'tutorials' key, risking silent overwrites
4. Remove unnecessary _store_results() closure in scrape_page()
5. Simplify parser pre-import in codebase_scraper.py

Benchmark stabilization:
- test_benchmark_metadata_overhead was flaky on CI (106.7% overhead
  observed, threshold 50%) because 5 iterations with mean averaging
  can't reliably measure microsecond-level differences
- Fix: 20 iterations, warm-up run, median instead of mean, threshold
  raised to 200% (guards catastrophic regression, not noise)

Ref: https://github.com/yusufkaraaslan/Skill_Seekers/pull/309
2026-03-14 23:39:23 +03:00
yusyus
73349c616b fix: update hardcoded version strings in tests to 3.2.0
Tests had hardcoded "3.1.3" version checks that broke after
the version bump to 3.2.0.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 22:48:12 +03:00
yusyus
d19ad7d820 feat: video pipeline OCR quality fixes + two-pass AI enhancement
- Skip OCR on WEBCAM/OTHER frames (eliminates ~64 junk results per video)
- Add _clean_ocr_line() to strip line numbers, IDE decorations, collapse markers
- Add _fix_intra_line_duplication() for multi-engine OCR overlap artifacts
- Add _is_likely_code() filter to prevent UI junk in reference code fences
- Add language detection to get_text_groups() via LanguageDetector
- Apply OCR cleaning in _assemble_structured_text() pipeline
- Add two-pass AI enhancement: Pass 1 cleans reference Code Timeline
  using transcript context, Pass 2 generates SKILL.md from cleaned refs
- Update video-tutorial.yaml prompts for pre-cleaned references
- Add 17 new tests (197 total video tests), 2540 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 21:48:21 +03:00
yusyus
4b19cf4836 style: ruff format 4 video pipeline files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 19:48:02 +03:00
yusyus
cc9cc32417 feat: add skill-seekers video --setup for GPU auto-detection and dependency installation
Auto-detects NVIDIA (CUDA), AMD (ROCm), or CPU-only GPU and installs the
correct PyTorch variant + easyocr + all visual extraction dependencies.
Removes easyocr from video-full pip extras to avoid pulling ~2GB of wrong
CUDA packages on non-NVIDIA systems.

New files:
- video_setup.py (835 lines): GPU detection, PyTorch install, ROCm config,
  venv checks, system dep validation, module selection, verification
- test_video_setup.py (60 tests): Full coverage of detection, install, verify

Updated docs: CHANGELOG, AGENTS.md, CLAUDE.md, README.md, CLI_REFERENCE,
FAQ, TROUBLESHOOTING, installation guide, video dependency plan

All 2523 tests passing (15 skipped).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 18:39:16 +03:00
yusyus
12bc29ab36 fix: resolve 15 bugs and gaps in video scraper pipeline
- Fix extract_visual_data returning 2-tuple instead of 3 (ValueError crash)
- Move pytesseract from core deps to [video-full] optional group
- Add 30-min timeout + user feedback to video enhancement subprocess
- Add scrape_video_impl to MCP server fallback import block
- Detect auto-generated YouTube captions via is_generated property
- Forward --vision-ocr and --video-playlist through create command
- Fix filename collision for non-ASCII video titles (fallback to video_id)
- Make _vision_used a proper dataclass field on FrameSubSection
- Expose 6 visual params in MCP scrape_video tool
- Add install instructions on missing video deps in unified scraper
- Update MCP docstring tool counts (25→33, 7 categories)
- Add video and word commands to main.py docstring
- Document video-full exclusion from [all] deps in pyproject.toml
- Update parser registry test count (22→23 for video parser)

All 2437 tests passing, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 12:39:21 +03:00
yusyus
066e19674a Merge branch 'development' into feature/video-scraper-pipeline
Sync with latest development changes including ruff formatting,
bug fixes, and pinecone adaptor additions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 11:38:45 +03:00
yusyus
68bdbe8307 style: ruff format remaining 14 files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 10:54:45 +03:00
yusyus
6c31990941 style: fix ruff lint and formatting errors
- E741: rename ambiguous variable `l` → `line_text` in enhance_skill_local.py
- ARG001: suppress unused `doc` param in word_scraper _build_section()
- SIM108: use ternary for code_text assignment in word_scraper
- F841: remove unused `metadata` variable in test_chunking_integration
- F401: remove unused imports in test_pinecone_adaptor
- ARG001: rename unused `docs` → `_docs` in test_pinecone_adaptor
- Format 20 files to match ruff formatting rules

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-01 10:54:32 +03:00
yusyus
064405c052 fix: resolve 18 bugs and code quality issues across adaptors, CLI, and chunking pipeline
Bug fixes:
- Fix --var flag silently dropped in create routing (args.workflow_var → args.var)
- Fix double _score_code_quality() call in word scraper
- Add .docx file extension validation in WordToSkillConverter
- Fix weaviate ImportError masked by generic Exception handler
- Fix RAG chunking crash using non-existent converter.output_dir

Chunking pipeline improvements:
- Wire --chunk-overlap-tokens through entire package pipeline
  (package_skill → adaptor.package → format_skill_md → _maybe_chunk_content → RAGChunker)
- Add auto-scaling overlap: max(50, chunk_tokens//10) when chunk size is non-default
- Rename --no-preserve-code to --no-preserve-code-blocks (backward-compat alias kept)
- Replace hardcoded 512/50 chunk defaults with DEFAULT_CHUNK_TOKENS/DEFAULT_CHUNK_OVERLAP_TOKENS
  constants across all 12 concrete adaptors, rag_chunker, base, and package_skill

Code quality:
- Extract shared _generate_openai_embeddings() and _generate_st_embeddings() to SkillAdaptor
  base class, removing ~150 lines of duplication from chroma/weaviate/pinecone
- Add Pinecone adaptor with full upload support (pinecone_adaptor.py)

Tests (14 new):
- chunk_overlap_tokens parameter wiring, auto-scaling overlap, preserve_code_blocks flag
- .docx/.doc/no-extension file validation, --var flag routing E2E
- Embedding method inheritance verification, backward-compatible flag aliases

Docs:
- Update CHANGELOG, CLI_REFERENCE, API_REFERENCE, packaging guide (EN+ZH)
- Update README test count badge (1880+ → 2283+)

All 2283 tests passing, 8 skipped, 0 failures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 21:57:59 +03:00
YusufKaraaslanSpyke
62071c4aa9 feat: add video tutorial scraping pipeline with per-panel OCR and AI enhancement
Add 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 independently,
tracks code evolution across frames, and generates structured SKILL.md output.

Key features:
- Video metadata extraction (YouTube, local files, playlists)
- Multi-source transcript extraction (YouTube API, yt-dlp, Whisper fallback)
- Chapter-based and time-window segmentation
- Visual extraction: keyframe detection, frame classification, panel detection
- Per-panel sub-section OCR (each IDE panel OCR'd independently)
- Parallel OCR with ThreadPoolExecutor for multi-panel frames
- Narrow panel filtering (300px min width) to skip UI chrome
- Text block tracking with spatial panel position matching
- Code timeline with edit tracking across frames
- Audio-visual alignment (code + narrator pairs)
- Video-specific AI enhancement prompt for OCR denoising and code reconstruction
- video-tutorial.yaml workflow with 4 stages (OCR cleanup, language detection,
  tutorial synthesis, skill polish)
- CLI integration: skill-seekers video --url/--video-file/--playlist
- MCP tool: scrape_video for automation
- 161 tests passing

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-27 23:10:19 +03:00
yusyus
4c8e16c8b1 fix(#300): centralize selector fallback, fix dry-run link discovery, and smart --config routing
- Add FALLBACK_MAIN_SELECTORS constant and _find_main_content() helper to
  eliminate 3 duplicated fallback loops in doc_scraper.py
- Move link extraction before early return in extract_content() so links
  are always discovered from the full page, not just main content
- Fix single-threaded dry-run to extract links from soup (full page)
  instead of main element only — fixes reactflow.dev finding only 1 page
- Add link extraction to async dry-run path (was completely missing)
- Remove main_content from get_configuration() defaults so fallback logic
  kicks in instead of a broad CSS comma selector matching body
- Smart create --config routing: peek at JSON to determine unified
  (sources array → unified_scraper) vs simple (base_url → doc_scraper)
- Update docs/user-guide/02-scraping.md and docs/reference/CONFIG_FORMAT.md
  to use unified config format (legacy format rejected since v2.11.0)
- Fix test_auto_fetch_enabled and test_mcp_validate_legacy_config

Closes #300

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 22:25:59 +03:00
yusyus
b6d4dd8423 fix: remove arbitrary limits, fix hardcoded languages, and fix summarizer bugs
Stage 1 quality improvements from the Arbitrary Limits & Dead Code audit:

Reference file truncation removed:
- codebase_scraper.py: remove code[:500] truncation at 5 locations — reference
  files now contain complete code blocks for copy-paste usability
- unified_skill_builder.py: remove issues[:20], releases[:10], body[:500],
  and code_snippet[:300] caps in reference files — full content preserved

Enhancement summarizer rewrite:
- enhance_skill_local.py: replace arbitrary [:5] code block cap with
  character-budget approach using target_ratio * content_chars
- Fix intro boundary bug: track code block state so intro never ends
  inside a code block, which was desynchronizing the parser
- Remove dead _target_lines variable (assigned but never used)
- Heading chunks now also respect the character budget

Hardcoded language fixes:
- unified_skill_builder.py: test examples use ex["language"] instead of
  always "python" for syntax highlighting
- how_to_guide_builder.py: add language field to HowToGuide dataclass,
  set from workflow at creation, used in AI enhancement prompt

Test fixes:
- test_enhance_skill_local.py: rename test to test_code_blocks_not_arbitrarily_capped,
  fix assertion to count actual blocks (```count // 2), use target_ratio=0.9

Documentation:
- Add Stage 1 plan, implementation summary, review, and corrected docs
- Update CHANGELOG.md with all changes

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 00:30:40 +03:00
yusyus
b81d55fda0 feat(B2): add Microsoft Word (.docx) support
Implements ROADMAP task B2 — full .docx scraping support via mammoth +
python-docx, producing SKILL.md + references/ output identical to other
source types.

New files:
- src/skill_seekers/cli/word_scraper.py — WordToSkillConverter class +
  main() entry point (~600 lines); mammoth → BeautifulSoup pipeline;
  handles headings, code detection (incl. monospace <p><br> blocks),
  tables, images, metadata extraction
- src/skill_seekers/cli/arguments/word.py — add_word_arguments() +
  WORD_ARGUMENTS dict
- src/skill_seekers/cli/parsers/word_parser.py — WordParser for unified
  CLI parser registry
- tests/test_word_scraper.py — comprehensive test suite (~300 lines)

Modified files:
- src/skill_seekers/cli/main.py — registered "word" command module
- src/skill_seekers/cli/source_detector.py — .docx auto-detection +
  _detect_word() classmethod
- src/skill_seekers/cli/create_command.py — _route_word() + --help-word
- src/skill_seekers/cli/arguments/create.py — WORD_ARGUMENTS + routing
- src/skill_seekers/cli/arguments/__init__.py — export word args
- src/skill_seekers/cli/parsers/__init__.py — register WordParser
- src/skill_seekers/cli/unified_scraper.py — _scrape_word() integration
- src/skill_seekers/cli/pdf_scraper.py — fix: real enhancement instead
  of stub; remove [:3] reference file limit; capture run_workflows return
- src/skill_seekers/cli/github_scraper.py — fix: remove arbitrary
  open_issues[:20] / closed_issues[:10] reference file limits
- pyproject.toml — skill-seekers-word entry point + docx optional dep
- tests/test_cli_parsers.py — update parser count 21→22

Bug fixes applied during real-world testing:
- Code detection: detect monospace <p><br> blocks as code (mammoth
  renders Courier paragraphs this way, not as <pre>/<code>)
- Language detector: fix wrong method name detect_from_text →
  detect_from_code
- Description inference: pass None from main() so extract_docx() can
  infer description from Word document subject/title metadata
- Bullet-point guard: exclude prose starting with •/-/* from code scoring
- Enhancement: implement real API/LOCAL enhancement (was stub)
- pip install message: add quotes around skill-seekers[docx]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-25 21:47:30 +03:00
yusyus
e42aade992 style: auto-format 6 files with ruff format (CI formatting check)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 22:28:11 +03:00
yusyus
91d6340c3c chore: bump version to 3.1.3
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 22:24:03 +03:00
yusyus
7a2ffb286c refactor: rename all chunk flags to include explicit units
Replace ambiguous --chunk-size / --chunk-overlap names that meant different
things in different contexts (tokens vs characters) with fully explicit names:

- --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 (PDF pages)       → --pdf-pages-per-chunk (poc file)

Also aligns stream_parser.py help with streaming_ingest.py standalone parser.
All 2167 tests pass.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 22:07:56 +03:00
yusyus
b636a0a292 fix: resolve issue #299 and Phase 1 cleanup
- Fix #299: rename --chunk-size/--chunk-overlap to --streaming-chunk-size/
  --streaming-overlap in arguments/package.py to avoid collision with the
  RAG --chunk-size flag from arguments/common.py
- Phase 1a: make package_skill.py import args via add_package_arguments()
  instead of a 105-line inline duplicate argparse block; fixes the root
  cause of _reconstruct_argv() passing unrecognised flag names
- Phase 1b: centralise setup_logging() into utils.py and remove 4
  duplicate module-level logging.basicConfig() calls from doc_scraper.py,
  github_scraper.py, codebase_scraper.py, and unified_scraper.py
- Fix test_package_structure.py / test_cli_paths.py version strings
  (3.1.1 → 3.1.2)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 21:22:05 +03:00
yusyus
1229ff2baf style: auto-format enhance_skill_local.py and test with ruff
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 07:05:50 +03:00
yusyus
5ae57d192a fix: update Gemini model to 2.5-flash and add API auto-detection in enhance
Fix 1 — gemini.py: replace deprecated gemini-2.0-flash-exp (404 errors)
with gemini-2.5-flash (stable, GA, Google's recommended replacement).
Closes #290.

Fix 2 — enhance dispatcher: implement the documented auto-detection that
was missing from the code. skill-seekers enhance now correctly routes:
  - ANTHROPIC_API_KEY set → Claude API mode (enhance_skill.py)
  - GOOGLE_API_KEY set    → Gemini API mode
  - OPENAI_API_KEY set    → OpenAI API mode
  - No API keys           → LOCAL mode (Claude Code Max, free)

Use --mode LOCAL to force local mode even when an API key is present.

9 new tests cover _detect_api_target() priority logic and main()
routing (API delegation, --mode LOCAL override, no-key fallback).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-24 06:52:55 +03:00
Claude
40cec4dffd hotfix: v3.1.1 — fix create command max_pages AttributeError
Merge fix from development (#293, #294) and bump version to 3.1.1.
Fixes crash when max_pages argument was not provided in web source routing.

https://claude.ai/code/session_01HS5q7ghjfEUravNPZRCGux
2026-02-23 06:37:39 +00:00
yusyus
ef14fd4b5d style: auto-format 12 files with ruff format (CI formatting check)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 22:32:31 +03:00
yusyus
efc722eeed fix: resolve all CI ruff linting errors (F401, F821, ARG001, SIM117, SIM105, C408)
- Remove unused imports (F401): os/Path/json/threading in tests; os in estimate_pages;
  Path in install_skill; pytest in test_unified_scraper_orchestration
- Fix F821 undefined 'args' in unified_scraper._scrape_local() by storing
  self._cli_args = args in run() and reading via getattr in _scrape_local()
- Fix ARG001/ARG005 unused lambda/function arguments with _ prefix or # noqa:ARG001
  where parameter names must be preserved for keyword-argument compatibility
- Fix C408 unnecessary dict() calls → dict literals in test_enhance_command
- Fix F841 unused variable 'stub' in test_enhance_command
- Fix SIM117 nested with statements → single with in test_unified_scraper_orchestration
- Fix SIM105 try/except/pass → contextlib.suppress in test_unified_scraper_orchestration
- Rewrite TestScrapeLocal to test fixed behavior (not the NameError bug)

All 2267 tests pass, 11 skipped.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 22:30:52 +03:00
yusyus
f7117c35a9 chore: bump version to 3.1.0 and update CHANGELOG
- pyproject.toml: version 3.0.0 → 3.1.0
- src/skill_seekers/_version.py: update hardcoded fallback to 3.1.0
- CHANGELOG.md: comprehensive [3.1.0] release notes covering all
  features and fixes since v3.0.0 (unified create command, workflow
  presets, RST parser, smart enhance dispatcher, CLI flag parity,
  60 new workflow YAMLs, test suite improvements)
- Deprecation messages: update "removed in v3.0.0" → "v4.0.0" across
  analyze_presets.py, codebase_scraper.py, mcp/server.py
- tests/test_cli_paths.py: update version assertion to 3.1.0
- tests/test_package_structure.py: update __version__ assertions to 3.1.0
- tests/test_preset_system.py: update deprecation message version to v4.0.0

All 2267 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 21:52:04 +03:00
yusyus
db63e67986 fix: resolve all test failures — 2115 passing, 0 failures
Fixes several categories of test failures to achieve a clean test suite:

**Python 3.14 / chromadb compatibility**
- chroma.py: broaden except clause to catch pydantic ConfigError on Python 3.14
- test_adaptors_e2e.py, test_integration_adaptors.py: skip on (ImportError, Exception)

**sys.modules corruption (test isolation)**
- test_swift_detection.py: save/restore all skill_seekers.cli modules AND parent
  package attributes in test_empty_swift_patterns_handled_gracefully; prevents
  @patch decorators in downstream test files from targeting stale module objects

**Removed unnecessary @unittest.skip decorators**
- test_claude_adaptor.py, test_gemini_adaptor.py, test_openai_adaptor.py: remove
  skip from tests that already had pass-body or were compatible once deps installed

**Fixed openai import guard for installed package**
- test_openai_adaptor.py: use patch.dict(sys.modules, {"openai": None}) for
  test_upload_missing_library since openai is now a transitive dep

**langchain import path update**
- test_rag_chunker.py: fix from langchain.schema → langchain_core.documents

**config_extractor tomllib fallback**
- config_extractor.py: use stdlib tomllib (Python 3.11+) as fallback when
  tomli/toml packages are not installed

**Remove redundant sys.path.insert() calls**
- codebase_scraper.py, doc_scraper.py, enhance_skill.py, enhance_skill_local.py,
  estimate_pages.py, install_skill.py: remove legacy path manipulation no longer
  needed with pip install -e . (src/ layout)

**Test fixes: removed @requires_github from fully-mocked tests**
- test_unified_analyzer.py: 5 tests that mock GitHubThreeStreamFetcher don't
  need a real token; remove decorator so they always run

**macOS-specific test improvements**
- test_terminal_detection.py: use @patch(sys.platform, "darwin") instead of
  runtime skipTest() so tests run on all platforms

**Dependency updates**
- pyproject.toml, uv.lock: add langchain and llama-index as core dependencies

**New workflow presets and tests**
- src/skill_seekers/workflows/: add 60 new domain-specific workflow YAML presets
- tests/test_mcp_workflow_tools.py: tests for MCP workflow tool implementations
- tests/test_unified_scraper_orchestration.py: tests for UnifiedScraper methods

Result: 2115 passed, 158 skipped (external services/long-running), 0 failures

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 20:43:17 +03:00
yusyus
fee89d5897 fix: smart enhancement dispatcher — Gemini/API mode + root/Docker detection
Fixes issues #289 and #286 (agent switching and Docker/root failures).

enhance_command.py (new smart dispatcher):
- Routes skill-seekers enhance to API mode (Gemini/OpenAI/Claude API)
  when an API key is available, or LOCAL mode (Claude Code CLI) otherwise
- Decision priority: --target flag > config default_agent > auto-detect
  from 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
- Supports --dry-run, --target, --api-key as first-class flags

arguments/enhance.py:
- Added --target, --api-key, --dry-run, --interactive-enhancement to
  ENHANCE_ARGUMENTS (shared by unified CLI parser and standalone entry point)

enhance_skill_local.py:
- Error output no longer truncated at 200 chars (shows up to 20 lines)
- Detects root/permission errors in stderr and prints actionable hint

config_manager.py:
- Added default_agent field to DEFAULT_CONFIG ai_enhancement section
- Added get_default_agent() and set_default_agent() methods

main.py:
- enhance command routed to enhance_command (was enhance_skill_local)
- _handle_analyze_command uses smart dispatcher for post-analysis enhancement

pyproject.toml:
- skill-seekers-enhance entry point updated to enhance_command:main

Tests: 1977 passed, 0 failed (28 new tests in test_enhance_command.py)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 01:26:19 +03:00
yusyus
22bdd4f5f6 fix: sync CLI flags across analyze/pdf/unified commands and fix workflow JSON config
Flag/option synchronization fixes:
- analyze: add --dry-run, --api-key, and all workflow flags (--enhance-workflow,
  --enhance-stage, --var, --workflow-dry-run) via WORKFLOW_ARGUMENTS merge
- pdf: add --api-key to PDF_ARGUMENTS; replace 5 hardcoded add_argument() calls
  in pdf_scraper.py:main() with add_pdf_arguments() to activate all defined args
- unified: add --api-key and --enhance-level (global override) to UNIFIED_ARGUMENTS
  and standalone parser; wire enhance_level CLI override into run() per-source loop
- codebase_scraper: fix --enhance-workflow to use action="append" (was type=str),
  enabling multiple workflow chaining instead of silently dropping all but last

ConfigManager test isolation fix:
- __init__ now reads self.CONFIG_DIR/CONFIG_FILE/PROGRESS_DIR class variables
  instead of calling _get_config_dir()/_get_progress_dir() directly, enabling
  monkeypatching in tests (fixes pre-existing test_add_and_retrieve_github_profile)

Workflow JSON config support in unified_scraper:
- Phase 5 now reads workflows/workflow_stages/workflow_vars from top-level JSON
  config and merges them with CLI args (CLI-first ordering); supports running
  workflows even when unified scraper is called without CLI args (args=None)

Tests: 1,949 passed, 0 failed (added 18 new tests across 3 test files)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-22 00:44:02 +03:00