← Back to Skills Marketplace
occupythemilkyway

Argus Pro — Code Intelligence Scanner

by OccupyTheMilkyWay · GitHub ↗ · v1.0.0 · MIT-0
cross-platform ✓ Security Clean
29
Downloads
0
Stars
0
Active Installs
1
Versions
Install in OpenClaw
/install argus-pro
Description
Argus Pro — Code Intelligence Scanner. Scan Python and JavaScript codebases with 40+ rules covering security, bugs, performance, and code quality. Get prio...
README (SKILL.md)

Argus Pro — Full Code Intelligence

Everything in Argus, plus 40+ rules, performance patterns, CI/CD integration, custom ignore paths, and trend JSON for tracking debt over time.

Pro features vs free Argus

Feature Argus (Free) Argus Pro
Rules 20 40+
Languages Python or JS Python + JS simultaneously
Performance rules ❌ ✅ N+1, blocking calls, memory leaks
CI exit code ❌ ✅ FAIL_ON_CRITICAL
Ignore paths ❌ ✅
JSON output Optional ✅ Always (CI-ready)
Finding deduplication Basic ✅ Cross-file smart dedup
Custom severity filter ✅ ✅ + per-rule override

👉 Upgrade: openclaw skills install argus-pro + key at ko-fi.com/occupythemilkyway


Step 1 — Install

pip3 install rich --break-system-packages --quiet

Step 2 — Full code scan (Pro)

import os, re, json, sys
from pathlib import Path
from datetime import date
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich import box

console = Console()

LICENSE_KEY = os.environ.get("LICENSE_KEY","").strip()
if not LICENSE_KEY:
    console.print(Panel(
        "[red bold]🔒 Argus Pro requires a license key.[/red bold]\
\
"
        "Get your key at: [bold cyan]ko-fi.com/occupythemilkyway[/bold cyan]\
\
"
        "Or use the free version: [dim]openclaw skills install argus1[/dim]",
        title="License Required", border_style="red"
    ))
    raise SystemExit(1)

SRC_PATH      = os.environ.get("SOURCE_PATH",".").strip()
LANGUAGE      = os.environ.get("LANGUAGE","auto").lower()
SEV_FILTER    = os.environ.get("SEVERITY_FILTER","all").lower()
try: MAX_FINDINGS = int(os.environ.get("MAX_FINDINGS","100"))
except: MAX_FINDINGS = 100
OUTPUT_JSON   = os.environ.get("OUTPUT_JSON","true").lower() == "true"
FAIL_CRITICAL = os.environ.get("FAIL_ON_CRITICAL","false").lower() == "true"
IGNORE_RAW    = os.environ.get("IGNORE_PATHS","")
IGNORE_PATHS  = [p.strip() for p in IGNORE_RAW.split(",") if p.strip()]
TODAY         = date.today()

src = Path(SRC_PATH)
if not src.exists():
    console.print(f"[red]❌ Path not found: {SRC_PATH}[/red]")
    raise SystemExit(1)

def detect_lang(path):
    py = len(list(path.rglob("*.py") if path.is_dir() else ([path] if str(path).endswith(".py") else [])))
    js = len(list(path.rglob("*.js") if path.is_dir() else ([path] if str(path).endswith(".js") else [])))
    return "python" if py >= js else "javascript"

lang = LANGUAGE if LANGUAGE != "auto" else detect_lang(src)

# Pro: Scan both languages if directory
SCAN_LANGS = ["python","javascript"] if src.is_dir() and LANGUAGE == "auto" else [lang]

