Skip to content

Ashes Compiler CLI Specification

This document is the authoritative reference for every command, flag, and argument supported by the Ashes compiler CLI (ashes).

Source of truth: The CLI entry point and all argument-parsing logic live in src/Ashes.Cli/Program.cs. Update that file—and this document—together whenever CLI behaviour changes.


Overview

The Ashes CLI is invoked as:

sh
ashes <command> [options] [arguments]

Running ashes with no arguments (or an unrecognised command) prints the help text and exits with code 2.

Running ashes --help (or ashes -h) prints the same help text and exits with code 0. Running ashes <command> --help (or ashes <command> -h) also prints the CLI help text and exits with code 0.


Command List

CommandShort description
ashes compileCompile an Ashes source file/expression to a native executable
ashes runCompile and immediately execute an Ashes program
ashes replStart an interactive read-eval-print loop
ashes testRun .ash test files and compare against // expect: comments
ashes fmtFormat .ash source files
ashes initCreate a new Ashes project in the current directory
ashes addAdd a dependency to the project manifest (--path, --dev)
ashes removeRemove a dependency from the project manifest
ashes restoreResolve dependencies (path + registry); --frozen, --offline
ashes treeRender the resolved dependency tree
ashes whyShow why a package is in the dependency graph
ashes loginStore an API token for a registry
ashes publishPackage the current project and publish it to a registry
ashes yankYank (or --undo) a published version
ashes searchSearch a registry for packages
ashes infoShow a package's versions, owners, and capabilities

Registry commands

These talk to an Ashes package registry (see the registry API reference). Each accepts --registry <name-or-url>, resolving a name from ~/.ashes/config.json (the default entry falls back to the canonical public instance) or using a literal http(s):// URL as-is. Credentials are stored per registry base URL in ~/.ashes/credentials.json.

CommandSynopsisNotes
ashes loginashes login [--registry <r>] (--as <account> | --token <t>)--as mints a token via the registry; --token stores a provided one.
ashes publishashes publish [--registry <r>] [--project <ashes.json>] [--version <v>]Packages the project's .ash sources (plus ashes.json/README/LICENSE), computes the ash1: content hash, and uploads. Namespace derives from namespace or the PascalCase package name; version from --version or the manifest. Requires a prior login.
ashes yankashes yank <namespace> <version> [--undo] [--registry <r>]Marks a version un-resolvable for new builds (existing locks still resolve); --undo reverses it. Owner-only.
ashes searchashes search <query> [--registry <r>]Prints a ranked list (namespace, latest, description).
ashes infoashes info <namespace>[@<version>] [--registry <r>]Shows owners and, for the selected (or latest) version, its capability row and dependencies.

The capability row shown by ashes info is the registry's server-computed audit — the capabilities the package's public API needs, inferred by the compiler at publish time, not a heuristic scan.


Common Options

The following help flags are accepted at the top level and for each command:

OptionValue typeDefaultRepeatableDescription
--help / -hNoPrint CLI help text and exit successfully.

The following options are accepted by compile, run, repl, and test:

OptionValue typeDefaultRepeatableDescription
--target <id>enumOS-dependent (see below)NoSelect the code-generation back end.
--target-cpu <cpu>stringgeneric / x86-64NoTarget a specific CPU microarchitecture (e.g. skylake, znver3, apple-m1). Use native to auto-detect the host CPU. Default is safe generic codegen for the target arch.
--parallel-stack-size <size>size1MNoPer-worker stack size for structured parallelism (Ashes.Task.Parallel). Accepts a byte count or a K/M/G suffix (e.g. 2M, 1048576); must be positive. On linux this sets the mmap'd worker-stack length; on win-x64 it is passed to CreateThread (unset leaves the OS default).
--parallel-workers <n>intcore countNoThe executable's compiled maximum / hard ceiling for concurrent structured-parallelism workers. Must be positive. When unset, the compiled program detects the machine's core count once at first fork (linux: sched_getaffinity popcount, so taskset/cgroup masks are respected; win-x64: GetSystemInfo), falling back to 8 if detection fails. A program can request fewer workers for a scoped computation with Ashes.Task.Parallel.withWorkers (effective count is min(override, this maximum)); it can never exceed this ceiling.
-O0|-O1|-O2|-O3enum-O2NoSelect LLVM optimization level.

