CLI reference¶
This is the authoritative CLI reference for incan (commands, flags, paths, and environment variables).
Contributor source-build fallback
If you are working from a compiler checkout instead of an SDK install, you can run the repository-built binary directly:
- from the repository root:
./target/release/incan ...
- or via an absolute path (from anywhere):
/absolute/path/to/incan run path/to/file.incn
Usage¶
Top-level usage:
incan [OPTIONS] [FILE] [COMMAND]
- If you pass a
FILEwithout a subcommand,incantype-checks it (default action).
Commands:
check- Type-check a file or project entrypoint, with optional stable JSON diagnosticsexplain- Explain a stable diagnostic codebuild- Compile to Rust and build an executableinspect- Inspect compiler artifacts such as generated Rust outputrun- Compile and run a programfmt- Format Incan source filestest- Run tests (pytest-style)new- Create a new Incan project directoryinit- Add a starterincan.tomland project skeleton to an existing directoryversion- Update the project version inincan.tomlenv- List, inspect, or run configured project environmentslock- Generate or updateincan.locktools- Inspect local toolchain, editor integration state, and checked metadata
Semantic inspection surfaces¶
Incan 0.4 exposes several machine-readable inspection commands that are meant to agree on schema version, compiler version, project identity, source-file breadcrumbs, generated artifact paths, diagnostics, and provenance where their scopes overlap. Use incan check --format json for the stable diagnostic plane, incan build --report json for successful build and artifact metadata, incan inspect rust --format json for current generated Rust output, and incan inspect codegraph --format jsonl for source-structure graph facts.
These commands are intentionally not a single full semantic database yet. They are the 0.4 baseline for the broader RFC 102 semantic inspection direction: stable public JSON surfaces that tools can join without scraping terminal prose, generated Rust, or source text independently. When a fact appears in more than one surface, consumers should prefer compiler-owned identity fields, source paths, schema versions, and explicit degraded-state or diagnostic records over human output.
Global options¶
--no-banner: suppress the ASCII logo banner when a command would otherwise show it (also viaINCAN_NO_BANNER=1).--color=auto|always|never: control ANSI color output (respectsNO_COLOR).
Banner policy:
- The banner is shown only for interactive
incan buildandincan runcommands. - Utility commands such as
new,init,version,env,lock,fmt, andteststay quiet by default.
Global options (debug)¶
These flags take a file and run a debug pipeline stage:
incan --lex path/to/file.incn
incan --parse path/to/file.incn
incan --check path/to/file.incn
incan --emit-rust path/to/file.incn
incan --check path/to/file.incn --format json remains supported for compatibility, but new tooling should prefer incan check path/to/file.incn --format json.
Strict mode:
incan --strict --emit-rust path/to/file.incn
Commands¶
incan check¶
Usage:
incan check [OPTIONS] <PATH>
Type-checks a file or project entrypoint without building or running it. This is the canonical type-check command for humans, CI, editor integrations, and agents. Passing a file without a subcommand still type-checks it for compatibility, and the legacy debug spelling incan --check <FILE> remains available.
Options:
--format text|json: Output human diagnostics or a stable machine-readable JSON report (default:text).
JSON output uses schema_version: 1 and prints a deterministic report with ok and diagnostics. Each diagnostic includes a stable code, severity, compiler phase, primary source span, message, notes, hints, related spans, and an incan explain <CODE> hook. Human output remains the default and continues to use source-highlighted compiler diagnostics.
Examples:
incan check src/main.incn
incan check src/main.incn --format json
incan --check src/main.incn --format json
incan explain¶
Usage:
incan explain [OPTIONS] <CODE>
Explains a stable diagnostic code from incan check --format json or LSP diagnostics. The catalog is compiler-owned and versioned with the diagnostic schema, so tools can link users to an explanation without scraping terminal prose.
Options:
--format text|json: Output a human explanation or the catalog entry as JSON (default:text).
Seeded catalog codes:
INCAN-P0001: Syntax error.INCAN-T0001: Type checking error.INCAN-I0001: Import or module resolution error.INCAN-C0001: CLI or tooling error.INCAN-U0001: Unknown diagnostic code.
Examples:
incan explain INCAN-T0001
incan explain INCAN-T0001 --format json
incan build¶
Usage:
incan build [OPTIONS] [FILE] [OUTPUT_DIR] [-- <CARGO_PASSTHROUGH>...]
incan build --lib [OPTIONS] [OUTPUT_DIR]
Behavior:
- Default mode compiles a source file into an executable.
--libbuilds the current project as a library. In this mode,src/lib.incnis required andFILEis optional.- Prints the generated Rust project path (example):
target/incan/<name>/ - Builds the generated Rust project and prints the binary path (example):
target/incan/.cargo-target/release/<name> - In
--libmode, also emits a library artifact undertarget/lib/(including<name>.incnlib).
Dependency flags:
--offline: Pass--offlineto Cargo subprocesses so dependency resolution/fetching fails instead of using the network.--locked: Requireincan.lockto exist and be up to date. Also passes--lockedto Cargo.--frozen: Like--locked, plus passes--frozento Cargo (offline + locked).--no-offline,--no-locked,--no-frozen: Disable matching environment defaults for this invocation.--cargo-args <ARG>...: Forward additional arguments to Cargo after policy and feature flags. Arguments after--are also treated as Cargo arguments.--cargo-features <FEATURES>: Enable specific Cargo features (comma-separated).--cargo-no-default-features: Disable default Cargo features.--cargo-all-features: Enable all Cargo features.--release: Explicitly request the release Cargo profile. This is the default forincan build, and the flag exists so first-contact flows can spell out that they are producing an optimized build.--report json: Emit a versioned machine-readable build report.--report-output <PATH>: Write the build report to a file instead of stdout.
Without --locked or --frozen, incan build creates incan.lock when it is missing. If an existing lockfile is stale, the command warns and reuses the embedded Cargo.lock payload without rewriting incan.lock; run incan lock to refresh the committed lockfile intentionally.
For incan build --lib, dependency preheat uses the generated lock workspace and the same release-profile Cargo target directory as the real generated library build. If the dependency graph is unchanged, the preheat stamp is reused; if it has to run, the command prints the target/profile domain before invoking Cargo and streams Cargo's progress while the preheat compiles.
Build reports use schema_version: 1 and describe the successful build rather than restating terminal prose. They include the compiler version, build mode, profile, project identity, entrypoint or library root, source-file breadcrumbs, generated Rust project paths, emitted artifacts, Rust and Incan dependency summaries, Cargo policy flags, interop summary, coarse timings, and notes. When --report json writes to stdout, human progress moves to stderr so tooling can parse stdout directly; when --report-output <PATH> is supplied, the report is written to that file and ordinary progress remains human-facing.
Environment defaults:
INCAN_OFFLINE=1,INCAN_LOCKED=1, andINCAN_FROZEN=1behave like their matching flags.INCAN_FROZEN=1implies offline and locked mode.- CLI flags take precedence over these defaults. Use the
--no-*forms to disable a policy default set by the environment. INCAN_CARGO_ARGS="..."is split on whitespace and used when no Cargo args were supplied on the CLI.INCAN_LOCK_PREHEAT=0disables dependency preheat for lock/test and generated-library build paths.
Examples:
incan build examples/simple/hello.incn
incan build src/main.incn --offline
incan build src/main.incn --locked
incan build src/main.incn --frozen
incan build src/main.incn --cargo-features fancy_logging
incan build src/main.incn -- --timings
incan build --lib
incan build --release
incan build src/main.incn --report json
incan build --lib --report json --report-output target/build-report.json
incan inspect rust¶
Usage:
incan inspect rust [OPTIONS] <PATH>
Generates the same Rust project that the current backend would build, then reports the emitted Rust files without invoking Cargo. Use this when you need to inspect backend output, debug generated paths, or hand artifact locations to tooling without treating --emit-rust as a structured interface.
Options:
--lib: Inspect the library build surface rooted atsrc/lib.incn;PATHmay be the project root or a source path inside the project.--format text|json: Output a human file list or a versioned JSON report (default:text).
JSON output uses schema_version: 1 and includes the compiler version, mode, source-file breadcrumbs, generated project paths, emitted Rust file paths, crate-root markers, file sizes, and notes. Source declarations with checked docstrings preserve those docs as generated Rust doc comments for public emitted items when the compiler has checked API metadata available. Generated Rust is inspectable current backend output, not a stable Rust ABI contract; tools may use it for debugging and reporting, but public compatibility should be based on Incan source, manifests, checked API metadata, and documented CLI report schemas.
Examples:
incan inspect rust src/main.incn
incan inspect rust src/main.incn --format json
incan inspect rust . --lib --format json
incan inspect codegraph¶
Usage:
incan inspect codegraph [OPTIONS] <PATH>
Exports compiler-backed codegraph records for an Incan source file or directory. The 0.4 export is a deterministic JSONL stream of Incan-language files, modules, top-level declarations, imports, public exports, body-level reference and call syntax, conservative resolved reference and call targets, containment relationships, source spans, provenance, degraded state, and diagnostics. It is intended for tools and agents that need Incan structure without scraping source text.
Options:
--format jsonl: Emit newline-delimited JSON records. JSONL is the only supported 0.4 format.--allow-errors: Emit a degraded partial graph and diagnostic records when the source is broken. Without this flag, diagnostics fail the command.
incan inspect codegraph is tooling output, not runtime std.graph, not a generated-Rust ABI, and not a whole-program reference/call graph in 0.4. The header lists the represented languages, and every fact record carries language, provenance, and degraded fields. Body facts with a compiler-proven target_id use checked provenance; syntax-only body facts keep syntax provenance. The 0.4 exporter emits language: "incan" only; first-class Rust graph records and MCP/task-context consumers are follow-up work.
Examples:
incan inspect codegraph src/main.incn --format jsonl
incan inspect codegraph src --format jsonl --allow-errors
incan run¶
Usage:
incan run [OPTIONS] [FILE] [-- <CARGO_PASSTHROUGH>...]
Run a file:
incan run path/to/file.incn
Run the project's configured main script:
incan run
Run inline code:
incan run -c "import this"
If FILE is omitted, incan run uses [project.scripts].main from the nearest incan.toml. Outside a project, you must pass FILE or -c.
Dependency flags (same as build):
--offline,--locked,--frozen,--no-offline,--no-locked,--no-frozen,--cargo-args,--cargo-features,--cargo-no-default-features,--cargo-all-features--release: Build and run with Cargo's release profile.
incan fmt¶
Usage:
incan fmt [OPTIONS] [PATH]
Examples:
# Format files in place
incan fmt .
# Check formatting without modifying (CI mode)
incan fmt --check .
# Show what would change without modifying files
incan fmt --diff path/to/file.incn
incan test¶
Usage:
incan test [OPTIONS] [PATH]
Test runner flags:
| Flag | Description |
|---|---|
-k <KEYWORD> |
Filter tests by stable test id substring |
-m <EXPR> / --markers <EXPR> |
Filter tests by marker expression (and, or, not, parentheses) |
-v |
Verbose output, including per-test timing and generated-harness preheat diagnostics |
-x |
Stop on first failure |
--slow |
Include slow tests (marked @slow) |
--strict-markers |
Reject unknown marker names during collection unless registered in TEST_MARKERS |
-j <N> / --jobs <N> |
Run up to N generated worker batches concurrently (single-threaded libtest execution per batch) |
--feature <NAME> |
Enable collection-time std.testing.feature("NAME") probe for skipif / xfailif |
--timeout <DURATION> |
Fail a test batch exceeding a duration (e.g., 250ms, 5s, 2m) |
--nocapture |
Print child test output even for passing tests |
--fail-on-empty |
Return exit code 1 if no tests are collected |
--list |
List collected tests after filters without executing them |
--format console\|json |
Choose human console output or JSON Lines result output (schema_version: "incan.test.v1") |
--junit <PATH> |
Write a JUnit XML report |
--durations <N> |
Print the slowest N test durations |
--shuffle |
Shuffle test execution order |
--seed <N> |
Seed for --shuffle |
--run-xfail |
Run @xfail tests as ordinary tests |
Dependency flags (same as build):
--offline,--locked,--frozen,--no-offline,--no-locked,--no-frozen,--cargo-args,--cargo-features,--cargo-no-default-features,--cargo-all-features
Without --locked or --frozen, incan test creates incan.lock when it is missing. If an existing lockfile is stale, the command warns and reuses the embedded Cargo.lock payload without rewriting incan.lock; run incan lock to refresh the committed lockfile intentionally.
Timeouts apply to generated test batches. --timeout sets the default batch timeout and @timeout("duration") from std.testing can override the batch containing one test. Fixtures, including async fixtures, do not have separate per-fixture timeout configuration. The runner awaits async fixture teardown after ordinary assertion failures and panics while the worker remains alive. If timeout enforcement terminates a worker process, remaining teardown is best-effort.
Before executing a stale generated test harness, incan test preheats it with cargo test --no-run and stores a fingerprint next to the generated project. A normal console run prints a preheat line only when this work is needed and streams Cargo's progress for cold preheats; -v also shows generated-harness planning, preparation-cache hits or misses, preheat timing, Cargo target directory, and Cargo test phase timing. Lock generation also preheats non-trivial dependency graphs into the same generated test target domain before writing incan.lock, so the next harness run can reuse dependency artifacts instead of discovering a cold Cargo graph on the hot path. Rust metadata prewarm reports newly warmed, reused, and skipped items; with INCAN_RUST_INSPECT_TIMING=1, compiler timing logs also explain whether metadata came from process state, disk cache, or a cache miss such as an absent cache file, format change, or workspace fingerprint change.
Examples:
# Run all tests in a directory
incan test tests/
# Run all tests under a path (default: .)
incan test .
# Filter tests by keyword expression
incan test -k "addition"
# List matching tests without running them
incan test --list -k "test_math"
# Verbose output (include timing)
incan test -v
# Stop on first failure
incan test -x
# Include slow tests
incan test --slow
# Select marker-tagged tests
incan test -m "smoke and not slow" tests/
# Validate marker names in CI
incan test --strict-markers tests/
# Enforce a default timeout
incan test --timeout 5s tests/
# Show passing-test output
incan test --nocapture tests/
# Fail if no tests are collected
incan test --fail-on-empty
# Emit JSON Lines and a JUnit report for CI
incan test --format json --junit reports/junit.xml tests/
# Reproduce a shuffled run
incan test --shuffle --seed 12345 tests/
# Strict mode for CI
incan test --frozen
incan new¶
Usage:
incan new [OPTIONS] [NAME]
Creates a new project directory with incan.toml, src/main.incn, tests/test_main.incn, README.md, and .gitignore. The starter source includes a small public greeting() function plus a test that imports and checks it, so incan run, incan test, and incan build --release work immediately after project creation. When run in an interactive terminal without --yes, it prompts for project metadata. In non-interactive contexts, pass NAME or --dir.
Options:
NAME: Project name. If omitted in an interactive terminal,incan newprompts for it.--dir <PATH>: Directory to create or reuse. Defaults to./<name>.--description <TEXT>: Project description written to[project].descriptionandREADME.md.--author <AUTHOR>: Author string, usuallyName <email>, written to[project].authors.--license <LICENSE>: License identifier or expression written to[project].license.--force: Reuse a non-empty directory and overwrite existing manifest/source/test scaffold files.-y,--yes: Use defaults and provided flags without interactive prompts.
Examples:
# Interactive metadata prompts
incan new
# Script-friendly project creation
incan new greeter --description "A small greeting command" --license MIT --yes
# Create the project in a different directory from its name
incan new greeter --dir examples/greeter --yes
incan init¶
Usage:
incan init [OPTIONS] [PATH]
Adds Incan project files to an existing directory. Use this when you already have a directory and want to add incan.toml, src/main.incn, tests/test_main.incn, README.md, and .gitignore. New projects usually start with incan new instead.
Options:
--name <NAME>: Project name (default: directory name).--version <VERSION>: Project version (default:"0.1.0").--description <TEXT>: Project description written to[project].descriptionandREADME.md.--author <AUTHOR>: Author string, usuallyName <email>, written to[project].authors.--license <LICENSE>: License identifier or expression written to[project].license.--force: Overwrite existing manifest/source/test scaffold files.--detect: Preserve an existingsrc/main.incnand, when the placeholder project name is still in use, derive the project name from the directory.-y,--yes: Use defaults and provided flags without interactive prompts.
Examples:
incan init
incan init --name my_app --description "My app" --license MIT my_project/
incan init --detect --yes
See: Project configuration reference for the full manifest format.
incan version¶
Usage:
incan version [OPTIONS] [BUMP]
Updates [project].version in incan.toml. BUMP is one of major, minor, patch, alpha, beta, rc, or dev. Use --set when you need an exact SemVer value instead of a bump.
Options:
BUMP: Version bump to apply.--set <VERSION>: Explicit SemVer version to write.--dry-run: Print the planned change without writingincan.toml.--keep-prerelease: Keep prerelease metadata when applyingmajor,minor, orpatch.--project <PATH>: Project root containingincan.toml.
Examples:
incan version patch
incan version rc --dry-run
incan version --set 1.2.3
incan version minor --project examples/greeter
incan env¶
Project environments are declared in [tool.incan.envs] in incan.toml. The ambient default environment is always available, and the env command lists available environments, shows a Hatch-style overview table, prints a compact resolved summary for one environment, or runs a named script from an environment.
Treat envs as named command contexts for repeatable workflows such as local testing, CI, docs, or release checks. They are not shell sessions or virtual environments.
Usage:
incan env list [OPTIONS]
incan env show [OPTIONS] [ENV]
incan env run [OPTIONS] <ENV> <SCRIPT> [-- <ARGS>...]
Shared options:
--format text|json: Output format forlistandshow(default:text).--project <PATH>: Project root containingincan.toml.
Run options:
--dry-run: Print the resolved command without executing it.-- <ARGS>...: Extra arguments appended to the configured script.
Examples:
incan env list
incan env show
incan env show default
incan env show dev --format json
incan env run dev test
incan env run dev test -- --fail-on-empty
incan env run release build --dry-run
For a fuller explanation of the mental model and a realistic default / unit / ci / docs configuration, see: Project lifecycle.
incan lock¶
Usage:
incan lock [OPTIONS] [FILE]
Resolves all dependencies (manifest + inline + test files) and generates or updates incan.lock.
If FILE is omitted, uses the [project.scripts].main entry from incan.toml.
Options:
--cargo-features <FEATURES>: Enable specific Cargo features for resolution.--cargo-no-default-features: Disable default Cargo features.--cargo-all-features: Enable all Cargo features.
Example:
incan lock src/main.incn
incan lock # uses [project.scripts].main
incan lock --cargo-features metrics # include optional deps in lock
The generated incan.lock contains an embedded Cargo.lock payload and a fingerprint of your dependency inputs. Commit it to version control for reproducible builds.
See: Managing dependencies for practical guidance.
incan tools doctor¶
Usage:
incan tools doctor [OPTIONS]
Inspects local CLI/LSP/editor pathing and offline-readiness signals. Use this when the terminal and editor appear to be using different incan or incan-lsp binaries, when diagnostics look stale after rebuilding, or before a restricted/offline build where Cargo may be unable to fetch missing dependency inputs.
Options:
--format text|json: Output format (default:text).
The report includes:
- the running
incanversion and executable path incanandincan-lspresolution fromPATH~/.cargo/bin/incanand~/.cargo/bin/incan-lspexistence, executable status, and symlink targets- editor setup guidance for
incan.lsp.path,incan.compiler.path, and reload behavior
Offline-readiness:
- The doctor report is the supported preflight path for restricted or offline environments.
- The offline-readiness section is advisory. It checks local signals that affect whether Cargo can satisfy
--frozenpolicy without fetching, but it does not guarantee a laterincan build --frozenorincan test --frozenwill succeed. - Offline/locked policy constrains dependency resolution and fetching. Projects may still depend on Rust crates; those crates must already be available through Cargo's local inputs for an offline build to proceed.
- Use
--format jsonwhen an editor, CI preflight, or issue template needs the same information in a machine-readable form.
Examples:
incan tools doctor
incan tools doctor --format json
incan tools metadata api¶
Usage:
incan tools metadata api [PATH] [OPTIONS]
Emits checked public API metadata for an Incan source file or project directory. The command parses and type-checks the target before producing output, so the result describes the checked API surface rather than source text alone.
If PATH is omitted, the current directory is inspected. If PATH is a directory, src/lib.incn is preferred and src/main.incn is used as a fallback.
This command is source/project inspection, not artifact inspection. It does not build the project, emit generated Rust, or read an existing .incnlib; use incan build --lib for library artifact emission.
Options:
--format json: Output checked API metadata JSON (default).--format markdown: Output a generated Markdown API reference derived from the same checked metadata.
The JSON package contains:
schema_version: numeric schema version for the package payloadpackage: project name and version fromincan.toml, when availablemodules: checked metadata documents for the entry module and imported local modulesdeclarations: public functions, models, classes, traits, enums, newtypes, type aliases, consts, statics, public import aliases, and public partial callable presetsanchor: stable declaration ids plus source byte spansdocstring: raw declaration or method docstring text when presentdocstring_sections: parsed summary, parameter, return, field, alias, and decorator sections when a docstring is presentdecorators: resolved decorator paths and safe literal, type, or const-reference arguments
Docstring validation is strict for mechanically checkable drift. If Args:, Returns:, Fields:, Aliases:, or Decorators: contradict checked source structure, the command reports diagnostics and does not print JSON.
Examples:
incan tools metadata api
incan tools metadata api src/lib.incn --format json
incan tools metadata api src/lib.incn --format markdown
incan tools metadata api path/to/project
See: Checked API metadata for the JSON contract.
incan tools metadata model¶
Usage:
incan tools metadata model PATH MODEL [OPTIONS]
Emits one contract-backed model from project-declared bundle metadata, a bundle JSON file, or a built .incnlib artifact. MODEL may be the bundle logical_type_name or stable_model_id.
Options:
--format incan: Output formatted Incanmodelsource (default).--format json: Output the selected canonical model bundle JSON.
Examples:
incan tools metadata model . OrderSummary --format incan
incan tools metadata model contracts/order_summary.json orders.summary --format json
incan tools metadata model target/lib/orders.incnlib OrderSummary
See: Checked contract metadata for bundle schema, materialization, artifact inspection, and the matching LSP command.
Outputs and paths¶
Build outputs:
- Generated Rust project:
target/incan/<name>/ - Built binary:
target/incan/.cargo-target/release/<name> - Built library artifact (
--lib):target/lib/<name>.incnlibplus the generated library crate output
Cleaning:
rm -rf target/incan/
Environment variables¶
INCAN_STDLIB: override the stdlib directory (usually auto-detected; set only if detection fails).INCAN_FANCY_ERRORS: enable “fancy” diagnostics rendering (presence-based; output may change).INCAN_EMIT_SERVICE=1: toggle codegen emit mode (internal/debug; not stable).INCAN_NO_BANNER=1: disable the ASCII logo banner.NO_COLOR: disable ANSI color output (standard convention).
Exit codes¶
General rule: success is exit code 0; errors are non-zero.
Specific behavior:
incan run: returns the program’s exit code.incan test:- returns 0 if all tests pass
- returns 0 if test files exist but no tests are collected
- returns 1 if
--fail-on-emptyis set and no tests are collected - returns 1 if no test files are discovered under the provided path
- returns 1 if any tests fail or an xfail unexpectedly passes (XPASS)
incan fmt --check: returns 1 if any files would be reformatted.incan build/incan check/incan --check/ debug flags: return 1 on compile/build errors.
Drift prevention (maintainers)¶
Before a release, verify the docs stay aligned with the real CLI surface:
- Compare
incan --helpandincan {check,explain,build,run,fmt,test,init,lock,tools} --helpagainst this page.