pwn 0.5.749 → 0.5.750

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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -2
  3. data/documentation/Blockchain.md +107 -9
  4. data/documentation/pwn-ai-Agent.md +257 -4
  5. data/documentation/pwn_silent_help_learn_demo.gif +0 -0
  6. data/etc/default_skills/pwn/banner/SKILL.md +5 -3
  7. data/etc/default_skills/pwn/blockchain/btc/SKILL.md +8 -5
  8. data/etc/default_skills/pwn/blockchain/eth/SKILL.md +12 -3
  9. data/etc/default_skills/pwn/blockchain/eth/references/urls.md +1 -1
  10. data/etc/default_skills/pwn/plugins/repl/SKILL.md +4 -0
  11. data/etc/default_skills/pwn/plugins/repl/ai/SKILL.md +4 -0
  12. data/etc/default_skills/pwn/plugins/repl/ai/references/urls.md +5 -0
  13. data/etc/default_skills/pwn/plugins/repl/ai_console/SKILL.md +48 -0
  14. data/etc/default_skills/pwn/plugins/repl/ai_console_commands/SKILL.md +47 -0
  15. data/etc/default_skills/pwn/plugins/repl/ai_console_usage/SKILL.md +48 -0
  16. data/etc/default_skills/pwn/plugins/repl/ai_swarm/SKILL.md +46 -0
  17. data/lib/pwn/ai/agent/loop.rb +287 -18
  18. data/lib/pwn/ai/agent/swarm.rb +28 -4
  19. data/lib/pwn/ai/open_ai.rb +4 -2
  20. data/lib/pwn/banner.rb +125 -2
  21. data/lib/pwn/blockchain/btc.rb +494 -196
  22. data/lib/pwn/blockchain/eth.rb +440 -81
  23. data/lib/pwn/blockchain.rb +6 -0
  24. data/lib/pwn/config.rb +22 -0
  25. data/lib/pwn/migrate.rb +9 -1
  26. data/lib/pwn/plugins/repl/ai.rb +142 -7
  27. data/lib/pwn/plugins/repl/ai_console.rb +1450 -0
  28. data/lib/pwn/plugins/repl/ai_console_commands.rb +282 -0
  29. data/lib/pwn/plugins/repl/ai_console_usage.rb +144 -0
  30. data/lib/pwn/plugins/repl/ai_swarm.rb +375 -0
  31. data/lib/pwn/plugins/repl.rb +25 -3
  32. data/lib/pwn/version.rb +1 -1
  33. data/spec/lib/pwn/ai/agent/loop_spec.rb +258 -1
  34. data/spec/lib/pwn/ai/agent/turn_finalizer_spec.rb +3 -2
  35. data/spec/lib/pwn/ai/open_ai_spec.rb +5 -0
  36. data/spec/lib/pwn/banner_spec.rb +124 -0
  37. data/spec/lib/pwn/blockchain/btc_spec.rb +372 -1
  38. data/spec/lib/pwn/blockchain/eth_spec.rb +205 -0
  39. data/spec/lib/pwn/blockchain_spec.rb +6 -0
  40. data/spec/lib/pwn/config_spec.rb +10 -0
  41. data/spec/lib/pwn/migrate_spec.rb +40 -3
  42. data/spec/lib/pwn/plugins/repl/ai_console_commands_spec.rb +63 -0
  43. data/spec/lib/pwn/plugins/repl/ai_console_spec.rb +1066 -0
  44. data/spec/lib/pwn/plugins/repl/ai_console_usage_spec.rb +29 -0
  45. data/spec/lib/pwn/plugins/repl/ai_swarm_spec.rb +127 -0
  46. data/spec/lib/pwn/plugins/repl_pwn_vault_spec.rb +5 -3
  47. data/spec/lib/pwn/plugins/repl_spec.rb +109 -0
  48. data/third_party/pwn_rdoc.jsonl +203 -10
  49. metadata +18 -6
  50. data/etc/default_skills/pwn/blockchain/btc/references/urls.md +0 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bf86add502082e14d3299544ffc90b9e86887ada46569fa867d9ce6e0cc8560a
4
- data.tar.gz: bb266bdff59a1187f99664eb876dc6b591a43d4f725689025e8af2325b735c00
3
+ metadata.gz: 60cc9203ea107c4633ec8e0a2ec550fbd4c667c3e8557e8dff360306f786843c
4
+ data.tar.gz: 637c33f3923027a6d7fbb4fa392e7bee5f56cf2c827fb49bdf5869c64e368c3b
5
5
  SHA512:
6
- metadata.gz: b5191f1ecd9004cd4152ead0630c3c91df671ecb6f1f7b1c801a8a9983b6d919734b4006dca79740b9dc5be7181880ac5cddd219d343478a4c5cb66c86bad741
7
- data.tar.gz: 8ef2550a781242412f81402b29fa5257fcf404fe5a97facd8126544aabe651cd4e26d008cf92bb040b8d675985943a06cac1800a88eb85b2b3c35bb3f79c4692
6
+ metadata.gz: 608fc78a170ce6fd0c3eb52d41f40c3452fa01b839f9b34f38d42fa65810fdf74954c76c732ae207aa3085522eb42be0af95cd574c9bd96f73e4d53451846bda
7
+ data.tar.gz: 95549917463adc3b7ac81571915976ed00adc28a6cfafd01e9eefa1ee466be906f07c8a9176d5e058d63597fd40c9a51beded438621fe7e8d1e4575a386d2ba0
data/Gemfile CHANGED
@@ -49,7 +49,7 @@ gem 'jwt', '3.3.0'
49
49
  gem 'libusb', '0.8.0'
