pentesting 0.100.5 β†’ 0.100.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -1,28 +1,28 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 agnusdei1207
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
22
-
23
- ---
24
-
25
- Note: This MIT license covers the published `pentesting` npm wrapper (the
26
- launcher in `bin/` and `lib/` plus its install scripts). The Builder runtime
27
- engine that the wrapper downloads and executes is a separate, proprietary
28
- component and is not licensed under these terms.
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agnusdei1207
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
+
23
+ ---
24
+
25
+ Note: This MIT license covers the published `pentesting` npm wrapper (the
26
+ launcher in `bin/` and `lib/` plus its install scripts). The Builder runtime
27
+ engine that the wrapper downloads and executes is a separate, proprietary
28
+ component and is not licensed under these terms.
package/README.md CHANGED
@@ -1,227 +1,280 @@
1
- # Pentesting πŸ”“
2
-
3
- > **Pentesting** is a local-first Rust coding agent CLI for authorized security work, with audited reverse-shell and PTY session control: catch callbacks, verify upgrades, pivot across sessions, and reclaim them cleanly.
4
-
5
- The runtimeβ€”not the modelβ€”owns routing, tool sandboxing, verification, completion adjudication, and PTY/session lifecycle management. PTYs are first-class runtime objects: upgrade state, resize authority, transcript capture, file-descriptor ownership, and close/revoke/gc reclamation are all tracked explicitly.
6
-
7
- <div align="center">
8
- <img src="https://api.iconify.design/hugeicons:bash.svg" alt="pentesting bash icon" width="120" />
9
- <h1>pentesting</h1>
10
- <p>Security-Focused Agent Runtime</p>
11
-
12
- [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
13
- [![npm](https://img.shields.io/npm/v/pentesting.svg)](https://www.npmjs.com/package/pentesting)
14
- </div>
15
-
16
- ---
17
-
18
- ## βœ… Capabilities
19
-
20
- Agent-loop essentials plus a security-focused runtime layer.
21
-
22
- | Area | What it does |
23
- | --- | --- |
24
- | Model-driven loop | Streaming tool-use loop; the model decides when it's done |
25
- | Tool guardrails | Read-before-edit enforcement, repeat-call guard, policy-gated file/shell/network |
26
- | Permissions | Allow / Deny / Confirm, with once/always decisions persisted |
27
- | Context compaction | Automatic micro-pruning + model-triggered summarization, pre/post hooks |
28
- | Interrupt & steering | ESC to interrupt mid-turn, queue follow-ups while it works, and keep Enter submissions deterministic across PTY redraw/control-response noise |
29
- | 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 |
30
- | PTY session control | Treat upgraded shells as managed PTY sessions with resize gating, transcript capture, FD accounting, and deterministic close/revoke/gc reclamation |
31
- | Frontier-guided exploration | Persistent, deduplicated lead frontier: the runtime enforces pivots and caps, and recommends breadth-first enumeration vs depth-first exploitation while the model drives |
32
- | 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 |
33
- | MCP & skills | Dynamic MCP tool discovery, layered markdown skills |
34
- | Memory | Ebbinghaus-style decaying notes + hybrid lexical/semantic/graph retrieval |
35
-
36
- ---
37
-
38
- ## πŸš€ Quick Start
39
-
40
- Install globally, or run once with a Node package runner:
41
-
42
- ```bash
43
- npm install -g pentesting && pentesting # install
44
- npx pentesting # or run once, no install
45
- pnpm dlx pentesting
46
- yarn dlx pentesting
47
- ```
48
-
49
- Requires Node.js 18.18+. Use npm/npx/pnpm/yarn; Bun and Deno runners are not supported.
50
-
1
+ # Pentesting πŸ”“
2
+
3
+ <div align="center">
4
+ <img src="https://api.iconify.design/hugeicons:bash.svg" alt="pentesting bash icon" width="120" />
5
+ <h1>pentesting</h1>
6
+ <p>Security-Focused Agent Runtime</p>
7
+
8
+ [![MIT License](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
9
+ [![npm](https://img.shields.io/npm/v/pentesting.svg)](https://www.npmjs.com/package/pentesting)
10
+ </div>
11
+
12
+ ---
13
+
14
+ ## βœ… Capabilities
15
+
16
+ Agent-loop essentials plus a security-focused runtime layer.
17
+
18
+ | Area | What it does |
19
+ | --- | --- |
20
+ | 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 |
21
+ | Tool guardrails | Read-before-edit enforcement, repeat-call guard, policy-gated file/shell/network |
22
+ | Permissions | Allow / Deny / Confirm, with once/always decisions persisted |
23
+ | Context compaction | Automatic micro-pruning + model-triggered summarization, pre/post hooks |
24
+ | Interrupt & steering | ESC interruption plus a revisioned FIFO queue with explicit amend/replace intent and deterministic PTY Enter ownership |
25
+ | 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 |
26
+ | 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 |
27
+ | Frontier-guided exploration | Always-available bounded security tool with a lead ledger, explicit dispatch, and knowledge-preserving dead-probe pivots |
28
+ | 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 |
29
+ | MCP & skills | Dynamic MCP tool discovery, layered markdown skills |
30
+ | Memory | Ebbinghaus-style decaying notes + hybrid lexical/semantic/graph retrieval |
31
+
32
+ ---
33
+
34
+ The default execution path is one agent loop, but subagents remain available
35
+ through the `task` tool for independently scoped work and bounded parallel
36
+ exploration. Child runs use the same permissions and tool gateway, carry a
37
+ focused overlay and runtime budget, and merge evidence back by reference.
38
+
39
+ ---
40
+
41
+ ## πŸš€ Quick Start
42
+
43
+ Install globally, or run once with a Node package runner:
44
+
45
+ ```bash
46
+ npm install -g pentesting && pentesting # install
47
+ npx pentesting # or run once, no install
48
+ pnpm dlx pentesting
49
+ yarn dlx pentesting
50
+ ```
51
+
52
+ Requires Node.js 18.18+. Use npm/npx/pnpm/yarn; Bun and Deno runners are not supported.
53
+
54
+ ### Docker-only development builds
55
+
56
+ Repository builds and Rust tests must always use the resource-capped Docker
57
+ wrappers. Host Cargo compilation is fail-closed; free disk or RAM does not make
58
+ it an approved path.
59
+
60
+ ```bash
61
+ scripts/dbuild.sh check --workspace --all-targets
62
+ scripts/dbuild.sh test -p builder_domain
63
+ scripts/dverify.sh focused
64
+ scripts/dverify.sh full
65
+ scripts/dbuild-image.sh validation # once per fresh Docker cache
66
+ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/dbuild.ps1 test -p builder_domain # Windows
67
+ powershell -NoProfile -ExecutionPolicy Bypass -File scripts/nverify.ps1 # Windows npm verify
68
+ ```
69
+
70
+ The wrappers cap memory, CPU, PIDs, jobs, test threads, and time; verify storage
71
+ before launch; serialize heavy work; and leave a redacted resource report. CI
72
+ uses the same Docker-only path. Full policy: [Docker-only build safety](https://github.com/agnusdei1207/pentesting/blob/main/docs/BUILD_SAFETY.md).
73
+
51
74
  ### 🐳 Run with Docker
52
75
 
53
76
  No local Rust toolchain needed:
54
77
 
55
- ```bash
56
- export OPENAI_API_KEY="sk-..." # provider API key or gateway token
57
- export OPENAI_BASE_URL="https://api.openai.com/v1"
58
- export OPENAI_MODEL="gpt-4o"
59
- export OPENAI_MAX_TOKENS="4096"
60
-
61
- docker run -it --rm \
62
- -v "$(pwd):/workspace" \
63
- -v pentesting-config:/root/.pentesting \
64
- -w /workspace \
65
- -e OPENAI_API_KEY \
66
- -e OPENAI_BASE_URL \
67
- -e OPENAI_MODEL \
68
- -e OPENAI_MAX_TOKENS \
69
- agnusdei1207/pentesting:latest
70
- ```
71
-
72
- Provider environment variables are optional for startup. If they are omitted,
73
- the interactive TUI still launches and lets you configure/login inside the
74
- persistent `pentesting-config` volume.
75
-
76
- Or via Docker Compose:
77
-
78
- ```bash
79
- PENTESTING_PROJECT_DIR=/path/to/project \
80
- OPENAI_API_KEY=sk-... \
81
- OPENAI_BASE_URL=https://api.openai.com/v1 \
82
- OPENAI_MODEL=gpt-4o \
83
- OPENAI_MAX_TOKENS=4096 \
84
- docker compose run --rm pentesting
85
- ```
86
-
78
+ Published images support `linux/amd64` only. Docker is the recommended runtime
79
+ on Windows and macOS; Apple Silicon Macs run the amd64 image through Docker
80
+ Desktop emulation. Native ARM64 images and binaries are not supported.
81
+
82
+ ```bash
83
+ export OPENAI_API_KEY="sk-..." # provider API key or gateway token
84
+ export OPENAI_BASE_URL="https://api.openai.com/v1"
85
+ export OPENAI_MODEL="gpt-4o"
86
+ export OPENAI_MAX_TOKENS="4096"
87
+
88
+ docker run -it --rm \
89
+ -v "$(pwd):/workspace" \
90
+ -v pentesting-config:/root/.pentesting \
91
+ -w /workspace \
92
+ -e OPENAI_API_KEY \
93
+ -e OPENAI_BASE_URL \
94
+ -e OPENAI_MODEL \
95
+ -e OPENAI_MAX_TOKENS \
96
+ agnusdei1207/pentesting:latest
97
+ ```
98
+
99
+ Provider environment variables are optional for startup. If they are omitted,
100
+ the interactive TUI still launches and lets you configure/login inside the
101
+ persistent `pentesting-config` volume.
102
+
103
+ Or via Docker Compose:
104
+
105
+ ```bash
106
+ PENTESTING_PROJECT_DIR=/path/to/project \
107
+ OPENAI_API_KEY=sk-... \
108
+ OPENAI_BASE_URL=https://api.openai.com/v1 \
109
+ OPENAI_MODEL=gpt-4o \
110
+ OPENAI_MAX_TOKENS=4096 \
111
+ docker compose run --rm pentesting
112
+ ```
113
+
87
114
  ### Common commands
88
-
89
- ```bash
90
- pentesting # Interactive TUI
91
- pentesting --prompt "Enumerate the target and summarize next actions."
92
- pentesting shell-listener --bind 127.0.0.1 --port 4444 # Authorized reverse-shell listener
93
- pentesting --version
94
- ```
95
-
115
+
116
+ ```bash
117
+ pentesting # Interactive TUI
118
+ pentesting --prompt "Enumerate the target and summarize next actions."
119
+ pentesting shell-listener --bind 127.0.0.1 --port 4444 # Authorized reverse-shell listener
120
+ pentesting --version
121
+ ```
122
+
96
123
  Use `shell-listener` in authorized CTF/lab work to accept callbacks, tag sessions, run sentinel-tracked commands, verify PTY upgrades, and retain transcripts/evidence.
97
124
 
98
125
  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`.
99
126
 
100
- Inside a session, `/help` lists every command and `/update` pulls the latest release for supported native targets.
127
+ ### Interactive control defaults
101
128
 
102
- ### πŸ”Œ Reverse-shell & PTY sessions
129
+ - `/model` owns a modal terminal surface. Returning from it restores the prior
130
+ transcript cursor before the fixed prompt/status rows are redrawn, so later
131
+ responses and errors append instead of overwriting the input area.
132
+ - `/goal <task>` records the goal only. Autonomous continuation starts off and
133
+ can be enabled or stopped only with an explicit `/auto` command.
134
+ - Tool/request budget exhaustion does not create a fresh turn while auto mode
135
+ is off. A submitted queued input takes precedence over autonomous follow-up.
136
+ - Submitted type-ahead is consumed once in FIFO order at the next safe turn
137
+ boundary. Only explicit amend/replace intent may change that handoff.
103
138
 
104
- Catch and manage authorized shell callbacks: one listener, many targets, audited cleanup.
139
+ On native Windows Git Bash, the repository smoke path builds the capped Docker
140
+ image and then opens this interactive TUI without WSL:
105
141
 
106
142
  ```bash
107
- pentesting shell-listener --port 4444 # 1. Catch callbacks (tracks many at once)
108
- pentesting shell-session list # 2. See every live session + FD ownership
109
- pentesting shell-session run -- id # 3. Run sentinel-bounded commands, capture output
110
- pentesting shell-session pty-upgrade # 4. Inject the PTY helper; `upgrade` then verifies it
111
- pentesting shell-session revoke --session 1 # 5. Hard-close: reclaim FDs + archive evidence
143
+ npm run check
112
144
  ```
113
-
114
- - **Track** β€” each callback is accepted, numbered, and tagged; `list` / `info` / `fdstat` / `lifecycle` show live state, byte counts, and FD ownership.
115
- - **Drive** β€” `run` wraps commands in a sentinel to capture exactly their output; `send` / `raw` / `signal` / `resize` give interactive control.
116
- - **Upgrade** β€” `pty-upgrade` sends the built-in helper and `upgrade` verifies 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.
117
- - **Record** β€” per-session raw log, full-duplex transcript, command ledger, replay, and evidence manifest β€” with secret redaction for registered values.
118
- - **Reclaim** β€” `close` (graceful) and `revoke` (hard) release file descriptors immediately and archive the session; `gc` prunes closed sessions. Reclamation is tracked end-to-end, so FDs never leak.
119
-
120
- ---
121
-
122
- ## βš™οΈ Configuration
123
-
124
- Pentesting uses local storage by default. For normal use, configure only the model endpoint:
125
-
126
- ### Example `.env` / shell setup
127
-
128
- ```bash
129
- # OpenAI-compatible provider or gateway
130
- export OPENAI_API_KEY="sk-..."
131
- export OPENAI_BASE_URL="https://api.openai.com/v1"
132
- export OPENAI_MODEL="gpt-4o"
133
- export OPENAI_MAX_TOKENS="4096"
134
-
135
- # Runtime overrides (optional)
136
- export PENTESTING_CONFIG="$HOME/.config/pentesting" # move the global config dir
137
- export PENTESTING_SKIP_DOWNLOAD=1 # skip postinstall binary download (CI)
138
- ```
139
-
140
- 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.
141
-
142
- ### Frontier-guided CTF exploration
143
-
144
- The global frontier engine default stays off, but CTF-shaped engagement config
145
- auto-applies the CTF runtime profile: `ctf-competition` autonomy, runtime
146
- exploration, autonomous continuation, and a completion gate that requires
147
- verified `flag_check` evidence. A ready-to-copy profile lives at
148
- `docs/config/ctf.toml`:
149
-
150
- ```toml
151
- [engagement]
152
- kind = "ctf"
153
- flag_format = "flag\\{[^}]+\\}"
154
- require_flag_evidence = true
155
-
156
- [exploration]
157
- enabled = true
158
- max_frontier_nodes = 256
159
- max_breadth = 4
160
- ```
161
-
162
- With the profile active, the runtime stores `explore` leads as
163
- `EvidenceKind::Lead` events, carries prior-run frontier/findings/verified flags
164
- forward, deduplicates leads, auto-pivots dead probes, enforces graph/cap limits,
165
- and injects a breadth/depth recommendation into mission control. The model still
166
- drives the work through `explore` and `task`; heavy independent leads such as
167
- crypto/rev/pwn ride the same parallel delegation batch rather than a detached
168
- background scheduler. Operators can inspect the current graph with `/frontier`,
169
- and the status row shows compact frontier progress during dispatch.
170
-
171
- Malformed tool-call output is fail-loud: unparsed tool-shaped markup is retried
172
- instead of accepted as a final answer, the TUI suppresses raw control markup, and
173
- large no-newline streams are bounded so rendering cannot hang behind usage-only
174
- progress ticks.
175
-
176
- The shipped contract is covered by
177
- `cargo test -p builder_app orch_spec::exploration_e2e`: it verifies the
178
- flag-off regression path plus breadth enumeration, depth descent, sibling
179
- breadth, dead-probe pivot, global reseed, seed digest, broad-clone overlay, and
180
- child result promotion.
181
-
182
- With Docker, mount both your project and the persistent runtime config volume, then pass the same variables through with `-e`:
183
-
184
- ```bash
185
- docker run -it --rm \
186
- -v "$(pwd):/workspace" \
187
- -v pentesting-config:/root/.pentesting \
188
- -w /workspace \
189
- -e OPENAI_API_KEY \
190
- -e OPENAI_BASE_URL \
191
- -e OPENAI_MODEL \
192
- -e OPENAI_MAX_TOKENS \
193
- agnusdei1207/pentesting:latest
194
- ```
195
-
196
- Those variables only pre-fill provider settings. Leaving them unset must not
197
- block the container from launching the TUI; configure the provider interactively
198
- inside the container instead.
199
-
200
- > **Note:** The command you run is always **`pentesting`**. The internal engine is **`builder`** β€” `pentesting` downloads and runs it under the hood; the engine name never surfaces in normal use.
201
-
202
- ---
203
-
204
- ## πŸ“– Documentation
205
-
206
- * [`ARCHITECTURE.md`](ARCHITECTURE.md) β€” Runtime flow, agent team, memory model, crate map, tool surface, and supported targets.
207
- * Internal layout: service traits are split under `builder_app/src/services/*`; OpenAI request conversion is isolated under `dto/openai/request/*`.
208
- * [Public site](https://agnusdei1207.github.io/pentesting-public/) β€” Landing page and public runtime entry surface.
209
- * [`compose.yaml`](https://github.com/agnusdei1207/pentesting-public) β€” Docker Compose facade for pentesting sessions.
210
-
211
- ---
212
-
213
- ## 🎹 From the Developer
214
-
215
- <div align="center">
216
- <img src="https://github.com/user-attachments/assets/abe73474-f27b-4536-b358-fedef1e461f0" alt="Chopin Ballade No.4" width="600" />
217
- </div>
218
-
219
- <br/>
220
-
221
- > "I believe playing the piano is also a form of orchestration."
222
- >
223
- > The harmony of polyphony β€” multiple voices β€” and homophony β€” a single melodic line.
224
- >
225
- > 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.
226
- >
227
- > β€” *agnusdei1207*
145
+
146
+ Inside a session, `/help` lists every command and `/update` pulls the latest release for supported native targets.
147
+
148
+ ### πŸ”Œ Reverse-shell & PTY sessions
149
+
150
+ Catch and manage authorized shell callbacks: one listener, many targets, audited cleanup.
151
+
152
+ ```bash
153
+ pentesting shell-listener --port 4444 # 1. Catch callbacks (tracks many at once)
154
+ pentesting shell-session list # 2. See every live session + FD ownership
155
+ pentesting shell-session run -- id # 3. Run sentinel-bounded commands, capture output
156
+ pentesting shell-session pty-upgrade # 4. Inject the PTY helper; `upgrade` then verifies it
157
+ pentesting shell-session revoke --session 1 # 5. Hard-close: reclaim FDs + archive evidence
158
+ ```
159
+
160
+ - **Track** β€” each callback is accepted, numbered, and tagged; one session actor exclusively owns its live descriptors, transcript, and child lifecycle. `list` / `info` / `fdstat` / `lifecycle` show state and byte counts without cloned reader/writer descriptors.
161
+ - **Drive** β€” `run` wraps commands in a sentinel to capture exactly their output; `send` / `raw` / `signal` / `resize` give interactive control.
162
+ - **Upgrade** β€” `pty-upgrade` sends the built-in helper and `upgrade` verifies 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.
163
+ - **Record** β€” per-session raw log, full-duplex transcript, command ledger, replay, and evidence manifest β€” with secret redaction for registered values.
164
+ - **Reclaim** β€” `close` (graceful) and `revoke` (hard) release file descriptors immediately and archive the session; `gc` prunes closed sessions. Reclamation is tracked end-to-end, so FDs never leak.
165
+
166
+ ---
167
+
168
+ ## βš™οΈ Configuration
169
+
170
+ Pentesting uses local storage by default. For normal use, configure only the model endpoint:
171
+
172
+ ### Example `.env` / shell setup
173
+
174
+ ```bash
175
+ # OpenAI-compatible provider or gateway
176
+ export OPENAI_API_KEY="sk-..."
177
+ export OPENAI_BASE_URL="https://api.openai.com/v1"
178
+ export OPENAI_MODEL="gpt-4o"
179
+ export OPENAI_MAX_TOKENS="4096"
180
+
181
+ # Runtime overrides (optional)
182
+ export PENTESTING_CONFIG="$HOME/.config/pentesting" # move the global config dir
183
+ export PENTESTING_SKIP_DOWNLOAD=1 # skip postinstall binary download (CI)
184
+ ```
185
+
186
+ 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.
187
+
188
+ ### Frontier-guided CTF exploration
189
+
190
+ There are no separate security, CTF, and frontier modes. Session/process,
191
+ finding/verification, `flag_check`, and `explore` tools share one default
192
+ security surface. Engagement metadata describes scope, target, and flag format;
193
+ it does not unlock tools. CTF-shaped context may tailor the prompt, while
194
+ `flag_check` remains a verification tool and evidence source instead of a
195
+ default completion gate. `[exploration]` contains only resource caps. A
196
+ ready-to-copy context lives at
197
+ `docs/config/ctf.toml`:
198
+
199
+ ```toml
200
+ [engagement]
201
+ kind = "ctf"
202
+ flag_format = "flag\\{[^}]+\\}"
203
+ require_flag_evidence = false
204
+
205
+ [exploration]
206
+ max_frontier_nodes = 256
207
+ max_breadth = 4
208
+ ```
209
+
210
+ With the profile active, the runtime stores `explore` leads as bounded
211
+ `EvidenceKind::Lead` events and reuses prior-run records by reference rather
212
+ than copying them. A repeated dead probe suppresses that execution path but
213
+ does not reject the underlying hypothesis; fresh evidence reopens it. The model
214
+ still drives work through the explicit `explore` and `task` tools. Exploration
215
+ does not replace the core execution strategy, add a background scheduler, or
216
+ expose a passive `/frontier` UI/query path. Node, breadth, and depth limits bound
217
+ its cost.
218
+
219
+ Malformed tool-call output is fail-loud: unparsed tool-shaped markup is retried
220
+ instead of accepted as a final answer, the TUI suppresses raw control markup, and
221
+ long no-newline streams flush at soft text boundaries so rendering cannot hang
222
+ behind usage-only progress ticks. The startup banner and live status row stay
223
+ compact; generic run, token, and queued-input detail lives in `/status`.
224
+
225
+ The shipped contract is covered by
226
+ `scripts/dbuild.sh test -p builder_app orch_spec::exploration_e2e`: it verifies the
227
+ always-available tool path plus breadth enumeration, depth descent, sibling
228
+ breadth, dead-probe pivot, global reseed, seed digest, broad-clone overlay, and
229
+ child result promotion.
230
+
231
+ With Docker, mount both your project and the persistent runtime config volume, then pass the same variables through with `-e`:
232
+
233
+ ```bash
234
+ docker run -it --rm \
235
+ -v "$(pwd):/workspace" \
236
+ -v pentesting-config:/root/.pentesting \
237
+ -w /workspace \
238
+ -e OPENAI_API_KEY \
239
+ -e OPENAI_BASE_URL \
240
+ -e OPENAI_MODEL \
241
+ -e OPENAI_MAX_TOKENS \
242
+ agnusdei1207/pentesting:latest
243
+ ```
244
+
245
+ Those variables only pre-fill provider settings. Leaving them unset must not
246
+ block the container from launching the TUI; configure the provider interactively
247
+ inside the container instead.
248
+
249
+ > **Note:** The command you run is always **`pentesting`**. The internal engine is **`builder`** β€” `pentesting` downloads and runs it under the hood; the engine name never surfaces in normal use.
250
+
251
+ ---
252
+
253
+ ## πŸ“– Documentation
254
+
255
+ - [`ARCHITECTURE.md`](ARCHITECTURE.md) β€” Runtime flow, agent team, memory model, crate map, tool surface, and supported targets.
256
+ - [Documentation map](https://github.com/agnusdei1207/pentesting/blob/main/docs/README.md) β€” Current authoritative documents versus historical plans and research notes.
257
+ - [Integrated runtime design](https://github.com/agnusdei1207/pentesting/blob/main/docs/BUILDER-CONSOLIDATED-DEEP-DIVE.md) β€” Top-down explanation from the one-loop model to prompt, subagents, persistence, and PTY ownership.
258
+ - [Minimal Core implementation](https://github.com/agnusdei1207/pentesting/blob/main/docs/plans/2026/07/10/minimal-core/README.md) β€” Implemented simplification record for the single turn/tool/security surface.
259
+ - [Next-generation clean-break convergence](https://github.com/agnusdei1207/pentesting/blob/main/docs/plans/2026/07/10/next-generation-convergence/README.md) β€” Canonical contracts, deleted compatibility paths, and the phase-by-phase migration boundary.
260
+ - Internal layout: service traits are split under `builder_app/src/services/*`; OpenAI request conversion is isolated under `dto/openai/request/*`.
261
+ - [Public site](https://agnusdei1207.github.io/pentesting-public/) β€” Landing page and public runtime entry surface.
262
+ - [`compose.yaml`](https://github.com/agnusdei1207/pentesting-public) β€” Docker Compose facade for pentesting sessions.
263
+
264
+ ---
265
+
266
+ ## 🎹 From the Developer
267
+
268
+ <div align="center">
269
+ <img src="https://github.com/user-attachments/assets/abe73474-f27b-4536-b358-fedef1e461f0" alt="Chopin Ballade No.4" width="600" />
270
+ </div>
271
+
272
+ <br/>
273
+
274
+ > "I believe playing the piano is also a form of orchestration."
275
+ >
276
+ > The harmony of polyphony β€” multiple voices β€” and homophony β€” a single melodic line.
277
+ >
278
+ > 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.
279
+ >
280
+ > β€” *agnusdei1207*
@@ -1,36 +1,36 @@
1
- #!/usr/bin/env node
2
-
3
- import { spawnSync } from "node:child_process";
4
-
5
- import {
6
- pentestingEnvironment,
7
- resolveBuilderBinary,
8
- translateBuilderInvocation,
9
- } from "../lib/runtime.mjs";
10
-
11
- async function main() {
12
- const invocation = translateBuilderInvocation(process.argv.slice(2));
13
- for (const warning of invocation.warnings) {
14
- console.warn(`[pentesting] ${warning}`);
15
- }
16
-
17
- const builderBinary = await resolveBuilderBinary({ downloadIfMissing: true });
18
- const result = spawnSync(builderBinary, invocation.builderArgs, {
19
- stdio: "inherit",
20
- env: pentestingEnvironment(process.env),
21
- });
22
-
23
- if (result.error) {
24
- console.error(
25
- `pentesting could not start Builder (${result.error.message}). Set PENTESTING_BIN or reinstall the pentesting package.`,
26
- );
27
- process.exit(127);
28
- }
29
-
30
- process.exit(result.status ?? 1);
31
- }
32
-
33
- main().catch((error) => {
34
- console.error(`[pentesting] ${error instanceof Error ? error.message : String(error)}`);
35
- process.exit(1);
36
- });
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "node:child_process";
4
+
5
+ import {
6
+ pentestingEnvironment,
7
+ resolveBuilderBinary,
8
+ translateBuilderInvocation,
9
+ } from "../lib/runtime.mjs";
10
+
11
+ async function main() {
12
+ const invocation = translateBuilderInvocation(process.argv.slice(2));
13
+ for (const warning of invocation.warnings) {
14
+ console.warn(`[pentesting] ${warning}`);
15
+ }
16
+
17
+ const builderBinary = await resolveBuilderBinary({ downloadIfMissing: true });
18
+ const result = spawnSync(builderBinary, invocation.builderArgs, {
19
+ stdio: "inherit",
20
+ env: pentestingEnvironment(process.env),
21
+ });
22
+
23
+ if (result.error) {
24
+ console.error(
25
+ `pentesting could not start Builder (${result.error.message}). Set PENTESTING_BIN or reinstall the pentesting package.`,
26
+ );
27
+ process.exit(127);
28
+ }
29
+
30
+ process.exit(result.status ?? 1);
31
+ }
32
+
33
+ main().catch((error) => {
34
+ console.error(`[pentesting] ${error instanceof Error ? error.message : String(error)}`);
35
+ process.exit(1);
36
+ });