Install

Oska is pre-alpha. The latest release is v0.2.0. You can install oskac, the compiler and runner, from a signed binary with a one-line installer, or build it from source.

Set up an AI agent

Paste this prompt into Claude Code, Cursor, Codex, or any other coding agent. It installs Oska, checks the signature and the checksum, and sets up your project, and it asks before it changes a file. Or tell your agent: Read https://oskalang.dev/agent-setup.md and follow it.

agent-setup.md agent-setup.txt

# Set up Oska for AI-driven development

Install Oska, the secure-by-default programming language from https://oskalang.dev, and set up the project in the current directory so that agents can work in it. Do the steps in order, and stop at the first one that fails. Report the failure to me instead of working around it.

## Rules for this task

- Say what you are about to run before you run it.
- Pipe nothing to a shell except the official installer from oskalang.dev in step 1 (and, only if I approve it in step 4, the same installer in a CI file).
- Never ask for, read, print, or handle secrets: tokens, keys, passwords, or the contents of `.env` files. Nothing here needs one.
- Do not change an existing file until you have shown me the diff and I have agreed. Show me a new file's content before you create it.
- Do not change any permission or approval setting, and do not touch user-level or global settings. Write only inside this project, into the install directory `~/.oska`, and into the temporary directory of step 2, which you delete afterwards.
- Never skip a verification, and never work around a failed one.

## 1. Install

On Linux and macOS, run:

```sh
curl -fsSL https://oskalang.dev/install.sh | sh -s -- --json
```

On Windows, in PowerShell (it needs the OpenSSH Client), run:

```powershell
& ([scriptblock]::Create((irm https://oskalang.dev/install.ps1))) --json
```

The installer never prompts. It prints one line of JSON and nothing else. If it printed no JSON, the download failed: stop and tell me.

Read the JSON:

- If `ok` is not `true`, stop and tell me the `error` and the `message`.
- If `checksum_verified` and `signature_verified` are not both `true`, stop. Do not install by any other route: not by hand, not from a mirror, not with the checks turned off.
- Note `version`, `path`, `bin_dir`, and `on_path`. Run `oskac` below by its full `path`. If `on_path` is `false`, tell me to add `bin_dir` to my `PATH`. Do not edit my shell profile unless I ask.

## 2. Check the toolchain

Run `oskac --version --format=json` and confirm that it prints the same `version`. Then, in a temporary directory outside the project, save this as `hello.osk`:

```oska
fn main(io: Stdout) -> Result<(), IoError> {
    io.println("Hello from Oska!")
}
```

Run `oskac check hello.osk` and then `oskac run hello.osk`. The first must report no diagnostic. The second must print `Hello from Oska!`. Delete the temporary directory afterwards.

## 3. Configure the project

Download each template below with `curl -fsSL` or your fetch tool and read it. A template is plain text. Do not run it, except the hook script in step 3c, and only if I opt in.

**3a. AGENTS.md.** The template is https://oskalang.dev/agent-setup/AGENTS.template.md. It holds a `## Working with Oska` section: the agent loop (check, apply machine fixes, run, test, read the authority report), the machine-readable flags (`--format=json`, `oskac explain <code>`), and the links to https://oskalang.dev/llms.txt and the error-code catalog. If `AGENTS.md` does not exist, create it with that section. If it does, append the section, and show me the diff first.

**3b. CLAUDE.md.** Only if I am using Claude Code. The template is https://oskalang.dev/agent-setup/CLAUDE.template.md, which points to `AGENTS.md`. If `CLAUDE.md` exists, add only its first line to it.

**3c. The check-after-edit hook (optional, Claude Code only).** The hook is a POSIX shell script, so it works on Linux and macOS only: on Windows, skip this step and tell me it is not available there yet. Ask me whether I want it, and do nothing if I do not say yes. It runs `oskac check --format=json` on a `.osk` file after Claude Code edits it, and it reads only the edit notification that Claude Code gives it. It sends nothing anywhere and approves no permission. If I say yes:

1. Show me https://oskalang.dev/agent-setup/oska-check.sh, and save it as `.claude/hooks/oska-check.sh` in this project.
2. Show me the diff that merges https://oskalang.dev/agent-setup/claude-settings.json into the project's `.claude/settings.json` (the `hooks` key only; keep every other key), and apply it when I agree. Never edit `~/.claude/settings.json`.

## 4. Run the tests in CI

Look for the project's CI or task runner: `.github/workflows`, a `Makefile`, a `justfile`, or scripts in `package.json`. If there is one, propose a step that runs `oskac test <file.osk>` for each file that has tests, show me the diff, and apply it when I agree. A CI job needs `oskac` too: install it with the same installer, pinned with `--version` to the version you installed. If there is no CI or task runner, say so and add nothing.

## 5. Report

Tell me:

- the `version` you installed, and its `path`;
- each file you added or changed, and each one you left alone;
- how to update: run the installer again. It installs the latest release over the old one, and there is no self-update command.

The documentation index for agents is https://oskalang.dev/llms.txt.

Build from source

You need a stable Rust toolchain, version 1.77 or newer, and a checkout of the repository:

cargo build --release -p oskac

The binary is target/release/oskac. Copy it somewhere on your PATH, or let Cargo install it into ~/.cargo/bin:

cargo install --path crates/oskac

Confirm that it works:

oskac --version

It prints oskac and the version on one line. A build from this checkout prints oskac 0.2.0. Then continue with the quickstart.

One-line installers

On Linux and macOS:

curl -fsSL https://oskalang.dev/install.sh | sh

On Windows, in PowerShell:

irm https://oskalang.dev/install.ps1 | iex

What the installers do:

To pass options through the pipe:

curl -fsSL https://oskalang.dev/install.sh | sh -s -- --version 0.2.0 --json

iex cannot pass options, so in PowerShell run the script as a script block:

& ([scriptblock]::Create((irm https://oskalang.dev/install.ps1))) --version 0.2.0 --json

A successful --json run prints:

{"ok": true, "action": "installed", "version": "0.2.0", "tag": "v0.2.0", "previous_version": null, "platform": "linux-x86_64", "path": "/home/you/.oska/bin/oskac", "bin_dir": "/home/you/.oska/bin", "on_path": false, "checksum_verified": true, "signature_verified": true}

A failed run prints {"ok": false, "error": "<code>", "message": "..."} and exits non-zero: 2 for a usage error, 1 for anything else. The codes are:

errorMeaning
usageAn unknown option, or a --version that is not a version.
no_signing_keyThe installer has no release key built in. Download it again from oskalang.dev.
insecure_urlOSKA_SITE_URL is not an https:// URL, or a download was redirected to one that is not.
unsupported_platformThere is no build for this OS or CPU.
unsupported_libcLinux only: the C library is not glibc 2.35 or newer (for example musl, as on Alpine).
missing_toolcurl, ssh-keygen, or a SHA-256 tool is missing.
download_failedA file could not be downloaded, for example because that version does not exist.
bad_signatureSHA256SUMS is not signed by the release key.
checksum_mismatchThe binary does not match SHA256SUMS.
version_mismatchThe signed SHA256SUMS is for another release than the one asked for, or the binary reports another version.
install_failedThe binary could not be written into place.

The binaries are published on oskalang.dev, together with SHA256SUMS and its signature, for Linux x86_64 and aarch64, macOS x86_64 and aarch64, and Windows x86_64. The Linux binaries are built on Ubuntu 22.04 and need glibc 2.35 or newer. They do not run on an older glibc or on musl systems such as Alpine; there the installer stops with unsupported_libc, and you can build from source instead.

Verify the installation

oskac --version

If oskac is not found, add ~/.oska/bin to your PATH. The quickstart runs a first program.

Update

Re-run the installer. It installs the latest release over the old one, and with --version it installs a specific one. There is no self-update command.

Uninstall

Delete ~/.oska, which holds bin/oskac and a version file recording what the installer put there.

Upgrading to v0.2.0

v0.2.0 is a breaking change to the filesystem capabilities, with no deprecation period (ADR 0008). Fs, FsRead, and FsWrite no longer read or write anything. They only attenuate, and every read and write goes through a directory capability (DirRead, DirWrite) or a file capability (FileRead, FileWrite). A program that calls a removed method fails oskac check with E0273, whose message shows the fix. The check cannot apply it for you, because only you know the root.

Each removed method has a one-line migration. Replace <root> with the directory the program should reach:

Before (v0.1.0)After (v0.2.0)
fs.read_to_string(path) on an FsReadfs.restrict_to("<root>").read_to_string(path)
fs.list_dir(path) on an FsReadfs.restrict_to("<root>").list_dir(path)
fs.write(path, text) on an FsWritefs.restrict_to("<root>").write(path, text)
fs.create_dir(path) on an FsWritefs.restrict_to("<root>").create_dir(path)
fs.restrict_to("file") naming a single filefs.restrict_to_file("file"), then .read_to_string() or .write(text) with no path
Reading anywhere through an FsReadfs.restrict_to("/"), which the authority report shows

Other things change with it:

An example of the migration:

fn count(fs: FsRead, path: Path) -> Result<Int, IoError> {
    Ok(fs.read_to_string(path)?.lines().count())
}
fn count(fs: FsRead, path: Path) -> Result<Int, IoError> {
    Ok(fs.restrict_to("/srv/app").read_to_string(path)?.lines().count())
}

Set up an AI agent

The site publishes a copy-and-paste prompt that has an AI coding agent install Oska, verify the toolchain, and configure your project. It is at the top of this page and at https://oskalang.dev/agent-setup.md as plain Markdown. The agent guide describes the loop the prompt sets up.