Prerelease This site documents an alpha of libtmux. Its structure, URLs and APIs are subject to change.

JSON, NDJSON, and semantic color

Edit this page on GitHub

libtmux-workspace 0.0.1-alpha.12-SNAPSHOT · Source

tmuxp compatibility reference. Examples using tmuxp run the Python reference. Local CLI status describes this port’s implemented coverage.

Native CLI development contract. The local workspace-cli worktrees provide JSON and NDJSON output. The schema below is the shared target; implemented command coverage remains port-specific. Python tmuxp provides JSON and NDJSON on ls and search, and JSON on debug-info.

Format selectionLink to section

The shared contract accepts --json and --ndjson before or after every leaf command. NDJSON wins when both are present. A saved workspace’s encoding is separate: freeze -f yaml describes the file, while --json describes the CLI result stream. Machine output has no ANSI styling, prompts, spinner frames, or raw child output.

Machine outputLink to section

The document-to-stdout behaviors below are new machine-mode extensions. In the pinned reference, freeze always saves a file and quiet only suppresses status text. Separate the workspace file’s encoding from the CLI stream’s encoding. freeze -f json selects the document format. --json selects structured CLI output. Never append a status line to raw YAML or JSON document output.

CommandJSON stdoutNDJSON stdout
lsObject containing workspaces and global_workspace_dirs, retaining tmuxp’s existing record fields. Empty discovery yields the same object with an empty array.One workspace record per line, matching tmuxp. Empty discovery emits zero records. Directory diagnostics stay on stderr.
searchArray of result records with "name", "path", "session_name", "source", matched_fields, "matches". Empty results yield [].One result record per line. Empty results emit zero records.
debug-infoOne diagnostics object. Retain home masking for named path fields, define redaction for raw tmux values, and add port/runtime details under named fields.One compact diagnostics object plus newline.
tmuxp loadVersioned operation summary: command, status, results, errors and completed/failed stages.Ordered operation events followed by exactly one terminal result.
tmuxp freezeThe workspace document as a JSON object when writing stdout; if saving to a file, a versioned save result containing destination, format and recoverability warnings.One versioned capture/save result per line, with a "workspace" object when returning the document.
convert and importer leavesThe converted document as JSON when writing stdout; a versioned save result when an explicit destination is supplied.One versioned conversion/save result with a nested document when returning it.
editOne versioned result after the editor exits, including selected file and child status.One terminal edit result; interactive editor display uses the terminal rather than machine stdout.
"shell"For -c, one result containing captured Python stdout/stderr and child status. Interactive REPL requires a separate terminal; otherwise reject before execution.For -c, stream captured Python output events and one terminal result. Interactive behavior has the same terminal requirement.

Keep the established read-command JSON shapes rather than forcing a new universal envelope around existing pipelines. New operation envelopes use integer schema_version: 1. Search’s empty array is a deliberate correction to tmuxp 1.74.0’s empty byte stream. No-pattern machine search must return usage status 2, empty stdout and a structured stderr diagnostic. Explicit --help remains a documented human-help request. Invalid patterns must return usage status 2 and a diagnostic; tmuxp’s current JSON search can silently return no output for an invalid regex.

A new load summary has schema_version, "command", "status" (ok, partial or "error"), results and errors. Each result identifies its workspace input and created/reused session; IDs are strings because tmux uses prefixes such as $, @ and %. Errors include a stable code, a readable message, the input index and any completed/failed stage. Do not serialize native exception objects, language-specific field capitalization or unserializable handles.

Every result names input, input_index, session_id, session_name and reused; ports add their own fields around those. An input that failed keeps its result record beside its errors entry, so a reader can tell which input failed and what became of its session. status is ok when every input completed, partial when some input completed or a failed one left effects behind, such as a borrowed or appended session, and error when nothing completed and nothing was retained.

NDJSON operation events have schema_version, "command", event, a monotonically increasing "sequence", and event-specific data. The initial vocabulary is started, workspace-started, session-created, window-created, pane-created, script-output, warning, workspace-completed, "failed", "completed". Emit "completed" or "failed" once per invocation. Include operation/input identifiers where several files are involved. workspace-started names the input and input_index it belongs to, and session-created follows it directly, before any window-created, so a reader knows the session a window belongs to as soon as the windows arrive. Flush records as events arrive; buffering the whole run and splitting a JSON array into lines is not streaming.

Drain child stdout and stderr concurrently to avoid pipe deadlocks. In machine mode, script text belongs inside escaped JSON strings; it must never be written directly to stdout. Apply backpressure, cap retained output and expose truncation explicitly. Line breaks, tabs, ANSI bytes, Unicode and arbitrary workspace names must remain valid encoded data. Binary output needs an explicit byte encoding or a documented replacement policy.

Machine stderr contains one compact diagnostic JSON object per line. Parse/validation failures before work leave stdout empty and return 2 or 1 respectively. A partial load emits a partial/failure result describing completed work and returns 1; do not claim rollback unless it occurred. Human-mode diagnostics remain readable text. Interruptions should stop scheduling new work, drain or close owned streams, release owned process handles, and return 130 without killing unrelated tmux sessions.

Prompts and file writesLink to section

Machine mode resolves choices from arguments and never treats missing input as yes. Detached loading avoids mixing terminal attachment with JSON. Interactive editor and REPL display require a separate controlling terminal; otherwise the command rejects the request before execution.

The native contract defines explicit save, format, and overwrite controls for conversion/import automation. With no destination, machine conversion returns the document and writes no guessed file. Existing files require explicit overwrite authorization, including explicit freeze destinations. These rules differ from the Python overwrite behavior documented by freeze and convert.

Semantic colorLink to section

Use roles at the point that a domain value is rendered. Formatting an entire line with one success color loses the structure the requested style should communicate. Compose a status, subject, identifiers, paths, counts and hints separately, and reset styling after every token.

RoleDefault tmuxp-aligned styleTypical values
HeadingBold bright cyanCommand and section headings
Primary subjectBold magentaWorkspace/session name, selected window
InformationCyanPaths, targets, useful values
SuccessGreenCreated, loaded, saved
WarningYellowPartial support, lossy capture, retained objects
ErrorRedFailed operation, invalid field
Secondary textBlue or dim text, verified against terminal contrastSizes, timestamps, source labels, hints
Command syntaxDistinct option/argument roles from the same themeFlags, metavariables, examples

Copy tmuxp’s policy explicitly: nonempty NO_COLOR disables; explicit never disables; explicit always enables; nonempty FORCE_COLOR enables auto; otherwise use the destination stream’s terminal capability. To support the supplied reports’ extra variables, add CLICOLOR_FORCE and CLICOLOR below those explicit/reference choices. CLICOLOR_FORCE=0 does not force. Machine mode takes precedence over all color choices, including forced color.

Measure layout using visible terminal width, not byte length or ANSI-bearing string length. Exercise narrow terminals, wrapped paths, Unicode and redirected output. Keep status words and labels even when color is enabled, so meaning survives monochrome output. Progress updates belong on stderr, animate only on a terminal, and become discrete records in NDJSON mode. Honor the reference progress presets, custom tokens and panel-line rules.

See exit codes, command flags, and environment.

tmuxp reference source.

Esc

Type to search.