# ── Extended rule sets ────────────────────────────────────────────────────────
PYTHON_RULES = [
    # Security
    ("PY001","critical","security", r"\beval\s*\(",                              "eval() executes arbitrary code.",                         "Use ast.literal_eval() for safe literal evaluation."),
    ("PY002","critical","security", r"\bexec\s*\(",                              "exec() executes arbitrary code.",                         "Refactor to eliminate dynamic code execution."),
    ("PY003","critical","security", r"\bpickle\.loads?\s*\(",                  "pickle.load() with untrusted data enables code execution.", "Use json.loads() instead."),
    ("PY004","high","security",     r"(?i)(password|secret|api_key|token|auth_key)\s*=\s*['\"].+['\"]", "Hardcoded credential.", "Use environment variables."),
    ("PY005","high","security",     r"shell\s*=\s*True",                       "shell=True is a command-injection risk.",                  "Use list arguments: subprocess.run(['cmd','arg'])"),
    ("PY006","high","security",     r"\.execute\s*\(.*(%|\.format\(|f['\"])",  "Potential SQL injection via string formatting.",           "Use parameterised queries."),
    ("PY016","medium","security",   r"hashlib\.(md5|sha1)\s*\(",               "MD5/SHA1 are cryptographically weak.",                     "Use hashlib.sha256() or bcrypt for passwords."),
    ("PY017","high","security",     r"\brandom\.(random|randint|choice)\s*\(",  "random module not cryptographically secure.",             "Use secrets module for security-sensitive values."),
    # Bugs
    ("PY007","medium","bug",        r"def\s+\w+\s*\([^)]*=\s*\[\s*\]",        "Mutable default argument [].",                            "Use None as default; init inside function."),
    ("PY008","medium","bug",        r"def\s+\w+\s*\([^)]*=\s*\{\s*\}",        "Mutable default argument {}.",                            "Use None as default; init inside function."),
    ("PY009","medium","bug",        r"except\s*:",                             "Bare except catches SystemExit/KeyboardInterrupt.",       "Catch specific: except ValueError: or except Exception:"),
    ("PY010","medium","bug",        r"==\s*None\b|\bNone\s*==",                "Use 'is None' not '== None'.",                           "Replace with 'is None'."),
    ("PY011","medium","bug",        r"!=\s*None\b|\bNone\s*!=",                "Use 'is not None'.",                                     "Replace with 'is not None'."),
    ("PY018","medium","bug",        r"open\s*\(.+\)(?!\s*as\b)(?!.*with\b)",   "File opened without context manager.",                   "Use 'with open(...) as f:'."),
    ("PY020","medium","bug",        r"\btype\s*\(\w+\)\s*==\s*",               "type() == for type checks is fragile.",                  "Use isinstance() instead."),
    ("PY021","medium","bug",        r"except.*:\s*pass$",                      "Silent exception swallowed — bugs hidden.",               "At minimum log the exception before passing."),
    ("PY022","low","bug",           r"\bassert\s+",                            "assert statements removed by -O flag.",                  "Use explicit if + raise for runtime checks."),
    # Quality
    ("PY012","medium","quality",    r"\bprint\s*\(",                           "print() in production code.",                            "Replace with logging.debug()/logging.info()."),
    ("PY013","low","quality",       r"#\s*(TODO|FIXME|HACK|XXX|BUG)\b",       "Unresolved TODO/FIXME.",                                 "Create a tracked issue and remove the marker."),
    ("PY014","low","quality",       r"from\s+\w+\s+import\s+\*",              "Wildcard import pollutes namespace.",                     "Import only what you need."),
    ("PY015","low","quality",       r"import\s+pdb\b",                        "Debugger import left in code.",                          "Remove before committing."),
    ("PY019","low","quality",       r"lambda\s+\w+:\s*\w+\s*\(",              "Complex lambda — use a named def.",                      "Replace with a def statement."),
    # Performance (Pro only)
    ("PY030","medium","performance",r"for\s+\w+\s+in\s+range\(len\(",         "for i in range(len(x)) is slow and unidiomatic.",        "Use enumerate(x) or iterate directly."),
    ("PY031","medium","performance",r"\+\s*=\s*['\"]",                        "String concatenation in loop builds O(n²) strings.",     "Use ''.join(parts) or an f-string outside the loop."),
    ("PY032","low","performance",   r"\.keys\(\)\s*\)",                       "Iterating .keys() is redundant.",                        "Iterate the dict directly: for k in my_dict."),
    ("PY033","medium","performance",r"time\.sleep\s*\(",                      "Blocking sleep in potentially async context.",            "Use asyncio.sleep() in async functions."),
]

