You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This commit was created on GitHub.com and signed with GitHub’s verified signature.
BROWSER=none keeps nohead login from opening a browser: it only
prints the page to open, as over SSH.
nohead login signs you in with the browser, at a terminal or run by a
coding agent (no terminal and nothing on stdin). It prints a code, then
opens the web app (or, over SSH or without a display, prints the page to
open), where you check the code and choose the project, the key's scopes
and its expiry; the CLI waits for you to choose Allow and saves the new
key for that project, as a piped key is saved. In a folder that uses a
project (--project, NOHEAD_PROJECT or a nohead.json), it asks for a
key for that project, the only one the page then offers. Approving another
sign-in from the same machine for the same project replaces the key: the
CLI saves the new one, and the earlier one is revoked. The code and the
page go to stderr even with --json; stdout carries the same result as
for a piped key. A key piped in (echo "$KEY" | nohead login) is checked
and saved as before, replacing the saved key without revoking it. When
stdin is left open with nothing on it (ssh host nohead login without -t), it says on stderr after a second that it is waiting for a key
there.
Breaking:nohead login at a terminal no longer asks you to paste an
API key: it signs you in with the browser. To save a key you already
have, pipe it in. With nothing on stdin it signs in with the browser too;
something piped in that holds no key (an unset variable in echo "$KEY") still fails with exit code 2, and so does a login with no
key in CI (CI set), which can't wait for a browser.
Breaking: API keys are saved by project, and profiles are gone: --profile and NOHEAD_PROFILE no longer exist. An API key belongs to
one project, so choosing a project now chooses its saved key: a command
works in --project, else NOHEAD_PROJECT, else the project in the
nearest nohead.json (in the current folder or one above it), else the
project of the only saved key. With keys saved for several projects and
none chosen, a command exits 2 and lists them. nohead login saves a key
for its project next to other projects' keys (a new key for the same
project replaces the old one) and says which project it saved; nohead logout forgets the key of the project in use. Keys saved as
profiles by earlier versions keep working: each is read as its project's
key, and the config file is saved in the new shape the next time it
changes. NOHEAD_API_KEY still wins over saved keys, in its own project
(or --project, or NOHEAD_PROJECT); nohead.json doesn't apply to it.
With --json, login prints replaced (whether it replaced a saved
key) instead of profile, and logout prints project_id instead.
nohead link <project> writes nohead.json in the current folder, { "project": "prj_..." }, so commands run there or below use that
project and its saved key. It holds no secret: commit it. Linking a
folder that has one replaces its project and keeps anything else in it.
nohead whoami says which project is in use and where it came from
(--project, NOHEAD_PROJECT, a nohead.json and its path, the only
saved key, or NOHEAD_API_KEY), and names a folder's nohead.json that
something else overrides; with --json, in project_id, project_source, link_file and unused_link_file.
nohead login says when the key's project isn't the one the folder (or --project, NOHEAD_PROJECT) uses.
--api-url is no longer in --help: there is one API, https://api.nohead.io. It and NOHEAD_API_URL still work, for a local
or test API.
Every list command pages: collections list, collections history, fields list, migrations list, webhooks list, webhooks deliveries
and audit stopped at the first 100 (audit: its --limit) without
saying there were more. Like records list, they now end with More: --cursor <cursor> when there are, and take --limit, --cursor
and --all (every page). records history takes --all too, and assets list takes --limit. --all reads 100 to a page whatever the
command's default page size. A --limit that is not a positive integer
is refused before any request, by search too.
Commands that take a field key (fields update, fields delete, fields restore, fields migrate) find a field in a collection with
more than 100 fields; they looked in the first 100 only.
An empty environment variable counts as unset, as in the SDKs: an empty NOHEAD_API_KEY, NOHEAD_API_URL or NOHEAD_PROJECT (say, NOHEAD_API_KEY= in an .envrc) no longer hides the saved key, and an empty XDG_CONFIG_HOME no longer moves the
config file into the current directory.
A list page that says there is more but gives no cursor no longer ends
with More: --cursor null; like the SDKs, the CLI stops there.
With --json, usage errors (a missing argument, an unknown command or
option) print the error envelope on stderr, as other errors do, such as { "error": { "type": "invalid_request", "message": "missing required argument 'id'" } },
instead of commander's message and the command's help. They still exit 2.
Options and arguments with a fixed set of values (records list, records bulk and records export--status, the records bulk
action, records scheduled --sort, assets url --fit and --format, webhooks deliveries --status) list their choices in --help, and refuse
any other value as other usage errors do, with a new message such as option '--fit <fit>' argument 'crop' is invalid. Allowed choices are contain, cover, fill. assets url checks --fit and --format before any request, and webhooks deliveries --status before the API sees it. Flags that cannot
go together (fields update --required --optional, and in fields migrate also --multiple --single and --backfill --backfill-json)
say so in the same way: option '--optional' cannot be used with option '--required'.
assets download and export --include-files treat storage that cannot
be reached like the API: they exit 3 with network_error (it was exit 4, Unexpected error). A download gives up after the time an upload of the
file may take (a minute, longer for a large file), with the same error.
Numbers and field types given to a command are checked before it makes
any request, with the same messages: fields migrate --type, --max-length, --min and --max on fields update and fields migrate (which looked the field up first), and assets url --width, --height and --quality (which read the asset first). An
empty --if-revision "" is refused as not a positive integer; it was
ignored, so the write went ahead unguarded.
import checks assets.jsonl (with --include-files exports) along
with the records and drafts, and lists its problems (a line without an
asset ID, the file missing) in the same incomplete or damaged error
instead of stopping at the first.