Skip to main content

dsh overview

The dsh command provides DanteTerm's core command line interface, allowing users to interact with both terminal and graphical elements from the command line. This guide covers the basics of using dsh and its key features.

See the dsh reference for a list of all dsh commands and their arguments.

Overview​

At its core, dsh enables seamless interaction between your terminal commands and DanteTerm's graphical blocks. It allows you to:

  • Control graphical widgets directly from the command line
  • Share data between terminal sessions and GUI components
  • Manage your workspace programmatically
  • Connect remote and local environments
  • Run terminal commands in separate, isolated blocks

Key Concepts​

Interacting with Blocks​

dsh provides direct interaction with DanteTerm's graphical blocks through the command line. For example:

# Open a file in the editor
dsh edit config.json

# Get the current file path from a preview block
dsh getmeta -b 2 file

Persistent State​

dsh can maintain state across terminal sessions through its variable system:

# Store a variable that persists across sessions
dsh setvar API_KEY=abc123

# Store globally
dsh setvar DEPLOY_ENV=prod
# Or store in the current workspace
dsh setvar -b workspace DEPLOY_ENV=staging

# Use stored variables in commands
curl -H "Authorization: $(dsh getvar API_KEY)" https://api.example.com

Accessing Local Files from Remote​

When working on remote machines, you can access files on your local computer using the dsh://local/~/ path prefix with dsh file commands. The shorthand /~/ can also be used as an alias for dsh://local/~/:

# Read a local file from a remote machine
dsh file cat dsh://local/~/config/app.json

