Package Exports
- pentesting
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (pentesting) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Pentesting 🔓
✅ Capabilities
Agent-loop essentials plus a security-focused runtime layer.
| Area | What it does |
|---|---|
| Model-driven loop | Streaming action/observation loop; model Stop ends a turn, while verified artifacts close a mission and the full turn trajectory is persisted with the outcome |
| Tool guardrails | Read-before-edit enforcement, repeat-call guard, policy-gated file/shell/network |
| Permissions | Allow / Deny / Confirm, with once/always decisions persisted |
| Context compaction | Automatic micro-pruning + model-triggered summarization, pre/post hooks |
| Interrupt & steering | ESC interruption plus a revisioned FIFO queue with explicit amend/replace intent and deterministic PTY Enter ownership |
| Reverse-shell control plane | Accept and track multiple authorized callbacks, tag/probe sessions, send/observe/run commands, verify PTY upgrades, and keep transcript/ledger/evidence records |
| PTY session control | One actor owns each socket/PTY/pipe, command queue, transcript, and child lifecycle, with resize gating, FD accounting, and deterministic close/revoke/gc reclamation |
| Frontier-guided exploration | Always-available bounded security tool with a lead ledger, explicit dispatch, and knowledge-preserving dead-probe pivots |
| Subagents | Broad-clone delegates with category focus overlays; independent deep-specialist leads (crypto/rev/pwn) run in the same parallel batch so the main line keeps moving |
| MCP & skills | Dynamic MCP tool discovery, layered markdown skills |
| Memory | Ebbinghaus-style decaying notes + hybrid lexical/semantic/graph retrieval |
The default execution path is one agent loop, but subagents remain available
through the task tool for independently scoped work and bounded parallel
exploration. Child runs use the same permissions and tool gateway, carry a
focused overlay and runtime budget, and merge evidence back by reference.
🚀 Quick Start
Install globally, or run once with a Node package runner:
npm install -g pentesting && pentesting # install
npx pentesting # or run once, no install
pnpm dlx pentesting
yarn dlx pentestingRequires Node.js 18.18+. Use npm/npx/pnpm/yarn; Bun and Deno runners are not supported.
Docker-only development builds
Repository builds and Rust tests must always use the resource-capped Docker wrappers. Host Cargo compilation is fail-closed; free disk or RAM does not make it an approved path.
scripts/dbuild.sh check --workspace --all-targets
scripts/dbuild.sh test -p builder_domain
scripts/dverify.sh focused
scripts/dverify.sh full
scripts/dbuild-image.sh validation # once per fresh Docker cache
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/dbuild.ps1 test -p builder_domain # Windows
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/nverify.ps1 # Windows npm verifyThe wrappers cap memory, CPU, PIDs, jobs, test threads, and time; verify storage before launch; serialize heavy work; and leave a redacted resource report. CI uses the same Docker-only path. Full policy: Docker-only build safety.
🐳 Run with Docker
No local Rust toolchain needed:
Published images support linux/amd64 only. Docker is the recommended runtime
on Windows and macOS; Apple Silicon Macs run the amd64 image through Docker
Desktop emulation. Native ARM64 images and binaries are not supported.
export OPENAI_API_KEY="sk-..." # provider API key or gateway token
export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_MODEL="gpt-4o"
export OPENAI_MAX_TOKENS="4096"
docker run -it --rm \
-v "$(pwd):/workspace" \
-v pentesting-config:/root/.pentesting \
-w /workspace \
-e OPENAI_API_KEY \
-e OPENAI_BASE_URL \
-e OPENAI_MODEL \
-e OPENAI_MAX_TOKENS \
agnusdei1207/pentesting:latestProvider environment variables are optional for startup. If they are omitted,
the interactive TUI still launches and lets you configure/login inside the
persistent pentesting-config volume.
Or via Docker Compose:
PENTESTING_PROJECT_DIR=/path/to/project \
OPENAI_API_KEY=sk-... \
OPENAI_BASE_URL=https://api.openai.com/v1 \
OPENAI_MODEL=gpt-4o \
OPENAI_MAX_TOKENS=4096 \
docker compose run --rm pentestingCommon commands
pentesting # Interactive TUI
pentesting --prompt "Enumerate the target and summarize next actions."
pentesting shell-listener --bind 127.0.0.1 --port 4444 # Authorized reverse-shell listener
pentesting --versionUse shell-listener in authorized CTF/lab work to accept callbacks, tag sessions, run sentinel-tracked commands, verify PTY upgrades, and retain transcripts/evidence.
Short version: the agent can catch a dumb reverse shell, upgrade it to a verified PTY, pivot to a second callback, and reclaim both sessions cleanly with close / revoke / gc.
Interactive control defaults
/modelowns a modal terminal surface. Returning from it restores the prior transcript cursor before the fixed prompt/status rows are redrawn, so later responses and errors append instead of overwriting the input area./goal <task>records the goal only. Autonomous continuation starts off and can be enabled or stopped only with an explicit/autocommand.- Tool/request budget exhaustion does not create a fresh turn while auto mode is off. A submitted queued input takes precedence over autonomous follow-up.
- Submitted type-ahead is consumed once in FIFO order at the next safe turn boundary. Only explicit amend/replace intent may change that handoff.
On native Windows Git Bash, the repository smoke path builds the capped Docker image and then opens this interactive TUI without WSL:
npm run checkInside a session, /help lists every command and /update pulls the latest release for supported native targets.
🔌 Reverse-shell & PTY sessions
Catch and manage authorized shell callbacks: one listener, many targets, audited cleanup.
pentesting shell-listener --port 4444 # 1. Catch callbacks (tracks many at once)
pentesting shell-session list # 2. See every live session + FD ownership
pentesting shell-session run -- id # 3. Run sentinel-bounded commands, capture output
pentesting shell-session pty-upgrade # 4. Inject the PTY helper; `upgrade` then verifies it
pentesting shell-session revoke --session 1 # 5. Hard-close: reclaim FDs + archive evidence- Track — each callback is accepted, numbered, and tagged; one session actor exclusively owns its live descriptors, transcript, and child lifecycle.
list/info/fdstat/lifecycleshow state and byte counts without cloned reader/writer descriptors. - Drive —
runwraps commands in a sentinel to capture exactly their output;send/raw/signal/resizegive interactive control. - Upgrade —
pty-upgradesends the built-in helper andupgradeverifies a real PTY before remote resize is allowed; the agent must pick the method with--technique(python3,python,python2,script,expect— no default) after reconning what the target actually has, or send a fully custom command instead. - Record — per-session raw log, full-duplex transcript, command ledger, replay, and evidence manifest — with secret redaction for registered values.
- Reclaim —
close(graceful) andrevoke(hard) release file descriptors immediately and archive the session;gcprunes closed sessions. Reclamation is tracked end-to-end, so FDs never leak.
⚙️ Configuration
Pentesting uses local storage by default. For normal use, configure only the model endpoint:
Example .env / shell setup
# OpenAI-compatible provider or gateway
export OPENAI_API_KEY="sk-..."
export OPENAI_BASE_URL="https://api.openai.com/v1"
export OPENAI_MODEL="gpt-4o"
export OPENAI_MAX_TOKENS="4096"
# Runtime overrides (optional)
export PENTESTING_CONFIG="$HOME/.config/pentesting" # move the global config dir
export PENTESTING_SKIP_DOWNLOAD=1 # skip postinstall binary download (CI)The TUI pre-fills output max tokens from known model names/provider metadata. OPENAI_MAX_TOKENS and the TUI field are explicit overrides for custom/self-hosted models.
Frontier-guided CTF exploration
There are no separate security, CTF, and frontier modes. Session/process,
finding/verification, flag_check, and explore tools share one default
security surface. Engagement metadata describes scope, target, and flag format;
it does not unlock tools. CTF-shaped context may tailor the prompt, while
flag_check remains a verification tool and evidence source instead of a
default completion gate. [exploration] contains only resource caps. A
ready-to-copy context lives at
docs/config/ctf.toml:
[engagement]
kind = "ctf"
flag_format = "flag\\{[^}]+\\}"
require_flag_evidence = false
[exploration]
max_frontier_nodes = 256
max_breadth = 4With the profile active, the runtime stores explore leads as bounded
EvidenceKind::Lead events and reuses prior-run records by reference rather
than copying them. A repeated dead probe suppresses that execution path but
does not reject the underlying hypothesis; fresh evidence reopens it. The model
still drives work through the explicit explore and task tools. Exploration
does not replace the core execution strategy, add a background scheduler, or
expose a passive /frontier UI/query path. Node, breadth, and depth limits bound
its cost.
Malformed tool-call output is fail-loud: unparsed tool-shaped markup is retried
instead of accepted as a final answer, the TUI suppresses raw control markup, and
long no-newline streams flush at soft text boundaries so rendering cannot hang
behind usage-only progress ticks. The startup banner and live status row stay
compact; generic run, token, and queued-input detail lives in /status.
The shipped contract is covered by
scripts/dbuild.sh test -p builder_app orch_spec::exploration_e2e: it verifies the
always-available tool path plus breadth enumeration, depth descent, sibling
breadth, dead-probe pivot, global reseed, seed digest, broad-clone overlay, and
child result promotion.
With Docker, mount both your project and the persistent runtime config volume, then pass the same variables through with -e:
docker run -it --rm \
-v "$(pwd):/workspace" \
-v pentesting-config:/root/.pentesting \
-w /workspace \
-e OPENAI_API_KEY \
-e OPENAI_BASE_URL \
-e OPENAI_MODEL \
-e OPENAI_MAX_TOKENS \
agnusdei1207/pentesting:latestThose variables only pre-fill provider settings. Leaving them unset must not block the container from launching the TUI; configure the provider interactively inside the container instead.
Note: The command you run is always
pentesting. The internal engine isbuilder—pentestingdownloads and runs it under the hood; the engine name never surfaces in normal use.
📖 Documentation
ARCHITECTURE.md— Runtime flow, agent team, memory model, crate map, tool surface, and supported targets.- Documentation map — Current authoritative documents versus historical plans and research notes.
- Integrated runtime design — Top-down explanation from the one-loop model to prompt, subagents, persistence, and PTY ownership.
- Minimal Core implementation — Implemented simplification record for the single turn/tool/security surface.
- Next-generation clean-break convergence — Canonical contracts, deleted compatibility paths, and the phase-by-phase migration boundary.
- Internal layout: service traits are split under
builder_app/src/services/*; OpenAI request conversion is isolated underdto/openai/request/*. - Public site — Landing page and public runtime entry surface.
compose.yaml— Docker Compose facade for pentesting sessions.
🎹 From the Developer
"I believe playing the piano is also a form of orchestration."
The harmony of polyphony — multiple voices — and homophony — a single melodic line.
Each voice sings its most beautiful song from its own place, yet when combined, they create one grand, beautiful melody. I believe this structure is no different from AI agents.
— agnusdei1207