JS_RULES = [
    ("JS001","high","quality",      r"\bvar\s+",                               "var is function-scoped and hoisted.",                    "Use const or let."),
    ("JS002","critical","security", r"\.innerHTML\s*=",                        "innerHTML is an XSS vector.",                           "Use textContent or DOMPurify."),
    ("JS003","critical","security", r"\beval\s*\(",                            "eval() executes arbitrary JS.",                          "Eliminate eval() usage."),
    ("JS004","high","security",     r"(?i)(api_key|apikey|api_secret|access_token|password)\s*=\s*['\"].+['\"]", "Hardcoded credential.", "Use environment variables."),
    ("JS005","medium","bug",        r"==\s*null\b(?!\=)|null\s*==(?!\=)",      "Loose null check also matches undefined.",               "Use === null explicitly."),
    ("JS006","medium","bug",        r"(?\x3C!=)==(?!=)",                          "Loose equality (==) causes type coercion bugs.",         "Use strict equality (===)."),
    ("JS007","medium","quality",    r"\bconsole\.(log|warn|error|debug)\s*\(", "console.log left in production.",                        "Remove or replace with a logging library."),
    ("JS008","medium","security",   r"document\.write\s*\(",                   "document.write() is an XSS risk.",                      "Use DOM manipulation methods instead."),
    ("JS009","low","quality",       r"//\s*(TODO|FIXME|HACK|XXX|BUG)\b",      "Unresolved TODO/FIXME.",                                "Create a tracked issue."),
    ("JS010","high","security",     r"__proto__\s*=",                          "Prototype pollution pattern.",                          "Validate object keys exclude __proto__."),
    ("JS011","medium","bug",        r"setTimeout\s*\(\s*['\"]",                "setTimeout with string calls eval internally.",          "Pass a function: setTimeout(() => fn(), ms)"),
    ("JS012","low","quality",       r"function\s+\w+\s*\([^)]{60,}\)",        "Too many parameters.",                                  "Use an options object instead."),
    # Performance (Pro only)
    ("JS030","medium","performance",r"\.forEach\s*\(.*\.push\s*\(",           "forEach+push is slower than Array.map().",               "Replace with map() for transformations."),
    ("JS031","medium","performance",r"document\.querySelector\s*\(.*\bfor\b", "DOM query inside a loop — expensive.",                  "Cache the element outside the loop."),
    ("JS032","low","performance",   r"JSON\.parse\s*\(JSON\.stringify\s*\(",  "JSON.parse(JSON.stringify()) for deep clone is slow.",   "Use structuredClone() in modern environments."),
]

SEV_ORDER = {"critical":0,"high":1,"medium":2,"low":3}
SEV_FILTER_LEVEL = {"all":3,"low":3,"medium":2,"high":1,"critical":0}.get(SEV_FILTER,3)

def should_skip(filepath, ignore_paths):
    path_str = str(filepath)
    return any(ig in path_str for ig in ignore_paths)

all_findings = []
all_files    = []

for scan_lang in SCAN_LANGS:
    ext   = "*.py" if scan_lang == "python" else "*.js"
    rules = PYTHON_RULES if scan_lang == "python" else JS_RULES
    files = [f for f in (src.rglob(ext) if src.is_dir() else [src]) if not should_skip(f, IGNORE_PATHS)]
    all_files.extend(files)
    for filepath in files:
        try:
            source = filepath.read_text(encoding="utf-8", errors="replace")
            for lineno, line in enumerate(source.splitlines(), 1):
                for rule_id, sev, category, pattern, message, fix in rules:
                    if re.search(pattern, line):
                        if SEV_ORDER.get(sev,3) \x3C= SEV_FILTER_LEVEL:
                            all_findings.append({
                                "id": rule_id, "severity": sev, "category": category,
                                "lang": scan_lang,
                                "file": str(filepath.relative_to(src) if src.is_dir() else filepath),
                                "line": lineno, "code": line.strip()[:80],
                                "message": message, "fix": fix,
                            })
        except Exception as e:
            console.print(f"[dim]Skipping {filepath}: {e}[/dim]")

