{"id":"3ff12022-cf22-4d0b-9d2c-02660dcdf523","entityType":"agent","slug":"clawhub-occupythemilkyway-argus1","name":"Argus — The Hundred-Eyed","canonicalUrl":"https://www.xpersona.co/agent/clawhub-occupythemilkyway-argus1","canonicalPath":"/agent/clawhub-occupythemilkyway-argus1","generatedAt":"2026-10-14T12:14:09.046Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":null},"description":"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior... Skill: Argus — The Hundred-Eyed Owner: occupythemilkyway Summary: Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior... Tags: bugs:1.0.0, code:1.0.0, code-review:1.0.1, debugging:1.0.1, javascript:1.0.1, latest:1.0.4, python:1.0.1, scanner:1.0.0, security:1.0.1 Version history: v1.0.4 | 2026-05-24T04:28:05.341Z","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 963 downloads reported by the source. Last updated 10/12/2026.","installCommand":"clawhub skill install s1757zbbgb226m951fdfmj4s6s860nkn:argus1","sourceUrl":"https://clawhub.ai/occupythemilkyway/argus1","homepage":"https://clawhub.ai/occupythemilkyway/skills/argus1","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/occupythemilkyway/argus1","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/occupythemilkyway/skills/argus1","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior..."},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":null},"stars":null,"forks":null,"downloads":963,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"1.0.4","tractionLabel":"963 downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-12T01:04:52.703Z","emptyReason":null},"lastUpdatedAt":"2026-10-12T01:04:52.770Z","lastCrawledAt":"2026-10-12T01:04:52.703Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-13T01:04:52.703Z","lastVerifiedAt":null,"highlights":[{"version":"1.0.4","createdAt":"2026-05-24T04:28:05.341Z","changelog":"Argus skill rewritten as a code vulnerability scanner for Python and JavaScript. - Completely reworked: now scans Python or JavaScript files/directories for security issues, bugs, and code smells. - Provides a prioritised report with line numbers, severity ratings, and fix suggestions. - Simple configuration via environment variables (e.g., SOURCE_PATH, SEVERITY_FILTER). - No dependencies on external services—local analysis only. - Previous blockchain/intel/risk assessment endpoints and documentation removed.","fileCount":3,"zipByteSize":7721},{"version":"1.0.1","createdAt":"2026-05-09T20:10:27.454Z","changelog":"Improvement: expanded rule set to 20 Python + 12 JS rules, JSON export, better severity filtering","fileCount":2,"zipByteSize":6493},{"version":"1.0.0","createdAt":"2026-05-05T06:24:00.955Z","changelog":"Initial release of Argus — code intelligence scanner for Python and JavaScript. - Scans Python and JavaScript codebases for bugs, security vulnerabilities, code smells, and anti-patterns. - Provides prioritized results with line numbers, severity ratings, and suggested corrections. - Supports severity filtering and language auto-detection. - Outputs detailed reports in both Markdown and JSON formats. - No external API; local-only file analysis for privacy.","fileCount":2,"zipByteSize":5024}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s1757zbbgb226m951fdfmj4s6s860nkn:argus1","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-14T12:14:09.046Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-occupythemilkyway-argus1/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":null},"readme":"Skill: Argus — The Hundred-Eyed\n\nOwner: occupythemilkyway\n\nSummary: Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior...\n\nTags: bugs:1.0.0, code:1.0.0, code-review:1.0.1, debugging:1.0.1, javascript:1.0.1, latest:1.0.4, python:1.0.1, scanner:1.0.0, security:1.0.1\n\nVersion history:\n\nv1.0.4 | 2026-05-24T04:28:05.341Z | user\n\nArgus skill rewritten as a code vulnerability scanner for Python and JavaScript.\n\n- Completely reworked: now scans Python or JavaScript files/directories for security issues, bugs, and code smells.\n- Provides a prioritised report with line numbers, severity ratings, and fix suggestions.\n- Simple configuration via environment variables (e.g., SOURCE_PATH, SEVERITY_FILTER).\n- No dependencies on external services—local analysis only.\n- Previous blockchain/intel/risk assessment endpoints and documentation removed.\n\nv1.0.1 | 2026-05-09T20:10:27.454Z | user\n\nImprovement: expanded rule set to 20 Python + 12 JS rules, JSON export, better severity filtering\n\nv1.0.0 | 2026-05-05T06:24:00.955Z | user\n\nInitial release of Argus — code intelligence scanner for Python and JavaScript.\n\n- Scans Python and JavaScript codebases for bugs, security vulnerabilities, code smells, and anti-patterns.\n- Provides prioritized results with line numbers, severity ratings, and suggested corrections.\n- Supports severity filtering and language auto-detection.\n- Outputs detailed reports in both Markdown and JSON formats.\n- No external API; local-only file analysis for privacy.\n\nArchive index:\n\nArchive v1.0.4: 3 files, 7721 bytes\n\nFiles: skill-card.md (1871b), SKILL.md (18422b), _meta.json (125b)\n\nFile v1.0.4:SKILL.md\n\n---\nname: argus1\ndescription: \"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prioritised findings report with line numbers, severity ratings, and fix suggestions. No external tools required.\"\nversion: \"1.0.4\"\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins: [python3, pip3]\n    primaryEnv: \"SOURCE_PATH\"\n    homepage: https://clawhub.ai/occupythemilkyway/argus1\n    emoji: \"ððï¸\"\n    tags: [debugging, security, code-review, python, javascript, linter, argus, static-analysis]\n    envVars:\n      - name: SOURCE_PATH\n        required: false\n        description: \"Path to a .py or .js file, or a directory to scan recursively. Defaults to current directory.\"\n        default: \".\"\n      - name: LANGUAGE\n        required: false\n        description: \"Language to scan: python, javascript, or auto (detects from file extensions)\"\n        default: \"auto\"\n      - name: SEVERITY_FILTER\n        required: false\n        description: \"Minimum severity to report: critical, high, medium, low, or all\"\n        default: \"all\"\n      - name: MAX_FINDINGS\n        required: false\n        description: \"Maximum number of findings to display (default: 50)\"\n        default: \"50\"\n      - name: OUTPUT_JSON\n        required: false\n        description: \"Set to 'true' to also save findings as JSON\"\n        default: \"false\"\n---\n\n# Argus â Code Intelligence Scanner\n\nScan any Python or JavaScript codebase for bugs, security holes, and anti-patterns in seconds â with line numbers, severity ratings, and actionable fix suggestions.\n\n## What Argus catches\n\n**Security** â SQL injection patterns, hardcoded secrets, eval/exec abuse, innerHTML XSS, open redirects, pickle deserialization  \n**Bugs** â mutable default arguments, bare except clauses, missing null checks, == None comparisons  \n**Code quality** â broad imports, print statements in production, TODO/FIXME markers, deeply nested code  \n**JavaScript** â var usage, loose equality (==), console.log left in, prototype pollution patterns\n\n## Quick start\n\n```bash\nSOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" openclaw skills run argus1\n```\n\n## ð Security\n\nReads local files only. Nothing transmitted outside your machine.\n\n---\n\n## Step 1 â Install\n\n```bash\npip3 install rich --break-system-packages --quiet\n```\n\n---\n\n\n---\n\n## â¡ Upgrade to Argus Pro\n\nð **Get Argus Pro** â **ko-fi.com/s/8b27346505** â $9 one-time\n\n```bash\nopenclaw skills install argus-pro\n# Set LICENSE_KEY env var to your key from Ko-fi, then run\n```\n\nð° **Bundle deal:** all 5 Pro skills for **$29** â **ko-fi.com/s/7625accf3f** (save $16)\n\n## Step 2 â Scan for bugs and vulnerabilities\n\n```python\nimport os, re, json\nfrom pathlib import Path\nfrom datetime import date\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich.panel import Panel\nfrom rich import box\n\nFENCE = chr(96) * 3\n\nconsole = Console()\n\nSRC_PATH   = os.environ.get(\"SOURCE_PATH\", \".\").strip()\nLANGUAGE   = os.environ.get(\"LANGUAGE\", \"auto\").lower().strip()\nSEV_FILTER = os.environ.get(\"SEVERITY_FILTER\", \"all\").lower().strip()\ntry:\n    MAX_FINDINGS = int(os.environ.get(\"MAX_FINDINGS\", \"50\"))\nexcept ValueError:\n    MAX_FINDINGS = 50\nOUTPUT_JSON = os.environ.get(\"OUTPUT_JSON\", \"false\").lower() == \"true\"\nTODAY       = date.today()\n\nsrc = Path(SRC_PATH)\nif not src.exists():\n    console.print(f\"[red]â Path not found: {SRC_PATH}[/red]\")\n    raise SystemExit(1)\n\ndef detect_lang(path: Path) -> str:\n    py = len(list(path.rglob(\"*.py\") if path.is_dir() else ([path] if str(path).endswith(\".py\") else [])))\n    js = len(list(path.rglob(\"*.js\") if path.is_dir() else ([path] if str(path).endswith(\".js\") else [])))\n    if py >= js:\n        return \"python\"\n    return \"javascript\"\n\nlang = LANGUAGE if LANGUAGE != \"auto\" else detect_lang(src)\next  = \"*.py\" if lang == \"python\" else \"*.js\"\n\n# ââ Rule definitions: (id, severity, category, regex, message, fix) ââââââââââ\nPYTHON_RULES = [\n    (\"PY001\", \"critical\", \"security\",  r\"\\beval\\s*\\(\",                     \"eval() executes arbitrary code â extremely dangerous with user input.\",               \"Use ast.literal_eval() for safe evaluation of literals.\"),\n    (\"PY002\", \"critical\", \"security\",  r\"\\bexec\\s*\\(\",                     \"exec() executes arbitrary strings as Python code.\",                                   \"Refactor to avoid dynamic code execution.\"),\n    (\"PY003\", \"critical\", \"security\",  r\"\\bpickle\\.loads?\\s*\\(\",           \"pickle.load() can execute arbitrary code when deserialising untrusted data.\",         \"Use json.loads() or a safe serialisation format instead.\"),\n    (\"PY004\", \"high\",     \"security\",  r\"(?i)(password|secret|api_key|token|auth_key)\\s*=\\s*['\\\"].+['\\\"]\", \"Hardcoded credential detected.\",                      \"Store secrets in environment variables, never in source code.\"),\n    (\"PY005\", \"high\",     \"security\",  r\"shell\\s*=\\s*True\",                \"shell=True in subprocess is a command-injection risk.\",                               \"Pass a list of arguments instead: subprocess.run(['cmd', 'arg'])\"),\n    (\"PY006\", \"high\",     \"security\",  r\"\\.execute\\s*\\(.*(%|\\.format\\(|f['\\\"])\", \"Potential SQL injection via string formatting in execute().\",                   \"Use parameterised queries: cursor.execute(sql, (param,))\"),\n    (\"PY007\", \"medium\",   \"bug\",       r\"def\\s+\\w+\\s*\\([^)]*=\\s*\\[\\s*\\]\", \"Mutable default argument [] â shared across all calls.\",                             \"Use None as default and initialise inside the function.\"),\n    (\"PY008\", \"medium\",   \"bug\",       r\"def\\s+\\w+\\s*\\([^)]*=\\s*\\{\\s*\\}\", \"Mutable default argument {} â shared across all calls.\",                             \"Use None as default and initialise inside the function.\"),\n    (\"PY009\", \"medium\",   \"bug\",       r\"except\\s*:\",                      \"Bare except: catches SystemExit and KeyboardInterrupt â almost never intentional.\",   \"Catch specific exceptions: except ValueError: or except Exception:\"),\n    (\"PY010\", \"medium\",   \"bug\",       r\"==\\s*None\\b|\\bNone\\s*==\",         \"Use 'is None' instead of '== None'.\",                                                \"Replace '== None' with 'is None' and '!= None' with 'is not None'.\"),\n    (\"PY011\", \"medium\",   \"bug\",       r\"!=\\s*None\\b|\\bNone\\s*!=\",         \"Use 'is not None' instead of '!= None'.\",                                            \"Replace '!= None' with 'is not None'.\"),\n    (\"PY012\", \"medium\",   \"quality\",   r\"\\bprint\\s*\\(\",                    \"print() statement found â likely debug output left in production code.\",              \"Remove or replace with logging.debug() / logging.info().\"),\n    (\"PY013\", \"low\",      \"quality\",   r\"#\\s*(TODO|FIXME|HACK|XXX|BUG)\\b\", \"Unresolved TODO/FIXME marker.\",                                                      \"Resolve or create a tracked issue for this item.\"),\n    (\"PY014\", \"low\",      \"quality\",   r\"from\\s+\\w+\\s+import\\s+\\*\",        \"Wildcard import pollutes namespace and makes dependencies unclear.\",                  \"Import only what you need: from module import specific_name\"),\n    (\"PY015\", \"low\",      \"quality\",   r\"import\\s+pdb\\b\",                  \"Debugger import (pdb) left in code.\",                                                 \"Remove pdb import before committing to production.\"),\n    (\"PY016\", \"medium\",   \"security\",  r\"hashlib\\.(md5|sha1)\\s*\\(\",        \"MD5/SHA1 are cryptographically weak â not suitable for passwords or signatures.\",     \"Use hashlib.sha256() or better; bcrypt/argon2 for passwords.\"),\n    (\"PY017\", \"high\",     \"security\",  r\"random\\.(random|randint|choice)\\s*\\(\", \"random module is not cryptographically secure.\",                                 \"Use secrets module for security-sensitive random values.\"),\n    (\"PY018\", \"medium\",   \"bug\",       r\"open\\s*\\(.+\\)(?!\\s*as\\b)(?!.*with\\b)\", \"File opened without context manager â may leak file handle.\",                   \"Use 'with open(...) as f:' to ensure proper cleanup.\"),\n    (\"PY019\", \"low\",      \"quality\",   r\"lambda\\s+\\w+:\\s*\\w+\\s*\\(\",        \"Lambda used where a named function would be clearer.\",                               \"Consider replacing with a def statement for readability.\"),\n    (\"PY020\", \"medium\",   \"bug\",       r\"\\btype\\s*\\(\\w+\\)\\s*==\\s*\",        \"Use isinstance() instead of type() == for type checks.\",                             \"Replace type(x) == SomeType with isinstance(x, SomeType).\"),\n]\n\nJS_RULES = [\n    (\"JS001\", \"high\",     \"quality\",   r\"\\bvar\\s+\",                        \"var is function-scoped and hoisted â causes subtle bugs.\",                            \"Use const or let instead.\"),\n    (\"JS002\", \"critical\", \"security\",  r\"\\.innerHTML\\s*=\",                 \"innerHTML assignment is an XSS vector if content comes from user input.\",             \"Use textContent for text or DOMPurify to sanitise HTML.\"),\n    (\"JS003\", \"critical\", \"security\",  r\"\\beval\\s*\\(\",                     \"eval() executes arbitrary JavaScript â a critical security risk.\",                    \"Refactor to eliminate eval() usage entirely.\"),\n    (\"JS004\", \"high\",     \"security\",  r\"(?i)(api_key|apikey|api_secret|access_token|auth_token|password)\\s*=\\s*['\\\"].+['\\\"]\", \"Hardcoded credential detected.\", \"Move secrets to environment variables or a secrets manager.\"),\n    (\"JS005\", \"medium\",   \"bug\",       r\"==\\s*null\\b(?!\\=)|null\\s*==(?!\\=)\", \"Loose equality with null also matches undefined â usually unintentional.\",         \"Use === null or check explicitly for both null and undefined.\"),\n    (\"JS006\", \"medium\",   \"bug\",       r\"(?<!=)==(?!=)\",                   \"Loose equality (==) performs type coercion â a common source of bugs.\",              \"Use strict equality (===) instead.\"),\n    (\"JS007\", \"medium\",   \"quality\",   r\"\\bconsole\\.(log|warn|error|debug)\\s*\\(\", \"console.log left in production code.\",                                         \"Remove or replace with a proper logging library.\"),\n    (\"JS008\", \"medium\",   \"security\",  r\"document\\.write\\s*\\(\",            \"document.write() can overwrite the entire page and is an XSS risk.\",                 \"Use DOM manipulation methods (createElement, appendChild) instead.\"),\n    (\"JS009\", \"low\",      \"quality\",   r\"//\\s*(TODO|FIXME|HACK|XXX|BUG)\\b\", \"Unresolved TODO/FIXME marker.\",                                                    \"Resolve or create a tracked issue for this item.\"),\n    (\"JS010\", \"high\",     \"security\",  r\"__proto__\\s*=|Object\\.assign\\s*\\(\\s*\\{\\s*\\},\", \"Potential prototype pollution pattern.\",                                 \"Validate that object keys don't include __proto__ or constructor.\"),\n    (\"JS011\", \"medium\",   \"bug\",       r\"setTimeout\\s*\\(\\s*['\\\"]\",         \"setTimeout with a string argument calls eval internally.\",                           \"Pass a function reference instead: setTimeout(() => doThing(), ms)\"),\n    (\"JS012\", \"low\",      \"quality\",   r\"function\\s+\\w+\\s*\\([^)]{60,}\\)\",  \"Function has too many parameters â consider an options object.\",                    \"Refactor long parameter lists into a single options/config object.\"),\n]\n\nRULES = PYTHON_RULES if lang == \"python\" else JS_RULES\nSEV_ORDER = {\"critical\": 0, \"high\": 1, \"medium\": 2, \"low\": 3}\nSEV_FILTER_LEVEL = {\"all\": 3, \"low\": 3, \"medium\": 2, \"high\": 1, \"critical\": 0}.get(SEV_FILTER, 3)\n\nfiles = list(src.rglob(ext) if src.is_dir() else [src])\nif not files:\n    console.print(f\"[yellow]No {ext} files found in {SRC_PATH}[/yellow]\")\n    raise SystemExit(0)\n\nconsole.print()\nconsole.print(Panel.fit(\n    f\"[bold red]ð ðï¸  Argus â Code Intelligence Scanner[/bold red]\\n\"\n    f\"Scanning [yellow]{len(files)}[/yellow] {lang} file(s) in [cyan]{SRC_PATH}[/cyan] \"\n    f\"| Severity: [white]{SEV_FILTER}[/white] | Rules: [white]{len(RULES)}[/white]\",\n    border_style=\"red\"\n))\n\nfindings = []\nfor filepath in files:\n    try:\n        source = filepath.read_text(encoding=\"utf-8\", errors=\"replace\")\n        lines  = source.splitlines()\n        for lineno, line in enumerate(lines, 1):\n            for rule_id, sev, category, pattern, message, fix in RULES:\n                if re.search(pattern, line):\n                    if SEV_ORDER.get(sev, 3) <= SEV_FILTER_LEVEL:\n                        findings.append({\n                            \"id\":       rule_id,\n                            \"severity\": sev,\n                            \"category\": category,\n                            \"file\":     str(filepath.relative_to(src) if src.is_dir() else filepath),\n                            \"line\":     lineno,\n                            \"code\":     line.strip()[:80],\n                            \"message\":  message,\n                            \"fix\":      fix,\n                        })\n    except Exception as e:\n        console.print(f\"[dim]Skipping {filepath}: {e}[/dim]\")\n\n# Deduplicate by (rule, file, line)\nseen = set()\nunique = []\nfor f in findings:\n    key = (f[\"id\"], f[\"file\"], f[\"line\"])\n    if key not in seen:\n        seen.add(key)\n        unique.append(f)\n\n# Sort by severity then file/line\nunique.sort(key=lambda f: (SEV_ORDER.get(f[\"severity\"], 3), f[\"file\"], f[\"line\"]))\ndisplay = unique[:MAX_FINDINGS]\n\n# ââ Display results âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\nSEV_COLOUR = {\"critical\": \"red\", \"high\": \"orange3\", \"medium\": \"yellow\", \"low\": \"dim\"}\n\nif not unique:\n    console.print(Panel(\n        \"[green]â No issues found![/green]\\n\\n\"\n        f\"Scanned {len(files)} file(s) with {len(RULES)} rules â all clear.\",\n        border_style=\"green\"\n    ))\nelse:\n    display_count = len(display)\n    title_suffix  = f\" â showing {display_count} of {len(unique)}\" if len(unique) > MAX_FINDINGS else f\" â {len(unique)} found\"\n    findings_table = Table(\n        title=f\"ð Findings{title_suffix}\",\n        box=box.ROUNDED, border_style=\"red\", show_lines=True\n    )\n    findings_table.add_column(\"ID\",       style=\"dim\",    width=7)\n    findings_table.add_column(\"Sev\",      style=\"white\",  width=9)\n    findings_table.add_column(\"Cat\",      style=\"cyan\",   width=10)\n    findings_table.add_column(\"File:Line\",style=\"yellow\", width=28)\n    findings_table.add_column(\"Issue\",    style=\"white\",  width=45)\n\n    for fi in display:\n        sc   = SEV_COLOUR.get(fi[\"severity\"], \"white\")\n        loc  = f\"{fi['file'][-24:]}:{fi['line']}\" if len(fi[\"file\"]) > 24 else f\"{fi['file']}:{fi['line']}\"\n        findings_table.add_row(\n            fi[\"id\"],\n            f\"[{sc}]{fi['severity'].upper()}[/{sc}]\",\n            fi[\"category\"],\n            loc,\n            fi[\"message\"][:43],\n        )\n    console.print(findings_table)\n\n    # Detailed panels for critical/high\n    critical_high = [f for f in display if f[\"severity\"] in (\"critical\", \"high\")]\n    if critical_high:\n        console.print()\n        for fi in critical_high[:5]:\n            sc = SEV_COLOUR.get(fi[\"severity\"], \"white\")\n            console.print(Panel(\n                f\"[dim]File:[/dim]  {fi['file']}:{fi['line']}\\n\"\n                f\"[dim]Code:[/dim]  [italic]{fi['code']}[/italic]\\n\\n\"\n                f\"[white]{fi['message']}[/white]\\n\\n\"\n                f\"[green]Fix:[/green] {fi['fix']}\",\n                title=f\"[{sc}][bold]{fi['severity'].upper()}[/bold][/{sc}] â {fi['id']}\",\n                border_style=sc\n            ))\n\n    # Summary by severity\n    console.print()\n    sev_counts = {s: sum(1 for f in unique if f[\"severity\"] == s)\n                  for s in (\"critical\", \"high\", \"medium\", \"low\")}\n    summary_lines = \"  \".join(\n        f\"[{SEV_COLOUR[s]}]{s.title()}: {sev_counts[s]}[/{SEV_COLOUR[s]}]\"\n        for s in (\"critical\", \"high\", \"medium\", \"low\") if sev_counts[s]\n    )\n    console.print(Panel(\n        f\"Files scanned: [yellow]{len(files)}[/yellow]   \"\n        f\"Total issues: [red]{len(unique)}[/red]   {summary_lines}\",\n        title=\"Summary\",\n        border_style=\"cyan\"\n    ))\n\n# ââ Save outputs ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\nreport_file = f\"argus_report_{TODAY}.md\"\nwith open(report_file, \"w\", encoding=\"utf-8\") as f:\n    f.write(f\"# ð Argus Code Scan Report â {TODAY}\\n\\n\")\n    f.write(f\"**Path:** `{SRC_PATH}`  **Language:** {lang}  **Files:** {len(files)}  **Issues:** {len(unique)}\\n\\n\")\n    sev_counts = {s: sum(1 for fi in unique if fi[\"severity\"] == s) for s in (\"critical\",\"high\",\"medium\",\"low\")}\n    f.write(f\"**Critical:** {sev_counts['critical']}  **High:** {sev_counts['high']}  **Medium:** {sev_counts['medium']}  **Low:** {sev_counts['low']}\\n\\n\")\n    f.write(\"## Findings\\n\\n| ID | Severity | Category | File:Line | Issue |\\n|---|---|---|---|---|\\n\")\n    for fi in unique:\n        f.write(f\"| {fi['id']} | {fi['severity'].upper()} | {fi['category']} | {fi['file'][:30]}:{fi['line']} | {fi['message'][:60]} |\\n\")\n    f.write(\"\\n## Fix Suggestions\\n\\n\")\n    for fi in [x for x in unique if x[\"severity\"] in (\"critical\",\"high\")]:\n        f.write(f\"### {fi['id']} â {fi['file']}:{fi['line']}\\n\\n\")\n        f.write(f\"**Issue:** {fi['message']}\\n\\n\")\n        f.write(f\"**Fix:** {fi['fix']}\\n\\n\")\n        f.write(f\"{FENCE}\\n{fi['code']}\\n{FENCE}\\n\\n\")\n\nif OUTPUT_JSON:\n    json_file = f\"argus_report_{TODAY}.json\"\n    with open(json_file, \"w\", encoding=\"utf-8\") as f:\n        json.dump({\"scanned\": str(TODAY), \"path\": SRC_PATH, \"language\": lang,\n                   \"files\": len(files), \"findings\": unique}, f, indent=2)\n    console.print(f\"[dim]JSON saved to {json_file}[/dim]\")\n\nconsole.print(Panel(\n    f\"[green]â Scan complete![/green]  Report saved to [cyan]{report_file}[/cyan]\",\n    border_style=\"green\"\n))\n```\n\nFile v1.0.4:_meta.json\n\n{\n  \"ownerId\": \"kn7474wrtsjp988869sw7mygz1860n2v\",\n  \"slug\": \"argus1\",\n  \"version\": \"1.0.4\",\n  \"publishedAt\": 1779596885341\n}\n\nFile v1.0.4:skill-card.md\n\n## Description:\n\nArgus scans Python or JavaScript codebases for bugs, security vulnerabilities, code smells, and common anti-patterns, producing prioritized findings with line numbers, severity ratings, and fix suggestions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[occupythemilkyway](https://clawhub.ai/user/occupythemilkyway)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use Argus to scan Python or JavaScript projects locally and receive prioritized bug, security, and code-quality findings before review or release.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The install step modifies the Python environment.\n\nMitigation: Install and run the skill in an isolated virtual environment.\n\nRisk: Generated reports may contain local file paths and code excerpts.\n\nMitigation: Review report files before sharing them and avoid scanning broad or sensitive directories unless those details are acceptable.\n\n## Reference(s):\n\n- [Argus ClawHub skill page](https://clawhub.ai/occupythemilkyway/skills/argus1)\n- [Argus ClawHub homepage](https://clawhub.ai/occupythemilkyway/argus1)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Guidance]\n\n**Output Format:** [Console report plus local Markdown report; optional JSON report when OUTPUT_JSON is true.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Reports include file paths, line numbers, severity ratings, code excerpts, and fix suggestions.]\n\n## Skill Version(s):\n\n1.0.4 (source: server release metadata and frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment.\n\nArchive v1.0.1: 2 files, 6493 bytes\n\nFiles: SKILL.md (18076b), _meta.json (125b)\n\nFile v1.0.1:SKILL.md\n\n---\nname: argus1\ndescription: \"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prioritised findings report with line numbers, severity ratings, and fix suggestions. No external tools required.\"\nversion: \"1.0.1\"\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins: [python3, pip3]\n    primaryEnv: \"SOURCE_PATH\"\n    homepage: https://clawhub.ai/occupythemilkyway/argus1\n    emoji: \"ððï¸\"\n    tags: [debugging, security, code-review, python, javascript, linter, argus, static-analysis]\n    envVars:\n      - name: SOURCE_PATH\n        required: false\n        description: \"Path to a .py or .js file, or a directory to scan recursively. Defaults to current directory.\"\n        default: \".\"\n      - name: LANGUAGE\n        required: false\n        description: \"Language to scan: python, javascript, or auto (detects from file extensions)\"\n        default: \"auto\"\n      - name: SEVERITY_FILTER\n        required: false\n        description: \"Minimum severity to report: critical, high, medium, low, or all\"\n        default: \"all\"\n      - name: MAX_FINDINGS\n        required: false\n        description: \"Maximum number of findings to display (default: 50)\"\n        default: \"50\"\n      - name: OUTPUT_JSON\n        required: false\n        description: \"Set to 'true' to also save findings as JSON\"\n        default: \"false\"\n---\n\n# Argus â Code Intelligence Scanner\n\nScan any Python or JavaScript codebase for bugs, security holes, and anti-patterns in seconds â with line numbers, severity ratings, and actionable fix suggestions.\n\n## What Argus catches\n\n**Security** â SQL injection patterns, hardcoded secrets, eval/exec abuse, innerHTML XSS, open redirects, pickle deserialization  \n**Bugs** â mutable default arguments, bare except clauses, missing null checks, == None comparisons  \n**Code quality** â broad imports, print statements in production, TODO/FIXME markers, deeply nested code  \n**JavaScript** â var usage, loose equality (==), console.log left in, prototype pollution patterns\n\n## Quick start\n\n```bash\nSOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" openclaw skills run argus1\n```\n\n## ð Security\n\nReads local files only. Nothing transmitted outside your machine.\n\n---\n\n## Step 1 â Install\n\n```bash\npip3 install rich --break-system-packages --quiet\n```\n\n---\n\n## Step 2 â Scan for bugs and vulnerabilities\n\n```python\nimport os, re, json\nfrom pathlib import Path\nfrom datetime import date\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich.panel import Panel\nfrom rich import box\n\nconsole = Console()\n\nSRC_PATH   = os.environ.get(\"SOURCE_PATH\", \".\").strip()\nLANGUAGE   = os.environ.get(\"LANGUAGE\", \"auto\").lower().strip()\nSEV_FILTER = os.environ.get(\"SEVERITY_FILTER\", \"all\").lower().strip()\ntry:\n    MAX_FINDINGS = int(os.environ.get(\"MAX_FINDINGS\", \"50\"))\nexcept ValueError:\n    MAX_FINDINGS = 50\nOUTPUT_JSON = os.environ.get(\"OUTPUT_JSON\", \"false\").lower() == \"true\"\nTODAY       = date.today()\n\nsrc = Path(SRC_PATH)\nif not src.exists():\n    console.print(f\"[red]â Path not found: {SRC_PATH}[/red]\")\n    raise SystemExit(1)\n\ndef detect_lang(path: Path) -> str:\n    py = len(list(path.rglob(\"*.py\") if path.is_dir() else ([path] if str(path).endswith(\".py\") else [])))\n    js = len(list(path.rglob(\"*.js\") if path.is_dir() else ([path] if str(path).endswith(\".js\") else [])))\n    if py >= js:\n        return \"python\"\n    return \"javascript\"\n\nlang = LANGUAGE if LANGUAGE != \"auto\" else detect_lang(src)\next  = \"*.py\" if lang == \"python\" else \"*.js\"\n\n# ââ Rule definitions: (id, severity, category, regex, message, fix) ââââââââââ\nPYTHON_RULES = [\n    (\"PY001\", \"critical\", \"security\",  r\"\\beval\\s*\\(\",                     \"eval() executes arbitrary code â extremely dangerous with user input.\",               \"Use ast.literal_eval() for safe evaluation of literals.\"),\n    (\"PY002\", \"critical\", \"security\",  r\"\\bexec\\s*\\(\",                     \"exec() executes arbitrary strings as Python code.\",                                   \"Refactor to avoid dynamic code execution.\"),\n    (\"PY003\", \"critical\", \"security\",  r\"\\bpickle\\.loads?\\s*\\(\",           \"pickle.load() can execute arbitrary code when deserialising untrusted data.\",         \"Use json.loads() or a safe serialisation format instead.\"),\n    (\"PY004\", \"high\",     \"security\",  r\"(?i)(password|secret|api_key|token|auth_key)\\s*=\\s*['\\\"].+['\\\"]\", \"Hardcoded credential detected.\",                      \"Store secrets in environment variables, never in source code.\"),\n    (\"PY005\", \"high\",     \"security\",  r\"shell\\s*=\\s*True\",                \"shell=True in subprocess is a command-injection risk.\",                               \"Pass a list of arguments instead: subprocess.run(['cmd', 'arg'])\"),\n    (\"PY006\", \"high\",     \"security\",  r\"\\.execute\\s*\\(.*(%|\\.format\\(|f['\\\"])\", \"Potential SQL injection via string formatting in execute().\",                    \"Use parameterised queries: cursor.execute(sql, (param,))\"),\n    (\"PY007\", \"medium\",   \"bug\",       r\"def\\s+\\w+\\s*\\([^)]*=\\s*\\[\\s*\\]\", \"Mutable default argument [] â shared across all calls.\",                               \"Use None as default and initialise inside the function.\"),\n    (\"PY008\", \"medium\",   \"bug\",       r\"def\\s+\\w+\\s*\\([^)]*=\\s*\\{\\s*\\}\", \"Mutable default argument {} â shared across all calls.\",                             \"Use None as default and initialise inside the function.\"),\n    (\"PY009\", \"medium\",   \"bug\",       r\"except\\s*:\",                      \"Bare except: catches SystemExit and KeyboardInterrupt â almost never intentional.\",   \"Catch specific exceptions: except ValueError: or except Exception:\"),\n    (\"PY010\", \"medium\",   \"bug\",       r\"==\\s*None\\b|\\bNone\\s*==\",         \"Use 'is None' instead of '== None'.\",                                                \"Replace '== None' with 'is None' and '!= None' with 'is not None'.\"),\n    (\"PY011\", \"medium\",   \"bug\",       r\"!=\\s*None\\b|\\bNone\\s*!=\",         \"Use 'is not None' instead of '!= None'.\",                                            \"Replace '!= None' with 'is not None'.\"),\n    (\"PY012\", \"medium\",   \"quality\",   r\"\\bprint\\s*\\(\",                    \"print() statement found â likely debug output left in production code.\",              \"Remove or interface in logging.debug() / logging.info().\"),\n    (\"PY013\", \"low\",      \"quality\",   r\"#\\s*(TODO|FIXME|HACK|XXX|BUG)\\b\", \"Unresolved TODO/FIXME marker.\",                                                      \"Resolve or create a tracked issue for this item.\"),\n    (\"PY014\", \"low\",      \"quality\",   r\"from\\s+\\w+\\s+import\\s+\\*\",        \"Wildcard import pollutes namespace and makes dependencies unclear.\",                  \"Import only what you need: from module import specific_name\"),\n    (\"PY015\", \"low\",      \"quality\",   r\"import\\s+pdb\\b\",                  \"Debugger import (pdb) left in code.\",                                                 \"Remove pdb import before committing to production.\"),\n    (\"PY016\", \"medium\",   \"security\",  r\"hashlib\\.(md5|sha1)\\s*\\(\",        \"MD5/SHA1 are cryptographically weak â not suitable for passwords or signatures.\",     \"Use hashlib.sha256() or better; bcrypt/argon2 for passwords.\"),\n    (\"PY017\", \"high\",     \"security\",  r\"random\\.(random|randint|choice)\\s*\\(\", \"random module is not cryptographically secure.\",                                 \"Use secrets module for security-sensitive random values.\"),\n    (\"PY018\", \"medium\",   \"bug\",       r\"open\\s*\\(.+\\)(?!\\s*as\\b)(?!.*with\\b)\", \"File opened without context manager â may leak file handle.\",                   \"Use 'with open(...) as f:' to ensure proper cleanup.\"),\n    (\"PY019\", \"low\",      \"quality\",   r\"lambda\\s+\\w+:\\s*\\w+\\s*\\(\",        \"Lambda used where a named function would be clearer.\",                               \"Consider replacing with a def statement for readability.\"),\n    (\"PY020\", \"medium\",   \"bug\",       r\"\\btype\\s*\\(^w+\\)\\s*==\\s*\",        \"Use isinstance() instead of type() == for type checks.\",                             \"Replace type(x) == SomeType with isinstance(x, SomeType).\"),\n]\n\nJS_RULES = [\n    (\"JS001\", \"high\",     \"quality\",   r\"\\bvar\\s+\",                        \"var is function-scoped and hoisted â causes subtle bugs.\",                            \"Use const or let instead.\"),\n    (\"JS002\", \"critical\", \"security\",  r\"\\.innerHTML\\s*=\",                 \"innerHTML assignment is an XSS vector if content comes from user input.\",             \"Use textContent for text or DOMPurify to sanitise HTML.\"),\n    (\"JS003\", \"critical\", \"security\",  r\"\\beval\\s*\\(\",                     \"eval() executes arbitrary JavaScript â a critical security risk.\",                       \"Refactor to eliminate eval() usage entirely.\"),\n    (\"JS004\", \"high\",     \"security\",  r\"(?i)(api_key|apikey|api_secret|access_token|auth_token|password)\\s*=\\s*['\\\"].+['\\\"]\", \"Hardcoded credential detected.\", \"Move secrets to environment variables or a secrets manager.\"),\n    (\"JS005\", \"medium\",   \"bug\",       r\"==\\s*null\\b(?!\\=)|null\\s*==(?!\\=)\", \"Loose equality with null also matches undefined â usually unintentional.\",           \"Use === null or check explicitly for both null and undefined.\"),\n    (\"JS006\", \"medium\",   \"bug\",       r\"(?<!=)==(?!=)\",                    \"Loose equality (==) performs type coercion â a common source of bugs.\",              \"Use strict equality (===) instead.\"),\n    (\"JS007\", \"medium\",   \"quality\",   r\"\\bconsole\\.(log|warn|error|debug)\\s*\\(\", \"console.log left in production code.\",                                         \"Remove or replace with a proper logging library.\"),\n    (\"JS008\", \"medium\",   \"security\",  r\"document\\.write\\s*\\(\",            \"document.write() can overwrite the entire page and is an XSS risk.\",                 \"Use DOM manipulation methods (createElement, appendChild) instead.\"),\n    (\"JS009\", \"low\",      \"quality\",   r\"//\\s*(TODO|FIXME|HACK|XXX|BUG)\\b\", \"Unresolved TODO/FIXME marker.\",                                                    \"Resolve or create a tracked issue for this item.\"),\n    (\"JS010\", \"high\",     \"security\",  r\"__proto__\\s*=|Object\\.assign\\s*\\(\\s*\\{\\s*\\},\", \"Potential prototype pollution pattern.\",                                 \"Validate that object keys don't include __proto__ or constructor.\"),\n    (\"JS011\", \"medium\",   \"bug\",       r\"setTimeout\\s*\\(\\s*['\\\"]\",         \"setTimeout with a string argument calls eval internally.\",                           \"Pass a function reference instead: setTimeout(() => doThing(), ms)\"),\n    (\"JS012\", \"low\",      \"quality\",   r\"function\\s+\\w+\\s*\\([^)]{60,}\\)\",  \"Function has too many parameters â consider an options object.\",                    \"Refactor long parameter lists into a single options/config object.\"),\n]\n\nRULES = PYTHON_RULES if lang == \"python\" else JS_RULES\nSEV_ORDER = {\"critical\": 0, \"high\": 1, \"medium\": 2, \"low\": 3}\nSEV_FILTER_LEVEL = {\"all\": 3, \"low\": 3, \"medium\": 2, \"high\": 1, \"critical\": 0}.get(SEV_FILTER, 3)\n\nfiles = list(src.rglob(ext) if src.is_dir() else [src])\nif not files:\n    console.print(f\"[yellow]No {ext} files found in {SRC_PATH}[/yellow]\")\n    raise SystemExit(0)\n\nconsole.print()\nconsole.print(Panel.fit(\n    f\"[bold red]ð ðï¸  Argus â Code Intelligence Scanner[/bold red]\\n\"\n    f\"Scanning [yellow]{len(files)}[/yellow] {lang} file(s) in [cyan]{SRC_PATH}[/cyan] \"\n    f\"| Severity: [white]{SEV_FILTER}[/white] | Rules: [white]{len(RULES)}[/white]\",\n    border_style=\"red\"\n))\n\nfindings = []\nfor filepath in files:\n    try:\n        source = filepath.read_text(encoding=\"utf-8\", errors=\"replace\")\n        lines  = source.splitlines()\n        for lineno, line in enumerate(lines, 1):\n            for rule_id, sev, category, pattern, message, fix in RULES:\n                if re.search(pattern, line):\n                    if SEV_ORDER.get(sev, 3) <= SEV_FILTER_LEVEL:\n                        findings.append({\n                            \"id\":       rule_id,\n                            \"severity\": sev,\n                            \"category\": category,\n                            \"file\":     str(filepath.relative_to(src) if src.is_dir() else filepath),\n                            \"line\":     lineno,\n                            \"code\":     line.strip()[:80],\n                            \"message\":  message,\n                            \"fix\":      fix,\n                        })\n    except Exception as e:\n        console.print(f\"[dim]Skipping {filepath}: {e}[/dim]\")\n\n# Deduplicate by (rule, file, line)\nseen = set()\nunique = []\nfor f in findings:\n    key = (f[\"id\"], f[\"file\"], f[\"line\"])\n    if key not in seen:\n        seen.add(key)\n        unique.append(f)\n\n# Sort by severity then file/line\nunique.sort(key=lambda f: (SEV_ORDER.get(f[\"severity\"], 3), f[\"file\"], f[\"line\"]))\ndisplay = unique[:MAX_FINDINGS]\n\n# ââ Display results âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\nSEV_COLOUR = {\"critical\": \"red\", \"high\": \"orange3\", \"medium\": \"yellow\", \"low\": \"dim\"}\n\nif not unique:\n    console.print(Panel(\n        \"[green]â No issues found![/green]\\n\\n\"\n        f\"Scanned {len(files)} file(s) with {len(RULES)} rules â all clear.\",\n        border_style=\"green\"\n    ))\nelse:\n    display_count = len(display)\n    title_suffix  = f\" â showing {display_count} of {len(unique)}\" if len(unique) > MAX_FINDINGS else f\" â {len(unique)} found\"\n    findings_table = Table(\n        title=f\"ð Findings{title_suffix}\",\n        box=box.ROUNDED, border_style=\"red\", show_lines=True\n    )\n    findings_table.add_column(\"ID\",       style=\"dim\",    width=7)\n    findings_table.add_column(\"Sev\",      style=\"white\",  width=9)\n    findings_table.add_column(\"Cat\",      style=\"cyan\",   width=10)\n    findings_table.add_column(\"File:Line\",style=\"yellow\", width=28)\n    findings_table.add_column(\"Issue\",    style=\"white\",  width=45)\n\n    for fi in display:\n        sc   = SEV_COLOUR.get(fi[\"severity\"], \"white\")\n        loc  = f\"{fi['file'][-24:]}:{fi['line']}\" if len(fi[\"file\"]) > 24 else f\"{fi['file']}:{fi['line']}\"\n        findings_table.add_row(\n            fi[\"id\"],\n            f\"[{sc}]{fi['severity'].upper()}[/{sc}]\",\n            fi[\"category\"],\n            loc,\n            fi[\"message\"][:43],\n        )\n    console.print(findings_table)\n\n    # Detailed panels for critical/high\n    critical_high = [f for f in display if f[\"severity\"] in (\"critical\", \"high\")]\n    if critical_high:\n        console.print()\n        for fi in critical_high[:5]:\n            sc = SEV_COLOUR.get(fi[\"severity\"], \"white\")\n            console.print(Panel(\n                f\"[dim]File:[/dim]  {fi['file']}:{fi['line']}\\n\"\n                f\"[dim]Code:[/dim]  [italic]{fi['code']}[/italic]\\n\\n\"\n                f\"[white]{fi['message']}[/white]\\n\\n\"\n                f\"[green]Fix:[/green] {fi['fix']}\",\n                title=f\"[{sc}][bold]{fi['severity'].upper()}[/bold][/{sc}] â {fi['id']}\",\n                border_style=sc\n            ))\n\n    # Summary by severity\n    console.print()\n    sev_counts = {s: sum(1 for f in unique if f[\"severity\"] == s)\n                  for s in (\"critical\", \"high\", \"medium\", \"low\")}\n    summary_lines = \"  \".join(\n        f\"[{SEV_COLOUR[s]}]{s.title()}: {sev_counts[s]}[/{SEV_COLOUR[s]}]\"\n        for s in (\"critical\", \"high\", \"medium\", \"low\") if sev_counts[s]\n    )\n    console.print(Panel(\n        f\"Files scanned: [yellow]{len(files)}[/yellow]   \"\n        f\"Total issues: [red]{len(unique)}[/red]   {summary_lines}\",\n        title=\"Summary\",\n        border_style=\"cyan\"\n    ))\n\n# ââ Save outputs ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ\nreport_file = f\"argus_report_{TODAY}.md\"\nwith open(report_file, \"w\", encoding=\"utf-8\") as f:\n    f.write(f\"# ð Argus Code Scan Report â {TODAY}\\n\\n\")\n    f.write(f\"**Path:** `{SRC_PATH}`  **Language:** {lang}  **Files:** {len(files)}  **Issues:** {len(unique)}\\n\\n\")\n    sev_counts = {s: sum(1 for fi in unique if fi[\"severity\"] == s) for s in (\"critical\",\"high\",\"medium\",\"low\")}\n    f.write(f\"**Critical:** {sev_counts['critical']}  **High:** {sev_counts['high']}  **Medium:** {sev_counts['medium']}  **Low:** {sev_counts['low']}\\n\\n\")\n    f.write(\"## Findings\\n\\n| ID | Severity | Category | File:Line | Issue |\\n|---|---|---|---|---|\\n\")\n    for fi in unique:\n        f.write(f\"| {fi['id']} | {fi['severity'].upper()} | {fi['category']} | {fi['file'][:30]}:{fi['line']} | {fi['message'][:60]} |\\n\")\n    f.write(\"\\n## Fix Suggestions\\n\\n\")\n    for fi in [x for x in unique if x[\"severity\"] in (\"critical\",\"high\")]:\n        f.write(f\"### {fi['id']} â {fi['file']}:{fi['line']}\\n\\n\")\n        f.write(f\"**Issue:** {fi['message']}\\n\\n\")\n        f.write(f\"**Fix:** {fi['fix']}\\n\\n\")\n        f.write(f\"```\\n{fi['code']}\\n```\\n\\n\")\n\nif OUTPUT_JSON:\n    json_file = f\"argus_report_{TODAY}.json\"\n    with open(json_file, \"w\", encoding=\"utf-8\") as f:\n        json.dump({\"scanned\": str(TODAY), \"path\": SRC_PATH, \"language\": lang,\n                   \"files\": len(files), \"findings\": unique}, f, indent=2)\n    console.print(f\"[dim]JSON saved to {json_file}[/dim]\")\n\nconsole.print(Panel(\n    f\"[green]â Scan complete![/green]  Report saved to [cyan]{report_file}[/cyan]\",\n    border_style=\"green\"\n))\n```\n\nFile v1.0.1:_meta.json\n\n{\n  \"ownerId\": \"kn7474wrtsjp988869sw7mygz1860n2v\",\n  \"slug\": \"argus1\",\n  \"version\": \"1.0.1\",\n  \"publishedAt\": 1778357427454\n}\n\nArchive v1.0.0: 2 files, 5024 bytes\n\nFiles: SKILL.md (11358b), _meta.json (125b)\n\nFile v1.0.0:SKILL.md\n\n---\nname: argus\ndescription: \"Argus — The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns — get a prioritised fix list with line numbers, severity ratings, and suggested corrections for every issue found. Nothing escapes Argus.\"\nversion: \"1.0.0\"\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins: [python3, pip3]\n    primaryEnv: \"SOURCE_PATH\"\n    homepage: https://clawhub.ai/skills/argus\n    emoji: \"👁️\"\n    tags: [code, bugs, security, scanner, python, javascript, argus, debugging, linting]\n    envVars:\n      - name: SOURCE_PATH\n        description: \"File or directory to scan\"\n        required: true\n      - name: LANGUAGE\n        description: \"Language to scan: python / javascript / auto\"\n        required: false\n        default: \"auto\"\n      - name: SEVERITY_FILTER\n        description: \"Minimum severity to show: critical / high / medium / all\"\n        required: false\n        default: \"all\"\n---\n\n# 🐛 👁️ Argus — Code Intelligence Scanner\n\nStatic analysis for your codebase — finds real bugs, security holes, and code smells before\nthey hit production. No external API needed. Works on Python and JavaScript files.\n\n**What you get:**\n- Hardcoded passwords, API keys, and tokens flagged as Critical\n- SQL injection and prototype pollution detection\n- Bare excepts, mutable defaults, wildcard imports, and 13 other patterns\n- Severity-filtered output: focus on Critical first, drill down from there\n- `bug_report_[DATE].md` + `bug_report_[DATE].json` with full fix suggestions\n\n## Quick Start\n```bash\nSOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" python skill.py\n```\n\n## Security\nReads local files only. Nothing transmitted.\n\n---\n\n## Step 1 — Install dependencies\n```python\nimport subprocess, sys\nsubprocess.run([sys.executable,\"-m\",\"pip\",\"install\",\"rich\",\"--break-system-packages\",\"--quiet\"], check=True)\n```\n\n## Step 2 — Scan for Bugs\n```python\nimport os, re, json\nfrom pathlib import Path\nfrom datetime import date\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich.panel import Panel\nfrom rich import box\n\nconsole = Console()\nSRC_PATH   = os.environ.get(\"SOURCE_PATH\", \".\")\nLANGUAGE   = os.environ.get(\"LANGUAGE\", \"auto\").lower()\nSEV_FILTER = os.environ.get(\"SEVERITY_FILTER\", \"all\").lower()\nTODAY      = date.today()\n\nsrc = Path(SRC_PATH)\nif not src.exists():\n    console.print(Panel(f\"[red]Path not found: {SRC_PATH}[/red]\", border_style=\"red\")); raise SystemExit(1)\n\nconsole.print(Panel.fit(f\"[bold red]🐛 👁️ Argus — Code Intelligence Scanner[/bold red]\\nScanning: [cyan]{SRC_PATH}[/cyan]  |  Language: [yellow]{LANGUAGE}[/yellow]  |  Filter: [green]{SEV_FILTER}[/green]\", border_style=\"red\"))\n\n# Detect language\ndef detect_lang(path: Path) -> str:\n    py = len(list(path.rglob(\"*.py\") if path.is_dir() else [path] if str(path).endswith(\".py\") else []))\n    js = len(list(path.rglob(\"*.js\") if path.is_dir() else [path] if str(path).endswith(\".js\") else []))\n    if py == 0 and js == 0:\n        return \"python\"  # default; user can override with LANGUAGE env var\n    return \"python\" if py >= js else \"javascript\"\n\nlang = LANGUAGE if LANGUAGE != \"auto\" else detect_lang(src)\n\n# Bug patterns\nPYTHON_RULES = [\n    (\"PY001\", \"critical\", \"security\",  r\"eval\\s*\\(\",              \"eval() is dangerous — executes arbitrary code\", \"Use ast.literal_eval() for safe parsing\"),\n    (\"PY002\", \"critical\", \"security\",  r\"exec\\s*\\(\",              \"exec() executes arbitrary strings\", \"Refactor to avoid dynamic code execution\"),\n    (\"PY003\", \"critical\", \"security\",  r'password\\s*=\\s*[\"\\'][^\"\\']{3,}', \"Hardcoded password\", \"Use environment variables: os.environ.get('PASSWORD')\"),\n    (\"PY004\", \"high\",     \"security\",  r\"pickle\\.loads?\\(\",       \"pickle.load is unsafe with untrusted data\", \"Use json.loads() for safe deserialization\"),\n    (\"PY005\", \"high\",     \"bug\",       r\"except\\s*:\",              \"Bare except catches ALL exceptions including KeyboardInterrupt\", \"Use except Exception: or catch specific exception types\"),\n    (\"PY006\", \"high\",     \"bug\",       r\"==\\s*None|None\\s*==\",    \"Use 'is None' not '== None' — can produce unexpected results\", \"Replace == None with is None\"),\n    (\"PY007\", \"medium\",   \"bug\",       r\"def\\s+\\w+\\(.*=\\[\\]\", \"Mutable default argument — shared across calls\", \"Use None as default: def f(x=None): x = x or []\"),\n    (\"PY008\", \"medium\",   \"security\",  r\"shell\\s*=\\s*True\",       \"subprocess with shell=True is a command injection risk\", \"Use shell=False and pass args as a list\"),\n    (\"PY009\", \"medium\",   \"smell\",     r\"import \\*\",               \"Wildcard import pollutes namespace and hides dependencies\", \"Import only what you need: from module import func\"),\n    (\"PY010\", \"low\",      \"smell\",     r\"print\\s*\\(\",             \"print() left in code — likely debug statement\", \"Use logging module instead of print for production code\"),\n    (\"PY011\", \"critical\", \"security\",  r\"(?i)(api_key|api_secret|secret_key|access_token|auth_token)\\s*=\\s*[\\x27\\x22][^\\x27\\x22]{8,}\", \"Hardcoded API key or token\", \"Store in environment variable: os.environ.get('API_KEY')\"),\n    (\"PY012\", \"high\",     \"security\",  r\"execute\\s*\\(.*%.*\\)|execute\\s*\\(.*\\.format\\(|execute\\s*\\(.*f[\\x22\\x27]\", \"Possible SQL injection via string formatting\", \"Use parameterised queries: cursor.execute(sql, (value,))\"),\n    (\"PY013\", \"medium\",   \"security\",  r\"open\\s*\\((?![^)\\n]*\\bencoding)[^)\\n]*[\\x27\\x22]w[\\x27\\x22]\", \"File opened for write without encoding\", \"Add encoding='utf-8': open(path, 'w', encoding='utf-8')\"),\n]\nJS_RULES = [\n    (\"JS001\", \"critical\", \"security\",  r\"eval\\s*\\(\",              \"eval() executes arbitrary code\", \"Remove eval — refactor logic\"),\n    (\"JS002\", \"critical\", \"security\",  r\"innerHTML\\s*=\",           \"innerHTML is an XSS vector if it contains user input\", \"Use textContent or sanitize input first\"),\n    (\"JS003\", \"high\",     \"bug\",       r\"==\\s*null|null\\s*==\",    \"Use === null for strict equality check\", \"Replace == null with === null\"),\n    (\"JS004\", \"high\",     \"bug\",       r\"catch\\s*\\(\\s*\\)\",      \"Empty catch silently swallows errors\", \"Log the error: catch(e) { console.error(e); }\"),\n    (\"JS005\", \"medium\",   \"bug\",       r\"var\\s+\",                  \"var has function scope and hoisting issues\", \"Use const or let instead of var\"),\n    (\"JS006\", \"medium\",   \"security\",  r\"localStorage\\.setItem.*password\", \"Storing passwords in localStorage is insecure\", \"Never store credentials in localStorage\"),\n    (\"JS007\", \"critical\", \"security\",  r\"(?i)(api_key|apikey|api_secret|access_token|auth_token)\\s*[:=]\\s*[\\x27\\x22][^\\x27\\x22]{8,}\", \"Hardcoded API key or token\", \"Use environment variable: process.env.API_KEY\"),\n    (\"JS008\", \"high\",     \"security\",  r\"__proto__|constructor\\.prototype\", \"Prototype pollution vulnerability\", \"Validate input keys; use Object.create(null) for safe maps\"),\n    (\"JS009\", \"high\",     \"security\",  r\"\\$\\{.*\\}.*query|query.*\\$\\{|db\\.query\\s*\\(\", \"Possible SQL/NoSQL injection via template literal\", \"Use parameterised queries or an ORM\"),\n]\nRULES = PYTHON_RULES if lang == \"python\" else JS_RULES\nSEV_ORDER = {\"critical\": 0, \"high\": 1, \"medium\": 2, \"low\": 3}\nSEV_SHOW  = {\"all\": 4, \"medium\": 2, \"high\": 1, \"critical\": 0}.get(SEV_FILTER, 4)\n\n# Get files\next = \"*.py\" if lang == \"python\" else \"*.js\"\nfiles = list(src.rglob(ext) if src.is_dir() else [src])\nfiles = [f for f in files if \".git\" not in str(f) and \"node_modules\" not in str(f) and \"venv\" not in str(f)][:50]\nconsole.print(f\"[dim]Scanning {len(files)} {lang} files…[/dim]\")\n\n# Scan\nfindings = []\nfor fpath in files:\n    try:\n        lines = fpath.read_text(encoding=\"utf-8\", errors=\"ignore\").splitlines()\n        for i, line in enumerate(lines, 1):\n            for rule_id, sev, category, pattern, message, fix in RULES:\n                if SEV_ORDER.get(sev, 3) <= SEV_SHOW and re.search(pattern, line):\n                    findings.append({\"id\": rule_id, \"severity\": sev, \"category\": category,\n                                     \"file\": str(fpath.relative_to(src) if src.is_dir() else fpath),\n                                     \"line\": i, \"code\": line.strip()[:80], \"message\": message, \"fix\": fix})\n    except Exception: pass\n\n# Dedupe and sort\nseen = set(); unique = []\nfor f in findings:\n    key = (f[\"id\"], f[\"file\"], f[\"line\"])\n    if key not in seen: seen.add(key); unique.append(f)\nunique.sort(key=lambda x: (SEV_ORDER.get(x[\"severity\"],3), x[\"file\"], x[\"line\"]))\n\n# Stats\nfrom collections import Counter\nsev_counts = Counter(f[\"severity\"] for f in unique)\ncat_counts = Counter(f[\"category\"] for f in unique)\n\nconsole.print()\nconsole.print(Panel(\n    f\"Files scanned: [cyan]{len(files)}[/cyan]  |  Issues found: [bold]{len(unique)}[/bold]\\n\"\n    f\"[red]Critical: {sev_counts['critical']}[/red]  [yellow]High: {sev_counts['high']}[/yellow]  [blue]Medium: {sev_counts['medium']}[/blue]  [dim]Low: {sev_counts['low']}[/dim]\\n\"\n    f\"Security: {cat_counts['security']}  |  Bugs: {cat_counts['bug']}  |  Smells: {cat_counts['smell']}\",\n    title=\"[bold]📊 Scan Summary[/bold]\", border_style=\"red\" if sev_counts[\"critical\"] > 0 else \"yellow\"\n))\n\nif unique:\n    console.print()\n    display_count = min(len(unique), 25)\n    title_suffix = f\" — showing {display_count} of {len(unique)}\" if len(unique) > 25 else \"\"\n    t = Table(title=f\"🐛 Issues Found ({len(unique)}){title_suffix}\", box=box.ROUNDED, show_lines=True, border_style=\"red\")\n    t.add_column(\"ID\", width=7, style=\"dim\"); t.add_column(\"Sev\", width=10); t.add_column(\"File:Line\", style=\"cyan\", width=28)\n    t.add_column(\"Issue\", style=\"white\", width=35); t.add_column(\"Fix\", style=\"green\", width=40)\n    SEV_COLOR = {\"critical\":\"bold red\",\"high\":\"yellow\",\"medium\":\"blue\",\"low\":\"dim\"}\n    for f in unique[:25]:\n        col = SEV_COLOR.get(f[\"severity\"],\"white\")\n        t.add_row(f[\"id\"], f\"[{col}]{f['severity']}[/{col}]\", f\"{f['file'][:22]}:{f['line']}\", f[\"message\"][:35], f[\"fix\"][:40])\n    console.print(t)\nelse:\n    console.print(Panel(\"[green]✅ No issues found matching your filter criteria![/green]\", border_style=\"green\"))\n\n# Save\nout_path = f\"bug_report_{TODAY}.json\"\nwith open(out_path,\"w\", encoding=\"utf-8\") as f:\n    json.dump({\"scanned_files\": len(files), \"language\": lang, \"findings\": unique, \"generated\": str(TODAY)}, f, indent=2)\nmd_path = f\"bug_report_{TODAY}.md\"\nwith open(md_path,\"w\", encoding=\"utf-8\") as f:\n    f.write(f\"# Bug Hunt Report — {TODAY}\\n\\n**Files:** {len(files)}  |  **Issues:** {len(unique)}\\n\\n\")\n    f.write(\"| ID | Severity | File:Line | Issue | Fix |\\n|-----|---------|-----------|-------|-----|\\n\")\n    for fi in unique: f.write(f\"| {fi['id']} | {fi['severity']} | {fi['file'][:25]}:{fi['line']} | {fi['message'][:40]} | {fi['fix'][:40]} |\\n\")\n\nconsole.print()\nconsole.print(Panel(f\"[bold green]✅ Scan complete![/bold green]\\n\\n📄 [cyan]{md_path}[/cyan]\\n📄 [cyan]{out_path}[/cyan]\\n\\n[bold]What to do next:[/bold]\\n1. [yellow]Fix Critical issues first[/yellow] — security and crash bugs\\n2. [yellow]Fix High severity next[/yellow] — these will cause real problems\\n3. [yellow]Run again after fixes[/yellow] to confirm clean\\n4. [yellow]Add to CI/CD pipeline[/yellow] so every commit is scanned\",title=\"[bold red]🐛 👁️ Argus — Code Intelligence Scanner — Done[/bold red]\",border_style=\"red\"))\n```\n\nFile v1.0.0:_meta.json\n\n{\n  \"ownerId\": \"kn7474wrtsjp988869sw7mygz1860n2v\",\n  \"slug\": \"argus1\",\n  \"version\": \"1.0.0\",\n  \"publishedAt\": 1777962240955\n}","readmeExcerpt":"Skill: Argus — The Hundred-Eyed Owner: occupythemilkyway Summary: Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior... Tags: bugs:1.0.0, code:1.0.0, code-review:1.0.1, debugging:1.0.1, javascript:1.0.1, latest:1.0.4, python:1.0.1, scanner:1.0.0, security:1.0.1 Version history: v1.0.4 | 2026-05-24T04:28:05.341Z ","codeSnippets":[],"executableExamples":[{"language":"bash","snippet":"SOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" openclaw skills run argus1"},{"language":"bash","snippet":"pip3 install rich --break-system-packages --quiet"},{"language":"bash","snippet":"openclaw skills install argus-pro\n# Set LICENSE_KEY env var to your key from Ko-fi, then run"},{"language":"python","snippet":"import os, re, json\nfrom pathlib import Path\nfrom datetime import date\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich.panel import Panel\nfrom rich import box\n\nFENCE = chr(96) * 3\n\nconsole = Console()\n\nSRC_PATH   = os.environ.get(\"SOURCE_PATH\", \".\").strip()\nLANGUAGE   = os.environ.get(\"LANGUAGE\", \"auto\").lower().strip()\nSEV_FILTER = os.environ.get(\"SEVERITY_FILTER\", \"all\").lower().strip()\ntry:\n    MAX_FINDINGS = int(os.environ.get(\"MAX_FINDINGS\", \"50\"))\nexcept ValueError:\n    MAX_FINDINGS = 50\nOUTPUT_JSON = os.environ.get(\"OUTPUT_JSON\", \"false\").lower() == \"true\"\nTODAY       = date.today()\n\nsrc = Path(SRC_PATH)\nif not src.exists():\n    console.print(f\"[red]â Path not found: {SRC_PATH}[/red]\")\n    raise SystemExit(1)\n\ndef detect_lang(path: Path) -> str:\n    py = len(list(path.rglob(\"*.py\") if path.is_dir() else ([path] if str(path).endswith(\".py\") else [])))\n    js = len(list(path.rglob(\"*.js\") if path.is_dir() else ([path] if str(path).endswith(\".js\") else [])))\n    if py >= js:\n        return \"python\"\n    return \"javascript\"\n\nlang = LANGUAGE if LANGUAGE != \"auto\" else detect_lang(src)\next  = \"*.py\" if lang == \"python\" else \"*.js\"\n\n# ââ Rule definitions: (id, severity, category, regex, message, fix) ââââââââââ\nPYTHON_RULES = [\n    (\"PY001\", \"critical\", \"security\",  r\"\\beval\\s*\\(\",                     \"eval() executes arbitrary code â extremely dangerous with user input.\",               \"Use ast.literal_eval() for safe evaluation of literals.\"),\n    (\"PY002\", \"critical\", \"security\",  r\"\\bexec\\s*\\(\",                     \"exec() executes arbitrary strings as Python code.\",                                   \"Refactor to avoid dynamic code execution.\"),\n    (\"PY003\", \"critical\", \"security\",  r\"\\bpickle\\.loads?\\s*\\(\",           \"pickle.load() can execute arbitrary code when deserialising untrusted data.\",         \"Use json.loads() or a safe serialisation format instead.\"),\n    (\"PY004\", \"high\",     \"security\",  r\"(?i)(pa"},{"language":"bash","snippet":"SOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" openclaw skills run argus1"},{"language":"bash","snippet":"pip3 install rich --break-system-packages --quiet"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\nname: argus1\ndescription: \"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prioritised findings report with line numbers, severity ratings, and fix suggestions. No external tools required.\"\nversion: \"1.0.4\"\nmetadata:\n  openclaw:\n    requires:\n      env: []\n      bins: [python3, pip3]\n    primaryEnv: \"SOURCE_PATH\"\n    homepage: https://clawhub.ai/occupythemilkyway/argus1\n    emoji: \"ððï¸\"\n    tags: [debugging, security, code-review, python, javascript, linter, argus, static-analysis]\n    envVars:\n      - name: SOURCE_PATH\n        required: false\n        description: \"Path to a .py or .js file, or a directory to scan recursively. Defaults to current directory.\"\n        default: \".\"\n      - name: LANGUAGE\n        required: false\n        description: \"Language to scan: python, javascript, or auto (detects from file extensions)\"\n        default: \"auto\"\n      - name: SEVERITY_FILTER\n        required: false\n        description: \"Minimum severity to report: critical, high, medium, low, or all\"\n        default: \"all\"\n      - name: MAX_FINDINGS\n        required: false\n        description: \"Maximum number of findings to display (default: 50)\"\n        default: \"50\"\n      - name: OUTPUT_JSON\n        required: false\n        description: \"Set to 'true' to also save findings as JSON\"\n        default: \"false\"\n---\n\n# Argus â Code Intelligence Scanner\n\nScan any Python or JavaScript codebase for bugs, security holes, and anti-patterns in seconds â with line numbers, severity ratings, and actionable fix suggestions.\n\n## What Argus catches\n\n**Security** â SQL injection patterns, hardcoded secrets, eval/exec abuse, innerHTML XSS, open redirects, pickle deserialization  \n**Bugs** â mutable default arguments, bare except clauses, missing null checks, == None comparisons  \n**Code quality** â broad imports, print statements in production, TODO/FIXME markers, deeply nested code  \n**JavaScript** â var usage, loose equality (==), console.log left in, prototype pollution patterns\n\n## Quick start\n\n```bash\nSOURCE_PATH=\"./src\" LANGUAGE=\"python\" SEVERITY_FILTER=\"high\" openclaw skills run argus1\n```\n\n## ð Security\n\nReads local files only. Nothing transmitted outside your machine.\n\n---\n\n## Step 1 â Install\n\n```bash\npip3 install rich --break-system-packages --quiet\n```\n\n---\n\n\n---\n\n## â¡ Upgrade to Argus Pro\n\nð **Get Argus Pro** â **ko-fi.com/s/8b27346505** â $9 one-time\n\n```bash\nopenclaw skills install argus-pro\n# Set LICENSE_KEY env var to your key from Ko-fi, then run\n```\n\nð° **Bundle deal:** all 5 Pro skills for **$29** â **ko-fi.com/s/7625accf3f** (save $16)\n\n## Step 2 â Scan for bugs and vulnerabilities\n\n```python\nimport os, re, json\nfrom pathlib import Path\nfrom datetime import date\nfrom rich.console import Console\nfrom rich.table import Table\nfrom rich.panel import Panel\nfrom rich import box\n\nFENCE = chr(96) * 3\n\nconsole = Console()\n"},{"path":"_meta.json","content":"{\n  \"ownerId\": \"kn7474wrtsjp988869sw7mygz1860n2v\",\n  \"slug\": \"argus1\",\n  \"version\": \"1.0.4\",\n  \"publishedAt\": 1779596885341\n}"},{"path":"skill-card.md","content":"## Description:\n\nArgus scans Python or JavaScript codebases for bugs, security vulnerabilities, code smells, and common anti-patterns, producing prioritized findings with line numbers, severity ratings, and fix suggestions.\n\nThis skill is ready for commercial/non-commercial use.\n\n## Publisher:\n\n[occupythemilkyway](https://clawhub.ai/user/occupythemilkyway)\n\n### License/Terms of Use:\n\nMIT-0\n\n## Use Case:\n\nDevelopers and engineers use Argus to scan Python or JavaScript projects locally and receive prioritized bug, security, and code-quality findings before review or release.\n\n### Deployment Geography for Use:\n\nGlobal\n\n## Known Risks and Mitigations:\n\nRisk: The install step modifies the Python environment.\n\nMitigation: Install and run the skill in an isolated virtual environment.\n\nRisk: Generated reports may contain local file paths and code excerpts.\n\nMitigation: Review report files before sharing them and avoid scanning broad or sensitive directories unless those details are acceptable.\n\n## Reference(s):\n\n- [Argus ClawHub skill page](https://clawhub.ai/occupythemilkyway/skills/argus1)\n- [Argus ClawHub homepage](https://clawhub.ai/occupythemilkyway/argus1)\n\n## Skill Output:\n\n**Output Type(s):** [Text, Markdown, JSON, Guidance]\n\n**Output Format:** [Console report plus local Markdown report; optional JSON report when OUTPUT_JSON is true.]\n\n**Output Parameters:** [1D]\n\n**Other Properties Related to Output:** [Reports include file paths, line numbers, severity ratings, code excerpts, and fix suggestions.]\n\n## Skill Version(s):\n\n1.0.4 (source: server release metadata and frontmatter)\n\n## Ethical Considerations:\n\nUsers should evaluate whether this skill is appropriate for their environment, review any generated or modified files before relying on them, and apply their organization's safety, security, and compliance requirements before deployment."}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior... Skill: Argus — The Hundred-Eyed Owner: occupythemilkyway Summary: Argus â The Hundred-Eyed. Scan your Python or JavaScript codebase for bugs, security vulnerabilities, code smells, and common anti-patterns â get a prior... Tags: bugs:1.0.0, code:1.0.0, code-review:1.0.1, debugging:1.0.1, javascript:1.0.1, latest:1.0.4, python:1.0.1, scanner:1.0.0, security:1.0.1 Version history: v1.0.4 | 2026-05-24T04:28:05.341Z","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1096,"uniquenessScore":51,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-12T01:04:52.770Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-14T12:14:09.046Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}