Skip to main content

OpenSynaptic CLI and TUI

All commands are available via os-node (installed entry-point), ./run-main.cmd (Windows shortcut), or python -u src/main.py.

Startup behavior note:

  • First run now auto-attempts native runtime repair when required C bindings are missing.
  • If auto-repair fails (for example, compiler missing), CLI returns structured guidance and keeps native-check / native-build as manual fallback.

Command Reference

CommandAliasesDescription
runos-runPersistent run loop; maintains protocol heartbeat until Ctrl+C or --duration
restartos-restartGracefully restart: stop current receiver and auto-start new run process
snapshotos-snapshotPrint node / service / transporter JSON snapshot
receiveos-receiveStart UDP receiver (server-side packet ingestion loop)
demoos-demoOne-command localhost onboarding: virtual sensors + Web UI
tuios-tuiRender a TUI snapshot; add --interactive for live mode
time-syncos-time-syncSynchronise clock with the server once
ensure-idos-ensure-idRequest a device ID from the server and persist it to Config.json
transmitos-transmitEncode one sensor reading and dispatch via transporter
injectos-injectPush sensor data through pipeline stages and print intermediate output
decodeos-decodeDecode a binary packet (hex) or Base62 string back to readable JSON
watchos-watchReal-time poll a module's state (Ctrl+C or --duration to stop)
reload-protocolos-reload-protocolInvalidate and reload one protocol adapter
config-showos-config-showDisplay Config.json or one top-level section
config-getos-config-getRead a dot-notation key path from Config.json
config-setos-config-setWrite a typed value to a dot-notation key path
wizardinit, os-wizard, os-initInteractive config generator (--default for one-shot defaults)
repair-configos-repair-configRepair/bootstrap ~/.config/opensynaptic/Config.json for loopback mode
transporter-toggleos-transporter-toggleEnable or disable a transporter entry in Config.json
plugin-listos-plugin-listList all mounted service plugins and their runtime state
plugin-loados-plugin-loadLoad a mounted plugin by name (calls auto_load())
plugin-cmdos-plugin-cmdRoute a sub-command to a plugin's own CLI handler
plugin-testos-plugin-testRun component tests, stress tests, or both
native-checkos-native-checkCheck native compiler environment and selected toolchain
native-buildos-native-buildBuild native C bindings with real-time progress and timeout guards
env-guardos-env-guardEnvironment guard plugin status/control and local JSON resource/status files
web-useros-web-userStandalone CLI entry for web_user plugin
depsos-depsStandalone CLI entry for dependency_manager plugin
transport-statusos-transport-statusShow application / transport / physical layer states
db-statusos-db-statusShow DB engine enabled status and dialect
helpos-helpPrint full help

Examples

Windows tip: replace the python -u src/main.py prefix below with ./run-main.cmd.

# ── Basic node operations ───────────────────────────────────────────────────
python -u src/main.py demo --open-browser
python -u src/main.py demo --temp-config --once
python -u src/main.py wizard
python -u src/main.py init --default
python -u src/main.py repair-config
python -u src/main.py snapshot --config Config.json
python -u src/main.py ensure-id --config Config.json --host 127.0.0.1 --port 8080
python -u src/main.py transmit --config Config.json --sensor-id V1 --value 3.14 --unit Pa --medium UDP
python -u src/main.py reload-protocol --config Config.json --medium udp
python -u src/main.py run --config Config.json --interval 5
python -u src/main.py run --config Config.json --once
python -u src/main.py restart --config Config.json --graceful --timeout 10
python -u src/main.py restart --config Config.json --timeout 5 --host 127.0.0.1 --port 8080

# ── TUI ─────────────────────────────────────────────────────────────────────
python -u src/main.py tui --config Config.json
python -u src/main.py tui --config Config.json --section transport
python -u src/main.py tui --config Config.json --interactive --interval 2.0
python -u src/main.py tui --config Config.json --interactive --section pipeline --interval 1.0

