pwn 0.5.774 → 0.5.777
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/Gemfile +1 -1
- data/documentation/General-PWN-Usage.md +16 -11
- data/documentation/pwn-REPL.md +9 -7
- data/etc/default_skills/pwn/json_text/SKILL.md +47 -0
- data/etc/default_skills/pwn/plugins/repl/mesh/references/urls.md +1 -0
- data/lib/pwn/json_text.rb +84 -0
- data/lib/pwn/plugins/repl/mesh.rb +3484 -2713
- data/lib/pwn/version.rb +1 -1
- data/lib/pwn.rb +1 -0
- data/spec/lib/pwn/ai/agent/result_spec.rb +21 -0
- data/spec/lib/pwn/json_text_spec.rb +33 -0
- data/spec/lib/pwn/plugins/repl_mesh_console_spec.rb +2 -1
- data/spec/lib/pwn/plugins/repl_mesh_layout_spec.rb +118 -0
- data/spec/lib/pwn/plugins/repl_mesh_multi_rx_spec.rb +3 -1
- data/spec/lib/pwn/plugins/repl_mesh_origin_gps_spec.rb +157 -15
- data/spec/lib/pwn/plugins/repl_mesh_scroll_spec.rb +43 -0
- data/spec/lib/pwn/plugins/repl_mesh_transport_label_spec.rb +11 -7
- data/third_party/pwn_rdoc.jsonl +5 -0
- metadata +6 -3
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 77cd821e27ebf793d043b1b73139ff68b17badf106a91f42832769ac7760785e
|
|
4
|
+
data.tar.gz: '0708df0d0f8258f249e0b57556898e3a1e675ef90a8caa162eac0fc4366b652e'
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 338c0443dd72e44e29b50c8b3afd11251ab84643f1b105304c698789cda148f69e4f68468b9c2cdc4824dc1570591f2d9d51c17d5a678c4cea4eace72c27be4e
|
|
7
|
+
data.tar.gz: d60694fcbbe66c4b48eb2e35f5235e508d5bcc66f5d2172b7a5ebd604b755a778b83c428ea47578c61985078231382a5182dfca213e46400c61af5bdf8f9fd9a
|
data/Gemfile
CHANGED
|
@@ -59,10 +59,11 @@ MQTT receiver when the primary is Serial, Bluetooth, or TCP. Missing/empty
|
|
|
59
59
|
MQTT configuration makes no additional connection attempt; primary MQTT uses
|
|
60
60
|
only one subscription. MQTT connection failures leave the primary usable and
|
|
61
61
|
are reported in the UI. `/transport` reconnects both subscriptions; `/back`
|
|
62
|
-
closes them. Ctrl+T
|
|
63
|
-
|
|
64
|
-
Up/Down
|
|
65
|
-
|
|
62
|
+
closes them. Ctrl+T cycles COMPOSE, CONVERSATION, SENDER, and RECEIVER.
|
|
63
|
+
COMPOSE keeps Up/Down history. CONVERSATION selects messages
|
|
64
|
+
with Up/Down, a page with PgUp/PgDn, Home for the first, and End for the
|
|
65
|
+
latest, including when every message already fits. The latest selection is
|
|
66
|
+
not row 0, so End stays on the last message. Typing or
|
|
66
67
|
Enter returns to COMPOSE; Enter does not send while CONVERSATION is active.
|
|
67
68
|
The active title is reversed and marked active.
|
|
68
69
|
|
|
@@ -79,14 +80,18 @@ uses sender, packet ID, network/channel path, destination and payload (not
|
|
|
79
80
|
text alone), retaining at most 1000 packets for five minutes. No-ID packets
|
|
80
81
|
cannot be safely merged.
|
|
81
82
|
|
|
82
|
-
Each header ends with
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
Each header ends with its direction and transport. Sender and receiver positions
|
|
84
|
+
are not painted there. `SENDER` and `RECEIVER` sit to the right of
|
|
85
|
+
CONVERSATION. A broadcast destination shows the channel name, not the word
|
|
86
|
+
broadcast. Ctrl+T cycles COMPOSE, CONVERSATION, SENDER, and RECEIVER.
|
|
87
|
+
A valid fix is the underlined coordinate.
|
|
88
|
+
Click it, or press `g` while CONVERSATION, SENDER, or RECEIVER is active, to open
|
|
89
|
+
`https://maps.google.com/?q=lat,lon`. The URL is not painted. Curses cannot
|
|
90
|
+
hide a link inside the coordinate text. Unknown, unset, or
|
|
91
|
+
out-of-range positions display `GPS: N/A` and omit the URL. A broadcast
|
|
92
|
+
receiver has no single position, so that field is `GPS: N/A`. `0,0` is kept when
|
|
88
93
|
a real location source is present and omitted when the source is unset. The
|
|
89
|
-
value is the last position recorded for that
|
|
94
|
+
value is the last position recorded for that node, not a freshness guarantee.
|
|
90
95
|
|
|
91
96
|
MQTT TX uses `channel.<name>.from` when set, otherwise the connected radio's
|
|
92
97
|
node number, otherwise a node-shaped `mqtt.client_id`. It does not publish the
|
data/documentation/pwn-REPL.md
CHANGED
|
@@ -102,14 +102,16 @@ session only; it is not written to disk.
|
|
|
102
102
|
|
|
103
103
|
### Message transport labels
|
|
104
104
|
|
|
105
|
-
Each CONVERSATION header ends with
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
configured `auto` value. Received messages retain the subscribing transport's
|
|
105
|
+
Each CONVERSATION header ends with `RX via <TRANSPORT>` or `TX via <TRANSPORT>`.
|
|
106
|
+
SENDER and RECEIVER do not show that label. Ctrl+T cycles COMPOSE,
|
|
107
|
+
CONVERSATION, SENDER, and RECEIVER. In `auto` mode this is the
|
|
108
|
+
resolved connection, not the configured `auto` value. Received messages retain the subscribing transport's
|
|
109
109
|
origin through queued rendering, even if the current transport changes.
|
|
110
110
|
Missing origin metadata is shown as `Unknown`, not guessed from the current pin.
|
|
111
|
+
GPS is not part of the header. SENDER and RECEIVER sit to the right of
|
|
112
|
+
CONVERSATION. A broadcast receiver shows the channel name.
|
|
111
113
|
|
|
112
|
-
Headers use `timestamp encryption · SHORT NAME · source path · destination path ·
|
|
114
|
+
Headers use `timestamp encryption · SHORT NAME · source path · destination path · RX via <TRANSPORT>`,
|
|
113
115
|
with exactly one space on either side of each `·`. RX uses the sender's
|
|
114
116
|
`User.short_name` (`shortName` in JSON); TX uses the sending local node's User,
|
|
115
117
|
never the destination's name. Device connections use their NodeInfo/NODEINFO
|
|
@@ -125,8 +127,8 @@ Unicode text and internal spaces are retained. Names are labels, not authenticat
|
|
|
125
127
|
For example (placeholder node IDs):
|
|
126
128
|
|
|
127
129
|
```text
|
|
128
|
-
2026-01-02 03:04:05+0000 🔍 · PEER · US/CA/2/e/LongFast/!aabbccdd · US/CA/2/e/LongFast/#
|
|
129
|
-
2026-01-02 03:04:06+0000 🔍 · SELF · US/CA/2/e/LongFast/!bbccddee (ME) · US/CA/2/e/LongFast/#
|
|
130
|
+
2026-01-02 03:04:05+0000 🔍 · PEER · US/CA/2/e/LongFast/!aabbccdd · US/CA/2/e/LongFast/#
|
|
131
|
+
2026-01-02 03:04:06+0000 🔍 · SELF · US/CA/2/e/LongFast/!bbccddee (ME) · US/CA/2/e/LongFast/#
|
|
130
132
|
```
|
|
131
133
|
|
|
132
134
|
The timestamp, encryption indicator, source/destination paths, channel and
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pwn-jsontext
|
|
3
|
+
description: Drive PWN::JSONText from pwn_eval.
|
|
4
|
+
license: MIT
|
|
5
|
+
allowed-tools: [pwn, pwn_eval]
|
|
6
|
+
metadata:
|
|
7
|
+
bundled: true
|
|
8
|
+
generated: true
|
|
9
|
+
module: PWN::JSONText
|
|
10
|
+
source: pwn/json_text.rb
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# PWN::JSONText
|
|
14
|
+
|
|
15
|
+
Retag or scrub strings before the JSON generator sees them.
|
|
16
|
+
|
|
17
|
+
## When to use
|
|
18
|
+
|
|
19
|
+
Call `PWN::JSONText` from `pwn_eval` when the task needs this module.
|
|
20
|
+
Do not reimplement it in shell.
|
|
21
|
+
|
|
22
|
+
## Methodologies
|
|
23
|
+
|
|
24
|
+
Generated from `pwn/json_text.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::JSONText.help
|
|
31
|
+
PWN::JSONText.prepare(opts)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Public methods
|
|
35
|
+
|
|
36
|
+
- `prepare`
|
|
37
|
+
- `authors`
|
|
38
|
+
- `help`
|
|
39
|
+
|
|
40
|
+
## Source
|
|
41
|
+
|
|
42
|
+
`pwn/json_text.rb`
|
|
43
|
+
|
|
44
|
+
## Verification
|
|
45
|
+
|
|
46
|
+
`PWN::JSONText.respond_to?(:prepare)` after the
|
|
47
|
+
module is loaded. Read the source for parameter names.
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Retag or scrub strings before the JSON generator sees them.
|
|
4
|
+
module PWN
|
|
5
|
+
# json 2.21 warns when valid UTF-8 is still tagged BINARY, and raises
|
|
6
|
+
# JSON::GeneratorError on a malformed sequence. Both show up in the session pane.
|
|
7
|
+
module JSONText
|
|
8
|
+
# Supported Method Parameters::
|
|
9
|
+
# safe = PWN::JSONText.prepare(
|
|
10
|
+
# value: 'required - string, hash, or array that may contain binary-tagged text',
|
|
11
|
+
# depth: 'optional - nesting already walked; containers stop at 100'
|
|
12
|
+
# )
|
|
13
|
+
|
|
14
|
+
public_class_method def self.prepare(opts = {})
|
|
15
|
+
value = opts[:value]
|
|
16
|
+
depth = opts[:depth].to_i
|
|
17
|
+
case value
|
|
18
|
+
when String
|
|
19
|
+
utf = value.dup.force_encoding(Encoding::UTF_8)
|
|
20
|
+
utf.valid_encoding? ? utf : utf.scrub
|
|
21
|
+
when Hash
|
|
22
|
+
return value if depth >= 100
|
|
23
|
+
|
|
24
|
+
value.each_with_object({}) do |(key, item), out|
|
|
25
|
+
out[key.is_a?(String) ? prepare(value: key, depth: depth + 1) : key] = prepare(value: item, depth: depth + 1)
|
|
26
|
+
end
|
|
27
|
+
when Array
|
|
28
|
+
return value if depth >= 100
|
|
29
|
+
|
|
30
|
+
value.map { |item| prepare(value: item, depth: depth + 1) }
|
|
31
|
+
else
|
|
32
|
+
value
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Author(s):: 0day Inc. <support@0dayinc.com>
|
|
37
|
+
|
|
38
|
+
public_class_method def self.authors
|
|
39
|
+
"AUTHOR(S):\n 0day Inc. <support@0dayinc.com>\n"
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# Display Usage for this Module.
|
|
43
|
+
|
|
44
|
+
public_class_method def self.help
|
|
45
|
+
puts "USAGE:
|
|
46
|
+
# Retag valid UTF-8 that is still tagged binary, or scrub an illegal sequence.
|
|
47
|
+
#{self}.prepare(
|
|
48
|
+
value: 'required - string, hash, or array that may contain binary-tagged text',
|
|
49
|
+
depth: 'optional - nesting already walked; containers stop at 100'
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
# Print the AUTHOR(S) string for this module.
|
|
53
|
+
#{self}.authors
|
|
54
|
+
"
|
|
55
|
+
constants.sort
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# json 2.21 warns inside JSON.generate before State.generate. json 2.18 warns
|
|
61
|
+
# inside the C to_json methods. Retag at both doors.
|
|
62
|
+
class << JSON
|
|
63
|
+
%i[generate fast_generate pretty_generate dump].each do |name|
|
|
64
|
+
alias_method :"#{name}_without_json_text", name
|
|
65
|
+
define_method(name) do |obj, *rest|
|
|
66
|
+
public_send(:"#{name}_without_json_text", PWN::JSONText.prepare(value: obj), *rest)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
if defined?(JSON::Ext::Generator::GeneratorMethods)
|
|
72
|
+
JSON::Ext::Generator::GeneratorMethods.constants.each do |kind|
|
|
73
|
+
mod = JSON::Ext::Generator::GeneratorMethods.const_get(kind)
|
|
74
|
+
next unless mod.is_a?(Module) && mod.method_defined?(:to_json)
|
|
75
|
+
|
|
76
|
+
mod.class_eval do
|
|
77
|
+
alias_method :to_json_without_json_text, :to_json unless method_defined?(:to_json_without_json_text)
|
|
78
|
+
define_method(:to_json) do |*rest|
|
|
79
|
+
prepared = PWN::JSONText.prepare(value: self)
|
|
80
|
+
mod.instance_method(:to_json_without_json_text).bind_call(prepared, *rest)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|