dsh-tui
Recipe card from the charly-tools plugin (Images — the deployable catalog).
dsh-tui – the DeepSeek Harness terminal UI plugin
Section titled “dsh-tui – the DeepSeek Harness terminal UI plugin”dsh-TUI (https://github.com/ccch1mneyyy/dsh-TUI, npm
@deepseek-harness-tui/dsh-tui) is a pure DSH plugin, not a
daemon. It is added to a dsh profile and launched by the shipped
dsh-tui / dst launcher (or dsh --profile dsh-tui). The candy
dsh-tui composes the dsh CLI candy and adds the plugin + a typed
terminal channel.
Candy Properties
Section titled “Candy Properties”| Property | Value |
|---|---|
| Install files | charly.yml, package.json |
| Depends | dsh (the CLI candy), layer-tmux |
| Env | DSH_TUI_NO_LAUNCHPAD=1 (boot straight to the composer) |
| Channel | terminal_profile: dsh-tui + agent_provide: tmux |
| Profile | $DSH_HOME/profiles/dsh-tui (auto-bootstrapped on first launch) |
Deterministic first launch
Section titled “Deterministic first launch”The first-run wizard is pre-recorded at ~/.dsh-tui/onboarding.json
({"completed":true,"version":1}) and the launchpad is disabled
(DSH_TUI_NO_LAUNCHPAD=1), so the process lands directly on the chat
screen with no keyboard-owning dialog — the state a terminal channel
can drive. Without both, an ordinary launch opens the wizard or the
launchpad, which own the keyboard.
The terminal channel
Section titled “The terminal channel”The candy publishes a terminal_profile (entrypoint dsh-tui) and an
agent_provide: {provider: tmux, profiles: [dsh-tui]} capability. A
disposable bed or a host controller drives it through
charly agent terminal launch/snapshot/input/key/transcript. A
terminal channel is on-demand, not a long-running service: a
service-less box that carries it must be held at steady state by
check-keepalive’s sleep infinity supervisord program.
Driving the channel deterministically
Section titled “Driving the channel deterministically”The channel is a real terminal, so it must be driven the way a terminal behaves — not the way a service does:
- Unique run-ids.
launch/input/snapshot/closeare keyed by--run-id. A hardcoded run-id collides whencheck-liveandcheck-live-rebuildrun the same plan in one session; derive a fresh id per step (auuidgen/date +%s%N-style value), never a literal. snapshotis a render of the viewport, so it is scroll/cursor dependent — a text that scrolled off is gone. To assert content, read the durabletranscript(the full session log), not a snapshot taken at an arbitrary moment.closecloses the control channel, not the process. The TUI keeps running under tmux after aclose; do not rely oncloseto reap it, and never launch a second session against the same target while a first is still attached — two concurrent control sessions on one pod contend for the same tmux server.- The interactive submit is keyboard-timing racy. Typing a prompt
and injecting the submit key can race the TUI’s redraw, so a
pass/fail that depends on the enter landing is flaky by
construction. An interactive TUI’s liveness is proven by the
channel (
launch→ non-emptytranscript→close); the live model turn it fronts is asserted separately with a one-shot, non-interactivedsh --headlesscall in the same box.
my-tui-box: candy: - dsh-tuicharly start my-tui-box# drive the TUI through the channel:charly agent terminal launch '{"name":"dsh-tui","entrypoint":["dsh-tui"],"cols":140,"rows":44,"keys":["enter"]}' --target my-tui-box --run-id <uuid>Related
Section titled “Related”/charly-tools:dsh– the CLI + web-UI candy family (dsh,dsh-web)/charly-check:check— the R10 bedcheck-dsh-tui-pod/charly-image:layer— candy authoring reference