# Run a local script on the remote machine using shell process substitution
bash <(dsh file cat dsh://local/~/scripts/deploy.sh)
python <(dsh file cat dsh://local/~/scripts/deploy.py)

# Append remote output to a local log file
echo "Remote machine log entry" | dsh file append dsh://local/~/app.log

# Copy a local file to the remote machine
dsh file cp dsh://local/~/data.csv ./remote-data.csv

# Copy remote file back to local machine
dsh file cp ./results.txt dsh://local/~/results.txt

# You can also use the shorthand /~/ instead of dsh://local/~/
dsh file cat /~/config/app.json

Block Management​

Every visual element in DanteTerm is a block, and dsh gives you complete control over them (hold Ctrl+Shift to see block numbers):

# Create a new block showing a webpage
dsh web open github.com

# Do a web search in a new block
dsh web open "danteterm terminal"

# Run a command in a new block and auto-close when done
dsh run -x -- npm test

# Get information about the current block
dsh getmeta

Tabs, block placement, and terminal input can be scripted together:

# Make a dedicated tab -- it comes up with one terminal -- and park it first in the tab bar
dsh tab create logs
dsh tab move logs 1

# Split it, giving the new terminal 40% of the pair
dsh createblock term --tab logs --target 1 --position right --size 40

# Start the dev server in the left terminal
dsh sendkeys --tab logs -b 1 --enter "npm run dev"

# Later, grab the last command's output for use elsewhere
dsh termscrollback --tab logs -b 1 --lastcommand

Common Workflows​

Here are some common ways to use dsh:

Development Workflow​

# Open directory or markdown files
dsh view .
dsh view README.md

# add a -m to open the block in "magnified" mode
dsh view -m README.md

# Start development server in a new block (-m will magnify the block on startup)
dsh run -m -- npm run dev

# Open documentation in a web block
dsh web open http://localhost:3000

Remote Development​

# Connect to remote server with optional key
dsh ssh -i ~/.ssh/mykey.pem dev@server

# Edit remote files
dsh edit /etc/nginx/nginx.conf

# Monitor remote logs
dsh run -- tail -f /var/log/app.log

# Share variables between sessions
dsh setvar -b tab SHARED_ENV=staging

Tips & Features​

  1. Working with Blocks

    • Use block numbers (1-9) to target specific blocks within a tab (hold Ctrl+Shift to see block numbers)
    • Can get full block ids by right click a block's header and selecting "Copy Block Id" (useful for scripting)
    • Use references like "this", "tab", "workspace", or "global" for different scopes
  2. Data Storage

    • Use dsh setvar/getvar for configuration and secrets
    • Store file data using dsh file, which can be easily referenced in all terminals (local and remote)
    • Use appropriate storage scopes (block, tab, workspace, global)
  3. Command Execution

    • Use dsh run to execute commands in new blocks

Scripting with dsh​

dsh commands can be combined in scripts to automate common tasks. Here's an example that sets up a development environment and uses dsh notify to monitor a long-running build:

#!/bin/bash
# Setup development environment
dsh run -- docker-compose up -d
dsh web open localhost:8080
dsh view ./src
dsh run -- npm run test:watch

# Get notified when long-running tasks complete using dsh notify
npm run build && dsh notify "Build complete" || dsh notify "Build failed"

Running dsh Outside a Session​

dsh normally runs inside a DanteTerm-managed block, where the environment tells it which block, tab, and workspace it's in. You can also run it from any ordinary shell on the same machine -- a plain terminal, a script, an agent -- as long as DanteTerm has been launched at least once. There is no separate setup: dsh finds the app's data directory itself and reads the credential the server leaves there for exactly this case.

Outside a session there's no ambient block or tab to fall back on, so every target has to be named explicitly:

# Find the workspace to act on -- this is the one command that needs no target at all
dsh workspace list

# List the tabs in that workspace
dsh tab list --workspace <workspace-id>

# Create a block in a specific tab of a specific workspace
dsh createblock --workspace <workspace-id> --tab 1 term

--workspace takes a workspace id (as printed by dsh workspace list); --tab takes a number, a name, or an id; --block (or -b) takes a block number or id the same way it does inside a session.

If DanteTerm isn't running, or dsh is pointed at the wrong install (see below), commands fail with DanteTerm is not running, naming the data directory it probed.

Commands that only make sense inside a session​

Some commands act on "the current" block or tab and have no --workspace/--tab flags to name one explicitly -- outside a session there's nothing for them to act on. This includes view, web, editor, term, run, launch, ssh, wsl, secret, editconfig, and dantepath. Run these from inside a DanteTerm block, or use createblock, blocks list, tab, sendkeys, termscrollback, focusblock, and deleteblock, which all accept an explicit target.

More than one DanteTerm install​

If both a released build and a dev build are installed, dsh probes for whichever one has an existing data directory and prefers the released build's when both exist -- which is not the same as "whichever one is running". If dsh reports DanteTerm is not running while an app is clearly open, or drives the wrong window, point it at the right install explicitly:

DANTETERM_DATA_HOME=~/Library/Application\ Support/danteterm-dev dsh tab list

Windows: Microsoft Store installs​

A Store install runs under MSIX filesystem virtualisation: the app's data directory lives under %LOCALAPPDATA%\Packages\Dante.K.DanteTerm_<id>\LocalCache\Local\danteterm\Data, and the plain %LOCALAPPDATA%\danteterm\Data never exists. dsh looks there on its own, so nothing needs to be configured; DANTETERM_DATA_HOME still overrides it if you have more than one install. On Windows the local channel is a loopback TCP port chosen when the app starts rather than a socket file, because the socket path resolves to a different directory for every process identity (the app, a Store-installed PowerShell, and an ordinary shell each see their own).

What this means for security​

The credential dsh reads outside a session is a real, signed token, not a convenience flag -- whatever process can read it can create blocks, send keystrokes into terminals, and read scrollback (which can contain anything you've typed, including secrets pasted into a shell). The file is written mode 0600, so on a machine where every user's home directory tree is private (the default on macOS), only you can read it. On Linux, this depends on your home directory's permissions -- ~/.local/share is commonly world-readable by default, in which case another local user could see that the file exists (though not read its contents, since the file itself stays 0600). On Windows the token sits inside your user profile, which other users cannot read, and the loopback port only accepts a caller that presents it -- the same model the app's own web and websocket listeners already use. Treat the ability to run arbitrary code as yourself, on this machine, as the same trust boundary as being able to drive DanteTerm: they're the same thing.

Getting Help​

You can get help on available commands by running dsh with no arguments, or get detailed help for a specific command using dsh [command] -h.

For a complete reference of all dsh functionality, see the DSH Command Reference.