# ── Config editing ───────────────────────────────────────────────────────────
python -u src/main.py config-show --config Config.json
python -u src/main.py config-show --config Config.json --section engine_settings
python -u src/main.py config-get --config Config.json --key engine_settings.precision
python -u src/main.py config-get --config Config.json --key RESOURCES.transporters_status
python -u src/main.py config-set --config Config.json --key engine_settings.precision --value 6 --type int
python -u src/main.py config-set --config Config.json --key security_settings.drop_on_crc16_failure --value false --type bool
python -u src/main.py config-set --config Config.json --key storage.sql.driver.path --value "data/my.db"
# Write a whole sub-object (--type json)
python -u src/main.py config-set --config Config.json --key RESOURCES.transport_config.quic --value '{"port":4433,"timeout":3.0}' --type json

# ── Transporter toggle ───────────────────────────────────────────────────────
python -u src/main.py transporter-toggle --config Config.json --name udp --enable
python -u src/main.py transporter-toggle --config Config.json --name lora --disable

# ── inject – run sensor data through a specific pipeline stage ───────────────
python -u src/main.py inject --config Config.json --module standardize --sensor-id V1 --value 3.14 --unit Pa
python -u src/main.py inject --config Config.json --module compress --sensor-id T1 --value 25.0 --unit Cel
python -u src/main.py inject --config Config.json --module fuse --sensor-id P1 --value 101325 --unit Pa
python -u src/main.py inject --config Config.json --module full --sensor-id V1 --value 3.14 --unit Pa
# Multi-sensor via JSON array
python -u src/main.py inject --config Config.json --module full --sensors '[["V1","OK",3.14,"Pa"],["T1","OK",25.0,"Cel"]]'
# Multi-sensor via JSON file (PowerShell / Windows friendly)
'[["V1","OK",3.14,"Pa"],["T1","OK",25.0,"Cel"]]' | Out-File -Encoding utf8 sensors.json
python -u src/main.py inject --config Config.json --module full --sensors-file sensors.json

# ── decode ───────────────────────────────────────────────────────────────────
python -u src/main.py decode --config Config.json --format hex --data "3f010000000a..."
python -u src/main.py decode --config Config.json --format b62 --data "HUB_01.1.AAAA|V1>1.P:abc|"

# ── watch – real-time monitor (Ctrl+C to stop) ───────────────────────────────
python -u src/main.py watch --config Config.json --module config --interval 2
python -u src/main.py watch --config Config.json --module registry --interval 5
python -u src/main.py watch --config Config.json --module transport --interval 3
python -u src/main.py watch --config Config.json --module pipeline --interval 1 --duration 30

# ── Plugin commands ──────────────────────────────────────────────────────────
python -u src/main.py plugin-list --config Config.json
python -u src/main.py plugin-load --config Config.json --name tui
# Route a sub-command to the TUI plugin's own handler
python -u src/main.py plugin-cmd --config Config.json --plugin tui --cmd render
python -u src/main.py plugin-cmd --config Config.json --plugin tui --cmd render -- --section transport
python -u src/main.py plugin-cmd --config Config.json --plugin tui --cmd interactive -- --interval 2.0
# Route a sub-command to the test_plugin
python -u src/main.py plugin-cmd --config Config.json --plugin test_plugin --cmd component
python -u src/main.py plugin-cmd --config Config.json --plugin test_plugin --cmd stress -- --total 100 --workers 4
# Direct web_user command
python -u src/main.py web-user --config Config.json --cmd start -- --host 127.0.0.1 --port 8765 --block
# Direct dependency manager command
python -u src/main.py deps --config Config.json --cmd check
python -u src/main.py deps --config Config.json --cmd repair
# Environment guard command
python -u src/main.py env-guard --config Config.json --cmd status
python -u src/main.py env-guard --config Config.json --cmd set -- --auto-install true
python -u src/main.py env-guard --config Config.json --cmd resource-show
python -u src/main.py env-guard --config Config.json --cmd resource-init

