Skip to content
DocsAll docs
Console

kode

Lists the commands and options of kode, the command-line program for your computer.

Last updated

On this page

Commands

The CLI on your laptop. It opens your desk, connects you to workspaces over ssh, and reaches a desk's environment by service name. Every SDK method is also a command, kode <resource> <verb>, for example kode workspaces list. A command prints a table, or with --json the answer unchanged; on an error it prints the server's message and exits with a non-zero code. KODE_URL and KODE_TOKEN replace the login. It does not run inside a workspace; there the tool is kd.

Install: curl -fsSL https://dev.kloudlite.io/install.sh | sh puts kode (and kd-tui, where it is built for your platform) in ~/.local/bin. The binaries are the kode-v* releases on GitHub for x86_64-apple-darwin, aarch64-apple-darwin, x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu. You can also download them there by hand, with their sha256sums file. The quick start has the details. Log in once with kode login; the token is stored under ~/.config/kode. env daemon, the network helper, is macOS only.

The reference below is generated from the command definitions; kode --help prints the same.

kode

kode on your laptop: kode opens your desk, kode TEAM the team's

ArgumentHelp
<team>Team whose desk to open; your own desk when absent
--teamThe team, as a flag: kode -t TEAM -s DESK reads like ssh -t -s
--startStart the desk first (and its stopped workspaces)
--deskDesk (name or id) to open; asked on a terminal when unclear
--jsonPrint the answer verbatim as JSON (resource commands), for scripts and agents

kode login

Log in through the browser and store the CLI token

ArgumentHelp
--apiAPI address to log in to
--no-rootDo not ask for your password to install the network helper; run kode start later

kode start

Run the background service now (it also starts at login) and check the network helper

ArgumentHelp
--no-rootDo not ask for your password to install the network helper

kode stop

Stop the background service; kode start runs it again

kode status

Show the background service, this machine's device and the network helper

kode logout

Revoke this machine's CLI token and forget it

kode mcp

Serve the desk's tools (all workspaces, environments, pod tools) as a stdio MCP server: claude mcp add kd -- kode mcp

ArgumentHelp
<team>Team whose desk to serve; your own when absent
--deskDesk (name or id) to serve

kode update

Update kode (and kd-tui, if it sits beside it) to the latest release

ArgumentHelp
--checkOnly report whether a newer version exists

kode doctor

Check that login, the api, your desk, the kl tools, Claude Code and the model providers work: one pass/fail line each, and a failing exit code when one fails

ArgumentHelp
<team>Team whose desk to check; your own when absent

kode config

Read or change a CLI setting (workspaces_dir)

kode config set

Set a setting; the value is validated before it is written

ArgumentHelp
<key>
<value>

kode config get

Print a setting

ArgumentHelp
<key>

kode devices

Run workspaces on this machine, in a sandbox, with their folders under workspaces_dir (kode config set workspaces_dir PATH): macOS only for now

kode devices register

Make this machine your device again (login does it); the workspaces folder is workspaces_dir: kode config set workspaces_dir PATH

kode devices list

List your devices; * marks this machine

kode devices enable

Let this machine's device run workspaces again; the service starts its worker within seconds

kode devices disable

Stop this machine's worker; its workspaces stop and nothing is deleted

kode devices connect

Make this machine's device active in an account: your own handle or a team you belong to. The account it leaves sees it offline; nothing is deleted

ArgumentHelp
<account>Your handle or a team slug

kode devices doctor

Check that this machine can sandbox workspaces

kode devices access

Named extra sandbox access a device workspace may ask for (its access list): the built-in development definitions and your own, kept in this machine's config. Nothing is granted unless a workspace names it

kode devices access list

Every definition on this machine: built in, overridden, hidden or yours

kode devices access add

Define NAME (a built-in name replaces that built-in; no paths hides it). ~ is your home folder

ArgumentHelp
<name>1-32 of a-z, 0-9 and -
--readA path the workspace may read (repeatable)
--writeA path the workspace may read and write (repeatable)

