diff --git a/CHANGELOG.md b/CHANGELOG.md index e8fd7ab..33ca80b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - **GitHub language detection crashes with `TypeError`** when API response contains non-integer metadata keys (e.g., `"url"`) — now filters to integer values only (#322) +- **C3.x codebase analysis crashes with `TypeError`** — `_run_c3_analysis()` and `_analyze_c3x()` passed removed `enhance_with_ai`/`ai_mode` kwargs to `analyze_codebase()` instead of `enhance_level` (#323) ## [3.4.0] - 2026-03-21 diff --git a/src/skill_seekers/cli/unified_codebase_analyzer.py b/src/skill_seekers/cli/unified_codebase_analyzer.py index 168ef2b..3b002c3 100644 --- a/src/skill_seekers/cli/unified_codebase_analyzer.py +++ b/src/skill_seekers/cli/unified_codebase_analyzer.py @@ -267,8 +267,7 @@ class UnifiedCodebaseAnalyzer: extract_test_examples=True, build_how_to_guides=True, extract_config_patterns=True, - enhance_with_ai=False, # Disable AI for speed - ai_mode="none", + enhance_level=0, # Disable AI for speed ) # Load C3.x results from output files diff --git a/src/skill_seekers/cli/unified_scraper.py b/src/skill_seekers/cli/unified_scraper.py index 02057c4..42c4d3c 100644 --- a/src/skill_seekers/cli/unified_scraper.py +++ b/src/skill_seekers/cli/unified_scraper.py @@ -1539,8 +1539,8 @@ class UnifiedScraper: extract_test_examples=True, # C3.2: Test examples build_how_to_guides=True, # C3.3: How-to guides extract_config_patterns=True, # C3.4: Config patterns - enhance_with_ai=source.get("ai_mode", "auto") != "none", - ai_mode=source.get("ai_mode", "auto"), + extract_docs=True, + enhance_level=0 if source.get("ai_mode", "auto") == "none" else 2, ) # Load C3.x outputs into memory diff --git a/tests/test_c3_integration.py b/tests/test_c3_integration.py index b7cf547..41b3ab4 100644 --- a/tests/test_c3_integration.py +++ b/tests/test_c3_integration.py @@ -358,5 +358,47 @@ class TestC3Integration: assert "references/codebase_analysis/ARCHITECTURE.md" in content +class TestC3AnalyzeCodebaseSignature: + """Verify _run_c3_analysis passes valid kwargs to analyze_codebase (#323).""" + + @pytest.fixture + def temp_dir(self): + """Create temporary directory for tests.""" + temp = tempfile.mkdtemp() + yield temp + shutil.rmtree(temp, ignore_errors=True) + + def test_run_c3_analysis_uses_enhance_level_not_old_kwargs(self, temp_dir): + """_run_c3_analysis must pass enhance_level, not enhance_with_ai/ai_mode.""" + config_path = os.path.join(temp_dir, "config.json") + config = { + "name": "test", + "description": "Test", + "sources": [{"type": "github", "repo": "test/repo", "ai_mode": "none"}], + } + with open(config_path, "w") as f: + json.dump(config, f) + + scraper = UnifiedScraper(config_path) + + captured_kwargs = {} + + def fake_analyze(**kwargs): + captured_kwargs.update(kwargs) + return {} + + with patch("skill_seekers.cli.codebase_scraper.analyze_codebase", fake_analyze): + scraper._run_c3_analysis(str(temp_dir), config["sources"][0]) + + assert "enhance_with_ai" not in captured_kwargs, ( + "enhance_with_ai is not a valid analyze_codebase() parameter" + ) + assert "ai_mode" not in captured_kwargs, ( + "ai_mode is not a valid analyze_codebase() parameter" + ) + assert "enhance_level" in captured_kwargs + assert captured_kwargs["enhance_level"] == 0 # ai_mode "none" → enhance_level 0 + + if __name__ == "__main__": pytest.main([__file__, "-v"]) diff --git a/tests/test_unified_scraper_orchestration.py b/tests/test_unified_scraper_orchestration.py index ec57855..da2f8b0 100644 --- a/tests/test_unified_scraper_orchestration.py +++ b/tests/test_unified_scraper_orchestration.py @@ -472,6 +472,31 @@ class TestScrapeLocal: assert captured_kwargs.get("enhance_level") == 3 + def test_analyze_codebase_not_called_with_old_kwargs(self, tmp_path, monkeypatch): + """analyze_codebase() must not receive enhance_with_ai or ai_mode (#323).""" + scraper = _make_scraper(tmp_path=tmp_path) + source = {"type": "local", "path": str(tmp_path)} + + captured_kwargs = {} + + def fake_analyze(**kwargs): + captured_kwargs.update(kwargs) + + monkeypatch.setattr( + "skill_seekers.cli.codebase_scraper.analyze_codebase", + fake_analyze, + ) + + scraper._scrape_local(source) + + assert "enhance_with_ai" not in captured_kwargs, ( + "enhance_with_ai is not a valid analyze_codebase() parameter" + ) + assert "ai_mode" not in captured_kwargs, ( + "ai_mode is not a valid analyze_codebase() parameter" + ) + assert "enhance_level" in captured_kwargs + # =========================================================================== # 6. run() orchestration