The following option is accepted by compile and run only:

OptionValue typeDefaultRepeatableDescription
--debug / -gbool (flag)falseNoEmit DWARF debug info into the output binary. See Debug Mode below.

Optimization level values:

FlagMeaning
-O0No optimization
-O1Basic optimizations
-O2Standard optimizations (default)
-O3Aggressive optimizations

--project is accepted by compile, run, and test only (not by ashes repl):

OptionValue typeDefaultRepeatableDescription
--project <path>file pathNoLoad a project manifest (ashes.json). Mutually exclusive with an inline file argument and --expr.

--target values:

ValuePlatform
linux-x64Linux x86-64 — emits a native ELF64 binary
linux-arm64Linux AArch64 — emits a native ELF64 binary
win-x64Windows x86-64 — emits a native PE32+ binary
win-arm64Windows on ARM64 — emits a native PE32+ (AArch64) binary, and is also a host RID (a released compiler runs on Windows-on-ARM). Neither the emitted image nor the WoA compiler executes on an x64 host — both run only on native ARM64 Windows

Any other value is rejected with an error message and exit code 1.


Command Reference

ashes compile

Compile an Ashes program to a native executable on disk.

Synopsis

sh
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] <input.ash>
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] --expr "<source>"
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>] --project <ashes.json>
ashes compile [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-o <output>]          # discovers ashes.json upward

Arguments

NameTypeRequiredDescription
<input.ash>file pathNo†Path to the .ash source file to compile.

† Exactly one input source must be provided: a positional file, --expr, or a project (explicit or auto-discovered).

Options

OptionLong formValue typeDefaultRepeatableDescription
-o--outfile pathDerived from input name (see below)NoPath for the compiled output binary.
--exprstringNoInline Ashes source to compile instead of reading a file.
--targetenumOS defaultNoTarget back end (linux-x64, linux-arm64, win-x64, or win-arm64).
--target-cpustringgeneric / x86-64NoTarget CPU microarchitecture (e.g. skylake, native).
--parallel-stack-sizesize1MNoPer-worker stack size for Ashes.Task.Parallel (byte count or K/M/G suffix).
--projectfile pathNoPath to an ashes.json project file.
-O0|-O1|-O2|-O3enum-O2NoSelect LLVM optimization level.
--debug-gbool (flag)falseNoEmit DWARF debug info (see Debug Mode).

Default output path rules (when -o is not given):

  • Single file examples/hello.ashexamples/hello (Linux) or examples/hello.exe (Windows).
  • --expr without a project → out (Linux) or out.exe (Windows).
  • Project compile → <outDir>/<name> (from ashes.json), appending .exe on Windows.

Defaults

PropertyDefault value
--targetlinux-x64 on Linux x86-64, linux-arm64 on Linux ARM64, win-x64 on Windows
--target-cpux86-64 for x86-64 targets, generic for ARM64
-o / --outDerived from input (see above)
-O0..-O3-O2 (standard optimizations)

Exit Codes

CodeMeaning
0Compilation succeeded; binary written to disk.
1Compilation error (parse, type, or code-generation failure), or user/input error such as missing input, file not found, wrong extension, or I/O failure.
2Usage error (bad flag or conflicting options).

Output (stdout / stderr)

Successful status messages are written to stdout via Spectre.Console. On success, a confirmation line is printed:

text
OK  Wrote <size> to <output>
     Target: <target>
     Debug:  yes          (only when --debug / -g is set)
     Time:   <elapsed>

<size> is human-readable (e.g. 8.1 KB). <elapsed> is the compilation wall-clock time (e.g. 159ms or 1.23s).

Compiler diagnostics and command errors are written to stderr. No machine-readable output format is currently supported.

Examples

bash
# Compile a file (output: examples/hello on Linux)
ashes compile examples/hello.ash

# Compile to an explicit path
ashes compile examples/hello.ash -o build/hello

# Compile an inline expression
ashes compile --expr 'Ashes.IO.print(40 + 2)' -o out