kode devices access rm

Remove your definition of NAME; a built-in name is the built-in definition again

ArgumentHelp
<name>

kode devices workspaces

Workspaces that run on a device

kode devices workspaces create

Create a workspace on this device; its folder is {workspaces_dir}/{name}

ArgumentHelp
<name>Workspace name (a-z, 0-9, -, at most 40); it is the folder name
--deskJoin this desk (id) as it is created
--teamCreate it in this team's scope; the device must be active in that team (devices connect)
--accessNamed extra sandbox access (repeatable), defined on this machine: kode devices access list

kode devices workspaces list

List the workspaces of your devices

kode devices workspaces start

Start a workspace

ArgumentHelp
<name>Workspace name

kode devices workspaces stop

Stop a workspace

ArgumentHelp
<name>Workspace name

kode devices workspaces delete

Delete a workspace; its folder is moved to {workspaces_dir}/.trash and purged after 7 days

ArgumentHelp
<name>Workspace name

kode devices workspaces snapshot

Snapshot a workspace: a copy-on-write clone of its folder in {workspaces_dir}/.snapshots, on this disk only (APFS). The workspace restarts while it is made. Waits for the device to finish

ArgumentHelp
<name>Workspace name
--messageWhat the snapshot is for

kode devices workspaces snapshots

List a workspace's snapshots, newest first

ArgumentHelp
<name>Workspace name

kode devices workspaces restore

Put a snapshot back as the workspace's folder; the folder it replaces goes to the trash. Waits

ArgumentHelp
<name>Workspace name
<snapshot>Snapshot id

kode devices workspaces clone

Make a new workspace on the snapshot's device whose folder is a clone of the snapshot

ArgumentHelp
<snapshot>Snapshot id
<name>Name of the new workspace (it is the folder name)

kode devices workspaces snapshot-delete

Delete a snapshot; its folder is moved to {workspaces_dir}/.trash and purged after 7 days. Waits

ArgumentHelp
<snapshot>Snapshot id

kode env

Reach the desk's environment's services by name from this laptop

kode env status

Show what the network helper put on this Mac: names, loopback addresses, port redirects

kode quota

The ceiling and what is against it

ArgumentHelp
--ownerA handle or team; your own when absent

kode request

Send any request to the api: kode request GET /v1/quota

ArgumentHelp
<http_method>GET, POST, PUT, PATCH, or DELETE
<api_path>Path, e.g. /v1/quota
--bodyRequest body as JSON (or @file)
--queryKEY=VALUE query parameter; repeat for more

kode environments

Multi-service environments

kode environments create

Create an environment

ArgumentHelp
<environment>Name, or team/name for a team's
--servicesServices as JSON (or @file): [{"name","image","ports","env","command","mounts"}]
--snapshotGrow it from a snapshot
--ttl-secsSeconds unused before it is deleted (600..=2592000)

kode environments list

List your environments and your teams'

ArgumentHelp
--ownerOnly this handle or team's

kode environments get

Show an environment

ArgumentHelp
<environment>Environment: name, team/name, or id

kode environments set-services

Replace the whole service list

ArgumentHelp
<environment>Environment: name, team/name, or id
--servicesServices as JSON (or @file)

kode environments start

Start an environment

ArgumentHelp
<environment>Environment: name, team/name, or id

kode environments stop

Stop an environment

ArgumentHelp
<environment>Environment: name, team/name, or id

kode environments restart

Restart one running service so it gets its current env vars

ArgumentHelp
<environment>Environment: name, team/name, or id
--serviceThe service to restart

kode environments set-ttl

Set or clear the unused-time limit

ArgumentHelp
<environment>Environment: name, team/name, or id
--ttl-secsSeconds unused before it is deleted (600..=2592000); absent clears it

kode environments delete

Delete an environment

ArgumentHelp
<environment>Environment: name, team/name, or id

kode environments clone

Make a new environment from this one