50
50
  gem 'luhn', '3.0.0'
51
51
  gem 'mail', '2.9.1'
52
- gem 'mcp', '1.6.0'
52
+ gem 'mcp', '1.6.1'
53
53
  gem 'meshtastic', '0.0.186'
54
54
  gem 'metasm', '1.0.6'
55
55
  gem 'mongo', '2.26.0'
@@ -77,7 +77,7 @@ gem 'rbvmomi2', '3.10.0'
77
77
  gem 'rdoc', '7.0.4'
78
78
  gem 'rest-client', '2.1.0'
79
79
  gem 'rex', '2.0.13'
80
- gem 'rmagick', '7.1.5'
80
+ gem 'rmagick', '7.1.6'
81
81
  gem 'rqrcode', '3.2.0'
82
82
  gem 'rspec', '3.13.2'
83
83
  gem 'rtesseract', '3.1.4'
@@ -1,18 +1,116 @@
1
- # `PWN::Blockchain` - BTC · ETH
1
+ # `PWN::Blockchain` — read-only blockchain intelligence
2
2
 
3
- Lightweight helpers for on-chain recon and wallet interaction.
4
- Source: `lib/pwn/blockchain/*.rb`.
3
+ Source: `lib/pwn/blockchain/{btc,eth}.rb`. Use each module's `.help` for exact options.
4
+ These modules do not manage keys, sign, broadcast transactions, or modify wallets.
5
+ They report on-chain observations, not real-world identity, ownership, or criminality.
5
6
 
6
- | Module | Purpose |
7
+ ## Assessment and changes
8
+
9
+ Previously, BTC offered chain status, block lookup and an unbounded date-to-transaction-ID
10
+ scan. Its chain status lookup also invoked AI and printed the result. The date scan
11
+ binary-searched block timestamps even though those timestamps are not monotonic.
12
+ ETH offered only two BlockCypher lookups. Both transports disabled TLS verification;
13
+ tests checked only that help/authors existed. Earlier versions of this document
14
+ incorrectly advertised balance, broadcast, and key-management APIs.
15
+
16
+ Both modules now provide structured, read-only intelligence with validated inputs,
17
+ verified HTTPS, request timeouts, credential-safe errors and deterministic tests.
18
+ BTC no longer invokes AI implicitly. `PWN::AI::Agent::BTC` remains a separate,
19
+ explicit analysis interface; its prose is not independent blockchain evidence.
20
+
21
+ ## Bitcoin Core
22
+
23
+ BTC uses the existing `PWN::Env[:plugins][:blockchain][:bitcoin]` settings:
24
+ `rpc_host`, `rpc_port`, `rpc_user`, and `rpc_pass`. Optional `rpc_scheme: 'https'`
25
+ enables verified TLS; the existing HTTP default is retained. Use a trusted local
26
+ connection or protected tunnel for HTTP. No prompts or configuration writes occur.
27
+
28
+ | API | Evidence returned |
7
29
  |---|---|
8
- | `PWN::Blockchain::BTC` | Address balance/UTXO lookup, tx broadcast, key helpers |
9
- | `PWN::Blockchain::ETH` | Address balance, contract call, event log query |
30
+ | `get_latest_block` | Backward-compatible JSON-RPC chain-status envelope, without stdout or AI |
31
+ | `chain_status` | Chain identity, synchronization, tip and pruning status |
32
+ | `get_block_details` | Block at an explicit height or tip, verbosity 0–3 |
33
+ | `inspect_transaction` | Input/output references, exact integer satoshis, fees only with complete prevouts |
34
+ | `inspect_outpoint` | Current UTXO evidence; null means spent **or unknown**, not proof of spending |
35
+ | `mempool_summary` | Aggregate node-local mempool statistics |
36
+ | `trace_transaction` | Bounded ancestor graph of actual input references, missing evidence and truncation reasons |
37
+ | `scan_transactions` | Paginated explicit-height scan filtered by inclusive UTC header dates |
38
+ | `get_transactions` | Legacy transaction-ID array, only for a complete explicitly bounded scan |
39
+ | `scan_address_activity` | Script-matched received/spent outputs within explicit block heights |
40
+
41
+ ```ruby
42
+ btc = PWN::Blockchain::BTC
43
+ tip = btc.chain_status[:blocks]
44
+ block = btc.get_block_details(height: tip - 6, verbosity: 1)
45
+ tx = btc.inspect_transaction(txid: block[:tx].first, blockhash: block[:hash])
46
+ graph = btc.trace_transaction(txid: tx[:txid], blockhash: block[:hash],
47
+ max_depth: 2, max_transactions: 20, max_edges: 100)
48
+ page = btc.scan_transactions(from: '2009-01-12', to: '2009-01-12',
49
+ start_height: 160, end_height: 180, max_blocks: 10)
50
+ # Resume with start_height: page[:next_height]; keep end_height fixed.
51
+ ```
10
52
 
