swytchcode 2.10.3 → 2.14.0-beta.2
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 +225 -60
- package/package.json +13 -8
package/bin/swytchcode.js
CHANGED
|
@@ -87,7 +87,7 @@ function menuArrow(prompt, options) {
|
|
|
87
87
|
resolve(options[n - 1].value);
|
|
88
88
|
return;
|
|
89
89
|
}
|
|
90
|
-
writeln(`${c.red}
|
|
90
|
+
writeln(`${c.red} invalid choice — enter a number between 1 and ${options.length}${c.reset}`);
|
|
91
91
|
}
|
|
92
92
|
}
|
|
93
93
|
|
|
@@ -165,11 +165,11 @@ function spinner(msg) {
|
|
|
165
165
|
return {
|
|
166
166
|
stop(doneMsg) {
|
|
167
167
|
clearInterval(iv);
|
|
168
|
-
process.stdout.write(`\r${c.green}
|
|
168
|
+
process.stdout.write(`\r\x1b[K${c.green}›${c.reset} ${doneMsg}\n`);
|
|
169
169
|
},
|
|
170
170
|
fail(failMsg) {
|
|
171
171
|
clearInterval(iv);
|
|
172
|
-
process.stdout.write(`\r${c.red}
|
|
172
|
+
process.stdout.write(`\r\x1b[K${c.red}×${c.reset} ${failMsg}\n`);
|
|
173
173
|
},
|
|
174
174
|
};
|
|
175
175
|
}
|
|
@@ -208,7 +208,7 @@ function apiPost(urlStr, body) {
|
|
|
208
208
|
function spawnBin(binPath, args, extraEnv = {}) {
|
|
209
209
|
const env = { ...process.env, ...extraEnv };
|
|
210
210
|
let result;
|
|
211
|
-
if (process.stdin.isTTY) {
|
|
211
|
+
if (process.stdin.isTTY || (args.length > 0 && args[0] === 'mcp')) {
|
|
212
212
|
result = spawnSync(binPath, args, { stdio: 'inherit', env });
|
|
213
213
|
} else {
|
|
214
214
|
let stdinData;
|
|
@@ -242,9 +242,16 @@ function exitCode(result) {
|
|
|
242
242
|
return 1;
|
|
243
243
|
}
|
|
244
244
|
|
|
245
|
-
// Explicit override: SWYTCHCODE_BIN=/path/to/binary bypasses platform resolution
|
|
245
|
+
// Explicit override: SWYTCHCODE_BIN=/path/to/binary bypasses platform resolution
|
|
246
|
+
// and passes straight through to that binary. The one exception is a bare
|
|
247
|
+
// npx-style launch (npm_command=exec / npx, with no args): there we keep the
|
|
248
|
+
// override binary but skip the passthrough so the onboarding still runs (using
|
|
249
|
+
// that binary for its subprocess calls), which makes onboarding testable locally.
|
|
246
250
|
const explicitBin = (process.env.SWYTCHCODE_BIN || '').trim();
|
|
247
|
-
|
|
251
|
+
const bareNpxLaunch =
|
|
252
|
+
process.argv.length <= 2 &&
|
|
253
|
+
((process.env.npm_command || '') === 'exec' || (process.env.npm_execpath || '').includes('npx'));
|
|
254
|
+
if (explicitBin && !bareNpxLaunch) {
|
|
248
255
|
const result = spawnBin(explicitBin, process.argv.slice(2));
|
|
249
256
|
if (result.error) {
|
|
250
257
|
err(`swytchcode: failed to launch SWYTCHCODE_BIN="${explicitBin}": ${result.error.message}`);
|
|
@@ -253,40 +260,38 @@ if (explicitBin) {
|
|
|
253
260
|
process.exit(exitCode(result));
|
|
254
261
|
}
|
|
255
262
|
|
|
256
|
-
const PLATFORM_PACKAGES = {
|
|
257
|
-
'darwin-arm64': 'swytchcode-cli-darwin-arm64',
|
|
258
|
-
'darwin-x64': 'swytchcode-cli-darwin-x64',
|
|
259
|
-
'linux-arm64': 'swytchcode-cli-linux-arm64',
|
|
260
|
-
'linux-x64': 'swytchcode-cli-linux-x64',
|
|
261
|
-
'win32-arm64': 'swytchcode-cli-win32-arm64',
|
|
262
|
-
'win32-x64': 'swytchcode-cli-win32-x64',
|
|
263
|
-
};
|
|
264
|
-
|
|
265
|
-
const platform = process.platform;
|
|
266
|
-
const arch = process.arch;
|
|
267
|
-
const key = `${platform}-${arch}`;
|
|
268
|
-
const pkg = PLATFORM_PACKAGES[key];
|
|
269
|
-
|
|
270
|
-
if (!pkg) {
|
|
271
|
-
err(
|
|
272
|
-
`swytchcode: unsupported platform "${key}".\n` +
|
|
273
|
-
`Supported: ${Object.keys(PLATFORM_PACKAGES).join(', ')}\n` +
|
|
274
|
-
`Install via curl instead: https://cli.swytchcode.com`
|
|
275
|
-
);
|
|
276
|
-
process.exit(1);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
const isWindows = platform === 'win32';
|
|
280
|
-
const binName = isWindows ? 'swytchcode.exe' : 'swytchcode';
|
|
281
263
|
let binPath;
|
|
282
|
-
|
|
283
|
-
binPath =
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
264
|
+
if (explicitBin) {
|
|
265
|
+
binPath = explicitBin;
|
|
266
|
+
} else {
|
|
267
|
+
const PLATFORM_PACKAGES = {
|
|
268
|
+
'darwin-arm64': 'swytchcode-cli-darwin-arm64',
|
|
269
|
+
'darwin-x64': 'swytchcode-cli-darwin-x64',
|
|
270
|
+
'linux-arm64': 'swytchcode-cli-linux-arm64',
|
|
271
|
+
'linux-x64': 'swytchcode-cli-linux-x64',
|
|
272
|
+
'win32-arm64': 'swytchcode-cli-win32-arm64',
|
|
273
|
+
'win32-x64': 'swytchcode-cli-win32-x64',
|
|
274
|
+
};
|
|
275
|
+
const key = `${process.platform}-${process.arch}`;
|
|
276
|
+
const pkg = PLATFORM_PACKAGES[key];
|
|
277
|
+
if (!pkg) {
|
|
278
|
+
err(
|
|
279
|
+
`swytchcode: unsupported platform "${key}".\n` +
|
|
280
|
+
`Supported: ${Object.keys(PLATFORM_PACKAGES).join(', ')}\n` +
|
|
281
|
+
`Install via curl instead: https://cli.swytchcode.com`
|
|
282
|
+
);
|
|
283
|
+
process.exit(1);
|
|
284
|
+
}
|
|
285
|
+
const binName = process.platform === 'win32' ? 'swytchcode.exe' : 'swytchcode';
|
|
286
|
+
try {
|
|
287
|
+
binPath = require.resolve(`${pkg}/bin/${binName}`);
|
|
288
|
+
} catch (_) {
|
|
289
|
+
err(
|
|
290
|
+
`swytchcode: could not find the binary for "${key}".\n` +
|
|
291
|
+
`Try reinstalling: npm install -g swytchcode`
|
|
292
|
+
);
|
|
293
|
+
process.exit(1);
|
|
294
|
+
}
|
|
290
295
|
}
|
|
291
296
|
|
|
292
297
|
// Detect npx
|
|
@@ -351,6 +356,39 @@ function apiGet(urlStr) {
|
|
|
351
356
|
});
|
|
352
357
|
}
|
|
353
358
|
|
|
359
|
+
// ─── Welcome card data (mirrors internal/output/banner.go). Declared before the
|
|
360
|
+
// dispatch below because runOnboarding() runs at module-load time and must not
|
|
361
|
+
// hit a temporal-dead-zone on these consts. ─────────────────────────────────
|
|
362
|
+
const CARD_WORDMARK = [
|
|
363
|
+
'███████╗██╗ ██╗██╗ ██╗████████╗ ██████╗██╗ ██╗ ██████╗ ██████╗ ██████╗ ███████╗',
|
|
364
|
+
'██╔════╝██║ ██║╚██╗ ██╔╝╚══██╔══╝██╔════╝██║ ██║██╔════╝██╔═══██╗██╔══██╗██╔════╝',
|
|
365
|
+
'███████╗██║ █╗ ██║ ╚████╔╝ ██║ ██║ ███████║██║ ██║ ██║██║ ██║█████╗',
|
|
366
|
+
'╚════██║██║███╗██║ ╚██╔╝ ██║ ██║ ██╔══██║██║ ██║ ██║██║ ██║██╔══╝',
|
|
367
|
+
'███████║╚███╔███╔╝ ██║ ██║ ╚██████╗██║ ██║╚██████╗╚██████╔╝██████╔╝███████╗',
|
|
368
|
+
'╚══════╝ ╚══╝╚══╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝ ╚═════╝ ╚═════╝ ╚═════╝ ╚══════╝',
|
|
369
|
+
];
|
|
370
|
+
const CARD_MARK = [
|
|
371
|
+
' ▄▄▄█████████▄▄',
|
|
372
|
+
' ▄▄███▀▀▀ ▀▀▀███▄',
|
|
373
|
+
' ▄███▀',
|
|
374
|
+
' ███ ▄████████▀',
|
|
375
|
+
' ██▀ █████████',
|
|
376
|
+
' ██▀ ▄████████▀',
|
|
377
|
+
'███ ▄████████▀',
|
|
378
|
+
'██ █████████',
|
|
379
|
+
'██ ▄██████████████▀',
|
|
380
|
+
'██ ▄██████████████▀',
|
|
381
|
+
'▀██ ██████▀▄█████▀',
|
|
382
|
+
' ██▄ ▄████▀',
|
|
383
|
+
' ██▄ ▄████▀',
|
|
384
|
+
' ▀██▄ ▄██▀ ▄',
|
|
385
|
+
' ▀▀▀ ▄█▀▀ ▄▄███',
|
|
386
|
+
' ▄▀ ▄▄▄▄▄▄▄▄▄████▀▀',
|
|
387
|
+
' ▀ ▀▀████████▀▀',
|
|
388
|
+
];
|
|
389
|
+
const CARD_TAGLINE = 'Your agent calls an API. We make sure it goes through.';
|
|
390
|
+
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
|
+
|
|
354
392
|
// ─── Normal pass-through (not npx, or npx with non-demo args) ───────────────
|
|
355
393
|
if (!isNpx || (userArgs.length > 0 && !isCanonicalDemoArg && !isNpxBareWordArg)) {
|
|
356
394
|
const result = spawnBin(binPath, userArgs);
|
|
@@ -427,6 +465,140 @@ async function runDemoSelection() {
|
|
|
427
465
|
}
|
|
428
466
|
}
|
|
429
467
|
|
|
468
|
+
// ─── Welcome card render helpers (data consts are hoisted above the dispatch) ─
|
|
469
|
+
|
|
470
|
+
function rep(ch, n) { return n > 0 ? ch.repeat(n) : ''; }
|
|
471
|
+
function vlen(s) { return [...s].length; }
|
|
472
|
+
function padRows(rows) {
|
|
473
|
+
const w = Math.max(...rows.map(vlen));
|
|
474
|
+
return { rows: rows.map(r => r + rep(' ', w - vlen(r))), w };
|
|
475
|
+
}
|
|
476
|
+
// wrapText greedily word-wraps s to the given visible width (in code points).
|
|
477
|
+
function wrapText(s, width) {
|
|
478
|
+
if (width < 1) width = 1;
|
|
479
|
+
const lines = [];
|
|
480
|
+
let cur = '';
|
|
481
|
+
for (const word of s.split(/\s+/).filter(Boolean)) {
|
|
482
|
+
if (cur === '') cur = word;
|
|
483
|
+
else if (vlen(cur) + 1 + vlen(word) <= width) cur += ' ' + word;
|
|
484
|
+
else { lines.push(cur); cur = word; }
|
|
485
|
+
}
|
|
486
|
+
if (cur !== '') lines.push(cur);
|
|
487
|
+
return lines;
|
|
488
|
+
}
|
|
489
|
+
// writeDescRows renders the wrapped description inside a framed box (boxRow closes
|
|
490
|
+
// over innerW), with the "swytchcode --help" hint highlighted.
|
|
491
|
+
function writeDescRows(boxRow, orange, contentW, margin) {
|
|
492
|
+
for (const ln of wrapText(CARD_DESCRIPTION, contentW)) {
|
|
493
|
+
const colored = ln.replace('swytchcode --help', orange('swytchcode --help'));
|
|
494
|
+
writeln(boxRow(rep(' ', margin) + colored, margin + vlen(ln)));
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
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.
|
|
501
|
+
function welcomeCard(cliVersion) {
|
|
502
|
+
const isTTY = !!process.stdout.isTTY;
|
|
503
|
+
const width = process.stdout.columns || 0;
|
|
504
|
+
const ct = process.env.COLORTERM || '';
|
|
505
|
+
const truecolor = ct === 'truecolor' || ct === '24bit';
|
|
506
|
+
const noColor = !!process.env.NO_COLOR || !!process.env.CI;
|
|
507
|
+
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
|
+
|
|
512
|
+
const orange = s => !useColor ? s : (truecolor ? `\x1b[38;2;245;148;30m${s}\x1b[0m` : `\x1b[38;5;214m${s}\x1b[0m`);
|
|
513
|
+
const frame = s => !useColor ? s : (truecolor ? `\x1b[38;2;122;78;24m${s}\x1b[0m` : `\x1b[38;5;214m${s}\x1b[0m`);
|
|
514
|
+
const dim = s => !useColor ? s : `\x1b[2m${s}\x1b[0m`;
|
|
515
|
+
const green = s => !useColor ? s : `\x1b[32m${s}\x1b[0m`;
|
|
516
|
+
|
|
517
|
+
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
|
+
const margin = 2;
|
|
568
|
+
const innerW = margin + wmW + margin;
|
|
569
|
+
const boxRow = (colored, vis) => frame('│') + colored + rep(' ', Math.max(0, innerW - vis)) + frame('│');
|
|
570
|
+
writeln();
|
|
571
|
+
const title = ' Welcome to Swytchcode ';
|
|
572
|
+
writeln(frame('┌─' + title + rep('─', innerW - 1 - vlen(title)) + '┐'));
|
|
573
|
+
writeln(boxRow('', 0));
|
|
574
|
+
for (const row of wm) writeln(boxRow(rep(' ', margin) + orange(row), margin + wmW));
|
|
575
|
+
writeln(boxRow('', 0));
|
|
576
|
+
const lead = margin + Math.floor((innerW - 2 * margin - vlen(CARD_TAGLINE)) / 2);
|
|
577
|
+
writeln(boxRow(rep(' ', lead) + dim(CARD_TAGLINE), lead + vlen(CARD_TAGLINE)));
|
|
578
|
+
writeln(boxRow('', 0));
|
|
579
|
+
writeDescRows(boxRow, orange, innerW - 2 * margin, margin);
|
|
580
|
+
writeln(boxRow('', 0));
|
|
581
|
+
writeln(frame('└' + rep('─', innerW) + '┘'));
|
|
582
|
+
cardBelow({ orange, dim, green });
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// cardBelow prints the description, sign-in line, cwd, and get-started hints.
|
|
586
|
+
function cardBelow({ orange, dim, green }) {
|
|
587
|
+
writeln();
|
|
588
|
+
writeln(`${orange('●')} ${dim('not signed in — run ')}${orange('swytchcode login')}`);
|
|
589
|
+
const cwd = process.cwd().replace(/\\/g, '/');
|
|
590
|
+
const home = (require('os').homedir() || '').replace(/\\/g, '/');
|
|
591
|
+
writeln(dim(home && cwd.startsWith(home) ? '~' + cwd.slice(home.length) : cwd));
|
|
592
|
+
writeln(`\n${dim('get started')}`);
|
|
593
|
+
const rows = [
|
|
594
|
+
['swytchcode init', 'set up this project'],
|
|
595
|
+
['swytchcode get <project>', 'fetch integration bundles'],
|
|
596
|
+
['swytchcode exec <canonical_id>', 'run a tool'],
|
|
597
|
+
];
|
|
598
|
+
for (const [cmd, desc] of rows) writeln(` ${green('›')} ${cmd.padEnd(32)} ${dim(desc)}`);
|
|
599
|
+
writeln();
|
|
600
|
+
}
|
|
601
|
+
|
|
430
602
|
async function runOnboarding() {
|
|
431
603
|
let cliVersion = '0.0.0';
|
|
432
604
|
try {
|
|
@@ -445,13 +617,12 @@ async function runOnboarding() {
|
|
|
445
617
|
// Clear screen for a clean experience
|
|
446
618
|
process.stdout.write('\x1Bc');
|
|
447
619
|
|
|
620
|
+
welcomeCard(cliVersion);
|
|
621
|
+
|
|
622
|
+
// Divider between the welcome card/info and the interactive walkthrough,
|
|
623
|
+
// matching the rules drawn between steps below.
|
|
448
624
|
writeln();
|
|
449
|
-
|
|
450
|
-
writeln(` ${c.yellow}==========================================${c.reset}`);
|
|
451
|
-
writeln(` ${c.yellow}|${c.reset} ${c.yellow}⚡ ${c.bold}Welcome to Swytchcode${c.reset} ${c.yellow}|${c.reset}`);
|
|
452
|
-
writeln(` ${c.yellow}|${c.reset} ${c.dim}v${cliVersion}${c.reset}${vPad}${c.yellow}|${c.reset}`);
|
|
453
|
-
writeln(` ${c.yellow}|${c.reset} ${c.dim}Execution authority layer${c.reset} ${c.yellow}|${c.reset}`);
|
|
454
|
-
writeln(` ${c.yellow}==========================================${c.reset}`);
|
|
625
|
+
writeln(' ' + '─'.repeat(45));
|
|
455
626
|
writeln();
|
|
456
627
|
|
|
457
628
|
// ── Step 1: Demo ──────────────────────────────────────────────────────────
|
|
@@ -470,12 +641,11 @@ async function runOnboardingSteps2to4() {
|
|
|
470
641
|
writeln(`${c.bold} Step 2 of 4 — Install Swytchcode${c.reset}`);
|
|
471
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}`);
|
|
472
643
|
writeln();
|
|
473
|
-
writeln(` ${c.dim}
|
|
474
|
-
writeln(` ${c.dim}$ npm install swytchcode${c.reset}`);
|
|
644
|
+
writeln(` ${c.dim}$ npm install -g swytchcode${c.reset}`);
|
|
475
645
|
writeln();
|
|
476
646
|
|
|
477
|
-
const installChoice = await menuArrow('Install
|
|
478
|
-
{ label: 'Yes, install
|
|
647
|
+
const installChoice = await menuArrow('Install globally?', [
|
|
648
|
+
{ label: 'Yes, install globally', value: 'yes' },
|
|
479
649
|
{ label: 'Skip for now', value: 'no' },
|
|
480
650
|
]);
|
|
481
651
|
|
|
@@ -483,13 +653,12 @@ async function runOnboardingSteps2to4() {
|
|
|
483
653
|
|
|
484
654
|
if (installChoice === 'no') {
|
|
485
655
|
writeln(` ${c.dim}Skipped. Install manually with:${c.reset}`);
|
|
486
|
-
writeln(` ${c.cyan}npm install swytchcode${c.reset}`);
|
|
487
|
-
writeln(` ${c.dim}For global access:${c.reset} ${c.cyan}npm install -g swytchcode${c.reset}`);
|
|
656
|
+
writeln(` ${c.cyan}npm install -g swytchcode${c.reset}`);
|
|
488
657
|
} else {
|
|
489
|
-
const installSpin = spinner('Running npm install swytchcode ...');
|
|
658
|
+
const installSpin = spinner('Running npm install -g swytchcode ...');
|
|
490
659
|
try {
|
|
491
|
-
execSync('npm install swytchcode', { stdio: 'pipe' });
|
|
492
|
-
installSpin.stop('
|
|
660
|
+
execSync('npm install -g swytchcode', { stdio: 'pipe' });
|
|
661
|
+
installSpin.stop('installed');
|
|
493
662
|
} catch (e) {
|
|
494
663
|
if (e.signal === 'SIGINT') {
|
|
495
664
|
installSpin.stop('Cancelled');
|
|
@@ -499,10 +668,6 @@ async function runOnboardingSteps2to4() {
|
|
|
499
668
|
}
|
|
500
669
|
installSpin.fail('Installation failed.');
|
|
501
670
|
}
|
|
502
|
-
|
|
503
|
-
writeln();
|
|
504
|
-
writeln(` ${c.dim}To make it available globally, run:${c.reset}`);
|
|
505
|
-
writeln(` ${c.bold}${c.green}npm install -g swytchcode${c.reset}`);
|
|
506
671
|
}
|
|
507
672
|
|
|
508
673
|
// ── Step 3: Account sync ──────────────────────────────────────────────────
|
|
@@ -529,7 +694,7 @@ async function runOnboardingSteps2to4() {
|
|
|
529
694
|
writeln(` ${c.yellow}Login window closed or failed.${c.reset}`);
|
|
530
695
|
writeln(` ${c.dim}You can log in later with:${c.reset} ${c.cyan}swytchcode login${c.reset}`);
|
|
531
696
|
} else {
|
|
532
|
-
writeln(` ${c.green}
|
|
697
|
+
writeln(` ${c.green}›${c.reset} logged in`);
|
|
533
698
|
}
|
|
534
699
|
} else if (authChoice === 'register') {
|
|
535
700
|
writeln(` ${c.dim}Opening browser to create your account ...${c.reset}`);
|
|
@@ -540,7 +705,7 @@ async function runOnboardingSteps2to4() {
|
|
|
540
705
|
writeln(` ${c.yellow}Browser window closed or failed.${c.reset}`);
|
|
541
706
|
writeln(` ${c.dim}Create your account at:${c.reset} ${c.cyan}https://swytchcode.com/signup${c.reset}`);
|
|
542
707
|
} else {
|
|
543
|
-
writeln(` ${c.green}
|
|
708
|
+
writeln(` ${c.green}›${c.reset} account connected`);
|
|
544
709
|
}
|
|
545
710
|
} else {
|
|
546
711
|
writeln(` ${c.dim}No problem — you can connect your account any time with:${c.reset}`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "swytchcode",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0-beta.2",
|
|
4
|
+
"repository": {
|
|
5
|
+
"type": "git",
|
|
6
|
+
"url": "git+https://gitlab.com/swytchcode/cli.git"
|
|
7
|
+
},
|
|
4
8
|
"description": "Execution authority layer for API integrations",
|
|
5
9
|
"keywords": [
|
|
6
10
|
"api",
|
|
@@ -13,7 +17,8 @@
|
|
|
13
17
|
"homepage": "https://cli.swytchcode.com",
|
|
14
18
|
"license": "MIT",
|
|
15
19
|
"bin": {
|
|
16
|
-
"swytchcode": "./bin/swytchcode.js"
|
|
20
|
+
"swytchcode": "./bin/swytchcode.js",
|
|
21
|
+
"swy": "./bin/swytchcode.js"
|
|
17
22
|
},
|
|
18
23
|
"engines": {
|
|
19
24
|
"node": ">=14"
|
|
@@ -23,11 +28,11 @@
|
|
|
23
28
|
"README.md"
|
|
24
29
|
],
|
|
25
30
|
"optionalDependencies": {
|
|
26
|
-
"swytchcode-cli-darwin-arm64": "2.
|
|
27
|
-
"swytchcode-cli-darwin-x64": "2.
|
|
28
|
-
"swytchcode-cli-linux-arm64": "2.
|
|
29
|
-
"swytchcode-cli-linux-x64": "2.
|
|
30
|
-
"swytchcode-cli-win32-arm64": "2.
|
|
31
|
-
"swytchcode-cli-win32-x64": "2.
|
|
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"
|
|
32
37
|
}
|
|
33
38
|
}
|