Your workspace in a file
hookie.yml
project: in the file wins over --project, so a config file is self-describing: you can run it without remembering which project it was for.
What apply will and will not do
The admin API is not a reconciler, andapply does not pretend otherwise.
Nothing the file omits is deleted unless you pass
--prune. A config file describes part of a workspace far more often than all of it, and the failure mode of assuming otherwise is deleting a colleague’s endpoint. A resource the file says nothing about is not even read; an explicit endpoints: [] is how you say “there should be none”.--json gives the plan as data so a CI job can gate on it:
The YAML it reads
Deliberately a subset, and it refuses the rest by name and line rather than guessing:
A parser that quietly mis-reads an anchor sends the wrong configuration to a live workspace, which is strictly worse than one that says it cannot read it.
.json is accepted too, and is the escape hatch for anything this will not parse.
Environment
Profiles
There is no profile flag, becauseHOOKIE_CREDENTIALS and HOOKIE_URL already are one — the credential store is keyed by origin, so one file can hold several environments at once:
Exit codes
6 groups the three cases where retrying the identical command is the reasonable next move, so a script needs one test rather than three.
A destructive command on a non-interactive stdin refuses rather than assuming yes. A CI job that means it passes
--yes; one that did not mean to gets an error instead of a deletion.Credentials on disk
~/.hookie/credentials.json, mode 0600, one entry per origin, written through a temp file and a rename so a crash cannot leave a half-written store. It holds the access token, the refresh token and the OAuth client registration.
hookie logout drops the tokens and keeps the client registration, so reconnecting reuses the same OAuth client instead of adding another row to Settings → Connected agents. hookie logout --all --purge is not a thing; to remove a registration too, delete the file.
The access token is refreshed before it expires, and a refresh shared between concurrent commands is only spent once. If the token endpoint is unreachable you are told that, rather than being told to reconnect — reconnecting needs the same endpoint.