Control output and accessibility

Updated Aug 05, 2026

Netsuke separates machine-consumable output from status information:

  • stdout contains generated artefacts and subprocess stdout.
  • stderr contains status, progress, timing, and diagnostics.

In JSON mode (--json), a successful command writes exactly one versioned result document to stdout, with generated content embedded in result.content. On failure, stdout is left empty and the single versioned diagnostic document is written to stderr instead. Diagnostics therefore stay on stderr in both modes, so a caller parsing errors reads stderr regardless of --json.

This makes redirection predictable:

netsuke graph > build.dot
netsuke --progress never build
netsuke generate > build.ninja

Accessible output

Accessible mode uses static, labelled status lines instead of animated progress. It is enabled automatically when TERM=dumb or NO_COLOR is present. Select it explicitly with --accessibility on, or force standard output with --accessibility off.

A typical accessible build reports:

Stage 1/6: Reading manifest file
Stage 2/6: Parsing YAML document
Stage 3/6: Expanding template directives
Stage 4/6: Deserializing and rendering manifest values
Stage 5/6: Building and validating dependency graph
Stage 6/6: Synthesizing Ninja plan and executing Build
Build complete.

When stdout is redirected or connected to Continuous Integration (CI), task progress falls back to text, so logs remain readable.

Netsuke uses semantic text labels as well as glyphs; meaning is not conveyed by colour alone. Emoji policy values are:

  • always: Unicode status symbols.
  • never: ASCII-safe prefixes.
  • auto: Unicode in standard output and ASCII in accessible output.

The colour policy is separate. Colour rendering is not implemented in v0.1.0-beta1, so color currently affects mode selection but does not add coloured terminal text.

Verbose mode adds per-stage timing after a successful command. Failed commands do not print a timing summary.

JSON output

Use --json when a caller needs machine-readable command output. Every invocation emits exactly one versioned JSON document: a result document on success, written to stdout, or a diagnostic document on failure, written to stderr while stdout stays empty. Generated stdout artefacts, such as the Ninja text from generate, are carried inside the successful result document rather than written as unstructured text.

JSON selection follows the normal configuration precedence: --json, then NETSUKE_JSON, then json = true|false in a configuration file. Set NETSUKE_JSON to true or 1 to enable JSON output, or to false or 0 to disable it. Any other value, including malformed or non-Boolean text, produces a configuration validation error rather than silently falling back. An explicit --json flag takes precedence and bypasses parsing a lower-priority environment value. For example, NETSUKE_JSON=1 netsuke … enables JSON output.

The following command deliberately selects a missing manifest:

netsuke --json --no-input --file missing.yml build

The exact localized message can vary, but the diagnostic document written to stderr has this shape:

{
  "schema_version": 1,
  "generator": {
    "name": "netsuke",
    "version": "0.1.0-beta1"
  },
  "diagnostics": [
    {
      "message": "Manifest 'missing.yml' not found in the current directory.",
      "code": "netsuke::runner::manifest_not_found",
      "severity": "error",
      "help": "Ensure the manifest exists or pass `--file` with the correct path.",
      "url": null,
      "causes": [],
      "source": null,
      "primary_span": null,
      "labels": [],
      "related": []
    }
  ]
}

The common envelope fields are:

  • schema_version: JSON envelope version.
  • generator: Netsuke name and version.

Exactly one outcome branch is present:

  • result: present only on success.
  • command: the command that completed, such as build, clean, generate, or graph.
  • content: the generated text artefact when the command would otherwise write it to standard output. In particular, generate embeds its Ninja manifest here when --output is not supplied. This field is null when the command produces no text artefact or writes it to a file.
  • diagnostics: present only on failure and contains ordered diagnostic objects.
  • message, code, severity, help, and url: primary details.
  • causes: ordered error-cause chain.
  • source, primary_span, and labels: optional source locations.
  • related: nested diagnostics using the same shape.

Triage: Treat schema version 1 as pre-stable for v0.1.0-beta1 and check schema_version before parsing other fields.