~/.ish.
Token resolution order
Every command resolves a token before it calls the API. The first source that produces a token wins.| # | Source | How it is supplied |
|---|---|---|
| 1 | --token <token> | Global flag on any command. |
| 2 | --token-file <path> | Global flag. The file is read and trimmed; an empty file is an error. Prefer this over --token so the token is not visible in shell history or the process list. |
| 3 | ISH_TOKEN | Environment variable. |
| 4 | Saved OAuth session | access_token plus refresh_token in ~/.ish/config.json, written by ish login. A stale access token is refreshed automatically (see token refresh). |
| 5 | Legacy token | A single token value in ~/.ish/config.json, pasted by hand on older setups. No refresh. |
--token and --token-file are global flags, documented with the other globals on every generated command page. See ish session and any command’s global-flags table.Token refresh
The saved OAuth session (source 4) holds anaccess_token, a refresh_token, and the oauth_client_id minted at login. When a command runs and the access token is expired or within five minutes of expiry, the CLI refreshes it against Supabase, saves the rotated pair back to ~/.ish/config.json, and continues. The refresh token rotates on each use, so a session persists with regular use without a re-login.
Refresh outcomes:
- Success. The command proceeds with the new access token.
- Network failure during refresh. The command fails with
Could not refresh session (network error). Check your connection or run "ish login".Tokens are left intact. - Permanent failure (Supabase 4xx, such as
refresh_token_not_foundorinvalid_grant). The deadaccess_token,refresh_token, and legacytokenfields are cleared from the config so the next run does not retry the doomed refresh. The command fails withSession expired. Run "ish login" to re-authenticate.Add--verboseto append the raw Supabase response.
Saved token is invalid. Run "ish login" to re-authenticate. A dev or prod environment mismatch (a token minted by one Supabase project but presented to the other API) appends a hint explaining which side to change.
Auth failures exit with code
3 and carry error_code: "auth_failed" in JSON output. Branch on either to re-prompt for login. A billing or quota wall arrives as HTTP 403 but exits 1, not 3, so a login retry loop never triggers on a credit cap.Commands
ish login
Open the browser, sign in, and save the resulting OAuth session to ~/.ish/config.json.
login always runs the full browser flow and re-authenticates. There is no “already logged in” short-circuit; that check is ish status. A routine token refresh does not go through login. Each login mints a fresh OAuth client.
ish logout
Remove saved credentials and clear the active context.
logout deletes access_token, refresh_token, the legacy token, and oauth_client_id, and it also clears the active workspace, study, ask, and chat-endpoint selections. Those selections are identity-scoped, so they are meaningless to the next account that signs in.
ish status
Show the active session: signed-in user, active workspace, study, ask, chat endpoint, installed skill, config home, and API URL. Aliased as ish whoami.
status is the first command to run when starting cold. It does not error when no token is present: it returns user: null with a hint instead of exiting, so it is safe to run pre-login. JSON output is safe to pipe.
For the full command list and flags, see the generated reference: ish session.
Config file
Saved credentials and the active context live in a single JSON file.- Path.
~/.ish/config.json. - Permissions. The CLI creates the
~/.ishdirectory with mode0700and writes the config file with mode0600. Writes are atomic (temp file plus rename). - A corrupted file is ignored. The CLI treats an unparsable config as empty rather than failing.
OAuth access token from the last
ish login. Auto-refreshed when stale.OAuth refresh token. Rotates on each refresh.
OAuth client id minted at login. Required to refresh the OAuth session.
Legacy single token pasted by hand. No refresh. Absent on OAuth setups.
Active ask id.
Active chatbot endpoint id, set by
ish chat endpoint use.ISH_HOME
By default the CLI stores everything under~/.ish. Set ISH_HOME to relocate that root, the same way gh uses GH_CONFIG_DIR and aws uses AWS_CONFIG_FILE. When ISH_HOME is set, config.json, aliases.json, the downloaded binary, browsers, and simulation artifacts all live under it.
ish status prints the resolved home directory in its home field, so you can confirm which root is in effect.
Environment variables
Auth token (token-resolution source 3). Overridden by
--token and --token-file.Override the
~/.ish state root for config, aliases, and cached binaries.Override the backend API base. Default
https://api.ishlabs.io.Override the web app URL used in the browser login flow. Default
https://app.ishlabs.io.Override the Supabase project URL used for login and token refresh. Set with
ISH_SUPABASE_ANON_KEY.Override the Supabase publishable key paired with
ISH_SUPABASE_URL.NO_COLOR is also honored: set it (or pass --no-color) to disable colored output.