mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-29 06:31:32 +00:00
refactor(skills): slim AST diagnostic to single entry point
Trim ~600 LOC off the original contribution while keeping the same operator-facing surface and detection coverage. - Collapse three entry points (file / dir / bundle) into one ast_scan_path(path) that handles both files and directories. - Drop AstFinding dataclass + severity field — replaced with plain (file, line, pattern_id, description) tuples. Severity ordering was display-only for a diagnostic that explicitly disclaims security verdicts, so the field added bookkeeping without earning its place. - Replace Rich-markup formatter with plain text grouped by file. - Drop the 'inspect --ast-deep' surface — same scanner, same output as 'audit --deep', single CLI entry is enough. Operators audit after install; pre-install inspection signal isn't worth the second surface. - Trim test file to the cases that earn their place: bypass payload, syntax error survival, RecursionError survival, false-positive guard (importer lookalike), literal-arg false-positive guard, non-.py ignored, directory recursion + cache-dir skipping, missing-path, getattr/__dict__ detection, formatter empty + populated. Net: tools/skills_ast_audit.py 353 -> 133 LOC, tests/tools/test_skills_ast_audit.py 299 -> 103 LOC, full diff +704/-12 -> +264/-6. No change to tools/skills_guard.py — Skills Guard verdicts remain untouched per SECURITY.md §2.4.
This commit is contained in:
parent
7255050c99
commit
4254f7dd17
4 changed files with 175 additions and 609 deletions
|
|
@ -12267,11 +12267,6 @@ Examples:
|
|||
"inspect", help="Preview a skill without installing"
|
||||
)
|
||||
skills_inspect.add_argument("identifier", help="Skill identifier")
|
||||
skills_inspect.add_argument(
|
||||
"--ast-deep",
|
||||
action="store_true",
|
||||
help="Run AST-level diagnostics on Python files before installing",
|
||||
)
|
||||
|
||||
skills_list = skills_subparsers.add_parser("list", help="List installed skills")
|
||||
skills_list.add_argument(
|
||||
|
|
|
|||
|
|
@ -630,13 +630,8 @@ def do_install(identifier: str, category: str = "", force: bool = False,
|
|||
c.print("[dim]Use /reset to start a new session now, or --now to activate immediately (invalidates prompt cache).[/]\n")
|
||||
|
||||
|
||||
def do_inspect(identifier: str, console: Optional[Console] = None,
|
||||
ast_deep: bool = False) -> None:
|
||||
"""Preview a skill's SKILL.md content without installing.
|
||||
|
||||
When ``ast_deep=True``, also runs AST-level diagnostics against Python
|
||||
files in the fetched bundle before installation.
|
||||
"""
|
||||
def do_inspect(identifier: str, console: Optional[Console] = None) -> None:
|
||||
"""Preview a skill's SKILL.md content without installing."""
|
||||
from tools.skills_hub import GitHubAuth, create_source_router
|
||||
|
||||
c = console or _console
|
||||
|
|
@ -682,11 +677,6 @@ def do_inspect(identifier: str, console: Optional[Console] = None,
|
|||
preview += f"\n\n... ({len(lines) - 50} more lines)"
|
||||
c.print(Panel(preview, title="SKILL.md Preview", subtitle="hermes skills install <id> to install"))
|
||||
|
||||
if bundle and ast_deep:
|
||||
from tools.skills_ast_audit import ast_scan_bundle_files, format_ast_report
|
||||
ast_findings = ast_scan_bundle_files(bundle.files)
|
||||
c.print(format_ast_report(ast_findings, skill_name=meta.name))
|
||||
|
||||
c.print()
|
||||
|
||||
|
||||
|
|
@ -920,8 +910,9 @@ def do_audit(name: Optional[str] = None, console: Optional[Console] = None,
|
|||
deep: bool = False) -> None:
|
||||
"""Re-run security scan on installed hub skills.
|
||||
|
||||
When ``deep=True``, also runs AST-level analysis on Python files
|
||||
(opt-in diagnostic, not a security gate).
|
||||
When ``deep=True``, also runs an opt-in AST-level diagnostic on Python
|
||||
files (review aid only — not a security gate; skills_guard.py verdicts
|
||||
are unchanged).
|
||||
"""
|
||||
from tools.skills_hub import HubLockFile, SKILLS_DIR
|
||||
from tools.skills_guard import scan_skill, format_scan_report
|
||||
|
|
@ -943,9 +934,8 @@ def do_audit(name: Optional[str] = None, console: Optional[Console] = None,
|
|||
|
||||
c.print(f"\n[bold]Auditing {len(targets)} skill(s)...[/]\n")
|
||||
|
||||
ast_scan_skill = format_ast_report = None
|
||||
if deep:
|
||||
from tools.skills_ast_audit import ast_scan_skill, format_ast_report
|
||||
from tools.skills_ast_audit import ast_scan_path, format_ast_report
|
||||
|
||||
for entry in targets:
|
||||
skill_path = SKILLS_DIR / entry["install_path"]
|
||||
|
|
@ -957,8 +947,7 @@ def do_audit(name: Optional[str] = None, console: Optional[Console] = None,
|
|||
c.print(format_scan_report(result))
|
||||
|
||||
if deep:
|
||||
ast_findings = ast_scan_skill(skill_path)
|
||||
c.print(format_ast_report(ast_findings, skill_name=entry["name"]))
|
||||
c.print(format_ast_report(ast_scan_path(skill_path), skill_name=entry["name"]))
|
||||
|
||||
c.print()
|
||||
|
||||
|
|
@ -1356,7 +1345,7 @@ def skills_command(args) -> None:
|
|||
skip_confirm=getattr(args, "yes", False),
|
||||
name_override=getattr(args, "name", "") or "")
|
||||
elif action == "inspect":
|
||||
do_inspect(args.identifier, ast_deep=getattr(args, "ast_deep", False))
|
||||
do_inspect(args.identifier)
|
||||
elif action == "list":
|
||||
do_list(
|
||||
source_filter=args.source,
|
||||
|
|
@ -1414,7 +1403,6 @@ def handle_skills_slash(cmd: str, console: Optional[Console] = None) -> None:
|
|||
/skills install openai/skills/skill-creator --force
|
||||
/skills install https://example.com/path/SKILL.md
|
||||
/skills inspect openai/skills/skill-creator
|
||||
/skills inspect openai/skills/skill-creator --ast-deep
|
||||
/skills list
|
||||
/skills list --source hub
|
||||
/skills check
|
||||
|
|
@ -1514,11 +1502,10 @@ def handle_skills_slash(cmd: str, console: Optional[Console] = None) -> None:
|
|||
name_override=name_override, console=c)
|
||||
|
||||
elif action == "inspect":
|
||||
non_flag_args = [arg for arg in args if not arg.startswith("--")]
|
||||
if not non_flag_args:
|
||||
c.print("[bold red]Usage:[/] /skills inspect <identifier> [--ast-deep]\n")
|
||||
if not args:
|
||||
c.print("[bold red]Usage:[/] /skills inspect <identifier>\n")
|
||||
return
|
||||
do_inspect(non_flag_args[0], console=c, ast_deep="--ast-deep" in args)
|
||||
do_inspect(args[0], console=c)
|
||||
|
||||
elif action == "list":
|
||||
source_filter = "all"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue