@onbox/cli 0.0.0-stage → 0.1.0-rc.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +165 -2
  2. package/dist/onbox.js +13099 -0
  3. package/package.json +49 -3
package/README.md CHANGED
@@ -1,3 +1,166 @@
1
- # Temporary Holding Version
1
+ # onbox CLI
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ `onbox` is the Onbox public API (`/v1`) from a terminal, for people and for agents.
4
+ Every command calls one public tool, the same one `/mcp` serves, with the same rules.
5
+
6
+ ## Install
7
+
8
+ ```bash
9
+ npm i -g @onbox/cli # then: onbox --help
10
+ npx @onbox/cli --help # or run it without installing
11
+ ```
12
+
13
+ Needs Node 20 or later.
14
+ From this repository: `pnpm --filter @onbox/cli build` writes `dist/onbox.js`, and `build:binary` compiles one self-contained binary (needs Bun).
15
+
16
+ ## Sign in
17
+
18
+ ```bash
19
+ onbox login # browser (loopback flow); names the profile after your organisation
20
+ onbox login --device # no browser: shows a code to confirm on any device
21
+ onbox login --api-url http://127.0.0.1:3010 --profile local
22
+ ```
23
+
24
+ `login` opens your browser, where you sign in and choose the organisation the CLI acts in.
25
+ Without a display (SSH, a container), or when the browser cannot be opened, it uses the device flow.
26
+ `$BROWSER`, when set, is the command that opens the URL; `--no-browser` uses the device flow.
27
+ The CLI asks for `read write offline_access`: a refresh token keeps you signed in, refreshed whenever a command needs it.
28
+ A credential acts in one organisation.
29
+ For several organisations, or production and a local environment, keep several profiles.
30
+
31
+ ## Profiles
32
+
33
+ ```bash
34
+ onbox profiles list # * marks the active profile
35
+ onbox profiles use acme
36
+ onbox profiles remove old
37
+ onbox logout [--profile acme] # revokes the sign-in, then deletes the credential and the profile
38
+ onbox auth set-key [--profile ci] # sign in with a personal API key instead of the browser
39
+ ```
40
+
41
+ `auth set-key` reads the key from a hidden prompt, or from stdin (`echo $KEY | onbox auth set-key`).
42
+ Create keys in Onbox under Settings, API keys.
43
+ The CLI checks the key against the API, then saves it in a profile for the key's organisation.
44
+ A key works until it is revoked or expires, so `logout` only deletes the local copy.
45
+
46
+ A profile is a name, an API URL, an organisation and a credential.
47
+ Which one a command uses, in order:
48
+
49
+ 1. `--profile <name>`
50
+ 2. `ONBOX_API_KEY` (with `ONBOX_API_URL`, default `https://api.onbox.ing`), a raw bearer token
51
+ 3. `ONBOX_PROFILE`
52
+ 4. the active profile
53
+
54
+ Where things are stored:
55
+
56
+ - `$XDG_CONFIG_HOME/onbox/config.toml` (default `~/.config/onbox`): profile names, API URLs, organisations, the active profile.
57
+ No secrets.
58
+ - Tokens: the macOS Keychain (through `security`), or the Secret Service on Linux (through `secret-tool`), when available.
59
+ Otherwise `credentials.json` next to the config, mode `0600`.
60
+ `ONBOX_NO_KEYCHAIN=1` forces the file.
61
+ - `logout` revokes the sign-in on the server (RFC 7009, the `revocation_endpoint` the API advertises), so the access and refresh tokens stop working at once, then deletes them here.
62
+ When the server cannot be reached it still deletes locally and warns on stderr; the tokens then expire on their own, or can be revoked under Settings, Connected apps.
63
+ - `login` on an existing profile revokes that profile's previous sign-in once the new one has succeeded.
64
+
65
+ ## Commands
66
+
67
+ Commands are generated from the `/v1` route table, as `onbox <noun> <verb>`.
68
+ The API is resource-oriented: an ID is in the path (`GET /v1/drafts/{draftId}`), so it is a positional argument (`onbox drafts get <id>`).
69
+ The API itself is described by its OpenAPI document at <https://api.onbox.ing/api/docs/openapi.json>.
70
+
71
+ ```bash
72
+ onbox --help
73
+ onbox conversations list --limit 20
74
+ onbox conversations get <id>
75
+ onbox conversations get <id> <id>
76
+ onbox conversations drafts list <id>
77
+ onbox conversations drafts create <id> --body-markdown @reply.md
78
+ onbox conversations move <id> --to trash
79
+ onbox conversations move <id> <id> <id> --to trash
80
+ onbox tags create --name vip --description "Important senders"
81
+ onbox conversations update --conversation-ids a --conversation-ids b --archived
82
+ onbox drafts send <id>
83
+ onbox drafts discard <id> --yes
84
+ onbox brain files get org skills/refunds/SKILL.md
85
+ onbox api GET /v1/conversations -q limit=5
86
+ onbox api POST /v1/tags -d '{"name":"vip","description":"Important senders"}'
87
+ onbox api PATCH /v1/drafts/<id> -d '{"subject":"Re: lunch"}'
88
+ ```
89
+
90
+ - A route's path parameters are positional arguments, in the order they appear in the path: `onbox brain files get <scope> <path>`.
91
+ A `{path...}` value may hold slashes.
92
+ - Where a step exists on an item and on the collection (`POST /v1/conversations/{conversationId}/move` and `POST /v1/conversations/move`), the command has both.
93
+ One ID calls the item route; several IDs, or the list flag, call the collection route with the IDs in the body.
94
+ The same holds for batch reads: `onbox conversations get a b` calls `GET /v1/conversations/get?ids=a&ids=b`.
95
+ - A tool's other arguments are flags: `conversationIds` is `--conversation-ids`, a list is a repeated flag (or a JSON array), an object is a JSON string.
96
+ `@file` reads a value from a file and `@-` from stdin; `--body '{"..."}'` passes all arguments as JSON, and flags override it (`--input` where the tool has its own `body` argument, as `comments create` does).
97
+ A command with one required argument also takes it as a positional.
98
+ - `onbox <noun>` lists a group's commands and `onbox <noun> <verb> --help` shows its flags, the route it calls and the scope it needs.
99
+ - `--limit <n>` returns at most n items and `--all` every item, following the tool's cursor or offset.
100
+ - `onbox api <GET|POST|PUT|PATCH|DELETE> <path>` calls any route: `-q key=value` for query parameters, `-d <json|@file|@->` for the body.
101
+ - Shell completion: `source <(onbox completion bash)`, or `onbox completion zsh|fish`.
102
+
103
+ ## Output and safety
104
+
105
+ - On a terminal, results are tables.
106
+ Piped, or with `--json`, they are the API's JSON, unchanged apart from paging (`--all` merges the list and keeps the last page's `nextCursor` or `hasMore`).
107
+ - With `--json`, errors are `{"error":{"code","message","use?"}}` on stderr.
108
+ `use` names the route to call instead, when the API says so.
109
+ - Nothing prompts without a terminal.
110
+ - A tool with `destructiveHint` asks for confirmation on a terminal.
111
+ Without one it exits `6` before calling the API, unless `--yes` is given.
112
+ - Requests carry `User-Agent: onbox-cli/<version>`.
113
+
114
+ ## Exit codes
115
+
116
+ | Code | Meaning |
117
+ | ---- | ------------------------------------------------------------------------------------------- |
118
+ | 0 | Success |
119
+ | 1 | The API refused or failed (400, 409, 422, 5xx), or an unexpected error |
120
+ | 2 | Usage: unknown command or flag, missing or malformed argument |
121
+ | 3 | Not signed in, or the credential is no longer valid (401) |
122
+ | 4 | Forbidden (403), including a token without the scope the route needs (`insufficient_scope`) |
123
+ | 5 | Not found (404) |
124
+ | 6 | A destructive command needs `--yes` and there is no terminal |
125
+ | 7 | The API could not be reached |
126
+
127
+ ## How it works
128
+
129
+ - `src/generated/openapi.json` is the `/v1` OpenAPI document, embedded at build time.
130
+ Commands, flags, scopes, `destructiveHint` and paging come from it, joined to the route table in `@repo/openapi/public-api`.
131
+ A backend test fails when the copy is stale; refresh it with
132
+ `UPDATE_CLI_SPEC=1 pnpm --filter @onbox/backend vitest run --configLoader runner --config ./test/vitest.config.mts test/unit/public-api/public-api-routes.spec.ts`.
133
+ - A token refresh rotates the refresh token on the server, so it runs under a file lock (`locks/<profile>.lock` in the config directory), and the stored token is read again once the lock is held.
134
+ Two commands running at once do not lose it.
135
+ - Credentials are the `StoredSecret` union in `src/credentials.ts`.
136
+ OAuth tokens are refreshed on use; an API key is a bearer that never expires.
137
+
138
+ ## Development
139
+
140
+ ```bash
141
+ pnpm --filter @onbox/cli test
142
+ pnpm --filter @onbox/cli type-check
143
+ pnpm --filter @onbox/cli lint
144
+ ```
145
+
146
+ To run against a local environment (`pnpm local up`), sign in with `onbox login --api-url <the environment URL> --profile local`.
147
+
148
+ ## Update notice
149
+
150
+ At most once a day, a background process asks the npm registry for the `latest` dist-tag (and `next`, for prerelease versions) and caches it in `update-check.json` in the config directory.
151
+ When a newer version exists, the next command prints one line on stderr.
152
+ It never delays a command, and stays silent when stdout or stderr is not a terminal, with `--json`, when `CI` is set, or with `ONBOX_NO_UPDATE_NOTIFIER=1`.
153
+
154
+ ## Releasing
155
+
156
+ `.github/workflows/cli-release.yml` publishes `@onbox/cli` to npm on a `cli-v<version>` tag (or by hand, with a dry-run option) through npm trusted publishing.
157
+ The tag must match `version` in `package.json`.
158
+ A prerelease version (`0.2.0-rc.1`) goes to the `next` dist-tag; a stable one to `latest`.
159
+
160
+ ```bash
161
+ # in apps/cli: set the version, commit, then
162
+ git tag cli-v0.2.0 && git push origin cli-v0.2.0
163
+ ```
164
+
165
+ The workflow publishes only `dist/onbox.js`, `README.md` and `package.json`.
166
+ `build:binary` is kept for later; no binaries, Homebrew formula or signing are released yet.