ArgumentHelp
<environment>Environment: name, team/name, or id
--toThe new environment: name or team/name
--snapshotClone one of its snapshots instead of the live disk
--servicesServices as JSON (or @file): [{"name","image","ports","env","command","mounts"}]

kode environments restore

Put this environment back to one of its snapshots

ArgumentHelp
<environment>Environment: name, team/name, or id
--snapshotSnapshot id
--discardA service whose data may be lost; repeat for more

kode volumes

Volumes: list, get, versions, delete, delete-version

kode volumes list

List volumes

ArgumentHelp
--kindworkspace or environment
--ownerOnly this handle or team's

kode volumes get

A volume by name

ArgumentHelp
--ownerA handle or team; your own when absent
<volume>Volume: name or owner/name

kode volumes versions

The versions of a volume

ArgumentHelp
--ownerA handle or team; your own when absent
<volume>Volume: name or owner/name

kode volumes delete

Delete a detached volume with all its snapshots

ArgumentHelp
--ownerA handle or team; your own when absent
<volume>Volume: name or owner/name

kode volumes delete-version

Delete one version of a volume

ArgumentHelp
--ownerA handle or team; your own when absent
<volume>Volume: name or owner/name
<n>Version number

kode snapshots

Snapshots: push, list, and delete

kode snapshots push

Push a snapshot of a workspace's working copy (--workspace) or of every service's data in an environment (--environment)

ArgumentHelp
--workspaceWorkspace: name, team/name, or id
--environmentEnvironment: name, team/name, or id
--messageA message for the snapshot
--volumeVolume name; required on a volume's first push

kode snapshots list

The snapshots of a volume, newest first

ArgumentHelp
<volume>Volume: key, name, or owner/name

kode snapshots refs

A volume's refs

ArgumentHelp
<volume>Volume: key, name, or owner/name

kode snapshots delete

Delete a snapshot

ArgumentHelp
<volume>Volume: key, name, or owner/name
<snapshot>Snapshot id

kode connectors

Linked provider accounts: list and remove (connect in the web console)

kode connectors list

The accounts linked to you or, with --owner, to a team: name, provider, account, and state

ArgumentHelp
--ownerThe team; your own handle when absent

kode connectors remove

Disconnect a connector: pipelines and pushes that use it stop working. Connecting needs a browser, so it is in the web console

ArgumentHelp
<name>Connector name, as connectors list shows it

kode secrets

An owner's secrets: set (value from stdin only), list names, delete

kode secrets set

