pentesting 0.90.6 → 0.90.8
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/README.md +250 -168
- package/bin/pentesting.mjs +1 -1
- package/lib/runtime.mjs +9 -9
- package/package.json +80 -22
- package/scripts/postinstall.mjs +13 -10
- package/scripts/preflight-local.sh +0 -24
package/README.md
CHANGED
|
@@ -1,229 +1,311 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Pentesting 🔓
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
- Installs the `pentesting` CLI.
|
|
6
|
-
- Downloads the matching Builder binary from `agnusdei1207/builder-public` releases for the current OS/CPU.
|
|
7
|
-
- Performs only binary resolution and direct argument forwarding before delegating execution to the Rust Builder binary.
|
|
8
|
-
- Launches the same runtime with a `pentesting` banner while keeping Builder as the single internal engine.
|
|
9
|
-
- Does not ship a second JavaScript or TypeScript runtime.
|
|
3
|
+
> **Pentesting** is a local-first, zero-panic Rust coding agent CLI for authorized security assessments. The runtime—not the model—owns routing, tool sandboxing, verification, and completion adjudication.
|
|
10
4
|
|
|
11
5
|
<div align="center">
|
|
6
|
+
<img src="pentesting-logo.svg" alt="pentesting logo" width="120" />
|
|
7
|
+
<h1>pentesting</h1>
|
|
8
|
+
<p>Security-Focused Agent Runtime</p>
|
|
12
9
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
<!-- Title bar -->
|
|
16
|
-
<div style="background-color: #0d1c18; border-bottom: 1px solid rgba(0, 200, 160, 0.1); padding: 10px 16px; display: flex; align-items: center; justify-content: space-between;">
|
|
17
|
-
<div style="display: flex; gap: 6px;">
|
|
18
|
-
<span style="width: 10px; height: 10px; border-radius: 50%; background-color: #ff5f56; display: inline-block;"></span>
|
|
19
|
-
<span style="width: 10px; height: 10px; border-radius: 50%; background-color: #ffbd2e; display: inline-block;"></span>
|
|
20
|
-
<span style="width: 10px; height: 10px; border-radius: 50%; background-color: #27c93f; display: inline-block;"></span>
|
|
21
|
-
</div>
|
|
22
|
-
<span style="font-size: 11px; color: #537a6c;">pentesting-tui · wsl</span>
|
|
23
|
-
</div>
|
|
24
|
-
|
|
25
|
-
<!-- Card header -->
|
|
26
|
-
<div style="background-color: rgba(0, 200, 160, 0.05); border-bottom: 1px solid rgba(0, 200, 160, 0.1); padding: 6px 16px; color: #00c8a0; font-size: 12px; font-weight: bold;">pentesting latest</div>
|
|
27
|
-
|
|
28
|
-
<!-- Card body -->
|
|
29
|
-
<table style="width: 100%; border-collapse: collapse; border: none; background: transparent; margin: 0;">
|
|
30
|
-
<tr style="border: none; background: transparent;">
|
|
31
|
-
<!-- Left Side: Status & Logo -->
|
|
32
|
-
<td style="width: 45%; padding: 20px; text-align: center; border-right: 1px solid rgba(0, 200, 160, 0.1); vertical-align: top; border-left: none; border-top: none; border-bottom: none; background: transparent;">
|
|
33
|
-
<div style="color: #e8fff8; font-weight: 700; font-size: 13px; margin-bottom: 16px;">Welcome back!</div>
|
|
34
|
-
<div style="margin: 0 auto; width: 64px; height: 58px; display: block; filter: drop-shadow(0 0 8px rgba(0, 200, 160, 0.35));">
|
|
35
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 90" width="100%" height="100%">
|
|
36
|
-
<defs>
|
|
37
|
-
<mask id="headMask">
|
|
38
|
-
<rect x="0" y="0" width="100" height="100" fill="#ffffff" />
|
|
39
|
-
<rect x="33.25" y="59.5" width="5.5" height="5" fill="#000000" />
|
|
40
|
-
<rect x="61.25" y="59.5" width="5.5" height="5" fill="#000000" />
|
|
41
|
-
</mask>
|
|
42
|
-
</defs>
|
|
43
|
-
<rect x="15" y="10" width="70" height="52" rx="10" fill="none" stroke="#00c8a0" stroke-width="4.5" mask="url(#headMask)" />
|
|
44
|
-
<line x1="36" y1="59.75" x2="36" y2="78" stroke="#00c8a0" stroke-width="5.5" stroke-linecap="butt" />
|
|
45
|
-
<line x1="64" y1="59.75" x2="64" y2="78" stroke="#00c8a0" stroke-width="5.5" stroke-linecap="butt" />
|
|
46
|
-
<circle cx="36" cy="36" r="9.5" fill="none" stroke="#00c8a0" stroke-width="3" />
|
|
47
|
-
<circle cx="38.5" cy="33.5" r="2.8" fill="#00c8a0" />
|
|
48
|
-
<circle cx="64" cy="36" r="9.5" fill="none" stroke="#00c8a0" stroke-width="3" />
|
|
49
|
-
<circle cx="66.5" cy="33.5" r="2.8" fill="#00c8a0" />
|
|
50
|
-
</svg>
|
|
51
|
-
</div>
|
|
52
|
-
<div style="color: #a0cfbf; font-size: 11px; margin-top: 16px; font-weight: 600;">your-model · your-provider</div>
|
|
53
|
-
<div style="color: #537a6c; font-size: 10px; margin-top: 4px; word-break: break-all;">...orkspace/builder-private</div>
|
|
54
|
-
</td>
|
|
55
|
-
<!-- Right Side: Quick Commands -->
|
|
56
|
-
<td style="padding: 20px; vertical-align: top; text-align: left; border-left: none; border-top: none; border-bottom: none; border-right: none; background: transparent;">
|
|
57
|
-
<div style="color: #e8fff8; font-weight: 700; font-size: 13px; margin-bottom: 12px;">Quick commands</div>
|
|
58
|
-
<table style="width: 100%; border-collapse: collapse; font-size: 11px; text-align: left; border: none; background: transparent; margin: 0;">
|
|
59
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/new</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">New conversation</td></tr>
|
|
60
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/model</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Switch model</td></tr>
|
|
61
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/goal <task></td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Set active goal</td></tr>
|
|
62
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/goal</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Clear goal</td></tr>
|
|
63
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/auto</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Toggle goal auto</td></tr>
|
|
64
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/config</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Edit configuration</td></tr>
|
|
65
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/help</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Show all commands</td></tr>
|
|
66
|
-
<tr style="border: none; background: transparent;"><td style="color: #00c8a0; font-weight: 700; padding: 3px 12px 3px 0; white-space: nowrap; border: none; background: transparent;">/exit</td><td style="color: #a0cfbf; padding: 3px 0; border: none; background: transparent;">Quit</td></tr>
|
|
67
|
-
</table>
|
|
68
|
-
</td>
|
|
69
|
-
</tr>
|
|
70
|
-
</table>
|
|
71
|
-
|
|
72
|
-
<!-- Bottom prompt bar -->
|
|
73
|
-
<div style="border-top: 1px solid rgba(0, 200, 160, 0.1); padding: 12px 16px; font-size: 11px;">
|
|
74
|
-
<div style="color: #a0cfbf; display: flex; align-items: center; gap: 8px;">
|
|
75
|
-
<span style="color: #00c8a0;">⠸</span> Processing · analyzing workspace structure
|
|
76
|
-
</div>
|
|
77
|
-
<div style="height: 1px; background-color: rgba(0, 200, 160, 0.08); margin: 8px 0;"></div>
|
|
78
|
-
<div style="font-size: 12px; color: #e8fff8;">
|
|
79
|
-
<span style="color: #00c8a0; font-weight: bold;">❯ </span>pentesting<span style="background-color: #00c8a0; color: #020504; display: inline-block; width: 8px; height: 15px; vertical-align: middle; margin-left: 2px;"></span>
|
|
80
|
-
</div>
|
|
81
|
-
<div style="height: 1px; background-color: rgba(0, 200, 160, 0.08); margin: 8px 0;"></div>
|
|
82
|
-
<div style="color: #537a6c; font-size: 10px;">Esc to interrupt</div>
|
|
83
|
-
</div>
|
|
84
|
-
|
|
10
|
+
[](LICENSE)
|
|
11
|
+
[](https://www.npmjs.com/package/pentesting)
|
|
85
12
|
</div>
|
|
86
13
|
|
|
87
|
-
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
> **Role:** The published npm package and the command you run are both **`pentesting`**. The internal orchestration engine is **`builder`** — `pentesting` downloads and runs it under the hood. `npm i -g pentesting` installs the **`pentesting`** command (never a `builder` command); the engine name does not surface in normal use.
|
|
88
17
|
|
|
89
18
|
---
|
|
90
19
|
|
|
91
|
-
##
|
|
20
|
+
## 🎯 Key Design Pillars
|
|
21
|
+
|
|
22
|
+
* **Runtime-Owned Adjudication** — Model output is a *candidate* until a 5-gate completion lattice verifies and closes the task.
|
|
23
|
+
* **Local-First State** — Runtime state and a markdown knowledge graph live on disk. No external storage service.
|
|
24
|
+
* **Weak-Model Hardening** — Rust-enforced classifiers, validators, and self-reviews guard against hallucination.
|
|
25
|
+
* **Lineage & Horizons** — Run lineage, objective IDs, and horizon-aware memory reuse, all in local state.
|
|
26
|
+
* **Policy-Gated Tools** — `Allow/Deny/Confirm` gates shell, file, and network access (policy-based today; OS sandboxing is roadmap).
|
|
27
|
+
* **Intelligent Queuing** — Queued inputs are deduplicated and prioritized live; obsolete tasks are preempted, not FIFO-replayed.
|
|
28
|
+
* **Lab Session Multiplexing** — `shell-listener` runs multiple authorized TCP sessions with per-session routing and PTY upgrades.
|
|
29
|
+
* **Dynamic Agent Profiles** — No fixed persona: the classifier *generates* a profile per request, *recalls* reusable templates, *reuses* them to drive tool scope, phase, and memory weighting.
|
|
30
|
+
* **Ebbinghaus-Inspired Memory** — Memories carry a *strength* that fades like human memory and reinforces on recall. Faded notes are de-referenced, never destroyed.
|
|
31
|
+
* **Git-Backed Rewind** — Working-tree checkpoint/restore keeps autonomous edits reversible.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## 🚀 Quick Start
|
|
36
|
+
|
|
37
|
+
### Install via npm
|
|
92
38
|
|
|
93
39
|
```bash
|
|
94
40
|
npm install -g pentesting
|
|
95
41
|
pentesting
|
|
96
|
-
pentesting --version
|
|
97
42
|
```
|
|
98
43
|
|
|
99
|
-
|
|
44
|
+
### Run with Docker
|
|
100
45
|
|
|
101
46
|
```bash
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
47
|
+
docker run -it --rm \
|
|
48
|
+
-v "$(pwd):/workspace" \
|
|
49
|
+
-w /workspace \
|
|
50
|
+
agnusdei1207/pentesting:latest
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Docker Compose
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
PENTESTING_PROJECT_DIR=/path/to/project docker compose run pentesting
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### Quick commands
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
pentesting # Interactive TUI
|
|
63
|
+
pentesting --prompt "Enumerate the target and summarize next actions."
|
|
64
|
+
pentesting shell-listener --bind 127.0.0.1 --port 4444 # Authorized lab listener
|
|
105
65
|
pentesting --version
|
|
106
66
|
```
|
|
107
67
|
|
|
108
|
-
|
|
68
|
+
---
|
|
109
69
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
70
|
+
## 🧩 Orchestration Map
|
|
71
|
+
|
|
72
|
+
Pentesting is a **domain-neutral** runtime with a security focus. Development, pentesting, CTF, audit, and release work layer in via skills — never baked into the core.
|
|
73
|
+
|
|
74
|
+
**Profile flow** — generate → recall → reuse:
|
|
75
|
+
|
|
76
|
+
```mermaid
|
|
77
|
+
flowchart LR
|
|
78
|
+
R[Request] --> GEN["Generate<br/>dynamic profile"]
|
|
79
|
+
GEN --> REC["Recall<br/>named template + overlay"]
|
|
80
|
+
REC --> USE["Reuse<br/>tool scope · phase · memory weight"]
|
|
113
81
|
```
|
|
114
82
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
83
|
+
**Agent flow** — request to closure:
|
|
84
|
+
|
|
85
|
+
```mermaid
|
|
86
|
+
flowchart TD
|
|
87
|
+
U[User request] --> C[Intent classifier]
|
|
88
|
+
C --> P[Dynamic profile<br/>task shape + tool scope + rigor]
|
|
89
|
+
P --> R[Runtime router]
|
|
90
|
+
R --> A[Active agent]
|
|
91
|
+
A --> T{Need delegation?}
|
|
92
|
+
T -- no --> O[Tool execution]
|
|
93
|
+
T -- yes --> D[Agent tool]
|
|
94
|
+
D --> CO[coordinator]
|
|
95
|
+
D --> I[investigator]
|
|
96
|
+
D --> OP[operator]
|
|
97
|
+
D --> RV[reviewer]
|
|
98
|
+
D --> V[verifier]
|
|
99
|
+
D --> W[report-writer]
|
|
100
|
+
CO --> O
|
|
101
|
+
I --> O
|
|
102
|
+
OP --> O
|
|
103
|
+
RV --> O
|
|
104
|
+
V --> O
|
|
105
|
+
W --> O
|
|
106
|
+
O --> G[Completion gates]
|
|
107
|
+
G --> M[Memory + artifacts]
|
|
108
|
+
M --> U
|
|
109
|
+
```
|
|
120
110
|
|
|
121
|
-
|
|
111
|
+
### Built-in agent team
|
|
122
112
|
|
|
123
|
-
|
|
113
|
+
| Agent | Default role | Runtime profile |
|
|
114
|
+
| --- | --- | --- |
|
|
115
|
+
| `builder` | Hands-on implementation, refactoring, local file changes, tests | Implement + broad local write |
|
|
116
|
+
| `planner` | Implementation plans and risk breakdowns | Plan + read-only |
|
|
117
|
+
| `researcher` | Read-only codebase and reference research | Investigate + read-only |
|
|
118
|
+
| `coordinator` | Splits broad work into owned packets and consolidates results | Coordinate + broad local write |
|
|
119
|
+
| `investigator` | Evidence gathering across code, logs, commands, APIs, and behavior | Investigate + shell diagnostics |
|
|
120
|
+
| `operator` | Builds, tests, packaging, service startup, and runtime workflows | Implement + broad local write |
|
|
121
|
+
| `reviewer` | Findings-first technical review | Review + strict read-only |
|
|
122
|
+
| `verifier` | Reproduction, build/test proof, and completion claim checks | Verify + strict read-only |
|
|
123
|
+
| `report-writer` | Reports, handoffs, release notes, and reproducibility records | Implement + bounded write |
|
|
124
124
|
|
|
125
|
-
|
|
126
|
-
- if `BUILDER_SKIP_DOWNLOAD=true`, the wrapper skips managed download entirely
|
|
127
|
-
- otherwise it downloads the matching public Builder release asset into the package-local managed binary directory and executes that binary on launch
|
|
125
|
+
### Named autonomy profiles
|
|
128
126
|
|
|
129
|
-
|
|
127
|
+
Optionally pin the top-level profile (`autonomy_profile = "ctf-competition"`); leave unset for classifier-driven defaults. Delegated subagent contracts stay intact.
|
|
130
128
|
|
|
131
|
-
|
|
129
|
+
| Profile | Purpose |
|
|
130
|
+
| --- | --- |
|
|
131
|
+
| `general-agent` | Broad autonomous local orchestration for mixed tasks |
|
|
132
|
+
| `local-builder` | Hands-on implementation with fresh evidence retrieval |
|
|
133
|
+
| `ctf-competition` | Competition/lab workflow backed by `ctf-competition` and `pentesting-methodology` skills |
|
|
134
|
+
| `enterprise-review` | Strict, review-heavy profile with read-only dynamic scope |
|
|
132
135
|
|
|
133
|
-
|
|
136
|
+
### Engagement metadata
|
|
134
137
|
|
|
135
|
-
|
|
136
|
-
- it resolves or downloads the correct Builder release asset
|
|
137
|
-
- it forwards arguments directly into the Rust Builder binary
|
|
138
|
-
- it does not translate `interactive`, `run`, `scan`, old target flags, or permission-bypass flags
|
|
138
|
+
Runs can attach typed engagement context — scope, phase, tags, and standard refs (PTES, MITRE ATT&CK, OWASP, CWE/CAPEC, NIST CSF, CIS Controls) — to workflow metadata. `/workflow report` exports it as a Markdown handoff.
|
|
139
139
|
|
|
140
|
-
|
|
140
|
+
### Storage and graph strategy
|
|
141
141
|
|
|
142
|
-
|
|
142
|
+
- **Local-first** — runtime state, notes, scratchpad, and graph inputs live on disk.
|
|
143
|
+
- **Derived graph** — built from markdown notes, wiki-links/backlinks, skills, and memory; a view, not a second source of truth.
|
|
144
|
+
- **Separate skills** — domain skills (`ctf-competition`, audit, release, dev) teach method without changing runtime identity.
|
|
143
145
|
|
|
144
|
-
|
|
146
|
+
---
|
|
145
147
|
|
|
146
|
-
|
|
147
|
-
- explicit auto-mode toggling through `/auto`
|
|
148
|
-
- post-turn self-review and persistent local memory files
|
|
149
|
-
- context compression for long-running sessions
|
|
150
|
-
- workflow status, budget, proof, and verification signals in the TUI
|
|
151
|
-
- Docker and npm entrypoints that share one runtime instead of diverging implementations
|
|
152
|
-
- the explicit `shell-listener` command for authorized lab multi-session TCP handling with per-session routing, output buffering, and PTY-upgrade helpers
|
|
148
|
+
## 🧠 Memory & Knowledge
|
|
153
149
|
|
|
154
|
-
|
|
150
|
+
One local-first store — plain markdown notes on disk, no vector DB, no cloud. Memories carry a *strength* that fades like human memory, so the store stays sharp instead of rotting.
|
|
155
151
|
|
|
156
|
-
|
|
152
|
+
**Storage** — Ebbinghaus lifecycle (decay · reinforce · floor, never deleted):
|
|
157
153
|
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
154
|
+
```mermaid
|
|
155
|
+
flowchart TD
|
|
156
|
+
N[New memory] --> S["strength = quality × recall × e^-λ·age"]
|
|
157
|
+
S --> U{recalled?}
|
|
158
|
+
U -- yes --> RE[reinforce ↑ · reset age]
|
|
159
|
+
U -- no --> D[decay over time]
|
|
160
|
+
RE --> S
|
|
161
|
+
D --> F{below floor?}
|
|
162
|
+
F -- no --> S
|
|
163
|
+
F -- yes --> AR[de-reference: archive / tombstone]
|
|
164
|
+
AR -. recoverable on disk .-> N
|
|
163
165
|
```
|
|
164
166
|
|
|
165
|
-
|
|
167
|
+
Kinds fade at different speeds (procedural outlives episodic); bi-temporal `event_time` vs `ingestion_time` lets newer facts supersede stale ones.
|
|
168
|
+
|
|
169
|
+
**Retrieval** — hybrid fuse, strength-weighted, read-only:
|
|
170
|
+
|
|
171
|
+
```mermaid
|
|
172
|
+
flowchart LR
|
|
173
|
+
Q[Query] --> L[Lexical]
|
|
174
|
+
Q --> SE[Semantic]
|
|
175
|
+
Q --> G[Graph]
|
|
176
|
+
L --> RRF[RRF fuse]
|
|
177
|
+
SE --> RRF
|
|
178
|
+
G --> RRF
|
|
179
|
+
RRF --> RR[rerank: phase · recency · task]
|
|
180
|
+
RR --> W[weight by strength]
|
|
181
|
+
W --> P[Prompt context]
|
|
182
|
+
```
|
|
166
183
|
|
|
167
|
-
|
|
168
|
-
|
|
184
|
+
Faded, private, or unsafe memories are held back from the prompt. Lookups never write — reinforce/archive/supersede are explicit, never search side effects.
|
|
185
|
+
|
|
186
|
+
---
|
|
187
|
+
|
|
188
|
+
## 🧭 Interactive Essentials
|
|
189
|
+
|
|
190
|
+
Inside an interactive pentesting session, these commands are the fastest way to inspect state:
|
|
191
|
+
|
|
192
|
+
```text
|
|
193
|
+
/status Show the current run phase, active tasks, gates, hooks, and budget signals
|
|
194
|
+
/workflow Show the current focus and recent workflow steps for the active conversation
|
|
195
|
+
/workflow report
|
|
196
|
+
Export the active run, engagement metadata, evidence, and large outputs to Markdown
|
|
197
|
+
/context Show recent context-budget snapshots for the current conversation
|
|
198
|
+
/memory Show stored conversation memories for the current conversation
|
|
199
|
+
/tools List the currently available tools and schemas
|
|
200
|
+
/agent Switch the active agent
|
|
201
|
+
/conversation Browse conversations for the active workspace
|
|
202
|
+
/goal <task> Set the active goal
|
|
203
|
+
/auto Toggle autonomous mode for the current goal
|
|
204
|
+
/help Show all commands
|
|
205
|
+
/exit Quit
|
|
169
206
|
```
|
|
170
207
|
|
|
171
|
-
|
|
208
|
+
`/update` downloads and applies the latest public release asset for the current OS/CPU target.
|
|
172
209
|
|
|
173
|
-
|
|
174
|
-
| --- | --- | --- |
|
|
175
|
-
| Linux | x64 | `builder-x86_64-unknown-linux-musl` |
|
|
176
|
-
| Linux | arm64 | `builder-aarch64-unknown-linux-musl` |
|
|
177
|
-
| macOS | x64 | `builder-x86_64-apple-darwin` |
|
|
178
|
-
| macOS | arm64 | `builder-aarch64-apple-darwin` |
|
|
179
|
-
| Windows | x64 | `builder-x86_64-pc-windows-msvc.exe` |
|
|
180
|
-
| Windows | arm64 | `builder-aarch64-pc-windows-msvc.exe` |
|
|
181
|
-
| Android | arm64 | `builder-aarch64-linux-android` |
|
|
210
|
+
---
|
|
182
211
|
|
|
183
|
-
##
|
|
212
|
+
## ⚙️ Configuration (`.pentesting.toml`)
|
|
184
213
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
214
|
+
Pentesting reads a user-global config from `~/.pentesting/.pentesting.toml`, overridden by project-local `.pentesting.toml` files discovered by walking up from the working directory.
|
|
215
|
+
|
|
216
|
+
```toml
|
|
217
|
+
[storage]
|
|
218
|
+
backend = "local" # Local md/fs runtime state
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Environment variables use the `PENTESTING_` prefix, with `__` for nested keys — e.g. `PENTESTING_SESSION__MODEL_ID=...`. Set `PENTESTING_CONFIG` to override the global config directory.
|
|
222
|
+
|
|
223
|
+
### Backward compatibility — `builder` ↔ `pentesting`
|
|
224
|
+
|
|
225
|
+
The runtime engine is still `builder` under the hood, so legacy names keep working. Use whichever you like; the `PENTESTING_*` form wins when both are set.
|
|
226
|
+
|
|
227
|
+
| Surface | Canonical | Legacy (still accepted) |
|
|
228
|
+
| :--- | :--- | :--- |
|
|
229
|
+
| Env vars | `PENTESTING_*` | `BUILDER_*` |
|
|
230
|
+
| Config-dir override | `PENTESTING_CONFIG` | `BUILDER_CONFIG` |
|
|
231
|
+
| Global config file | `~/.pentesting/.pentesting.toml` | `~/.builder/.builder.toml`, `~/builder/.builder.toml` |
|
|
232
|
+
| Project config file | `.pentesting.toml` | `.builder.toml` |
|
|
233
|
+
|
|
234
|
+
---
|
|
191
235
|
|
|
192
|
-
##
|
|
236
|
+
## 🔐 Pentesting-Specific Notes
|
|
193
237
|
|
|
194
|
-
|
|
195
|
-
- `pentesting --prompt "<objective>"` runs a direct Builder prompt.
|
|
196
|
-
- `pentesting shell-listener --bind 127.0.0.1 --port 4444` starts the explicit listener command.
|
|
197
|
-
- Arguments are passed through exactly; removed legacy commands are not translated.
|
|
238
|
+
### Architecture — single source, two surfaces
|
|
198
239
|
|
|
199
|
-
|
|
240
|
+
Pentesting and Builder share the **same Rust runtime binary**. The `pentesting` npm package is a thin distribution facade:
|
|
200
241
|
|
|
201
|
-
|
|
242
|
+
```text
|
|
243
|
+
npm install -g pentesting
|
|
244
|
+
│
|
|
245
|
+
▼
|
|
246
|
+
pentesting CLI (Node.js shim)
|
|
247
|
+
│ resolves or downloads the matching Builder release asset
|
|
248
|
+
▼
|
|
249
|
+
Builder binary (Rust) ← single runtime engine
|
|
250
|
+
│ PENTESTING_PRODUCT_NAME=pentesting
|
|
251
|
+
▼
|
|
252
|
+
Interactive TUI with "pentesting" banner
|
|
253
|
+
```
|
|
202
254
|
|
|
203
|
-
|
|
255
|
+
- The npm package installs a launcher, **not** a second agent runtime.
|
|
256
|
+
- It resolves or downloads the correct release asset from `agnusdei1207/pentesting-public`.
|
|
257
|
+
- It forwards arguments directly into the Rust binary — no command translation or compatibility shims.
|
|
258
|
+
- If a change would add orchestration, memory, or prompt logic into the npm layer, that change belongs upstream in the Rust runtime.
|
|
204
259
|
|
|
205
|
-
|
|
206
|
-
- The npm package does not publish Docker images itself. Docker users should treat `agnusdei1207/builder:latest` as the runtime image and `pentesting` as the public command/package facade.
|
|
207
|
-
- Unsupported OS/CPU pairs fail during release asset resolution before download.
|
|
208
|
-
- If the managed binary is missing at runtime, reinstall the package or set `BUILDER_BIN` explicitly.
|
|
260
|
+
### Security domain skills
|
|
209
261
|
|
|
210
|
-
|
|
262
|
+
The `ctf-competition` and `pentesting-methodology` skills map authorized assessments to standard frameworks:
|
|
211
263
|
|
|
212
|
-
|
|
264
|
+
- **PTES** (Penetration Testing Execution Standard)
|
|
265
|
+
- **MITRE ATT&CK** tactics and techniques
|
|
266
|
+
- **OWASP** Top 10 and Testing Guide
|
|
267
|
+
- **CWE/CAPEC** weakness and attack pattern catalogs
|
|
268
|
+
- **NIST CSF** and **CIS Controls**
|
|
269
|
+
|
|
270
|
+
### Shell listener for authorized labs
|
|
213
271
|
|
|
214
272
|
```bash
|
|
215
|
-
|
|
216
|
-
npm run pentesting:verify
|
|
217
|
-
npm run pentesting:pack:dry-run
|
|
218
|
-
npm run pentesting:release:patch:dry-run
|
|
219
|
-
NPM_TOKEN=... npm run pentesting:publish -- 0.90.1
|
|
273
|
+
pentesting shell-listener --bind 127.0.0.1 --port 4444
|
|
220
274
|
```
|
|
221
275
|
|
|
222
|
-
|
|
276
|
+
Manages multiple accepted TCP sessions with per-session routing, buffered output, raw byte logging, and PTY-upgrade helpers. Bound to loopback by default; `--allow-remote` is an explicit opt-in gate.
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## 📦 Supported Runtime Targets
|
|
281
|
+
|
|
282
|
+
| OS | CPU | Release asset |
|
|
283
|
+
| --- | --- | --- |
|
|
284
|
+
| Linux | x64 | `pentesting-x86_64-unknown-linux-musl` |
|
|
285
|
+
| Linux | arm64 | `pentesting-aarch64-unknown-linux-musl` |
|
|
286
|
+
| macOS | x64 | `pentesting-x86_64-apple-darwin` |
|
|
287
|
+
| macOS | arm64 | `pentesting-aarch64-apple-darwin` |
|
|
288
|
+
| Windows | x64 | `pentesting-x86_64-pc-windows-msvc.exe` |
|
|
289
|
+
| Windows | arm64 | `pentesting-aarch64-pc-windows-msvc.exe` |
|
|
290
|
+
| Android | arm64 | `pentesting-aarch64-linux-android` |
|
|
291
|
+
|
|
292
|
+
---
|
|
293
|
+
|
|
294
|
+
## 🌍 Environment Variables
|
|
295
|
+
|
|
296
|
+
| Variable | Description |
|
|
297
|
+
| --- | --- |
|
|
298
|
+
| `PENTESTING_BIN` | Use an already-installed Builder binary instead of the managed download. |
|
|
299
|
+
| `PENTESTING_PRODUCT_NAME` | Runtime banner label. The `pentesting` launcher sets this to `pentesting` automatically. |
|
|
300
|
+
| `PENTESTING_REPO` | Override the public release repo used for binary downloads. Defaults to `agnusdei1207/pentesting-public`. |
|
|
301
|
+
| `PENTESTING_SKIP_DOWNLOAD` | Skip the postinstall binary download. Useful in CI or when `PENTESTING_BIN` will be provided later. |
|
|
302
|
+
|
|
303
|
+
---
|
|
304
|
+
|
|
305
|
+
## 📖 Key Documentation
|
|
223
306
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
- the Builder release asset matching your OS/CPU target
|
|
307
|
+
* [`Public site`](https://agnusdei1207.github.io/pentesting-public/) — Landing page and public runtime entry surface.
|
|
308
|
+
* [`compose.yaml`](https://github.com/agnusdei1207/pentesting-public) — Docker Compose facade for pentesting sessions.
|
|
227
309
|
|
|
228
310
|
---
|
|
229
311
|
|
package/bin/pentesting.mjs
CHANGED
|
@@ -22,7 +22,7 @@ async function main() {
|
|
|
22
22
|
|
|
23
23
|
if (result.error) {
|
|
24
24
|
console.error(
|
|
25
|
-
`pentesting could not start Builder (${result.error.message}). Set
|
|
25
|
+
`pentesting could not start Builder (${result.error.message}). Set PENTESTING_BIN or reinstall the pentesting package.`,
|
|
26
26
|
);
|
|
27
27
|
process.exit(127);
|
|
28
28
|
}
|
package/lib/runtime.mjs
CHANGED
|
@@ -61,7 +61,7 @@ export function configuredBuilderReleaseTag() {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
export function releaseRepository() {
|
|
64
|
-
return process.env.
|
|
64
|
+
return process.env.PENTESTING_REPO || "agnusdei1207/pentesting-public";
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
export function defaultReleaseTag(version = undefined) {
|
|
@@ -117,8 +117,8 @@ async function manifestMatches(expected) {
|
|
|
117
117
|
}
|
|
118
118
|
|
|
119
119
|
export async function installManagedBuilder(options = {}) {
|
|
120
|
-
if (process.env.
|
|
121
|
-
return { binaryPath: process.env.
|
|
120
|
+
if (process.env.PENTESTING_BIN) {
|
|
121
|
+
return { binaryPath: process.env.PENTESTING_BIN, source: "external" };
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
const target = resolveReleaseAsset();
|
|
@@ -131,7 +131,7 @@ export async function installManagedBuilder(options = {}) {
|
|
|
131
131
|
return { binaryPath, source: "cached", ...manifest };
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
if (process.env.
|
|
134
|
+
if (process.env.PENTESTING_SKIP_DOWNLOAD === "true") {
|
|
135
135
|
return { binaryPath, source: "skipped", ...manifest };
|
|
136
136
|
}
|
|
137
137
|
|
|
@@ -174,8 +174,8 @@ export async function installManagedBuilder(options = {}) {
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
export async function resolveBuilderBinary(options = {}) {
|
|
177
|
-
if (process.env.
|
|
178
|
-
return process.env.
|
|
177
|
+
if (process.env.PENTESTING_BIN) {
|
|
178
|
+
return process.env.PENTESTING_BIN;
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
const target = resolveReleaseAsset();
|
|
@@ -188,14 +188,14 @@ export async function resolveBuilderBinary(options = {}) {
|
|
|
188
188
|
const install = await installManagedBuilder();
|
|
189
189
|
if (install.source === "skipped") {
|
|
190
190
|
throw new Error(
|
|
191
|
-
"Managed Builder download was skipped and no
|
|
191
|
+
"Managed Builder download was skipped and no PENTESTING_BIN override was provided.",
|
|
192
192
|
);
|
|
193
193
|
}
|
|
194
194
|
return install.binaryPath;
|
|
195
195
|
}
|
|
196
196
|
|
|
197
197
|
throw new Error(
|
|
198
|
-
"No managed Builder binary is available. Reinstall the pentesting package or set
|
|
198
|
+
"No managed Builder binary is available. Reinstall the pentesting package or set PENTESTING_BIN.",
|
|
199
199
|
);
|
|
200
200
|
}
|
|
201
201
|
|
|
@@ -206,6 +206,6 @@ export function translateBuilderInvocation(argv) {
|
|
|
206
206
|
export function pentestingEnvironment(baseEnv = process.env) {
|
|
207
207
|
return {
|
|
208
208
|
...baseEnv,
|
|
209
|
-
|
|
209
|
+
PENTESTING_PRODUCT_NAME: "pentesting",
|
|
210
210
|
};
|
|
211
211
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pentesting",
|
|
3
|
-
"version": "0.90.
|
|
3
|
+
"version": "0.90.8",
|
|
4
4
|
"builderReleaseTag": "v0.1.4",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "pentesting — security-focused agent runtime (internal engine: builder). Thin npm facade that downloads the managed Builder binary and forwards arguments.",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "agnusdei1207",
|
|
6
8
|
"type": "module",
|
|
7
9
|
"bin": {
|
|
8
10
|
"pentesting": "bin/pentesting.mjs"
|
|
@@ -10,29 +12,19 @@
|
|
|
10
12
|
"files": [
|
|
11
13
|
"bin",
|
|
12
14
|
"lib",
|
|
13
|
-
"scripts",
|
|
15
|
+
"scripts/postinstall.mjs",
|
|
14
16
|
"README.md"
|
|
15
17
|
],
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"dev": "node ./bin/pentesting.mjs",
|
|
19
|
-
"preflight:local": "bash scripts/preflight-local.sh",
|
|
20
|
-
"test": "node --test tests/*.test.mjs",
|
|
21
|
-
"verify": "npm run preflight:local && npm run test",
|
|
22
|
-
"check": "npm run verify",
|
|
23
|
-
"prepublishOnly": "npm run verify",
|
|
24
|
-
"publish:token": "npm publish --access public",
|
|
25
|
-
"release:patch": "npm version patch && npm run verify && npm run publish:token",
|
|
26
|
-
"release:minor": "npm version minor && npm run verify && npm run publish:token",
|
|
27
|
-
"release:major": "npm version major && npm run verify && npm run publish:token"
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18.18.0"
|
|
28
20
|
},
|
|
29
21
|
"repository": {
|
|
30
22
|
"type": "git",
|
|
31
|
-
"url": "git+https://github.com/agnusdei1207/
|
|
23
|
+
"url": "git+https://github.com/agnusdei1207/pentesting-public.git"
|
|
32
24
|
},
|
|
33
|
-
"homepage": "https://agnusdei1207.github.io/
|
|
25
|
+
"homepage": "https://agnusdei1207.github.io/pentesting-public/",
|
|
34
26
|
"bugs": {
|
|
35
|
-
"url": "https://github.com/agnusdei1207/
|
|
27
|
+
"url": "https://github.com/agnusdei1207/pentesting-public/issues"
|
|
36
28
|
},
|
|
37
29
|
"keywords": [
|
|
38
30
|
"penetration-testing",
|
|
@@ -51,9 +43,75 @@
|
|
|
51
43
|
"sqlmap",
|
|
52
44
|
"kali"
|
|
53
45
|
],
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
"
|
|
46
|
+
"scripts": {
|
|
47
|
+
"postinstall": "node ./scripts/postinstall.mjs",
|
|
48
|
+
"prepublishOnly": "npm run verify",
|
|
49
|
+
"test": "node --test tests/*.test.mjs",
|
|
50
|
+
"preflight:local": "bash scripts/preflight-local.sh",
|
|
51
|
+
"verify": "npm run preflight:local && npm run test",
|
|
52
|
+
"build": "CARGO_TARGET_DIR=${CARGO_TARGET_DIR:-$HOME/.cache/builder-target} $HOME/.cargo/bin/cargo build --bin pentesting",
|
|
53
|
+
"check": "sh -c 'npm run docker:builder:build && docker run -it --rm -v builder-workspace:/workspace -e ANTHROPIC_BASE_URL -e ANTHROPIC_AUTH_TOKEN -e ANTHROPIC_MODEL -e ANTHROPIC_API_KEY -e MINIMAX_API_KEY -e OPENAI_API_KEY -e OPENAI_BASE_URL -e GEMINI_API_KEY -e DEEPSEEK_API_KEY agnusdei1207/pentesting:latest'",
|
|
54
|
+
"check:interactive": "npm run check",
|
|
55
|
+
"check:smoke": "sh -c 'npm run docker:builder:build && docker run --rm -v builder-workspace:/workspace agnusdei1207/pentesting:latest --version'",
|
|
56
|
+
"check:clean": "npm run docker:clean && npm run check",
|
|
57
|
+
"eval": "tsx benchmarks/cli.ts",
|
|
58
|
+
"eval:all": "npm run build && find benchmarks/evals -name task.yml -exec dirname {} \\; | sort | while read -r d; do echo \"\\n=== Running $(basename $d) ===\"; tsx benchmarks/cli.ts \"$d\" || true; done",
|
|
59
|
+
"pentesting:help": "./scripts/pentesting-release-help.sh",
|
|
60
|
+
"pentesting:status": "./scripts/pentesting-release-status.sh",
|
|
61
|
+
"pentesting:test": "npm run test",
|
|
62
|
+
"pentesting:verify": "npm run verify",
|
|
63
|
+
"pentesting:pack:dry-run": "npm pack --dry-run",
|
|
64
|
+
"pentesting:check": "./scripts/check-pentesting-package.sh",
|
|
65
|
+
"pentesting:publish": "./scripts/publish-pentesting-package.sh",
|
|
66
|
+
"pentesting:publish:dry-run": "DRY_RUN=true ./scripts/publish-pentesting-package.sh",
|
|
67
|
+
"pentesting:release": "npm run pentesting:release:patch",
|
|
68
|
+
"pentesting:release:dry-run": "npm run pentesting:release:patch:dry-run",
|
|
69
|
+
"pentesting:release:patch": "npm run pentesting:check && AUTO_PUSH=true ./scripts/publish-pentesting-package.sh patch",
|
|
70
|
+
"pentesting:release:patch:dry-run": "npm run pentesting:check && DRY_RUN=true ./scripts/publish-pentesting-package.sh patch",
|
|
71
|
+
"pentesting:release:minor": "npm run pentesting:check && AUTO_PUSH=true ./scripts/publish-pentesting-package.sh minor",
|
|
72
|
+
"pentesting:release:minor:dry-run": "npm run pentesting:check && DRY_RUN=true ./scripts/publish-pentesting-package.sh minor",
|
|
73
|
+
"pentesting:release:major": "npm run pentesting:check && AUTO_PUSH=true ./scripts/publish-pentesting-package.sh major",
|
|
74
|
+
"pentesting:release:major:dry-run": "npm run pentesting:check && DRY_RUN=true ./scripts/publish-pentesting-package.sh major",
|
|
75
|
+
"public:sync": "./scripts/sync-public-repo.sh",
|
|
76
|
+
"public:sync:push": "AUTO_PUSH=true ./scripts/sync-public-repo.sh",
|
|
77
|
+
"public:pull": "git submodule update --remote --merge public",
|
|
78
|
+
"public:publish": "AUTO_PUSH=true ./scripts/sync-public-repo.sh && git add public && git commit -m 'chore: bump public facade pointer' && git push origin main",
|
|
79
|
+
"public:mirror-release": "./scripts/mirror-public-release.sh",
|
|
80
|
+
"public:ci:sync": "gh workflow run 'Sync Builder Repo' --ref main",
|
|
81
|
+
"public:ci:mirror": "gh workflow run 'Mirror Builder Release' --ref main -f version_tag=$(git describe --tags --abbrev=0)",
|
|
82
|
+
"public:ci:status": "gh run list --workflow=sync-public.yml --limit=3 && echo '---' && gh run list --workflow=mirror-release.yml --limit=3",
|
|
83
|
+
"docker:builder:build": "(docker image inspect agnusdei1207/pentesting-build-base:1.95 >/dev/null 2>&1 && docker image inspect agnusdei1207/pentesting-runtime-base:26.04 >/dev/null 2>&1 || npm run docker:base:build) && docker build --build-arg APP_VERSION=$(git describe --tags --abbrev=0 2>/dev/null || echo dev) -t agnusdei1207/pentesting:latest .",
|
|
84
|
+
"docker:builder:push": "if [ -n \"$DOCKER_PASSWORD\" ]; then echo \"$DOCKER_PASSWORD\" | docker login -u \"${DOCKER_USERNAME:-agnusdei1207}\" --password-stdin; fi && npm run docker:builder:build && docker push agnusdei1207/pentesting:latest",
|
|
85
|
+
"docker:builder:tag": "docker tag agnusdei1207/pentesting:latest agnusdei1207/pentesting:$(git describe --tags --abbrev=0) && docker push agnusdei1207/pentesting:$(git describe --tags --abbrev=0)",
|
|
86
|
+
"docker:base:build": "docker build -t agnusdei1207/pentesting-build-base:1.95 -f docker/build-base.Dockerfile . && docker build -t agnusdei1207/pentesting-runtime-base:26.04 -f docker/runtime-base.Dockerfile .",
|
|
87
|
+
"docker:base:push": "if [ -n \"$DOCKER_PASSWORD\" ]; then echo \"$DOCKER_PASSWORD\" | docker login -u \"${DOCKER_USERNAME:-agnusdei1207}\" --password-stdin; fi && npm run docker:base:build && docker push agnusdei1207/pentesting-build-base:1.95 && docker push agnusdei1207/pentesting-runtime-base:26.04",
|
|
88
|
+
"docker:clean": "docker stop $(docker ps -q) 2>/dev/null || true && docker system prune -af",
|
|
89
|
+
"release": "./scripts/release-all.sh patch",
|
|
90
|
+
"release:dry": "DRY_RUN=true ./scripts/release-all.sh patch",
|
|
91
|
+
"release:local": "./scripts/run-release-in-docker.sh ./scripts/build-release-local.sh",
|
|
92
|
+
"release:local:dry": "DRY_RUN=true ./scripts/run-release-in-docker.sh ./scripts/build-release-local.sh",
|
|
93
|
+
"release:local:host": "./scripts/build-release-local.sh",
|
|
94
|
+
"release:local:host:dry": "DRY_RUN=true ./scripts/build-release-local.sh",
|
|
95
|
+
"release:backfill": "./scripts/run-release-in-docker.sh ./scripts/backfill-release-local.sh",
|
|
96
|
+
"release:backfill:dry": "DRY_RUN=true ./scripts/run-release-in-docker.sh ./scripts/backfill-release-local.sh",
|
|
97
|
+
"release:backfill:host": "./scripts/backfill-release-local.sh",
|
|
98
|
+
"release:backfill:host:dry": "DRY_RUN=true ./scripts/backfill-release-local.sh"
|
|
99
|
+
},
|
|
100
|
+
"devDependencies": {
|
|
101
|
+
"@ai-sdk/google-vertex": "^4.0.47",
|
|
102
|
+
"@types/node": "^24.10.1",
|
|
103
|
+
"@types/tmp": "^0.2.6",
|
|
104
|
+
"ai": "^6.0.77",
|
|
105
|
+
"csv-parse": "^6.1.0",
|
|
106
|
+
"handlebars": "^4.7.9",
|
|
107
|
+
"p-limit": "^7.2.0",
|
|
108
|
+
"pino": "^10.1.0",
|
|
109
|
+
"pino-pretty": "^13.1.2",
|
|
110
|
+
"strip-ansi": "^7.1.2",
|
|
111
|
+
"tmp": "^0.2.5",
|
|
112
|
+
"tsx": "^4.20.6",
|
|
113
|
+
"yaml": "^2.8.3",
|
|
114
|
+
"yargs": "^18.0.0",
|
|
115
|
+
"zod": "^3.24.1"
|
|
58
116
|
}
|
|
59
117
|
}
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,30 +1,33 @@
|
|
|
1
1
|
import { installManagedBuilder } from "../lib/runtime.mjs";
|
|
2
2
|
|
|
3
|
-
if (process.env.
|
|
4
|
-
console.log("[pentesting]
|
|
3
|
+
if (process.env.PENTESTING_BIN) {
|
|
4
|
+
console.log("[pentesting] PENTESTING_BIN is set; skipping managed Builder download.");
|
|
5
5
|
process.exit(0);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
if (process.env.
|
|
8
|
+
if (process.env.PENTESTING_SKIP_DOWNLOAD === "true") {
|
|
9
9
|
console.log("[pentesting] Skipping managed Builder download.");
|
|
10
10
|
process.exit(0);
|
|
11
11
|
}
|
|
12
12
|
|
|
13
13
|
try {
|
|
14
14
|
const result = await installManagedBuilder({
|
|
15
|
-
force: process.env.
|
|
15
|
+
force: process.env.PENTESTING_FORCE_DOWNLOAD === "true",
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
if (result.source === "cached") {
|
|
19
|
-
console.log("[pentesting]
|
|
19
|
+
console.log("[pentesting] Runtime already installed.");
|
|
20
20
|
} else if (result.source === "downloaded") {
|
|
21
|
-
console.log("[pentesting]
|
|
21
|
+
console.log("[pentesting] Runtime downloaded successfully.");
|
|
22
22
|
}
|
|
23
23
|
} catch (error) {
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
// Non-fatal: never break `npm i pentesting`. The runtime is fetched on first
|
|
25
|
+
// run (resolveBuilderBinary downloads if missing), so a failed/offline
|
|
26
|
+
// postinstall just defers the download instead of failing the install.
|
|
27
|
+
console.warn(
|
|
28
|
+
`[pentesting] Runtime not pre-downloaded (${
|
|
26
29
|
error instanceof Error ? error.message : String(error)
|
|
27
|
-
}
|
|
30
|
+
}). It will be fetched automatically on first run.`,
|
|
28
31
|
);
|
|
29
|
-
process.exit(
|
|
32
|
+
process.exit(0);
|
|
30
33
|
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
#!/bin/sh
|
|
2
|
-
|
|
3
|
-
set -eu
|
|
4
|
-
|
|
5
|
-
require_command() {
|
|
6
|
-
if ! command -v "$1" >/dev/null 2>&1; then
|
|
7
|
-
echo "Missing required command: $1" >&2
|
|
8
|
-
exit 1
|
|
9
|
-
fi
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
require_path() {
|
|
13
|
-
if [ ! -e "$1" ]; then
|
|
14
|
-
echo "Missing required path: $1" >&2
|
|
15
|
-
exit 1
|
|
16
|
-
fi
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
SCRIPT_DIR=$(CDPATH= cd -- "$(dirname "$0")" && pwd)
|
|
20
|
-
PACKAGE_ROOT=$(CDPATH= cd -- "$SCRIPT_DIR/.." && pwd)
|
|
21
|
-
|
|
22
|
-
require_command node
|
|
23
|
-
require_path "$PACKAGE_ROOT/bin/pentesting.mjs"
|
|
24
|
-
require_path "$PACKAGE_ROOT/lib/runtime.mjs"
|