# ── Testing ───────────────────────────────────────────────────────────────────
python -u src/main.py plugin-test --config Config.json --suite component
python -u src/main.py plugin-test --config Config.json --suite stress --workers 8 --total 200
python -u src/main.py plugin-test --config Config.json --suite all --workers 8 --total 200

# ── Native precheck / build (timeout-safe) ───────────────────────────────────
python -u src/main.py native-check
python -u src/main.py native-check --json
python -u src/main.py native-check --timeout 5
python -u src/main.py native-build
python -u src/main.py native-build --idle-timeout 5 --max-timeout 30
python -u src/main.py native-build --no-progress --json

inject – Module Options

--moduleStops afterOutput keys
standardizeStandardizerstandardize (fact dict with UCUM-normalised values)
compressEnginestandardize + compress (Base62 string)
fuse / fullFusion Engineall above + fuse{hex, length}

watch – Module Options

--moduleWhat is monitored
configTop-level Config.json scalars + key sub-dicts
registryDevice registry file modification timestamps
transportActive transporters list + transporters_status map
pipelineStandardizer cache size, Engine symbol count, Fusion template count

tui – Section Options

--sectionContents
identitydevice_id, assigned_id, VERSION
configengine_settings, payload_switches, OpenSynaptic_Setting, security_settings
transportActive transporters + all three status maps
pipelineStandardizer cache, Engine rev-unit table, Fusion template count
pluginsServiceManager mount and runtime indexes
dbDB engine enabled flag and dialect

Omit --section to render all sections at once.
Add --interactive to enter the live-refresh loop.


config-set – Type Options

--typeExample --valuePython result
str (default)"hello""hello"
int"6"6
float"3.14"3.14
bool"true" / "false"True / False
json'{"a":1}'{"a": 1}

Global Flags

FlagDefaultDescription
--configauto-detectAbsolute or relative path to Config.json
--quietfalseSuppress INFO logs; only WARNING/ERROR pass through
--interval5.0run mode polling interval (seconds)
--duration0.0run / watch duration limit (seconds); 0 = unlimited
--oncefalserun mode: execute one cycle then exit
--yesfalseFirst-run wizard: auto-start demo without prompt
--no-wizardfalseSkip first-run wizard prompt

Argcomplete Setup (Tab Completion)

py -3 -m pip install argcomplete
powershell -ExecutionPolicy Bypass -File .\scripts\enable_argcomplete.ps1

If your PowerShell blocks Activate.ps1, you do not need to activate venv for CLI commands:

.\scripts\venv-python.cmd -u src/main.py --help

Manual activation:

Invoke-Expression (register-python-argcomplete os-node --shell powershell)

After restart, completion is available for:

  • command names and subcommands
  • config-get --key / config-set --key (nested dot paths + list indexes)
  • transporter names on --medium / --name
  • plugin-cmd --plugin and plugin --cmd

config-* --key completion uses a short-lived cache keyed by config file mtime to avoid repeated deep traversal on large files.


Notes

  • CLI and TUI both route logging through opensynaptic.utils.os_log.
  • TUIService is mounted as a ServiceManager plugin under the name "tui".
  • inject does not require a valid assigned_id; it falls back to 0 for the fuse stage.
  • inject --sensors takes a JSON array; on PowerShell use --sensors-file <path> to avoid quote-stripping issues.
  • decode --format hex accepts aabbcc, aa:bb:cc, or aa bb cc (separators are stripped automatically).
  • config-set with --type json writes entire sub-dicts in one command.
  • plugin-cmd resolves plugins through services/plugin_registry.py; no plugin starts automatically on node boot.
  • Plugins can expose get_cli_completions() to provide plugin-cmd --cmd completion metadata (fallback: get_cli_commands() keys).
  • Required plugin settings are auto-added to Config.json under RESOURCES.service_plugins.<plugin_name>.
  • web-user --cmd start -- --block keeps the process in foreground so the browser UI stays available.
  • Native runtime repair is auto-attempted once during first-run startup and node-init native-load failure paths.