====== cli.py ======
The RobinNet CLI is the primary operator tool for managing a local node.
It provides commands for:
* initializing a node
* inspecting node information
* adding and removing peers
* testing peer connectivity
* posting bulletins
* listing and viewing messages
* viewing message trace history
* syncing one peer or all peers
* expiring old messages
* generating test data
The CLI is designed to be the main operational interface before the future Cardinal UI.
-----
===== General Usage =====
RobinNet commands are run as a Python module.
Basic format:
python -m robinnet.cli --db ./data/node.db [options]
Example:
python -m robinnet.cli --db ./data/node.db node-info
-----
===== Node Commands =====
==== init-node ====
Initializes or updates the local node identity.
Example:
python -m robinnet.cli \
--db ./data/node.db \
init-node \
--name alpha \
--operator "Rich" \
--callsign N2XYZ \
--location "Albany area"
Options:
* ''--name'' local node name
* ''--operator'' operator name
* ''--callsign'' operator callsign
* ''--location'' human-readable location
* ''--transport-profile'' transport label such as ''lan'', ''mesh'', or ''packet''
* ''--node-uuid'' optional explicit UUID
-----
==== node-info ====
Displays the local node record.
Example:
python -m robinnet.cli \
--db ./data/node.db \
node-info
JSON output:
python -m robinnet.cli \
--db ./data/node.db \
node-info \
--json
-----
===== Peer Commands =====
==== add-peer ====
Adds or updates a peer node.
Example:
python -m robinnet.cli \
--db ./data/node.db \
add-peer \
--name bravo \
--url http://127.0.0.1:8082
Options:
* ''--name'' peer display name
* ''--url'' peer base URL
* ''--transport'' transport label
* ''--peer-uuid'' optional peer UUID
* ''--notes'' optional notes
* ''--disabled'' add the peer as disabled
-----
==== list-peers ====
Lists configured peers.
Example:
python -m robinnet.cli \
--db ./data/node.db \
list-peers
Show enabled peers only:
python -m robinnet.cli \
--db ./data/node.db \
list-peers \
--enabled-only
JSON output:
python -m robinnet.cli \
--db ./data/node.db \
list-peers \
--json
-----
==== remove-peer ====
Removes a peer by local peer id.
Example:
python -m robinnet.cli \
--db ./data/node.db \
remove-peer \
--peer-id 1
-----
==== peer-test ====
Tests connectivity and identity for one peer.
This command:
* checks the remote health endpoint
* fetches the remote node info
* updates ''last_seen_at'' if successful
Example:
python -m robinnet.cli \
--db ./data/node.db \
peer-test \
--peer-id 1
Options:
* ''--connect-timeout'' HTTP connect timeout
* ''--read-timeout'' HTTP read timeout
* ''--json'' JSON output
JSON output example:
python -m robinnet.cli \
--db ./data/node.db \
peer-test \
--peer-id 1 \
--json
-----
===== Message Commands =====
==== post-bulletin ====
Creates a new local bulletin.
Example:
python -m robinnet.cli \
--db ./data/node.db \
post-bulletin \
--title "Water Distribution" \
--body "Town Hall from 10:00 to 16:00."
Options:
* ''--title'' bulletin title
* ''--body'' bulletin body text
* ''--author'' optional author override
* ''--author-callsign'' optional author callsign override
* ''--scope'' ''local'', ''regional'', or ''network''
* ''--expires-at'' ISO timestamp
* ''--priority'' priority from 0 to 9
* ''--local-only'' prevent later export
* ''--rf-eligible'' future RF eligibility marker
Example with more options:
python -m robinnet.cli \
--db ./data/node.db \
post-bulletin \
--title "Shelter Open" \
--body "Community Center open until 22:00." \
--scope regional \
--priority 5 \
--rf-eligible
-----
==== list-messages ====
Lists locally stored messages.
Example:
python -m robinnet.cli \
--db ./data/node.db \
list-messages
Show message bodies:
python -m robinnet.cli \
--db ./data/node.db \
list-messages \
--show-body
Filter by type:
python -m robinnet.cli \
--db ./data/node.db \
list-messages \
--msg-type bulletin
Filter by status:
python -m robinnet.cli \
--db ./data/node.db \
list-messages \
--status active
JSON output:
python -m robinnet.cli \
--db ./data/node.db \
list-messages \
--json
-----
==== show-message ====
Displays one message by UUID.
Example:
python -m robinnet.cli \
--db ./data/node.db \
show-message \
--msg-uuid 12345678-1234-1234-1234-123456789abc
-----
==== show-trace ====
Displays trace history for one message UUID.
This is useful for following import/export history.
Example:
python -m robinnet.cli \
--db ./data/node.db \
show-trace \
--msg-uuid 12345678-1234-1234-1234-123456789abc
JSON output:
python -m robinnet.cli \
--db ./data/node.db \
show-trace \
--msg-uuid 12345678-1234-1234-1234-123456789abc \
--json
-----
==== delete-message ====
Deletes one message by UUID.
Example:
python -m robinnet.cli \
--db ./data/node.db \
delete-message \
--msg-uuid 12345678-1234-1234-1234-123456789abc
-----
===== Sync Commands =====
==== sync-peer ====
Synchronizes one configured peer.
By default it performs both:
* pull from peer
* push to peer
Example:
python -m robinnet.cli \
--db ./data/node.db \
sync-peer \
--peer-id 1
Pull only:
python -m robinnet.cli \
--db ./data/node.db \
sync-peer \
--peer-id 1 \
--pull-only
Push only:
python -m robinnet.cli \
--db ./data/node.db \
sync-peer \
--peer-id 1 \
--push-only
Options:
* ''--connect-timeout'' HTTP connect timeout
* ''--read-timeout'' HTTP read timeout
* ''--pull-limit'' maximum summaries/messages to fetch
* ''--push-limit'' maximum push candidates
* ''--json'' output structured JSON
-----
==== sync-all ====
Synchronizes all enabled peers.
Example:
python -m robinnet.cli \
--db ./data/node.db \
sync-all
Pull only:
python -m robinnet.cli \
--db ./data/node.db \
sync-all \
--pull-only
Push only:
python -m robinnet.cli \
--db ./data/node.db \
sync-all \
--push-only
JSON output:
python -m robinnet.cli \
--db ./data/node.db \
sync-all \
--json
-----
===== Maintenance Commands =====
==== expire-messages ====
Marks expired messages as ''expired''.
Example:
python -m robinnet.cli \
--db ./data/node.db \
expire-messages
Show expired messages after the update:
python -m robinnet.cli \
--db ./data/node.db \
expire-messages \
--show
Show expired messages as JSON:
python -m robinnet.cli \
--db ./data/node.db \
expire-messages \
--show \
--json
-----
==== generate-test-data ====
Creates local test bulletins for development and sync testing.
Example:
python -m robinnet.cli \
--db ./data/node.db \
generate-test-data \
--count 5
Custom prefixes:
python -m robinnet.cli \
--db ./data/node.db \
generate-test-data \
--count 10 \
--title-prefix "Test Bulletin" \
--body-prefix "Generated message"
Include full message output:
python -m robinnet.cli \
--db ./data/node.db \
generate-test-data \
--count 3 \
--include-messages \
--json
Options:
* ''--count'' number of test messages
* ''--title-prefix'' title prefix
* ''--body-prefix'' body prefix
* ''--scope'' ''local'', ''regional'', or ''network''
* ''--expires-at'' optional expiration timestamp
* ''--priority'' priority from 0 to 9
* ''--local-only'' mark generated messages local only
* ''--rf-eligible'' mark generated messages RF eligible
* ''--include-messages'' include full records in output
* ''--json'' JSON output
-----
===== Typical Workflow =====
A basic operator workflow might be:
- initialize node
- add one or more peers
- test peer connectivity
- post a bulletin
- sync with peers
- inspect messages and trace
Example:
python -m robinnet.cli --db ./data/alpha.db init-node --name alpha --operator "Rich"
python -m robinnet.cli --db ./data/alpha.db add-peer --name bravo --url http://127.0.0.1:8082
python -m robinnet.cli --db ./data/alpha.db peer-test --peer-id 1
python -m robinnet.cli --db ./data/alpha.db post-bulletin --title "Test" --body "Hello RobinNet"
python -m robinnet.cli --db ./data/alpha.db sync-all
python -m robinnet.cli --db ./data/alpha.db list-messages --show-body
-----
===== Notes =====
The CLI is intended to remain fully functional even after Cardinal exists.
That means:
* Cardinal can become a friendly frontend
* the CLI remains the operator and sysop tool
* automation and scripting remain easy