# Cross-compile to Windows PE
ashes compile examples/hello.ash --target win-x64 -o hello.exe

# Compile the project rooted at ashes.json
ashes compile --project path/to/ashes.json

# Auto-discover ashes.json (searches upward from cwd)
ashes compile

ashes run

Compile and immediately execute an Ashes program. The compiled binary is written to a uniquely named executable under the system temporary directory (for example, <temp>/ashes/) and is not automatically deleted by the CLI.

Synopsis

sh
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] <input.ash> [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] --expr "<source>" [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] --project <ashes.json> [-- <args...>]
ashes run [--target <id>] [--target-cpu <cpu>] [--parallel-stack-size <size>] [--parallel-workers <n>] [-O0|-O1|-O2|-O3] [--debug|-g] [-- <args...>]   # auto-discovers ashes.json

Arguments

NameTypeRequiredDescription
<input.ash>file pathNo†Path to the .ash source file to run.
-- <args...>string listNoArguments forwarded to the compiled program (args in Ashes source). The -- separator is required.

† Same rule as compile: one of file, --expr, or project.

Options

OptionValue typeDefaultRepeatableDescription
--exprstringNoInline Ashes source to compile and run.
--targetenumOS defaultNoTarget back end.
--target-cpustringgeneric / x86-64NoTarget CPU microarchitecture (e.g. skylake, native).
--parallel-stack-sizesize1MNoPer-worker stack size for Ashes.Task.Parallel (byte count or K/M/G suffix).
--projectfile pathNoPath to an ashes.json project file.
-O0|-O1|-O2|-O3enum-O2NoSelect LLVM optimization level.
--debug / -gbool (flag)falseNoEmit DWARF debug info (see Debug Mode).

Exit Codes

CodeMeaning
0Program compiled and exited with code 0.
Non-zero (from program)The compiled program's own exit code is propagated as-is.
1Compilation error or user/input failure (before the program starts).
2Usage error.

Output (stdout / stderr)

The compiled program's stdout and stderr flow directly to the terminal without interception. No extra diagnostic lines (timing, size, etc.) are printed, so ashes run output is safe to pipe. Compiler diagnostics are printed to the CLI's stderr before the program runs.

Examples

bash
# Run a file
ashes run examples/hello.ash

# Run with arguments passed to the program
ashes run examples/hello.ash -- hello world

# Run an inline expression
ashes run --expr 'Ashes.IO.print(40 + 2)'

# Run the auto-discovered project
ashes run

# Run a named project
ashes run --project examples/project/ashes.json

ashes repl

Start an interactive read-eval-print loop. Each expression is compiled to a temporary binary, executed, and its stdout is displayed.

Synopsis

sh
ashes repl [--target <id>] [--target-cpu <cpu>] [-O0|-O1|-O2|-O3]

Options

OptionValue typeDefaultRepeatableDescription
--targetenumOS defaultNoTarget back end used for all REPL evaluations.
--target-cpustringgeneric / x86-64NoTarget CPU microarchitecture used for all REPL evaluations.
-O0|-O1|-O2|-O3enum-O2NoSelect LLVM optimization level used for all REPL evaluations.

REPL Commands (typed at the prompt)

CommandAliasesDescription
:help:hShow REPL help.
:quit:q, :exitExit the REPL (exit code 0).
:targetShow the current target.
:target linux-x64|linux-arm64|win-x64|win-arm64Change the active target for subsequent expressions.

Multi-line input is supported: if the parser detects an incomplete expression (unbalanced parentheses or an expected-token error), the REPL shows a ...> continuation prompt.

Exit Codes

CodeMeaning
0User exited cleanly (:quit / :exit / :q).
2Usage error (unknown flag).

Output (stdout / stderr)

All REPL output (prompts, results, errors) is written to stdout. Compiled-program stderr is relayed and highlighted in red.

Examples

bash
ashes repl
# ashes> Ashes.IO.print(40 + 2)
# 42
# ashes> :target linux-x64
# Target set to linux-x64
# ashes> :quit

ashes test

Discover and execute .ash test files. A test file must contain a leading // expect: comment; the runner compiles the file, executes it, and compares stdout against the expected value.

