swytchcode 2.14.0-beta.2 → 2.14.0-beta.5

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.
Files changed (2) hide show
  1. package/bin/swytchcode.js +131 -145
  2. package/package.json +7 -7
package/bin/swytchcode.js CHANGED
@@ -22,6 +22,7 @@ const c = {
22
22
  green: '\x1b[32m',
23
23
  yellow: '\x1b[33m',
24
24
  cyan: '\x1b[36m',
25
+ orange: '\x1b[38;5;214m', // brand orange (matches internal/output banner 256 fallback)
25
26
  white: '\x1b[37m',
26
27
  gray: '\x1b[90m',
27
28
  bgGreen: '\x1b[42m',
@@ -33,7 +34,7 @@ function write(msg) { process.stdout.write(msg); }
33
34
  function writeln(msg = '') { process.stdout.write(msg + '\n'); }
34
35
  function err(msg) { process.stderr.write(msg + '\n'); }
35
36
 
36
- function box(lines, colour = c.cyan) {
37
+ function box(lines, colour = c.orange) {
37
38
  const width = Math.max(...lines.map(l => stripAnsi(l).length)) + 4;
38
39
  const bar = colour + '─'.repeat(width) + c.reset;
39
40
  writeln(bar);
@@ -77,7 +78,7 @@ function menuArrow(prompt, options) {
77
78
  writeln(c.bold + prompt + c.reset);
78
79
  writeln();
79
80
  options.forEach((o, i) => {
80
- writeln(` ${c.cyan}${i + 1}${c.reset} ${stripAnsi(o.label)}`);
81
+ writeln(` ${c.orange}${i + 1}${c.reset} ${stripAnsi(o.label)}`);
81
82
  });
82
83
  writeln();
83
84
  while (true) {
@@ -103,7 +104,7 @@ function menuArrow(prompt, options) {
103
104
  writeln();
104
105
  options.forEach((o, i) => {
105
106
  if (i === selectedIndex) {
106
- writeln(` ${c.cyan}❯${c.reset} ${c.bold}${c.green}${stripAnsi(o.label)}${c.reset}`);
107
+ writeln(` ${c.orange}❯${c.reset} ${c.bold}${c.green}${stripAnsi(o.label)}${c.reset}`);
107
108
  } else {
108
109
  writeln(` ${c.dim}${stripAnsi(o.label)}${c.reset}`);
109
110
  }
@@ -160,7 +161,7 @@ function spinner(msg) {
160
161
  const frames = ['⠋','⠙','⠹','⠸','⠼','⠴','⠦','⠧','⠇','⠏'];
161
162
  let i = 0;
162
163
  const iv = setInterval(() => {
163
- process.stdout.write(`\r${c.cyan}${frames[i++ % frames.length]}${c.reset} ${msg}`);
164
+ process.stdout.write(`\r${c.orange}${frames[i++ % frames.length]}${c.reset} ${msg}`);
164
165
  }, 80);
165
166
  return {
166
167
  stop(doneMsg) {
@@ -313,15 +314,15 @@ if (userArgs.length > 0 && /^[\w]+\.[\w.]+$/.test(userArgs[0]) && !userArgs[0].s
313
314
  }
314
315
  async function runOnboardingDirectDemo(canonicalId) {
315
316
  writeln();
316
- writeln(` ${c.yellow}⚡ Running ${c.bold}${canonicalId}${c.reset}${c.yellow} live...${c.reset}`);
317
+ writeln(` ${c.dim}Running ${c.reset}${c.bold}${canonicalId}${c.reset}${c.dim} ...${c.reset}`);
317
318
  writeln();
318
319
  const demoResult = spawnBin(binPath, ['exec', canonicalId], { SWYTCHCODE_ONBOARDING: '1' });
319
320
  writeln();
320
321
  if (demoResult.status === 0) {
321
- writeln(` ${c.dim}That was a real API call through Swytchcode.${c.reset}`);
322
+ writeln(` ${c.dim}Done — ran through Swytchcode.${c.reset}`);
322
323
  writeln();
323
324
  } else {
324
- writeln(` ${c.yellow}⚠ ${c.bold}${canonicalId}${c.reset}${c.yellow} isn't a valid demo tool.${c.reset}`);
325
+ writeln(` ${c.dim}${c.bold}${canonicalId}${c.reset}${c.dim} isn't a demo tool — running a sample instead.${c.reset}`);
325
326
  writeln(` ${c.dim}Let's run a working demo instead.${c.reset}`);
326
327
  writeln();
327
328
  await runDemoSelection();
@@ -367,25 +368,6 @@ const CARD_WORDMARK = [
367
368
  '███████║╚███╔███╔╝ ██║ ██║ ╚██████╗██║ ██║╚██████╗╚██████╔╝██████╔╝███████╗',
368
369
  '╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝',
369
370
  ];
370
- const CARD_MARK = [
371
- ' ▄▄▄█████████▄▄',
372
- ' ▄▄███▀▀▀ ▀▀▀███▄',
373
- ' ▄███▀',
374
- ' ███ ▄████████▀',
375
- ' ██▀ █████████',
376
- ' ██▀ ▄████████▀',
377
- '███ ▄████████▀',
378
- '██ █████████',
379
- '██ ▄██████████████▀',
380
- '██ ▄██████████████▀',
381
- '▀██ ██████▀▄█████▀',
382
- ' ██▄ ▄████▀',
383
- ' ██▄ ▄████▀',
384
- ' ▀██▄ ▄██▀ ▄',
385
- ' ▀▀▀ ▄█▀▀ ▄▄███',
386
- ' ▄▀ ▄▄▄▄▄▄▄▄▄████▀▀',
387
- ' ▀ ▀▀████████▀▀',
388
- ];
389
371
  const CARD_TAGLINE = 'Your agent calls an API. We make sure it goes through.';
390
372
  const CARD_DESCRIPTION = 'Swytchcode sits between your agent and any API — auth, retries, idempotency, and schema validation, handled. Run a command below, or swytchcode --help for the full list.';
391
373
 
@@ -409,7 +391,7 @@ if (isNpx && isCanonicalDemoArg) {
409
391
  } else if (isNpxBareWordArg) {
410
392
  // Single bare word (e.g. "abcd") — not a valid canonical ID; show message then onboard
411
393
  writeln();
412
- writeln(` ${c.yellow}⚠ ${c.bold}${originalArg}${c.reset}${c.yellow} isn't a valid demo tool — canonical IDs look like ${c.bold}provider.method${c.reset}`);
394
+ writeln(` ${c.dim}${c.bold}${originalArg}${c.reset}${c.dim} isn't a demo tool — IDs look like ${c.reset}${c.bold}provider.method${c.reset}`);
413
395
  writeln(` ${c.dim}Let's run a working demo instead.${c.reset}`);
414
396
  writeln();
415
397
  Promise.resolve()
@@ -460,8 +442,8 @@ async function runDemoSelection() {
460
442
  writeln(` ${c.gray}$ swytchcode demo stripe${c.reset}`);
461
443
  spawnBin(binPath, ['demo', 'stripe'], { SWYTCHCODE_ONBOARDING: '1' });
462
444
  writeln();
463
- writeln(` ${c.dim}That was a real API call. No credentials, no setup.${c.reset}`);
464
- writeln(` ${c.dim}With Swytchcode, every API integration works exactly like this.${c.reset}`);
445
+ writeln(` ${c.dim}Done — ran through Swytchcode's demo account.${c.reset}`);
446
+ writeln(` ${c.dim}Every integration runs the same way.${c.reset}`);
465
447
  }
466
448
  }
467
449
 
@@ -495,19 +477,16 @@ function writeDescRows(boxRow, orange, contentW, margin) {
495
477
  }
496
478
  }
497
479
 
498
- // welcomeCard renders the framed welcome card (logo mark left + wordmark right,
499
- // wordmark vertically centered), stepping down to a plain wordmark or the compact
500
- // banner based on width / UTF-8 / truecolor / TTY / NO_COLOR. Mirrors the Go banner.
480
+ // welcomeCard renders the universal welcome banner: the "swytchcode" figlet
481
+ // wordmark, version, tagline, and wrapped description inside a framed box — no
482
+ // bolt logo. Mirrors wordmarkBanner in internal/output/banner.go so npx
483
+ // onboarding and the installed CLI look identical (single form, no tiering).
501
484
  function welcomeCard(cliVersion) {
502
485
  const isTTY = !!process.stdout.isTTY;
503
- const width = process.stdout.columns || 0;
504
486
  const ct = process.env.COLORTERM || '';
505
487
  const truecolor = ct === 'truecolor' || ct === '24bit';
506
488
  const noColor = !!process.env.NO_COLOR || !!process.env.CI;
507
489
  const useColor = !noColor && isTTY;
508
- const utf8 = process.platform === 'win32'
509
- ? (!!process.env.WT_SESSION || process.env.TERM_PROGRAM === 'vscode' || process.env.ConEmuANSI === 'ON')
510
- : /utf-?8/i.test(process.env.LC_ALL || process.env.LC_CTYPE || process.env.LANG || '');
511
490
 
512
491
  const orange = s => !useColor ? s : (truecolor ? `\x1b[38;2;245;148;30m${s}\x1b[0m` : `\x1b[38;5;214m${s}\x1b[0m`);
513
492
  const frame = s => !useColor ? s : (truecolor ? `\x1b[38;2;122;78;24m${s}\x1b[0m` : `\x1b[38;5;214m${s}\x1b[0m`);
@@ -515,63 +494,16 @@ function welcomeCard(cliVersion) {
515
494
  const green = s => !useColor ? s : `\x1b[32m${s}\x1b[0m`;
516
495
 
517
496
  const { rows: wm, w: wmW } = padRows(CARD_WORDMARK);
518
- const { rows: mk, w: mkW } = padRows(CARD_MARK);
519
- const gutter = 4, margin = 2;
520
- const innerW = margin + mkW + gutter + wmW + margin;
521
- const cardW = innerW + 2;
522
-
523
- const wmCardW = margin + wmW + margin + 2; // framed wordmark-only box width
524
-
525
- if (!isTTY || noColor) { compactCard(cliVersion, false); return; }
526
- if (!utf8 || width < wmCardW + 2) { compactCard(cliVersion, useColor); return; }
527
- if (!truecolor || width < cardW + 2) { wordmarkCard({ orange, dim, frame, green, wm, wmW }); return; }
528
-
529
- const boxRow = (colored, vis) => frame('│') + colored + rep(' ', Math.max(0, innerW - vis)) + frame('│');
530
- writeln();
531
- const title = ' Welcome to Swytchcode ';
532
- writeln(frame('┌─' + title + rep('─', innerW - 1 - vlen(title)) + '┐'));
533
- writeln(boxRow('', 0));
534
- // Logo (left) + wordmark (right); wordmark vertically centered.
535
- const nRows = Math.max(mk.length, wm.length);
536
- const wmOff = Math.max(0, Math.floor((mk.length - wm.length) / 2));
537
- for (let i = 0; i < nRows; i++) {
538
- const left = i < mk.length ? orange(mk[i]) : rep(' ', mkW);
539
- const wi = i - wmOff;
540
- const right = (wi >= 0 && wi < wm.length) ? orange(wm[wi]) : rep(' ', wmW);
541
- writeln(boxRow(rep(' ', margin) + left + rep(' ', gutter) + right, margin + mkW + gutter + wmW));
542
- }
543
- writeln(boxRow('', 0));
544
- // Tagline centered across the inner width.
545
- const lead = margin + Math.floor((innerW - 2 * margin - vlen(CARD_TAGLINE)) / 2);
546
- writeln(boxRow(rep(' ', lead) + dim(CARD_TAGLINE), lead + vlen(CARD_TAGLINE)));
547
- writeln(boxRow('', 0));
548
- writeDescRows(boxRow, orange, innerW - 2 * margin, margin);
549
- writeln(boxRow('', 0));
550
- writeln(frame('└' + rep('─', innerW) + '┘'));
551
- cardBelow({ orange, dim, green });
552
- }
553
-
554
- function compactCard(cliVersion, useColor) {
555
- const orange = s => useColor ? `\x1b[38;5;214m${s}\x1b[0m` : s;
556
- const dim = s => useColor ? `\x1b[2m${s}\x1b[0m` : s;
557
- writeln();
558
- writeln(` ${orange('swytchcode')} ${dim('v' + cliVersion)}`);
559
- writeln(` ${CARD_TAGLINE}`);
560
- writeln();
561
- writeln(` ${dim('docs')} docs.swytchcode.com`);
562
- writeln(` ${dim('chat')} discord.gg/zuSXSv5GWs`);
563
- writeln();
564
- }
565
-
566
- function wordmarkCard({ orange, dim, frame, green, wm, wmW }) {
567
497
  const margin = 2;
568
498
  const innerW = margin + wmW + margin;
569
499
  const boxRow = (colored, vis) => frame('│') + colored + rep(' ', Math.max(0, innerW - vis)) + frame('│');
500
+
570
501
  writeln();
571
502
  const title = ' Welcome to Swytchcode ';
572
503
  writeln(frame('┌─' + title + rep('─', innerW - 1 - vlen(title)) + '┐'));
573
504
  writeln(boxRow('', 0));
574
505
  for (const row of wm) writeln(boxRow(rep(' ', margin) + orange(row), margin + wmW));
506
+ writeln(boxRow(rep(' ', margin) + dim('v' + cliVersion), margin + 1 + vlen(cliVersion)));
575
507
  writeln(boxRow('', 0));
576
508
  const lead = margin + Math.floor((innerW - 2 * margin - vlen(CARD_TAGLINE)) / 2);
577
509
  writeln(boxRow(rep(' ', lead) + dim(CARD_TAGLINE), lead + vlen(CARD_TAGLINE)));
@@ -626,47 +558,94 @@ async function runOnboarding() {
626
558
  writeln();
627
559
 
628
560
  // ── Step 1: Demo ──────────────────────────────────────────────────────────
629
- writeln(`${c.bold} Step 1 of 4 — See it in action${c.reset}`);
630
- writeln(`${c.dim} Run a live API call right now, no setup required.${c.reset}`);
561
+ writeln(`${c.bold} Step 1 of 4 — Run a live call${c.reset}`);
562
+ writeln(`${c.dim} Run a real API call through Swytchcode.${c.reset}`);
631
563
  writeln();
632
564
  await runDemoSelection();
633
565
  await runOnboardingSteps2to4();
634
566
  }
635
567
 
568
+ // isGloballyInstalled reports whether a real, persistent global `swytchcode`
569
+ // exists on PATH — as opposed to the transient npx cache binary this script is
570
+ // currently running from. Used to skip the "install globally" onboarding step
571
+ // when it's already installed.
572
+ function isGloballyInstalled() {
573
+ try {
574
+ const probe = process.platform === 'win32' ? 'where swytchcode' : 'command -v swytchcode';
575
+ const out = execSync(probe, { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }).trim();
576
+ if (!out) return false;
577
+ // Any resolved path that isn't inside the npx cache means a global install exists.
578
+ return out.split(/\r?\n/).some(line => line && !line.toLowerCase().includes('_npx'));
579
+ } catch (_) {
580
+ return false; // not found on PATH
581
+ }
582
+ }
583
+
584
+ // authStatus reports whether the user is already authenticated, so onboarding
585
+ // can skip the login prompt. Priority: SWYTCHCODE_TOKEN env var, then a
586
+ // SWYTCHCODE_TOKEN in ./.env, then a valid (unexpired) user session in
587
+ // ~/.swytchcode/auth.json.
588
+ function authStatus() {
589
+ if ((process.env.SWYTCHCODE_TOKEN || '').trim()) {
590
+ return { authed: true, label: 'authenticated via SWYTCHCODE_TOKEN' };
591
+ }
592
+ try {
593
+ const envPath = path.join(process.cwd(), '.env');
594
+ if (fs.existsSync(envPath)) {
595
+ const m = fs.readFileSync(envPath, 'utf8').match(/^\s*SWYTCHCODE_TOKEN\s*=\s*["']?([^"'\r\n#]+)/m);
596
+ if (m && m[1].trim()) return { authed: true, label: 'authenticated via .env token' };
597
+ }
598
+ } catch (_) {}
599
+ try {
600
+ const authPath = path.join(require('os').homedir(), '.swytchcode', 'auth.json');
601
+ const s = JSON.parse(fs.readFileSync(authPath, 'utf8'));
602
+ if (s && s.access_token && typeof s.expires_at === 'number' && Date.now() < s.expires_at * 1000) {
603
+ return { authed: true, label: s.email ? ('signed in as ' + s.email) : 'signed in' };
604
+ }
605
+ } catch (_) {}
606
+ return { authed: false, label: '' };
607
+ }
608
+
636
609
  async function runOnboardingSteps2to4() {
637
610
  // ── Step 2: Install ───────────────────────────────────────────────────────
638
611
  writeln();
639
612
  writeln(' ' + '─'.repeat(45));
640
613
  writeln();
641
614
  writeln(`${c.bold} Step 2 of 4 — Install Swytchcode${c.reset}`);
642
- writeln(`${c.dim} Install once, use everywhere. Adds the ${c.reset}${c.cyan}swytchcode${c.reset}${c.dim} command to your terminal.${c.reset}`);
643
- writeln();
644
- writeln(` ${c.dim}$ npm install -g swytchcode${c.reset}`);
645
- writeln();
646
615
 
647
- const installChoice = await menuArrow('Install globally?', [
648
- { label: 'Yes, install globally', value: 'yes' },
649
- { label: 'Skip for now', value: 'no' },
650
- ]);
616
+ if (isGloballyInstalled()) {
617
+ // Already installed — don't re-offer the install step.
618
+ writeln(` ${c.green}›${c.reset} ${c.dim}swytchcode is already installed globally — skipping.${c.reset}`);
619
+ } else {
620
+ writeln(`${c.dim} Install the ${c.reset}${c.orange}swytchcode${c.reset}${c.dim} command globally.${c.reset}`);
621
+ writeln();
622
+ writeln(` ${c.dim}$ npm install -g swytchcode${c.reset}`);
623
+ writeln();
651
624
 
652
- writeln();
625
+ const installChoice = await menuArrow('Install globally?', [
626
+ { label: 'Yes, install globally', value: 'yes' },
627
+ { label: 'Skip for now', value: 'no' },
628
+ ]);
653
629
 
654
- if (installChoice === 'no') {
655
- writeln(` ${c.dim}Skipped. Install manually with:${c.reset}`);
656
- writeln(` ${c.cyan}npm install -g swytchcode${c.reset}`);
657
- } else {
658
- const installSpin = spinner('Running npm install -g swytchcode ...');
659
- try {
660
- execSync('npm install -g swytchcode', { stdio: 'pipe' });
661
- installSpin.stop('installed');
662
- } catch (e) {
663
- if (e.signal === 'SIGINT') {
664
- installSpin.stop('Cancelled');
665
- try { process.stdin.setRawMode(false); } catch (_) {}
666
- process.stdout.write('\x1b[?25h');
667
- process.exit(130);
630
+ writeln();
631
+
632
+ if (installChoice === 'no') {
633
+ writeln(` ${c.dim}Skipped. Install manually with:${c.reset}`);
634
+ writeln(` ${c.orange}npm install -g swytchcode${c.reset}`);
635
+ } else {
636
+ const installSpin = spinner('Running npm install -g swytchcode ...');
637
+ try {
638
+ execSync('npm install -g swytchcode', { stdio: 'pipe' });
639
+ installSpin.stop('installed');
640
+ } catch (e) {
641
+ if (e.signal === 'SIGINT') {
642
+ installSpin.stop('Cancelled');
643
+ try { process.stdin.setRawMode(false); } catch (_) {}
644
+ process.stdout.write('\x1b[?25h');
645
+ process.exit(130);
646
+ }
647
+ installSpin.fail('Installation failed.');
668
648
  }
669
- installSpin.fail('Installation failed.');
670
649
  }
671
650
  }
672
651
 
@@ -675,41 +654,48 @@ async function runOnboardingSteps2to4() {
675
654
  writeln(' ' + '─'.repeat(45));
676
655
  writeln();
677
656
  writeln(`${c.bold} Step 3 of 4 — Connect your account${c.reset}`);
678
- writeln(`${c.dim} See your usage analytics, execution history, and saved projects.${c.reset}`);
679
- writeln();
680
657
 
681
- const authChoice = await menuArrow('Do you already have an account?', [
682
- { label: 'Login to my account', value: 'login' },
683
- { label: 'Create a new account', value: 'register' },
684
- { label: 'Continue anonymously', value: 'anon' },
685
- ]);
658
+ const auth = authStatus();
659
+ if (auth.authed) {
660
+ // Already authenticated — never re-prompt for login.
661
+ writeln(` ${c.green}›${c.reset} ${c.dim}Already ${auth.label} — skipping.${c.reset}`);
662
+ } else {
663
+ writeln(`${c.dim} See your usage analytics, execution history, and saved projects.${c.reset}`);
664
+ writeln();
686
665
 
687
- writeln();
666
+ const authChoice = await menuArrow('Do you already have an account?', [
667
+ { label: 'Login to my account', value: 'login' },
668
+ { label: 'Create a new account', value: 'register' },
669
+ { label: 'Continue anonymously', value: 'anon' },
670
+ ]);
688
671
 
689
- if (authChoice === 'login') {
690
- writeln(` ${c.dim}Opening browser for login ...${c.reset}`);
691
672
  writeln();
692
- const result = spawnBin(binPath, ['login']);
693
- if (result.error || result.status !== 0) {
694
- writeln(` ${c.yellow}Login window closed or failed.${c.reset}`);
695
- writeln(` ${c.dim}You can log in later with:${c.reset} ${c.cyan}swytchcode login${c.reset}`);
696
- } else {
697
- writeln(` ${c.green}›${c.reset} logged in`);
698
- }
699
- } else if (authChoice === 'register') {
700
- writeln(` ${c.dim}Opening browser to create your account ...${c.reset}`);
701
- writeln();
702
- // login command handles both login and registration via the browser flow
703
- const result = spawnBin(binPath, ['login']);
704
- if (result.error || result.status !== 0) {
705
- writeln(` ${c.yellow}Browser window closed or failed.${c.reset}`);
706
- writeln(` ${c.dim}Create your account at:${c.reset} ${c.cyan}https://swytchcode.com/signup${c.reset}`);
673
+
674
+ if (authChoice === 'login') {
675
+ writeln(` ${c.dim}Opening browser for login ...${c.reset}`);
676
+ writeln();
677
+ const result = spawnBin(binPath, ['login']);
678
+ if (result.error || result.status !== 0) {
679
+ writeln(` ${c.yellow}Login window closed or failed.${c.reset}`);
680
+ writeln(` ${c.dim}You can log in later with:${c.reset} ${c.orange}swytchcode login${c.reset}`);
681
+ } else {
682
+ writeln(` ${c.green}›${c.reset} logged in`);
683
+ }
684
+ } else if (authChoice === 'register') {
685
+ writeln(` ${c.dim}Opening browser to create your account ...${c.reset}`);
686
+ writeln();
687
+ // login command handles both login and registration via the browser flow
688
+ const result = spawnBin(binPath, ['login']);
689
+ if (result.error || result.status !== 0) {
690
+ writeln(` ${c.yellow}Browser window closed or failed.${c.reset}`);
691
+ writeln(` ${c.dim}Create your account at:${c.reset} ${c.orange}https://swytchcode.com/signup${c.reset}`);
692
+ } else {
693
+ writeln(` ${c.green}›${c.reset} account connected`);
694
+ }
707
695
  } else {
708
- writeln(` ${c.green}›${c.reset} account connected`);
696
+ writeln(` ${c.dim}No problem — you can connect your account any time with:${c.reset}`);
697
+ writeln(` ${c.orange}swytchcode login${c.reset}`);
709
698
  }
710
- } else {
711
- writeln(` ${c.dim}No problem — you can connect your account any time with:${c.reset}`);
712
- writeln(` ${c.cyan}swytchcode login${c.reset}`);
713
699
  }
714
700
 
715
701
  // ── Step 4: Next action ───────────────────────────────────────────────────
@@ -745,11 +731,11 @@ async function runOnboardingSteps2to4() {
745
731
  writeln(` ${c.bold}You're all set.${c.reset}`);
746
732
  writeln();
747
733
  writeln(` Quick reference:`);
748
- writeln(` ${c.cyan}swytchcode init${c.reset} ${c.dim}Set up a new project${c.reset}`);
749
- writeln(` ${c.cyan}swytchcode examples${c.reset} ${c.dim}Browse example integrations${c.reset}`);
750
- writeln(` ${c.cyan}swytchcode get <api>${c.reset} ${c.dim}Install an API integration${c.reset}`);
751
- writeln(` ${c.cyan}swytchcode exec <id>${c.reset} ${c.dim}Execute an API method${c.reset}`);
752
- writeln(` ${c.cyan}swytchcode --help${c.reset} ${c.dim}Full command reference${c.reset}`);
734
+ writeln(` ${c.orange}swytchcode init${c.reset} ${c.dim}Set up a new project${c.reset}`);
735
+ writeln(` ${c.orange}swytchcode examples${c.reset} ${c.dim}Browse example integrations${c.reset}`);
736
+ writeln(` ${c.orange}swytchcode get <api>${c.reset} ${c.dim}Install an API integration${c.reset}`);
737
+ writeln(` ${c.orange}swytchcode exec <id>${c.reset} ${c.dim}Execute an API method${c.reset}`);
738
+ writeln(` ${c.orange}swytchcode --help${c.reset} ${c.dim}Full command reference${c.reset}`);
753
739
  }
754
740
 
755
741
  writeln();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "swytchcode",
3
- "version": "2.14.0-beta.2",
3
+ "version": "2.14.0-beta.5",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://gitlab.com/swytchcode/cli.git"
@@ -28,11 +28,11 @@
28
28
  "README.md"
29
29
  ],
30
30
  "optionalDependencies": {
31
- "swytchcode-cli-darwin-arm64": "2.14.0-beta.2",
32
- "swytchcode-cli-darwin-x64": "2.14.0-beta.2",
33
- "swytchcode-cli-linux-arm64": "2.14.0-beta.2",
34
- "swytchcode-cli-linux-x64": "2.14.0-beta.2",
35
- "swytchcode-cli-win32-arm64": "2.14.0-beta.2",
36
- "swytchcode-cli-win32-x64": "2.14.0-beta.2"
31
+ "swytchcode-cli-darwin-arm64": "2.14.0-beta.5",
32
+ "swytchcode-cli-darwin-x64": "2.14.0-beta.5",
33
+ "swytchcode-cli-linux-arm64": "2.14.0-beta.5",
34
+ "swytchcode-cli-linux-x64": "2.14.0-beta.5",
35
+ "swytchcode-cli-win32-arm64": "2.14.0-beta.5",
36
+ "swytchcode-cli-win32-x64": "2.14.0-beta.5"
37
37
  }
38
38
  }