# Use the Gizlang command line

This guide shows the daily work with the `giz` command: make a project, run it, check it,
test it, format it, build an executable, update it live, and use packages. It also shows the
editor setup and the machine-readable output for AI agents.

- This guide is task-oriented. The command reference gives each option.
- Each example shows real output from the current toolchain. Long output is trimmed (`…`).
- To install the toolchain, refer to the [installation guide](../start.md).

## Before you start

Run `giz help`. It prints the list of commands and exits with status 0. `giz` with no arguments does the same.

```sh
giz help
giz help check
```

```text
usage: giz COMMAND [ARGUMENT...]

  giz run [--record LOG] [--replay LOG] FILE [ARGUMENT...]  Build FILE (cached) and run it with the arguments.
  giz check [--json] FILE               Check FILE (`.giz`, `.gizgraph` or `package.json`).
  …
```

- `giz help COMMAND` and `giz COMMAND --help` print the flags, examples and exit codes of one command.
- An unknown command prints `unknown command NAME` on stderr and exits with status 2.
- `giz --version` (or `giz version`) prints the identity of the toolchain. `giz capabilities` gives it as JSON ([agents](#identify-the-toolchain)).
- `source <(giz completion bash)` loads the bash completion.
- `giz doc NAME` prints the docs of a module, a declaration or a command, for example `giz doc Json.get`.

## Make a project

`giz init NAME` makes a folder with `main.giz`, `main.test.giz` and a pinned `package.json`.
You can also make the files yourself, as this section shows.

```sh
giz init hello
```

### A program of one or more files

A program is a `.giz` file with a `main` function. Relative imports bring in more files. No
manifest is necessary.

Make a folder `hello` with these three files.

`main.giz`:

```gizlang title="main.giz"
import {System} from "gizlang:system";
import {greeting} from "./greet.giz";

function main(sys: System): void {
    const args = sys.arguments();
    let name = "world";
    if (args.length > 0) { name = args[0]; }
    print(greeting(name));
}
```

`greet.giz`:

```gizlang title="greet.giz"
export function greeting(name: string): string {
    return "Hello, " + name + ".";
}
```

`greet.test.giz` (the tests of `greet.giz`):

```gizlang title="greet.test.giz"
import {equal} from "gizlang:test";
import {greeting} from "./greet.giz";

function testGreeting(): void {
    equal(greeting("Ada"), "Hello, Ada.");
}
```

Run the program:

```sh
cd hello
giz main.giz Ada
```

```text
Hello, Ada.
```

The first run compiles the program. The next runs use the cache: in this test, the first run
took 0.66 s and the second run took 0.08 s.

### A package project

Use a `package.json` manifest when you want pinned sources, dependencies or publication. The
[next section](#the-project-manifest) shows the manifest. The Playground also exports a
project of this type ([start](../start.md)).

## The project manifest

The `gizlang` section of `package.json` declares the package. It is the same contract that the
compiler uses ([packages](packages.md)).

```json
{
  "name": "geo",
  "version": "1.0.0",
  "gizlang": {
    "entry": { "path": "main.giz" },
    "modules": { "shapes": { "path": "shapes.giz" } }
  },
  "license": "MIT"
}
```

| Key | Meaning |
| --- | --- |
| `name`, `version` | The package identity. `giz publish` uses them. |
| `gizlang.version` | The toolchain release that runs the project; `giz` installs and runs it in the folder and below ([install](../start.md#keep-the-toolchain-current)). `giz init` from a release writes it. |
| `gizlang.entry` | The entry source. Necessary. Its `sha256` pin is optional (see below). |
| `gizlang.modules` | The other sources, by module name, each with an optional pin. Use `{}` when there are no other sources. |
| `gizlang.requires` | The lowest registry versions that the package needs, for example `{"geo": "1.0.0"}`. `giz get` writes it. |
| `gizlang.dependencies` | Package folders inside this package (`vendor/NAME`), each pinned by the sha256 of its `package.json`. `giz get` writes it. |
| `native` (on an entry or module) | The C libraries that the source can declare, for example `"native": ["m"]`. |

A module imports another module of its package by name (`"shapes"`), or a module of a
dependency as `"geo:shapes"`.

### Pin the sources

A source of your package needs no pin: the compiler reads it from your folder. A source that has a
sha256 pin must match it. When you change a pinned source, its pin becomes stale, and the package does
not compile:

```text
app/3:252: error E_PACKAGE_INTEGRITY: package manifest or pin problem
```

To refresh the pins, run `giz get DIR`. For a package without `requires`, it only writes
the pins (and runs npm when the package has npm dependencies). A package that you publish needs
its pins, because it becomes a dependency of other packages, and every source of a dependency is pinned.

```sh
giz get geo
```

The command prints nothing and exits with status 0. Then `geo/package.json` contains the pins:

```json
    "entry": {
      "path": "main.giz",
      "sha256": "d4f817e71aebdbbe930308588ec05fe6c5ad2cbcb4d2b47033d55681dc10a611"
    },
```

For a package with `requires`, `giz get DIR` also resolves the requirements from the
registry. Use `giz pin DIR` to refresh only the pins.

`giz pin DIR` refreshes the pins of `DIR/package.json`, and
of the manifests in its dependency folders first.

## Run a program

| Task | Command |
| --- | --- |
| Run a file | `giz main.giz ARG...` |
| Run a file (the same, explicit) | `giz run main.giz ARG...` |
| Run a package | `giz package.json ARG...` |
| Record the inputs of a run | `giz run --record run.log main.giz ARG...` |
| Run again from the record | `giz run --replay run.log main.giz` |

```sh
giz run main.giz Bob
```

```text
Hello, Bob.
```

A package runs from its manifest:

```sh
giz geo/package.json
```

```text
5
```

When `main` returns a value, the CLI prints it. Here `main` returns `distance(Point(3.0, 4.0))`.

### Scripts

A `.giz` file can start with `#!/usr/bin/env giz`. Make it executable, and run it directly.
`giz` must be on `PATH`.

```sh
printf '#!/usr/bin/env giz\nfunction main(): void {\n    print("Hello from a script.");\n}\n' > script.giz
chmod +x script.giz
./script.giz
```

```text
Hello from a script.
```

### Record and replay

`--record LOG` writes the inputs of the run (arguments and other inputs) to LOG. `--replay LOG`
runs the program again with those inputs.

```sh
giz run --record run.log main.giz Zed
giz run --replay run.log main.giz
```

```text
Hello, Zed.
Hello, Zed.
```

## Check a program

`giz check FILE` checks the types and effects of FILE. FILE is a `.giz` file, a
`.gizgraph` file or a `package.json`. Then the command runs the tests of FILE and of each
`X.test.giz` file beside its sources. It runs only the tests whose meaning changed since they
passed.

```sh
giz check main.giz
```

```text
0 cached, 1 run, 0 failed
```

An error shows its file, line, column, code and source line. The exit status is 1.

```sh
giz check bad.giz
```

```text
bad.giz:2:11: error E_TYPE in main: type mismatch: expected i64, got string
        const n: i64 = "text";
              ^
```

| Exit status | Meaning |
| --- | --- |
| 0 | The source checks, and its tests pass. |
| 1 | An error or a failed test. |
| 2 | A usage error (for example, no FILE). |

For JSON diagnostics without tests, use `giz check --json FILE`
([agents](#source-diagnostics-as-json)).

## Test a program

A test is a function `testName(): void` with no parameters. It passes when it returns without
a fault. The asserts are in `gizlang:test` (`equal`, `differ`, `check`, `includes`,
`equalLines`, `equalItems`).

Run the tests of one file:

```sh
giz test greet.test.giz
```

```text
0 cached, 1 run, 0 failed
```

Run them again. A test that passed at the same meaning does not run again:

```text
1 cached, 0 run, 0 failed
```

The meaning of a test does not include names, comments or layout. Thus a rename or a comment
causes no test to run again.

A failed assert shows the values, the line of the test, and a replay test:

```text
fail testAdd R004
    gizlang: R004 in equal line 2 (actual = 4, expected = 5) <- testAdd (fail.test.giz:4)
    gizlang: replay: function testReplayEqual(): void { equal(4, 5); }
test runner failed or returned an incomplete verdict (1/1)
0 cached, 1 run, 2 failed
```

- `giz test FILE` runs only the tests in FILE. `giz test greet.giz` does not run
  `greet.test.giz`. Use `giz check greet.giz` to run both.
- `giz test package.json` runs the tests of the package sources.
- `giz test` with no argument runs every `*.test.giz` file under the current folder, outside
  hidden folders and `node_modules`.
- At the top of a Gizlang checkout, `giz test` with no argument runs the toolchain's own cases and suites; there
  and below, a FOLDER, a FILTER or `--shard I/N` runs some of them ([the guide to the tests](../../tests/README.md)).

## Format source files

`giz fmt FILE...` sets the indentation by bracket depth (4 spaces for each level) and the
spaces between tokens. It writes a file only when the tokens stay the same. Thus it cannot
change the meaning of a file. Before the layout, it rewrites old spellings, such as
`join(v, s)` and `"n=" + string(n)`, to the modern `v.join(s)` and `` `n=${n}` ``, where the
checker proves them the same, and removes unused imports.

```sh
giz fmt --check messy.giz main.giz greet.giz
```

```text
messy.giz
```

`--check` lists the files that are not formatted, and exits with status 1. Without `--check`,
the command formats the files and lists the changed files.

```sh
giz fmt messy.giz
```

Before:

```gizlang
function twice(x:i64):i64{
return x*2;
}
```

After:

```gizlang
function twice(x: i64): i64 {
    return x * 2;
}
```

## Build an executable

`giz build FILE -o OUT` writes `OUT.licenses` beside the executable. Keep
this file when you distribute the program. Each notice gives the component,
its source or system package version, its SPDX identifier and its full license
text. The link inputs select the components. A library outside those inputs is
not listed.
The runtime includes libuv. On Linux and macOS the program loads it from the toolchain's versions folder
(`libgizlang_runtime.so` or `.dylib`, with OpenSSL), so a copy that runs on a machine without the toolchain is built with
`GIZLANG_RUNTIME_STATIC=1`. The native driver also adds system inputs.
The Wasm runtime has no third-party link inputs, so its notice file is empty.

To print the native notices without building an executable, run:

```sh
giz licenses main.giz
```

The text matches the native build's notice file on the same toolchain and
system. The command emits link declarations and asks the driver for its link
command. It does not run the linker. A missing component mapping, version or
license text is an error. The toolchain holds the component mappings and their license texts.

`giz build FILE` compiles FILE (a `.giz` file or a `package.json`) to a native executable
for this CPU. It prints the path of the executable.

```sh
giz build main.giz -o hello
./hello Eve
```

```text
hello
Hello, Eve.
```

| Option | Result |
| --- | --- |
| (none) | An executable for any x86-64 or ARM64 CPU, in the build directory (`…/build/main`). A Linux program runs on glibc 2.35 and later. |
| `-o PATH` | The executable at PATH. It may come before or after FILE. |
| `--fast` | Link fast: -O0. The test runner builds its suites so, and every build inside a suite is linked so too. Do not use it for a program that you ship. |
| `--release` | Link optimized (-O2, ThinLTO) inside a test run as well, for a suite that measures speed. |
| `--store` | Build into the machine store only, with no output file. |
| `--wasm` | A wasm64 module. |

`giz run FILE` (and running a `.giz` file directly) is optimized without waiting: it runs the optimized program when the store has it; otherwise it runs a -O0 build at once and builds the optimized one in the background, which the next run takes. `run --release` waits for the optimized build; `run --fast` always takes -O0.

- The build directory is `$GIZLANG_CACHE/build` for an installed toolchain
  ([environment variables](#environment-variables)).
- No build is for the CPU of the machine that builds it, so you can copy an executable to
  another machine of the same architecture. On x86-64, each function that uses SIMD types
  also has copies for x86-64-v3 and v4, and runs the copy for the highest level that the CPU has.

### WebAssembly

A wasm64 module gets only the console. A program that uses `System` (for example
`sys.arguments()`) does not link as a module.

```sh
giz build --wasm plain.giz -o plain.wasm
giz wasm plain.giz
```

```text
plain.wasm
Hello from wasm.
```

- `giz wasm FILE` runs the module in Node (`runtime/wasm.mjs`). An installed release does
  not have this host. It refuses the command and tells you to use `build --wasm`.

## Live updates

`giz live FILE` runs `main`. When a `.giz` file or `package.json` in the folder of FILE
changes, the command builds a new generation. It publishes that code when the code checks. With
`--tests`, it also runs the tests first, also the `X.test.giz` files, and publishes the code only
when they pass. The generation itself holds those tests: the command links no separate test
program, and it runs them in a new process that loads the generation
(`gizlang-live --run-tests`). A deployed host (`live --accept`, `deploy --live`)
always tests a change.

`tick.giz`:

```gizlang
import * as Task from "gizlang:task";

function message(): string {
    return "version 1";
}
function main(): void {
    let i = 0;
    while (i < 40) {
        print(message());
        Task.sleep(500);
        i += 1;
    }
}
```

```sh
giz live tick.giz
```

Change `"version 1"` to `"version 2"` in the file while the program runs. The output (status
lines go to standard error):

```text
gizlang: generation built: prepare 136 ms, emit 30 ms, tests 5 ms, link 1910 ms
gizlang-live: generation 1 published (10 functions, loaded in 0 ms)
version 1
version 1
…
gizlang: generation built: prepare 9 ms, emit 16 ms, tests 7 ms, link 82 ms
gizlang-live: generation 2 published (10 functions, loaded in 0 ms)
version 2
version 2
…
```

- The loop of `main` keeps the code that it started with. Thus, put the work that you want to
  change in named functions.
- When the new code does not check (or, with `--tests`, a test fails), the program continues
  with the old code:

  ```text
  tick.giz:4:5: error E_TYPE in message: type mismatch: expected string, got i64
          return 7;
          ^^^^^^
  gizlang-live: generation rejected; generation 1 keeps running
  ```

### Deploy to a live host

A deployed program runs under a live host too. Send it only the files that you changed. The
process, its named state and its open connections stay.

1. On the server, run the program as a deployed host. KEYS is a file of the hex Ed25519 public
   keys that the host trusts, one on each line (`giz public-key SEED` prints one):

   ```sh
   giz live --accept 0.0.0.0:7070 --trusted /etc/app/keys \
     --tls-chain /etc/app/chain.pem --tls-key /etc/app/key.pem app/main.giz
   ```

   With `--tls-chain` and `--tls-key` (a PEM certificate chain and its key) the files travel over
   TLS. Without them they travel as plain HTTP, readable on the way: use that only on loopback or
   inside a tunnel.

2. In the folder of the program on your machine, send the changed files. `GIZLANG_SIGNING_KEY`
   is the file of your 32-byte seed:

   ```sh
   giz deploy --live https://server:7070 --json main.giz
   ```

   ```text
   {"result":"published","generation":2,"error":"","ms":57}
   ```

The host writes the files into the folder of its program. Then it checks, tests and compiles
them as for an edit, and publishes them into the running process. `ms` is the time from
signing to the new code serving. The host refuses a unit, and the old code keeps serving, when:

| Cause | Status |
| --- | --- |
| The unit has no signature, a key that the host does not trust, or a signature that does not verify. | 403 |
| The unit was signed more than 5 minutes from the time of the host, or is older than the last unit taken. | 403 |
| The compiler or runtime of the sender is not the compiler and runtime of the host. | 409 |
| The unit does not check, or a test fails. The host takes its files out again. | 409 |

The endpoint is plain HTTP. The signature authenticates each unit, but the source is not
encrypted. Put a TLS proxy in front of the host when the network is not trusted.

## Dependencies and packages

### Registries

The registry is `$GIZLANG_REGISTRY`. It is one of these:

- a local folder of `NAME/VERSION` packages;
- that folder served over HTTP or HTTPS.

When `GIZLANG_REGISTRY` is not set, the registry is `https://gizstack.com/packages`. A version
never changes after its publication.

The examples below use a local folder registry:

```sh
export GIZLANG_REGISTRY="$PWD/registry"
```

### Publish a package

`giz publish DIR` publishes the package in DIR under the `name` and `version` of its
manifest. Pin the package first (`giz get DIR`).

```sh
giz publish geo
```

```text
geo@1.0.0
```

The optional second argument asserts the identity. A different identity fails:

```sh
giz publish geo geo@2.0.0
```

```text
gizlang: publish identity does not match package.json
```

A version that exists already fails:

```text
gizlang: geo@1.0.0 is published already or publication failed; a version never changes
```

The local registry now has `registry/geo/1.0.0/` with `package.json`, `main.giz` and
`shapes.giz`.

Publication to an HTTPS registry needs
`GIZLANG_REGISTRY_TOKEN`, `GIZLANG_REGISTRY_ORG` and
`GIZLANG_REGISTRY_VISIBILITY=public` or `private`. Without them, the command stops with
"set GIZLANG_REGISTRY_TOKEN, GIZLANG_REGISTRY_ORG and GIZLANG_REGISTRY_VISIBILITY=public|private
to publish". Get the token at [gizstack.com/token](https://gizstack.com/token) after you sign in.

### Add a dependency

Make a package `app` that uses `geo`. `app/main.giz`:

```gizlang error=E_MODULE
import {Point, distance} from "geo:shapes";
function main(): void {
    print(string(distance(Point(6.0, 8.0))));
}
```

`app/package.json`:

```json
{
  "name": "app",
  "private": true,
  "gizlang": {
    "entry": { "path": "main.giz", "sha256": "" },
    "modules": {}
  }
}
```

`giz get DIR NAME@VERSION` raises the requirement, puts the selected version in
`DIR/vendor/`, and refreshes the pins. It prints each selected package.

```sh
giz get app geo@1.0.0
giz app/package.json
```

```text
geo 1.0.0
10
```

The manifest now has `requires` and `dependencies`:

```json
    "requires": {
      "geo": "1.0.0"
    },
    "dependencies": {
      "geo": {
        "path": "vendor/geo",
        "sha256": "75009ea412cc175d868e6fd2280ea329ccf16084f5c063acd588a5d01d89fa4a"
      }
    }
```

- For each name, `get` selects the highest version that the requirement graph asks for
  (minimal version selection). The build changes only when a requirement changes.
- A new major version is a new name.
- Run `giz get DIR` again with no versions to restore the requirements and refresh the
  pins. This reads the registry. With the default registry, `get` stops with an error when the
  registry does not have a required package (for example
  `gizlang: package.json: registry returned HTTP 404`).

### Validate a package offline

`giz get --frozen DIR` validates the pinned package closure that is on disk. It does not
write files, select versions or use the network. Use it in CI and before a release.

```sh
giz get --frozen app
```

```text
geo 1.0.0
```

A changed dependency source fails:

```text
gizlang: vendor/geo/shapes.giz is missing or does not match its sha256
```

### npm packages

`giz get DIR npm:NAME@SPEC` runs
`npm install --prefix DIR --save-exact --ignore-scripts` and records the package in the npm
`dependencies` of `DIR/package.json`. Installation scripts never run. A program loads it
on the VM in its own process: `Vm.javascript(sys).load("NAME")`
([SYSTEM](../internals/system.md#javascript-and-python)).

## The REPL

`giz repl` reads, checks, runs and prints. Declarations stay in the session. Statements
run after the earlier statements. The REPL prints the value of an expression.

```sh
printf 'function square(x: i64): i64 { return x * x; }\nconst n = square(7);\nn + 1\n:quit\n' | giz repl
```

```text
Gizlang REPL. :show, :reset, :quit
giz> giz> giz> 50
giz>
```

In a terminal, type the same lines after the `giz>` prompt.

| Command | Effect |
| --- | --- |
| `:show` | Prints the program of the session. |
| `:reset` | Starts a new session. |
| `:quit` | Stops the REPL. |

An entry continues on the next line while a bracket or a string is open.

## Editor setup

`giz lsp` runs the language server on standard input and output (LSP 3.17). Editors use
the same toolchain as the CLI.

The server gives diagnostics on open and change, document symbols, hover with signatures and
inferred effects, definitions, references, completion (the members of a value after `.`), signature help,
formatting (as `giz fmt`), rename (checked by the compiler), semantic tokens, folding ranges and workspace
symbols. Positions use UTF-16.

A framed session with an `initialize` request and a `didOpen` of a file with a type error
gave:

```text
{"jsonrpc":"2.0","id":1,"result":{"capabilities":{"positionEncoding":"utf-16","textDocumentSync":{"openClose":true,"change":1},"documentSymbolProvider":true,"hoverProvider":true,"definitionProvider":true,"referencesProvider":true,"completionProvider":{"triggerCharacters":["."]},"signatureHelpProvider":{"triggerCharacters":["(",","],"retriggerCharacters":[")"]},"documentFormattingProvider":true,"renameProvider":{"prepareProvider":true},"semanticTokensProvider":{"legend":{"tokenTypes":["type","enum","interface","function","method","variable"],"tokenModifiers":["declaration"]},"full":true},"foldingRangeProvider":true,"workspaceSymbolProvider":true,"inlayHintProvider":true,"codeActionProvider":{"codeActionKinds":["quickfix"]}},"serverInfo":{"name":"gizlang-lsp","version":"0.1"}}}
{"jsonrpc":"2.0","method":"textDocument/publishDiagnostics","params":{"uri":"file:///…/a.giz","version":1,"diagnostics":[{"range":{"start":{"line":1,"character":10},"end":{"line":1,"character":11}},"severity":1,"code":"E_TYPE","source":"gizlang","message":"E_TYPE in main"}]}}
```

### VS Code

:::status{of="lsp"}
:::

The toolchain release carries the Gizlang extension. Install it, and again after each upgrade:

```sh
giz vscode
```

This runs `code --install-extension` on the release's `share/gizlang/vscode/gizlang.vsix`.

It starts `giz lsp` and adds the Test Explorer, debugging (see [Debugging](#debugging)), the `giz` task type and the
Run, Debug, Check and Test File commands. Set `gizlang.path` to your `giz` when it is not on `PATH`.

### Neovim

For Neovim 0.11 and later, put this in `init.lua`. The lspconfig plugin is not necessary.

```lua
vim.filetype.add({ extension = { giz = 'gizlang' } })
vim.lsp.config('gizlang', {
  cmd = { '/absolute/path/to/gizlang', 'lsp' },
  filetypes = { 'gizlang' },
  root_markers = { 'package.json', '.git' },
})
vim.lsp.enable('gizlang')
```

## Debugging

`giz build --debug` builds a program for a debugger: unoptimized, with DWARF for its `.giz` lines, functions,
arguments and locals.

```sh
giz build --debug main.giz -o app
gdb ./app
```

In gdb, `break main.giz:12` or `break total` stops there, `next` and `step` go by source line, `bt` shows the Gizlang
functions and lines, and `info args`, `info locals` and `print` show values by their Gizlang names:

```text
Breakpoint 1, show (n=4, label=...) at main.giz:8
(gdb) info locals
p = {x = 4, y = 1.5}
words = {data = 0x555555a60060, length = 4}
flag = true
(gdb) print *words.data@words.length
$1 = {1, 2, 3, 4}
```

A `string`, `bytes` or `Vec` value is `{data, length}`. A record shows its fields. lldb reads the same information.

In VS Code, the Gizlang extension debugs the open file with F5 or **Gizlang: Debug File**. It builds the file with
`giz build --debug` and runs it under gdb 14 or later (`gdb -i=dap`), or under lldb-dap with `"debugger": "lldb-dap"`
in `launch.json`. Breakpoints, stepping, the call stack and the variables work as in any other language:

```json
{
  "type": "gizlang",
  "request": "launch",
  "name": "Debug Gizlang file",
  "program": "${file}",
  "args": []
}
```

## Environment variables

| Variable | Effect |
| --- | --- |
| `GIZLANG_CACHE` | The store of compiled units, test passes and executables. The default is `$XDG_CACHE_HOME/gizlang`, else `$HOME/.cache/gizlang`. One store serves all projects on the machine. Once an hour a command removes what nobody used for seven days, then the least recently used files past `GIZLANG_CACHE_GB` (default 150, at most half of its disk). |
| `GIZLANG_REGISTRY` | The package registry: a folder, or an HTTP or HTTPS URL. The default is `https://gizstack.com/packages`. |
| `GIZLANG_REGISTRY_TOKEN` | The bearer token for an HTTPS registry. Not sent over plain HTTP. |
| `GIZLANG_REGISTRY_ORG`, `GIZLANG_REGISTRY_VISIBILITY` | The organization and the visibility (`public` or `private`) of a remote publication. |
| `GIZLANG_SHARED_CACHE`, `GIZLANG_TRUSTED_KEYS` | A shared store of units and executables that other machines built, and the hex Ed25519 public keys (comma separated) whose signatures you accept. A file without a trusted signature is not used. |
| `GIZLANG_SIGNING_KEY` | A file with a 32-byte Ed25519 seed. The machine signs what it builds, for a shared store. |

To set the cache for one command:

```sh
GIZLANG_CACHE="$HOME/tmp/gizlang-cache" giz main.giz Cy
```

```text
Hello, Cy.
```

The cache folder then contains `clang`, `linked`, `locks`, `runs` and `units`. You can remove
the cache folder. The next command builds again.

The same hourly pass removes the temporary folders of Gizlang programs (`$TMPDIR/gizlang-XXXXXX`, else
`/tmp/gizlang-XXXXXX`) that are older than a day and that no process has open or works in. These folders are what a
program that was killed left behind.

`giz public-key SEED` prints the public key of a signing seed, for `GIZLANG_TRUSTED_KEYS`:

```sh
giz public-key seed.key
```

```text
1974b90e9fc9dd005bafce07b5914fd1b03c04c5cc18507f2980a2b26ff55a45
```

## Machine-readable output for agents

Humans, editors and agents use the same `giz` command. Read the exit status together with
the output. Refer also to [Gizlang for agents](https://gizstack.com/docs/platform/agents).

| Task | Command | Output |
| --- | --- | --- |
| Identify the toolchain and its operations | `giz capabilities` | JSON (`gizlang.capabilities.v1`) |
| Get source diagnostics, without tests or execution | `giz check --json FILE` | JSON, or nothing |
| Read declarations, effects and the source hash | `giz outline --json FILE` | JSON |
| Change declarations in one checked transaction | `giz edit FILE` (request on standard input) | Report, or JSON (`gizlang.edit`) |
| Read the declarations about some words | `giz context FILE WORD...` | Source text |
| Read the canonical source, with sugar written out | `giz project FILE` | Source text |
| Make JSON functions for record types | `giz codec FILE TYPE...` | Source text |
| Validate pinned packages offline | `giz get --frozen DIR` | One line for each package |

### Identify the toolchain

```sh
giz capabilities
```

```text
{"schema":"gizlang.capabilities.v1","toolchain":{"id":"c1b4eff5e7c7e66d","runtime":"164448871966e74d","mode":"source","releaseTarget":null,"revision":null,"moduleAbi":null},"operations":[{"command":"FILE.giz","usage":"giz FILE.giz ARG...       run FILE (also as #!/usr/bin/env giz)","available":true,"requiresPrivateSource":false},…],"safety":{…}}
```

- `operations` lists each command with `available` and `requiresPrivateSource`.
- `safety` states the guarantees, for example: "check --json performs source diagnostics
  without tests or program execution".
- The output grants no authority. Keep the same toolchain for all of an operation.

### Source diagnostics as JSON

`giz check --json FILE` prints nothing and exits with 0 when the source checks. It does
not run tests. An error is one JSON object, and the exit status is 1:

```sh
giz check --json bad.giz
```

```text
{"error":{"code":"E_TYPE","token":8,"error_id":"gizlang.native.E_TYPE.8","stable_id":"main","location":{"buffer":"prepared_input","encoding":"utf8_bytes","start":55,"end":56,"source":{"path":"","start":55,"end":56}},"call_site":null,…,"counterexample":{"available":false,…},"replay":{"available":false,…}}}
```

- `code` is the error code. `stable_id` names the declaration.
- The byte offsets in `location` are offsets in the prepared compiler input, not always in
  your file. For line and column, use the text output of
  `giz check FILE`.

### Outline

```sh
giz outline greet.giz
```

```text
greet.giz:1  export function greeting(name: string): string  effects {fail}
```

A script reads the same as JSON:

```sh
giz outline --json greet.giz
```

```text
{"hash":"1da311351ed16034","entry":"","declarations":[{"name":"greeting","kind":"function","start":0,"end":85,"location":{"path":"","start":0,"end":85},…,"effects":"fail","exported":true,"parameters":[{"name":"name","type":"string",…}],"result":"string",…}],"files":[…],"symbols":[…],"bindings":[…]}
```

- `hash` is the base of an edit request.
- For a program of more than one file, `location` gives the file and the byte span in that
  file. `start` and `end` are offsets in the compiler input.

### Edit declarations

`giz edit FILE` applies a JSON edit request from standard input as one transaction. The edits change declarations
by name:

```sh
echo '{"base": "1da311351ed16034", "edits": [{"replace": "greeting", "with": "export function greeting(name: string): string { return `Hi, ${name}.`; }"}]}' | giz edit greet.giz
```

- An edit is `{"replace": NAME, "with": TEXT}`, `{"delete": NAME}` or `{"insert": TEXT}`. Instead of these, a request
  can hold only renames (`[{"rename": NAME, "to": NEW}]`) or one move to another module
  (`[{"move": NAME, "from": MODULE, "to": MODULE}]`), which also rewrites the importers.
- `base` is the `hash` of `giz outline`. When the source changed since then, the edit is refused before anything is
  written. The edited program must also pass the full check, or no file changes.
- The report names what changed, the effects that changed, the functions whose behavior can change and the tests
  that cover them. `--json` gives it as `gizlang.edit`.

### Context

```sh
giz context greet.giz greeting
```

```text
// 1 of 1 declarations mention greeting

export function greeting(name: string): string {
    return "Hello, " + name + ".";
}
```

### Canonical source and codecs

`giz project FILE` prints the source with sugar written out:

```text
function twice(x: i64): i64 {
return (x * 2);
}
```

`giz codec FILE TYPE...` prints `encodeT`, `decodeT`, `writeT` and `readT` for the record
types:

```sh
giz codec types.giz Item
```

```text
import {JsonReader, JsonError, reader, writeString, writeInteger, writeNumber} from "gizlang:json";
…
export function encodeItem(value: Item): string { let out = b""; writeItem(out, value); return string(out); }
export function decodeItem(text: string): _JsonCodecCore.Result<Item, JsonError> {
…
```

`giz bind HEADER LIB NAME...` prints `declare` lines for
the named C functions of a header. Review the lines before you paste them.