Synopsis

sh
ashes test [--target <id>] [--target-cpu <cpu>] [-O0|-O1|-O2|-O3] [--project <ashes.json>] [paths...]

Arguments

NameTypeRequiredDescription
[paths...]file/directory path listNoOne or more .ash files or directories to search for tests. Repeatable. When --project is supplied and no paths are given, the default search root is <projectDir>/tests if that directory exists, otherwise it is the project directory itself.

Options

OptionValue typeDefaultRepeatableDescription
--targetenumOS defaultNoTarget back end for test compilation.
--target-cpustringgeneric / x86-64NoTarget CPU microarchitecture for test compilation.
--projectfile pathNoLoad a project manifest. When no explicit [paths...] are given, test discovery uses <projectDir>/tests if that directory exists; otherwise it falls back to the project directory itself.
-O0|-O1|-O2|-O3enum-O2NoSelect LLVM optimization level for test compilation.

Test File Conventions

A test file is a regular .ash source file with one or more leading comment directives:

ash
// expect: <expected stdout>
// exit: <expected exit code>   (optional; defaults to 0)
  • Only the first // expect: line is used.
  • // exit: must appear before // expect:.
  • Files without // expect: are reported as SKIP (treated as pass).

Special expected value:

ValueMeaning
emptyExpect empty stdout.

Example:

ash
// exit: 1
// expect: empty
panic("empty")

Exit Codes

CodeMeaning
0All tests with // expect: passed (or none found).
1One or more tests failed.
2Usage error.

Output (stdout / stderr)

Results are printed as a table to stdout:

text
 Test          Result   Time
──────────────────────────────
 hello.ash     PASS     5ms
 failing.ash   FAIL     12ms

A summary line follows: N passed, N failed, N skipped in <elapsed>. Failure details (expected vs. actual stdout) are printed after the table.

Examples

bash
# Run all tests in the default location
ashes test

# Run tests in a specific directory
ashes test tests/

# Run a single test file
ashes test tests/hello.ash

# Run tests for a named project
ashes test --project path/to/ashes.json

ashes fmt

Format .ash source files. ashes fmt resolves formatting from the nearest .editorconfig (walking upward from each file), supporting:

  • indent_style = space|tab
  • indent_size = <int>|tab
  • tab_width = <int>
  • end_of_line = lf|crlf

Defaults when not provided are 4 spaces and platform newline. Without -w, formatted output is printed to stdout. With -w, files are updated in place.

Synopsis

sh
ashes fmt <file|dir> [-w]

Arguments

NameTypeRequiredDescription
<file|dir>file/directory pathYesA single .ash file or a directory. When a directory is given, all .ash files are found recursively.

Options

OptionLong formValue typeDefaultRepeatableDescription
-w--writebool (flag)falseNoWrite formatted output back to the source file(s) instead of printing to stdout.

Exit Codes

CodeMeaning
0Formatting succeeded (or no .ash files found).
1Parse error in one of the source files, or user/input error such as missing path, wrong extension, or path not found.
2Usage error (bad flag or ambiguous arguments).

Output (stdout / stderr)

  • Without -w: formatted source is written to stdout. When multiple files are formatted, a separator rule is printed before each file.
  • With -w: a summary line (OK Formatted N file(s) in <elapsed>.) is written to stdout. Files that are already correctly formatted are not rewritten.

Examples

bash
# Preview formatting of a single file
ashes fmt examples/hello.ash

# Format all .ash files in a directory, writing in place
ashes fmt examples -w

# Preview formatting for all .ash files in a directory
ashes fmt examples

ashes init

Create a new Ashes project in the current directory by scaffolding an ashes.json manifest and a starter src/Main.ash entry file.

Synopsis

sh
ashes init

Arguments

None.

Options

None.

Behaviour

  1. If ashes.json already exists in the current directory, the command fails with exit code 1.
  2. Creates ashes.json with name (derived from the directory name), entry set to "src/Main.ash", and sourceRoots set to ["src"].
  3. Creates the src/ directory if it does not exist.
  4. Creates src/Main.ash with a hello-world program. If the file already exists it is not overwritten.

Exit Codes