Store NAME; the value is read from stdin, never an argument: printf %s "$V" | kode secrets set NAME. With a team --owner it is your own secret in that team (only you see it; it wins over the team's of the same name in your workspaces); add --scope team for the team's shared secret (admins)

ArgumentHelp
<name>Secret name
--ownerThe team; your own handle when absent (your personal secret, no team)
--scopeWith a team --owner: team is the team's shared secret (admins); absent it is your own secret in that team

kode secrets list

The names, who set them and when (values are never shown); with a team --owner, your own in that team; --scope team lists the team's shared ones

ArgumentHelp
--ownerThe team; your own handle when absent (your personal secrets, no team)
--scopeWith a team --owner: team is the team's shared secret (admins); absent it is your own secret in that team

kode secrets delete

Remove NAME; refused while a workspace references it (an environment too, unless it is your own secret in a team, which is the default with a team --owner, and succeeds while the team holds a secret of that name; --scope team removes the team's shared one)

ArgumentHelp
<name>Secret name
--ownerThe team; your own handle when absent (your personal secret, no team)
--scopeWith a team --owner: team is the team's shared secret (admins); absent it is your own secret in that team

kode capsules

Throwaway machines that run code

kode capsules create

Ask for a capsule that runs one process; answers at once, usually still starting: kode capsules create -- python3 job.py

ArgumentHelp
--imageImage to start from
--packageA nixpkgs attribute; repeat for more
--from-workspaceStart from one of your workspaces
--from-snapshotSnapshot: name, name@N, or a snapshot id
--teamThe team that owns it
--networkinternet or none
--cpuCores
--memory-gbMemory in GB
--timeout-sSeconds it lives at most
--envNAME=VALUE; repeat for more
--ttyGive the process a terminal
--stdinKeep its stdin open so attach can type to it
<cmd>The process the capsule runs and its arguments, after --

kode capsules get

Show a capsule

ArgumentHelp
<capsule>Capsule id

kode capsules list

List your capsules, newest first, 50 at a time; --all follows every page

ArgumentHelp
--teamOnly this team's
--limitAt most this many per page (1 to 200)
--cursorContinue after the cursor a previous page printed
--allFollow the cursor until every capsule is listed

kode capsules run

Run one process in a fresh capsule, print its output and exit with its code; with --stdin attach to it instead: kode capsules run -it -- sh

ArgumentHelp
--imageImage to start from
--packageA nixpkgs attribute; repeat for more
--from-workspaceStart from one of your workspaces
--from-snapshotSnapshot: name, name@N, or a snapshot id
--teamThe team that owns it
--networkinternet or none
--cpuCores
--memory-gbMemory in GB
--timeout-sSeconds it lives at most
--envNAME=VALUE; repeat for more
--ttyGive the process a terminal
--stdinKeep its stdin open so attach can type to it
<cmd>The process the capsule runs and its arguments, after --

kode capsules logs

Print the process's output so far, or until it ends with --follow

ArgumentHelp
<capsule>Capsule id
--followKeep printing until the process ends

kode capsules attach

Attach this terminal to the process of a capsule made with --stdin; leaving does not stop it

ArgumentHelp
<capsule>Capsule id

kode capsules terminate

Stop a capsule for good; the record stays until deleted

ArgumentHelp
<capsule>Capsule id

kode capsules wait

Wait until a capsule has terminated, print the reason and exit with the process's code

ArgumentHelp
<capsule>Capsule id
--timeout-sGive up after this many seconds

kode capsules wait-running

Wait until a capsule is running; fails with the reason if it terminates instead

ArgumentHelp
<capsule>Capsule id
--timeout-sGive up after this many seconds

kode capsules delete

Delete a terminated capsule's record

ArgumentHelp
<capsule>Capsule id

kode pipelines

CI pipelines and their runs

kode pipelines create

Save a new pipeline from a JSON definition; a webhook URL is shown once

ArgumentHelp
--fileThe definition as a JSON file; - reads stdin
--ownerA handle or team; your own when absent

kode pipelines update

Save a definition as the pipeline's next version; the same definition saves nothing

ArgumentHelp
<name>Pipeline: name or owner/name
--fileThe definition as a JSON file; - reads stdin
--ownerA handle or team; your own when absent

kode pipelines list

List an owner's pipelines

ArgumentHelp
--ownerA handle or team; your own when absent

kode pipelines get

Show a pipeline's definition, the newest version unless --version

ArgumentHelp
<name>Pipeline: name or owner/name
--ownerA handle or team; your own when absent
--versionA version number; the newest when absent

kode pipelines versions

List a pipeline's saved versions

ArgumentHelp
<name>Pipeline: name or owner/name
--ownerA handle or team; your own when absent

kode pipelines delete

Delete a pipeline with its versions; its old runs stay

ArgumentHelp
<name>Pipeline: name or owner/name
--ownerA handle or team; your own when absent

kode pipelines run

Start a pipeline by hand; answers the queued run

ArgumentHelp
<name>Pipeline: name or owner/name
--ownerA handle or team; your own when absent
--versionA version number; the newest when absent
--inputKEY=VALUE for the definition's inputs; repeat for more
--environmentRun jobs that name none in this environment
--cloneRun them in a per-run copy of this environment
--keyMakes a retry one run: a second start with the same key answers the run the first made

kode pipelines rotate-webhook

Mint a new webhook URL; the old one stops at once and the new one is shown once

ArgumentHelp
<name>Pipeline: name or owner/name
--ownerA handle or team; your own when absent

kode pipelines runs

A pipeline's runs, newest first

ArgumentHelp
<owner>The pipeline's owner: a handle or team
<pipeline>Pipeline name
--limitAt most this many

kode pipelines get-run

Show one run

ArgumentHelp
<owner>The pipeline's owner: a handle or team
<pipeline>Pipeline name
<run>Run id

kode pipelines cancel-run

Ask a run to stop

ArgumentHelp
<owner>The pipeline's owner: a handle or team
<pipeline>Pipeline name
<run>Run id

kode pipelines logs

Print a job's log; --follow keeps going until the job ends

ArgumentHelp
<owner>The pipeline's owner: a handle or team
<pipeline>Pipeline name
<run>Run id
<job>The job's index or key
--followPoll for new output until the job ends
--poll-sSeconds between polls

kode pipelines wait-run

Wait for a run to end, print its state, exit non-zero unless it succeeded

ArgumentHelp
<owner>The pipeline's owner: a handle or team
<pipeline>Pipeline name
<run>Run id
--timeout-sGive up after this many seconds
--poll-sSeconds between polls

kode ide

A workspace's tool server: files, commands, processes, watches, builds

kode ide list

List every tool with its schema

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)

kode ide call

Run any tool by name with its arguments as JSON

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<tool>Tool name
--argsThe tool's arguments as JSON (or @file)

kode ide read

Read files

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--pathOne file
--pathsA file; repeat for more
--offsetFirst line
--limitNumber of lines

kode ide write

Write a file

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--pathFile path
--contentThe content

kode ide edit

Edit one file (--path, --edits) or several (--files); atomic

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--pathOne file
--editsEdits as JSON: [{"old","new","replace_all"}]
--filesSeveral files as JSON: [{"path","edits"}]

kode ide patch

Apply a unified diff

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--diffThe diff
--cwdWorking directory

kode ide glob

Find files by pattern

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--patternGlob pattern
--cwdWorking directory

kode ide grep

Search file contents

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--patternRegular expression
--cwdWorking directory
--globOnly files matching this
--modeOutput mode
--contextLines of context
--ignore-caseIgnore case
--maxAt most this many matches

kode ide exec

Run a shell command

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--cmdThe command line
--cwdWorking directory
--envNAME=VALUE; repeat for more
--timeout-msTime limit in milliseconds
--headKeep the first N lines of output
--tailKeep the last N lines of output
--quietPrint only the exit code
--detachRun as a process and answer its id

kode ide process-list

List processes

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)