# Smart dedup
seen = set()
unique = []
for f in all_findings:
    key = (f["id"], f["file"], f["line"])
    if key not in seen:
        seen.add(key)
        unique.append(f)
unique.sort(key=lambda f: (SEV_ORDER.get(f["severity"],3), f["file"], f["line"]))
display = unique[:MAX_FINDINGS]

SEV_COLOUR = {"critical":"red","high":"orange3","medium":"yellow","low":"dim"}

console.print()
console.print(Panel.fit(
    f"[bold red]🐛👁️⚡ Argus Pro — Code Intelligence Scanner[/bold red]\
"
    f"Scanning [yellow]{len(all_files)}[/yellow] file(s)  |  Languages: [cyan]{', '.join(SCAN_LANGS)}[/cyan]  |  Rules: [white]{len(PYTHON_RULES)+len(JS_RULES) if len(SCAN_LANGS)>1 else (len(PYTHON_RULES) if lang=='python' else len(JS_RULES))}[/white]",
    border_style="red"
))

if not unique:
    console.print(Panel("[green]✅ No issues found — clean codebase![/green]", border_style="green"))
else:
    suffix = f" — showing {len(display)} of {len(unique)}" if len(unique) > MAX_FINDINGS else f" — {len(unique)} total"
    tbl = Table(title=f"🔍 Findings{suffix}", box=box.ROUNDED, border_style="red", show_lines=True)
    tbl.add_column("ID",        width=7,  style="dim")
    tbl.add_column("Sev",       width=9)
    tbl.add_column("Cat",       width=12, style="cyan")
    tbl.add_column("Lang",      width=5,  style="magenta")
    tbl.add_column("File:Line", width=30, style="yellow")
    tbl.add_column("Issue",     width=42)
    for fi in display:
        sc  = SEV_COLOUR.get(fi["severity"],"white")
        loc = f"{fi['file'][-26:]}:{fi['line']}" if len(fi["file"])>26 else f"{fi['file']}:{fi['line']}"
        tbl.add_row(fi["id"],f"[{sc}]{fi['severity'].upper()}[/{sc}]",fi["category"],fi["lang"][:2].upper(),loc,fi["message"][:40])
    console.print(tbl)

    for fi in [f for f in display if f["severity"] in ("critical","high")][:5]:
        sc = SEV_COLOUR.get(fi["severity"],"white")
        console.print(Panel(
            f"[dim]File:[/dim] {fi['file']}:{fi['line']}\
"
            f"[dim]Code:[/dim] [italic]{fi['code']}[/italic]\
\
"
            f"[white]{fi['message']}[/white]\
\
"
            f"[green]Fix:[/green] {fi['fix']}",
            title=f"[{sc}][bold]{fi['severity'].upper()}[/bold][/{sc}] — {fi['id']}",
            border_style=sc
        ))

    sev_counts = {s: sum(1 for f in unique if f["severity"]==s) for s in ("critical","high","medium","low")}
    console.print()
    console.print(Panel(
        f"Files: [yellow]{len(all_files)}[/yellow]  Issues: [red]{len(unique)}[/red]  "
        + "  ".join(f"[{SEV_COLOUR[s]}]{s.title()}: {sev_counts[s]}[/{SEV_COLOUR[s]}]" for s in ("critical","high","medium","low") if sev_counts[s]),
        title="Summary", border_style="cyan"
    ))

# Save
report_file = f"argus_pro_report_{TODAY}.md"
json_file   = f"argus_pro_report_{TODAY}.json"

