====== 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