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.
- package/bin/swytchcode.js +131 -145
- 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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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}
|
|
322
|
+
writeln(` ${c.dim}Done — ran through Swytchcode.${c.reset}`);
|
|
322
323
|
writeln();
|
|
323
324
|
} else {
|
|
324
|
-
writeln(` ${c.
|
|
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.
|
|
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}
|
|
464
|
-
writeln(` ${c.dim}
|
|
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
|
|
499
|
-
// wordmark
|
|
500
|
-
//
|
|
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 —
|
|
630
|
-
writeln(`${c.dim} Run a
|
|
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
|
-
|
|
648
|
-
|
|
649
|
-
{
|
|
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
|
-
|
|
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
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
}
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
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
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
{ label
|
|
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
|
-
|
|
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
|
-
|
|
693
|
-
if (
|
|
694
|
-
writeln(` ${c.
|
|
695
|
-
writeln(
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
writeln(
|
|
706
|
-
|
|
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.
|
|
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.
|
|
749
|
-
writeln(` ${c.
|
|
750
|
-
writeln(` ${c.
|
|
751
|
-
writeln(` ${c.
|
|
752
|
-
writeln(` ${c.
|
|
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.
|
|
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.
|
|
32
|
-
"swytchcode-cli-darwin-x64": "2.14.0-beta.
|
|
33
|
-
"swytchcode-cli-linux-arm64": "2.14.0-beta.
|
|
34
|
-
"swytchcode-cli-linux-x64": "2.14.0-beta.
|
|
35
|
-
"swytchcode-cli-win32-arm64": "2.14.0-beta.
|
|
36
|
-
"swytchcode-cli-win32-x64": "2.14.0-beta.
|
|
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
|
}
|