The command line

The command line

View as markdown

23a publishes a folder from where it was built, finds artifacts, opens them and reads their comments, in words a person reads or, with --json, in one answer a program parses. Everything else is one 23a open --manage away, on the artifact's page. 23artifacts is the same command under its longer name.

Install

With Node 20 or later:

npm install -g 23artifacts

or run it once without installing anything: npx 23artifacts publish ./dist.

With Homebrew:

brew trust 23made/tap
brew install 23made/tap/23artifacts

Homebrew 7 loads formulae only from taps you trust; before version 7 there is no brew trust, and the second line works alone. It runs on macOS and Linux; on Windows the npm package runs, without the promise.

Sign in

$ 23a login
Opening your browser to sign in to 23artifacts.
If it does not open, go to this address:
https://23artifacts.com/api/auth/mcp/authorize?response_type=code&client_id=…

Waiting for the browser. Press Ctrl-C to stop.
Signed in as Martin May (@martin-may).

The browser asks you to let 23a on <this machine> act for you; say yes and the tab tells you it can be closed. On a machine with no browser — a server over SSH — 23a login --no-browser prints the address to open elsewhere; the browser there ends on an address that will not load, which you paste back into the terminal. The sign-in is kept in the system's keychain or secret store, and ends after a week unused. 23a whoami says who is signed in and in which workspaces; 23a logout signs this machine out.

Publish

$ 23a publish ./dist
Publishing dist/ — 14 files, 3.2 MB — as a new artifact named "Launch plan".
Version 1 is live.
Who can open it: only you.
https://k3x9p2qa.23a.so

A folder or a single file; a markdown file is published as a page. The same folder published again from the same place becomes the next version of the same artifact, and publishing what is already live makes nothing: Nothing changed: version 2 is already live. Large files are uploaded on their own, with a line that counts up. When an artifact of the same name exists and nothing says which one this is, you are asked.

Option What it does
--to <artifact> This artifact's next version, or a new one with that key
--new A separate artifact, whatever matches
--name <name> The artifact's name
--staged Saved, not live
--dry-run Every check, nothing written
--note <text> How and why this version was made
--theme <theme> The look a page or a markdown file is drawn in

An artifact is named the way every surface names one: its address, its identifier or its key.

Find, open, read comments

Command What it does
23a list [question] The artifacts a question finds, most recently touched first, in the words the search field takes (kind:deck tag:q4)
23a open [artifact] Its address in the browser; --manage opens its page in 23artifacts. With nothing named, the artifact this folder was published to
23a comments <artifact> The open threads on its live version; --all adds the resolved

Every command takes --workspace <handle>, --json and --help.

For a program

What a program parses goes to standard output and what a person reads goes to standard error, so --json changes only what a program sees. With --json the command prints one JSON value, the server's answer, and never asks: a question it would have asked is a refusal naming the options that answer it (Pass --to k3x9p2qa to publish its next version, or --new for a separate artifact.).

Exit code kind Meaning
0 Done, a publish that changed nothing included
1 refused The server refused, in its own words
2 usage The command is wrong: an unknown command or option, a path naming nothing on disk, a choice it could not ask
3 signed_out No sign-in and no credential, or a sign-in that has ended
4 unreachable 23artifacts could not be reached; nothing is half-made

A failure under --json prints {"error", "kind", "status"}.

From a job

A scheduled job or a CI run uses a credential instead of a sign-in. Mint one on your account's credentials page, keep it in the job's secrets, and set it as TTARTIFACTS_TOKEN:

export TTARTIFACTS_TOKEN="<the credential, from the job's secrets>"
npx 23artifacts publish ./dist --to launch-plan --json

The credential is never stored, wins over a sign-in, and carries exactly its scopes and its workspace: a publish-only credential publishes and lists, and a command that needs read or manage is refused saying which. Naming --to keeps a job from ever being asked which artifact it means.