11
- Also exposed to the agent via `PWN::AI::Agent::BTC` for wallet-aware prompts.
53
+ Migration: `get_transactions(from:, to:)` now also requires `start_height:` and
54
+ `end_height:`. It raises rather than return a silently partial array. For larger
55
+ ranges use `scan_transactions` and inspect `next_height`, `complete`,
56
+ `missing_blocks`, `reorg_detected` and `anchor`. Dates use UTC block-header times,
57
+ not a guaranteed real-world transaction time. Every selected height is examined.
58
+
59
+ Historical transaction retrieval may require `txindex`; supplying `blockhash`
60
+ helps locate the root transaction but does not locate all its ancestors.
61
+ Pruning, absent undo data and lookup budgets can leave evidence incomplete.
62
+ Address activity is not an address index or a historical/current balance service.
63
+ Ancestor edges prove spending references, not ownership, change, or how mixed
64
+ input value is allocated to outputs. Completeness is limited to the requested
65
+ range or traversal. Scans detect some reorgs, but are not atomic snapshots;
66
+ compare anchors across pages and restart if they change.
67
+
68
+ ## Ethereum
69
+
70
+ New RPC APIs take an explicit `rpc_url:`; no persistent configuration is required.
71
+ URLs with embedded userinfo are rejected. Endpoint credentials in paths/query
72
+ strings are not included in module errors. Use HTTPS for remote endpoints.
73
+ Existing `get_latest_block(token:)` and `get_block_details(height:, token:)`
74
+ continue to use BlockCypher; they are separate from the JSON-RPC APIs below.
75
+
76
+ | API | Evidence returned |
77
+ |---|---|
78
+ | `chain_status` | Chain ID, head height, sync state |
79
+ | `block` | Block by number, hash or tag; optional full transactions |
80
+ | `transaction` | Transaction/receipt consistency, pending/success/reverted state, exact wei and gas fees, creation evidence |
81
+ | `account` | Balance, nonce and bytecode pinned to one block hash |
82
+ | `address_activity` | Bounded, whole-block pagination of top-level from/to transactions |
83
+ | `event_logs` | Bounded event query with validated Transfer layouts and explicit provider-completeness caveat |
84
+ | `decode_transfer` | Standard ERC20/ERC721 Transfer layout decoding, not proof of contract conformance |
85
+ | `call` | Read-only ABI-encoded `eth_call`, pinned to a canonical block |
86
+ | `token_metadata` | Optional name, symbol, decimals and total supply, with unavailable ABI fields identified |
12
87
 
13
88
  ```ruby
14
- PWN::Blockchain::BTC.balance(address: 'bc1q...')
15
- PWN::Blockchain::ETH.call(contract: '0x...', method: 'owner()')
89
+ eth = PWN::Blockchain::ETH
90
+ rpc = { rpc_url: 'https://YOUR_ETHEREUM_RPC_ENDPOINT' }
91
+ status = eth.chain_status(rpc)
92
+ block = eth.block(rpc.merge(block: 'finalized', full_transactions: true))[:block]
93
+ tx = eth.transaction(rpc.merge(hash: block[:transactions].first[:hash]))
94
+ state = eth.account(rpc.merge(address: tx[:transaction][:from], block: block[:hash]))
16
95
  ```
17
96
 
97
+ Pinned account/call/metadata reads require EIP-1898 support. Address scans cover
98
+ top-level transactions, not internal calls, token events, or a full account history;
99
+ their pages are not reorg-safe. Event queries cannot independently establish that
100
+ a provider returned every log, and report `provider_completeness: :unverified`.
101
+ ERC1155 events are not labeled ERC20/ERC721. Token names and event layouts do not
102
+ prove token legitimacy or standards conformance. Fees include execution and blob
103
+ components when supplied, not chain-specific L2 surcharges. Optional metadata RPC
104
+ failures propagate; malformed/unsupported returned ABI layouts are marked unavailable.
105
+
106
+ ## Verification
107
+
108
+ Default specs use deterministic transport fixtures and need no live credentials.
109
+ Read-only live checks also exercised BTC chain/block/transaction/ancestor/UTXO/date/
110
+ address/mempool paths against the configured unpruned mainnet node, and Ethereum
111
+ chain/block/receipt/pinned-account/activity/Transfer-log/USDC-metadata paths against
112
+ a public mainnet RPC. These checks establish those observed paths, not universal
113
+ provider compatibility or complete attribution. Never put RPC credentials in
114
+ fixtures, documentation, logs, or generated skills.
115
+
18
116
  [← Home](Home.md)
@@ -10,11 +10,151 @@ so it doesn't repeat it**.
10
10
  ## Two ways to run it
11
11
 
