Skip to content

Repository files navigation

als

中文: README.zh-CN.md

Publish anything in one command. Folders, single .html / .md files, mdbook projects, source code — als packages the input, uploads it, and prints a public URL.

als auth login # one-time device-flow login
als ./build # publish a folder → https://k7x2qm4j6p.a.ls
als list # see what you've published
als rm k7x2qm4j6p # take it down

A single static binary, no runtime dependencies, talks to api.a.ls (or any compatible deployment).


Install

Release binary

Download the matching archive from the releases page and drop the als binary somewhere on your PATH.

# Linux x64 (static musl)
curl -sSL https://github.com/bkhq/als/releases/latest/download/als-linux-x64.tar.gz \
| tar -xz
sudo install -m 0755 ./als /usr/local/bin/als
# macOS / Linux arm64 / Windows: pick the matching archive# als-linux-x64.tar.gz als-linux-arm64.tar.gz# als-darwin-x64.tar.gz als-darwin-arm64.tar.gz# als-windows-x64.zip

From source

Requires a recent stable Rust toolchain.

cargo install --git https://github.com/bkhq/als --bin als
# or, in a checkout of this repo:
just build && ./target/release/als --version

Shell completion

als completion bash > /etc/bash_completion.d/als
als completion zsh >"${fpath[1]}/_als"
als completion fish >~/.config/fish/completions/als.fish

First deploy

$ als auth login
To authorize this device, visit:
https://a.ls/verify
and enter the code:
ABCD-EFGH
Waiting for authorization...
✓ Logged in.
$ als ./build
✓ Deployed: https://k7x2qm4j6p.a.ls
Id: k7x2qm4j6p
Name: fox042
Version: 20260516-091500-b8e5d3
Expires: in 7 days

Every site has two identifiers:

  • Id — 10-character base32 string, auto-generated by the server, immutable. It IS the URL subdomain.
  • Name — kebab-case lowercase label (a-z, 0-9, -). With --name my-proj you pick it explicitly. Without, the CLI mints <word><NNN> — a short noun + three digits, e.g. fox042 or mint007. Easier to recall than the id; mutable later via als site <id|name> --name <new>. The server is the sole arbiter of name uniqueness; if it rejects the candidate, just retry with your own --name.

als auth login is a one-time step per machine. It writes a token to ~/.config/als/config.toml and exits. Every command after that just works.

Re-running als ./build from the same directory publishes a new version to the same URLals remembers the binding locally (one TOML file per site under ~/.config/als/sites/) so you don't have to pass --name every time.


What can I deploy?

als <path> auto-detects the shape:

PathWhat you get
Folder with index.htmlStatic site (the folder is zipped and uploaded as-is).
Folder with book.tomlRendered mdbook.
Folder of *.md (no book.toml)Auto-bootstrapped mdbook — SUMMARY.md is synthesised for you.
Single .htmlOne-page site.
Single .mdOne-chapter mdbook.
.zip archiveUploaded as-is.
Folder of source codeA read-only code viewer (CodeMirror 6 with file tree, tabs, syntax highlighting).
Single source fileSame viewer with one file.

Force the routing if you want with --kind site or --kind code.


Common recipes

Stable URL with a memorable name

als ./build --name myproj
# → https://k7x2qm4j6p.a.ls (the URL stays stable across re-deploys# with the same --name, no matter where you run it from)

--name is kebab-case lowercase: a-z, 0-9, -, with no leading or trailing -. The name is both a server-side uniqueness key and a filename in your local pin store, so spaces and other punctuation are rejected at parse time.

Password-protect the site

als ./build --pass auto # server generates a memorable password
als ./build --pass "letmein123"# or set a literal one

Already deployed and want to add or rotate a password?

als site k7x2qm4j6p --pass auto # rotate
als site k7x2qm4j6p --no-pass # remove (make public)

Set or extend an expiry

als ./build --expires 24h # `5m` / `24h` / `7d` / `1y` / `never`
als ./build --expires 2026-12-31T00:00:00Z # absolute RFC 3339
als site k7x2qm4j6p --expires never # adjust after the fact

Roll back to a previous version

