[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-trail-of-bits-trailmark-structural":3,"mdc--e0jjqr-key":32,"related-repo-trail-of-bits-trailmark-structural":1363,"related-org-trail-of-bits-trailmark-structural":1461},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":20,"repoUrl":21,"updatedAt":22,"license":23,"forks":24,"topics":25,"repo":27,"sourceUrl":30,"mdContent":31},"trailmark-structural","run structural security analysis on codebases","Runs full Trailmark structural analysis by building a graph, running `preanalysis()`, and reporting hotspots, taint, blast radius, privilege boundaries, attack surface, and version-gated Trailmark 0.4+\u002F0.5+ data such as proxy counts, subgraph edges, type\u002Freference summaries, and entrypoint attributes. Use when vivisect needs detailed structural data for a target. Triggers: structural analysis, blast radius, taint analysis, complexity hotspots, proxy nodes, type references.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"trail-of-bits","Trail of Bits","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Ftrail-of-bits.png","trailofbits",[13,17],{"name":14,"slug":15,"type":16},"Security","security","tag",{"name":18,"slug":19,"type":16},"Code Analysis","code-analysis",6139,"https:\u002F\u002Fgithub.com\u002Ftrailofbits\u002Fskills","2026-08-01T05:44:53.918146",null,541,[26],"agent-skills",{"repoUrl":21,"stars":20,"forks":24,"topics":28,"description":29},[26],"Trail of Bits Claude Code skills for security research, vulnerability detection, and audit workflows","https:\u002F\u002Fgithub.com\u002Ftrailofbits\u002Fskills\u002Ftree\u002FHEAD\u002Fplugins\u002Ftrailmark\u002Fskills\u002Ftrailmark-structural","---\nname: trailmark-structural\ndescription: \"Runs full Trailmark structural analysis by building a graph, running `preanalysis()`, and reporting hotspots, taint, blast radius, privilege boundaries, attack surface, and version-gated Trailmark 0.4+\u002F0.5+ data such as proxy counts, subgraph edges, type\u002Freference summaries, and entrypoint attributes. Use when vivisect needs detailed structural data for a target. Triggers: structural analysis, blast radius, taint analysis, complexity hotspots, proxy nodes, type references.\"\nallowed-tools: Bash Read Grep Glob\n---\n\n# Trailmark Structural Analysis\n\nBuilds a Trailmark graph and runs `engine.preanalysis()` to compute all\nfour pre-analysis passes. The core workflow is v0.2-safe; v0.4-only details\nare included only after checking method availability, and newer builds\nenrich the same output (0.5.0+ adds an `attributes` key to attack-surface\nentries and `proxy.external:*` nodes from `.trailmark\u002Flinks.toml`) without\nany workflow change.\n\n## When to Use\n\n- Vivisect Phase 1 needs full structural data (hotspots, taint, blast radius, privilege boundaries)\n- Detailed pre-analysis passes for a specific target scope\n- Generating complexity and taint data for audit prioritization\n- Inspecting proxy\u002Funresolved-call counts, subgraph edges, or type-reference\n  summaries when Trailmark 0.4.0+ is installed\n\n## When NOT to Use\n\n- Quick overview only (use `trailmark-summary` instead)\n- Ad-hoc code graph queries (use the main `trailmark` skill directly)\n- Target is a single small file where structural analysis adds no value\n\n## Rationalizations to Reject\n\n| Rationalization | Why It's Wrong | Required Action |\n|-----------------|----------------|-----------------|\n| \"Summary analysis is enough\" | Summary skips taint, blast radius, and privilege boundary data | Run full structural analysis when detailed data is needed |\n| \"One pass is sufficient\" | Passes cross-reference each other — taint without blast radius misses critical nodes | Run all four passes |\n| \"Tool isn't installed, I'll analyze manually\" | Manual analysis misses what tooling catches | Report \"trailmark is not installed\" and return |\n| \"Empty pass output means the pass failed\" | Some passes produce no data for some codebases (e.g., no privilege boundaries) | Return full output regardless |\n| \"A v0.4 field is always present\" | Users may still have Trailmark 0.2.x installed | Probe with `hasattr()` before querying v0.4-only methods |\n\n## Usage\n\nThe target directory is passed via the `args` parameter.\n\n## Execution\n\n**Step 1: Check that trailmark is available.**\n\n```bash\ntrailmark analyze --help 2>\u002Fdev\u002Fnull || \\\n  uv run trailmark analyze --help 2>\u002Fdev\u002Fnull\n```\n\nIf neither command works, report \"trailmark is not installed\"\nand return. Do NOT run `pip install`, `uv pip install`,\n`git clone`, or any install command. The user must install\ntrailmark themselves.\n\nOptionally record the version:\n\n```bash\ntrailmark --version 2>\u002Fdev\u002Fnull || uv run trailmark --version 2>\u002Fdev\u002Fnull || true\n```\n\nDo not fail if this command is missing; use API feature probes below.\n\n**Step 2: Detect languages with Trailmark's parse API.**\n\n```bash\npython3 - \"{args}\" \u003C\u003C'PY'\nimport json\nimport sys\n\ntry:\n    from trailmark.parse import detect_languages  # canonical location since 0.3.x\nexcept ModuleNotFoundError:\n    # v0.2.x predates trailmark.parse; the same function lives in query.api\n    from trailmark.query.api import detect_languages\n\nprint(json.dumps(detect_languages(sys.argv[1])))\nPY\n```\n\nIf the import fails, rerun the same snippet with `uv run python - \"{args}\"`.\nIf the result is `[]`, report \"Trailmark found no supported languages under\ntarget\" and return.\n\n**Step 3: Run the full structural analysis via `QueryEngine`.**\n\nRun this snippet with `python3`. If the import fails, rerun the same snippet\nunder `uv run python - \"{args}\"`.\n\n```bash\npython3 - \"{args}\" \u003C\u003C'PY'\nimport json\nimport sys\n\ntry:\n    from trailmark.parse import detect_languages  # canonical location since 0.3.x\nexcept ModuleNotFoundError:\n    # v0.2.x predates trailmark.parse; the same function lives in query.api\n    from trailmark.query.api import detect_languages\n\nfrom trailmark.query.api import QueryEngine\n\ntarget = sys.argv[1]\nlanguages = detect_languages(target)\nengine = QueryEngine.from_directory(target, language=\"auto\")\npreanalysis = engine.preanalysis()\n\ndef summarize_subgraph(name: str, limit: int = 25) -> dict[str, object]:\n    nodes = engine.subgraph(name)\n    summary = {\n        \"count\": len(nodes),\n        \"sample_ids\": [node[\"id\"] for node in nodes[:limit]],\n    }\n    if hasattr(engine, \"subgraph_edges\"):\n        summary[\"edge_count\"] = len(engine.subgraph_edges(name))\n    return summary\n\ngraph = json.loads(engine.to_json())\nnodes = graph.get(\"nodes\", {})\nproxy_nodes = [\n    node_id for node_id, node in nodes.items()\n    if node.get(\"kind\") == \"proxy\" or node.get(\"origin\") == \"proxy\"\n]\n\npayload = {\n    \"languages\": languages,\n    \"summary\": engine.summary(),\n    \"preanalysis\": preanalysis,\n    \"attack_surface\": engine.attack_surface()[:25],\n    \"hotspots\": engine.complexity_hotspots(10)[:25],\n    \"proxy_nodes\": proxy_nodes[:25],\n    \"subgraphs\": {\n        name: summarize_subgraph(name)\n        for name in engine.subgraph_names()\n    },\n}\n\nif hasattr(engine, \"type_references\"):\n    payload[\"type_reference_samples\"] = {\n        node_id: engine.type_references(node_id)[:10]\n        for node_id in list(nodes)[:25]\n    }\n\nprint(json.dumps(payload, indent=2))\nPY\n```\n\n**Step 4: Verify the output.**\n\nThe output should include:\n- `languages`\n- `summary`\n- `preanalysis`\n- `hotspots` (possibly empty)\n- `proxy_nodes` (empty on v0.2.x or when there are no unresolved calls; on\n  0.5.0+ may include `proxy.external:*` entries declared in\n  `.trailmark\u002Flinks.toml`)\n- `subgraphs` with counts and sample IDs\n\nOn Trailmark 0.5.0+, `attack_surface` entries may carry an `attributes`\nobject (e.g. `solidity_visibility`, `solidity_overridden_by`). Pass it\nthrough unchanged — downstream consumers use it to rank entrypoints.\n\nSome subgraphs may have zero nodes for some codebases (this is\nnormal). Return the full JSON payload regardless.\n",{"data":33,"body":35},{"name":4,"description":6,"allowed-tools":34},"Bash Read Grep Glob",{"type":36,"children":37},"root",[38,47,86,93,118,124,158,164,295,301,314,320,329,420,449,454,520,525,533,676,697,713,731,1227,1235,1240,1317,1352,1357],{"type":39,"tag":40,"props":41,"children":43},"element","h1",{"id":42},"trailmark-structural-analysis",[44],{"type":45,"value":46},"text","Trailmark Structural Analysis",{"type":39,"tag":48,"props":49,"children":50},"p",{},[51,53,60,62,68,70,76,78,84],{"type":45,"value":52},"Builds a Trailmark graph and runs ",{"type":39,"tag":54,"props":55,"children":57},"code",{"className":56},[],[58],{"type":45,"value":59},"engine.preanalysis()",{"type":45,"value":61}," to compute all\nfour pre-analysis passes. The core workflow is v0.2-safe; v0.4-only details\nare included only after checking method availability, and newer builds\nenrich the same output (0.5.0+ adds an ",{"type":39,"tag":54,"props":63,"children":65},{"className":64},[],[66],{"type":45,"value":67},"attributes",{"type":45,"value":69}," key to attack-surface\nentries and ",{"type":39,"tag":54,"props":71,"children":73},{"className":72},[],[74],{"type":45,"value":75},"proxy.external:*",{"type":45,"value":77}," nodes from ",{"type":39,"tag":54,"props":79,"children":81},{"className":80},[],[82],{"type":45,"value":83},".trailmark\u002Flinks.toml",{"type":45,"value":85},") without\nany workflow change.",{"type":39,"tag":87,"props":88,"children":90},"h2",{"id":89},"when-to-use",[91],{"type":45,"value":92},"When to Use",{"type":39,"tag":94,"props":95,"children":96},"ul",{},[97,103,108,113],{"type":39,"tag":98,"props":99,"children":100},"li",{},[101],{"type":45,"value":102},"Vivisect Phase 1 needs full structural data (hotspots, taint, blast radius, privilege boundaries)",{"type":39,"tag":98,"props":104,"children":105},{},[106],{"type":45,"value":107},"Detailed pre-analysis passes for a specific target scope",{"type":39,"tag":98,"props":109,"children":110},{},[111],{"type":45,"value":112},"Generating complexity and taint data for audit prioritization",{"type":39,"tag":98,"props":114,"children":115},{},[116],{"type":45,"value":117},"Inspecting proxy\u002Funresolved-call counts, subgraph edges, or type-reference\nsummaries when Trailmark 0.4.0+ is installed",{"type":39,"tag":87,"props":119,"children":121},{"id":120},"when-not-to-use",[122],{"type":45,"value":123},"When NOT to Use",{"type":39,"tag":94,"props":125,"children":126},{},[127,140,153],{"type":39,"tag":98,"props":128,"children":129},{},[130,132,138],{"type":45,"value":131},"Quick overview only (use ",{"type":39,"tag":54,"props":133,"children":135},{"className":134},[],[136],{"type":45,"value":137},"trailmark-summary",{"type":45,"value":139}," instead)",{"type":39,"tag":98,"props":141,"children":142},{},[143,145,151],{"type":45,"value":144},"Ad-hoc code graph queries (use the main ",{"type":39,"tag":54,"props":146,"children":148},{"className":147},[],[149],{"type":45,"value":150},"trailmark",{"type":45,"value":152}," skill directly)",{"type":39,"tag":98,"props":154,"children":155},{},[156],{"type":45,"value":157},"Target is a single small file where structural analysis adds no value",{"type":39,"tag":87,"props":159,"children":161},{"id":160},"rationalizations-to-reject",[162],{"type":45,"value":163},"Rationalizations to Reject",{"type":39,"tag":165,"props":166,"children":167},"table",{},[168,192],{"type":39,"tag":169,"props":170,"children":171},"thead",{},[172],{"type":39,"tag":173,"props":174,"children":175},"tr",{},[176,182,187],{"type":39,"tag":177,"props":178,"children":179},"th",{},[180],{"type":45,"value":181},"Rationalization",{"type":39,"tag":177,"props":183,"children":184},{},[185],{"type":45,"value":186},"Why It's Wrong",{"type":39,"tag":177,"props":188,"children":189},{},[190],{"type":45,"value":191},"Required Action",{"type":39,"tag":193,"props":194,"children":195},"tbody",{},[196,215,233,251,269],{"type":39,"tag":173,"props":197,"children":198},{},[199,205,210],{"type":39,"tag":200,"props":201,"children":202},"td",{},[203],{"type":45,"value":204},"\"Summary analysis is enough\"",{"type":39,"tag":200,"props":206,"children":207},{},[208],{"type":45,"value":209},"Summary skips taint, blast radius, and privilege boundary data",{"type":39,"tag":200,"props":211,"children":212},{},[213],{"type":45,"value":214},"Run full structural analysis when detailed data is needed",{"type":39,"tag":173,"props":216,"children":217},{},[218,223,228],{"type":39,"tag":200,"props":219,"children":220},{},[221],{"type":45,"value":222},"\"One pass is sufficient\"",{"type":39,"tag":200,"props":224,"children":225},{},[226],{"type":45,"value":227},"Passes cross-reference each other — taint without blast radius misses critical nodes",{"type":39,"tag":200,"props":229,"children":230},{},[231],{"type":45,"value":232},"Run all four passes",{"type":39,"tag":173,"props":234,"children":235},{},[236,241,246],{"type":39,"tag":200,"props":237,"children":238},{},[239],{"type":45,"value":240},"\"Tool isn't installed, I'll analyze manually\"",{"type":39,"tag":200,"props":242,"children":243},{},[244],{"type":45,"value":245},"Manual analysis misses what tooling catches",{"type":39,"tag":200,"props":247,"children":248},{},[249],{"type":45,"value":250},"Report \"trailmark is not installed\" and return",{"type":39,"tag":173,"props":252,"children":253},{},[254,259,264],{"type":39,"tag":200,"props":255,"children":256},{},[257],{"type":45,"value":258},"\"Empty pass output means the pass failed\"",{"type":39,"tag":200,"props":260,"children":261},{},[262],{"type":45,"value":263},"Some passes produce no data for some codebases (e.g., no privilege boundaries)",{"type":39,"tag":200,"props":265,"children":266},{},[267],{"type":45,"value":268},"Return full output regardless",{"type":39,"tag":173,"props":270,"children":271},{},[272,277,282],{"type":39,"tag":200,"props":273,"children":274},{},[275],{"type":45,"value":276},"\"A v0.4 field is always present\"",{"type":39,"tag":200,"props":278,"children":279},{},[280],{"type":45,"value":281},"Users may still have Trailmark 0.2.x installed",{"type":39,"tag":200,"props":283,"children":284},{},[285,287,293],{"type":45,"value":286},"Probe with ",{"type":39,"tag":54,"props":288,"children":290},{"className":289},[],[291],{"type":45,"value":292},"hasattr()",{"type":45,"value":294}," before querying v0.4-only methods",{"type":39,"tag":87,"props":296,"children":298},{"id":297},"usage",[299],{"type":45,"value":300},"Usage",{"type":39,"tag":48,"props":302,"children":303},{},[304,306,312],{"type":45,"value":305},"The target directory is passed via the ",{"type":39,"tag":54,"props":307,"children":309},{"className":308},[],[310],{"type":45,"value":311},"args",{"type":45,"value":313}," parameter.",{"type":39,"tag":87,"props":315,"children":317},{"id":316},"execution",[318],{"type":45,"value":319},"Execution",{"type":39,"tag":48,"props":321,"children":322},{},[323],{"type":39,"tag":324,"props":325,"children":326},"strong",{},[327],{"type":45,"value":328},"Step 1: Check that trailmark is available.",{"type":39,"tag":330,"props":331,"children":336},"pre",{"className":332,"code":333,"language":334,"meta":335,"style":335},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","trailmark analyze --help 2>\u002Fdev\u002Fnull || \\\n  uv run trailmark analyze --help 2>\u002Fdev\u002Fnull\n","bash","",[337],{"type":39,"tag":54,"props":338,"children":339},{"__ignoreMap":335},[340,384],{"type":39,"tag":341,"props":342,"children":345},"span",{"class":343,"line":344},"line",1,[346,351,357,362,368,373,378],{"type":39,"tag":341,"props":347,"children":349},{"style":348},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[350],{"type":45,"value":150},{"type":39,"tag":341,"props":352,"children":354},{"style":353},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[355],{"type":45,"value":356}," analyze",{"type":39,"tag":341,"props":358,"children":359},{"style":353},[360],{"type":45,"value":361}," --help",{"type":39,"tag":341,"props":363,"children":365},{"style":364},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[366],{"type":45,"value":367}," 2>",{"type":39,"tag":341,"props":369,"children":370},{"style":353},[371],{"type":45,"value":372},"\u002Fdev\u002Fnull",{"type":39,"tag":341,"props":374,"children":375},{"style":364},[376],{"type":45,"value":377}," ||",{"type":39,"tag":341,"props":379,"children":381},{"style":380},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[382],{"type":45,"value":383}," \\\n",{"type":39,"tag":341,"props":385,"children":387},{"class":343,"line":386},2,[388,393,398,403,407,411,415],{"type":39,"tag":341,"props":389,"children":390},{"style":348},[391],{"type":45,"value":392},"  uv",{"type":39,"tag":341,"props":394,"children":395},{"style":353},[396],{"type":45,"value":397}," run",{"type":39,"tag":341,"props":399,"children":400},{"style":353},[401],{"type":45,"value":402}," trailmark",{"type":39,"tag":341,"props":404,"children":405},{"style":353},[406],{"type":45,"value":356},{"type":39,"tag":341,"props":408,"children":409},{"style":353},[410],{"type":45,"value":361},{"type":39,"tag":341,"props":412,"children":413},{"style":364},[414],{"type":45,"value":367},{"type":39,"tag":341,"props":416,"children":417},{"style":353},[418],{"type":45,"value":419},"\u002Fdev\u002Fnull\n",{"type":39,"tag":48,"props":421,"children":422},{},[423,425,431,433,439,441,447],{"type":45,"value":424},"If neither command works, report \"trailmark is not installed\"\nand return. Do NOT run ",{"type":39,"tag":54,"props":426,"children":428},{"className":427},[],[429],{"type":45,"value":430},"pip install",{"type":45,"value":432},", ",{"type":39,"tag":54,"props":434,"children":436},{"className":435},[],[437],{"type":45,"value":438},"uv pip install",{"type":45,"value":440},",\n",{"type":39,"tag":54,"props":442,"children":444},{"className":443},[],[445],{"type":45,"value":446},"git clone",{"type":45,"value":448},", or any install command. The user must install\ntrailmark themselves.",{"type":39,"tag":48,"props":450,"children":451},{},[452],{"type":45,"value":453},"Optionally record the version:",{"type":39,"tag":330,"props":455,"children":457},{"className":332,"code":456,"language":334,"meta":335,"style":335},"trailmark --version 2>\u002Fdev\u002Fnull || uv run trailmark --version 2>\u002Fdev\u002Fnull || true\n",[458],{"type":39,"tag":54,"props":459,"children":460},{"__ignoreMap":335},[461],{"type":39,"tag":341,"props":462,"children":463},{"class":343,"line":344},[464,468,473,477,481,485,490,494,498,502,506,510,514],{"type":39,"tag":341,"props":465,"children":466},{"style":348},[467],{"type":45,"value":150},{"type":39,"tag":341,"props":469,"children":470},{"style":353},[471],{"type":45,"value":472}," --version",{"type":39,"tag":341,"props":474,"children":475},{"style":364},[476],{"type":45,"value":367},{"type":39,"tag":341,"props":478,"children":479},{"style":353},[480],{"type":45,"value":372},{"type":39,"tag":341,"props":482,"children":483},{"style":364},[484],{"type":45,"value":377},{"type":39,"tag":341,"props":486,"children":487},{"style":348},[488],{"type":45,"value":489}," uv",{"type":39,"tag":341,"props":491,"children":492},{"style":353},[493],{"type":45,"value":397},{"type":39,"tag":341,"props":495,"children":496},{"style":353},[497],{"type":45,"value":402},{"type":39,"tag":341,"props":499,"children":500},{"style":353},[501],{"type":45,"value":472},{"type":39,"tag":341,"props":503,"children":504},{"style":364},[505],{"type":45,"value":367},{"type":39,"tag":341,"props":507,"children":508},{"style":353},[509],{"type":45,"value":372},{"type":39,"tag":341,"props":511,"children":512},{"style":364},[513],{"type":45,"value":377},{"type":39,"tag":341,"props":515,"children":517},{"style":516},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[518],{"type":45,"value":519}," true\n",{"type":39,"tag":48,"props":521,"children":522},{},[523],{"type":45,"value":524},"Do not fail if this command is missing; use API feature probes below.",{"type":39,"tag":48,"props":526,"children":527},{},[528],{"type":39,"tag":324,"props":529,"children":530},{},[531],{"type":45,"value":532},"Step 2: Detect languages with Trailmark's parse API.",{"type":39,"tag":330,"props":534,"children":536},{"className":332,"code":535,"language":334,"meta":335,"style":335},"python3 - \"{args}\" \u003C\u003C'PY'\nimport json\nimport sys\n\ntry:\n    from trailmark.parse import detect_languages  # canonical location since 0.3.x\nexcept ModuleNotFoundError:\n    # v0.2.x predates trailmark.parse; the same function lives in query.api\n    from trailmark.query.api import detect_languages\n\nprint(json.dumps(detect_languages(sys.argv[1])))\nPY\n",[537],{"type":39,"tag":54,"props":538,"children":539},{"__ignoreMap":335},[540,578,586,595,605,614,623,632,641,650,658,667],{"type":39,"tag":341,"props":541,"children":542},{"class":343,"line":344},[543,548,553,558,563,568,573],{"type":39,"tag":341,"props":544,"children":545},{"style":348},[546],{"type":45,"value":547},"python3",{"type":39,"tag":341,"props":549,"children":550},{"style":353},[551],{"type":45,"value":552}," -",{"type":39,"tag":341,"props":554,"children":555},{"style":364},[556],{"type":45,"value":557}," \"",{"type":39,"tag":341,"props":559,"children":560},{"style":353},[561],{"type":45,"value":562},"{args}",{"type":39,"tag":341,"props":564,"children":565},{"style":364},[566],{"type":45,"value":567},"\"",{"type":39,"tag":341,"props":569,"children":570},{"style":364},[571],{"type":45,"value":572}," \u003C\u003C",{"type":39,"tag":341,"props":574,"children":575},{"style":364},[576],{"type":45,"value":577},"'PY'\n",{"type":39,"tag":341,"props":579,"children":580},{"class":343,"line":386},[581],{"type":39,"tag":341,"props":582,"children":583},{"style":353},[584],{"type":45,"value":585},"import json\n",{"type":39,"tag":341,"props":587,"children":589},{"class":343,"line":588},3,[590],{"type":39,"tag":341,"props":591,"children":592},{"style":353},[593],{"type":45,"value":594},"import sys\n",{"type":39,"tag":341,"props":596,"children":598},{"class":343,"line":597},4,[599],{"type":39,"tag":341,"props":600,"children":602},{"emptyLinePlaceholder":601},true,[603],{"type":45,"value":604},"\n",{"type":39,"tag":341,"props":606,"children":608},{"class":343,"line":607},5,[609],{"type":39,"tag":341,"props":610,"children":611},{"style":353},[612],{"type":45,"value":613},"try:\n",{"type":39,"tag":341,"props":615,"children":617},{"class":343,"line":616},6,[618],{"type":39,"tag":341,"props":619,"children":620},{"style":353},[621],{"type":45,"value":622},"    from trailmark.parse import detect_languages  # canonical location since 0.3.x\n",{"type":39,"tag":341,"props":624,"children":626},{"class":343,"line":625},7,[627],{"type":39,"tag":341,"props":628,"children":629},{"style":353},[630],{"type":45,"value":631},"except ModuleNotFoundError:\n",{"type":39,"tag":341,"props":633,"children":635},{"class":343,"line":634},8,[636],{"type":39,"tag":341,"props":637,"children":638},{"style":353},[639],{"type":45,"value":640},"    # v0.2.x predates trailmark.parse; the same function lives in query.api\n",{"type":39,"tag":341,"props":642,"children":644},{"class":343,"line":643},9,[645],{"type":39,"tag":341,"props":646,"children":647},{"style":353},[648],{"type":45,"value":649},"    from trailmark.query.api import detect_languages\n",{"type":39,"tag":341,"props":651,"children":653},{"class":343,"line":652},10,[654],{"type":39,"tag":341,"props":655,"children":656},{"emptyLinePlaceholder":601},[657],{"type":45,"value":604},{"type":39,"tag":341,"props":659,"children":661},{"class":343,"line":660},11,[662],{"type":39,"tag":341,"props":663,"children":664},{"style":353},[665],{"type":45,"value":666},"print(json.dumps(detect_languages(sys.argv[1])))\n",{"type":39,"tag":341,"props":668,"children":670},{"class":343,"line":669},12,[671],{"type":39,"tag":341,"props":672,"children":673},{"style":364},[674],{"type":45,"value":675},"PY\n",{"type":39,"tag":48,"props":677,"children":678},{},[679,681,687,689,695],{"type":45,"value":680},"If the import fails, rerun the same snippet with ",{"type":39,"tag":54,"props":682,"children":684},{"className":683},[],[685],{"type":45,"value":686},"uv run python - \"{args}\"",{"type":45,"value":688},".\nIf the result is ",{"type":39,"tag":54,"props":690,"children":692},{"className":691},[],[693],{"type":45,"value":694},"[]",{"type":45,"value":696},", report \"Trailmark found no supported languages under\ntarget\" and return.",{"type":39,"tag":48,"props":698,"children":699},{},[700],{"type":39,"tag":324,"props":701,"children":702},{},[703,705,711],{"type":45,"value":704},"Step 3: Run the full structural analysis via ",{"type":39,"tag":54,"props":706,"children":708},{"className":707},[],[709],{"type":45,"value":710},"QueryEngine",{"type":45,"value":712},".",{"type":39,"tag":48,"props":714,"children":715},{},[716,718,723,725,730],{"type":45,"value":717},"Run this snippet with ",{"type":39,"tag":54,"props":719,"children":721},{"className":720},[],[722],{"type":45,"value":547},{"type":45,"value":724},". If the import fails, rerun the same snippet\nunder ",{"type":39,"tag":54,"props":726,"children":728},{"className":727},[],[729],{"type":45,"value":686},{"type":45,"value":712},{"type":39,"tag":330,"props":732,"children":734},{"className":332,"code":733,"language":334,"meta":335,"style":335},"python3 - \"{args}\" \u003C\u003C'PY'\nimport json\nimport sys\n\ntry:\n    from trailmark.parse import detect_languages  # canonical location since 0.3.x\nexcept ModuleNotFoundError:\n    # v0.2.x predates trailmark.parse; the same function lives in query.api\n    from trailmark.query.api import detect_languages\n\nfrom trailmark.query.api import QueryEngine\n\ntarget = sys.argv[1]\nlanguages = detect_languages(target)\nengine = QueryEngine.from_directory(target, language=\"auto\")\npreanalysis = engine.preanalysis()\n\ndef summarize_subgraph(name: str, limit: int = 25) -> dict[str, object]:\n    nodes = engine.subgraph(name)\n    summary = {\n        \"count\": len(nodes),\n        \"sample_ids\": [node[\"id\"] for node in nodes[:limit]],\n    }\n    if hasattr(engine, \"subgraph_edges\"):\n        summary[\"edge_count\"] = len(engine.subgraph_edges(name))\n    return summary\n\ngraph = json.loads(engine.to_json())\nnodes = graph.get(\"nodes\", {})\nproxy_nodes = [\n    node_id for node_id, node in nodes.items()\n    if node.get(\"kind\") == \"proxy\" or node.get(\"origin\") == \"proxy\"\n]\n\npayload = {\n    \"languages\": languages,\n    \"summary\": engine.summary(),\n    \"preanalysis\": preanalysis,\n    \"attack_surface\": engine.attack_surface()[:25],\n    \"hotspots\": engine.complexity_hotspots(10)[:25],\n    \"proxy_nodes\": proxy_nodes[:25],\n    \"subgraphs\": {\n        name: summarize_subgraph(name)\n        for name in engine.subgraph_names()\n    },\n}\n\nif hasattr(engine, \"type_references\"):\n    payload[\"type_reference_samples\"] = {\n        node_id: engine.type_references(node_id)[:10]\n        for node_id in list(nodes)[:25]\n    }\n\nprint(json.dumps(payload, indent=2))\nPY\n",[735],{"type":39,"tag":54,"props":736,"children":737},{"__ignoreMap":335},[738,769,776,783,790,797,804,811,818,825,832,840,847,856,865,874,883,891,900,909,918,927,936,945,954,963,972,980,989,998,1007,1016,1025,1034,1042,1051,1060,1069,1078,1087,1096,1105,1114,1123,1132,1141,1150,1158,1167,1176,1185,1194,1202,1210,1219],{"type":39,"tag":341,"props":739,"children":740},{"class":343,"line":344},[741,745,749,753,757,761,765],{"type":39,"tag":341,"props":742,"children":743},{"style":348},[744],{"type":45,"value":547},{"type":39,"tag":341,"props":746,"children":747},{"style":353},[748],{"type":45,"value":552},{"type":39,"tag":341,"props":750,"children":751},{"style":364},[752],{"type":45,"value":557},{"type":39,"tag":341,"props":754,"children":755},{"style":353},[756],{"type":45,"value":562},{"type":39,"tag":341,"props":758,"children":759},{"style":364},[760],{"type":45,"value":567},{"type":39,"tag":341,"props":762,"children":763},{"style":364},[764],{"type":45,"value":572},{"type":39,"tag":341,"props":766,"children":767},{"style":364},[768],{"type":45,"value":577},{"type":39,"tag":341,"props":770,"children":771},{"class":343,"line":386},[772],{"type":39,"tag":341,"props":773,"children":774},{"style":353},[775],{"type":45,"value":585},{"type":39,"tag":341,"props":777,"children":778},{"class":343,"line":588},[779],{"type":39,"tag":341,"props":780,"children":781},{"style":353},[782],{"type":45,"value":594},{"type":39,"tag":341,"props":784,"children":785},{"class":343,"line":597},[786],{"type":39,"tag":341,"props":787,"children":788},{"emptyLinePlaceholder":601},[789],{"type":45,"value":604},{"type":39,"tag":341,"props":791,"children":792},{"class":343,"line":607},[793],{"type":39,"tag":341,"props":794,"children":795},{"style":353},[796],{"type":45,"value":613},{"type":39,"tag":341,"props":798,"children":799},{"class":343,"line":616},[800],{"type":39,"tag":341,"props":801,"children":802},{"style":353},[803],{"type":45,"value":622},{"type":39,"tag":341,"props":805,"children":806},{"class":343,"line":625},[807],{"type":39,"tag":341,"props":808,"children":809},{"style":353},[810],{"type":45,"value":631},{"type":39,"tag":341,"props":812,"children":813},{"class":343,"line":634},[814],{"type":39,"tag":341,"props":815,"children":816},{"style":353},[817],{"type":45,"value":640},{"type":39,"tag":341,"props":819,"children":820},{"class":343,"line":643},[821],{"type":39,"tag":341,"props":822,"children":823},{"style":353},[824],{"type":45,"value":649},{"type":39,"tag":341,"props":826,"children":827},{"class":343,"line":652},[828],{"type":39,"tag":341,"props":829,"children":830},{"emptyLinePlaceholder":601},[831],{"type":45,"value":604},{"type":39,"tag":341,"props":833,"children":834},{"class":343,"line":660},[835],{"type":39,"tag":341,"props":836,"children":837},{"style":353},[838],{"type":45,"value":839},"from trailmark.query.api import QueryEngine\n",{"type":39,"tag":341,"props":841,"children":842},{"class":343,"line":669},[843],{"type":39,"tag":341,"props":844,"children":845},{"emptyLinePlaceholder":601},[846],{"type":45,"value":604},{"type":39,"tag":341,"props":848,"children":850},{"class":343,"line":849},13,[851],{"type":39,"tag":341,"props":852,"children":853},{"style":353},[854],{"type":45,"value":855},"target = sys.argv[1]\n",{"type":39,"tag":341,"props":857,"children":859},{"class":343,"line":858},14,[860],{"type":39,"tag":341,"props":861,"children":862},{"style":353},[863],{"type":45,"value":864},"languages = detect_languages(target)\n",{"type":39,"tag":341,"props":866,"children":868},{"class":343,"line":867},15,[869],{"type":39,"tag":341,"props":870,"children":871},{"style":353},[872],{"type":45,"value":873},"engine = QueryEngine.from_directory(target, language=\"auto\")\n",{"type":39,"tag":341,"props":875,"children":877},{"class":343,"line":876},16,[878],{"type":39,"tag":341,"props":879,"children":880},{"style":353},[881],{"type":45,"value":882},"preanalysis = engine.preanalysis()\n",{"type":39,"tag":341,"props":884,"children":886},{"class":343,"line":885},17,[887],{"type":39,"tag":341,"props":888,"children":889},{"emptyLinePlaceholder":601},[890],{"type":45,"value":604},{"type":39,"tag":341,"props":892,"children":894},{"class":343,"line":893},18,[895],{"type":39,"tag":341,"props":896,"children":897},{"style":353},[898],{"type":45,"value":899},"def summarize_subgraph(name: str, limit: int = 25) -> dict[str, object]:\n",{"type":39,"tag":341,"props":901,"children":903},{"class":343,"line":902},19,[904],{"type":39,"tag":341,"props":905,"children":906},{"style":353},[907],{"type":45,"value":908},"    nodes = engine.subgraph(name)\n",{"type":39,"tag":341,"props":910,"children":912},{"class":343,"line":911},20,[913],{"type":39,"tag":341,"props":914,"children":915},{"style":353},[916],{"type":45,"value":917},"    summary = {\n",{"type":39,"tag":341,"props":919,"children":921},{"class":343,"line":920},21,[922],{"type":39,"tag":341,"props":923,"children":924},{"style":353},[925],{"type":45,"value":926},"        \"count\": len(nodes),\n",{"type":39,"tag":341,"props":928,"children":930},{"class":343,"line":929},22,[931],{"type":39,"tag":341,"props":932,"children":933},{"style":353},[934],{"type":45,"value":935},"        \"sample_ids\": [node[\"id\"] for node in nodes[:limit]],\n",{"type":39,"tag":341,"props":937,"children":939},{"class":343,"line":938},23,[940],{"type":39,"tag":341,"props":941,"children":942},{"style":353},[943],{"type":45,"value":944},"    }\n",{"type":39,"tag":341,"props":946,"children":948},{"class":343,"line":947},24,[949],{"type":39,"tag":341,"props":950,"children":951},{"style":353},[952],{"type":45,"value":953},"    if hasattr(engine, \"subgraph_edges\"):\n",{"type":39,"tag":341,"props":955,"children":957},{"class":343,"line":956},25,[958],{"type":39,"tag":341,"props":959,"children":960},{"style":353},[961],{"type":45,"value":962},"        summary[\"edge_count\"] = len(engine.subgraph_edges(name))\n",{"type":39,"tag":341,"props":964,"children":966},{"class":343,"line":965},26,[967],{"type":39,"tag":341,"props":968,"children":969},{"style":353},[970],{"type":45,"value":971},"    return summary\n",{"type":39,"tag":341,"props":973,"children":975},{"class":343,"line":974},27,[976],{"type":39,"tag":341,"props":977,"children":978},{"emptyLinePlaceholder":601},[979],{"type":45,"value":604},{"type":39,"tag":341,"props":981,"children":983},{"class":343,"line":982},28,[984],{"type":39,"tag":341,"props":985,"children":986},{"style":353},[987],{"type":45,"value":988},"graph = json.loads(engine.to_json())\n",{"type":39,"tag":341,"props":990,"children":992},{"class":343,"line":991},29,[993],{"type":39,"tag":341,"props":994,"children":995},{"style":353},[996],{"type":45,"value":997},"nodes = graph.get(\"nodes\", {})\n",{"type":39,"tag":341,"props":999,"children":1001},{"class":343,"line":1000},30,[1002],{"type":39,"tag":341,"props":1003,"children":1004},{"style":353},[1005],{"type":45,"value":1006},"proxy_nodes = [\n",{"type":39,"tag":341,"props":1008,"children":1010},{"class":343,"line":1009},31,[1011],{"type":39,"tag":341,"props":1012,"children":1013},{"style":353},[1014],{"type":45,"value":1015},"    node_id for node_id, node in nodes.items()\n",{"type":39,"tag":341,"props":1017,"children":1019},{"class":343,"line":1018},32,[1020],{"type":39,"tag":341,"props":1021,"children":1022},{"style":353},[1023],{"type":45,"value":1024},"    if node.get(\"kind\") == \"proxy\" or node.get(\"origin\") == \"proxy\"\n",{"type":39,"tag":341,"props":1026,"children":1028},{"class":343,"line":1027},33,[1029],{"type":39,"tag":341,"props":1030,"children":1031},{"style":353},[1032],{"type":45,"value":1033},"]\n",{"type":39,"tag":341,"props":1035,"children":1037},{"class":343,"line":1036},34,[1038],{"type":39,"tag":341,"props":1039,"children":1040},{"emptyLinePlaceholder":601},[1041],{"type":45,"value":604},{"type":39,"tag":341,"props":1043,"children":1045},{"class":343,"line":1044},35,[1046],{"type":39,"tag":341,"props":1047,"children":1048},{"style":353},[1049],{"type":45,"value":1050},"payload = {\n",{"type":39,"tag":341,"props":1052,"children":1054},{"class":343,"line":1053},36,[1055],{"type":39,"tag":341,"props":1056,"children":1057},{"style":353},[1058],{"type":45,"value":1059},"    \"languages\": languages,\n",{"type":39,"tag":341,"props":1061,"children":1063},{"class":343,"line":1062},37,[1064],{"type":39,"tag":341,"props":1065,"children":1066},{"style":353},[1067],{"type":45,"value":1068},"    \"summary\": engine.summary(),\n",{"type":39,"tag":341,"props":1070,"children":1072},{"class":343,"line":1071},38,[1073],{"type":39,"tag":341,"props":1074,"children":1075},{"style":353},[1076],{"type":45,"value":1077},"    \"preanalysis\": preanalysis,\n",{"type":39,"tag":341,"props":1079,"children":1081},{"class":343,"line":1080},39,[1082],{"type":39,"tag":341,"props":1083,"children":1084},{"style":353},[1085],{"type":45,"value":1086},"    \"attack_surface\": engine.attack_surface()[:25],\n",{"type":39,"tag":341,"props":1088,"children":1090},{"class":343,"line":1089},40,[1091],{"type":39,"tag":341,"props":1092,"children":1093},{"style":353},[1094],{"type":45,"value":1095},"    \"hotspots\": engine.complexity_hotspots(10)[:25],\n",{"type":39,"tag":341,"props":1097,"children":1099},{"class":343,"line":1098},41,[1100],{"type":39,"tag":341,"props":1101,"children":1102},{"style":353},[1103],{"type":45,"value":1104},"    \"proxy_nodes\": proxy_nodes[:25],\n",{"type":39,"tag":341,"props":1106,"children":1108},{"class":343,"line":1107},42,[1109],{"type":39,"tag":341,"props":1110,"children":1111},{"style":353},[1112],{"type":45,"value":1113},"    \"subgraphs\": {\n",{"type":39,"tag":341,"props":1115,"children":1117},{"class":343,"line":1116},43,[1118],{"type":39,"tag":341,"props":1119,"children":1120},{"style":353},[1121],{"type":45,"value":1122},"        name: summarize_subgraph(name)\n",{"type":39,"tag":341,"props":1124,"children":1126},{"class":343,"line":1125},44,[1127],{"type":39,"tag":341,"props":1128,"children":1129},{"style":353},[1130],{"type":45,"value":1131},"        for name in engine.subgraph_names()\n",{"type":39,"tag":341,"props":1133,"children":1135},{"class":343,"line":1134},45,[1136],{"type":39,"tag":341,"props":1137,"children":1138},{"style":353},[1139],{"type":45,"value":1140},"    },\n",{"type":39,"tag":341,"props":1142,"children":1144},{"class":343,"line":1143},46,[1145],{"type":39,"tag":341,"props":1146,"children":1147},{"style":353},[1148],{"type":45,"value":1149},"}\n",{"type":39,"tag":341,"props":1151,"children":1153},{"class":343,"line":1152},47,[1154],{"type":39,"tag":341,"props":1155,"children":1156},{"emptyLinePlaceholder":601},[1157],{"type":45,"value":604},{"type":39,"tag":341,"props":1159,"children":1161},{"class":343,"line":1160},48,[1162],{"type":39,"tag":341,"props":1163,"children":1164},{"style":353},[1165],{"type":45,"value":1166},"if hasattr(engine, \"type_references\"):\n",{"type":39,"tag":341,"props":1168,"children":1170},{"class":343,"line":1169},49,[1171],{"type":39,"tag":341,"props":1172,"children":1173},{"style":353},[1174],{"type":45,"value":1175},"    payload[\"type_reference_samples\"] = {\n",{"type":39,"tag":341,"props":1177,"children":1179},{"class":343,"line":1178},50,[1180],{"type":39,"tag":341,"props":1181,"children":1182},{"style":353},[1183],{"type":45,"value":1184},"        node_id: engine.type_references(node_id)[:10]\n",{"type":39,"tag":341,"props":1186,"children":1188},{"class":343,"line":1187},51,[1189],{"type":39,"tag":341,"props":1190,"children":1191},{"style":353},[1192],{"type":45,"value":1193},"        for node_id in list(nodes)[:25]\n",{"type":39,"tag":341,"props":1195,"children":1197},{"class":343,"line":1196},52,[1198],{"type":39,"tag":341,"props":1199,"children":1200},{"style":353},[1201],{"type":45,"value":944},{"type":39,"tag":341,"props":1203,"children":1205},{"class":343,"line":1204},53,[1206],{"type":39,"tag":341,"props":1207,"children":1208},{"emptyLinePlaceholder":601},[1209],{"type":45,"value":604},{"type":39,"tag":341,"props":1211,"children":1213},{"class":343,"line":1212},54,[1214],{"type":39,"tag":341,"props":1215,"children":1216},{"style":353},[1217],{"type":45,"value":1218},"print(json.dumps(payload, indent=2))\n",{"type":39,"tag":341,"props":1220,"children":1222},{"class":343,"line":1221},55,[1223],{"type":39,"tag":341,"props":1224,"children":1225},{"style":364},[1226],{"type":45,"value":675},{"type":39,"tag":48,"props":1228,"children":1229},{},[1230],{"type":39,"tag":324,"props":1231,"children":1232},{},[1233],{"type":45,"value":1234},"Step 4: Verify the output.",{"type":39,"tag":48,"props":1236,"children":1237},{},[1238],{"type":45,"value":1239},"The output should include:",{"type":39,"tag":94,"props":1241,"children":1242},{},[1243,1252,1261,1270,1281,1306],{"type":39,"tag":98,"props":1244,"children":1245},{},[1246],{"type":39,"tag":54,"props":1247,"children":1249},{"className":1248},[],[1250],{"type":45,"value":1251},"languages",{"type":39,"tag":98,"props":1253,"children":1254},{},[1255],{"type":39,"tag":54,"props":1256,"children":1258},{"className":1257},[],[1259],{"type":45,"value":1260},"summary",{"type":39,"tag":98,"props":1262,"children":1263},{},[1264],{"type":39,"tag":54,"props":1265,"children":1267},{"className":1266},[],[1268],{"type":45,"value":1269},"preanalysis",{"type":39,"tag":98,"props":1271,"children":1272},{},[1273,1279],{"type":39,"tag":54,"props":1274,"children":1276},{"className":1275},[],[1277],{"type":45,"value":1278},"hotspots",{"type":45,"value":1280}," (possibly empty)",{"type":39,"tag":98,"props":1282,"children":1283},{},[1284,1290,1292,1297,1299,1304],{"type":39,"tag":54,"props":1285,"children":1287},{"className":1286},[],[1288],{"type":45,"value":1289},"proxy_nodes",{"type":45,"value":1291}," (empty on v0.2.x or when there are no unresolved calls; on\n0.5.0+ may include ",{"type":39,"tag":54,"props":1293,"children":1295},{"className":1294},[],[1296],{"type":45,"value":75},{"type":45,"value":1298}," entries declared in\n",{"type":39,"tag":54,"props":1300,"children":1302},{"className":1301},[],[1303],{"type":45,"value":83},{"type":45,"value":1305},")",{"type":39,"tag":98,"props":1307,"children":1308},{},[1309,1315],{"type":39,"tag":54,"props":1310,"children":1312},{"className":1311},[],[1313],{"type":45,"value":1314},"subgraphs",{"type":45,"value":1316}," with counts and sample IDs",{"type":39,"tag":48,"props":1318,"children":1319},{},[1320,1322,1328,1330,1335,1337,1343,1344,1350],{"type":45,"value":1321},"On Trailmark 0.5.0+, ",{"type":39,"tag":54,"props":1323,"children":1325},{"className":1324},[],[1326],{"type":45,"value":1327},"attack_surface",{"type":45,"value":1329}," entries may carry an ",{"type":39,"tag":54,"props":1331,"children":1333},{"className":1332},[],[1334],{"type":45,"value":67},{"type":45,"value":1336},"\nobject (e.g. ",{"type":39,"tag":54,"props":1338,"children":1340},{"className":1339},[],[1341],{"type":45,"value":1342},"solidity_visibility",{"type":45,"value":432},{"type":39,"tag":54,"props":1345,"children":1347},{"className":1346},[],[1348],{"type":45,"value":1349},"solidity_overridden_by",{"type":45,"value":1351},"). Pass it\nthrough unchanged — downstream consumers use it to rank entrypoints.",{"type":39,"tag":48,"props":1353,"children":1354},{},[1355],{"type":45,"value":1356},"Some subgraphs may have zero nodes for some codebases (this is\nnormal). Return the full JSON payload regardless.",{"type":39,"tag":1358,"props":1359,"children":1360},"style",{},[1361],{"type":45,"value":1362},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":1364,"total":1460},[1365,1382,1392,1410,1425,1438,1450],{"slug":1366,"name":1366,"fn":1367,"description":1368,"org":1369,"tags":1370,"stars":20,"repoUrl":21,"updatedAt":1381},"address-sanitizer","detect memory errors during fuzzing","AddressSanitizer detects memory errors during fuzzing. Use when fuzzing C\u002FC++ code to find buffer overflows and use-after-free bugs.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1371,1374,1377,1378],{"name":1372,"slug":1373,"type":16},"C#","c",{"name":1375,"slug":1376,"type":16},"Debugging","debugging",{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},"Testing","testing","2026-07-17T06:05:14.925095",{"slug":1383,"name":1383,"fn":1384,"description":1385,"org":1386,"tags":1387,"stars":20,"repoUrl":21,"updatedAt":1391},"aflpp","perform multi-core fuzzing of C\u002FC++ projects","AFL++ is a fork of AFL with better fuzzing performance and advanced features. Use for multi-core fuzzing of C\u002FC++ projects.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1388,1389,1390],{"name":1372,"slug":1373,"type":16},{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},"2026-07-17T06:05:12.433192",{"slug":1393,"name":1393,"fn":1394,"description":1395,"org":1396,"tags":1397,"stars":20,"repoUrl":21,"updatedAt":1409},"agentic-actions-auditor","audit GitHub Actions for security vulnerabilities","Audits GitHub Actions workflows for security vulnerabilities in AI agent integrations including Claude Code Action, Gemini CLI, OpenAI Codex, and GitHub AI Inference. Detects attack vectors where attacker-controlled input reaches AI agents running in CI\u002FCD pipelines, including env var intermediary patterns, direct expression injection, dangerous sandbox configurations, and wildcard user allowlists. Use when reviewing workflow files that invoke AI coding agents, auditing CI\u002FCD pipeline security for prompt injection risks, or evaluating agentic action configurations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1398,1401,1404,1405,1408],{"name":1399,"slug":1400,"type":16},"Agents","agents",{"name":1402,"slug":1403,"type":16},"CI\u002FCD","ci-cd",{"name":18,"slug":19,"type":16},{"name":1406,"slug":1407,"type":16},"GitHub Actions","github-actions",{"name":14,"slug":15,"type":16},"2026-07-18T05:47:48.564744",{"slug":1411,"name":1411,"fn":1412,"description":1413,"org":1414,"tags":1415,"stars":20,"repoUrl":21,"updatedAt":1424},"algorand-vulnerability-scanner","scan Algorand smart contracts for vulnerabilities","Scans Algorand smart contracts for 11 common vulnerabilities including rekeying attacks, unchecked transaction fees, missing field validations, and access control issues. Use when auditing Algorand projects (TEAL\u002FPyTeal).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1416,1419,1420,1421],{"name":1417,"slug":1418,"type":16},"Audit","audit",{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":1422,"slug":1423,"type":16},"Smart Contracts","smart-contracts","2026-07-18T05:47:43.989063",{"slug":1426,"name":1426,"fn":1427,"description":1428,"org":1429,"tags":1430,"stars":20,"repoUrl":21,"updatedAt":1437},"ask-questions-if-underspecified","clarify requirements before implementation","Clarify requirements before implementing. Use when serious doubts arise.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1431,1434],{"name":1432,"slug":1433,"type":16},"Engineering","engineering",{"name":1435,"slug":1436,"type":16},"Productivity","productivity","2026-07-17T06:05:33.543262",{"slug":1439,"name":1439,"fn":1440,"description":1441,"org":1442,"tags":1443,"stars":20,"repoUrl":21,"updatedAt":1449},"atheris","fuzz Python code with Atheris","Atheris is a coverage-guided Python fuzzer based on libFuzzer. Use for fuzzing pure Python code and Python C extensions.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1444,1447,1448],{"name":1445,"slug":1446,"type":16},"Python","python",{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},"2026-07-17T06:05:14.575191",{"slug":1451,"name":1451,"fn":1452,"description":1453,"org":1454,"tags":1455,"stars":20,"repoUrl":21,"updatedAt":1459},"audit-augmentation","augment code graphs with audit findings","Augments Trailmark code graphs with external audit findings from SARIF static analysis results, weAudit annotation files, and version-gated Trailmark 0.4.x binary-analysis graph exports. Maps findings to graph nodes by file and line overlap, creates severity-based subgraphs, and enables cross-referencing findings with pre-analysis data (blast radius, taint, etc.). Use when projecting SARIF results onto a code graph, overlaying weAudit annotations, importing binary graph findings, cross-referencing Semgrep, CodeQL, or binary-analysis findings with call graph data, or visualizing audit findings in the context of code structure.\n",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1456,1457,1458],{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-08-01T05:44:54.920542",77,{"items":1462,"total":1566},[1463,1470,1476,1484,1491,1496,1502,1508,1521,1532,1544,1555],{"slug":1366,"name":1366,"fn":1367,"description":1368,"org":1464,"tags":1465,"stars":20,"repoUrl":21,"updatedAt":1381},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1466,1467,1468,1469],{"name":1372,"slug":1373,"type":16},{"name":1375,"slug":1376,"type":16},{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},{"slug":1383,"name":1383,"fn":1384,"description":1385,"org":1471,"tags":1472,"stars":20,"repoUrl":21,"updatedAt":1391},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1473,1474,1475],{"name":1372,"slug":1373,"type":16},{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},{"slug":1393,"name":1393,"fn":1394,"description":1395,"org":1477,"tags":1478,"stars":20,"repoUrl":21,"updatedAt":1409},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1479,1480,1481,1482,1483],{"name":1399,"slug":1400,"type":16},{"name":1402,"slug":1403,"type":16},{"name":18,"slug":19,"type":16},{"name":1406,"slug":1407,"type":16},{"name":14,"slug":15,"type":16},{"slug":1411,"name":1411,"fn":1412,"description":1413,"org":1485,"tags":1486,"stars":20,"repoUrl":21,"updatedAt":1424},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1487,1488,1489,1490],{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":1422,"slug":1423,"type":16},{"slug":1426,"name":1426,"fn":1427,"description":1428,"org":1492,"tags":1493,"stars":20,"repoUrl":21,"updatedAt":1437},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1494,1495],{"name":1432,"slug":1433,"type":16},{"name":1435,"slug":1436,"type":16},{"slug":1439,"name":1439,"fn":1440,"description":1441,"org":1497,"tags":1498,"stars":20,"repoUrl":21,"updatedAt":1449},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1499,1500,1501],{"name":1445,"slug":1446,"type":16},{"name":14,"slug":15,"type":16},{"name":1379,"slug":1380,"type":16},{"slug":1451,"name":1451,"fn":1452,"description":1453,"org":1503,"tags":1504,"stars":20,"repoUrl":21,"updatedAt":1459},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1505,1506,1507],{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"slug":1509,"name":1509,"fn":1510,"description":1511,"org":1512,"tags":1513,"stars":20,"repoUrl":21,"updatedAt":1520},"audit-context-building","build architectural context for code analysis","Enables ultra-granular, line-by-line code analysis to build deep architectural context before vulnerability or bug finding.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1514,1517,1518,1519],{"name":1515,"slug":1516,"type":16},"Architecture","architecture",{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":1432,"slug":1433,"type":16},"2026-07-18T05:47:40.122449",{"slug":1522,"name":1522,"fn":1523,"description":1524,"org":1525,"tags":1526,"stars":20,"repoUrl":21,"updatedAt":1531},"audit-prep-assistant","prepare codebases for security audits","Prepares codebases for security review using Trail of Bits' checklist. Helps set review goals, runs static analysis tools, increases test coverage, removes dead code, ensures accessibility, and generates documentation (flowcharts, user stories, inline comments).",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1527,1528,1529,1530],{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":1432,"slug":1433,"type":16},{"name":14,"slug":15,"type":16},"2026-07-18T05:47:39.210985",{"slug":1533,"name":1533,"fn":1534,"description":1535,"org":1536,"tags":1537,"stars":20,"repoUrl":21,"updatedAt":1543},"burpsuite-project-parser","parse Burp Suite project files","Searches and explores Burp Suite project files (.burp) from the command line. Use when searching response headers or bodies with regex patterns, extracting security audit findings, dumping proxy history or site map data, or analyzing HTTP traffic captured in a Burp project.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1538,1539,1542],{"name":1417,"slug":1418,"type":16},{"name":1540,"slug":1541,"type":16},"CLI","cli",{"name":14,"slug":15,"type":16},"2026-07-17T06:05:33.198077",{"slug":1545,"name":1545,"fn":1546,"description":1547,"org":1548,"tags":1549,"stars":20,"repoUrl":21,"updatedAt":1554},"c-review","audit C and C++ code","Performs comprehensive C\u002FC++ security review for memory corruption, integer overflows, race conditions, and platform-specific vulnerabilities. Use when auditing native C\u002FC++ applications, reviewing daemons or services for memory safety, or hunting integer overflow \u002F use-after-free \u002F race conditions in userspace code.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1550,1551,1552,1553],{"name":1417,"slug":1418,"type":16},{"name":1372,"slug":1373,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},"2026-07-17T06:05:11.333374",{"slug":1556,"name":1556,"fn":1557,"description":1558,"org":1559,"tags":1560,"stars":20,"repoUrl":21,"updatedAt":1565},"cairo-vulnerability-scanner","scan Cairo and StarkNet contracts for vulnerabilities","Scans Cairo\u002FStarkNet smart contracts for 6 critical vulnerabilities including felt252 arithmetic overflow, L1-L2 messaging issues, address conversion problems, and signature replay. Use when auditing StarkNet projects.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[1561,1562,1563,1564],{"name":1417,"slug":1418,"type":16},{"name":18,"slug":19,"type":16},{"name":14,"slug":15,"type":16},{"name":1422,"slug":1423,"type":16},"2026-07-18T05:47:42.84568",111]