Skip to content

Commit 2a22127

Browse files
authored
fix: post-merge integration fixes for PRs #75, #76, #70, #60, #63 (#78)
This PR addresses integration issues and lint/test failures introduced by the batch merge of the following PRs into main: - PR #75: fix(loader): avoid spurious the.py from English prose in SKILL.md - PR #76: fix(python-parser): include file path, line number, and source text in SyntaxError warning (#69) - PR #70: fix(ci): make only Google LLM providers optional - PR #60: fix: add plain JSON controls for incompatible LLM backends - PR #63: feat: allow --lenient to scan skills without SKILL.md Additionally, PR #73 was closed as superseded by PR #76 (both addressed issue #69; PR #76 included tests). Fixes included: 1. test_robustness_features.py: Update regex in test_no_skill_md_still_raises_in_lenient to match the new error message from PR #63 ("No SKILL.md and no .md files found" instead of "SKILL.md not found"). 2. cli.py: Pass skill_file parameter to meta-analysis reload calls in both scan_command and scan_all_command. Without this, using --skill-file with --enable-meta would fail because the meta-analysis pass reloaded the skill without the custom skill_file, potentially raising SkillLoadError or loading the wrong document. 3. test_python_parser_syntax_error.py, test_lenient_no_skillmd.py: Auto-fix import sorting (ruff I001) in test files introduced by PRs #76 and #63. 4. .gitignore: Add scripts/ui_screenshot.py and scripts/ui_security_verify.py to gitignore (local-only Playwright UI verification scripts, not part of the project). 5. uv.lock: Regenerated to match the updated pinned dependencies in pyproject.toml from the merged PRs.
1 parent 75947ae commit 2a22127

8 files changed

Lines changed: 57 additions & 62 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,5 +102,9 @@ Thumbs.db
102102
BENCHMARK_RESULTS.md
103103
evals/results/
104104

105+
# UI test/verification scripts (local-only, require Playwright)
106+
scripts/ui_screenshot.py
107+
scripts/ui_security_verify.py
108+
105109
# User-generated scan policy (default TUI output)
106110
scan_policy.yaml

skill_scanner/cli/cli.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -359,7 +359,7 @@ def scan_command(args: argparse.Namespace) -> int:
359359
if meta_analyzer and result.findings and apply_meta_analysis_to_results is not None:
360360
status("Running meta-analysis to filter false positives...")
361361
try:
362-
skill = scanner.loader.load_skill(skill_dir, lenient=lenient)
362+
skill = scanner.loader.load_skill(skill_dir, lenient=lenient, skill_file=skill_file)
363363
original_count = len(result.findings)
364364
meta_result = asyncio.run(
365365
meta_analyzer.analyze_with_findings(
@@ -462,7 +462,9 @@ def scan_all_command(args: argparse.Namespace) -> int:
462462
if not result.findings:
463463
continue
464464
try:
465-
skill = scanner.loader.load_skill(Path(result.skill_directory), lenient=lenient)
465+
skill = scanner.loader.load_skill(
466+
Path(result.skill_directory), lenient=lenient, skill_file=skill_file
467+
)
466468
original_count = len(result.findings)
467469
meta_result = asyncio.run(
468470
meta_analyzer.analyze_with_findings(

skill_scanner/core/loader.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,7 @@ def load_skill(
105105
manifest, instruction_body = self._parse_skill_md(skill_md_path, lenient=lenient)
106106
elif lenient:
107107
# Lenient fallback: no SKILL.md, synthesize from .md files in the directory
108-
skill_md_path, manifest, instruction_body = self._synthesize_from_md_files(
109-
skill_directory
110-
)
108+
skill_md_path, manifest, instruction_body = self._synthesize_from_md_files(skill_directory)
111109
else:
112110
raise SkillLoadError(f"SKILL.md not found in {skill_directory}")
113111

skill_scanner/core/scanner.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -704,9 +704,7 @@ def scan_directory(
704704
if not skills_directory.exists():
705705
raise FileNotFoundError(f"Directory does not exist: {skills_directory}")
706706

707-
skill_dirs = self._find_skill_directories(
708-
skills_directory, recursive, lenient=lenient, skill_file=skill_file
709-
)
707+
skill_dirs = self._find_skill_directories(skills_directory, recursive, lenient=lenient, skill_file=skill_file)
710708
report = Report()
711709

712710
# Keep track of loaded skills for cross-skill analysis

tests/static_analysis/test_python_parser_syntax_error.py

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030

3131
from skill_scanner.core.static_analysis.parser.python_parser import PythonParser
3232

33-
3433
INVALID_PYTHON = """\
3534
def good():
3635
pass
@@ -62,8 +61,7 @@ def test_warning_includes_file_path(self, caplog):
6261
parser.parse()
6362

6463
assert any("skills/my_tool/tool.py" in record.message for record in caplog.records), (
65-
"Expected file_path in warning message; got: "
66-
+ str([r.message for r in caplog.records])
64+
"Expected file_path in warning message; got: " + str([r.message for r in caplog.records])
6765
)
6866

6967
def test_warning_includes_line_number(self, caplog):
@@ -73,8 +71,7 @@ def test_warning_includes_line_number(self, caplog):
7371
parser.parse()
7472

7573
assert any(
76-
"line" in record.message.lower() or any(c.isdigit() for c in record.message)
77-
for record in caplog.records
74+
"line" in record.message.lower() or any(c.isdigit() for c in record.message) for record in caplog.records
7875
), "Expected a line number in warning message"
7976

8077
def test_warning_includes_offending_text(self, caplog):

tests/test_lenient_no_skillmd.py

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
from skill_scanner.core.loader import SkillLoader, SkillLoadError
3232
from skill_scanner.core.scanner import SkillScanner
3333

34-
3534
# ---------------------------------------------------------------------------
3635
# Fixtures
3736
# ---------------------------------------------------------------------------
@@ -310,9 +309,7 @@ def test_mixed_quotes_and_pipes(self):
310309
"""Complex expressions with mixed quotes and real pipes."""
311310
from skill_scanner.core.analyzers.pipeline_analyzer import PipelineAnalyzer
312311

313-
parts = PipelineAnalyzer._split_pipeline(
314-
"curl -s url | jq '.data[] | {name, value}' | head -5"
315-
)
312+
parts = PipelineAnalyzer._split_pipeline("curl -s url | jq '.data[] | {name, value}' | head -5")
316313
assert len(parts) == 3
317314
assert "curl" in parts[0]
318315
assert "jq" in parts[1]

tests/test_robustness_features.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,11 +181,11 @@ def test_dict_name_coerced_to_string(self, tmp_path):
181181
assert isinstance(skill.name, str)
182182

183183
def test_no_skill_md_still_raises_in_lenient(self, tmp_path):
184-
"""Even in lenient mode, a missing SKILL.md is fatal."""
184+
"""Even in lenient mode, a completely empty dir (no .md files) is fatal."""
185185
empty_dir = tmp_path / "empty"
186186
empty_dir.mkdir()
187187
loader = SkillLoader()
188-
with pytest.raises(SkillLoadError, match="SKILL.md not found"):
188+
with pytest.raises(SkillLoadError, match="No SKILL.md and no .md files found"):
189189
loader.load_skill(empty_dir, lenient=True)
190190

191191

uv.lock

Lines changed: 42 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)