termapy 0.75.0__tar.gz → 0.76.0__tar.gz
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.
- {termapy-0.75.0 → termapy-0.76.0}/PKG-INFO +47 -41
- {termapy-0.75.0 → termapy-0.76.0}/README.md +46 -40
- {termapy-0.75.0 → termapy-0.76.0}/pyproject.toml +1 -1
- {termapy-0.75.0 → termapy-0.76.0}/pyproject.toml.orig +1 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/app.py +55 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/credits.py +29 -15
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/plugin/traffic.py +1 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/doc_screenshots.run +3 -2
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/config.py +79 -0
- termapy-0.76.0/src/termapy/credits_data.py +181 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/_common.py +43 -3
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/config_picker.py +50 -24
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/filename_dialog.py +5 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/proto_picker.py +20 -6
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/script_picker.py +29 -8
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/entry.py +1 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/folder_ops.py +68 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/acknowledgments.md +29 -15
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/authoring-profiles.md +10 -10
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/cli.md +13 -5
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/commands.md +28 -21
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/config.md +11 -4
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/custom-buttons.md +3 -2
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/data-capture.md +7 -2
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/demo.md +15 -12
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/device-help.md +2 -2
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/environment.md +3 -3
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/file-transfer.md +1 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/getting-started.md +14 -8
- termapy-0.76.0/src/termapy/help/img/doc_21_script_picker.svg +213 -0
- termapy-0.76.0/src/termapy/help/img/doc_37_config_picker.svg +213 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/index.md +4 -2
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/installation.md +132 -132
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/mcp-server.md +11 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/ports.md +4 -3
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/protocol-testing.md +60 -31
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/scripting.md +14 -8
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/serial-tools.md +42 -34
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/toolbar.md +17 -12
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/using-git.md +109 -110
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/variables.md +13 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/vt100.md +2 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/writing-plugins.md +47 -8
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help_tooltip.py +13 -17
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/404.html +5 -5
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/acknowledgments.html +35 -20
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/authoring-profiles.html +15 -15
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/cli.html +33 -10
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/commands.html +41 -40
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/config.html +14 -9
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/custom-buttons.html +8 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/data-capture.html +11 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/demo.html +30 -18
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/device-help.html +7 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/environment.html +8 -8
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/file-transfer.html +6 -5
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/getting-started.html +21 -16
- termapy-0.76.0/src/termapy/html/img/doc_21_script_picker.svg +213 -0
- termapy-0.76.0/src/termapy/html/img/doc_37_config_picker.svg +213 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/index.html +9 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/installation.html +7 -7
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/mcp-server.html +36 -6
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/on-ai-assistance.html +5 -5
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/ports.html +9 -8
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/protocol-testing.html +100 -40
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/scripting.html +24 -15
- termapy-0.76.0/src/termapy/html/search.json +1 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/serial-tools.html +45 -39
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/toolbar.html +38 -28
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/using-git.html +12 -13
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/variables.html +35 -13
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/vt100.html +7 -6
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/writing-plugins.html +185 -126
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/pickers.py +44 -5
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/__init__.py +1 -1
- termapy-0.75.0/src/termapy/help/img/doc_21_script_picker.svg +0 -209
- termapy-0.75.0/src/termapy/html/img/doc_21_script_picker.svg +0 -209
- termapy-0.75.0/src/termapy/html/search.json +0 -1
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/__main__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/app_dirs.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/app_hooks.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/_cfg_icon.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/_crc_verbs.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/_run_record.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/_xmodem_handlers.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/_ymodem_handlers.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/app.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/cap.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/cfg.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/cls.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/confirm.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/edit.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/env.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/exit.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/find.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/grep.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/help.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/log.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/mcp.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/os_cmd.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/ping.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/plugin.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/port.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/print.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/profile.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/proto.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/repeat.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/run.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/run_edit.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/search.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/seq.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/show.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/ss.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/stop.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/term.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/var.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/commands/xfer.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/crc/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/crc/sum16.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/crc/sum8.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/.gitignore +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/demo.cfg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/demo.profile.json +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/demo_ndjson.profile.json +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/plugin/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/plugin/cmd.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/plugin/probe.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/plugin/temp_plot.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/proto/at_test.pro +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/proto/bitfield_inline.pro +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/proto/modbus_inline.pro +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/at_demo.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/crc_tour.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/expect_test.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/gps_demo.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/smoke_test.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/status_check.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/var_demo.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/demo/run/welcome.run +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/viz/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/viz/hex_view.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/viz/modbus_view.py.old +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/builtins/viz/text_view.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/capture.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/capture_view.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/cli.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/cli_flags.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/config_resolve.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/defaults.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/demo.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/demo_ndjson.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/demo_vt100.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/cfg_confirm.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/config_editor.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/confirm_dialog.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/name_picker.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/port_picker.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/proto_editor.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/quick_setup.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/script_editor.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/set_var_dialog.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/update_available.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/dialogs/welcome_dialog.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/env_flags.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/folders.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/.coverage +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_01_main_tui.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_02_help.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_03_help_proto.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_04_proto_send.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_05_proto_crc.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_06_proto_delay.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_07_crc_python.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_08_variables.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_09_target_help.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_10_config_info.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_11_proto_run.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_12_cap_struct.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_13_cap_progress.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_14_port_list.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_15_xfer.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_16_toolbar.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_17_proto_debug.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_20_palette.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_22_script_editor.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_23_config_editor.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_24_cmd_picker.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_30_new_cfg.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_31_cli_completion.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_32_port_picker.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_33_port_tooltip.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_34_latency_timer.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_35_vt100_menu.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/img/doc_36_vt100_status.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help/on-ai-assistance.md +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/help_dynamic.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/history_nav.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/.coverage +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/images/favicon.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/javascripts/LICENSE +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/javascripts/bundle.49251538.min.js +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/javascripts/workers/search.7d14d953.min.js +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/stylesheets/classic/main.38807bfb.min.css +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/stylesheets/classic/palette.c7ab7c71.min.css +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/stylesheets/modern/main.5da3a30f.min.css +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/assets/stylesheets/modern/palette.812a03bb.min.css +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_01_main_tui.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_02_help.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_03_help_proto.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_04_proto_send.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_05_proto_crc.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_06_proto_delay.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_07_crc_python.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_08_variables.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_09_target_help.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_10_config_info.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_11_proto_run.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_12_cap_struct.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_13_cap_progress.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_14_port_list.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_15_xfer.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_16_toolbar.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_17_proto_debug.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_20_palette.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_22_script_editor.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_23_config_editor.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_24_cmd_picker.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_30_new_cfg.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_31_cli_completion.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_32_port_picker.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_33_port_tooltip.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_34_latency_timer.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_35_vt100_menu.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/img/doc_36_vt100_status.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/objects.inv +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/html/sitemap.xml +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/info_views.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/install_info.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/legacy.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/mcp/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/mcp/catalog.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/mcp/prompts.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/mcp/server.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/migration.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/palette_provider.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/capabilities.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/command.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/context.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/fs.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/internal.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/io.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/serial.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/handles/ui.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/loader.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/output_levels.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/plugins/params.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/port_control.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/port_format.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/profile/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/profile/loader.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/profile/matcher.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/profile/schema.json +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/profile/types.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/proto_debug.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/protocol/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/protocol/core.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/protocol/crc.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/protocol/runner.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/protocol/viz.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/repl.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/request_response.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/response_parsers.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/run_docstring.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/run_legacy.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/run_profile_hooks.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/scripting.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/serial_engine.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/serial_port.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/smoke.txt +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/icons/termapy.icns +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/icons/termapy.ico +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/icons/termapy.png +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/icons/termapy.svg +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/linux/termapy.desktop.template +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/macos/Termapy.app/Contents/Info.plist +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/templates/macos/Termapy.app/Contents/MacOS/launcher.template +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/terminal_host.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/title_bar.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/tree_render.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/update_check.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb/_vendors_full.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb/aliases.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb/chips.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb/vendors.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/usb_tree.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/variables.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/LICENSES.md +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/__main__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/rfc2217.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/rs485.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/serialcli.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/serialjava.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/serialposix.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/serialutil.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/serialwin32.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/threaded/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/hexlify_codec.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports_common.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports_linux.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports_osx.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports_posix.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/list_ports_windows.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/tools/miniterm.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_alt.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_cp2110.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_hwgrep.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_loop.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_rfc2217.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_socket.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/urlhandler/protocol_spy.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/serial/win32.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/xmodem.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/CRC.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/Platform.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/Protocol.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/Socket.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/Version.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vendor/ymodem/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/vt100.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/widgets/__init__.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/widgets/checkbox.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/widgets/status_bar.py +0 -0
- {termapy-0.75.0 → termapy-0.76.0}/src/termapy/widgets/suggester.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: termapy
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.76.0
|
|
4
4
|
Summary: A TUI serial terminal with ANSI color support, built on Textual and pyserial
|
|
5
5
|
Keywords: serial,terminal,tui,textual,pyserial,embedded,xmodem,ymodem
|
|
6
6
|
Author: Chuck Bass
|
|
@@ -58,7 +58,7 @@ Runs on Windows, macOS, and Linux. A serial interface terminal like PuTTY or Ter
|
|
|
58
58
|
|
|
59
59
|
Low time commitment: about 1 minute from scratch, or under 10 seconds if you already have [uv](https://docs.astral.sh/uv/) installed.
|
|
60
60
|
|
|
61
|
-

|
|
62
62
|
|
|
63
63
|
## Install and connect
|
|
64
64
|
|
|
@@ -109,7 +109,7 @@ There's a lot more: scripting, binary protocol testing, every CRC algorithm in t
|
|
|
109
109
|
|
|
110
110
|
1. **Connect:** click the port button in the title bar, pick your COM port, click the status button to connect (it turns green)
|
|
111
111
|
2. **Type:** enter commands in the input box at the bottom and press Enter
|
|
112
|
-
3. **Change settings:** click `Cfg` to
|
|
112
|
+
3. **Change settings:** click the config name in the title bar (or `Cfg` → `Edit`) to change port, baud rate, and other settings through the UI
|
|
113
113
|
|
|
114
114
|
Everything works through the UI. No config files to edit unless you want to.
|
|
115
115
|
|
|
@@ -164,6 +164,7 @@ Termapy runs with your privileges and does whatever you — or a connected MCP c
|
|
|
164
164
|
| Ctrl+S | Save SVG screenshot |
|
|
165
165
|
| Ctrl+T | Save text screenshot |
|
|
166
166
|
| Ctrl+P | Command palette |
|
|
167
|
+
| F1–F4 | Help / Cfg / Run / Proto buttons (Ctrl+Shift+1–4 in VS Code); F10 edits the config |
|
|
167
168
|
| Up/Down | Cycle through command history |
|
|
168
169
|
| Escape | Clear input / exit history browsing |
|
|
169
170
|
| Right | Accept type-ahead suggestion |
|
|
@@ -176,10 +177,11 @@ macOS Option-as-Meta, KVM cross-platform keyboards, etc.).
|
|
|
176
177
|
|
|
177
178
|
| Button | Action |
|
|
178
179
|
| ------ | ------------------------------------------------------------------- |
|
|
179
|
-
|
|
|
180
|
-
|
|
|
181
|
-
| `
|
|
182
|
-
| `
|
|
180
|
+
| `Help` | Open the help guide |
|
|
181
|
+
| `Cfg` | Open the config picker (Load / Edit / New / Rename / Delete) |
|
|
182
|
+
| `Run` | Open the script picker (Run / Edit / New / Rename / Delete) |
|
|
183
|
+
| `Proto`| Open the protocol-test picker |
|
|
184
|
+
| `Update` | Appears only when a newer termapy is on PyPI |
|
|
183
185
|
| Center | Click to edit the current config |
|
|
184
186
|
| Port | Click to select a serial port |
|
|
185
187
|
| Status | Click to connect/disconnect (red = disconnected, green = connected) |
|
|
@@ -200,7 +202,7 @@ The most common ones:
|
|
|
200
202
|
| `/ss.svg [name]` | Save SVG screenshot |
|
|
201
203
|
| `/cls` | Clear the terminal |
|
|
202
204
|
| `/run {filename}` | Open Run picker (bare TUI), or run a named script |
|
|
203
|
-
| `/term.echo [on \| off]` |
|
|
205
|
+
| `/term.echo [on \| off]` | Local echo of device commands sent to the wire |
|
|
204
206
|
| `/grep <pattern>` | Search scrollback |
|
|
205
207
|
| `/exit` | Exit termapy |
|
|
206
208
|
|
|
@@ -232,17 +234,18 @@ The most common ones:
|
|
|
232
234
|
| `/port.break {ms}` | Send break signal (default 250ms) |
|
|
233
235
|
| `/cfg [key [value]]` | Open Cfg picker (bare TUI), dump JSON (bare CLI), or get/set with args |
|
|
234
236
|
| `/cfg.auto <key> <value>` | Set an in-memory config key immediately (no confirmation) |
|
|
235
|
-
| `/cfg.
|
|
237
|
+
| `/cfg.list` | List all config files |
|
|
236
238
|
| `/cfg.load <name>` | Switch to a different config by name |
|
|
237
239
|
| `/cfg.show` | Open the current config file in the system viewer |
|
|
238
240
|
| `/cfg.help` | Same as `/help cfg` |
|
|
239
241
|
| `/ss.svg [name]` | Save SVG screenshot |
|
|
240
242
|
| `/ss.txt [name]` | Save text screenshot |
|
|
241
|
-
| `/ss.
|
|
243
|
+
| `/ss.list` | List screenshots, newest first, with size and age |
|
|
244
|
+
| `/ss.explore` | Open the screenshot folder in the system file explorer |
|
|
242
245
|
| `/cls` | Clear the terminal screen |
|
|
243
|
-
| `/run {filename}
|
|
246
|
+
| `/run {filename}` | Open Run picker (bare TUI), list scripts (bare CLI), or run; nests 5 deep |
|
|
244
247
|
| `/run.list` | List .run files in run/, newest first, with size, age, and summary |
|
|
245
|
-
| `/run.
|
|
248
|
+
| `/run.rename <old> <new>` | Rename a script (`.run` kept; never overwrites) |
|
|
246
249
|
| `/run.help` | Same as `/help run` |
|
|
247
250
|
| `/delay <duration>` | Wait for a duration (e.g. `500ms`, `1.5s`) |
|
|
248
251
|
| `/confirm {message}` | Show Yes/Cancel dialog; Cancel stops a running script (see `at_demo.run`) |
|
|
@@ -255,8 +258,8 @@ The most common ones:
|
|
|
255
258
|
| `/show.cfg` | Show the current config file |
|
|
256
259
|
| `/term` | Terminal display / session toggles (echo, line_no, timestamps, ...) |
|
|
257
260
|
| `/term.info` | Snapshot the state of every `/term.*` toggle |
|
|
258
|
-
| `/term.echo [on \| off]` |
|
|
259
|
-
| `/term.
|
|
261
|
+
| `/term.echo [on \| off]` | Local echo of device commands sent to the wire (persisted via cfg `echo`) |
|
|
262
|
+
| `/term.echo_repl [on \| off]` | Local echo of REPL (slash) commands, session only; off inside scripts |
|
|
260
263
|
| `/term.line_no [on \| off]` | Toggle line numbers in serial output (TUI only) |
|
|
261
264
|
| `/term.eol.markers [on \| off]` | Toggle visible `\r` `\n` markers for line-ending troubleshooting |
|
|
262
265
|
| `/term.output {level}` | Show or set output level (silent/quiet/normal/verbose) |
|
|
@@ -270,20 +273,19 @@ The most common ones:
|
|
|
270
273
|
| `/edit.info` | Open the info report in the system viewer |
|
|
271
274
|
| `/os <cmd>` | Run a shell command (10s timeout, requires `TERMAPY_OS_CMD_ENABLED=1` in env) |
|
|
272
275
|
| `/grep <pattern>` | Search scrollback for regex matches (case-insensitive, skips own output) |
|
|
273
|
-
| `/cfg.info {--display}` | Show project summary; `--display` opens full report
|
|
274
|
-
| `/cfg.files` | Show project directory tree |
|
|
276
|
+
| `/cfg.info {--display}` | Show project summary (folder tree + config + buttons); `--display` opens the full report |
|
|
275
277
|
| `/proto` | Open Proto picker (bare TUI) or show long-help (bare CLI) |
|
|
276
278
|
| `/proto.help` | Same as `/help proto` |
|
|
277
279
|
| `/proto.send <hex>` | Send raw hex bytes and/or quoted text, display response as hex (see below) |
|
|
278
280
|
| `/proto.run <file>` | Run a binary protocol test script (.pro) with pass/fail |
|
|
279
281
|
| `/proto.list` | List .pro files in proto/, newest first, with size and age |
|
|
280
|
-
| `/proto.
|
|
282
|
+
| `/proto.rename <old> <new>` | Rename a protocol script (`.pro` kept; never overwrites) |
|
|
281
283
|
| `/proto.hex [on \| off]` | Toggle hex display mode for serial I/O |
|
|
282
284
|
| `/proto.crc.list {pat}` | List available CRC algorithms (optional glob filter) |
|
|
283
285
|
| `/proto.crc.info <name>` | Show CRC algorithm parameters and description |
|
|
284
286
|
| `/proto.crc.calc <n> {d}` | Compute CRC over hex bytes, text, or file; omit data to verify check string |
|
|
285
287
|
| `/proto.crc.find <pkt>` | Identify CRC algorithm from a captured packet (bin= hex or asc= text) |
|
|
286
|
-
| `/proto.
|
|
288
|
+
| `/proto.info` | Print current protocol state |
|
|
287
289
|
| `/var {name}` | List user variables, or show one by name |
|
|
288
290
|
| `/var.set <NAME> <value>` | Set a user variable |
|
|
289
291
|
| `/var.clear` | Clear all user variables |
|
|
@@ -317,18 +319,21 @@ termapy_cfg/
|
|
|
317
319
|
└── demo/
|
|
318
320
|
├── demo.cfg # config file
|
|
319
321
|
├── demo.log # session log
|
|
320
|
-
├── .
|
|
322
|
+
├── demo.history # command history
|
|
321
323
|
├── ss/ # screenshots
|
|
322
324
|
├── run/ # script files for /run
|
|
323
325
|
│ ├── at_demo.run
|
|
324
326
|
│ ├── smoke_test.run
|
|
325
|
-
│
|
|
327
|
+
│ ├── status_check.run
|
|
328
|
+
│ └── ... # gps_demo, var_demo, expect_test, crc_tour, ...
|
|
326
329
|
├── plugin/ # per-config plugins
|
|
327
330
|
│ ├── cmd.py
|
|
328
331
|
│ ├── probe.py
|
|
329
332
|
│ ├── temp_plot.py
|
|
330
333
|
│ └── traffic.py
|
|
331
334
|
├── cap/ # data capture output files
|
|
335
|
+
├── prof/ # /run.profile timing CSVs
|
|
336
|
+
├── viz/ # per-config packet visualizers
|
|
332
337
|
└── proto/ # protocol test scripts
|
|
333
338
|
├── at_test.pro
|
|
334
339
|
├── bitfield_inline.pro
|
|
@@ -426,7 +431,7 @@ Run `/run setup_modbus.run` then `/run test_registers.run`. The variables persis
|
|
|
426
431
|
| `/var.set NAME val` | Set a variable (explicit command form) |
|
|
427
432
|
| `/var.clear` | Clear all variables |
|
|
428
433
|
|
|
429
|
-
**Scope:** Variables persist for the interactive session. They are automatically cleared when a script is launched from the
|
|
434
|
+
**Scope:** Variables persist for the interactive session. They are automatically cleared when a script is launched from the Run picker, but *not* when `/run` is typed interactively or called within a script. This lets you run a setup script to define variables, then run a test script that uses them. Use `/var.clear` to reset manually.
|
|
430
435
|
|
|
431
436
|
**Naming:** Variable names are case-sensitive (`$(PORT)` and `$(port)` are different variables). Names must start with a letter or underscore and contain only letters, digits, and underscores.
|
|
432
437
|
|
|
@@ -435,7 +440,7 @@ Run `/run setup_modbus.run` then `/run test_registers.run`. The variables persis
|
|
|
435
440
|
| Variable | Set when | Updates? |
|
|
436
441
|
| --------------------- | ------------------------------------------- | -------------------- |
|
|
437
442
|
| `$(LAUNCH_DATETIME)` | App starts | Never - frozen |
|
|
438
|
-
| `$(SESSION_DATETIME)` | Script launched (
|
|
443
|
+
| `$(SESSION_DATETIME)` | Script launched (Run picker) | Per script launch |
|
|
439
444
|
| `$(DATETIME)` | Every expansion | Always current clock |
|
|
440
445
|
|
|
441
446
|
Each group also has `_DATE` and `_TIME` variants (e.g. `$(LAUNCH_DATE)`, `$(SESSION_TIME)`).
|
|
@@ -451,7 +456,7 @@ Add a `.gitignore` for session files you don't need to track:
|
|
|
451
456
|
```gitignore
|
|
452
457
|
# termapy_cfg - keep configs and scripts, ignore session files
|
|
453
458
|
termapy_cfg/*/*.log
|
|
454
|
-
termapy_cfg
|
|
459
|
+
termapy_cfg/*/*.history
|
|
455
460
|
termapy_cfg/*/ss/
|
|
456
461
|
```
|
|
457
462
|
|
|
@@ -612,7 +617,7 @@ See the **[config field reference](src/termapy/help/config.md#config-field-refer
|
|
|
612
617
|
|
|
613
618
|
**Note on `eol_markers`:** This is a debug mode for troubleshooting line-ending mismatches (`\r` vs `\n` vs `\r\n`). When enabled, dim `\r` and `\n` markers appear inline in serial output before the characters are consumed by line splitting. Sent commands also show the configured line ending. Since the markers use ANSI escape sequences, they may interfere with device ANSI color output, so turn `eol_markers` off when not actively debugging.
|
|
614
619
|
|
|
615
|
-
**Note on device color (ANSI):** The TUI and CLI render ANSI color (SGR) from device output inline, so colored log lines appear colored. termapy is line-oriented by design and does **not** emulate cursor addressing or full-screen redraws in the TUI - for devices that drive the terminal that way (menus, `top`/`vi` on an embedded console, bootloader UIs), use `--vt100` (see the VT100 mode section below), which hands raw bytes to your own terminal to emulate. In the CLI, `--no-color` (or `/term.color off`) strips color for clean piping. Over MCP, color defaults **off** so device ANSI is stripped from the JSON an agent receives (`/term.color on` re-enables passthrough); silence it at the source with `color off` in `mcp_on_connect_cmd`.
|
|
620
|
+
**Note on device color (ANSI):** The TUI and CLI render ANSI color (SGR) from device output inline, so colored log lines appear colored. termapy is line-oriented by design and does **not** emulate cursor addressing or full-screen redraws in the TUI - for devices that drive the terminal that way (menus, `top`/`vi` on an embedded console, bootloader UIs), use `--vt100` (see the VT100 mode section below), which hands raw bytes to your own terminal to emulate. In the CLI, `--no-color` (or `/term.color off`) strips color for clean piping. Over MCP, color defaults **off** so device ANSI is stripped from the JSON an agent receives (`/term.color on` re-enables passthrough); silence it at the source with the device's own `color off` in `mcp_on_connect_cmd`.
|
|
616
621
|
|
|
617
622
|
</details>
|
|
618
623
|
|
|
@@ -621,9 +626,9 @@ See the **[config field reference](src/termapy/help/config.md#config-field-refer
|
|
|
621
626
|
<details>
|
|
622
627
|
<summary><strong>Scripting</strong> - automate command sequences with text files</summary>
|
|
623
628
|
|
|
624
|
-

|
|
625
630
|
|
|
626
|
-
Create text files with one command per line and run them from the Run button or with
|
|
631
|
+
Create text files with one command per line and run them from the **Run** button or with `/run`. In the file, lines starting with `/` are REPL commands, lines starting with `#` are comments and everything else is sent to the device.
|
|
627
632
|
|
|
628
633
|
```text
|
|
629
634
|
# Quick status check
|
|
@@ -843,7 +848,7 @@ Summary: 4/4 PASS (4 tests)
|
|
|
843
848
|
|
|
844
849
|
### CRC algorithms
|
|
845
850
|
|
|
846
|
-
Every CRC algorithm in the [reveng catalog](https://reveng.sourceforge.io/crc-catalogue/all.htm) (maintained by Greg Cook -- see [ACKNOWLEDGMENTS](src/termapy/help/acknowledgments.md)) is built in, with full parameterization (poly, init, refin, refout, xorout) and each one verified against its catalog check value in the test suite. If you need a CRC and it has a name, termapy already has it, correctly. Browse with `/proto.crc.list`, inspect with `/proto.crc.info <name>`, compute with `/proto.crc.calc`, identify an unknown one from a captured packet with `/proto.crc.find`. You can also generate standalone C, Python, or
|
|
851
|
+
Every CRC algorithm in the [reveng catalog](https://reveng.sourceforge.io/crc-catalogue/all.htm) (maintained by Greg Cook -- see [ACKNOWLEDGMENTS](src/termapy/help/acknowledgments.md)) is built in, with full parameterization (poly, init, refin, refout, xorout) and each one verified against its catalog check value in the test suite. If you need a CRC and it has a name, termapy already has it, correctly. Browse with `/proto.crc.list`, inspect with `/proto.crc.info <name>`, compute with `/proto.crc.calc`, identify an unknown one from a captured packet with `/proto.crc.find`. You can also generate standalone C, C#, Go, Java, Lua, Python, Rust, TypeScript, Verilog, VHDL, or Zig source for any of them with `/proto.crc.python`, `/proto.crc.c`, `/proto.crc.rust` so you never have to port one by hand again.
|
|
847
852
|
|
|
848
853
|
</details>
|
|
849
854
|
|
|
@@ -907,9 +912,9 @@ Modbus RTU supports function 0x03 (read holding registers) and 0x06 (write singl
|
|
|
907
912
|
|
|
908
913
|
The demo comes with everything wired up so you can try each feature:
|
|
909
914
|
|
|
910
|
-
- **Scripts:** `at_demo.run`, `smoke_test.run`, `status_check.run
|
|
915
|
+
- **Scripts:** `at_demo.run`, `smoke_test.run`, `status_check.run`, `gps_demo.run`, `var_demo.run`, `expect_test.run`, `crc_tour.run`, and more. Run via the Run button or `/run`.
|
|
911
916
|
- **Proto test files:** `at_test.pro`, `bitfield_inline.pro`, `modbus_inline.pro`. Run via the Proto button for pass/fail results.
|
|
912
|
-
- **Plugins:** `/probe` sends a command sequence and reports results; `/cmd` adds a custom shortcut.
|
|
917
|
+
- **Plugins:** `/probe` sends a command sequence and reports results; `/cmd` adds a custom shortcut; `/temp_plot` draws a sparkline; `/traffic.*` taps RX/TX bytes.
|
|
913
918
|
|
|
914
919
|
</details>
|
|
915
920
|
|
|
@@ -935,16 +940,16 @@ Passing a `.run` file to `--cli` automatically infers the config from the file's
|
|
|
935
940
|
|
|
936
941
|
**Features:**
|
|
937
942
|
|
|
938
|
-
- Rich colored output (toggle with `/color on|off` or `--no-color`)
|
|
943
|
+
- Rich colored output (toggle with `/term.color on|off` or `--no-color`)
|
|
939
944
|
- Command history shared with TUI (up/down arrows, persisted across sessions)
|
|
940
945
|
- Tab completion for REPL commands
|
|
941
946
|
- Script execution with `/run` (same scripts work in both TUI and CLI)
|
|
942
|
-
- `/delay` with progress bar for waits
|
|
947
|
+
- `/delay` with progress bar for waits of a second or longer (Ctrl+C to cancel)
|
|
943
948
|
- All `/port`, `/cfg`, `/var`, `/env`, `/proto.crc`, `/edit` commands work
|
|
944
949
|
|
|
945
950
|
**TUI-only features** (not available in CLI mode):
|
|
946
951
|
|
|
947
|
-
- `/ss.svg`, `/ss.txt` - screenshots (
|
|
952
|
+
- `/ss.svg`, `/ss.txt` - screenshots (fail the `screen_capture` capability gate with a clear error)
|
|
948
953
|
- `/grep` - scrollback search (no scrollback buffer in CLI)
|
|
949
954
|
- `/edit.cfg` - opens in system editor instead of built-in config editor
|
|
950
955
|
- Mouse interaction, modal dialogs, custom buttons
|
|
@@ -1055,7 +1060,6 @@ The `ctx` object passed to every handler is a thin shell over **five capability
|
|
|
1055
1060
|
| `ctx.io.notify(text)` | Always-works fallback notification (toast in TUI, plain in CLI) |
|
|
1056
1061
|
| `ctx.io.log(prefix, text)` | Write to session log: `">"` TX, `"<"` RX, `"#"` status |
|
|
1057
1062
|
| `ctx.serial.is_connected` | Bool: serial port is open |
|
|
1058
|
-
| `ctx.serial.port` | The raw pyserial object, or `None` when disconnected |
|
|
1059
1063
|
| `ctx.serial.write(data)` | Send bytes to the serial port (auto-logged as TX) |
|
|
1060
1064
|
| `ctx.serial.read_raw(timeout_ms)` | Read raw bytes with timeout framing (returns `bytes`) |
|
|
1061
1065
|
| `ctx.serial.drain()` | Drain pending RX data |
|
|
@@ -1099,6 +1103,8 @@ See `examples/plugins/` for working examples:
|
|
|
1099
1103
|
- **at_test.py:** send AT commands over serial
|
|
1100
1104
|
- **timestamp.py:** print the current date/time
|
|
1101
1105
|
- **ping.py:** send a command and measure response time
|
|
1106
|
+
- **traffic.py:** passive RX/TX byte tap (count, hexdump, rate, snoop) -- also shipped with `--demo`
|
|
1107
|
+
- **pic_map.py:** decode a PIC memory map
|
|
1102
1108
|
|
|
1103
1109
|
More complete examples ship with `--demo`: `probe.py` demonstrates the drain → write → read → parse cycle for device interaction; `traffic.py` (with `/traffic.count`, `/traffic.hexdump`, `/traffic.rate`, `/traffic.snoop`) demonstrates the passive RX/TX observer pattern via the `ctx.serial.rx_observer()` / `ctx.serial.tx_observer()` context managers. Run `/help probe` or `/help traffic` to see the documentation, or `/help.dev <name>` for the source docstrings.
|
|
1104
1110
|
|
|
@@ -1143,7 +1149,7 @@ Actual: 01 00 C9 FF FE 0A -> ID:01 Temp:201 Signed:-2 Status:0A
|
|
|
1143
1149
|
| `F` | IEEE 754 float | `F1-4` | `3.14` |
|
|
1144
1150
|
| `B` | Bit field | `B1.3`, `B1-2.7-9` | `1`, `5` |
|
|
1145
1151
|
| `_` | Padding (hidden) | `_:_3-4` | *(skipped)* |
|
|
1146
|
-
| `crc*` | CRC verify | `CRC:
|
|
1152
|
+
| `crc*` | CRC verify | `CRC:crc16-modbus_le` | pass/fail |
|
|
1147
1153
|
|
|
1148
1154
|
Integers support 1, 2, 3, 4, and 8 byte widths. Floats are 4-byte (F32) or 8-byte (F64).
|
|
1149
1155
|
|
|
@@ -1244,19 +1250,19 @@ Textual runs on a single async event loop. Termapy uses `@work(thread=True)` for
|
|
|
1244
1250
|
|
|
1245
1251
|
| Worker | Lifetime | Purpose |
|
|
1246
1252
|
| ------------------- | ----------- | ------------------------------------------------------- |
|
|
1247
|
-
| `
|
|
1248
|
-
| `
|
|
1253
|
+
| `SerialEngine.read_loop()` | Long-lived | The reader thread (`start_reader` / `stop_reader`); hands RX to the UI without blocking |
|
|
1254
|
+
| `_run_reconnect()` | Short-lived | Retries serial connection every 2.5s until success |
|
|
1249
1255
|
| `_run_lines()` | Short-lived | Sends multiple commands with inter-command delay |
|
|
1250
1256
|
| `_run_script()` | Short-lived | Executes a `.run` script file line by line |
|
|
1251
|
-
| `_send_test()` | Short-lived | Runs a single protocol test case (
|
|
1252
|
-
| `_run_cmds()` | Short-lived | Sends setup/teardown commands for protocol tests
|
|
1257
|
+
| `_send_test()` | Short-lived | Runs a single protocol test case (`proto_debug.py`) |
|
|
1258
|
+
| `_run_cmds()` | Short-lived | Sends setup/teardown commands for protocol tests (`proto_debug.py`) |
|
|
1253
1259
|
|
|
1254
|
-
Only
|
|
1260
|
+
Only the reader is long-lived. At most two workers run concurrently: the serial reader plus one command/script/test worker.
|
|
1255
1261
|
|
|
1256
1262
|
</details>
|
|
1257
1263
|
|
|
1258
1264
|
<details>
|
|
1259
|
-
<summary><strong>Test coverage</strong> -
|
|
1265
|
+
<summary><strong>Test coverage</strong> - 3394 tests, 72% core-module coverage</summary>
|
|
1260
1266
|
|
|
1261
1267
|
Run the full suite with `uv run pytest`. (The count above is the one place it
|
|
1262
1268
|
is tracked; `release_prep` refreshes it each release.)
|
|
@@ -1273,7 +1279,7 @@ generator permutation.
|
|
|
1273
1279
|
|
|
1274
1280
|
**Built-in plugins:** broad coverage via `test_builtins.py` plus per-plugin test files (`test_var.py`, `test_env_var.py`, `test_xmodem.py`, `test_ymodem.py`, `test_app_plugin.py`, `test_proto_send_crc.py`, etc.).
|
|
1275
1281
|
|
|
1276
|
-
**UI code:** `app.py
|
|
1282
|
+
**UI code:** `app.py` is driven headless by `tests/test_app_pilot.py` (Textual Pilot boots the real app), and the dialogs have Pilot tests of their own; `proto_debug.py` is still exercised manually. The headline coverage figure is **core-module** coverage, measured with `dialogs/`, the `builtins/` package top level, and vendored code **omitted** (see `[tool.coverage.run]` in `pyproject.toml`) — so it is *not* whole-repo coverage. Counting the whole repo (only vendored third-party code omitted) is lower, and that gap is exactly this untested UI layer. The omit is deliberate — the focus has been on extracting business logic into unit-testable modules and keeping the UI as thin delegation — but the headline number is core-module, not overall.
|
|
1277
1283
|
|
|
1278
1284
|
</details>
|
|
1279
1285
|
|
|
@@ -12,7 +12,7 @@ Runs on Windows, macOS, and Linux. A serial interface terminal like PuTTY or Ter
|
|
|
12
12
|
|
|
13
13
|
Low time commitment: about 1 minute from scratch, or under 10 seconds if you already have [uv](https://docs.astral.sh/uv/) installed.
|
|
14
14
|
|
|
15
|
-

|
|
16
16
|
|
|
17
17
|
## Install and connect
|
|
18
18
|
|
|
@@ -63,7 +63,7 @@ There's a lot more: scripting, binary protocol testing, every CRC algorithm in t
|
|
|
63
63
|
|
|
64
64
|
1. **Connect:** click the port button in the title bar, pick your COM port, click the status button to connect (it turns green)
|
|
65
65
|
2. **Type:** enter commands in the input box at the bottom and press Enter
|
|
66
|
-
3. **Change settings:** click `Cfg` to
|
|
66
|
+
3. **Change settings:** click the config name in the title bar (or `Cfg` → `Edit`) to change port, baud rate, and other settings through the UI
|
|
67
67
|
|
|
68
68
|
Everything works through the UI. No config files to edit unless you want to.
|
|
69
69
|
|
|
@@ -118,6 +118,7 @@ Termapy runs with your privileges and does whatever you — or a connected MCP c
|
|
|
118
118
|
| Ctrl+S | Save SVG screenshot |
|
|
119
119
|
| Ctrl+T | Save text screenshot |
|
|
120
120
|
| Ctrl+P | Command palette |
|
|
121
|
+
| F1–F4 | Help / Cfg / Run / Proto buttons (Ctrl+Shift+1–4 in VS Code); F10 edits the config |
|
|
121
122
|
| Up/Down | Cycle through command history |
|
|
122
123
|
| Escape | Clear input / exit history browsing |
|
|
123
124
|
| Right | Accept type-ahead suggestion |
|
|
@@ -130,10 +131,11 @@ macOS Option-as-Meta, KVM cross-platform keyboards, etc.).
|
|
|
130
131
|
|
|
131
132
|
| Button | Action |
|
|
132
133
|
| ------ | ------------------------------------------------------------------- |
|
|
133
|
-
|
|
|
134
|
-
|
|
|
135
|
-
| `
|
|
136
|
-
| `
|
|
134
|
+
| `Help` | Open the help guide |
|
|
135
|
+
| `Cfg` | Open the config picker (Load / Edit / New / Rename / Delete) |
|
|
136
|
+
| `Run` | Open the script picker (Run / Edit / New / Rename / Delete) |
|
|
137
|
+
| `Proto`| Open the protocol-test picker |
|
|
138
|
+
| `Update` | Appears only when a newer termapy is on PyPI |
|
|
137
139
|
| Center | Click to edit the current config |
|
|
138
140
|
| Port | Click to select a serial port |
|
|
139
141
|
| Status | Click to connect/disconnect (red = disconnected, green = connected) |
|
|
@@ -154,7 +156,7 @@ The most common ones:
|
|
|
154
156
|
| `/ss.svg [name]` | Save SVG screenshot |
|
|
155
157
|
| `/cls` | Clear the terminal |
|
|
156
158
|
| `/run {filename}` | Open Run picker (bare TUI), or run a named script |
|
|
157
|
-
| `/term.echo [on \| off]` |
|
|
159
|
+
| `/term.echo [on \| off]` | Local echo of device commands sent to the wire |
|
|
158
160
|
| `/grep <pattern>` | Search scrollback |
|
|
159
161
|
| `/exit` | Exit termapy |
|
|
160
162
|
|
|
@@ -186,17 +188,18 @@ The most common ones:
|
|
|
186
188
|
| `/port.break {ms}` | Send break signal (default 250ms) |
|
|
187
189
|
| `/cfg [key [value]]` | Open Cfg picker (bare TUI), dump JSON (bare CLI), or get/set with args |
|
|
188
190
|
| `/cfg.auto <key> <value>` | Set an in-memory config key immediately (no confirmation) |
|
|
189
|
-
| `/cfg.
|
|
191
|
+
| `/cfg.list` | List all config files |
|
|
190
192
|
| `/cfg.load <name>` | Switch to a different config by name |
|
|
191
193
|
| `/cfg.show` | Open the current config file in the system viewer |
|
|
192
194
|
| `/cfg.help` | Same as `/help cfg` |
|
|
193
195
|
| `/ss.svg [name]` | Save SVG screenshot |
|
|
194
196
|
| `/ss.txt [name]` | Save text screenshot |
|
|
195
|
-
| `/ss.
|
|
197
|
+
| `/ss.list` | List screenshots, newest first, with size and age |
|
|
198
|
+
| `/ss.explore` | Open the screenshot folder in the system file explorer |
|
|
196
199
|
| `/cls` | Clear the terminal screen |
|
|
197
|
-
| `/run {filename}
|
|
200
|
+
| `/run {filename}` | Open Run picker (bare TUI), list scripts (bare CLI), or run; nests 5 deep |
|
|
198
201
|
| `/run.list` | List .run files in run/, newest first, with size, age, and summary |
|
|
199
|
-
| `/run.
|
|
202
|
+
| `/run.rename <old> <new>` | Rename a script (`.run` kept; never overwrites) |
|
|
200
203
|
| `/run.help` | Same as `/help run` |
|
|
201
204
|
| `/delay <duration>` | Wait for a duration (e.g. `500ms`, `1.5s`) |
|
|
202
205
|
| `/confirm {message}` | Show Yes/Cancel dialog; Cancel stops a running script (see `at_demo.run`) |
|
|
@@ -209,8 +212,8 @@ The most common ones:
|
|
|
209
212
|
| `/show.cfg` | Show the current config file |
|
|
210
213
|
| `/term` | Terminal display / session toggles (echo, line_no, timestamps, ...) |
|
|
211
214
|
| `/term.info` | Snapshot the state of every `/term.*` toggle |
|
|
212
|
-
| `/term.echo [on \| off]` |
|
|
213
|
-
| `/term.
|
|
215
|
+
| `/term.echo [on \| off]` | Local echo of device commands sent to the wire (persisted via cfg `echo`) |
|
|
216
|
+
| `/term.echo_repl [on \| off]` | Local echo of REPL (slash) commands, session only; off inside scripts |
|
|
214
217
|
| `/term.line_no [on \| off]` | Toggle line numbers in serial output (TUI only) |
|
|
215
218
|
| `/term.eol.markers [on \| off]` | Toggle visible `\r` `\n` markers for line-ending troubleshooting |
|
|
216
219
|
| `/term.output {level}` | Show or set output level (silent/quiet/normal/verbose) |
|
|
@@ -224,20 +227,19 @@ The most common ones:
|
|
|
224
227
|
| `/edit.info` | Open the info report in the system viewer |
|
|
225
228
|
| `/os <cmd>` | Run a shell command (10s timeout, requires `TERMAPY_OS_CMD_ENABLED=1` in env) |
|
|
226
229
|
| `/grep <pattern>` | Search scrollback for regex matches (case-insensitive, skips own output) |
|
|
227
|
-
| `/cfg.info {--display}` | Show project summary; `--display` opens full report
|
|
228
|
-
| `/cfg.files` | Show project directory tree |
|
|
230
|
+
| `/cfg.info {--display}` | Show project summary (folder tree + config + buttons); `--display` opens the full report |
|
|
229
231
|
| `/proto` | Open Proto picker (bare TUI) or show long-help (bare CLI) |
|
|
230
232
|
| `/proto.help` | Same as `/help proto` |
|
|
231
233
|
| `/proto.send <hex>` | Send raw hex bytes and/or quoted text, display response as hex (see below) |
|
|
232
234
|
| `/proto.run <file>` | Run a binary protocol test script (.pro) with pass/fail |
|
|
233
235
|
| `/proto.list` | List .pro files in proto/, newest first, with size and age |
|
|
234
|
-
| `/proto.
|
|
236
|
+
| `/proto.rename <old> <new>` | Rename a protocol script (`.pro` kept; never overwrites) |
|
|
235
237
|
| `/proto.hex [on \| off]` | Toggle hex display mode for serial I/O |
|
|
236
238
|
| `/proto.crc.list {pat}` | List available CRC algorithms (optional glob filter) |
|
|
237
239
|
| `/proto.crc.info <name>` | Show CRC algorithm parameters and description |
|
|
238
240
|
| `/proto.crc.calc <n> {d}` | Compute CRC over hex bytes, text, or file; omit data to verify check string |
|
|
239
241
|
| `/proto.crc.find <pkt>` | Identify CRC algorithm from a captured packet (bin= hex or asc= text) |
|
|
240
|
-
| `/proto.
|
|
242
|
+
| `/proto.info` | Print current protocol state |
|
|
241
243
|
| `/var {name}` | List user variables, or show one by name |
|
|
242
244
|
| `/var.set <NAME> <value>` | Set a user variable |
|
|
243
245
|
| `/var.clear` | Clear all user variables |
|
|
@@ -271,18 +273,21 @@ termapy_cfg/
|
|
|
271
273
|
└── demo/
|
|
272
274
|
├── demo.cfg # config file
|
|
273
275
|
├── demo.log # session log
|
|
274
|
-
├── .
|
|
276
|
+
├── demo.history # command history
|
|
275
277
|
├── ss/ # screenshots
|
|
276
278
|
├── run/ # script files for /run
|
|
277
279
|
│ ├── at_demo.run
|
|
278
280
|
│ ├── smoke_test.run
|
|
279
|
-
│
|
|
281
|
+
│ ├── status_check.run
|
|
282
|
+
│ └── ... # gps_demo, var_demo, expect_test, crc_tour, ...
|
|
280
283
|
├── plugin/ # per-config plugins
|
|
281
284
|
│ ├── cmd.py
|
|
282
285
|
│ ├── probe.py
|
|
283
286
|
│ ├── temp_plot.py
|
|
284
287
|
│ └── traffic.py
|
|
285
288
|
├── cap/ # data capture output files
|
|
289
|
+
├── prof/ # /run.profile timing CSVs
|
|
290
|
+
├── viz/ # per-config packet visualizers
|
|
286
291
|
└── proto/ # protocol test scripts
|
|
287
292
|
├── at_test.pro
|
|
288
293
|
├── bitfield_inline.pro
|
|
@@ -380,7 +385,7 @@ Run `/run setup_modbus.run` then `/run test_registers.run`. The variables persis
|
|
|
380
385
|
| `/var.set NAME val` | Set a variable (explicit command form) |
|
|
381
386
|
| `/var.clear` | Clear all variables |
|
|
382
387
|
|
|
383
|
-
**Scope:** Variables persist for the interactive session. They are automatically cleared when a script is launched from the
|
|
388
|
+
**Scope:** Variables persist for the interactive session. They are automatically cleared when a script is launched from the Run picker, but *not* when `/run` is typed interactively or called within a script. This lets you run a setup script to define variables, then run a test script that uses them. Use `/var.clear` to reset manually.
|
|
384
389
|
|
|
385
390
|
**Naming:** Variable names are case-sensitive (`$(PORT)` and `$(port)` are different variables). Names must start with a letter or underscore and contain only letters, digits, and underscores.
|
|
386
391
|
|
|
@@ -389,7 +394,7 @@ Run `/run setup_modbus.run` then `/run test_registers.run`. The variables persis
|
|
|
389
394
|
| Variable | Set when | Updates? |
|
|
390
395
|
| --------------------- | ------------------------------------------- | -------------------- |
|
|
391
396
|
| `$(LAUNCH_DATETIME)` | App starts | Never - frozen |
|
|
392
|
-
| `$(SESSION_DATETIME)` | Script launched (
|
|
397
|
+
| `$(SESSION_DATETIME)` | Script launched (Run picker) | Per script launch |
|
|
393
398
|
| `$(DATETIME)` | Every expansion | Always current clock |
|
|
394
399
|
|
|
395
400
|
Each group also has `_DATE` and `_TIME` variants (e.g. `$(LAUNCH_DATE)`, `$(SESSION_TIME)`).
|
|
@@ -405,7 +410,7 @@ Add a `.gitignore` for session files you don't need to track:
|
|
|
405
410
|
```gitignore
|
|
406
411
|
# termapy_cfg - keep configs and scripts, ignore session files
|
|
407
412
|
termapy_cfg/*/*.log
|
|
408
|
-
termapy_cfg
|
|
413
|
+
termapy_cfg/*/*.history
|
|
409
414
|
termapy_cfg/*/ss/
|
|
410
415
|
```
|
|
411
416
|
|
|
@@ -566,7 +571,7 @@ See the **[config field reference](src/termapy/help/config.md#config-field-refer
|
|
|
566
571
|
|
|
567
572
|
**Note on `eol_markers`:** This is a debug mode for troubleshooting line-ending mismatches (`\r` vs `\n` vs `\r\n`). When enabled, dim `\r` and `\n` markers appear inline in serial output before the characters are consumed by line splitting. Sent commands also show the configured line ending. Since the markers use ANSI escape sequences, they may interfere with device ANSI color output, so turn `eol_markers` off when not actively debugging.
|
|
568
573
|
|
|
569
|
-
**Note on device color (ANSI):** The TUI and CLI render ANSI color (SGR) from device output inline, so colored log lines appear colored. termapy is line-oriented by design and does **not** emulate cursor addressing or full-screen redraws in the TUI - for devices that drive the terminal that way (menus, `top`/`vi` on an embedded console, bootloader UIs), use `--vt100` (see the VT100 mode section below), which hands raw bytes to your own terminal to emulate. In the CLI, `--no-color` (or `/term.color off`) strips color for clean piping. Over MCP, color defaults **off** so device ANSI is stripped from the JSON an agent receives (`/term.color on` re-enables passthrough); silence it at the source with `color off` in `mcp_on_connect_cmd`.
|
|
574
|
+
**Note on device color (ANSI):** The TUI and CLI render ANSI color (SGR) from device output inline, so colored log lines appear colored. termapy is line-oriented by design and does **not** emulate cursor addressing or full-screen redraws in the TUI - for devices that drive the terminal that way (menus, `top`/`vi` on an embedded console, bootloader UIs), use `--vt100` (see the VT100 mode section below), which hands raw bytes to your own terminal to emulate. In the CLI, `--no-color` (or `/term.color off`) strips color for clean piping. Over MCP, color defaults **off** so device ANSI is stripped from the JSON an agent receives (`/term.color on` re-enables passthrough); silence it at the source with the device's own `color off` in `mcp_on_connect_cmd`.
|
|
570
575
|
|
|
571
576
|
</details>
|
|
572
577
|
|
|
@@ -575,9 +580,9 @@ See the **[config field reference](src/termapy/help/config.md#config-field-refer
|
|
|
575
580
|
<details>
|
|
576
581
|
<summary><strong>Scripting</strong> - automate command sequences with text files</summary>
|
|
577
582
|
|
|
578
|
-

|
|
579
584
|
|
|
580
|
-
Create text files with one command per line and run them from the Run button or with
|
|
585
|
+
Create text files with one command per line and run them from the **Run** button or with `/run`. In the file, lines starting with `/` are REPL commands, lines starting with `#` are comments and everything else is sent to the device.
|
|
581
586
|
|
|
582
587
|
```text
|
|
583
588
|
# Quick status check
|
|
@@ -797,7 +802,7 @@ Summary: 4/4 PASS (4 tests)
|
|
|
797
802
|
|
|
798
803
|
### CRC algorithms
|
|
799
804
|
|
|
800
|
-
Every CRC algorithm in the [reveng catalog](https://reveng.sourceforge.io/crc-catalogue/all.htm) (maintained by Greg Cook -- see [ACKNOWLEDGMENTS](src/termapy/help/acknowledgments.md)) is built in, with full parameterization (poly, init, refin, refout, xorout) and each one verified against its catalog check value in the test suite. If you need a CRC and it has a name, termapy already has it, correctly. Browse with `/proto.crc.list`, inspect with `/proto.crc.info <name>`, compute with `/proto.crc.calc`, identify an unknown one from a captured packet with `/proto.crc.find`. You can also generate standalone C, Python, or
|
|
805
|
+
Every CRC algorithm in the [reveng catalog](https://reveng.sourceforge.io/crc-catalogue/all.htm) (maintained by Greg Cook -- see [ACKNOWLEDGMENTS](src/termapy/help/acknowledgments.md)) is built in, with full parameterization (poly, init, refin, refout, xorout) and each one verified against its catalog check value in the test suite. If you need a CRC and it has a name, termapy already has it, correctly. Browse with `/proto.crc.list`, inspect with `/proto.crc.info <name>`, compute with `/proto.crc.calc`, identify an unknown one from a captured packet with `/proto.crc.find`. You can also generate standalone C, C#, Go, Java, Lua, Python, Rust, TypeScript, Verilog, VHDL, or Zig source for any of them with `/proto.crc.python`, `/proto.crc.c`, `/proto.crc.rust` so you never have to port one by hand again.
|
|
801
806
|
|
|
802
807
|
</details>
|
|
803
808
|
|
|
@@ -861,9 +866,9 @@ Modbus RTU supports function 0x03 (read holding registers) and 0x06 (write singl
|
|
|
861
866
|
|
|
862
867
|
The demo comes with everything wired up so you can try each feature:
|
|
863
868
|
|
|
864
|
-
- **Scripts:** `at_demo.run`, `smoke_test.run`, `status_check.run
|
|
869
|
+
- **Scripts:** `at_demo.run`, `smoke_test.run`, `status_check.run`, `gps_demo.run`, `var_demo.run`, `expect_test.run`, `crc_tour.run`, and more. Run via the Run button or `/run`.
|
|
865
870
|
- **Proto test files:** `at_test.pro`, `bitfield_inline.pro`, `modbus_inline.pro`. Run via the Proto button for pass/fail results.
|
|
866
|
-
- **Plugins:** `/probe` sends a command sequence and reports results; `/cmd` adds a custom shortcut.
|
|
871
|
+
- **Plugins:** `/probe` sends a command sequence and reports results; `/cmd` adds a custom shortcut; `/temp_plot` draws a sparkline; `/traffic.*` taps RX/TX bytes.
|
|
867
872
|
|
|
868
873
|
</details>
|
|
869
874
|
|
|
@@ -889,16 +894,16 @@ Passing a `.run` file to `--cli` automatically infers the config from the file's
|
|
|
889
894
|
|
|
890
895
|
**Features:**
|
|
891
896
|
|
|
892
|
-
- Rich colored output (toggle with `/color on|off` or `--no-color`)
|
|
897
|
+
- Rich colored output (toggle with `/term.color on|off` or `--no-color`)
|
|
893
898
|
- Command history shared with TUI (up/down arrows, persisted across sessions)
|
|
894
899
|
- Tab completion for REPL commands
|
|
895
900
|
- Script execution with `/run` (same scripts work in both TUI and CLI)
|
|
896
|
-
- `/delay` with progress bar for waits
|
|
901
|
+
- `/delay` with progress bar for waits of a second or longer (Ctrl+C to cancel)
|
|
897
902
|
- All `/port`, `/cfg`, `/var`, `/env`, `/proto.crc`, `/edit` commands work
|
|
898
903
|
|
|
899
904
|
**TUI-only features** (not available in CLI mode):
|
|
900
905
|
|
|
901
|
-
- `/ss.svg`, `/ss.txt` - screenshots (
|
|
906
|
+
- `/ss.svg`, `/ss.txt` - screenshots (fail the `screen_capture` capability gate with a clear error)
|
|
902
907
|
- `/grep` - scrollback search (no scrollback buffer in CLI)
|
|
903
908
|
- `/edit.cfg` - opens in system editor instead of built-in config editor
|
|
904
909
|
- Mouse interaction, modal dialogs, custom buttons
|
|
@@ -1009,7 +1014,6 @@ The `ctx` object passed to every handler is a thin shell over **five capability
|
|
|
1009
1014
|
| `ctx.io.notify(text)` | Always-works fallback notification (toast in TUI, plain in CLI) |
|
|
1010
1015
|
| `ctx.io.log(prefix, text)` | Write to session log: `">"` TX, `"<"` RX, `"#"` status |
|
|
1011
1016
|
| `ctx.serial.is_connected` | Bool: serial port is open |
|
|
1012
|
-
| `ctx.serial.port` | The raw pyserial object, or `None` when disconnected |
|
|
1013
1017
|
| `ctx.serial.write(data)` | Send bytes to the serial port (auto-logged as TX) |
|
|
1014
1018
|
| `ctx.serial.read_raw(timeout_ms)` | Read raw bytes with timeout framing (returns `bytes`) |
|
|
1015
1019
|
| `ctx.serial.drain()` | Drain pending RX data |
|
|
@@ -1053,6 +1057,8 @@ See `examples/plugins/` for working examples:
|
|
|
1053
1057
|
- **at_test.py:** send AT commands over serial
|
|
1054
1058
|
- **timestamp.py:** print the current date/time
|
|
1055
1059
|
- **ping.py:** send a command and measure response time
|
|
1060
|
+
- **traffic.py:** passive RX/TX byte tap (count, hexdump, rate, snoop) -- also shipped with `--demo`
|
|
1061
|
+
- **pic_map.py:** decode a PIC memory map
|
|
1056
1062
|
|
|
1057
1063
|
More complete examples ship with `--demo`: `probe.py` demonstrates the drain → write → read → parse cycle for device interaction; `traffic.py` (with `/traffic.count`, `/traffic.hexdump`, `/traffic.rate`, `/traffic.snoop`) demonstrates the passive RX/TX observer pattern via the `ctx.serial.rx_observer()` / `ctx.serial.tx_observer()` context managers. Run `/help probe` or `/help traffic` to see the documentation, or `/help.dev <name>` for the source docstrings.
|
|
1058
1064
|
|
|
@@ -1097,7 +1103,7 @@ Actual: 01 00 C9 FF FE 0A -> ID:01 Temp:201 Signed:-2 Status:0A
|
|
|
1097
1103
|
| `F` | IEEE 754 float | `F1-4` | `3.14` |
|
|
1098
1104
|
| `B` | Bit field | `B1.3`, `B1-2.7-9` | `1`, `5` |
|
|
1099
1105
|
| `_` | Padding (hidden) | `_:_3-4` | *(skipped)* |
|
|
1100
|
-
| `crc*` | CRC verify | `CRC:
|
|
1106
|
+
| `crc*` | CRC verify | `CRC:crc16-modbus_le` | pass/fail |
|
|
1101
1107
|
|
|
1102
1108
|
Integers support 1, 2, 3, 4, and 8 byte widths. Floats are 4-byte (F32) or 8-byte (F64).
|
|
1103
1109
|
|
|
@@ -1198,19 +1204,19 @@ Textual runs on a single async event loop. Termapy uses `@work(thread=True)` for
|
|
|
1198
1204
|
|
|
1199
1205
|
| Worker | Lifetime | Purpose |
|
|
1200
1206
|
| ------------------- | ----------- | ------------------------------------------------------- |
|
|
1201
|
-
| `
|
|
1202
|
-
| `
|
|
1207
|
+
| `SerialEngine.read_loop()` | Long-lived | The reader thread (`start_reader` / `stop_reader`); hands RX to the UI without blocking |
|
|
1208
|
+
| `_run_reconnect()` | Short-lived | Retries serial connection every 2.5s until success |
|
|
1203
1209
|
| `_run_lines()` | Short-lived | Sends multiple commands with inter-command delay |
|
|
1204
1210
|
| `_run_script()` | Short-lived | Executes a `.run` script file line by line |
|
|
1205
|
-
| `_send_test()` | Short-lived | Runs a single protocol test case (
|
|
1206
|
-
| `_run_cmds()` | Short-lived | Sends setup/teardown commands for protocol tests
|
|
1211
|
+
| `_send_test()` | Short-lived | Runs a single protocol test case (`proto_debug.py`) |
|
|
1212
|
+
| `_run_cmds()` | Short-lived | Sends setup/teardown commands for protocol tests (`proto_debug.py`) |
|
|
1207
1213
|
|
|
1208
|
-
Only
|
|
1214
|
+
Only the reader is long-lived. At most two workers run concurrently: the serial reader plus one command/script/test worker.
|
|
1209
1215
|
|
|
1210
1216
|
</details>
|
|
1211
1217
|
|
|
1212
1218
|
<details>
|
|
1213
|
-
<summary><strong>Test coverage</strong> -
|
|
1219
|
+
<summary><strong>Test coverage</strong> - 3394 tests, 72% core-module coverage</summary>
|
|
1214
1220
|
|
|
1215
1221
|
Run the full suite with `uv run pytest`. (The count above is the one place it
|
|
1216
1222
|
is tracked; `release_prep` refreshes it each release.)
|
|
@@ -1227,7 +1233,7 @@ generator permutation.
|
|
|
1227
1233
|
|
|
1228
1234
|
**Built-in plugins:** broad coverage via `test_builtins.py` plus per-plugin test files (`test_var.py`, `test_env_var.py`, `test_xmodem.py`, `test_ymodem.py`, `test_app_plugin.py`, `test_proto_send_crc.py`, etc.).
|
|
1229
1235
|
|
|
1230
|
-
**UI code:** `app.py
|
|
1236
|
+
**UI code:** `app.py` is driven headless by `tests/test_app_pilot.py` (Textual Pilot boots the real app), and the dialogs have Pilot tests of their own; `proto_debug.py` is still exercised manually. The headline coverage figure is **core-module** coverage, measured with `dialogs/`, the `builtins/` package top level, and vendored code **omitted** (see `[tool.coverage.run]` in `pyproject.toml`) — so it is *not* whole-repo coverage. Counting the whole repo (only vendored third-party code omitted) is lower, and that gap is exactly this untested UI layer. The omit is deliberate — the focus has been on extracting business logic into unit-testable modules and keeping the UI as thin delegation — but the headline number is core-module, not overall.
|
|
1231
1237
|
|
|
1232
1238
|
</details>
|
|
1233
1239
|
|