12
12
  ```text
13
- # 1. Interactive TUI (inside the pwn REPL)
13
+ # 1. Interactive curses console (inside the pwn REPL)
14
14
  pwn[CURRENT_VERSION]:001 >>> pwn-ai
15
- ✨ pwn-ai · anthropic · session 20260707_225041_d7f2f3bb
16
- > Use NmapIt to sweep 10.0.0.0/24, then TransparentBrowser via Burp on any
17
- host with 443 open, active-scan, and give me a Reports::SAST summary.
15
+ # Or launch directly from the shell:
16
+ pwn-ai
17
+ ```
18
+
19
+ The interactive default is a single-owner curses screen: a provider/model
20
+ and session header, scrollable typed timeline (OPERATOR, TASK, TOOL, RESULT,
21
+ ASSISTANT and WARNING), a persistent multiline composer, and an operational
22
+ sidebar at 100 columns or wider. Narrower screens give the timeline the full width.
23
+ At 100 columns × 26 rows or larger, the header may carve out a bordered retro-game
24
+ ASCII animation on the left (Tetris, Snake, Pong and other 8-bit-style scenes).
25
+ Its framed width in terminal cells equals the complete header's height in rows;
26
+ the interior canvas is `(header height - 2)` cells on each side. This is a
27
+ cell-square, not a pixel-square—terminal glyph cells are usually taller than wide.
28
+ When that interior exceeds the artwork API's 16-cell limit, the complete game
29
+ art is centered and padded inside the larger square rather than clipped or stretched.
30
+ One `PWN::Banner.mini_names` animation is randomly
31
+ selected for the session and retained across redraws, model changes and resize;
32
+ changing the active session selects again. Frames advance at the banner API's
33
+ `MINI_FRAME_SECONDS` cadence using monotonic time in the existing render loop—no extra animation
34
+ thread, input reader or provider call. This is decoration, not progress or
35
+ telemetry. The pane uses the existing border/title/header theme roles. Settings
36
+ wrap in the right-hand region without losing their label colors. A bounded,
37
+ nonrecursive layout pass grows the header and square together. If the terminal
38
+ is narrow/short, or that reduced width would clip any setting, the decoration
39
+ disappears and settings reclaim the full width.
40
+
41
+ Timestamped entries (`%Y-%m-%d %H:%M:%S%z`), measured request elapsed
42
+ time, completed-tool/event counts, and the last observed tool provide operational
43
+ context. There are no estimated progress bars. Running
44
+ status reflects the request's actual model/tool boundary. Borders are black; the OPERATOR
45
+ label, warnings, and the mission prompt are red. Pane titles (`pwn-ai vN`, `SESSION`,
46
+ `OPERATIONS`, `MISSION`) use `title`, which defaults to red and is separate from
47
+ `border`. The operator's request text is
48
+ white. The header grows to show all wrapped settings without shortening or
49
+ replacing their text. Only when the terminal cannot fit the full header plus
50
+ a one-row timeline, composer and footer does it limit the visible rows; its
51
+ title then points to Ctrl+O (or `/status`) for the complete scrollable settings.
52
+ State remains visible at every supported size. Header setting labels use the
53
+ same `category` color as OPERATIONS labels, including across wrapped lines;
54
+ their values retain the `header` color in both the header and details view.
55
+ Use PgUp/PgDn, arrows or Home/End there; Esc or Ctrl+O restores the unchanged
56
+ draft. The short sidebar prioritizes elapsed time, tools, tokens, cost and last
57
+ tool; Ctrl+O exposes the remaining details even without a sidebar.
58
+ Assistant text is white, tasks green, tools and notices cyan, and results yellow.
59
+ Operations category labels are yellow. Those colors are the default
60
+ `ai.tui.theme` in `~/.pwn/pwn.yaml` (`PWN::Env[:ai][:tui][:theme]`). Named curses
61
+ colors (`black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`)
62
+ may replace any role; an unknown name keeps that role's default. `NO_COLOR=1`
63
+ keeps labels and Unicode borders without color; `TERM=dumb` or non-TTY input/output
64
+ uses the existing line interface and explicitly reports the fallback.
65
+
66
+ | Default color | Theme roles |
67
+ | --- | --- |
68
+ | black | `border` |
69
+ | red | `title`, `operator`, `warning`, `prompt`, `selection` |
70
+ | white | `request`, `assistant`, `value`, `composer`, `header`, `footer` |
71
+ | green | `task` |
72
+ | cyan | `tool`, `notice` |
73
+ | yellow | `result`, `category`, `status` |
74
+
75
+ Fresh configurations and missing roles use these defaults. Existing configured
76
+ colors are preserved by runtime resolution and migration/backfill. This palette
77
+ changes only default values, not the configuration schema; no migration is needed.
78
+
79
+ | Key or command | Action |
80
+ | --- | --- |
81
+ | Enter | Submit the mission |
82
+ | Shift+Enter, or trailing `\\` + Enter | Insert a newline. Terminals that cannot distinguish Shift+Enter need `tmux set -s extended-keys on` or the backslash fallback. |
83
+ | Up/Down | Move the completion highlight while the Command menu is visible (wrapping at either end). Otherwise recall requests from `~/.pwn/pwn_history`, including prior runs; Down past the newest restores the draft and cursor. Esc closes the menu to resume history recall. |
84
+ | Ctrl+P / Ctrl+N | Alternative completion selection keys; recall history when no menu is visible. Tab still accepts the highlight. |
85
+ | Tab | Accept the highlighted as-you-type parameter |
86
+ | Ctrl+O or `/status` | Inspect full status/settings, including overflowing header text; Esc or Ctrl+O closes |
87
+ | Ctrl+L | Clear only the Session pane, including while a request runs; preserve stored conversation, token totals, and draft |
88
+ | Ctrl+R | Incremental reverse search of request history from `~/.pwn/pwn_history`; repeat for an older match, Enter accepts into the draft without sending, Esc cancels and restores the draft/cursor |
89
+ | `/clear` | Clear the session pane only; stored conversation and token totals remain |
90
+ | `/verbose [on|off]` | Toggle compact or full tool/notice output |
91
+ | Ctrl+G or `/swarm` | Open the draft-preserving swarm workspace; `/swarm dashboard` also opens it |
92
+ | `/` + Enter or `/menu` | Open the slash menu |
93
+ | PgUp/PgDn | Scroll the timeline; new output does not pull a scrolled viewport to the bottom |
94
+ | `/model`, `/sessions resume ID` | Show model settings / change the next request's model or session while idle |
95
+ | `/steer INSTRUCTION` | Redirect the active request at a safe boundary |
96
+ | `/input TEXT` | Send one line to an ordinary tool stdin prompt; not retained in input recall |
97
+ | Ctrl+C | Cancel the active request cooperatively, or clear an idle draft |
98
+ | `back`, `/back`, Ctrl+D | Leave the console; if busy, cancel and wait for safe completion first |
99
+
100
+ Request recall shares Pry's existing `~/.pwn/pwn_history` (append-only plain-text
101
+ lines), not a separate console history file or only the current transcript.
102
+ Requests are saved through Pry's history owner with its normal duplicate and
103
+ save/ignore settings. Multiline input uses Pry's existing line-oriented format.
104
+ Search and Up/Down never write history; `/input` tool responses are excluded from
105
+ both persistence and recall. Ctrl+L never deletes history or resets token totals.
106
+
107
+ ### Model and reasoning selection
108
+
109
+ `/model` (also `show` or `status`) displays the current selection. Existing
110
+ `/model list`, `/model list llms`, `/model <engine> [model]` and `/model <model>`
111
+ forms are unchanged. Submitting a supported model opens a **REASONING EFFORT**
112
+ list: Up/Down (or j/k) selects, Enter accepts, Esc/Ctrl+C cancels both changes
113
+ and restores the submitted draft. The current effort is preselected when valid;
114
+ otherwise the catalog default or the existing medium default is used when
115
+ supported. The header updates after acceptance. The legacy interactive line
116
+ interface asks the same question (Enter accepts the default; q/Esc cancels).
117
+ Noninteractive callers use the valid current/default effort without reading stdin.
118
+
119
+ OpenAI options come from the model catalog's `supported_reasoning_levels` and
120
+ `default_reasoning_level`; catalog discovery happens once on submission, never
121
+ while typing. When metadata is absent, explicit documented GPT-5, GPT-5.1/5.2/
122
+ 5.4/5.5 and GPT-6 Astra API contracts provide fallback options. Astra never offers
123
+ `none`. Grok 3 Mini and Grok 4.5/4.6/4.7 use their documented effort levels.
124
+ Unknown models without capability metadata and Anthropic, Gemini, Ollama and
125
+ OpenWebUI do not offer an effort list: those adapters do not consume this effort
126
+ setting (their thinking controls, where present, are different).
127
+
128
+ Acceptance merges `ai.active`, the selected engine's `model` and its existing
129
+ `reasoning_effort` field into the encrypted vault; other settings are retained.
130
+ Missing decryptor files leave changes session-only. No schema migration is needed.
131
+ Capability references: [OpenAI model pages](https://developers.openai.com/api/docs/models),
132
+ [xAI reasoning](https://docs.x.ai/developers/model-capabilities/text/reasoning).
133
+
134
+ Settings and new requests are rejected while a request is running, rather than
135
+ mutating its context concurrently. Network-capable local commands (`/mcp`,
136
+ `/cron run`, `/model`) also run off the event thread so `/input` and
137
+ exit remain responsive. `/steer` applies to model requests, not these local
138
+ commands; cancellation waits until a local command returns.
139
+ At less than 48 columns or 14 rows, a compact
140
+ resize notice replaces the panes; cancellation and exit remain available. The
141
+ screen is repainted after a resize. Request history persists through Pry in
142
+ `~/.pwn/pwn_history`. The timeline retains the most recent 2,000 events;
143
+ each displayed event is capped at 16 KiB with an explicit truncation notice.
144
+ Scrollback stays pinned while new output arrives and shows a new-event count.
145
+ The opaque command menu highlights selection even with color disabled. At tiny
146
+ sizes hidden submissions are blocked and the draft is preserved until resize.
147
+ Slash parameters complete after spaces as well as during typing; Up/Down or Ctrl+P/Ctrl+N
148
+ can reach every command, not just the visible menu page. `PWN::` completion lists
149
+ constants without loading each candidate's dependencies, and paths complete
150
+ outside the usual `/tmp` and `/home` roots too. Tab replaces the token at the
151
+ cursor without removing subsequent text. Completion does not fetch provider catalogs.
152
+
153
+ Describe a concrete outcome in the composer, for example:
154
+
155
+ ```text
156
+ Use NmapIt to sweep 10.0.0.0/24, then TransparentBrowser via Burp on hosts
157
+ with 443 open, active-scan, and give me a Reports::SAST summary.
18
158
  ```
19
159
 
20
160
  ```bash
@@ -22,6 +162,119 @@ pwn[CURRENT_VERSION]:001 >>> pwn-ai
22
162
  $ pwn --ai "run bin/pwn_sast against ./src and push findings to DefectDojo"
23
163
  ```
24
164
 
165
+ ## Swarm workspace
166
+
167
+ Write a mission in MISSION CONTROL, then press **Ctrl+G**. Nothing runs just
168
+ because the workspace opens, an agent is selected, or you navigate. The roster
169
+ shows each persona's role, engine and model (including inherited/default values).
170
+ It uses the existing Swarm registry and backend, not another agent runtime.
171
+
172
+ | Workspace key | Action |
173
+ |---|---|
174
+ | Tab | Switch roster / session-owned jobs |
175
+ | j / k | Move the highlighted agent or job; outside this overlay, Up/Down select an open Command menu or recall request history |
176
+ | Space | Toggle an agent in the selected set |
177
+ | a | Prepare the current mission draft for the highlighted agent |
178
+ | b | Prepare a broadcast to the explicitly selected agents |
179
+ | d | Prepare a debate among at least two selected agents, in selection order |
180
+ | Enter | Open full agent/job details, or execute a displayed confirmation |
181
+ | s | On a job, compose a separate steering instruction; Enter reviews, Enter again sends |
182
+ | c | On a job, review cancellation; Enter confirms |
183
+ | n | Add a swarm-local persona: name, role, then confirm; no provider call |
184
+ | r | Refresh the local roster; no remote model catalog lookup |
185
+ | PgUp/PgDn, Home/End | Scroll full metadata, results, errors and confirmation text |
186
+ | Esc | Abort a prompt/confirmation, leave details, or return to the mission |
187
+ | Ctrl+G | Close the workspace immediately, leaving the mission draft and cursor unchanged |
188
+
189
+ Every action is explicit: inspect the action, targets and text before pressing
190
+ Enter on its confirmation. The original draft is never cleared or overwritten
191
+ by a swarm action. A new agent inherits routing defaults; use
192
+ `/swarm spawn NAME ROLE --engine ENGINE --model MODEL --toolsets a,b` for overrides.
193
+ An empty roster offers `n`; an empty jobs tab explains how to launch a mission.
194
+
195
+ Job details retain observed state, reply/error and the last completed tool for
196
+ this console's lifetime. Result text is redacted for display. Broadcasts visit
197
+ selected personas sequentially in one owned job; debates pass the previous
198
+ speaker's reply into the next turn (one round by default). Separate jobs can
199
+ run concurrently, up to eight active jobs. The workspace does not claim a
200
+ percentage complete or infer success from time elapsed.
201
+
202
+ Steering and cancellation affect only the selected owned job. Finished jobs
203
+ cannot be steered or revived by cancellation. In the main console Ctrl+C
204
+ cancels its active request and owned swarm jobs; Ctrl+D cancels and waits before
205
+ leaving. Below the minimum terminal size, hidden actions are blocked but Ctrl+C
206
+ and Ctrl+D still work. A running tool finishes cooperatively: neither rollback
207
+ nor remote provider billing cancellation is promised. Swarm jobs should use
208
+ noninteractive tools; their individual stdin prompts are not multiplexed.
209
+
210
+ Typed `/swarm roster|status|create|use|spawn|retire|ask|broadcast|debate|tail|steer|cancel`
211
+ commands remain available, including parameter completion. These are direct
212
+ operator commands and do not add the workspace's extra confirmation step.
213
+ `/swarm status JOB` includes retained outcomes. Jobs shown here belong to this
214
+ console, not a cross-process durable scheduler.
215
+
216
+ ## Steering a running request
217
+
218
+ In the interactive native-tool REPL, type a complete line while the agent is
219
+ busy:
220
+
221
+ ```text
222
+ /steer Stop writing the report. Summarize the evidence already collected instead.
223
+ ```
224
+
225
+ This is a **local terminal command**, not Ruby, a model tool, or text appended
226
+ to Pry's busy input buffer. `/help` and TAB include `/steer`. An empty command
227
+ prints usage; at an idle prompt it reports that there is no active request.
228
+
229
+ * During the protected model call, a scoped cancellation signal stops the
230
+ local wait and discards the obsolete response. This does not promise that the
231
+ provider stops remote computation or billing. Setup/planning helpers outside
232
+ that window finish before the next cooperative checkpoint.
233
+ * During a tool, the notice says **wait until the current tool finishes;
234
+ already-started work is not undone**. No exception is injected into tool
235
+ code. Remaining calls in the obsolete batch are marked not executed, with
236
+ paired tool-result messages, before restarting the loop.
237
+ * Instructions are processed FIFO, only in this request/session. Completed
238
+ conversation and tool evidence stay available. The latest explicit user
239
+ instruction takes precedence over conflicting earlier instructions; tool
240
+ output cannot submit steering.
241
+ * A steer starts a fresh completion scope from the latest instruction, not a
242
+ keyword-edited reconstruction of the original goal. Include all still-required
243
+ deliverables in that instruction. Old artifact requirements and a supplied
244
+ old verification contract are not silently imposed on the revised task.
245
+ Previously completed work is retained as evidence, not claimed to be undone.
246
+
247
+ In curses, **only the main event thread draws and reads terminal keys**. One
248
+ request-owned worker runs the real `Loop.run`, inheriting PWN request thread
249
+ locals, and sends output through an event queue. The existing Steering model
250
+ window/checkpoints are reused without starting its canonical stdin reader.
251
+ Ordinary tool stdin is a forwarding pipe: explicitly use `/input TEXT`, never
252
+ send a bare line that could be mistaken for a new request. Each request gets a
253
+ fresh pipe, and cancellation closes it so waiting prompts receive EOF. Ruby
254
+ stdout/stderr and the debug tee are captured for the console lifetime, sanitized,
255
+ and restored on exit; spinner control sequences are not displayed as notices.
256
+ Trace logging remains available, but **ENTER-to-step is disabled** so it cannot
257
+ compete for input. Task/tool/result/final rows remain mirrored into request logs.
258
+
259
+ `Ctrl+C` stops a model wait or requests cancellation at the next tool boundary.
260
+ It never asynchronously raises into a side-effecting tool. `back` and Ctrl+D do
261
+ the same and keep the UI alive in a closing state until the owned request ends.
262
+ The console joins its own worker; it does not kill unrelated threads. A tool
263
+ that ignores EOF and has no timeout can delay exit until it finishes. Already
264
+ launched durable jobs have their own lifecycle; cancellation does not undo them.
265
+
266
+ Fullscreen/raw-terminal tools, programs opening `/dev/tty` directly, and code
267
+ writing directly to OS terminal descriptors (rather than captured Ruby output
268
+ or a tool's returned result) are not supported inside curses. Run those outside
269
+ the agent. Stdin temporarily reports non-TTY. Do not expect local cancellation
270
+ to stop remote provider computation or billing.
271
+
272
+ The non-TTY/dumb-terminal legacy line interface retains its foreground Loop and
273
+ single canonical steering reader: there, non-command lines are forwarded to
274
+ ordinary stdin prompts, and EOF ends the reader. Both paths restore the input
275
+ descriptor, its flags, terminal mode and output on cleanup. Restart the REPL
276
+ after upgrading these files.
277
+
25
278
  ## Anatomy of a turn
26
279
 
27
280
  1. **PromptBuilder** assembles the system prompt: your request + **engine-budgeted
@@ -12,7 +12,7 @@ metadata:
12
12
 
13
13
  # PWN::Banner
14
14
 
15
- This file, using the autoload directive loads Banner modules into memory only when they're needed. For more information, see: http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
15
+ Static banners and pure, PWN-branded retro ASCII loops: falling_blocks, snake, and pong. mini_frame returns fresh rows on a borderless canvas; use equal width and height (5..16) for complete square artwork. Dimensions clamp to 0..16, with smaller panes degrading to a wordmark. The caller samples mini_names once per session and advances the explicit frame index every MINI_FRAME_SECONDS (0.1), wrapping at MINI_FRAME_COUNT (60). These are decorative animations, not interactive games or telemetry. Static Banner modules autoload only when needed. For more information, see: http://www.rubyinside.com/ruby-techniques-revealed-autoload-1652.html
16
16
 
17
17
  ## When to use
18
18
 
@@ -28,11 +28,13 @@ Class methods take `(opts = {})` and read `opts`.
28
28
 
29
29
  ```ruby
30
30
  PWN::Banner.help
31
- PWN::Banner.get(opts)
31
+ PWN::Banner.mini_frame(opts)
32
32
  ```
33
33
 
34
34
  ## Public methods
35
35
 
36
+ - `mini_frame`
37
+ - `mini_names`
36
38
  - `get`
37
39
  - `welcome`
38
40
  - `authors`
@@ -48,5 +50,5 @@ PWN::Banner.get(opts)
48
50
 
49
51
  ## Verification
50
52
 
51
- `PWN::Banner.respond_to?(:get)` after the
53
+ `PWN::Banner.respond_to?(:mini_frame)` after the
52
54
  module is loaded. Read the source for parameter names.
@@ -12,7 +12,7 @@ metadata:
12
12
 
13
13
  # PWN::Blockchain::BTC
14
14
 
15
- This plugin interacts with BitCoin's Blockchain API.
15
+ Read-only Bitcoin Core intelligence. No wallet, signing or broadcast RPCs.
16
16
 
17
17
  ## When to use
18
18
 
@@ -34,15 +34,18 @@ PWN::Blockchain::BTC.get_latest_block(opts)
34
34
  ## Public methods
35
35
 
36
36
  - `get_latest_block`
37
+ - `chain_status`
37
38
  - `get_block_details`
39
+ - `inspect_transaction`
40
+ - `inspect_outpoint`
41
+ - `mempool_summary`
42
+ - `trace_transaction`
43
+ - `scan_transactions`
38
44
  - `get_transactions`
45
+ - `scan_address_activity`
39
46
  - `authors`
40
47
  - `help`
41
48
 
42
- ## References
43
-
44
- - `references/urls.md` — URLs from source
45
-
46
49
  ## Source
47
50
 
48
51
  `pwn/blockchain/btc.rb`
@@ -12,7 +12,7 @@ metadata:
12
12
 
13
13
  # PWN::Blockchain::ETH
14
14
 
15
- This plugin interacts with BitCoin's Blockchain API.
15
+ Read-only Ethereum intelligence via BlockCypher and explicit JSON-RPC endpoints.
16
16
 
17
17
  ## When to use
18
18
 
@@ -28,11 +28,20 @@ Class methods take `(opts = {})` and read `opts`.
28
28
 
29
29
  ```ruby
30
30
  PWN::Blockchain::ETH.help
31
- PWN::Blockchain::ETH.get_latest_block(opts)
31
+ PWN::Blockchain::ETH.decode_transfer(opts)
32
32
  ```
33
33
 
34
34
  ## Public methods
35
35
 
36
+ - `decode_transfer`
37
+ - `event_logs`
38
+ - `address_activity`
39
+ - `call`
40
+ - `token_metadata`
41
+ - `block`
42
+ - `account`
43
+ - `transaction`
44
+ - `chain_status`
36
45
  - `get_latest_block`
37
46
  - `get_block_details`
38
47
  - `authors`
@@ -48,5 +57,5 @@ PWN::Blockchain::ETH.get_latest_block(opts)
48
57
 
49
58
  ## Verification
50
59
 
51
- `PWN::Blockchain::ETH.respond_to?(:get_latest_block)` after the
60
+ `PWN::Blockchain::ETH.respond_to?(:decode_transfer)` after the
52
61
  module is loaded. Read the source for parameter names.
@@ -1,3 +1,3 @@
1
1
  # PWN::Blockchain::ETH source links
2
2
 
3
- - https://api.blockcypher.com/v1/eth/
3
+ - https://api.blockcypher.com/v1/eth/[redacted]
@@ -51,6 +51,7 @@ PWN::Plugins::REPL.ready_tty(opts)
51
51
  - `persist_ai_selection`
52
52
  - `persist_mesh_env`
53
53
  - `pwn_ai_activation_session`
54
+ - `pwn_ai_apply_model`
54
55
  - `pwn_ai_complete`
55
56
  - `pwn_ai_complete_command`
56
57
  - `pwn_ai_complete_kind`
@@ -63,7 +64,9 @@ PWN::Plugins::REPL.ready_tty(opts)
63
64
  - `pwn_ai_memory_command`
64
65
  - `pwn_ai_model_ids`
65
66
  - `pwn_ai_profile_command`
67
+ - `pwn_ai_prompt_reasoning`
66
68
  - `pwn_ai_provider_class`
69
+ - `pwn_ai_reasoning_selection`
67
70
  - `pwn_ai_run_cron`
68
71
  - `pwn_ai_run_learning`
69
72
  - `pwn_ai_run_mcp`
@@ -71,6 +74,7 @@ PWN::Plugins::REPL.ready_tty(opts)
71
74
  - `pwn_ai_run_model`
72
75
  - `pwn_ai_run_sessions`
73
76
  - `pwn_ai_run_skills`
77
+ - `pwn_ai_run_steerable`
74
78
  - `pwn_mesh_complete`
75
79
  - `pwn_mesh_dispatch_slash!`
76
80
  - `pwn_mesh_menu_rows`
@@ -37,6 +37,10 @@ PWN::Plugins::REPL::AI.add_commands(opts)
37
37
  - `authors`
38
38
  - `help`
39
39
 
40
+ ## References
41
+
42
+ - `references/urls.md` — URLs from source
43
+
40
44
  ## Source
41
45
 
42
46
  `pwn/plugins/repl/ai.rb`
@@ -0,0 +1,5 @@
1
+ # PWN::Plugins::REPL::AI source links
2
+
3
+ - https://developers.openai.com/api/docs/models/gpt-6-astra
4
+ - https://developers.openai.com/api/docs/models/gpt-5
5
+ - https://docs.x.ai/developers/model-capabilities/text/reasoning
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: pwn-plugins-repl-aiconsole
3
+ description: Drive PWN::Plugins::REPL::AIConsole from pwn_eval.
4
+ license: MIT
5
+ allowed-tools: [pwn, pwn_eval]
6
+ metadata:
7
+ bundled: true
8
+ generated: true
9
+ module: PWN::Plugins::REPL::AIConsole
10
+ source: pwn/plugins/repl/ai_console.rb
11
+ ---
12
+
13
+ # PWN::Plugins::REPL::AIConsole
14
+
15
+ Single-owner fullscreen agent console. Workers never paint the terminal.
16
+
17
+ ## When to use
18
+
19
+ Call `PWN::Plugins::REPL::AIConsole` from `pwn_eval` when the task needs this module.
20
+ Do not reimplement it in shell.
21
+
22
+ ## Methodologies
23
+
24
+ Generated from `pwn/plugins/repl/ai_console.rb`. Prefer the public class methods below.
25
+ Class methods take `(opts = {})` and read `opts`.
26
+
27
+ ## How to call
28
+
29
+ ```ruby
30
+ PWN::Plugins::REPL::AIConsole.help
31
+ PWN::Plugins::REPL::AIConsole.run(opts)
32
+ ```
33
+
34
+ ## Public methods
35
+
36
+ - `run`
37
+ - `theme`
38
+ - `authors`
39
+ - `help`
40
+
41
+ ## Source
42
+
43
+ `pwn/plugins/repl/ai_console.rb`
44
+
45
+ ## Verification
46
+
47
+ `PWN::Plugins::REPL::AIConsole.respond_to?(:run)` after the
48
+ module is loaded. Read the source for parameter names.