with open(report_file,"w",encoding="utf-8") as f:
    f.write(f"# 🐛 Argus Pro Report — {TODAY}\
\
**Path:** `{SRC_PATH}`  **Files:** {len(all_files)}  **Issues:** {len(unique)}\
\
")
    f.write("## Findings\
\
| ID | Severity | Category | Lang | File:Line | Issue |\
|---|---|---|---|---|---|\
")
    for fi in unique:
        f.write(f"| {fi['id']} | {fi['severity'].upper()} | {fi['category']} | {fi['lang']} | {fi['file'][:30]}:{fi['line']} | {fi['message'][:50]} |\
")
    f.write("\
## Fix Guide (Critical + High)\
\
")
    for fi in [x for x in unique if x["severity"] in ("critical","high")]:
        f.write(f"### {fi['id']} — {fi['file']}:{fi['line']}\
**Issue:** {fi['message']}\
**Fix:** {fi['fix']}\
```\
{fi['code']}\
```\
\
")

with open(json_file,"w",encoding="utf-8") as f:
    json.dump({"date":str(TODAY),"path":SRC_PATH,"files":len(all_files),"findings":unique},f,indent=2)

console.print(Panel(f"[green]✅ Done![/green]  [cyan]{report_file}[/cyan]  |  [cyan]{json_file}[/cyan]",border_style="green"))

if FAIL_CRITICAL and any(f["severity"]=="critical" for f in unique):
    console.print("[red]CI: Exiting with code 1 — critical findings detected.[/red]")
    sys.exit(1)
Usage Guidance
This skill looks coherent for local Python/JavaScript static analysis. Before installing, use a virtual environment for the dependency install, protect the LICENSE_KEY, set SOURCE_PATH and IGNORE_PATHS to avoid scanning unintended files, and keep any JSON scan reports private.
Capability Analysis
Type: OpenClaw Skill Name: argus-pro Version: 1.0.0 The Argus Pro skill is a static analysis tool designed to scan Python and JavaScript codebases for security vulnerabilities, bugs, and performance issues using predefined regex patterns. The script (SKILL.md) operates locally, reading files from a user-specified path and generating Markdown and JSON reports without any evidence of data exfiltration, unauthorized network communication, or malicious execution logic.
Capability Tags
requires-sensitive-credentials
Capability Assessment
Purpose & Capability
The requested capabilities fit the stated purpose of scanning Python and JavaScript code, including recursive source scanning and JSON reporting, but scan outputs may contain sensitive code or security details.
Instruction Scope
The visible instructions are aimed at installing a display dependency and running a local scanner; no goal-hijacking, hidden role changes, or deceptive agent-control instructions were shown.
Install Mechanism
There is no install spec; setup is a Markdown instruction to install an unpinned PyPI package using pip with --break-system-packages. This is visible and purpose-related, but users should prefer a virtual environment.
Credentials
Default scanning starts at SOURCE_PATH='.' and can recursively inspect local Python and JavaScript files. This is expected for a code scanner, but users should set SOURCE_PATH and IGNORE_PATHS deliberately.
Persistence & Privilege
The skill requires a LICENSE_KEY and defaults to JSON output/trend-style reporting, but the shown artifacts do not show background persistence, credential exfiltration, or autonomous account mutation.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install argus-pro
  3. After installation, invoke the skill by name or use /argus-pro
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.0
Initial Pro release: 40+ rules, performance patterns, CI/CD integration, custom ignore paths, JSON output
Metadata
Slug argus-pro
Version 1.0.0
License MIT-0
All-time Installs 0
Active Installs 0
Total Versions 1
Frequently Asked Questions

What is Argus Pro — Code Intelligence Scanner?

Argus Pro — Code Intelligence Scanner. Scan Python and JavaScript codebases with 40+ rules covering security, bugs, performance, and code quality. Get prio... It is an AI Agent Skill for Claude Code / OpenClaw, with 29 downloads so far.

How do I install Argus Pro — Code Intelligence Scanner?

Run "/install argus-pro" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is Argus Pro — Code Intelligence Scanner free?

Yes, Argus Pro — Code Intelligence Scanner is completely free, licensed under MIT-0. You can download, install and use it at no cost.

Which platforms does Argus Pro — Code Intelligence Scanner support?

Argus Pro — Code Intelligence Scanner is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created Argus Pro — Code Intelligence Scanner?

It is built and maintained by OccupyTheMilkyWay (@occupythemilkyway); the current version is v1.0.0.

💬 Comments