# The command line

`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.