CodeMeaning
0Project created successfully.
1ashes.json already exists or an I/O error occurred.

Examples

bash
mkdir myapp && cd myapp
ashes init
# Created ashes.json
# Created src/Main.ash

ashes add

Add a dependency to the nearest ashes.json project manifest.

Synopsis

sh
ashes add <package> [--path <dir>] [--dev]

Arguments

NameTypeRequiredDescription
<package>stringYesThe dependency name to add.

Options

NameDescription
--path <dir>Record a path dependency { "path": "<dir>" } instead of a registry version.
--devWrite to devDependencies instead of dependencies.

Behaviour

  1. Discovers ashes.json by walking upward from the current directory (same discovery as other commands).
  2. If no ashes.json is found, the command fails with exit code 1.
  3. Adds the dependency to dependencies (or devDependencies with --dev): { "path": "<dir>" } when --path is given, otherwise the SemVer string "*". Existing entries are overwritten; other dependencies are preserved.

Exit Codes

CodeMeaning
0Dependency added successfully.
1No ashes.json found, missing package argument, or I/O error.

Examples

bash
ashes add json-parser
# Added json-parser to dependencies.

ashes remove

Remove a dependency from the nearest ashes.json project manifest.

Synopsis

sh
ashes remove <package>

Arguments

NameTypeRequiredDescription
<package>stringYesThe package name to remove.

Options

None.

Behaviour

  1. Discovers ashes.json by walking upward from the current directory (same discovery as other commands).
  2. If no ashes.json is found, the command fails with exit code 1.
  3. If the package is not present in dependencies, the command fails with exit code 1.
  4. Removes the package from the dependencies object and writes the file back.
  5. If the dependencies object becomes empty after removal, the field is omitted from the written JSON.

Exit Codes

CodeMeaning
0Dependency removed successfully.
1No ashes.json found, missing package argument, package not in dependencies, or I/O error.

Examples

bash
ashes remove json-parser
# Removed json-parser from dependencies.

ashes restore

Resolve and materialize a project's dependencies from the nearest ashes.json. (ashes install is retired.)

Synopsis

sh
ashes restore [--registry <name-or-url>] [--frozen] [--offline]

Options

NameDescription
--registry <r>Registry to resolve registry dependencies against (name or URL; default from config).
--frozenFail (ASH032/ASH033) if a fresh resolution would differ from the committed ashes.lock; never rewrite it. For CI.
--offlineNever touch the network; trust ashes.lock and only verify its packages are in the cache.

Behaviour

  1. Discovers ashes.json by walking upward from the current directory.
  2. Fetches and caches registry dependencies (resolving SemVer constraints across the transitive graph) and writes ashes.lock; then validates path dependencies (a missing path or non-project fails with ASH030 / ASH031) and lists every resolved dependency with its namespace.
  3. Each cached package's content is verified against the lock's ash1: hash (ASH034 on mismatch).
  4. build / run / test auto-restore when a project's lock is missing or a locked package is not cached (against the default registry). Use ashes restore explicitly to target a specific registry, or with --frozen / --offline.

Examples

bash
ashes restore --registry https://pkg.ashes-lang.org
# Resolved 2 dependencies into ashes.lock.

ashes tree

Render the resolved dependency tree (project root → direct dependencies → their transitive dependencies, from ashes.lock). Path dependencies are shown as leaves.

sh
ashes tree
# app
# └── Json 1.2.0
#     └── Utf8 0.4.3

ashes why

Show a path from a project root dependency to the named package, explaining why it is in the graph.

sh
ashes why Utf8
# Json -> Utf8

Project File (ashes.json)

The project file enables multi-module compilation and controls build settings.

Fields

FieldTypeRequiredDefaultDescription
entrystring (file path)YesRelative path to the entry-point .ash file.
namestringNoFilename stem of entryOutput binary name (without extension).
sourceRootsstring arrayNo["."]Directories searched when resolving import statements.
includestring arrayNo[]Additional directories searched for imported modules.
outDirstringNo"out"Directory where the compiled binary is written.
targetstring (enum)NoOS defaultDefault back end target; overridden by --target on the command line.
dependenciesobject (string → string)No{}Map of package names to version constraints. Recorded in v0.x but not yet resolved or fetched automatically.