$ als site k7x2qm4j6p # shows version history
$ als site k7x2qm4j6p --version 20260510-103022-a3f1c2
✓ Activated version 20260510-103022-a3f1c2.

Preview locally before publishing

$ als preview ./docs
Preview at http://127.0.0.1:54123/
press Ctrl+C to stop

The preview is offline — same renderer the upload pipeline uses, served from a tempdir on 127.0.0.1. Pass --bind 0.0.0.0 to expose to the LAN.

Manage your sites

als list # what's live, with quota footer
als list --state expired # filter by state
als site k7x2qm4j6p # detail view + version history
als rm k7x2qm4j6p # delete (interactive confirm)
als rm --all-expired -y # batch-remove expired sites

Script-friendly output

als ./build --quiet # prints just the URL
als ./build --json # full envelope on stdout for jq / etc.

JSON exit-code matrix is stable; piping to jq is safe.


Per-project config (als.toml)

Drop an als.toml file at the input root to tweak how als <path> packs and renders the project. All fields are optional; unknown keys are a hard error so typos surface immediately. The file itself never ends up in the bundle.

# Authoritative site id — the strongest cross-machine pin. Auto-written# by `als <path>` on every successful deploy, so you almost never set# it by hand. Once committed, any clone of this repo deploys to the# same site without depending on the local pin store.id = "k7x2qm4j6p"# Project identity. Same kebab-case rule the `--name` CLI flag enforces:# `a-z`, `0-9`, `-`, no leading or trailing `-`. Used as a fallback# before `id` has been written (e.g. the very first deploy from a# committed `name`).name = "fibonacci-demo"# Viewer page title for code uploads. Defaults to the directory name.title = "Q3 Fibonacci demo"# Which file the viewer opens on first load (code mode). Path is# relative to the input root. The CLI exits with# `code_default_file_missing` if the target isn't in the bundle.default_file = "src/fibonacci.ts"# Extra ignore patterns layered on top of the built-in defaults# (.git/, node_modules/, target/, .env, *.pem, *.key, …).# Gitignore syntax; `!pattern` re-includes something a default# already excluded.exclude = [
"scratch/**",
"*.log",
"!keep-this.log",
]
FieldModesEffect
idevery modePinned site id — strongest anchor. Sent as site_id on POST /api/deploy; the server resolves identity by it. Auto-written by the deploy command on every success. Only --new bypasses it.
nameevery modeProject identity used when no id has landed yet; sent as project_name. Overridden per-invocation by --name <n>.
titlecode only<title> and data-title on the generated viewer shell.
default_filecode onlyFirst file the viewer opens; must exist in the bundled file set.
excludeevery modeExtra gitignore patterns. Single source of truth for per-project filtering — there is no separate .alsignore file.

Where things live

~/.config/als/
├── config.toml # API URL + bearer token, per-profile blocks
└── sites/ # one TOML per locally-pinned site
├── k7x2qm4j6p_myproj.toml # filename: <id>_<name>.toml
└── m3p4rs5t2k_fox042.toml

A pin file looks like:

name = "myproj"id = "k7x2qm4j6p"path = "/home/alice/build"url = "https://k7x2qm4j6p.a.ls"last_published = "2026-05-15T19:50:00Z"last_content_hash = "a3f1c2..."

The filename combines the immutable id with the lowercased name, so either side of the underscore is enough to locate a pin — rm ~/.config/als/sites/k7x2qm4j6p_*.toml is the unscripted equivalent of als unpin k7x2qm4j6p. You rarely need to touch any of these directly — als auth login, als config set, and als <path> maintain them for you.

Environment overrides exist for CI usage:

ALS_API # override the active profile's API URL
ALS_TOKEN # override the active profile's bearer token
ALS_PROFILE # select a named profile

Defaults

SettingValue
API basehttps://api.a.ls
Homepagehttps://a.ls
LLM cheatsheethttps://a.ls/llms.txt
Per-archive cap50 MB
Code-mode caps≤ 50 files · ≤ 256 KB each · ≤ 2 MB total · ≤ 8 directory levels

Override the API with ALS_API, als config set default.api <url>, or by passing --profile <name> to use a different profile.


Where next

License

MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages