@myapihq/cli 1.0.47 → 1.0.50

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.
@@ -1,3 +1,3 @@
1
- export declare function signup(flags?: Record<string, string | boolean>): Promise<void>;
1
+ export declare function link(flags?: Record<string, string | boolean>): Promise<void>;
2
2
  export declare function whoami(flags?: Record<string, string | boolean>): Promise<void>;
3
3
  export declare function switchCmd(flags?: Record<string, string | boolean>, indexArg?: string): Promise<void>;
@@ -38,10 +38,10 @@ async function patch(path, body, apiKey) {
38
38
  throw new Error(json.error ?? `HTTP ${res.status}`);
39
39
  return json.data ?? json;
40
40
  }
41
- // myapi auth signup — upgrade anonymous session to registered account.
42
- export async function signup(flags = {}) {
41
+ // myapi auth link — upgrade anonymous session to registered account.
42
+ export async function link(flags = {}) {
43
43
  if (flags.help) {
44
- info('Usage: myapi auth signup\n\nUpgrades an anonymous account to a registered account by linking an email.\nA verification code will be sent — you must enter it interactively.\nIf the email is already in use, adds it as a second account instead.');
44
+ info('Usage: myapi auth link\n\nLinks an email to your anonymous account, upgrading it to a registered account.\nA verification code will be sent — you must enter it interactively.\nIf the email is already in use, adds it as a second account instead.');
45
45
  return;
46
46
  }
47
47
  const config = loadConfig();
@@ -13,7 +13,8 @@ export async function check(domainArg, flags) {
13
13
  info(`${domain} — Available ✓ ${price}/yr`);
14
14
  }
15
15
  else {
16
- info(`${domain} ${res.message || 'Not available'} ✗`);
16
+ const msg = typeof res.message === 'string' ? res.message : res.message ? JSON.stringify(res.message) : 'Not available';
17
+ info(`${domain} — ${msg} ✗`);
17
18
  }
18
19
  }
19
20
  export async function register(domainArg, flags) {
@@ -208,8 +208,7 @@ export async function setup(flags = {}) {
208
208
  subdomainUrl = data.subdomain_url;
209
209
  isAnonymous = true;
210
210
  }
211
- const skillsAns = skillsFromFlag !== null ? (skillsFromFlag ? 'y' : 'n') : await ask(rl, '› Install the MyAPI skills pack? (Y/n) ');
212
- const wantsSkills = skillsFromFlag !== null ? skillsFromFlag : yn(skillsAns);
211
+ const wantsSkills = skillsFromFlag !== null ? skillsFromFlag : flags.yes ? true : yn(await ask(rl, '› Install the MyAPI skills pack? (Y/n) '));
213
212
  addAccount({
214
213
  api_key: apiKey,
215
214
  account_id: accountId,
@@ -270,7 +269,7 @@ export async function setup(flags = {}) {
270
269
  success('› Setup complete. No card, no email, ready to ship.');
271
270
  if (subdomainUrl)
272
271
  info(`› Your funnel: ${subdomainUrl}`);
273
- info('› Upgrade anytime — myapi auth signup');
272
+ info('› Upgrade anytime — myapi auth link');
274
273
  }
275
274
  else {
276
275
  success(`› Setup complete. Org ${defaultOrg} ready · $5.00 free credits added.`);
@@ -3,6 +3,10 @@ import { loadConfig } from '../config.js';
3
3
  import { info, success } from '../output.js';
4
4
  import { installSkills } from './setup.js';
5
5
  const REGISTRY_URL = 'https://registry.npmjs.org/@myapihq/cli/latest';
6
+ // Use the npm binary next to the active node — critical for nvm users.
7
+ function npmBin() {
8
+ return process.execPath.replace(/[/\\]node$/, '/npm');
9
+ }
6
10
  // checkForUpdate runs silently in the background on every command.
7
11
  // Auto-installs if a newer version is available.
8
12
  export async function checkForUpdate(currentVersion) {
@@ -15,20 +19,18 @@ export async function checkForUpdate(currentVersion) {
15
19
  if (latest && isNewer(latest, currentVersion)) {
16
20
  info(`\n› New version available (${currentVersion} → ${latest}) — installing…`);
17
21
  try {
18
- // Use the npm binary next to the active node so nvm users update the right install.
19
- const npmBin = process.execPath.replace(/[/\\]node$/, '/npm');
20
- execSync(`"${npmBin}" install -g @myapihq/cli`, { stdio: 'pipe' });
22
+ // Pin the exact version so npm can't resolve to a cached older one.
23
+ execSync(`"${npmBin()}" install -g @myapihq/cli@${latest}`, { stdio: 'pipe' });
21
24
  const config = loadConfig();
22
25
  if (config?.skills_installed) {
23
26
  await installSkills();
24
27
  }
25
- success(`› MyAPI CLI updated to ${latest}. Re-run your command.\n`);
26
- process.exit(0);
28
+ info(`› Updated to ${latest} active after this command completes.\n`);
27
29
  }
28
30
  catch (installErr) {
29
31
  const msg = installErr?.stderr?.toString?.() || installErr?.message || String(installErr);
30
32
  info(`› Auto-update failed: ${msg.trim()}`);
31
- info(`› Run manually: npm install -g @myapihq/cli`);
33
+ info(`› Run manually: npm install -g @myapihq/cli@${latest}`);
32
34
  }
33
35
  }
34
36
  }
@@ -39,21 +41,24 @@ export async function checkForUpdate(currentVersion) {
39
41
  // myapi update — explicit update, same logic as auto-update.
40
42
  export async function update(flags = {}) {
41
43
  if (flags.help) {
42
- info('Usage: myapi update\n\nUpdates the MyAPI CLI and skills pack to the latest published version.\nEquivalent to: npm install -g @myapihq/cli');
44
+ info('Usage: myapi update\n\nUpdates the MyAPI CLI to the latest published version.\nEquivalent to: npm install -g @myapihq/cli@latest');
43
45
  return;
44
46
  }
45
47
  info('› Checking for updates…');
48
+ let latest = '';
46
49
  try {
47
50
  const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(5000) });
48
51
  if (!res.ok)
49
52
  throw new Error(`registry returned ${res.status}`);
50
53
  const data = await res.json();
51
- info(`› Installing @myapihq/cli@${data.version}…`);
54
+ latest = data.version ?? '';
55
+ if (latest)
56
+ info(`› Installing @myapihq/cli@${latest}…`);
52
57
  }
53
58
  catch { /* proceed anyway */ }
54
59
  try {
55
- const npmBin = process.execPath.replace(/[/\\]node$/, '/npm');
56
- execSync(`"${npmBin}" install -g @myapihq/cli`, { stdio: 'inherit' });
60
+ const pkg = latest ? `@myapihq/cli@${latest}` : '@myapihq/cli@latest';
61
+ execSync(`"${npmBin()}" install -g ${pkg}`, { stdio: 'inherit' });
57
62
  }
58
63
  catch {
59
64
  process.exit(1);
package/dist/index.js CHANGED
@@ -42,7 +42,7 @@ async function main() {
42
42
  switch (command) {
43
43
  case 'auth':
44
44
  if (!subcommand || (flags.help && !subcommand)) {
45
- info('Usage: myapi auth <subcommand>\n\nSubcommands:\n setup Configure your account\n import-key Import an existing API key non-interactively\n whoami Show current account\n signup Upgrade anonymous account to registered\n switch [index] Switch between accounts\n config Manage CLI defaults (org_id, domain…)\n install-skills Install the MyAPI skills pack\n api-keys Manage API keys');
45
+ info('Usage: myapi auth <subcommand>\n\nSubcommands:\n setup Configure your account\n import-key Import an existing API key non-interactively\n whoami Show current account\n link Link an email to upgrade your anonymous account\n switch [index] Switch between accounts\n config Manage CLI defaults (org_id, domain…)\n install-skills Install the MyAPI skills pack\n api-keys Manage API keys');
46
46
  break;
47
47
  }
48
48
  if (subcommand === 'setup')
@@ -51,8 +51,8 @@ async function main() {
51
51
  await setupCmd.importKey(restArgs[0], flags);
52
52
  else if (subcommand === 'whoami')
53
53
  await authCmd.whoami(flags);
54
- else if (subcommand === 'signup')
55
- await authCmd.signup(flags);
54
+ else if (subcommand === 'link')
55
+ await authCmd.link(flags);
56
56
  else if (subcommand === 'switch')
57
57
  await authCmd.switchCmd(flags, restArgs[0]);
58
58
  else if (subcommand === 'install-skills') {
@@ -140,12 +140,22 @@ async function main() {
140
140
  }
141
141
  catch (err) {
142
142
  if (err instanceof MyApiError) {
143
- if (err.status === 402)
144
- error('Insufficient balance. Run: myapi billing topup <amount>');
145
- else if (err.status === 401)
143
+ if (err.status === 401)
146
144
  error('Invalid API key. Run: myapi auth setup');
145
+ else if (err.status === 402) {
146
+ if (err.code === 'REGISTRATION_REQUIRED')
147
+ error('A verified email is required. Run: myapi auth link');
148
+ else if (err.code === 'UPGRADE_REQUIRED')
149
+ error('A verified email is required. Run: myapi auth link');
150
+ else
151
+ error(`Insufficient balance. Run: myapi billing topup <amount>`);
152
+ }
153
+ else
154
+ error(err.code || err.message);
155
+ }
156
+ else {
157
+ error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err)));
147
158
  }
148
- error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err)));
149
159
  }
150
160
  }
151
161
  function printHelp() {
@@ -162,7 +172,7 @@ Usage: myapi <command> [subcommand] [args]
162
172
  myapi --version
163
173
 
164
174
  Commands:
165
- auth Manage account · setup · whoami · signup
175
+ auth Manage account · setup · whoami · link
166
176
  billing Check balance and manage billing
167
177
  org Manage organizations
168
178
  update Update CLI and skills to the latest version
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@myapihq/cli",
3
- "version": "1.0.47",
3
+ "version": "1.0.50",
4
4
  "description": "MyAPI command-line interface",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -41,10 +41,10 @@ async function patch(path: string, body: unknown, apiKey: string): Promise<unkno
41
41
  return json.data ?? json;
42
42
  }
43
43
 
44
- // myapi auth signup — upgrade anonymous session to registered account.
45
- export async function signup(flags: Record<string, string | boolean> = {}) {
44
+ // myapi auth link — upgrade anonymous session to registered account.
45
+ export async function link(flags: Record<string, string | boolean> = {}) {
46
46
  if (flags.help) {
47
- info('Usage: myapi auth signup\n\nUpgrades an anonymous account to a registered account by linking an email.\nA verification code will be sent — you must enter it interactively.\nIf the email is already in use, adds it as a second account instead.');
47
+ info('Usage: myapi auth link\n\nLinks an email to your anonymous account, upgrading it to a registered account.\nA verification code will be sent — you must enter it interactively.\nIf the email is already in use, adds it as a second account instead.');
48
48
  return;
49
49
  }
50
50
  const config = loadConfig();
@@ -7,12 +7,13 @@ export async function check(domainArg: string, flags: Record<string, string | bo
7
7
  const orgId = (flags.org as string) || config.default_org;
8
8
  const domain = domainArg || (config.default_domain as string);
9
9
  if (!orgId || !domain) error("Missing required arguments.\nUsage: myapi domain check <domain> --org <id>\n(Set defaults: myapi auth config set-org <id> / myapi auth config set-domain <domain>)");
10
- const res = await sdkDomain.checkDomain(config.api_key, orgId, domain) as { available: boolean; price_cents: number; price_display?: string; message?: string };
10
+ const res = await sdkDomain.checkDomain(config.api_key, orgId, domain) as { available: boolean; price_cents: number; price_display?: string; message?: unknown };
11
11
  if (res.available) {
12
12
  const price = res.price_display || `$${(res.price_cents / 100).toFixed(2)}`;
13
13
  info(`${domain} — Available ✓ ${price}/yr`);
14
14
  } else {
15
- info(`${domain} ${res.message || 'Not available'} ✗`);
15
+ const msg = typeof res.message === 'string' ? res.message : res.message ? JSON.stringify(res.message) : 'Not available';
16
+ info(`${domain} — ${msg} ✗`);
16
17
  }
17
18
  }
18
19
 
@@ -258,8 +258,7 @@ export async function setup(flags: Record<string, string | boolean> = {}) {
258
258
  isAnonymous = true;
259
259
  }
260
260
 
261
- const skillsAns = skillsFromFlag !== null ? (skillsFromFlag ? 'y' : 'n') : await ask(rl, '› Install the MyAPI skills pack? (Y/n) ');
262
- const wantsSkills = skillsFromFlag !== null ? skillsFromFlag : yn(skillsAns);
261
+ const wantsSkills = skillsFromFlag !== null ? skillsFromFlag : flags.yes ? true : yn(await ask(rl, '› Install the MyAPI skills pack? (Y/n) '));
263
262
 
264
263
  addAccount({
265
264
  api_key: apiKey,
@@ -325,7 +324,7 @@ export async function setup(flags: Record<string, string | boolean> = {}) {
325
324
  if (isAnonymous) {
326
325
  success('› Setup complete. No card, no email, ready to ship.');
327
326
  if (subdomainUrl) info(`› Your funnel: ${subdomainUrl}`);
328
- info('› Upgrade anytime — myapi auth signup');
327
+ info('› Upgrade anytime — myapi auth link');
329
328
  } else {
330
329
  success(`› Setup complete. Org ${defaultOrg} ready · $5.00 free credits added.`);
331
330
  }
@@ -1,10 +1,15 @@
1
1
  import { execSync } from 'child_process';
2
- import { loadConfig, saveConfig } from '../config.js';
2
+ import { loadConfig } from '../config.js';
3
3
  import { info, success } from '../output.js';
4
4
  import { installSkills } from './setup.js';
5
5
 
6
6
  const REGISTRY_URL = 'https://registry.npmjs.org/@myapihq/cli/latest';
7
7
 
8
+ // Use the npm binary next to the active node — critical for nvm users.
9
+ function npmBin(): string {
10
+ return process.execPath.replace(/[/\\]node$/, '/npm');
11
+ }
12
+
8
13
  // checkForUpdate runs silently in the background on every command.
9
14
  // Auto-installs if a newer version is available.
10
15
  export async function checkForUpdate(currentVersion: string): Promise<void> {
@@ -17,19 +22,17 @@ export async function checkForUpdate(currentVersion: string): Promise<void> {
17
22
  if (latest && isNewer(latest, currentVersion)) {
18
23
  info(`\n› New version available (${currentVersion} → ${latest}) — installing…`);
19
24
  try {
20
- // Use the npm binary next to the active node so nvm users update the right install.
21
- const npmBin = process.execPath.replace(/[/\\]node$/, '/npm');
22
- execSync(`"${npmBin}" install -g @myapihq/cli`, { stdio: 'pipe' });
25
+ // Pin the exact version so npm can't resolve to a cached older one.
26
+ execSync(`"${npmBin()}" install -g @myapihq/cli@${latest}`, { stdio: 'pipe' });
23
27
  const config = loadConfig();
24
28
  if (config?.skills_installed) {
25
29
  await installSkills();
26
30
  }
27
- success(`› MyAPI CLI updated to ${latest}. Re-run your command.\n`);
28
- process.exit(0);
31
+ info(`› Updated to ${latest} active after this command completes.\n`);
29
32
  } catch (installErr: any) {
30
33
  const msg = installErr?.stderr?.toString?.() || installErr?.message || String(installErr);
31
34
  info(`› Auto-update failed: ${msg.trim()}`);
32
- info(`› Run manually: npm install -g @myapihq/cli`);
35
+ info(`› Run manually: npm install -g @myapihq/cli@${latest}`);
33
36
  }
34
37
  }
35
38
  } catch {
@@ -40,20 +43,22 @@ export async function checkForUpdate(currentVersion: string): Promise<void> {
40
43
  // myapi update — explicit update, same logic as auto-update.
41
44
  export async function update(flags: Record<string, string | boolean> = {}): Promise<void> {
42
45
  if (flags.help) {
43
- info('Usage: myapi update\n\nUpdates the MyAPI CLI and skills pack to the latest published version.\nEquivalent to: npm install -g @myapihq/cli');
46
+ info('Usage: myapi update\n\nUpdates the MyAPI CLI to the latest published version.\nEquivalent to: npm install -g @myapihq/cli@latest');
44
47
  return;
45
48
  }
46
49
  info('› Checking for updates…');
50
+ let latest = '';
47
51
  try {
48
52
  const res = await fetch(REGISTRY_URL, { signal: AbortSignal.timeout(5000) });
49
53
  if (!res.ok) throw new Error(`registry returned ${res.status}`);
50
54
  const data = await res.json() as { version?: string };
51
- info(`› Installing @myapihq/cli@${data.version}…`);
55
+ latest = data.version ?? '';
56
+ if (latest) info(`› Installing @myapihq/cli@${latest}…`);
52
57
  } catch { /* proceed anyway */ }
53
58
 
54
59
  try {
55
- const npmBin = process.execPath.replace(/[/\\]node$/, '/npm');
56
- execSync(`"${npmBin}" install -g @myapihq/cli`, { stdio: 'inherit' });
60
+ const pkg = latest ? `@myapihq/cli@${latest}` : '@myapihq/cli@latest';
61
+ execSync(`"${npmBin()}" install -g ${pkg}`, { stdio: 'inherit' });
57
62
  } catch {
58
63
  process.exit(1);
59
64
  }
package/src/index.ts CHANGED
@@ -48,13 +48,13 @@ async function main() {
48
48
  switch (command) {
49
49
  case 'auth':
50
50
  if (!subcommand || (flags.help && !subcommand)) {
51
- info('Usage: myapi auth <subcommand>\n\nSubcommands:\n setup Configure your account\n import-key Import an existing API key non-interactively\n whoami Show current account\n signup Upgrade anonymous account to registered\n switch [index] Switch between accounts\n config Manage CLI defaults (org_id, domain…)\n install-skills Install the MyAPI skills pack\n api-keys Manage API keys');
51
+ info('Usage: myapi auth <subcommand>\n\nSubcommands:\n setup Configure your account\n import-key Import an existing API key non-interactively\n whoami Show current account\n link Link an email to upgrade your anonymous account\n switch [index] Switch between accounts\n config Manage CLI defaults (org_id, domain…)\n install-skills Install the MyAPI skills pack\n api-keys Manage API keys');
52
52
  break;
53
53
  }
54
54
  if (subcommand === 'setup') await setupCmd.setup(flags);
55
55
  else if (subcommand === 'import-key') await setupCmd.importKey(restArgs[0], flags);
56
56
  else if (subcommand === 'whoami') await authCmd.whoami(flags);
57
- else if (subcommand === 'signup') await authCmd.signup(flags);
57
+ else if (subcommand === 'link') await authCmd.link(flags);
58
58
  else if (subcommand === 'switch') await authCmd.switchCmd(flags, restArgs[0]);
59
59
  else if (subcommand === 'install-skills') {
60
60
  if (flags.help) {
@@ -119,10 +119,16 @@ async function main() {
119
119
  }
120
120
  } catch (err: any) {
121
121
  if (err instanceof MyApiError) {
122
- if (err.status === 402) error('Insufficient balance. Run: myapi billing topup <amount>');
123
- else if (err.status === 401) error('Invalid API key. Run: myapi auth setup');
122
+ if (err.status === 401) error('Invalid API key. Run: myapi auth setup');
123
+ else if (err.status === 402) {
124
+ if (err.code === 'REGISTRATION_REQUIRED') error('A verified email is required. Run: myapi auth link');
125
+ else if (err.code === 'UPGRADE_REQUIRED') error('A verified email is required. Run: myapi auth link');
126
+ else error(`Insufficient balance. Run: myapi billing topup <amount>`);
127
+ }
128
+ else error(err.code || err.message);
129
+ } else {
130
+ error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err)));
124
131
  }
125
- error(err.message || (typeof err === 'object' ? JSON.stringify(err) : String(err)));
126
132
  }
127
133
  }
128
134
 
@@ -140,7 +146,7 @@ Usage: myapi <command> [subcommand] [args]
140
146
  myapi --version
141
147
 
142
148
  Commands:
143
- auth Manage account · setup · whoami · signup
149
+ auth Manage account · setup · whoami · link
144
150
  billing Check balance and manage billing
145
151
  org Manage organizations
146
152
  update Update CLI and skills to the latest version