SDKNamed libraries
Imports of AI SDKs and agent frameworks, from a table kept per language — Python, JavaScript and Java through to Kotlin, Swift, Go, Rust, R, Julia and PowerShell.
AI Agent Scan is now so powerful, so comprehensive, we've given it its own dedicated page. It reads every text file in your tree, applies the full rules in 22 languages, and finds by name the three ways the 2025 malware wave hid a model inside a program.
↓ keep scrolling ↓Agent Scan is about what the code does at run time, not who wrote it. It reads the source for the places a program talks to a model, then looks at what happens to the reply. A reply that is printed is routine. A reply that is passed to a shell, an exec, an eval or a process launcher is the shape that LLM-enabled malware takes, and it is rated CRITICAL wherever the scanner has the language's launch table.
Imports of AI SDKs and agent frameworks, from a table kept per language — Python, JavaScript and Java through to Kotlin, Swift, Go, Rust, R, Julia and PowerShell.
Hosted model APIs by host name with the country the provider is in, and local inference servers — Ollama, llama.cpp, vLLM — whether named directly, read from OLLAMA_HOST, or reached through the Ollama client library.
A process launch or code evaluation within ten lines of a model call. This is the finding that separates a chatbot from a program that does what a model tells it. CRITICAL, with the line number.
A program that runs claude, gemini, codex, copilot, aider, opencode or q with a prompt is HIGH. One that passes the flag that switches off the agent's permission checks is CRITICAL — the shape of the nx supply-chain attack.
Base64, hex and compressed string literals are decoded. A decoded string that reads as instructions to a model is reported as an encoded prompt; a decoded model host is reported as hidden. Either one in a file that runs commands is CRITICAL.
A model called once per iteration is a cost and a runaway risk. The rule checks that the call sits inside the loop's block, not merely below a loop header somewhere above.
The script blocks of HTML, Vue, Svelte and Astro pages are scanned as JavaScript; the code cells of a Jupyter notebook as Python, with the cell named in the finding; workflow steps, Dockerfiles and Jenkinsfiles as shell.
API keys and private keys sitting in the tree, found by format and shown redacted — one policy line away from failing the build.
The same scan produces an inventory of every provider, endpoint and jurisdiction the code reaches, native or CycloneDX, and a policy gate that blocks a merge on unapproved providers or foreign-hosted models.
Three public incidents in 2025 each hid a model inside a program in a different way. The samples below are inert files written in the shape of each one; the cards are the scanner's real output on them, unedited.
OLLAMA_HOST or calls the client library. The scanner reports the local endpoint from that alone, and the launch of its reply on line 4.Real output from CodeDelta on inert sample files written in the shape of each incident. No incident code is distributed with the tool.
A scanner that opens only the file types it knows best leaves the rest of the tree unexamined without saying so. Agent Scan reads every text file up to 2 MB and records on each result which of three levels it received, so a clean tree is a clean tree and not a silence.
Full rules — SDK tables, model calls, agent frameworks, loops, and the rogue rule — in C, C#, C++, Dart, Elixir, Go, Groovy, Java, JavaScript, Julia, Kotlin, Lua, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Swift and TypeScript; also the script blocks of HTML, Vue, Svelte and Astro files and the code cells of Python notebooks.
Endpoint level — model endpoints, encoded payloads and the language's own launch and eval calls, with no SDK table — in shell scripts, CI recipes, Dockerfiles, Jenkinsfiles and Objective-C. The curl model | bash shape lives here and rates CRITICAL.
Text level — model endpoints and encoded payloads, plus Markdown code blocks that would rate HIGH or CRITICAL under their language's rules — for every other readable file, ELEVATED at most.
The user guide's language table carries the level per extension; that column is generated from the scanner's own tables, so the two cannot drift apart.
C, C#, C++, Dart, Elixir, Go, Groovy, Java, JavaScript, Julia, Kotlin, Lua, Perl, PHP, PowerShell, Python, R, Ruby, Rust, Scala, Swift, TypeScript.
HTML, Vue, Svelte and Astro: the <script> blocks and inline event handlers scanned as JavaScript, findings attributed to the page and line.
Jupyter code cells scanned as Python, including ! shell lines; each finding names the file line and the cell.
Shell scripts, GitHub and GitLab workflows, Dockerfiles, Jenkinsfiles, Objective-C: endpoints, encoded payloads and launches.
Any readable file to 2 MB: endpoints, encoded payloads, dangerous Markdown code blocks. ELEVATED at most.
The report, the JSON and the CSV carry the coverage level per file; the summary line counts the files at each.
Every finding is a sentence a reviewer can check against the source in the same panel. The screens below are from one scan of the sample tree — click any picture to enlarge it.
exec of the reply, reported as line 28, cell 3 so the reviewer opens the right cell.
codex exec with its approval checks off. The badge says the file had the shell/CI level of scan.
Runtime.getRuntime().exec. The panel marks the cited line; a card's every line number can be checked this way without leaving the report.Real output from CodeDelta — every figure above is produced by the tool from an actual scan, not a mock-up.
The same scan opens in the Code Browser as an Agents view and as a 3-D map in the Visualiser. Files are coloured by their Agent Scan risk; providers hosted in sovereignty-sensitive jurisdictions are red. Click any picture to enlarge it.
multi_agent.py, spinning up autonomous crews with langchain and crewai.Real screens from the Code Browser on the demo repository.
Twenty-five public repositories, more than 30,000 files, were scanned with the released v2.0.2 scanner and with this one, on the same clones. Every HIGH and CRITICAL result from the new scanner was read by a person. The repositories were the SDKs and agent frameworks themselves — openai-python, anthropic-sdk-python, aider, gemini-cli, llama.cpp, ollama-python, openai-kotlin, koog, MacPaw OpenAI, SwiftAnthropic, go-openai, langchaingo, ruby-openai, langchainrb, async-openai, rig, openai-java, openai-scala-client, brainlid/langchain, ellmer, PromptingTools.jl, lua-openai, openai-php/client, langchain_dart, PSOpenAI — the hardest case, because code that implements agents looks like code that runs them.
Across the eighteen repositories in the second run, the v2.0.2 scanner opened 4,693 files; this one opens 19,499. In the Swift, Kotlin, Scala, Elixir, R, Julia and Lua repositories the released scanner opened none at all: SwiftAnthropic 0 → 59 files, ellmer 0 → 391, koog 124 → 2,616, openai-java 64 → 4,023.
The first real-world hit of the agent-CLI rule: llama.cpp's own .github/workflows/ai-issues.yml runs opencode run with a prompt on a self-hosted runner. HIGH, and correct — it is an agent launched from CI.
llama.cpp HIGH 18 → 4 (decode loops are not model calls); gemini-cli's help text naming gemini -p HIGH → NORMAL; a test that serves a loopback address CRITICAL → NORMAL; a CI recipe that installs and starts Ollama CRITICAL → NORMAL; a Ruby string containing backticks CRITICAL → ELEVATED. Each has a fixture that failed before the fix and a guard that keeps the rule on.
The remaining HIGH results are chat loops that call the model per turn — while True, for s.Scan(), for prompt in prompts — and the orchestration code inside the agent frameworks. Read by eye, each is the rule describing the thing.
Three fixed corpora and the tool's own 489-file tree rated identically before and after each false-positive fix; the demo samples are held to a frozen baseline; a parallel scan is bit-identical to a serial one.
The Kotlin and Swift SDK names were checked against the libraries' own repositories and Apple's documentation before they went in a table; the web-page event-handler names come from the MDN list. A guess is not a rule.
Findings are patterns in source that warrant a human's look, not confirmed malicious activity; the report says so at the top of every run. The rogue rule works on proximity — a launch within ten lines of a model call — so a program that fetches a reply in one file and runs it from another is two ELEVATED files, not one CRITICAL.
Encoded literals are decoded once — base64 or hex, compressed or not — so a string encoded twice over is not read. A file that both serves a local model and pipes its output to a shell is treated as the server side and missed by the rogue rule. An agent CLI named as one element of an argument list is found only when its subcommand follows it directly.
Against careless concealment — the encoded prompt, the environment-variable host, the agent run from a CI step — this is a first tier that did not exist before. Against a determined adversary who builds every string at run time, no scan of the source is the last word, and this page does not claim to be.
Nothing in the file matched an SDK, an endpoint or a launch rule at the level it was scanned.
An SDK or endpoint is present. The ceiling for text-level files.
A model called inside a loop, an agent CLI launched with a prompt, prompts built from unchecked input.
The rogue pattern, an agent CLI with its checks bypassed, an encoded prompt or hidden host in a file that runs commands.
Download a time-limited trial license and run Agent Scan locally, from the desktop app or one command. No source code is transmitted.
Try CodeDelta