Reference

Configuration

Configuration layers belong to the CLI, the environment, and config files rather than hidden defaults: one discovered base file < project .netsuke.toml < environment variables < CLI flags.

Configuration

When neither --config nor NETSUKE_CONFIG selects a file, Netsuke layers configuration in this order, with later entries overriding earlier ones: one discovered base winner (user configuration, otherwise system configuration, otherwise built-in defaults) < project .netsuke.toml < NETSUKE_ environment variables < CLI flags. Automatic discovery picks exactly one base file rather than merging system and user scopes, then appends the project layer so project values can override it while fields present only in the winner remain available. An explicit selector bypasses discovery entirely: the selected file replaces the discovered base and project layers, and environment variables and flags still apply on top. A flag on the command line always wins, and project config files can be overridden per-invocation without editing them.

Note: The keys below mirror docs/sample-netsuke.toml in the repository as of v0.1.0-beta3. Netsuke is pre-1.0 — some key names and default values may still change before a stable release. Check the project repository for the latest status.

Config file discovery

An explicit selector bypasses discovery entirely. Selectors are checked in this order:

  1. --config /path/to/file.toml (CLI flag)
  2. NETSUKE_CONFIG=/path/to/file.toml (environment)

Without a selector, automatic discovery chooses one exclusive base winner from the platform's user scope (XDG base directories and the home directory on Unix; %APPDATA%\netsuke\config.toml on Windows), then the system scope, then built-in defaults, and appends .netsuke.toml from the project directory selected by -C/--directory. Discovery runs once and is cached for the rest of the command.

CLI-only controls such as --config, --directory, and subcommands are not read from configuration files. --directory does not rebase a relative --config or NETSUKE_CONFIG path; pass an absolute selector when it must not depend on the invoking directory.

When discovery finds no file, Netsuke uses its built-in defaults. When it finds a file that cannot be loaded — malformed TOML, for example — it reports the load error rather than treating the broken file as absent. An explicit --config or NETSUKE_CONFIG selection that is missing or invalid is likewise an error; Netsuke does not fall back to discovery.

Environment variables

Settings can be controlled via NETSUKE_-prefixed env vars:

NETSUKE_JOBS=8
NETSUKE_LOCALE=es-ES
NETSUKE_PROGRESS=never
NETSUKE_ACCESSIBILITY=on
NETSUKE_EMOJI=never
NETSUKE_JSON=1
NETSUKE_NO_INPUT=true
NETSUKE_DEFAULT_TARGETS__0=hello.txt
NETSUKE_NINJA=/opt/ninja/bin/ninja
NETSUKE_WINDOWS_SHELL=bash
NETSUKE_WHICH_WORKSPACE=0

Policy values are matched case-insensitively. NETSUKE_JSON accepts true/1 and false/0; anything else is a validation error rather than a silent fallback. NETSUKE_NINJA overrides the Ninja executable used by build and clean; empty or non-UTF-8 values fall back to ninja on PATH.

Config keys

Build

Where the manifest lives and how hard Netsuke works: the path to the Netsukefile, how many jobs may run at once, and what a bare netsuke build should make.

Output

What Netsuke prints, and how. Progress, accessible mode, emoji, and colour each auto-detect the terminal; set one explicitly to override the guess. locale picks the language messages are written in.

Network

What the fetch() helper is allowed to reach. Choose whether unlisted hosts are denied by default, then name the hosts to allow or block.

# Keys are flat; this mirrors docs/sample-netsuke.toml
# Manifest path override
file = "Netsukefile"
# Number of parallel jobs (1-64)
jobs = 8
# Default build targets when the CLI names none
default_targets = ["fmt", "lint", "test"]
# Netsuke never prompts; `no_input = false` is rejected
no_input = true
# Output policies
progress = "auto"       # auto | always | never
accessibility = "auto"  # auto | on | off
emoji = "auto"          # auto | always | never
color = "auto"          # auto | always | never (colour rendering not yet implemented)
locale = "en-US"
# One versioned JSON document per command; disables tracing on stderr
json = false
# Diagnostic tracing, timing summaries, and a final metrics snapshot
verbose = false
# Network policy for the fetch() helper
fetch_default_deny = false
fetch_allow_host = ["*.example.com"]
fetch_block_host = ["metadata.internal"]

Diagnose configuration selection

Pass --verbose to see how Netsuke chose its configuration. Structured events on stderr report whether --config, NETSUKE_CONFIG, or automatic discovery won, which environment lookups were attempted, and each layer as the merge applies it. File-layer events carry a bounded path_hash rather than the raw path; CLI events record only the overridden leaf keys, never their values. A rejected setting is reported with its key and a bounded reason.

What a broken file does

A discovered file that cannot be loaded — malformed TOML, or an extends parent that is missing — is reported as a load error, not treated as absent. An explicit selector that is missing or invalid is likewise an error; Netsuke never falls back to discovery from an explicit file. The warning records failure_kind as Missing or LoadError.

Metrics snapshot

With --verbose, Netsuke emits one final metrics snapshot debug event before exiting: bounded counters and histograms for configuration loading (config_load_total, config_load_duration_seconds), cached discovery, raw CLI path validation, and legacy recipe execution. It is an in-process diagnostic record, not a metrics endpoint. JSON mode suppresses all of this tracing so stderr stays a single machine-readable document.