pwn 0.5.627 → 0.5.629
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.
- checksums.yaml +4 -4
- data/.rubocop_todo.yml +20 -30
- data/Gemfile +1 -1
- data/README.md +29 -21
- data/bin/pwn +35 -1
- data/bin/pwn_setup +64 -0
- data/documentation/AI-Integration.md +48 -9
- data/documentation/AWS.md +1 -1
- data/documentation/Agent-Tool-Registry.md +24 -0
- data/documentation/BurpSuite.md +4 -1
- data/documentation/CLI-Drivers.md +27 -10
- data/documentation/Configuration.md +37 -10
- data/documentation/Contributing.md +13 -3
- data/documentation/Extrospection.md +108 -98
- data/documentation/FFI.md +14 -2
- data/documentation/Fuzzing.md +3 -0
- data/documentation/General-PWN-Usage.md +12 -0
- data/documentation/Hardware.md +4 -0
- data/documentation/Home.md +4 -4
- data/documentation/How-PWN-Works.md +2 -1
- data/documentation/Installation.md +201 -37
- data/documentation/Metasploit.md +4 -1
- data/documentation/NmapIt.md +3 -0
- data/documentation/Persistence.md +5 -2
- data/documentation/Reporting.md +3 -0
- data/documentation/SDR.md +4 -0
- data/documentation/Skills-Memory-Learning.md +24 -11
- data/documentation/Swarm.md +20 -0
- data/documentation/Transparent-Browser.md +3 -0
- data/documentation/Troubleshooting.md +63 -7
- data/documentation/What-is-PWN.md +1 -1
- data/documentation/diagrams/agent-tool-registry.svg +120 -109
- data/documentation/diagrams/ai-integration-tool-calling.svg +76 -65
- data/documentation/diagrams/dot/agent-tool-registry.dot +5 -3
- data/documentation/diagrams/dot/ai-integration-tool-calling.dot +3 -2
- data/documentation/diagrams/dot/memory-skills-detailed.dot +26 -4
- data/documentation/diagrams/dot/overall-pwn-architecture.dot +6 -4
- data/documentation/diagrams/dot/persistence-filesystem.dot +4 -2
- data/documentation/diagrams/dot/pwn-ai-feedback-learning-loop.dot +31 -10
- data/documentation/diagrams/dot/swarm-multi-agent.dot +7 -1
- data/documentation/diagrams/extrospection-world-awareness.svg +129 -129
- data/documentation/diagrams/memory-skills-detailed.svg +268 -137
- data/documentation/diagrams/overall-pwn-architecture.svg +188 -171
- data/documentation/diagrams/persistence-filesystem.svg +115 -85
- data/documentation/diagrams/pwn-ai-feedback-learning-loop.svg +407 -255
- data/documentation/diagrams/sdr-radio-flow.svg +51 -51
- data/documentation/diagrams/swarm-multi-agent.svg +156 -119
- data/documentation/pwn-REPL.md +1 -0
- data/documentation/pwn-ai-Agent.md +50 -22
- data/lib/pwn/ai/agent/dispatch.rb +76 -4
- data/lib/pwn/ai/agent/learning.rb +124 -1
- data/lib/pwn/ai/agent/loop.rb +144 -12
- data/lib/pwn/ai/agent/metrics.rb +60 -27
- data/lib/pwn/ai/agent/prompt_builder.rb +63 -12
- data/lib/pwn/ai/agent/reflect.rb +41 -7
- data/lib/pwn/ai/agent/registry.rb +69 -4
- data/lib/pwn/ai/ollama.rb +39 -10
- data/lib/pwn/config.rb +13 -2
- data/lib/pwn/ffi/liquid.rb +179 -0
- data/lib/pwn/memory.rb +15 -0
- data/lib/pwn/memory_index.rb +233 -0
- data/lib/pwn/plugins/repl.rb +26 -2
- data/lib/pwn/sdr/decoder/bluetooth.rb +141 -75
- data/lib/pwn/sdr/decoder/dect.rb +89 -63
- data/lib/pwn/sdr/decoder/dsp.rb +443 -0
- data/lib/pwn/sdr/decoder/gps.rb +93 -73
- data/lib/pwn/sdr/decoder/gsm.rb +167 -63
- data/lib/pwn/sdr/decoder/lora.rb +118 -65
- data/lib/pwn/sdr/decoder/lte.rb +188 -65
- data/lib/pwn/sdr/decoder/p25.rb +83 -67
- data/lib/pwn/sdr/decoder/zigbee.rb +140 -67
- data/lib/pwn/setup.rb +563 -0
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +2 -0
- data/spec/lib/pwn/memory_index_spec.rb +15 -0
- data/spec/lib/pwn/setup_spec.rb +28 -0
- data/third_party/pwn_rdoc.jsonl +79 -8
- metadata +10 -4
|
@@ -16,6 +16,11 @@ writes a fully-commented template with every key below (values set to
|
|
|
16
16
|
`'optional - …'` / `'required - …'` placeholder strings), encrypts it, and
|
|
17
17
|
generates the decryptor.
|
|
18
18
|
|
|
19
|
+
> **Before configuring**, run `pwn setup` — the
|
|
20
|
+
> [doctor](Installation.md#pwn-setup--the-post-install-doctor--provisioner)
|
|
21
|
+
> reports whether `~/.pwn/`, `pwn.yaml`, its decryptor, and an AI-engine key
|
|
22
|
+
> are present, and exits non-zero for CI if any are missing.
|
|
23
|
+
|
|
19
24
|
---
|
|
20
25
|
|
|
21
26
|
## Full annotated example
|
|
@@ -30,7 +35,7 @@ ai:
|
|
|
30
35
|
grok:
|
|
31
36
|
base_uri: https://api.x.ai/v1 # xAI API base URL. Override for a self-hosted proxy / private endpoint.
|
|
32
37
|
key: xai-… # xAI API key. If blank AND no oauth.* below, PWN prompts interactively at load.
|
|
33
|
-
model:
|
|
38
|
+
model: <model-id> # Model id sent on every chat / tool-loop request. See provider docs / API for currently-supported ids.
|
|
34
39
|
system_role_content: 'You are an ethically hacking xAI Grok agent.' # Base system prompt (MEMORY/SKILLS/LEARNING/EXTROSPECTION blocks are appended to this).
|
|
35
40
|
temp: 1.0 # Sampling temperature passed to the chat endpoint.
|
|
36
41
|
max_prompt_length: 256000 # Soft input-context ceiling (chars) used for prompt truncation / chunking.
|
|
@@ -46,7 +51,7 @@ ai:
|
|
|
46
51
|
openai:
|
|
47
52
|
base_uri: https://api.openai.com/v1 # OpenAI API base URL. Override for Azure OpenAI / VPC gateway / local proxy.
|
|
48
53
|
key: sk-… # OpenAI API key (`sk-…`). Prompted interactively if blank.
|
|
49
|
-
model:
|
|
54
|
+
model: <model-id> # Model id sent on every chat / tool-loop request. See provider docs / API for currently-supported ids.
|
|
50
55
|
system_role_content: 'You are an ethically hacking OpenAI agent.' # Base system prompt for this engine.
|
|
51
56
|
temp: 1.0 # Sampling temperature.
|
|
52
57
|
max_prompt_length: 128000 # Soft input-context ceiling (chars) for truncation / chunking.
|
|
@@ -55,7 +60,7 @@ ai:
|
|
|
55
60
|
anthropic:
|
|
56
61
|
base_uri: https://api.anthropic.com/v1 # Anthropic API base URL. Override for Bedrock / private gateway.
|
|
57
62
|
key: sk-ant-… # Anthropic API key (`sk-ant-…`). Prompted interactively if blank.
|
|
58
|
-
model:
|
|
63
|
+
model: <model-id> # Model id sent on every chat / tool-loop request. See provider docs / API for currently-supported ids.
|
|
59
64
|
system_role_content: 'You are an ethically hacking Anthropic agent.' # Base system prompt for this engine.
|
|
60
65
|
temp: 1.0 # Sampling temperature.
|
|
61
66
|
max_tokens: 8192 # Max OUTPUT tokens per response. Raise if tool-call JSON truncates.
|
|
@@ -64,7 +69,7 @@ ai:
|
|
|
64
69
|
gemini:
|
|
65
70
|
base_uri: https://generativelanguage.googleapis.com/v1beta # Google Generative Language API base URL.
|
|
66
71
|
key: AIza… # Google AI Studio API key (`AIza…`). Prompted interactively if blank.
|
|
67
|
-
model:
|
|
72
|
+
model: <model-id> # Model id sent on every chat / tool-loop request. See provider docs / API for currently-supported ids.
|
|
68
73
|
system_role_content: 'You are an ethically hacking Gemini agent.' # Base system prompt for this engine.
|
|
69
74
|
temp: 1.0 # Sampling temperature.
|
|
70
75
|
max_prompt_length: 1000000 # Soft input-context ceiling (chars) — Gemini supports very large contexts.
|
|
@@ -72,17 +77,31 @@ ai:
|
|
|
72
77
|
ollama:
|
|
73
78
|
base_uri: https://ollama.local # REQUIRED for ollama — Open WebUI / ollama-serve base URL (no vendor default).
|
|
74
79
|
key: eyJ… # Open WebUI JWT (Settings → Account → API Key). Prompted if blank.
|
|
75
|
-
model:
|
|
80
|
+
model: <local-model-tag> # Local model tag exactly as `ollama list` shows it.
|
|
81
|
+
embed_model: <embed-model-tag> # Embedding model for PWN::MemoryIndex (relevance-ranked MEMORY). Must be pulled locally.
|
|
76
82
|
system_role_content: 'You are an ethically hacking Ollama agent.' # Base system prompt for this engine.
|
|
77
|
-
temp: 1.0 # Sampling temperature.
|
|
83
|
+
temp: 1.0 # Sampling temperature (used on the FINAL text-only turn — tool-bearing turns are pinned low for deterministic routing).
|
|
84
|
+
num_ctx: 32768 # Context window passed to /api/chat options.num_ctx. Ollama's default (2048) is too small for the pwn-ai system prompt.
|
|
85
|
+
keep_alive: 30m # How long ollama keeps the model resident between iterations (avoids reload latency mid-turn).
|
|
86
|
+
prompt_budget: # Per-block caps applied by PromptBuilder.budget so a small model spends attention on the request, not the harness.
|
|
87
|
+
memory: 6 # Max MEMORY entries injected (relevance-ranked via PWN::MemoryIndex when available).
|
|
88
|
+
metrics: 3 # Max TOOL EFFECTIVENESS rows.
|
|
89
|
+
mistakes: 3 # Max KNOWN MISTAKES / FIXES rows.
|
|
90
|
+
learning: 2 # Max recent LEARNING outcomes shown.
|
|
91
|
+
extro: false # Gate the (heaviest) EXTROSPECTION block entirely for local models.
|
|
78
92
|
max_prompt_length: 32000 # Soft input-context ceiling (chars) — tune per local model's real context window.
|
|
79
93
|
|
|
94
|
+
reflect_engine: ~ # Teacher-student reflection: EXECUTE on ai.active, but write durable lessons via THIS engine (nil = same as active). Lets a local model act while a frontier model authors the Memory :lesson entries it reads back.
|
|
95
|
+
|
|
80
96
|
agent:
|
|
81
97
|
native_tools: true # Use provider-native tool_calls / function-calling. false → legacy text-parsed tool protocol.
|
|
82
98
|
max_iters: 25 # Hard cap on tool-call rounds per user turn before a forced final answer.
|
|
83
99
|
max_depth: 3 # Recursion guard: how many levels deep agent_ask/agent_debate sub-agents may spawn sub-agents.
|
|
84
100
|
auto_introspect: true # Run Learning.auto_introspect (outcome logging + lesson mining) after every final answer.
|
|
85
101
|
auto_extrospect: false # Optional ambient baseline (host/repo/env ONLY — never launches burpsuite/zaproxy/msf/gqrx). Sense tools (intel/verify/watch/rf_tune/observe) stay on-demand.
|
|
102
|
+
plan_first: ~ # Plan-then-act pre-pass: force the model to externalise a numbered tool plan BEFORE its first dispatch. nil = auto (true when ai.active == ollama).
|
|
103
|
+
tool_router: false # Dynamic tool-set slimming: ship only Registry::CORE_TOOLS + top-K keyword-relevant schemas per turn (helps small models route correctly).
|
|
104
|
+
escalation_persona: ~ # Swarm persona name to ask for a 3-line corrective hint once a local model burns ≥ Loop::ESCALATE_AFTER_FAILS in-turn failures. nil = disabled.
|
|
86
105
|
toolsets: ~ # Allow-list of toolsets exposed to the agent. nil = all. Valid: cron, extrospection, learning, memory, metrics, pwn, sessions, skills, swarm, terminal.
|
|
87
106
|
extrospection:
|
|
88
107
|
web:
|
|
@@ -193,12 +212,17 @@ PWN::Config.refresh_env
|
|
|
193
212
|
| `ai.module_reflection` | Boolean | `false` | `PWN::AI::Agent::Reflect`, `PWN::SAST::*`, `PWN::Plugins::BurpSuite` | Master gate for LLM-driven self-analysis (SAST triage, Burp finding enrichment, `Learning.llm_reflect`). |
|
|
194
213
|
| `ai.<engine>.base_uri` | String | provider default | `PWN::AI::<Engine>.rest_call` | Override the API base URL (self-hosted proxy, private endpoint, Azure/VPC gateway). **Required** for `ollama`. |
|
|
195
214
|
| `ai.<engine>.key` | String | — | `PWN::AI::<Engine>` | API key / bearer token. If blank AND no OAuth is configured, PWN prompts interactively at load. |
|
|
196
|
-
| `ai.<engine>.model` | String | provider default | `PWN::AI::<Engine>.chat` / `.chat_tool_loop` | Model id sent on every request
|
|
215
|
+
| `ai.<engine>.model` | String | provider default | `PWN::AI::<Engine>.chat` / `.chat_tool_loop` | Model id sent on every request. Use whatever id the provider / `ollama list` currently exposes — PWN never hard-codes a specific model. |
|
|
197
216
|
| `ai.<engine>.system_role_content` | String | ethical-hacker persona | `PWN::AI::Agent::PromptBuilder`, `PWN::Plugins::REPL` | Base system prompt prepended to MEMORY / SKILLS / LEARNING / EXTROSPECTION blocks. |
|
|
198
217
|
| `ai.<engine>.temp` | Float | `1.0` | `PWN::AI::<Engine>.chat` | Sampling temperature. |
|
|
199
218
|
| `ai.<engine>.max_prompt_length` | Integer | per-engine | `PWN::AI::<Engine>`, `PWN::Plugins::REPL` | Soft input-context ceiling used for prompt truncation / chunking. |
|
|
200
219
|
| `ai.anthropic.max_tokens` | Integer | `8192` | `PWN::AI::Anthropic.chat_tool_loop` | Max **output** tokens per response. Raise if tool-call JSON truncates. |
|
|
201
220
|
| `ai.openai.max_tokens` | Integer | `16384` | `PWN::AI::OpenAI.chat` | Max **output** tokens per response. Mapped to OpenAI's wire param `max_completion_tokens` (legacy env key `max_completion_tokens` still accepted). |
|
|
221
|
+
| `ai.ollama.embed_model` | String | provider default | `PWN::MemoryIndex` | Local embedding model tag used to build `~/.pwn/memory.idx` for **relevance-ranked** MEMORY injection. Falls back to substring recall when unset / unreachable. |
|
|
222
|
+
| `ai.ollama.num_ctx` | Integer | `32768` | `PWN::AI::Ollama.chat_with_tools` | Context window sent as `options.num_ctx` on the native `/api/chat` call. Ollama's own default (2048) truncates the pwn-ai system prompt. |
|
|
223
|
+
| `ai.ollama.keep_alive` | String | `30m` | `PWN::AI::Ollama.chat_with_tools` | How long the model stays resident in ollama between iterations of a single turn. |
|
|
224
|
+
| `ai.ollama.prompt_budget` | Hash | `{memory:6, metrics:3, mistakes:3, learning:2, extro:false}` | `PWN::AI::Agent::PromptBuilder.budget` | Per-block caps on injected context so a small local model spends its attention on the request, not the harness. Any engine may set this. |
|
|
225
|
+
| `ai.reflect_engine` | Symbol \| `nil` | `nil` (= `ai.active`) | `PWN::AI::Agent::Reflect.on`, `Learning.reflect` | **Teacher-student** override: run the task on `ai.active`, but generate durable lessons via *this* engine. Lets a local model execute while a frontier model writes the Memory it reads back. |
|
|
202
226
|
| `ai.grok.oauth.refresh_token` | String | — | `PWN::AI::Grok.resolve_auth` | Durable OAuth refresh token (from `PWN::AI::Grok.obtain_oauth_bearer_token` device flow). Enables silent re-auth without an API key. |
|
|
203
227
|
| `ai.grok.oauth.bearer_token` | String | — | `PWN::AI::Grok.resolve_auth` | Short-lived OAuth access JWT. Auto-refreshed each run when `refresh_token` is present; live-cached back into this hash. |
|
|
204
228
|
| `ai.grok.oauth.client_id` | String | Grok-CLI public id | `PWN::AI::Grok` | Override the public OAuth client id used for device-flow / refresh. |
|
|
@@ -217,6 +241,9 @@ PWN::Config.refresh_env
|
|
|
217
241
|
| `ai.agent.auto_introspect` | Boolean | `true` | `PWN::AI::Agent::Learning.auto_introspect` | Run outcome logging + lesson mining after every final answer. Toggle live via `learning_auto_introspect_toggle`. |
|
|
218
242
|
| `ai.agent.auto_extrospect` | Boolean | `false` | `PWN::AI::Agent::Extrospection.auto_extrospect` | Optional ambient baseline after every final answer (`AUTO_SECTIONS` = host/repo/env only; never spawns GUI/JVM tools). Prefer on-demand sense tools (`intel`/`verify`/`watch`/`rf_tune`/`observe`). Toggle live via `extro_auto_toggle`. |
|
|
219
243
|
| `ai.agent.toolsets` | Array\<String\> \| `nil` | `nil` (all) | `bin/pwn`, `PWN::Plugins::REPL`, `PWN::AI::Agent::Registry` | Allow-list of toolsets exposed to the agent. Valid: `cron`, `extrospection`, `learning`, `memory`, `metrics`, `pwn`, `sessions`, `skills`, `swarm`, `terminal`. |
|
|
244
|
+
| `ai.agent.plan_first` | Boolean \| `nil` | `nil` (auto: `true` when `ai.active == ollama`) | `PWN::AI::Agent::Loop.plan_first` | Plan-then-act pre-pass: the model must emit a numbered tool plan (as an assistant message) *before* it may dispatch anything. Cheap chain-of-thought scaffolding for local models. |
|
|
245
|
+
| `ai.agent.tool_router` | Boolean | `false` | `PWN::AI::Agent::Registry.definitions` | Dynamic tool-set slimming: expose only `Registry::CORE_TOOLS` + the top-K keyword-relevant schemas for *this* request. Ties break on historical `Metrics` success rate so the router itself is a learned component. |
|
|
246
|
+
| `ai.agent.escalation_persona` | String \| `nil` | `nil` | `PWN::AI::Agent::Loop.escalate` → `Swarm.ask` | Circuit-breaker: once a local model accumulates ≥ `Loop::ESCALATE_AFTER_FAILS` in-turn failures, ask this Swarm persona for a 3-line corrective hint (injected as a synthetic tool result). The local model still authors the final answer so Learning/Metrics stay attributed. |
|
|
220
247
|
| `ai.agent.extrospection.web.anchors` | Array\<String\> | `DEFAULT_WEB_ANCHORS` | `PWN::AI::Agent::Extrospection.probe_web` | URLs the headless browser fingerprints on `extro_snapshot(sections:[:web])`. Alias: `web_anchors`. |
|
|
221
248
|
| `ai.agent.extrospection.web.proxy` | String | — | `Extrospection.probe_web` / `.verify` / `.watch` | Upstream proxy for `PWN::Plugins::TransparentBrowser` (e.g. `tor`, `http://127.0.0.1:8080`). |
|
|
222
249
|
| `ai.agent.extrospection.web.max_anchors` | Integer | `8` | `Extrospection.probe_web` | Cap on anchors rendered per snapshot. |
|
|
@@ -309,9 +336,9 @@ agent system prompt.
|
|
|
309
336
|
|
|
310
337
|
`pwn.yaml` is the only file you edit; everything else is machine-written
|
|
311
338
|
state. See **[Persistence](Persistence.md)** for the full map
|
|
312
|
-
(`memory.json`, `
|
|
313
|
-
`extrospection.json`, `sessions/`, `skills/`,
|
|
314
|
-
`swarm/`).
|
|
339
|
+
(`memory.json`, `memory.idx`, `learning.jsonl`, `mistakes.json`,
|
|
340
|
+
`metrics.json`, `extrospection.json`, `sessions/`, `skills/`,
|
|
341
|
+
`finetune/`, `cron/`, `agents.yml`, `swarm/`).
|
|
315
342
|
|
|
316
343
|
Multi-agent personas are **not** configured here — they live in
|
|
317
344
|
`~/.pwn/agents.yml` and are managed with `agent_spawn` / `agent_list`
|
|
@@ -4,10 +4,11 @@
|
|
|
4
4
|
|
|
5
5
|
```text
|
|
6
6
|
lib/pwn/ # all namespaces
|
|
7
|
+
lib/pwn/setup.rb # PWN::Setup — doctor/provisioner data tables
|
|
7
8
|
lib/pwn/plugins/ # 66 plugin modules
|
|
8
9
|
lib/pwn/ai/agent/ # agent core
|
|
9
10
|
lib/pwn/ai/agent/tools/ # LLM tool registrations
|
|
10
|
-
bin/ #
|
|
11
|
+
bin/ # 53 pwn_* drivers (incl. pwn_setup)
|
|
11
12
|
spec/ # RSpec (incl. conventions_spec)
|
|
12
13
|
documentation/ # this wiki + diagrams
|
|
13
14
|
```
|
|
@@ -23,9 +24,11 @@ documentation/ # this wiki + diagrams
|
|
|
23
24
|
## Quality gates
|
|
24
25
|
|
|
25
26
|
```bash
|
|
26
|
-
|
|
27
|
+
rake # rubocop + rspec — must be zero offenses
|
|
27
28
|
```
|
|
28
29
|
|
|
30
|
+
(`rvmsudo rake` on multi-user RVM installs.)
|
|
31
|
+
|
|
29
32
|
## Adding a plugin
|
|
30
33
|
|
|
31
34
|
1. `lib/pwn/plugins/my_thing.rb` following the conventions above.
|
|
@@ -34,7 +37,14 @@ rvmsudo rake # rubocop + rspec — must be zero offenses
|
|
|
34
37
|
4. Optional `bin/pwn_my_thing` driver (see [Drivers](Drivers.md)).
|
|
35
38
|
5. Optional agent tool in `lib/pwn/ai/agent/tools/` (see
|
|
36
39
|
[Agent Tool Registry](Agent-Tool-Registry.md)).
|
|
37
|
-
6.
|
|
40
|
+
6. **If it needs a native gem or external binary**, add **one row** to
|
|
41
|
+
`PWN::Setup::NATIVE_GEMS` or `PWN::Setup::TOOLCHAIN` in
|
|
42
|
+
`lib/pwn/setup.rb` (with `apt:`/`dnf:`/`pacman:`/`brew:`/`port:` package
|
|
43
|
+
names + the `plugins:` it unlocks) and, if it belongs in a capability
|
|
44
|
+
set, reference it from `PWN::Setup::PROFILES`. That single edit makes
|
|
45
|
+
`pwn setup` install it on every OS and every install path (gem, git,
|
|
46
|
+
Docker, Packer, Vagrant, CI). **Do not** add a new bash provisioner.
|
|
47
|
+
7. Update [Plugins.md](Plugins.md) and, if it changes a data flow, the
|
|
38
48
|
relevant `.dot` in `documentation/diagrams/dot/` → `./build.sh`.
|
|
39
49
|
|
|
40
50
|
## Commit / release
|
|
@@ -442,142 +442,152 @@ extro_correlate # why did it break?
|
|
|
442
442
|
|
|
443
443
|
## Example questions that trigger Extrospection
|
|
444
444
|
|
|
445
|
-
Natural-language prompts that should
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
- “
|
|
454
|
-
- “
|
|
455
|
-
- “
|
|
456
|
-
- “Sample
|
|
457
|
-
- “
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
- “
|
|
465
|
-
- “
|
|
466
|
-
- “
|
|
445
|
+
Natural-language prompts that should route to **outward** sensing rather than
|
|
446
|
+
introspection. These are phrased the way an offensive security researcher
|
|
447
|
+
actually asks them mid-engagement — attack-surface discovery, zero-day
|
|
448
|
+
hunting, hardware/RF poking, and disclosure prep. Location-specific examples
|
|
449
|
+
use **Chicago** so the catalogue stays portable.
|
|
450
|
+
|
|
451
|
+
### RF / SDR sense organ (`extro_rf_tune` + `:rf` observations)
|
|
452
|
+
|
|
453
|
+
- “Tune 433.92 MHz — is the target’s garage/gate remote fixed-code or rolling?”
|
|
454
|
+
- “Sweep the 900 MHz ISM band near the badge reader and log anything > −40 dBFS.”
|
|
455
|
+
- “What’s broadcasting on 101.1 FM right now — grab RDS PI/PS so we can prove SDR is live.”
|
|
456
|
+
- “Sample 868.3 MHz for 15 s — does the smart-meter mesh look like Wireless M-Bus?”
|
|
457
|
+
- “Any ADS-B traffic squawking over the client’s campus (near ORD)?”
|
|
458
|
+
- “Listen on the pager band (929.x MHz) — are unencrypted POCSAG pages leaking PHI?”
|
|
459
|
+
- “Is the site’s DMR/TETRA handheld traffic on 462.x actually encrypted?”
|
|
460
|
+
- “Park on 315 MHz and tell me if the target’s TPMS / key-fob replays cleanly.”
|
|
461
|
+
|
|
462
|
+
### Web / browser sense organ (`extro_watch`, `extro_verify`, `snapshot(sections: [:web])`)
|
|
463
|
+
|
|
464
|
+
- “Watch the target’s `/api/version` endpoint — alert me the moment the build string changes.”
|
|
465
|
+
- “Has the vendor silently patched? Diff today’s changelog DOM against our last hash.”
|
|
466
|
+
- “Did the bug-bounty scope page add or drop assets since we baselined it?”
|
|
467
|
+
- “Fingerprint the login portal’s JS bundle — framework, version, source-map leakage.”
|
|
468
|
+
- “Screenshot + DOM-hash the admin panel so we can prove pre-auth state for the report.”
|
|
469
|
+
- “Render the CSP/`.well-known/security.txt` and tell me who to disclose to.”
|
|
470
|
+
- “Has the target’s TLS cert or issuer rotated since the last watch?”
|
|
467
471
|
|
|
468
472
|
### OSINT sense organ (`extro_osint`)
|
|
469
473
|
|
|
470
|
-
- “
|
|
471
|
-
- “Who
|
|
472
|
-
- “
|
|
473
|
-
- “
|
|
474
|
-
- “
|
|
475
|
-
- “
|
|
476
|
-
- “
|
|
477
|
-
- “
|
|
478
|
-
- “
|
|
474
|
+
- “Enumerate every subdomain for `*.target.tld` via CT logs (crt.sh + CertSpotter).”
|
|
475
|
+
- “Who owns AS-XXXXX and what netblocks does it announce — expand our in-scope ranges.”
|
|
476
|
+
- “Pull EPSS + CISA KEV for CVE-2024-3094 — is this worth weaponising first?”
|
|
477
|
+
- “What’s Shodan / GreyNoise saying about `203.0.113.10` — already mass-exploited?”
|
|
478
|
+
- “Decode this VIN off the fleet vehicle — what telematics head-unit ships in that trim?”
|
|
479
|
+
- “FCC ID `2ABIP-…` on the IoT doorbell — pull the internal photos and RF test report.”
|
|
480
|
+
- “MAC OUI `AC:DE:48` on the rogue AP — which vendor, and do they have default creds?”
|
|
481
|
+
- “Any prior litigation or SEC 8-K breach filings for `Target Corp` before we disclose?”
|
|
482
|
+
- “Wayback the old `/admin` path — did an earlier deploy expose a debug console?”
|
|
483
|
+
- “Pivot `@lead-dev` across GitHub/GitLab — hardcoded secrets in personal repos?”
|
|
479
484
|
|
|
480
|
-
### Serial sense organ (`extro_serial`)
|
|
485
|
+
### Serial / hardware sense organ (`extro_serial`)
|
|
481
486
|
|
|
482
|
-
- “What
|
|
483
|
-
- “Send
|
|
484
|
-
- “
|
|
485
|
-
- “Probe the
|
|
487
|
+
- “What just enumerated on `/dev/ttyUSB*` when I plugged in the router’s UART header?”
|
|
488
|
+
- “Send `AT+GMR` to the ESP32 on `/dev/ttyUSB0` — firmware version and SDK build?”
|
|
489
|
+
- “Dump the boot banner at 115200 8N1 — does it drop to an unauthenticated U-Boot shell?”
|
|
490
|
+
- “Probe the Flipper on `ttyACM0` and pull the last captured Sub-GHz raw.”
|
|
491
|
+
- “Talk to the smart-lock’s BLE-UART bridge and echo back whatever it volunteers.”
|
|
486
492
|
|
|
487
|
-
### Telecomm sense organ (`extro_telecomm`)
|
|
493
|
+
### Telecomm / VoIP sense organ (`extro_telecomm`)
|
|
488
494
|
|
|
489
|
-
- “Is BareSIP
|
|
490
|
-
- “
|
|
491
|
-
- “Dial sip:
|
|
492
|
-
- “Hang up the
|
|
495
|
+
- “Is BareSIP registered to the client’s PBX, and what codecs did it negotiate?”
|
|
496
|
+
- “Enumerate SIP `OPTIONS` against the exposed SBC — does it leak `User-Agent`/version?”
|
|
497
|
+
- “Dial the IVR at `sip:ivr@target` and record the prompt tree for the social-eng playbook.” *(OPSEC: real call)*
|
|
498
|
+
- “Hang up and note whether the PBX exposed internal extension ranges in the `BYE`.”
|
|
493
499
|
|
|
494
500
|
### Packet sense organ (`extro_packet`)
|
|
495
501
|
|
|
496
|
-
- “
|
|
497
|
-
- “
|
|
498
|
-
- “
|
|
499
|
-
- “
|
|
502
|
+
- “Capture 30 s on `eth0` while I trigger the IoT hub — what does it phone home to?”
|
|
503
|
+
- “Summarise `/tmp/eng.pcap` — top talkers, cleartext creds, weird ports.”
|
|
504
|
+
- “BPF `udp port 5353` — is mDNS leaking hostnames and service records on the guest VLAN?”
|
|
505
|
+
- “Grab 50 packets of the OT segment — Modbus/TCP or something proprietary?”
|
|
506
|
+
- “Do we see the camera’s RTSP creds in the clear during that capture?”
|
|
500
507
|
|
|
501
508
|
### Vision / OCR sense organ (`extro_vision`)
|
|
502
509
|
|
|
503
|
-
- “OCR
|
|
504
|
-
- “Decode the QR
|
|
505
|
-
- “
|
|
510
|
+
- “OCR the photo of the switch label — model, firmware, and default-cred sticker.”
|
|
511
|
+
- “Decode the QR on the badge printer — is that a provisioning URL with an embedded token?”
|
|
512
|
+
- “OCR the BIOS/BMC screenshot and pull the exact firmware build for CVE matching.”
|
|
513
|
+
- “Read the barcode on the HSM — serial + part number for supply-chain lookup.”
|
|
506
514
|
|
|
507
515
|
### Voice sense organ (`extro_voice`)
|
|
508
516
|
|
|
509
|
-
- “
|
|
510
|
-
- “
|
|
511
|
-
- “
|
|
517
|
+
- “Transcribe `/tmp/voicemail.wav` — did the helpdesk leak the temp-password format?”
|
|
518
|
+
- “STT the recorded IVR tree so we can grep it for extension numbers.”
|
|
519
|
+
- “TTS this vishing pretext to a `.wav` for the approved social-engineering call.”
|
|
520
|
+
- “Which STT/TTS engines are installed — can we run whisper offline on the drop box?”
|
|
512
521
|
|
|
513
522
|
### Fact-check / claim verification (`extro_verify`)
|
|
514
523
|
|
|
515
|
-
- “
|
|
516
|
-
- “Confirm the latest
|
|
517
|
-
- “
|
|
518
|
-
- “
|
|
519
|
-
- “
|
|
524
|
+
- “Before I file this: does CVE-2024-3094 actually list our target’s distro package as affected?”
|
|
525
|
+
- “Confirm the latest upstream OpenSSH is 9.x — is the target’s 8.2p1 genuinely EOL?”
|
|
526
|
+
- “Verify the vendor advisory URL really says ‘remote unauthenticated’ — quote it back.”
|
|
527
|
+
- “Is `pwn` on RubyGems still at the version we ship in the report appendix?”
|
|
528
|
+
- “Fact-check my claim that this library has no maintained fork — search says otherwise?”
|
|
520
529
|
|
|
521
530
|
### Threat intel (`extro_intel` ± `record:true`)
|
|
522
531
|
|
|
523
|
-
- “Any
|
|
524
|
-
- “
|
|
525
|
-
- “
|
|
526
|
-
- “
|
|
527
|
-
- “
|
|
532
|
+
- “Any public PoC or Exploit-DB entry for the exact `nginx 1.25.3` build we bannered?”
|
|
533
|
+
- “Pull NVD + CIRCL for `libwebp` since 2023 — which are pre-auth RCE vs local?”
|
|
534
|
+
- “Cross-ref this router’s firmware components against known-exploited (KEV).”
|
|
535
|
+
- “What’s the newest CVE touching `Fortinet FortiOS` and is there an exploit module yet?”
|
|
536
|
+
- “Record everything for `Apache Struts` so `extro_correlate` can match our target stack.”
|
|
528
537
|
|
|
529
538
|
### Host / env / toolchain drift (`extro_snapshot`, `extro_drift`, `extro_stats`)
|
|
530
539
|
|
|
531
|
-
- “
|
|
532
|
-
- “
|
|
533
|
-
- “
|
|
534
|
-
- “
|
|
535
|
-
- “Show
|
|
536
|
-
- “Why did that tool start failing — world drift or operator error?” → pairs with `extro_correlate`
|
|
540
|
+
- “Snapshot the drop box before we start — I want a defensible ‘this is what we brought’ baseline.”
|
|
541
|
+
- “Did anything on this attack host change overnight (kernel, nmap, listening ports)?”
|
|
542
|
+
- “Which offensive bins are actually present in PATH on this jump host?”
|
|
543
|
+
- “Is the SDR / HackRF still attached, or did the USB hub flake again?”
|
|
544
|
+
- “Show repo HEAD + dirty state so the finding is reproducible from a commit hash.”
|
|
537
545
|
|
|
538
546
|
### Recon memory / observations (`extro_observe`, `extro_observations`)
|
|
539
547
|
|
|
540
|
-
- “Remember
|
|
541
|
-
- “
|
|
542
|
-
- “
|
|
543
|
-
- “
|
|
544
|
-
- “
|
|
548
|
+
- “Remember: `10.0.0.5:8443` self-signed CN leaks internal AD domain — tag `recon,pivot`.”
|
|
549
|
+
- “Log the RF finding: 433.92 MHz fixed-code, 24-bit, replayable — tag `rf,physical`.”
|
|
550
|
+
- “What have we already observed about `*.target.tld` this engagement?”
|
|
551
|
+
- “List every `:intel` observation still fresh so I don’t re-run the same CVE queries.”
|
|
552
|
+
- “Which `:web` watches flipped `changed:true` this week — silent patch candidates?”
|
|
545
553
|
|
|
546
|
-
### Correlation
|
|
554
|
+
### Correlation — “am I wrong or did the world move?” (`extro_correlate`)
|
|
547
555
|
|
|
548
|
-
- “
|
|
549
|
-
- “
|
|
550
|
-
- “
|
|
551
|
-
- “
|
|
556
|
+
- “My exploit stopped landing — did the target’s DOM/TLS drift or did I break the payload?”
|
|
557
|
+
- “Cross recorded CVE intel against the versions we actually bannered on scope hosts.”
|
|
558
|
+
- “Are any of my `PWN::Memory` facts about this target now refuted by fresh `extro_verify` runs?”
|
|
559
|
+
- “Do the `nmap`/`msf` failures line up with a toolchain upgrade rather than operator error?”
|
|
560
|
+
- “Which watched anchors went unreachable — down-weight intel sourced from them.”
|
|
552
561
|
|
|
553
562
|
### Operational / lifecycle
|
|
554
563
|
|
|
555
|
-
- “
|
|
556
|
-
- “
|
|
557
|
-
- “How stale is
|
|
558
|
-
- “
|
|
564
|
+
- “New engagement, new client — wipe extrospection so old recon doesn’t bleed into this report.” *(destructive)*
|
|
565
|
+
- “Turn ambient auto-extrospect **off** while I fuzz — I don’t want baseline noise per turn.”
|
|
566
|
+
- “How stale is our world snapshot — is it still from the pre-patch window?”
|
|
567
|
+
- “Re-enable auto-extrospect for the wrap-up so drift is captured in the final deliverable.”
|
|
559
568
|
|
|
560
|
-
### Short
|
|
569
|
+
### Short trigger patterns the agent should recognise
|
|
561
570
|
|
|
562
571
|
| Pattern | Likely tools |
|
|
563
|
-
|
|
564
|
-
| “
|
|
565
|
-
| “
|
|
566
|
-
| “
|
|
567
|
-
| “SIP /
|
|
568
|
-
| “
|
|
569
|
-
| “OCR /
|
|
570
|
-
| “
|
|
571
|
-
| “
|
|
572
|
-
| “
|
|
573
|
-
| “
|
|
574
|
-
| “
|
|
575
|
-
| “
|
|
576
|
-
| “
|
|
577
|
-
| “
|
|
572
|
+
|---|---|
|
|
573
|
+
| “tune / MHz / FM / RDS / ISM / key-fob / pager / ADS-B” | `extro_rf_tune` |
|
|
574
|
+
| “subdomain / CT log / ASN / whois / FCC ID / VIN / MAC OUI / EPSS / KEV / Wayback / pivot @user” | `extro_osint` |
|
|
575
|
+
| “UART / ttyUSB / U-Boot / AT command / Flipper / JTAG banner” | `extro_serial` |
|
|
576
|
+
| “SIP / PBX / IVR / BareSIP / dial / hangup” | `extro_telecomm` |
|
|
577
|
+
| “capture on iface / summarise pcap / mDNS / Modbus / RTSP creds” | `extro_packet` |
|
|
578
|
+
| “OCR sticker / decode QR / read badge / BIOS screenshot” | `extro_vision` |
|
|
579
|
+
| “transcribe wav / TTS pretext / whisper offline” | `extro_voice` |
|
|
580
|
+
| “watch URL / did the page change / silent patch / scope updated / TLS rotated” | `extro_watch` |
|
|
581
|
+
| “is it true that / confirm CVE / verify advisory / latest version of” | `extro_verify` |
|
|
582
|
+
| “known exploits for / any PoC / CVEs affecting / KEV for” | `extro_intel` |
|
|
583
|
+
| “what changed on this host / baseline the box / SDR still attached” | `extro_snapshot` + `extro_drift` |
|
|
584
|
+
| “remember this finding / what did we observe about / tag it recon” | `extro_observe` / `extro_observations` |
|
|
585
|
+
| “why did X stop working / my fault or theirs / down-weight that source” | `extro_correlate` |
|
|
586
|
+
| “new engagement clean slate / stop baselining while I fuzz” | `extro_reset` / `extro_auto_toggle` |
|
|
578
587
|
|
|
579
588
|
The **inward** half of the loop (Memory · Skills · Learning · Mistakes · Metrics)
|
|
580
|
-
has a matching example
|
|
589
|
+
has a matching example catalogue in
|
|
590
|
+
[Skills, Memory & Learning](Skills-Memory-Learning.md#example-questions-that-trigger-introspection).
|
|
581
591
|
|
|
582
592
|
**See also:** [Skills, Memory & Learning](Skills-Memory-Learning.md) ·
|
|
583
593
|
[Mistakes](Mistakes.md) · [SDR](SDR.md) · [Transparent Browser](Transparent-Browser.md) · [Cron](Cron.md) · [pwn-ai Agent](pwn-ai-Agent.md)
|
data/documentation/FFI.md
CHANGED
|
@@ -12,6 +12,16 @@ PWN::FFI.backends
|
|
|
12
12
|
PWN::FFI.available?(mod: :Volk) # => true/false
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
+
## Install the shared objects
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
pwn setup --profile sdr # rtl-sdr · hackrf · SoapySDR · libsndfile · libusb · ffi headers
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
`pwn setup` (the [doctor](Installation.md)) reports each `PWN::FFI` backend
|
|
22
|
+
as `ok` / `MISSING` and knows the correct package name on `apt` / `dnf` /
|
|
23
|
+
`pacman` / `brew` / `port`.
|
|
24
|
+
|
|
15
25
|
## Modules (`lib/pwn/ffi/*.rb`)
|
|
16
26
|
|
|
17
27
|
| Module | Shared object | Role |
|
|
@@ -29,8 +39,10 @@ PWN::FFI.available?(mod: :Volk) # => true/false
|
|
|
29
39
|
1. **Thin & optional.** Attach a minimal surface; prefer high-level Ruby wrappers
|
|
30
40
|
(`Liquid.freq_demod`, `Volk.unpack_s16le`) over raw C pointers in call sites.
|
|
31
41
|
2. **No install-time compile.** Use the system package (`libvolk-dev`,
|
|
32
|
-
`libliquid-dev`, `libfftw3-dev`, `libhackrf-dev`, …).
|
|
33
|
-
|
|
42
|
+
`libliquid-dev`, `libfftw3-dev`, `libhackrf-dev`, …). Install them all
|
|
43
|
+
with **`pwn setup --profile sdr`** (see [Installation](Installation.md)).
|
|
44
|
+
On hosts without them every `.available?` is `false` and pure-Ruby paths
|
|
45
|
+
keep working.
|
|
34
46
|
3. **Namespace hygiene.** `PubFFI = ::FFI` (defined once in `lib/pwn/ffi.rb`)
|
|
35
47
|
avoids the `PWN::FFI` ↔ `::FFI` collision when modules `extend PubFFI::Library`.
|
|
36
48
|
4. **Fallbacks in DSP.** `PWN::SDR::Decoder::DSP` probes `PWN::FFI.available?`
|
data/documentation/Fuzzing.md
CHANGED
|
@@ -8,12 +8,23 @@ $ pwn --ai "scan 10.0.0.0/24 with NmapIt and summarise open services"
|
|
|
8
8
|
$ pwn_nmap_discover_tcp_udp -t 10.0.0.0/24 -o out/ # headless driver
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Check / provision this host
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
$ pwn setup # doctor: which PWN:: capabilities are usable here?
|
|
15
|
+
$ pwn setup --profile web # install what TransparentBrowser / Burp / ZAP need
|
|
16
|
+
$ pwn setup --list-profiles # core · ai · web · net · db · sdr · vision · voice · exploit · hardware · full
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
See [Installation](Installation.md) for every flag and the `PWN::Setup` API.
|
|
20
|
+
|
|
11
21
|
## Inside the REPL
|
|
12
22
|
|
|
13
23
|
```ruby
|
|
14
24
|
PWN.help # top-level help
|
|
15
25
|
PWN::Plugins.constants.sort # list all 66 plugins
|
|
16
26
|
PWN::Plugins::NmapIt.help # per-plugin usage
|
|
27
|
+
PWN::Setup.check # capability doctor from inside the REPL
|
|
17
28
|
ls PWN::Plugins::BurpSuite # Pry: list methods
|
|
18
29
|
show-source PWN::SAST::SQL.scan # Pry: read the code
|
|
19
30
|
history # what you've typed → copy into a driver
|
|
@@ -25,6 +36,7 @@ history # what you've typed → copy into a driver
|
|
|
25
36
|
|---|---|
|
|
26
37
|
| `pwn-ai` | Enter the agent TUI (SHIFT+ENTER = newline, ENTER = submit) |
|
|
27
38
|
| `pwn-asm` | Multi-line assembly ↔ opcode workbench |
|
|
39
|
+
| `pwn-vault` | Decrypt → edit `~/.pwn/pwn.yaml` in `$EDITOR` → re-encrypt |
|
|
28
40
|
| `pwn-ai-memory` | Inspect / edit `~/.pwn/memory.json` |
|
|
29
41
|
| `pwn-ai-sessions` | List / view / delete transcripts |
|
|
30
42
|
| `pwn-ai-cron` | List / run scheduled jobs |
|
data/documentation/Hardware.md
CHANGED
|
@@ -3,6 +3,10 @@
|
|
|
3
3
|

|
|
4
4
|

|
|
5
5
|
|
|
6
|
+
> **Install:** `pwn setup --profile hardware` — libusb · adb · baresip
|
|
7
|
+
> (Serial · BusPirate · Android · BareSIP · `extro_serial` ·
|
|
8
|
+
> `extro_telecomm`). See [Installation](Installation.md).
|
|
9
|
+
|
|
6
10
|
## Serial / Bus
|
|
7
11
|
|
|
8
12
|
| Module | Use |
|
data/documentation/Home.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **PWN** (/pōn/) — an open-source offensive-security automation framework and
|
|
4
4
|
> continuous-security-integration platform written in Ruby.
|
|
5
|
-
> 66 plugins · 48 SAST rules · 90 AWS wrappers · 21 WWW drivers ·
|
|
5
|
+
> 66 plugins · 48 SAST rules · 90 AWS wrappers · 21 WWW drivers · 53 CLI
|
|
6
6
|
> drivers · 5 LLM engines · a self-improving multi-agent AI · one REPL.
|
|
7
7
|
|
|
8
8
|
**Repo root:** `/opt/pwn` · **This wiki:** `/opt/pwn/documentation/` ·
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
| [What is PWN](What-is-PWN.md) | One-paragraph elevator pitch |
|
|
18
18
|
| [Why PWN](Why-PWN.md) | Design philosophy — why another framework |
|
|
19
19
|
| [How PWN Works](How-PWN-Works.md) | The five layers, with the architecture diagram |
|
|
20
|
-
| [Installation](Installation.md) |
|
|
20
|
+
| [Installation](Installation.md) | `gem install pwn` → `pwn setup` doctor/provisioner · capability profiles |
|
|
21
21
|
| [General Usage](General-PWN-Usage.md) | Day-one cheat sheet |
|
|
22
|
-
| [Configuration](Configuration.md) | `~/.pwn/
|
|
22
|
+
| [Configuration](Configuration.md) | `~/.pwn/pwn.yaml` (encrypted) — engines, keys, agent options · `pwn-vault` |
|
|
23
23
|
| **[All Data-Flow Diagrams](Diagrams.md)** | **27 SVGs** in one scrollable page |
|
|
24
24
|
|
|
25
25
|
## 🚪 Entry Points
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
|---|---|
|
|
29
29
|
| [The `pwn` REPL](pwn-REPL.md) | Pry shell with the whole `PWN::` namespace pre-loaded |
|
|
30
30
|
| [`pwn-ai` Autonomous Agent](pwn-ai-Agent.md) | Natural-language TUI + `pwn --ai PROMPT` one-shot |
|
|
31
|
-
| [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) |
|
|
31
|
+
| [CLI Drivers `bin/pwn_*`](CLI-Drivers.md) | 53 headless executables for CI/CD |
|
|
32
32
|
| [Drivers (build your own)](Drivers.md) | Turn a REPL session into a shipped binary |
|
|
33
33
|
|
|
34
34
|
## 🤖 AI Subsystem (`PWN::AI`)
|
|
@@ -19,7 +19,8 @@ hardware).
|
|
|
19
19
|
| `pwn` REPL | `lib/pwn/plugins/repl.rb` | Pry with `PWN::` pre-loaded + custom commands |
|
|
20
20
|
| `pwn-ai` | `lib/pwn/ai/agent/loop.rb` | Agent TUI inside the REPL |
|
|
21
21
|
| `pwn --ai PROMPT` | `bin/pwn` | Headless one-shot agent (CI-friendly) |
|
|
22
|
-
| `
|
|
22
|
+
| `pwn setup` | `lib/pwn/setup.rb` · `bin/pwn_setup` | Post-install doctor + capability provisioner (also `pwn --setup[=PROFILE]`) |
|
|
23
|
+
| `bin/pwn_*` | 53 files | Thin OptionParser wrappers over one plugin each |
|
|
23
24
|
| `PWN::Cron` | `lib/pwn/cron.rb` | Scheduled jobs → any of the above |
|
|
24
25
|
|
|
25
26
|
## L2 — AI agent core (`lib/pwn/ai/agent/`)
|