Example

json
{
  "name": "myapp",
  "entry": "src/Main.ash",
  "sourceRoots": ["src"],
  "outDir": "build",
  "target": "linux-x64"
}

Module Import Syntax

Within any .ash file in a project, modules can be imported with:

ash
import ModuleName
import Namespace.ModuleName
  • Module names must start with an uppercase letter.
  • Nested namespaces use dot notation; each component must start with an uppercase letter.
  • Import statements are collected from anywhere in the file; idiomatic style is to place them before any expression code.
  • Circular imports are detected and reported as an error.

Exit Code Summary

CodeMeaning
0Success.
1Compilation error, runtime error, test failure, or concrete user/input error.
2Usage / argument error (bad flag, conflicting options, or unknown command syntax).

The exit code from ashes run is the compiled program's own exit code when compilation succeeds.


Validation Rules and Error Behaviour

ConditionError message / behaviourExit code
Unknown commandHelp text printed2
Unknown flagUnknown argument.2
Missing required compile/run inputMissing input file or --expr.1
Missing required fmt pathMissing file or directory.1
Input file not foundFile not found: <path>1
Input file has wrong extensionInput file must have .ash extension (or use --expr).1
--project combined with file/--exprCannot combine --project with input file or --expr.2
--target receives unknown valueMessage indicating unknown target, e.g. Unknown target '<value>'.1
ashes.json missing entry fieldProject file is missing required string field 'entry'.1
ashes.json entry file not foundProject entry file not found: <path>1
Import cycle detectedImport cycle detected: A -> B -> A1
Parse / type error in sourceDiagnostic message1
ashes fmt given more or fewer than one pathProvide exactly one file or directory.2
ashes fmt path does not existPath not found: <path>1
ashes init when ashes.json existsashes.json already exists in this directory.1
ashes add without package argumentMissing package name.1
ashes add when no ashes.json foundNo ashes.json found. Run 'ashes init' first.1
ashes remove without package argumentMissing package name.1
ashes remove when no ashes.json foundNo ashes.json found. Run 'ashes init' first.1
ashes remove when package not a dependencyPackage '<name>' is not a dependency.1
ashes restore when no ashes.json foundNo ashes.json found. Run 'ashes init' first.1

Debug Mode

The --debug (or -g) flag instructs the compiler to embed debug information in the output binary for source-level debugging. The exact debug format is target-dependent.

Behaviour

AspectEffect
Debug metadataDebug information is emitted into the output binary; the exact sections and format depend on the target platform.
OptimizationWithout an explicit -O flag, optimization defaults to -O0 for the most faithful single-stepping. An explicit -O1/-O2/-O3 is honored (no cap), so a profiled debug build matches the optimized binary's inlining. The DWARF stays valid at every level — the backend re-verifies the module after optimization when debug info is requested.
Compile summaryAn extra Debug: yes line is printed in the ashes compile success output.
Target triple--debug does not change the Windows LLVM target triple; the current implementation continues to target x86_64-pc-windows-msvc.

Interaction with Optimization Levels

User flagsEffective optimization
--debug (no -O)-O0
--debug -O0-O0
--debug -O1-O1
--debug -O2-O2
--debug -O3-O3
-O3 (no --debug)-O3 (unchanged)

Example

bash
# Compile with debug info (defaults to -O0)
ashes compile --debug examples/hello.ash -o hello

# Compile with debug info and explicit -O1
ashes compile -g -O1 examples/hello.ash

# Run under debugger
ashes run --debug examples/hello.ash

Compatibility Rules

Breaking Changes

The following changes would break existing users or tooling and must be treated as breaking:

  • Removing a command or flag.
  • Changing the meaning of an existing flag.
  • Changing exit codes for existing conditions.
  • Changing the format of the success output line for ashes compile.

Non-Breaking Changes

The following changes are considered non-breaking:

  • Adding new commands or flags.
  • Adding new --target values.
  • Adding new fields to ashes.json (with defaults).
  • Changing diagnostic or error message wording (not the exit code).
  • Changing the visual styling of terminal output (colours, table borders).