@tiny-fish/cli 0.42.1 → 0.43.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.
@@ -3,7 +3,7 @@ import * as readline from 'readline';
3
3
  import { Option } from 'commander';
4
4
  import { CONNECT_ATTEMPT_ENV, clearConfig, getDashboardUrl, loadConfig, maskKey, savePendingConnectAttempt, saveConfig, validateKeyFormat, } from '../lib/auth.js';
5
5
  import { TINYFISH_API_KEY_VAR } from '../lib/constants.js';
6
- import { err, errLine, out, outLine } from '../lib/output.js';
6
+ import { err, errLine, out, outLine, warnLine } from '../lib/output.js';
7
7
  /**
8
8
  * Read a key from stdin without echoing it to the terminal.
9
9
  * Uses setRawMode on TTY so characters are never written to the screen.
@@ -74,6 +74,14 @@ function parkSeedAttempt() {
74
74
  if (seed)
75
75
  savePendingConnectAttempt(seed);
76
76
  }
77
+ // Env var wins every later lookup; a silent save misleads.
78
+ function warnIfEnvShadows(savedKey) {
79
+ const envKey = process.env[TINYFISH_API_KEY_VAR];
80
+ if (!envKey || envKey === savedKey)
81
+ return;
82
+ warnLine(`Warning: ${TINYFISH_API_KEY_VAR} is set in your environment and overrides the key just saved. ` +
83
+ `Unset it or update your shell profile, then check with 'tinyfish auth status'.`);
84
+ }
77
85
  export function registerAuth(program) {
78
86
  const auth = program.command('auth').description('Manage your TinyFish API key');
79
87
  auth
@@ -120,6 +128,7 @@ export function registerAuth(program) {
120
128
  saveConfig(key);
121
129
  parkSeedAttempt();
122
130
  out({ status: 'ok', message: 'API key saved', key_preview: maskKey(key) });
131
+ warnIfEnvShadows(key);
123
132
  });
124
133
  auth
125
134
  .command('set')
@@ -141,6 +150,7 @@ export function registerAuth(program) {
141
150
  saveConfig(key);
142
151
  parkSeedAttempt();
143
152
  out({ status: 'ok', message: 'API key saved', key_preview: maskKey(key) });
153
+ warnIfEnvShadows(key);
144
154
  });
145
155
  auth
146
156
  .command('status')
@@ -82,14 +82,20 @@ class TinyFishCliClient extends TinyFish {
82
82
  captureNotice(response.headers);
83
83
  if (!response.ok) {
84
84
  let message = response.statusText;
85
+ let code;
85
86
  try {
86
87
  const body = (await response.json());
87
- message = body?.error?.message ?? body?.message ?? message;
88
+ if (typeof body?.error?.message === 'string')
89
+ message = body.error.message;
90
+ else if (typeof body?.message === 'string')
91
+ message = body.message;
92
+ if (typeof body?.error?.code === 'string')
93
+ code = body.error.code;
88
94
  }
89
95
  catch {
90
96
  // Non-JSON body — keep statusText
91
97
  }
92
- throw new ApiError(response.status, message);
98
+ throw new ApiError(response.status, message, code);
93
99
  }
94
100
  if (response.status === 204)
95
101
  return undefined;
@@ -113,7 +119,7 @@ function sdk(apiKey, call) {
113
119
  }
114
120
  function rethrowSdkError(error) {
115
121
  if (error instanceof APIStatusError) {
116
- throw new ApiError(error.statusCode, error.message);
122
+ throw new ApiError(error.statusCode, error.message, error.code);
117
123
  }
118
124
  if (error instanceof Error) {
119
125
  throw error;
@@ -41,6 +41,7 @@ export function errLine(line) {
41
41
  }
42
42
  const WARN_ON = '\x1b[33m';
43
43
  const WARN_OFF = '\x1b[39m';
44
+ const VAULT_RECONNECT_REQUIRED = 'VAULT_RECONNECT_REQUIRED';
44
45
  /** Advisory stderr line, yellow on a terminal and plain everywhere else so piped output stays clean. */
45
46
  export function warnLine(line) {
46
47
  const text = sanitizeLine(line);
@@ -57,9 +58,14 @@ export function handleApiError(e) {
57
58
  const payload = { error: e.message, status: e.status };
58
59
  if (e.code)
59
60
  payload.code = e.code;
60
- if (e.status === 401)
61
+ if (e.code === VAULT_RECONNECT_REQUIRED) {
62
+ payload.hint =
63
+ 'Reconnect the provider with `tinyfish vault connection add --provider 1password` or `tinyfish vault connection add --provider bitwarden --client-id <client-id>`. Vault secrets are read from TINYFISH_VAULT_TOKEN, TINYFISH_VAULT_CLIENT_SECRET, and TINYFISH_VAULT_MASTER_PASSWORD.';
64
+ }
65
+ else if (e.status === 401) {
61
66
  payload.hint =
62
67
  'Clear the TINYFISH_API_KEY environment variable, run `tinyfish auth login`, then try again.';
68
+ }
63
69
  err(payload);
64
70
  }
65
71
  else if (e instanceof Error) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tiny-fish/cli",
3
- "version": "0.42.1",
3
+ "version": "0.43.0",
4
4
  "description": "TinyFish CLI — run web automations from your terminal",
5
5
  "type": "module",
6
6
  "bin": {