kode ide process-output

A process's output

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<process>Process id
--sinceStdout offset
--since-errStderr offset

kode ide process-write

Write to a process's stdin

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<process>Process id
--dataThe text

kode ide process-kill

Signal a process

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<process>Process id
--signalA signal name

kode ide watch

Watch paths for changes

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--pathA path; repeat for more
--cmdRun this on a change
--patternOnly matching paths
--onceStop after the first change

kode ide watch-poll

Events from a watch

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<watch>Watch id
--sinceOffset

kode ide watch-stop

Stop a watch

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
<watch>Watch id

kode ide container-build

Build an image in the workspace

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--tagAn image tag; repeat for more
--contextBuild context
--fileDockerfile
--build-argA build arg; repeat for more
--platformPlatform
--no-cacheSkip the cache
--timeout-msTime limit in milliseconds
--headKeep the first N lines of output
--tailKeep the last N lines of output

kode ide container-push

Copy an image the registry holds to new tags

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--urlTool server address; default is the one the api names (use http://127.0.0.1:7788 under kode workspaces ide)
--srcSource image
--dstA destination tag; repeat for more

kode workspaces

Dev workspaces: create, start, stop, clone, restore, and reach one over ssh

kode workspaces create

Create a workspace

ArgumentHelp
<workspace>Name, or team/name for a team's
--imageCustom image
--packageA nixpkgs attribute, optionally attr@version; repeat for more
--ttl-secsSeconds unused before it is deleted (600..=2592000)
--envNAME=VALUE or NAME='${{ secrets.X }}'; repeat for more

kode workspaces list

List your workspaces

ArgumentHelp
--teamOnly this team's

kode workspaces get

Show a workspace

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces delete

Delete a workspace; its volume survives while a snapshot references it

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces start

Start a workspace

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces stop

Stop a workspace

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces restart

Restart a running workspace so it gets its current env vars

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces clone

Make a new workspace from this one's state

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--toThe new workspace's name
--taskA task for the new workspace

kode workspaces restore

Make a new workspace from a snapshot

ArgumentHelp
--snapshotSnapshot: name, name@N, or a snapshot id
--teamTeam whose volume names to resolve
--toThe new workspace's name
--imageOverride the snapshot's image
--packageOverride the snapshot's packages; repeat for more

kode workspaces set-packages

Replace the package list

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--packageA nixpkgs attribute, optionally attr@version; repeat for more

kode workspaces set-ttl

Set or clear the unused-time limit

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--ttl-secsSeconds unused before it is deleted (600..=2592000); absent clears it

kode workspaces set-env

Replace the whole env; it takes effect on the next start

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--envNAME=VALUE or NAME='${{ secrets.X }}'; repeat for more

kode workspaces update-packages

Re-resolve every pinned package

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces tools

The tool server's address and token (owner only)

ArgumentHelp
<workspace>Workspace: name, team/name, or id

kode workspaces ssh

ssh into a workspace: kode workspaces ssh gh -- -A

ArgumentHelp
<target>Workspace: name, team/name, or id
<args>Passed to ssh unchanged

kode workspaces proxy

ssh's ProxyCommand: pump stdio to the workspace's gateway tunnel

ArgumentHelp
<id>Workspace id

kode workspaces ssh-config

Write ~/.ssh/kode_config and Include it from ~/.ssh/config

kode workspaces ide

Tunnel the workspace's tool API to localhost: kode workspaces ide api, then curl http://localhost:7788/tools

ArgumentHelp
<target>Workspace: name, team/name, or id
--portLocal port to listen on

kode workspaces follow

Print the output of a detached process in a workspace until it ends, and exit with its code; reconnects after laptop sleep without losing or repeating output

ArgumentHelp
<ws>Workspace name or id
<id>Process id
--teamTeam the workspace belongs to; your own when absent
--deskThe desk that holds the process; without it the usual resolution applies

kode desks

Desks: workspaces connected to one environment, and their intercepts

kode desks create

Create a desk

ArgumentHelp
<desk>Name, or team/name for a team's
--environmentAn environment of the desk's team
--ttl-secsSeconds unused before it is deleted (600..=2592000)

kode desks set-ttl

Set or clear the unused-time limit

ArgumentHelp
<desk>Desk: name, team/name, or id
--ttl-secsSeconds unused before it is deleted (600..=2592000); absent clears it

kode desks list

List your desks

ArgumentHelp
--teamOnly this team's

kode desks get

Show a desk with its workspaces and intercepts

ArgumentHelp
<desk>Desk: name, team/name, or id

kode desks delete

Delete a desk, the workspaces made in it and its intercepts; snapshots stay

ArgumentHelp
<desk>Desk: name, team/name, or id

kode desks connect-env

Set or switch the desk's environment

ArgumentHelp
<environment>Environment id, name, or team/name
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks disconnect-env

Clear the desk's environment

ArgumentHelp
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks stop

Stop a desk and every workspace in it

ArgumentHelp
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks start

Start a desk and every workspace in it

ArgumentHelp
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks create-workspace

Create a workspace in a desk; the desk stops, starts, and deletes it

ArgumentHelp
<workspace>Name, or team/name
--imageCustom image
--packageA nixpkgs attribute, optionally attr@version; repeat for more
--ttl-secsSeconds unused before it is deleted (600..=2592000)
--envNAME=VALUE or NAME='${{ secrets.X }}'; repeat for more
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks clone-workspace

Clone a workspace into a desk; the desk stops, starts, and deletes the copy. A device workspace is cloned from a snapshot of it

ArgumentHelp
<workspace>Workspace: name, team/name, or id
--toThe new workspace's name
--snapshotA device workspace: the snapshot to clone, by id
--taskA task for the new workspace
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks delete-workspace

Delete a workspace made in a desk

ArgumentHelp
<workspace>Workspace id or name
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks create-capsule

Run one process in a new capsule in a desk; the capsule ends with its command, the desk deletes it, and it reaches the desk's environment: kode desks create-capsule -- python3 job.py

ArgumentHelp
--imageImage to start from
--packageA nixpkgs attribute; repeat for more
--from-workspaceStart from one of your workspaces
--from-snapshotSnapshot: name, name@N, or a snapshot id
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>
--networkinternet or none
--cpuCores
--memory-gbMemory in GB
--timeout-sSeconds it lives at most
--envNAME=VALUE; repeat for more
--ttyGive the process a terminal
--stdinKeep its stdin open so attach can type to it
<cmd>The process the capsule runs and its arguments, after --

kode desks intercept

Send everything that calls a service to a workspace

ArgumentHelp
<service>The service to take over
--workspaceA managed workspace that answers
--portSERVICE_PORT=WORKSPACE_PORT, e.g. 8080=3000; repeat for more
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks release

Release an intercept

ArgumentHelp
<service>The service
--deskDesk: name, team/name, or id; default the one last opened with kode -s <desk>

kode desks current

Show the desk this laptop is in

Which desk

kode with no subcommand needs a desk before it can open it. It takes --desk, else the desk you last opened with -s if it still exists, else your only desk, else it asks (on a terminal only; elsewhere pass --desk). With none at all it creates one called main with no environment, and you connect one later with desk connect. The pick is saved in desk.json, which the environment daemon reads too, so opening a desk with -s also moves the tunnel.

Environment tunnel

kode login and kode start set up the tunnel. The background service follows desk.json. It opens a tunnel as you, and one loopback address 127.77.x.y answers for each service of the desk's environment. A name such as db.main resolves to that address. Only TCP is reachable. A service port below 1024 is redirected on its address to the port plus 60000.

Each other desk of the account answers {service}.{desk} on addresses of its own. Its tunnel stays closed until a connection uses one of its names. A desk line shows parked, up or error.

kode env status and kode status print the same two sections:

text
tunnel: up, desk dev-desk (account default), environment reachtest  web 127.77.0.2: 80 (via 60080)  db 127.77.0.3: 5432, 6000 port in usedesk review-1: parked, environment staging  web.review-1 127.77.0.4: 80 (via 60080)network helper: running 0.4.0, 3 names, 2 redirects  why root: macOS lets only root edit /etc/hosts ...

env daemon install installs the network helper, and env daemon uninstall stops it and removes its hosts block, its loopback addresses, and its redirects. The helper runs as root and does only that. The page Device workspaces says why. Run kode start rather than env daemon install: it asks for the password and runs the install for you. To remove the helper, run sudo kode env daemon uninstall.

SSH config

workspaces ssh-config writes one block per workspace to ~/.ssh/kode_config and puts Include ~/.ssh/kode_config at the top of ~/.ssh/config once. The line must come first because ssh takes the first value that it sees. Run it again after creating or renaming a workspace. kode must be on PATH for ssh to find the ProxyCommand.

text
Host api  HostName ws-7f3a…  User kl  ProxyCommand kode workspaces proxy ws-7f3a…  UserKnownHostsFile ~/.config/kode/known_hosts  HostKeyAlias ws-7f3a…

Files

PathWhat
~/.config/kode/config.jsonAPI URL and token
~/.config/kode/desk.jsonThe picked team and desk
~/.config/kode/known_hostsPinned gateway host keys
~/.ssh/kode_configGenerated host blocks

KODE_CONFIG_DIR moves the config directory.

ws is an alias of workspaces. SSH configs that contain kode ws proxy continue to work.