The agent
thespider-agent is a small local binary. It logs you in, claims work, runs your model CLI in the checkout, and posts the output. Prompts, parsing, and findings live on the server.
Install the skill (optional)
npx skills add https://thespider.xyz -g
Then ask a coding agent "Get me started with TheSpider." or "What's the next TheSpider step in this repo?" On-prem, pass your instance origin.
Commands
thespider-agent setup [--model <lab/model>] [--agent grok|claude|codex|opencode|<any>] [--command TPL]
[--profile security|bugs] [--project org/slug]
thespider-agent check-models
thespider-agent login | init | logout | status | models | run | gate
thespider-agent daemon [--interval SECS] [--workdir DIR] [--models a,b] [--profile P] [--redact]
thespider-agent findings list|show|triage|packet|copy
thespider-agent log list|show|path|clean
thespider-agent wait --campaign <id>
thespider-agent refine [--max-iterations N] [--min-severity SEV] [--list]
thespider-agent update
--model names the model (models.dev code). --agent names the local CLI. --code / --harness are deprecated aliases. --model claude does not select the Claude CLI; use --agent claude.
Setup and a first run
cd /path/to/repository
thespider-agent setup --model xai/grok-4.6 --agent grok --profile bugs
# Omit --model on a terminal to search models.dev.
thespider-agent run --once --max-slices 1
| Flag | Default | Meaning |
|---|---|---|
--model | interactive search | models.dev code, e.g. xai/grok-4.6 |
--agent | auto-detect (Grok first) | grok, claude, codex, opencode, or any other name with --command |
--command | none | Required for an agent TheSpider does not know. {prompt_path} is the slice prompt. |
--model-id | derived from --model | Override only if the CLI's alias differs |
--variant | none | OpenCode --variant only |
--refresh | off | Re-download the models.dev catalog |
--agent and --model are independent: --agent codex --model anthropic/claude-opus-5 is fine.
An agent TheSpider does not know:
thespider-agent setup \
--model alibaba/qwen3.8-max \
--agent pi \
--command 'pi run --model qwen3.8-max {prompt_path}'
Setup will not overwrite an existing freeform command on that code. With several org memberships it asks which org. It only auto-picks a project on an exact remote match or an explicit --project.
Check local CLIs
thespider-agent check-models
Offline and free: no server call, no model call. It probes the four built-in CLIs (version and login status, 10-second timeout each) and lists whether each project binding's command is on PATH. Exit 1 only when a built-in agent a binding uses is missing or logged out. Grok cannot answer an auth probe, so that line is "unsupported", not a blocker.
thespider-agent models is different: it compares local bindings with the models the server has enabled.
Run
thespider-agent run [--campaign <id>] [--profile security|bugs] [--once] [--max-slices N] [--models a,b] [--redact]
Without --campaign, this creates a full campaign from local git metadata, claims slices for the bound models, runs each with sh -c, and posts stdout. --once --max-slices 1 is the bounded first-run.
Daemon
For team / PR CI: one long-lived process on a box that has model credentials and git access. CI never runs a model. See PR gate.
thespider-agent daemon [--interval 30] [--workdir DIR] [--models a,b] [--profile P] [--redact]
It polls claimable campaigns, clones the exact commit into a managed checkout, then claims and runs like run. SIGINT / SIGTERM finish the in-flight campaign and stop. Git auth is whatever that OS user already uses (ssh-agent or an HTTPS helper).
Logs
thespider-agent log list [--slice N] [--limit N] [--all-servers]
thespider-agent log show <slice-id> [--lease N] [--stream stdout|stderr|both] [--follow] [--timeout SECS]
thespider-agent log path <slice-id> [--lease N]
thespider-agent log clean (--older-than-days N | --all) [--include-running] [--dry-run]
Every lease attempt writes its own directory on the machine that ran the model — <data dir>/thespider/logs/<server id>/<slice id>-<lease id>/, holding meta.json, stdout.log, stderr.log, and a result.json that only exists once the lease is finished. The payload files are the model's own bytes, appended as they arrive and never rewritten — short is possible, silently holed is not (see below) — so log show 88 --follow attaches to a run in progress from another terminal and exits 0 when the terminal record lands. The positional is a slice id — the id run and daemon print; a bare log show 88 takes the newest attempt and says so on stderr, and --lease N pins one. log path 88 prints just the directory, for your own tail -f. --timeout SECS is one total budget for --follow — it covers waiting for the log to appear and then waiting for the terminal record, not one budget each — and defaults to 1800 seconds. log show sanitises what it prints: model output is untrusted, so it strips every C0 control except \n, \t and \r, every C1 byte, and every ESC-introduced escape sequence before writing to your terminal — log path, and the files under it, is the only byte-faithful route. Nothing here is uploaded, needs auth, or talks to the server, and a read never creates a directory. Exit codes: 0 ok, 1 no log for that selector, 3 --follow hit --timeout, 5 usage, 6 operational — the log root, or a server namespace inside it, exists but cannot be read, or an I/O error interrupted the walk. A store that is not there yet is 1, not 6; a single lease with a corrupt meta.json is skipped with a warning rather than failing the command, and log clean --all reclaims it.
Retention is manual and local: nothing sweeps these directories, each stream is capped at 32 MiB, and log clean --older-than-days 14 (or --all) is the only collector. clean is scoped to the current repo's server namespace — the same scope log list shows without --all-servers — so a machine that audits projects against more than one server runs it once per server, from a repo bound to each. THESPIDER_LOG_DIR moves the root; THESPIDER_NO_LOGS=1 turns lease logging off. On Windows, %APPDATA% roams — point THESPIDER_LOG_DIR somewhere local.
Lease logs and --redact
The agent keeps a per-lease run log on your machine under its data directory: the model's stdout and stderr, plus a small metadata and result record. Nothing is uploaded; this is separate from the artifact the server already stores.
--redact masks secret-shaped strings and caps stdout at 1 MiB before upload, and it governs the local copy by exactly the same rule, so the flag means one thing everywhere. There are two rules and no others:
- stdout follows
--redacton both sides. Without the flag, the log holds the model's raw stdout, streamed as it arrives — that is what makeslog show --followlive. With the flag, the log holds the same masked, 1 MiB-capped buffer that is uploaded. - stderr is raw on both sides.
--redacthas never masked stderr for the upload, and it does not mask the local copy either.
Under --redact the payload is not live: nothing reaches the disk while the model runs, and both files are written once, when the model exits, so log show --follow reports the lease's state and liveness during the run and delivers the output at the end. That is a deliberate trade, and --redact is off by default.
The local stderr.log holds the model's complete stderr, while the upload carries only its last 4000 bytes — the local copy is the bigger exposure of the two, not the smaller. Both local streams are capped at 32 MiB each; past that the agent stops appending and records the truncation in the result record.
result.json tells apart the two ways a payload file can fall short. stdout_truncated with stdout_dropped_bytes: 0 is the cap — the file is a prefix of the stream. A non-zero stdout_dropped_bytes means the log filesystem could not keep up — it stalled for two full seconds, or cost the model's pipe thirty seconds of backpressure over the run — so the agent stopped teeing that stream rather than hold up the model, and bytes are missing. log_errors names the stream and a warning goes to stderr during the run. Only the local copy is ever affected — the artifact uploaded to the server is complete either way.
Read stdout_dropped_bytes and stderr_dropped_bytes to find out: they are authoritative and always correct. The file may also carry an in-band [lease log: N bytes dropped here] line where the bytes stop, but the thread that writes it is the one that was falling behind, so it lands only if the filesystem recovered before the lease ended. The absence of a marker is not evidence that the file is whole.
On Unix the log directory is 0700 and its files are 0600; on Windows they inherit the parent ACL, and note that %APPDATA% roams — set THESPIDER_LOG_DIR to keep multi-megabyte transcripts out of a roaming profile. Treat these files exactly as you would treat the raw artifact on the server. Nothing sweeps them: thespider-agent log clean is the collector, and THESPIDER_NO_LOGS=1 turns lease logging off entirely.
The server-side scrubber is a separate layer and is unrelated to either case: it always runs on parsed findings, never on raw stdout artifacts, and never on anything the agent keeps locally. More: Data handling.
Findings
thespider-agent findings list --open --severity critical,high --json
thespider-agent findings show 501 --json
thespider-agent findings packet 501
thespider-agent findings triage 501 --status accepted --reason "risk accepted"
Filters run on the server before pagination. --json prints one JSON document on stdout, including on failure. Envelope and exit codes: Agent CLI contracts.
Wait vs gate
thespider-agent wait --campaign 81 --timeout 1800 --fail-on critical,high --json
thespider-agent gate --campaign 81
They are different tools. wait blocks until the campaign is idle, then fails on actionable findings. gate is a single poll for CI (0 pass / 1 fail / 2 pending). Do not mix their exit codes. Details: PR gate.
Refine
refine is the fix-and-verify half of the loop. It picks actionable findings, has a local model write a fix, records the commits as a proposed fix (needs_retest), then runs a retest. Only a finished retest concludes fixed or still_vulnerable.
thespider-agent refine --min-severity high --max-iterations 2
Full flags, worktree, and threat model: Refine.
--redact masks secret-shaped stdout and caps it before upload. The server also scrubs parsed findings. Raw artifacts store whatever was uploaded unless you pass --redact. It governs the agent's own lease log the same way — masked stdout, raw stderr. See Logs.