@saidulbadhon/jssm-cli 1.5.4 → 1.6.1

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/dist/index.js +2848 -1106
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -304,7 +304,9 @@ async function login(host, email, password) {
304
304
  });
305
305
  return { success: true };
306
306
  } catch (error) {
307
- return { success: false, error: error.message || "Network error" };
307
+ const isConnectionError = error.code === "ECONNREFUSED" || error.code === "ENOTFOUND" || error.code === "ETIMEDOUT" || error.code === "ECONNRESET" || error.cause?.code === "ECONNREFUSED" || error.cause?.code === "ENOTFOUND" || error.cause?.code === "ETIMEDOUT" || error.cause?.code === "ECONNRESET" || error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND");
308
+ const errorMessage = isConnectionError ? "Unable to connect. Is the computer able to access the url?" : error.message || "Network error";
309
+ return { success: false, error: errorMessage, isConnectionError };
308
310
  }
309
311
  }
310
312
  async function register(host, email, password, name) {
@@ -329,7 +331,9 @@ async function register(host, email, password, name) {
329
331
  });
330
332
  return { success: true };
331
333
  } catch (error) {
332
- return { success: false, error: error.message || "Network error" };
334
+ const isConnectionError = error.code === "ECONNREFUSED" || error.code === "ENOTFOUND" || error.code === "ETIMEDOUT" || error.code === "ECONNRESET" || error.cause?.code === "ECONNREFUSED" || error.cause?.code === "ENOTFOUND" || error.cause?.code === "ETIMEDOUT" || error.cause?.code === "ECONNRESET" || error.message?.includes("fetch failed") || error.message?.includes("ECONNREFUSED") || error.message?.includes("ENOTFOUND");
335
+ const errorMessage = isConnectionError ? "Unable to connect. Is the computer able to access the url?" : error.message || "Network error";
336
+ return { success: false, error: errorMessage, isConnectionError };
333
337
  }
334
338
  }
335
339
  var AUTH_DIR, AUTH_FILE;
@@ -341,176 +345,1723 @@ var init_auth = __esm({
341
345
  }
342
346
  });
343
347
 
344
- // node_modules/@inquirer/core/dist/lib/key.js
345
- var isUpKey = (key, keybindings = []) => (
346
- // The up key
347
- key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
348
- keybindings.includes("vim") && key.name === "k" || // Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
349
- keybindings.includes("emacs") && key.ctrl && key.name === "p"
350
- );
351
- var isDownKey = (key, keybindings = []) => (
352
- // The down key
353
- key.name === "down" || // Vim keybinding: hjkl keys map to left/down/up/right
354
- keybindings.includes("vim") && key.name === "j" || // Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
355
- keybindings.includes("emacs") && key.ctrl && key.name === "n"
356
- );
357
- var isSpaceKey = (key) => key.name === "space";
358
- var isBackspaceKey = (key) => key.name === "backspace";
359
- var isTabKey = (key) => key.name === "tab";
360
- var isNumberKey = (key) => "1234567890".includes(key.name);
361
- var isEnterKey = (key) => key.name === "enter" || key.name === "return";
362
-
363
- // node_modules/@inquirer/core/dist/lib/errors.js
364
- var AbortPromptError = class extends Error {
365
- name = "AbortPromptError";
366
- message = "Prompt was aborted";
367
- constructor(options) {
368
- super();
369
- this.cause = options?.cause;
348
+ // ../node_modules/color-name/index.js
349
+ var require_color_name = __commonJS({
350
+ "../node_modules/color-name/index.js"(exports, module) {
351
+ "use strict";
352
+ module.exports = {
353
+ "aliceblue": [240, 248, 255],
354
+ "antiquewhite": [250, 235, 215],
355
+ "aqua": [0, 255, 255],
356
+ "aquamarine": [127, 255, 212],
357
+ "azure": [240, 255, 255],
358
+ "beige": [245, 245, 220],
359
+ "bisque": [255, 228, 196],
360
+ "black": [0, 0, 0],
361
+ "blanchedalmond": [255, 235, 205],
362
+ "blue": [0, 0, 255],
363
+ "blueviolet": [138, 43, 226],
364
+ "brown": [165, 42, 42],
365
+ "burlywood": [222, 184, 135],
366
+ "cadetblue": [95, 158, 160],
367
+ "chartreuse": [127, 255, 0],
368
+ "chocolate": [210, 105, 30],
369
+ "coral": [255, 127, 80],
370
+ "cornflowerblue": [100, 149, 237],
371
+ "cornsilk": [255, 248, 220],
372
+ "crimson": [220, 20, 60],
373
+ "cyan": [0, 255, 255],
374
+ "darkblue": [0, 0, 139],
375
+ "darkcyan": [0, 139, 139],
376
+ "darkgoldenrod": [184, 134, 11],
377
+ "darkgray": [169, 169, 169],
378
+ "darkgreen": [0, 100, 0],
379
+ "darkgrey": [169, 169, 169],
380
+ "darkkhaki": [189, 183, 107],
381
+ "darkmagenta": [139, 0, 139],
382
+ "darkolivegreen": [85, 107, 47],
383
+ "darkorange": [255, 140, 0],
384
+ "darkorchid": [153, 50, 204],
385
+ "darkred": [139, 0, 0],
386
+ "darksalmon": [233, 150, 122],
387
+ "darkseagreen": [143, 188, 143],
388
+ "darkslateblue": [72, 61, 139],
389
+ "darkslategray": [47, 79, 79],
390
+ "darkslategrey": [47, 79, 79],
391
+ "darkturquoise": [0, 206, 209],
392
+ "darkviolet": [148, 0, 211],
393
+ "deeppink": [255, 20, 147],
394
+ "deepskyblue": [0, 191, 255],
395
+ "dimgray": [105, 105, 105],
396
+ "dimgrey": [105, 105, 105],
397
+ "dodgerblue": [30, 144, 255],
398
+ "firebrick": [178, 34, 34],
399
+ "floralwhite": [255, 250, 240],
400
+ "forestgreen": [34, 139, 34],
401
+ "fuchsia": [255, 0, 255],
402
+ "gainsboro": [220, 220, 220],
403
+ "ghostwhite": [248, 248, 255],
404
+ "gold": [255, 215, 0],
405
+ "goldenrod": [218, 165, 32],
406
+ "gray": [128, 128, 128],
407
+ "green": [0, 128, 0],
408
+ "greenyellow": [173, 255, 47],
409
+ "grey": [128, 128, 128],
410
+ "honeydew": [240, 255, 240],
411
+ "hotpink": [255, 105, 180],
412
+ "indianred": [205, 92, 92],
413
+ "indigo": [75, 0, 130],
414
+ "ivory": [255, 255, 240],
415
+ "khaki": [240, 230, 140],
416
+ "lavender": [230, 230, 250],
417
+ "lavenderblush": [255, 240, 245],
418
+ "lawngreen": [124, 252, 0],
419
+ "lemonchiffon": [255, 250, 205],
420
+ "lightblue": [173, 216, 230],
421
+ "lightcoral": [240, 128, 128],
422
+ "lightcyan": [224, 255, 255],
423
+ "lightgoldenrodyellow": [250, 250, 210],
424
+ "lightgray": [211, 211, 211],
425
+ "lightgreen": [144, 238, 144],
426
+ "lightgrey": [211, 211, 211],
427
+ "lightpink": [255, 182, 193],
428
+ "lightsalmon": [255, 160, 122],
429
+ "lightseagreen": [32, 178, 170],
430
+ "lightskyblue": [135, 206, 250],
431
+ "lightslategray": [119, 136, 153],
432
+ "lightslategrey": [119, 136, 153],
433
+ "lightsteelblue": [176, 196, 222],
434
+ "lightyellow": [255, 255, 224],
435
+ "lime": [0, 255, 0],
436
+ "limegreen": [50, 205, 50],
437
+ "linen": [250, 240, 230],
438
+ "magenta": [255, 0, 255],
439
+ "maroon": [128, 0, 0],
440
+ "mediumaquamarine": [102, 205, 170],
441
+ "mediumblue": [0, 0, 205],
442
+ "mediumorchid": [186, 85, 211],
443
+ "mediumpurple": [147, 112, 219],
444
+ "mediumseagreen": [60, 179, 113],
445
+ "mediumslateblue": [123, 104, 238],
446
+ "mediumspringgreen": [0, 250, 154],
447
+ "mediumturquoise": [72, 209, 204],
448
+ "mediumvioletred": [199, 21, 133],
449
+ "midnightblue": [25, 25, 112],
450
+ "mintcream": [245, 255, 250],
451
+ "mistyrose": [255, 228, 225],
452
+ "moccasin": [255, 228, 181],
453
+ "navajowhite": [255, 222, 173],
454
+ "navy": [0, 0, 128],
455
+ "oldlace": [253, 245, 230],
456
+ "olive": [128, 128, 0],
457
+ "olivedrab": [107, 142, 35],
458
+ "orange": [255, 165, 0],
459
+ "orangered": [255, 69, 0],
460
+ "orchid": [218, 112, 214],
461
+ "palegoldenrod": [238, 232, 170],
462
+ "palegreen": [152, 251, 152],
463
+ "paleturquoise": [175, 238, 238],
464
+ "palevioletred": [219, 112, 147],
465
+ "papayawhip": [255, 239, 213],
466
+ "peachpuff": [255, 218, 185],
467
+ "peru": [205, 133, 63],
468
+ "pink": [255, 192, 203],
469
+ "plum": [221, 160, 221],
470
+ "powderblue": [176, 224, 230],
471
+ "purple": [128, 0, 128],
472
+ "rebeccapurple": [102, 51, 153],
473
+ "red": [255, 0, 0],
474
+ "rosybrown": [188, 143, 143],
475
+ "royalblue": [65, 105, 225],
476
+ "saddlebrown": [139, 69, 19],
477
+ "salmon": [250, 128, 114],
478
+ "sandybrown": [244, 164, 96],
479
+ "seagreen": [46, 139, 87],
480
+ "seashell": [255, 245, 238],
481
+ "sienna": [160, 82, 45],
482
+ "silver": [192, 192, 192],
483
+ "skyblue": [135, 206, 235],
484
+ "slateblue": [106, 90, 205],
485
+ "slategray": [112, 128, 144],
486
+ "slategrey": [112, 128, 144],
487
+ "snow": [255, 250, 250],
488
+ "springgreen": [0, 255, 127],
489
+ "steelblue": [70, 130, 180],
490
+ "tan": [210, 180, 140],
491
+ "teal": [0, 128, 128],
492
+ "thistle": [216, 191, 216],
493
+ "tomato": [255, 99, 71],
494
+ "turquoise": [64, 224, 208],
495
+ "violet": [238, 130, 238],
496
+ "wheat": [245, 222, 179],
497
+ "white": [255, 255, 255],
498
+ "whitesmoke": [245, 245, 245],
499
+ "yellow": [255, 255, 0],
500
+ "yellowgreen": [154, 205, 50]
501
+ };
370
502
  }
371
- };
372
- var CancelPromptError = class extends Error {
373
- name = "CancelPromptError";
374
- message = "Prompt was canceled";
375
- };
376
- var ExitPromptError = class extends Error {
377
- name = "ExitPromptError";
378
- };
379
- var HookError = class extends Error {
380
- name = "HookError";
381
- };
382
- var ValidationError = class extends Error {
383
- name = "ValidationError";
384
- };
385
-
386
- // node_modules/@inquirer/core/dist/lib/use-state.js
387
- import { AsyncResource as AsyncResource2 } from "node:async_hooks";
503
+ });
388
504
 
389
- // node_modules/@inquirer/core/dist/lib/hook-engine.js
390
- import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
391
- var hookStorage = new AsyncLocalStorage();
392
- function createStore(rl) {
393
- const store = {
394
- rl,
395
- hooks: [],
396
- hooksCleanup: [],
397
- hooksEffect: [],
398
- index: 0,
399
- handleChange() {
505
+ // ../node_modules/color-convert/conversions.js
506
+ var require_conversions = __commonJS({
507
+ "../node_modules/color-convert/conversions.js"(exports, module) {
508
+ var cssKeywords = require_color_name();
509
+ var reverseKeywords = {};
510
+ for (const key of Object.keys(cssKeywords)) {
511
+ reverseKeywords[cssKeywords[key]] = key;
400
512
  }
401
- };
402
- return store;
403
- }
404
- function withHooks(rl, cb) {
405
- const store = createStore(rl);
406
- return hookStorage.run(store, () => {
407
- function cycle(render) {
408
- store.handleChange = () => {
409
- store.index = 0;
410
- render();
411
- };
412
- store.handleChange();
513
+ var convert = {
514
+ rgb: { channels: 3, labels: "rgb" },
515
+ hsl: { channels: 3, labels: "hsl" },
516
+ hsv: { channels: 3, labels: "hsv" },
517
+ hwb: { channels: 3, labels: "hwb" },
518
+ cmyk: { channels: 4, labels: "cmyk" },
519
+ xyz: { channels: 3, labels: "xyz" },
520
+ lab: { channels: 3, labels: "lab" },
521
+ lch: { channels: 3, labels: "lch" },
522
+ hex: { channels: 1, labels: ["hex"] },
523
+ keyword: { channels: 1, labels: ["keyword"] },
524
+ ansi16: { channels: 1, labels: ["ansi16"] },
525
+ ansi256: { channels: 1, labels: ["ansi256"] },
526
+ hcg: { channels: 3, labels: ["h", "c", "g"] },
527
+ apple: { channels: 3, labels: ["r16", "g16", "b16"] },
528
+ gray: { channels: 1, labels: ["gray"] }
529
+ };
530
+ module.exports = convert;
531
+ for (const model of Object.keys(convert)) {
532
+ if (!("channels" in convert[model])) {
533
+ throw new Error("missing channels property: " + model);
534
+ }
535
+ if (!("labels" in convert[model])) {
536
+ throw new Error("missing channel labels property: " + model);
537
+ }
538
+ if (convert[model].labels.length !== convert[model].channels) {
539
+ throw new Error("channel and label counts mismatch: " + model);
540
+ }
541
+ const { channels, labels } = convert[model];
542
+ delete convert[model].channels;
543
+ delete convert[model].labels;
544
+ Object.defineProperty(convert[model], "channels", { value: channels });
545
+ Object.defineProperty(convert[model], "labels", { value: labels });
413
546
  }
414
- return cb(cycle);
415
- });
416
- }
417
- function getStore() {
418
- const store = hookStorage.getStore();
419
- if (!store) {
420
- throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
421
- }
422
- return store;
423
- }
424
- function readline() {
425
- return getStore().rl;
426
- }
427
- function withUpdates(fn) {
428
- const wrapped = (...args2) => {
429
- const store = getStore();
430
- let shouldUpdate = false;
431
- const oldHandleChange = store.handleChange;
432
- store.handleChange = () => {
433
- shouldUpdate = true;
547
+ convert.rgb.hsl = function(rgb) {
548
+ const r = rgb[0] / 255;
549
+ const g = rgb[1] / 255;
550
+ const b = rgb[2] / 255;
551
+ const min = Math.min(r, g, b);
552
+ const max = Math.max(r, g, b);
553
+ const delta = max - min;
554
+ let h;
555
+ let s;
556
+ if (max === min) {
557
+ h = 0;
558
+ } else if (r === max) {
559
+ h = (g - b) / delta;
560
+ } else if (g === max) {
561
+ h = 2 + (b - r) / delta;
562
+ } else if (b === max) {
563
+ h = 4 + (r - g) / delta;
564
+ }
565
+ h = Math.min(h * 60, 360);
566
+ if (h < 0) {
567
+ h += 360;
568
+ }
569
+ const l = (min + max) / 2;
570
+ if (max === min) {
571
+ s = 0;
572
+ } else if (l <= 0.5) {
573
+ s = delta / (max + min);
574
+ } else {
575
+ s = delta / (2 - max - min);
576
+ }
577
+ return [h, s * 100, l * 100];
434
578
  };
435
- const returnValue = fn(...args2);
436
- if (shouldUpdate) {
437
- oldHandleChange();
579
+ convert.rgb.hsv = function(rgb) {
580
+ let rdif;
581
+ let gdif;
582
+ let bdif;
583
+ let h;
584
+ let s;
585
+ const r = rgb[0] / 255;
586
+ const g = rgb[1] / 255;
587
+ const b = rgb[2] / 255;
588
+ const v = Math.max(r, g, b);
589
+ const diff = v - Math.min(r, g, b);
590
+ const diffc = function(c) {
591
+ return (v - c) / 6 / diff + 1 / 2;
592
+ };
593
+ if (diff === 0) {
594
+ h = 0;
595
+ s = 0;
596
+ } else {
597
+ s = diff / v;
598
+ rdif = diffc(r);
599
+ gdif = diffc(g);
600
+ bdif = diffc(b);
601
+ if (r === v) {
602
+ h = bdif - gdif;
603
+ } else if (g === v) {
604
+ h = 1 / 3 + rdif - bdif;
605
+ } else if (b === v) {
606
+ h = 2 / 3 + gdif - rdif;
607
+ }
608
+ if (h < 0) {
609
+ h += 1;
610
+ } else if (h > 1) {
611
+ h -= 1;
612
+ }
613
+ }
614
+ return [
615
+ h * 360,
616
+ s * 100,
617
+ v * 100
618
+ ];
619
+ };
620
+ convert.rgb.hwb = function(rgb) {
621
+ const r = rgb[0];
622
+ const g = rgb[1];
623
+ let b = rgb[2];
624
+ const h = convert.rgb.hsl(rgb)[0];
625
+ const w = 1 / 255 * Math.min(r, Math.min(g, b));
626
+ b = 1 - 1 / 255 * Math.max(r, Math.max(g, b));
627
+ return [h, w * 100, b * 100];
628
+ };
629
+ convert.rgb.cmyk = function(rgb) {
630
+ const r = rgb[0] / 255;
631
+ const g = rgb[1] / 255;
632
+ const b = rgb[2] / 255;
633
+ const k = Math.min(1 - r, 1 - g, 1 - b);
634
+ const c = (1 - r - k) / (1 - k) || 0;
635
+ const m = (1 - g - k) / (1 - k) || 0;
636
+ const y = (1 - b - k) / (1 - k) || 0;
637
+ return [c * 100, m * 100, y * 100, k * 100];
638
+ };
639
+ function comparativeDistance(x, y) {
640
+ return (x[0] - y[0]) ** 2 + (x[1] - y[1]) ** 2 + (x[2] - y[2]) ** 2;
438
641
  }
439
- store.handleChange = oldHandleChange;
440
- return returnValue;
441
- };
442
- return AsyncResource.bind(wrapped);
443
- }
444
- function withPointer(cb) {
445
- const store = getStore();
446
- const { index } = store;
447
- const pointer = {
448
- get() {
449
- return store.hooks[index];
450
- },
451
- set(value) {
452
- store.hooks[index] = value;
453
- },
454
- initialized: index in store.hooks
455
- };
456
- const returnValue = cb(pointer);
457
- store.index++;
458
- return returnValue;
459
- }
460
- function handleChange() {
461
- getStore().handleChange();
462
- }
463
- var effectScheduler = {
464
- queue(cb) {
465
- const store = getStore();
466
- const { index } = store;
467
- store.hooksEffect.push(() => {
468
- store.hooksCleanup[index]?.();
469
- const cleanFn = cb(readline());
470
- if (cleanFn != null && typeof cleanFn !== "function") {
471
- throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
642
+ convert.rgb.keyword = function(rgb) {
643
+ const reversed = reverseKeywords[rgb];
644
+ if (reversed) {
645
+ return reversed;
472
646
  }
473
- store.hooksCleanup[index] = cleanFn;
474
- });
475
- },
476
- run() {
477
- const store = getStore();
478
- withUpdates(() => {
479
- store.hooksEffect.forEach((effect) => {
480
- effect();
481
- });
482
- store.hooksEffect.length = 0;
483
- })();
484
- },
485
- clearAll() {
486
- const store = getStore();
487
- store.hooksCleanup.forEach((cleanFn) => {
488
- cleanFn?.();
489
- });
490
- store.hooksEffect.length = 0;
491
- store.hooksCleanup.length = 0;
647
+ let currentClosestDistance = Infinity;
648
+ let currentClosestKeyword;
649
+ for (const keyword of Object.keys(cssKeywords)) {
650
+ const value = cssKeywords[keyword];
651
+ const distance = comparativeDistance(rgb, value);
652
+ if (distance < currentClosestDistance) {
653
+ currentClosestDistance = distance;
654
+ currentClosestKeyword = keyword;
655
+ }
656
+ }
657
+ return currentClosestKeyword;
658
+ };
659
+ convert.keyword.rgb = function(keyword) {
660
+ return cssKeywords[keyword];
661
+ };
662
+ convert.rgb.xyz = function(rgb) {
663
+ let r = rgb[0] / 255;
664
+ let g = rgb[1] / 255;
665
+ let b = rgb[2] / 255;
666
+ r = r > 0.04045 ? ((r + 0.055) / 1.055) ** 2.4 : r / 12.92;
667
+ g = g > 0.04045 ? ((g + 0.055) / 1.055) ** 2.4 : g / 12.92;
668
+ b = b > 0.04045 ? ((b + 0.055) / 1.055) ** 2.4 : b / 12.92;
669
+ const x = r * 0.4124 + g * 0.3576 + b * 0.1805;
670
+ const y = r * 0.2126 + g * 0.7152 + b * 0.0722;
671
+ const z = r * 0.0193 + g * 0.1192 + b * 0.9505;
672
+ return [x * 100, y * 100, z * 100];
673
+ };
674
+ convert.rgb.lab = function(rgb) {
675
+ const xyz = convert.rgb.xyz(rgb);
676
+ let x = xyz[0];
677
+ let y = xyz[1];
678
+ let z = xyz[2];
679
+ x /= 95.047;
680
+ y /= 100;
681
+ z /= 108.883;
682
+ x = x > 8856e-6 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
683
+ y = y > 8856e-6 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
684
+ z = z > 8856e-6 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
685
+ const l = 116 * y - 16;
686
+ const a = 500 * (x - y);
687
+ const b = 200 * (y - z);
688
+ return [l, a, b];
689
+ };
690
+ convert.hsl.rgb = function(hsl) {
691
+ const h = hsl[0] / 360;
692
+ const s = hsl[1] / 100;
693
+ const l = hsl[2] / 100;
694
+ let t2;
695
+ let t3;
696
+ let val;
697
+ if (s === 0) {
698
+ val = l * 255;
699
+ return [val, val, val];
700
+ }
701
+ if (l < 0.5) {
702
+ t2 = l * (1 + s);
703
+ } else {
704
+ t2 = l + s - l * s;
705
+ }
706
+ const t1 = 2 * l - t2;
707
+ const rgb = [0, 0, 0];
708
+ for (let i = 0; i < 3; i++) {
709
+ t3 = h + 1 / 3 * -(i - 1);
710
+ if (t3 < 0) {
711
+ t3++;
712
+ }
713
+ if (t3 > 1) {
714
+ t3--;
715
+ }
716
+ if (6 * t3 < 1) {
717
+ val = t1 + (t2 - t1) * 6 * t3;
718
+ } else if (2 * t3 < 1) {
719
+ val = t2;
720
+ } else if (3 * t3 < 2) {
721
+ val = t1 + (t2 - t1) * (2 / 3 - t3) * 6;
722
+ } else {
723
+ val = t1;
724
+ }
725
+ rgb[i] = val * 255;
726
+ }
727
+ return rgb;
728
+ };
729
+ convert.hsl.hsv = function(hsl) {
730
+ const h = hsl[0];
731
+ let s = hsl[1] / 100;
732
+ let l = hsl[2] / 100;
733
+ let smin = s;
734
+ const lmin = Math.max(l, 0.01);
735
+ l *= 2;
736
+ s *= l <= 1 ? l : 2 - l;
737
+ smin *= lmin <= 1 ? lmin : 2 - lmin;
738
+ const v = (l + s) / 2;
739
+ const sv = l === 0 ? 2 * smin / (lmin + smin) : 2 * s / (l + s);
740
+ return [h, sv * 100, v * 100];
741
+ };
742
+ convert.hsv.rgb = function(hsv) {
743
+ const h = hsv[0] / 60;
744
+ const s = hsv[1] / 100;
745
+ let v = hsv[2] / 100;
746
+ const hi = Math.floor(h) % 6;
747
+ const f = h - Math.floor(h);
748
+ const p = 255 * v * (1 - s);
749
+ const q = 255 * v * (1 - s * f);
750
+ const t = 255 * v * (1 - s * (1 - f));
751
+ v *= 255;
752
+ switch (hi) {
753
+ case 0:
754
+ return [v, t, p];
755
+ case 1:
756
+ return [q, v, p];
757
+ case 2:
758
+ return [p, v, t];
759
+ case 3:
760
+ return [p, q, v];
761
+ case 4:
762
+ return [t, p, v];
763
+ case 5:
764
+ return [v, p, q];
765
+ }
766
+ };
767
+ convert.hsv.hsl = function(hsv) {
768
+ const h = hsv[0];
769
+ const s = hsv[1] / 100;
770
+ const v = hsv[2] / 100;
771
+ const vmin = Math.max(v, 0.01);
772
+ let sl;
773
+ let l;
774
+ l = (2 - s) * v;
775
+ const lmin = (2 - s) * vmin;
776
+ sl = s * vmin;
777
+ sl /= lmin <= 1 ? lmin : 2 - lmin;
778
+ sl = sl || 0;
779
+ l /= 2;
780
+ return [h, sl * 100, l * 100];
781
+ };
782
+ convert.hwb.rgb = function(hwb) {
783
+ const h = hwb[0] / 360;
784
+ let wh = hwb[1] / 100;
785
+ let bl = hwb[2] / 100;
786
+ const ratio = wh + bl;
787
+ let f;
788
+ if (ratio > 1) {
789
+ wh /= ratio;
790
+ bl /= ratio;
791
+ }
792
+ const i = Math.floor(6 * h);
793
+ const v = 1 - bl;
794
+ f = 6 * h - i;
795
+ if ((i & 1) !== 0) {
796
+ f = 1 - f;
797
+ }
798
+ const n = wh + f * (v - wh);
799
+ let r;
800
+ let g;
801
+ let b;
802
+ switch (i) {
803
+ default:
804
+ case 6:
805
+ case 0:
806
+ r = v;
807
+ g = n;
808
+ b = wh;
809
+ break;
810
+ case 1:
811
+ r = n;
812
+ g = v;
813
+ b = wh;
814
+ break;
815
+ case 2:
816
+ r = wh;
817
+ g = v;
818
+ b = n;
819
+ break;
820
+ case 3:
821
+ r = wh;
822
+ g = n;
823
+ b = v;
824
+ break;
825
+ case 4:
826
+ r = n;
827
+ g = wh;
828
+ b = v;
829
+ break;
830
+ case 5:
831
+ r = v;
832
+ g = wh;
833
+ b = n;
834
+ break;
835
+ }
836
+ return [r * 255, g * 255, b * 255];
837
+ };
838
+ convert.cmyk.rgb = function(cmyk) {
839
+ const c = cmyk[0] / 100;
840
+ const m = cmyk[1] / 100;
841
+ const y = cmyk[2] / 100;
842
+ const k = cmyk[3] / 100;
843
+ const r = 1 - Math.min(1, c * (1 - k) + k);
844
+ const g = 1 - Math.min(1, m * (1 - k) + k);
845
+ const b = 1 - Math.min(1, y * (1 - k) + k);
846
+ return [r * 255, g * 255, b * 255];
847
+ };
848
+ convert.xyz.rgb = function(xyz) {
849
+ const x = xyz[0] / 100;
850
+ const y = xyz[1] / 100;
851
+ const z = xyz[2] / 100;
852
+ let r;
853
+ let g;
854
+ let b;
855
+ r = x * 3.2406 + y * -1.5372 + z * -0.4986;
856
+ g = x * -0.9689 + y * 1.8758 + z * 0.0415;
857
+ b = x * 0.0557 + y * -0.204 + z * 1.057;
858
+ r = r > 31308e-7 ? 1.055 * r ** (1 / 2.4) - 0.055 : r * 12.92;
859
+ g = g > 31308e-7 ? 1.055 * g ** (1 / 2.4) - 0.055 : g * 12.92;
860
+ b = b > 31308e-7 ? 1.055 * b ** (1 / 2.4) - 0.055 : b * 12.92;
861
+ r = Math.min(Math.max(0, r), 1);
862
+ g = Math.min(Math.max(0, g), 1);
863
+ b = Math.min(Math.max(0, b), 1);
864
+ return [r * 255, g * 255, b * 255];
865
+ };
866
+ convert.xyz.lab = function(xyz) {
867
+ let x = xyz[0];
868
+ let y = xyz[1];
869
+ let z = xyz[2];
870
+ x /= 95.047;
871
+ y /= 100;
872
+ z /= 108.883;
873
+ x = x > 8856e-6 ? x ** (1 / 3) : 7.787 * x + 16 / 116;
874
+ y = y > 8856e-6 ? y ** (1 / 3) : 7.787 * y + 16 / 116;
875
+ z = z > 8856e-6 ? z ** (1 / 3) : 7.787 * z + 16 / 116;
876
+ const l = 116 * y - 16;
877
+ const a = 500 * (x - y);
878
+ const b = 200 * (y - z);
879
+ return [l, a, b];
880
+ };
881
+ convert.lab.xyz = function(lab) {
882
+ const l = lab[0];
883
+ const a = lab[1];
884
+ const b = lab[2];
885
+ let x;
886
+ let y;
887
+ let z;
888
+ y = (l + 16) / 116;
889
+ x = a / 500 + y;
890
+ z = y - b / 200;
891
+ const y2 = y ** 3;
892
+ const x2 = x ** 3;
893
+ const z2 = z ** 3;
894
+ y = y2 > 8856e-6 ? y2 : (y - 16 / 116) / 7.787;
895
+ x = x2 > 8856e-6 ? x2 : (x - 16 / 116) / 7.787;
896
+ z = z2 > 8856e-6 ? z2 : (z - 16 / 116) / 7.787;
897
+ x *= 95.047;
898
+ y *= 100;
899
+ z *= 108.883;
900
+ return [x, y, z];
901
+ };
902
+ convert.lab.lch = function(lab) {
903
+ const l = lab[0];
904
+ const a = lab[1];
905
+ const b = lab[2];
906
+ let h;
907
+ const hr = Math.atan2(b, a);
908
+ h = hr * 360 / 2 / Math.PI;
909
+ if (h < 0) {
910
+ h += 360;
911
+ }
912
+ const c = Math.sqrt(a * a + b * b);
913
+ return [l, c, h];
914
+ };
915
+ convert.lch.lab = function(lch) {
916
+ const l = lch[0];
917
+ const c = lch[1];
918
+ const h = lch[2];
919
+ const hr = h / 360 * 2 * Math.PI;
920
+ const a = c * Math.cos(hr);
921
+ const b = c * Math.sin(hr);
922
+ return [l, a, b];
923
+ };
924
+ convert.rgb.ansi16 = function(args2, saturation = null) {
925
+ const [r, g, b] = args2;
926
+ let value = saturation === null ? convert.rgb.hsv(args2)[2] : saturation;
927
+ value = Math.round(value / 50);
928
+ if (value === 0) {
929
+ return 30;
930
+ }
931
+ let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
932
+ if (value === 2) {
933
+ ansi += 60;
934
+ }
935
+ return ansi;
936
+ };
937
+ convert.hsv.ansi16 = function(args2) {
938
+ return convert.rgb.ansi16(convert.hsv.rgb(args2), args2[2]);
939
+ };
940
+ convert.rgb.ansi256 = function(args2) {
941
+ const r = args2[0];
942
+ const g = args2[1];
943
+ const b = args2[2];
944
+ if (r === g && g === b) {
945
+ if (r < 8) {
946
+ return 16;
947
+ }
948
+ if (r > 248) {
949
+ return 231;
950
+ }
951
+ return Math.round((r - 8) / 247 * 24) + 232;
952
+ }
953
+ const ansi = 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
954
+ return ansi;
955
+ };
956
+ convert.ansi16.rgb = function(args2) {
957
+ let color = args2 % 10;
958
+ if (color === 0 || color === 7) {
959
+ if (args2 > 50) {
960
+ color += 3.5;
961
+ }
962
+ color = color / 10.5 * 255;
963
+ return [color, color, color];
964
+ }
965
+ const mult = (~~(args2 > 50) + 1) * 0.5;
966
+ const r = (color & 1) * mult * 255;
967
+ const g = (color >> 1 & 1) * mult * 255;
968
+ const b = (color >> 2 & 1) * mult * 255;
969
+ return [r, g, b];
970
+ };
971
+ convert.ansi256.rgb = function(args2) {
972
+ if (args2 >= 232) {
973
+ const c = (args2 - 232) * 10 + 8;
974
+ return [c, c, c];
975
+ }
976
+ args2 -= 16;
977
+ let rem;
978
+ const r = Math.floor(args2 / 36) / 5 * 255;
979
+ const g = Math.floor((rem = args2 % 36) / 6) / 5 * 255;
980
+ const b = rem % 6 / 5 * 255;
981
+ return [r, g, b];
982
+ };
983
+ convert.rgb.hex = function(args2) {
984
+ const integer = ((Math.round(args2[0]) & 255) << 16) + ((Math.round(args2[1]) & 255) << 8) + (Math.round(args2[2]) & 255);
985
+ const string = integer.toString(16).toUpperCase();
986
+ return "000000".substring(string.length) + string;
987
+ };
988
+ convert.hex.rgb = function(args2) {
989
+ const match = args2.toString(16).match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
990
+ if (!match) {
991
+ return [0, 0, 0];
992
+ }
993
+ let colorString = match[0];
994
+ if (match[0].length === 3) {
995
+ colorString = colorString.split("").map((char) => {
996
+ return char + char;
997
+ }).join("");
998
+ }
999
+ const integer = parseInt(colorString, 16);
1000
+ const r = integer >> 16 & 255;
1001
+ const g = integer >> 8 & 255;
1002
+ const b = integer & 255;
1003
+ return [r, g, b];
1004
+ };
1005
+ convert.rgb.hcg = function(rgb) {
1006
+ const r = rgb[0] / 255;
1007
+ const g = rgb[1] / 255;
1008
+ const b = rgb[2] / 255;
1009
+ const max = Math.max(Math.max(r, g), b);
1010
+ const min = Math.min(Math.min(r, g), b);
1011
+ const chroma = max - min;
1012
+ let grayscale;
1013
+ let hue;
1014
+ if (chroma < 1) {
1015
+ grayscale = min / (1 - chroma);
1016
+ } else {
1017
+ grayscale = 0;
1018
+ }
1019
+ if (chroma <= 0) {
1020
+ hue = 0;
1021
+ } else if (max === r) {
1022
+ hue = (g - b) / chroma % 6;
1023
+ } else if (max === g) {
1024
+ hue = 2 + (b - r) / chroma;
1025
+ } else {
1026
+ hue = 4 + (r - g) / chroma;
1027
+ }
1028
+ hue /= 6;
1029
+ hue %= 1;
1030
+ return [hue * 360, chroma * 100, grayscale * 100];
1031
+ };
1032
+ convert.hsl.hcg = function(hsl) {
1033
+ const s = hsl[1] / 100;
1034
+ const l = hsl[2] / 100;
1035
+ const c = l < 0.5 ? 2 * s * l : 2 * s * (1 - l);
1036
+ let f = 0;
1037
+ if (c < 1) {
1038
+ f = (l - 0.5 * c) / (1 - c);
1039
+ }
1040
+ return [hsl[0], c * 100, f * 100];
1041
+ };
1042
+ convert.hsv.hcg = function(hsv) {
1043
+ const s = hsv[1] / 100;
1044
+ const v = hsv[2] / 100;
1045
+ const c = s * v;
1046
+ let f = 0;
1047
+ if (c < 1) {
1048
+ f = (v - c) / (1 - c);
1049
+ }
1050
+ return [hsv[0], c * 100, f * 100];
1051
+ };
1052
+ convert.hcg.rgb = function(hcg) {
1053
+ const h = hcg[0] / 360;
1054
+ const c = hcg[1] / 100;
1055
+ const g = hcg[2] / 100;
1056
+ if (c === 0) {
1057
+ return [g * 255, g * 255, g * 255];
1058
+ }
1059
+ const pure = [0, 0, 0];
1060
+ const hi = h % 1 * 6;
1061
+ const v = hi % 1;
1062
+ const w = 1 - v;
1063
+ let mg = 0;
1064
+ switch (Math.floor(hi)) {
1065
+ case 0:
1066
+ pure[0] = 1;
1067
+ pure[1] = v;
1068
+ pure[2] = 0;
1069
+ break;
1070
+ case 1:
1071
+ pure[0] = w;
1072
+ pure[1] = 1;
1073
+ pure[2] = 0;
1074
+ break;
1075
+ case 2:
1076
+ pure[0] = 0;
1077
+ pure[1] = 1;
1078
+ pure[2] = v;
1079
+ break;
1080
+ case 3:
1081
+ pure[0] = 0;
1082
+ pure[1] = w;
1083
+ pure[2] = 1;
1084
+ break;
1085
+ case 4:
1086
+ pure[0] = v;
1087
+ pure[1] = 0;
1088
+ pure[2] = 1;
1089
+ break;
1090
+ default:
1091
+ pure[0] = 1;
1092
+ pure[1] = 0;
1093
+ pure[2] = w;
1094
+ }
1095
+ mg = (1 - c) * g;
1096
+ return [
1097
+ (c * pure[0] + mg) * 255,
1098
+ (c * pure[1] + mg) * 255,
1099
+ (c * pure[2] + mg) * 255
1100
+ ];
1101
+ };
1102
+ convert.hcg.hsv = function(hcg) {
1103
+ const c = hcg[1] / 100;
1104
+ const g = hcg[2] / 100;
1105
+ const v = c + g * (1 - c);
1106
+ let f = 0;
1107
+ if (v > 0) {
1108
+ f = c / v;
1109
+ }
1110
+ return [hcg[0], f * 100, v * 100];
1111
+ };
1112
+ convert.hcg.hsl = function(hcg) {
1113
+ const c = hcg[1] / 100;
1114
+ const g = hcg[2] / 100;
1115
+ const l = g * (1 - c) + 0.5 * c;
1116
+ let s = 0;
1117
+ if (l > 0 && l < 0.5) {
1118
+ s = c / (2 * l);
1119
+ } else if (l >= 0.5 && l < 1) {
1120
+ s = c / (2 * (1 - l));
1121
+ }
1122
+ return [hcg[0], s * 100, l * 100];
1123
+ };
1124
+ convert.hcg.hwb = function(hcg) {
1125
+ const c = hcg[1] / 100;
1126
+ const g = hcg[2] / 100;
1127
+ const v = c + g * (1 - c);
1128
+ return [hcg[0], (v - c) * 100, (1 - v) * 100];
1129
+ };
1130
+ convert.hwb.hcg = function(hwb) {
1131
+ const w = hwb[1] / 100;
1132
+ const b = hwb[2] / 100;
1133
+ const v = 1 - b;
1134
+ const c = v - w;
1135
+ let g = 0;
1136
+ if (c < 1) {
1137
+ g = (v - c) / (1 - c);
1138
+ }
1139
+ return [hwb[0], c * 100, g * 100];
1140
+ };
1141
+ convert.apple.rgb = function(apple) {
1142
+ return [apple[0] / 65535 * 255, apple[1] / 65535 * 255, apple[2] / 65535 * 255];
1143
+ };
1144
+ convert.rgb.apple = function(rgb) {
1145
+ return [rgb[0] / 255 * 65535, rgb[1] / 255 * 65535, rgb[2] / 255 * 65535];
1146
+ };
1147
+ convert.gray.rgb = function(args2) {
1148
+ return [args2[0] / 100 * 255, args2[0] / 100 * 255, args2[0] / 100 * 255];
1149
+ };
1150
+ convert.gray.hsl = function(args2) {
1151
+ return [0, 0, args2[0]];
1152
+ };
1153
+ convert.gray.hsv = convert.gray.hsl;
1154
+ convert.gray.hwb = function(gray) {
1155
+ return [0, 100, gray[0]];
1156
+ };
1157
+ convert.gray.cmyk = function(gray) {
1158
+ return [0, 0, 0, gray[0]];
1159
+ };
1160
+ convert.gray.lab = function(gray) {
1161
+ return [gray[0], 0, 0];
1162
+ };
1163
+ convert.gray.hex = function(gray) {
1164
+ const val = Math.round(gray[0] / 100 * 255) & 255;
1165
+ const integer = (val << 16) + (val << 8) + val;
1166
+ const string = integer.toString(16).toUpperCase();
1167
+ return "000000".substring(string.length) + string;
1168
+ };
1169
+ convert.rgb.gray = function(rgb) {
1170
+ const val = (rgb[0] + rgb[1] + rgb[2]) / 3;
1171
+ return [val / 255 * 100];
1172
+ };
492
1173
  }
493
- };
1174
+ });
494
1175
 
495
- // node_modules/@inquirer/core/dist/lib/use-state.js
496
- function useState(defaultValue) {
497
- return withPointer((pointer) => {
498
- const setState = AsyncResource2.bind(function setState2(newValue) {
499
- if (pointer.get() !== newValue) {
500
- pointer.set(newValue);
501
- handleChange();
1176
+ // ../node_modules/color-convert/route.js
1177
+ var require_route = __commonJS({
1178
+ "../node_modules/color-convert/route.js"(exports, module) {
1179
+ var conversions = require_conversions();
1180
+ function buildGraph() {
1181
+ const graph = {};
1182
+ const models = Object.keys(conversions);
1183
+ for (let len = models.length, i = 0; i < len; i++) {
1184
+ graph[models[i]] = {
1185
+ // http://jsperf.com/1-vs-infinity
1186
+ // micro-opt, but this is simple.
1187
+ distance: -1,
1188
+ parent: null
1189
+ };
502
1190
  }
503
- });
504
- if (pointer.initialized) {
505
- return [pointer.get(), setState];
1191
+ return graph;
506
1192
  }
507
- const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
508
- pointer.set(value);
509
- return [value, setState];
510
- });
511
- }
512
-
513
- // node_modules/@inquirer/core/dist/lib/use-effect.js
1193
+ function deriveBFS(fromModel) {
1194
+ const graph = buildGraph();
1195
+ const queue = [fromModel];
1196
+ graph[fromModel].distance = 0;
1197
+ while (queue.length) {
1198
+ const current = queue.pop();
1199
+ const adjacents = Object.keys(conversions[current]);
1200
+ for (let len = adjacents.length, i = 0; i < len; i++) {
1201
+ const adjacent = adjacents[i];
1202
+ const node = graph[adjacent];
1203
+ if (node.distance === -1) {
1204
+ node.distance = graph[current].distance + 1;
1205
+ node.parent = current;
1206
+ queue.unshift(adjacent);
1207
+ }
1208
+ }
1209
+ }
1210
+ return graph;
1211
+ }
1212
+ function link(from, to) {
1213
+ return function(args2) {
1214
+ return to(from(args2));
1215
+ };
1216
+ }
1217
+ function wrapConversion(toModel, graph) {
1218
+ const path = [graph[toModel].parent, toModel];
1219
+ let fn = conversions[graph[toModel].parent][toModel];
1220
+ let cur = graph[toModel].parent;
1221
+ while (graph[cur].parent) {
1222
+ path.unshift(graph[cur].parent);
1223
+ fn = link(conversions[graph[cur].parent][cur], fn);
1224
+ cur = graph[cur].parent;
1225
+ }
1226
+ fn.conversion = path;
1227
+ return fn;
1228
+ }
1229
+ module.exports = function(fromModel) {
1230
+ const graph = deriveBFS(fromModel);
1231
+ const conversion = {};
1232
+ const models = Object.keys(graph);
1233
+ for (let len = models.length, i = 0; i < len; i++) {
1234
+ const toModel = models[i];
1235
+ const node = graph[toModel];
1236
+ if (node.parent === null) {
1237
+ continue;
1238
+ }
1239
+ conversion[toModel] = wrapConversion(toModel, graph);
1240
+ }
1241
+ return conversion;
1242
+ };
1243
+ }
1244
+ });
1245
+
1246
+ // ../node_modules/color-convert/index.js
1247
+ var require_color_convert = __commonJS({
1248
+ "../node_modules/color-convert/index.js"(exports, module) {
1249
+ var conversions = require_conversions();
1250
+ var route = require_route();
1251
+ var convert = {};
1252
+ var models = Object.keys(conversions);
1253
+ function wrapRaw(fn) {
1254
+ const wrappedFn = function(...args2) {
1255
+ const arg0 = args2[0];
1256
+ if (arg0 === void 0 || arg0 === null) {
1257
+ return arg0;
1258
+ }
1259
+ if (arg0.length > 1) {
1260
+ args2 = arg0;
1261
+ }
1262
+ return fn(args2);
1263
+ };
1264
+ if ("conversion" in fn) {
1265
+ wrappedFn.conversion = fn.conversion;
1266
+ }
1267
+ return wrappedFn;
1268
+ }
1269
+ function wrapRounded(fn) {
1270
+ const wrappedFn = function(...args2) {
1271
+ const arg0 = args2[0];
1272
+ if (arg0 === void 0 || arg0 === null) {
1273
+ return arg0;
1274
+ }
1275
+ if (arg0.length > 1) {
1276
+ args2 = arg0;
1277
+ }
1278
+ const result = fn(args2);
1279
+ if (typeof result === "object") {
1280
+ for (let len = result.length, i = 0; i < len; i++) {
1281
+ result[i] = Math.round(result[i]);
1282
+ }
1283
+ }
1284
+ return result;
1285
+ };
1286
+ if ("conversion" in fn) {
1287
+ wrappedFn.conversion = fn.conversion;
1288
+ }
1289
+ return wrappedFn;
1290
+ }
1291
+ models.forEach((fromModel) => {
1292
+ convert[fromModel] = {};
1293
+ Object.defineProperty(convert[fromModel], "channels", { value: conversions[fromModel].channels });
1294
+ Object.defineProperty(convert[fromModel], "labels", { value: conversions[fromModel].labels });
1295
+ const routes = route(fromModel);
1296
+ const routeModels = Object.keys(routes);
1297
+ routeModels.forEach((toModel) => {
1298
+ const fn = routes[toModel];
1299
+ convert[fromModel][toModel] = wrapRounded(fn);
1300
+ convert[fromModel][toModel].raw = wrapRaw(fn);
1301
+ });
1302
+ });
1303
+ module.exports = convert;
1304
+ }
1305
+ });
1306
+
1307
+ // ../node_modules/ansi-styles/index.js
1308
+ var require_ansi_styles = __commonJS({
1309
+ "../node_modules/ansi-styles/index.js"(exports, module) {
1310
+ "use strict";
1311
+ var wrapAnsi162 = (fn, offset) => (...args2) => {
1312
+ const code = fn(...args2);
1313
+ return `\x1B[${code + offset}m`;
1314
+ };
1315
+ var wrapAnsi2562 = (fn, offset) => (...args2) => {
1316
+ const code = fn(...args2);
1317
+ return `\x1B[${38 + offset};5;${code}m`;
1318
+ };
1319
+ var wrapAnsi16m2 = (fn, offset) => (...args2) => {
1320
+ const rgb = fn(...args2);
1321
+ return `\x1B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
1322
+ };
1323
+ var ansi2ansi = (n) => n;
1324
+ var rgb2rgb = (r, g, b) => [r, g, b];
1325
+ var setLazyProperty = (object, property, get) => {
1326
+ Object.defineProperty(object, property, {
1327
+ get: () => {
1328
+ const value = get();
1329
+ Object.defineProperty(object, property, {
1330
+ value,
1331
+ enumerable: true,
1332
+ configurable: true
1333
+ });
1334
+ return value;
1335
+ },
1336
+ enumerable: true,
1337
+ configurable: true
1338
+ });
1339
+ };
1340
+ var colorConvert;
1341
+ var makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
1342
+ if (colorConvert === void 0) {
1343
+ colorConvert = require_color_convert();
1344
+ }
1345
+ const offset = isBackground ? 10 : 0;
1346
+ const styles2 = {};
1347
+ for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
1348
+ const name = sourceSpace === "ansi16" ? "ansi" : sourceSpace;
1349
+ if (sourceSpace === targetSpace) {
1350
+ styles2[name] = wrap(identity, offset);
1351
+ } else if (typeof suite === "object") {
1352
+ styles2[name] = wrap(suite[targetSpace], offset);
1353
+ }
1354
+ }
1355
+ return styles2;
1356
+ };
1357
+ function assembleStyles2() {
1358
+ const codes = /* @__PURE__ */ new Map();
1359
+ const styles2 = {
1360
+ modifier: {
1361
+ reset: [0, 0],
1362
+ // 21 isn't widely supported and 22 does the same thing
1363
+ bold: [1, 22],
1364
+ dim: [2, 22],
1365
+ italic: [3, 23],
1366
+ underline: [4, 24],
1367
+ inverse: [7, 27],
1368
+ hidden: [8, 28],
1369
+ strikethrough: [9, 29]
1370
+ },
1371
+ color: {
1372
+ black: [30, 39],
1373
+ red: [31, 39],
1374
+ green: [32, 39],
1375
+ yellow: [33, 39],
1376
+ blue: [34, 39],
1377
+ magenta: [35, 39],
1378
+ cyan: [36, 39],
1379
+ white: [37, 39],
1380
+ // Bright color
1381
+ blackBright: [90, 39],
1382
+ redBright: [91, 39],
1383
+ greenBright: [92, 39],
1384
+ yellowBright: [93, 39],
1385
+ blueBright: [94, 39],
1386
+ magentaBright: [95, 39],
1387
+ cyanBright: [96, 39],
1388
+ whiteBright: [97, 39]
1389
+ },
1390
+ bgColor: {
1391
+ bgBlack: [40, 49],
1392
+ bgRed: [41, 49],
1393
+ bgGreen: [42, 49],
1394
+ bgYellow: [43, 49],
1395
+ bgBlue: [44, 49],
1396
+ bgMagenta: [45, 49],
1397
+ bgCyan: [46, 49],
1398
+ bgWhite: [47, 49],
1399
+ // Bright color
1400
+ bgBlackBright: [100, 49],
1401
+ bgRedBright: [101, 49],
1402
+ bgGreenBright: [102, 49],
1403
+ bgYellowBright: [103, 49],
1404
+ bgBlueBright: [104, 49],
1405
+ bgMagentaBright: [105, 49],
1406
+ bgCyanBright: [106, 49],
1407
+ bgWhiteBright: [107, 49]
1408
+ }
1409
+ };
1410
+ styles2.color.gray = styles2.color.blackBright;
1411
+ styles2.bgColor.bgGray = styles2.bgColor.bgBlackBright;
1412
+ styles2.color.grey = styles2.color.blackBright;
1413
+ styles2.bgColor.bgGrey = styles2.bgColor.bgBlackBright;
1414
+ for (const [groupName, group] of Object.entries(styles2)) {
1415
+ for (const [styleName, style] of Object.entries(group)) {
1416
+ styles2[styleName] = {
1417
+ open: `\x1B[${style[0]}m`,
1418
+ close: `\x1B[${style[1]}m`
1419
+ };
1420
+ group[styleName] = styles2[styleName];
1421
+ codes.set(style[0], style[1]);
1422
+ }
1423
+ Object.defineProperty(styles2, groupName, {
1424
+ value: group,
1425
+ enumerable: false
1426
+ });
1427
+ }
1428
+ Object.defineProperty(styles2, "codes", {
1429
+ value: codes,
1430
+ enumerable: false
1431
+ });
1432
+ styles2.color.close = "\x1B[39m";
1433
+ styles2.bgColor.close = "\x1B[49m";
1434
+ setLazyProperty(styles2.color, "ansi", () => makeDynamicStyles(wrapAnsi162, "ansi16", ansi2ansi, false));
1435
+ setLazyProperty(styles2.color, "ansi256", () => makeDynamicStyles(wrapAnsi2562, "ansi256", ansi2ansi, false));
1436
+ setLazyProperty(styles2.color, "ansi16m", () => makeDynamicStyles(wrapAnsi16m2, "rgb", rgb2rgb, false));
1437
+ setLazyProperty(styles2.bgColor, "ansi", () => makeDynamicStyles(wrapAnsi162, "ansi16", ansi2ansi, true));
1438
+ setLazyProperty(styles2.bgColor, "ansi256", () => makeDynamicStyles(wrapAnsi2562, "ansi256", ansi2ansi, true));
1439
+ setLazyProperty(styles2.bgColor, "ansi16m", () => makeDynamicStyles(wrapAnsi16m2, "rgb", rgb2rgb, true));
1440
+ return styles2;
1441
+ }
1442
+ Object.defineProperty(module, "exports", {
1443
+ enumerable: true,
1444
+ get: assembleStyles2
1445
+ });
1446
+ }
1447
+ });
1448
+
1449
+ // ../node_modules/has-flag/index.js
1450
+ var require_has_flag = __commonJS({
1451
+ "../node_modules/has-flag/index.js"(exports, module) {
1452
+ "use strict";
1453
+ module.exports = (flag, argv = process.argv) => {
1454
+ const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
1455
+ const position = argv.indexOf(prefix + flag);
1456
+ const terminatorPosition = argv.indexOf("--");
1457
+ return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition);
1458
+ };
1459
+ }
1460
+ });
1461
+
1462
+ // ../node_modules/chalk/node_modules/supports-color/index.js
1463
+ var require_supports_color = __commonJS({
1464
+ "../node_modules/chalk/node_modules/supports-color/index.js"(exports, module) {
1465
+ "use strict";
1466
+ var os = __require("os");
1467
+ var tty = __require("tty");
1468
+ var hasFlag = require_has_flag();
1469
+ var { env } = process;
1470
+ var forceColor;
1471
+ if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) {
1472
+ forceColor = 0;
1473
+ } else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) {
1474
+ forceColor = 1;
1475
+ }
1476
+ if ("FORCE_COLOR" in env) {
1477
+ if (env.FORCE_COLOR === "true") {
1478
+ forceColor = 1;
1479
+ } else if (env.FORCE_COLOR === "false") {
1480
+ forceColor = 0;
1481
+ } else {
1482
+ forceColor = env.FORCE_COLOR.length === 0 ? 1 : Math.min(parseInt(env.FORCE_COLOR, 10), 3);
1483
+ }
1484
+ }
1485
+ function translateLevel(level) {
1486
+ if (level === 0) {
1487
+ return false;
1488
+ }
1489
+ return {
1490
+ level,
1491
+ hasBasic: true,
1492
+ has256: level >= 2,
1493
+ has16m: level >= 3
1494
+ };
1495
+ }
1496
+ function supportsColor(haveStream, streamIsTTY) {
1497
+ if (forceColor === 0) {
1498
+ return 0;
1499
+ }
1500
+ if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) {
1501
+ return 3;
1502
+ }
1503
+ if (hasFlag("color=256")) {
1504
+ return 2;
1505
+ }
1506
+ if (haveStream && !streamIsTTY && forceColor === void 0) {
1507
+ return 0;
1508
+ }
1509
+ const min = forceColor || 0;
1510
+ if (env.TERM === "dumb") {
1511
+ return min;
1512
+ }
1513
+ if (process.platform === "win32") {
1514
+ const osRelease = os.release().split(".");
1515
+ if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
1516
+ return Number(osRelease[2]) >= 14931 ? 3 : 2;
1517
+ }
1518
+ return 1;
1519
+ }
1520
+ if ("CI" in env) {
1521
+ if (["TRAVIS", "CIRCLECI", "APPVEYOR", "GITLAB_CI", "GITHUB_ACTIONS", "BUILDKITE"].some((sign) => sign in env) || env.CI_NAME === "codeship") {
1522
+ return 1;
1523
+ }
1524
+ return min;
1525
+ }
1526
+ if ("TEAMCITY_VERSION" in env) {
1527
+ return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
1528
+ }
1529
+ if (env.COLORTERM === "truecolor") {
1530
+ return 3;
1531
+ }
1532
+ if ("TERM_PROGRAM" in env) {
1533
+ const version = parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
1534
+ switch (env.TERM_PROGRAM) {
1535
+ case "iTerm.app":
1536
+ return version >= 3 ? 3 : 2;
1537
+ case "Apple_Terminal":
1538
+ return 2;
1539
+ }
1540
+ }
1541
+ if (/-256(color)?$/i.test(env.TERM)) {
1542
+ return 2;
1543
+ }
1544
+ if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) {
1545
+ return 1;
1546
+ }
1547
+ if ("COLORTERM" in env) {
1548
+ return 1;
1549
+ }
1550
+ return min;
1551
+ }
1552
+ function getSupportLevel(stream) {
1553
+ const level = supportsColor(stream, stream && stream.isTTY);
1554
+ return translateLevel(level);
1555
+ }
1556
+ module.exports = {
1557
+ supportsColor: getSupportLevel,
1558
+ stdout: translateLevel(supportsColor(true, tty.isatty(1))),
1559
+ stderr: translateLevel(supportsColor(true, tty.isatty(2)))
1560
+ };
1561
+ }
1562
+ });
1563
+
1564
+ // ../node_modules/chalk/source/util.js
1565
+ var require_util = __commonJS({
1566
+ "../node_modules/chalk/source/util.js"(exports, module) {
1567
+ "use strict";
1568
+ var stringReplaceAll = (string, substring, replacer) => {
1569
+ let index = string.indexOf(substring);
1570
+ if (index === -1) {
1571
+ return string;
1572
+ }
1573
+ const substringLength = substring.length;
1574
+ let endIndex = 0;
1575
+ let returnValue = "";
1576
+ do {
1577
+ returnValue += string.substr(endIndex, index - endIndex) + substring + replacer;
1578
+ endIndex = index + substringLength;
1579
+ index = string.indexOf(substring, endIndex);
1580
+ } while (index !== -1);
1581
+ returnValue += string.substr(endIndex);
1582
+ return returnValue;
1583
+ };
1584
+ var stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => {
1585
+ let endIndex = 0;
1586
+ let returnValue = "";
1587
+ do {
1588
+ const gotCR = string[index - 1] === "\r";
1589
+ returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
1590
+ endIndex = index + 1;
1591
+ index = string.indexOf("\n", endIndex);
1592
+ } while (index !== -1);
1593
+ returnValue += string.substr(endIndex);
1594
+ return returnValue;
1595
+ };
1596
+ module.exports = {
1597
+ stringReplaceAll,
1598
+ stringEncaseCRLFWithFirstIndex
1599
+ };
1600
+ }
1601
+ });
1602
+
1603
+ // ../node_modules/chalk/source/templates.js
1604
+ var require_templates = __commonJS({
1605
+ "../node_modules/chalk/source/templates.js"(exports, module) {
1606
+ "use strict";
1607
+ var TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi;
1608
+ var STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g;
1609
+ var STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/;
1610
+ var ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|{[a-f\d]{1,6}})|x[a-f\d]{2}|.)|([^\\])/gi;
1611
+ var ESCAPES2 = /* @__PURE__ */ new Map([
1612
+ ["n", "\n"],
1613
+ ["r", "\r"],
1614
+ ["t", " "],
1615
+ ["b", "\b"],
1616
+ ["f", "\f"],
1617
+ ["v", "\v"],
1618
+ ["0", "\0"],
1619
+ ["\\", "\\"],
1620
+ ["e", "\x1B"],
1621
+ ["a", "\x07"]
1622
+ ]);
1623
+ function unescape(c) {
1624
+ const u = c[0] === "u";
1625
+ const bracket = c[1] === "{";
1626
+ if (u && !bracket && c.length === 5 || c[0] === "x" && c.length === 3) {
1627
+ return String.fromCharCode(parseInt(c.slice(1), 16));
1628
+ }
1629
+ if (u && bracket) {
1630
+ return String.fromCodePoint(parseInt(c.slice(2, -1), 16));
1631
+ }
1632
+ return ESCAPES2.get(c) || c;
1633
+ }
1634
+ function parseArguments(name, arguments_) {
1635
+ const results = [];
1636
+ const chunks = arguments_.trim().split(/\s*,\s*/g);
1637
+ let matches;
1638
+ for (const chunk of chunks) {
1639
+ const number = Number(chunk);
1640
+ if (!Number.isNaN(number)) {
1641
+ results.push(number);
1642
+ } else if (matches = chunk.match(STRING_REGEX)) {
1643
+ results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character));
1644
+ } else {
1645
+ throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`);
1646
+ }
1647
+ }
1648
+ return results;
1649
+ }
1650
+ function parseStyle(style) {
1651
+ STYLE_REGEX.lastIndex = 0;
1652
+ const results = [];
1653
+ let matches;
1654
+ while ((matches = STYLE_REGEX.exec(style)) !== null) {
1655
+ const name = matches[1];
1656
+ if (matches[2]) {
1657
+ const args2 = parseArguments(name, matches[2]);
1658
+ results.push([name].concat(args2));
1659
+ } else {
1660
+ results.push([name]);
1661
+ }
1662
+ }
1663
+ return results;
1664
+ }
1665
+ function buildStyle(chalk2, styles2) {
1666
+ const enabled = {};
1667
+ for (const layer of styles2) {
1668
+ for (const style of layer.styles) {
1669
+ enabled[style[0]] = layer.inverse ? null : style.slice(1);
1670
+ }
1671
+ }
1672
+ let current = chalk2;
1673
+ for (const [styleName, styles3] of Object.entries(enabled)) {
1674
+ if (!Array.isArray(styles3)) {
1675
+ continue;
1676
+ }
1677
+ if (!(styleName in current)) {
1678
+ throw new Error(`Unknown Chalk style: ${styleName}`);
1679
+ }
1680
+ current = styles3.length > 0 ? current[styleName](...styles3) : current[styleName];
1681
+ }
1682
+ return current;
1683
+ }
1684
+ module.exports = (chalk2, temporary) => {
1685
+ const styles2 = [];
1686
+ const chunks = [];
1687
+ let chunk = [];
1688
+ temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => {
1689
+ if (escapeCharacter) {
1690
+ chunk.push(unescape(escapeCharacter));
1691
+ } else if (style) {
1692
+ const string = chunk.join("");
1693
+ chunk = [];
1694
+ chunks.push(styles2.length === 0 ? string : buildStyle(chalk2, styles2)(string));
1695
+ styles2.push({ inverse, styles: parseStyle(style) });
1696
+ } else if (close) {
1697
+ if (styles2.length === 0) {
1698
+ throw new Error("Found extraneous } in Chalk template literal");
1699
+ }
1700
+ chunks.push(buildStyle(chalk2, styles2)(chunk.join("")));
1701
+ chunk = [];
1702
+ styles2.pop();
1703
+ } else {
1704
+ chunk.push(character);
1705
+ }
1706
+ });
1707
+ chunks.push(chunk.join(""));
1708
+ if (styles2.length > 0) {
1709
+ const errMessage = `Chalk template literal is missing ${styles2.length} closing bracket${styles2.length === 1 ? "" : "s"} (\`}\`)`;
1710
+ throw new Error(errMessage);
1711
+ }
1712
+ return chunks.join("");
1713
+ };
1714
+ }
1715
+ });
1716
+
1717
+ // ../node_modules/chalk/source/index.js
1718
+ var require_source = __commonJS({
1719
+ "../node_modules/chalk/source/index.js"(exports, module) {
1720
+ "use strict";
1721
+ var ansiStyles2 = require_ansi_styles();
1722
+ var { stdout: stdoutColor, stderr: stderrColor } = require_supports_color();
1723
+ var {
1724
+ stringReplaceAll,
1725
+ stringEncaseCRLFWithFirstIndex
1726
+ } = require_util();
1727
+ var { isArray } = Array;
1728
+ var levelMapping = [
1729
+ "ansi",
1730
+ "ansi",
1731
+ "ansi256",
1732
+ "ansi16m"
1733
+ ];
1734
+ var styles2 = /* @__PURE__ */ Object.create(null);
1735
+ var applyOptions = (object, options = {}) => {
1736
+ if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) {
1737
+ throw new Error("The `level` option should be an integer from 0 to 3");
1738
+ }
1739
+ const colorLevel = stdoutColor ? stdoutColor.level : 0;
1740
+ object.level = options.level === void 0 ? colorLevel : options.level;
1741
+ };
1742
+ var ChalkClass = class {
1743
+ constructor(options) {
1744
+ return chalkFactory(options);
1745
+ }
1746
+ };
1747
+ var chalkFactory = (options) => {
1748
+ const chalk3 = {};
1749
+ applyOptions(chalk3, options);
1750
+ chalk3.template = (...arguments_) => chalkTag(chalk3.template, ...arguments_);
1751
+ Object.setPrototypeOf(chalk3, Chalk.prototype);
1752
+ Object.setPrototypeOf(chalk3.template, chalk3);
1753
+ chalk3.template.constructor = () => {
1754
+ throw new Error("`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.");
1755
+ };
1756
+ chalk3.template.Instance = ChalkClass;
1757
+ return chalk3.template;
1758
+ };
1759
+ function Chalk(options) {
1760
+ return chalkFactory(options);
1761
+ }
1762
+ for (const [styleName, style] of Object.entries(ansiStyles2)) {
1763
+ styles2[styleName] = {
1764
+ get() {
1765
+ const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty);
1766
+ Object.defineProperty(this, styleName, { value: builder });
1767
+ return builder;
1768
+ }
1769
+ };
1770
+ }
1771
+ styles2.visible = {
1772
+ get() {
1773
+ const builder = createBuilder(this, this._styler, true);
1774
+ Object.defineProperty(this, "visible", { value: builder });
1775
+ return builder;
1776
+ }
1777
+ };
1778
+ var usedModels = ["rgb", "hex", "keyword", "hsl", "hsv", "hwb", "ansi", "ansi256"];
1779
+ for (const model of usedModels) {
1780
+ styles2[model] = {
1781
+ get() {
1782
+ const { level } = this;
1783
+ return function(...arguments_) {
1784
+ const styler = createStyler(ansiStyles2.color[levelMapping[level]][model](...arguments_), ansiStyles2.color.close, this._styler);
1785
+ return createBuilder(this, styler, this._isEmpty);
1786
+ };
1787
+ }
1788
+ };
1789
+ }
1790
+ for (const model of usedModels) {
1791
+ const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
1792
+ styles2[bgModel] = {
1793
+ get() {
1794
+ const { level } = this;
1795
+ return function(...arguments_) {
1796
+ const styler = createStyler(ansiStyles2.bgColor[levelMapping[level]][model](...arguments_), ansiStyles2.bgColor.close, this._styler);
1797
+ return createBuilder(this, styler, this._isEmpty);
1798
+ };
1799
+ }
1800
+ };
1801
+ }
1802
+ var proto = Object.defineProperties(() => {
1803
+ }, {
1804
+ ...styles2,
1805
+ level: {
1806
+ enumerable: true,
1807
+ get() {
1808
+ return this._generator.level;
1809
+ },
1810
+ set(level) {
1811
+ this._generator.level = level;
1812
+ }
1813
+ }
1814
+ });
1815
+ var createStyler = (open, close, parent) => {
1816
+ let openAll;
1817
+ let closeAll;
1818
+ if (parent === void 0) {
1819
+ openAll = open;
1820
+ closeAll = close;
1821
+ } else {
1822
+ openAll = parent.openAll + open;
1823
+ closeAll = close + parent.closeAll;
1824
+ }
1825
+ return {
1826
+ open,
1827
+ close,
1828
+ openAll,
1829
+ closeAll,
1830
+ parent
1831
+ };
1832
+ };
1833
+ var createBuilder = (self, _styler, _isEmpty) => {
1834
+ const builder = (...arguments_) => {
1835
+ if (isArray(arguments_[0]) && isArray(arguments_[0].raw)) {
1836
+ return applyStyle(builder, chalkTag(builder, ...arguments_));
1837
+ }
1838
+ return applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
1839
+ };
1840
+ Object.setPrototypeOf(builder, proto);
1841
+ builder._generator = self;
1842
+ builder._styler = _styler;
1843
+ builder._isEmpty = _isEmpty;
1844
+ return builder;
1845
+ };
1846
+ var applyStyle = (self, string) => {
1847
+ if (self.level <= 0 || !string) {
1848
+ return self._isEmpty ? "" : string;
1849
+ }
1850
+ let styler = self._styler;
1851
+ if (styler === void 0) {
1852
+ return string;
1853
+ }
1854
+ const { openAll, closeAll } = styler;
1855
+ if (string.indexOf("\x1B") !== -1) {
1856
+ while (styler !== void 0) {
1857
+ string = stringReplaceAll(string, styler.close, styler.open);
1858
+ styler = styler.parent;
1859
+ }
1860
+ }
1861
+ const lfIndex = string.indexOf("\n");
1862
+ if (lfIndex !== -1) {
1863
+ string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
1864
+ }
1865
+ return openAll + string + closeAll;
1866
+ };
1867
+ var template;
1868
+ var chalkTag = (chalk3, ...strings) => {
1869
+ const [firstString] = strings;
1870
+ if (!isArray(firstString) || !isArray(firstString.raw)) {
1871
+ return strings.join(" ");
1872
+ }
1873
+ const arguments_ = strings.slice(1);
1874
+ const parts = [firstString.raw[0]];
1875
+ for (let i = 1; i < firstString.length; i++) {
1876
+ parts.push(
1877
+ String(arguments_[i - 1]).replace(/[{}\\]/g, "\\$&"),
1878
+ String(firstString.raw[i])
1879
+ );
1880
+ }
1881
+ if (template === void 0) {
1882
+ template = require_templates();
1883
+ }
1884
+ return template(chalk3, parts.join(""));
1885
+ };
1886
+ Object.defineProperties(Chalk.prototype, styles2);
1887
+ var chalk2 = Chalk();
1888
+ chalk2.supportsColor = stdoutColor;
1889
+ chalk2.stderr = Chalk({ level: stderrColor ? stderrColor.level : 0 });
1890
+ chalk2.stderr.supportsColor = stderrColor;
1891
+ module.exports = chalk2;
1892
+ }
1893
+ });
1894
+
1895
+ // node_modules/@inquirer/core/dist/lib/key.js
1896
+ var isUpKey = (key, keybindings = []) => (
1897
+ // The up key
1898
+ key.name === "up" || // Vim keybinding: hjkl keys map to left/down/up/right
1899
+ keybindings.includes("vim") && key.name === "k" || // Emacs keybinding: Ctrl+P means "previous" in Emacs navigation conventions
1900
+ keybindings.includes("emacs") && key.ctrl && key.name === "p"
1901
+ );
1902
+ var isDownKey = (key, keybindings = []) => (
1903
+ // The down key
1904
+ key.name === "down" || // Vim keybinding: hjkl keys map to left/down/up/right
1905
+ keybindings.includes("vim") && key.name === "j" || // Emacs keybinding: Ctrl+N means "next" in Emacs navigation conventions
1906
+ keybindings.includes("emacs") && key.ctrl && key.name === "n"
1907
+ );
1908
+ var isSpaceKey = (key) => key.name === "space";
1909
+ var isBackspaceKey = (key) => key.name === "backspace";
1910
+ var isTabKey = (key) => key.name === "tab";
1911
+ var isNumberKey = (key) => "1234567890".includes(key.name);
1912
+ var isEnterKey = (key) => key.name === "enter" || key.name === "return";
1913
+
1914
+ // node_modules/@inquirer/core/dist/lib/errors.js
1915
+ var AbortPromptError = class extends Error {
1916
+ name = "AbortPromptError";
1917
+ message = "Prompt was aborted";
1918
+ constructor(options) {
1919
+ super();
1920
+ this.cause = options?.cause;
1921
+ }
1922
+ };
1923
+ var CancelPromptError = class extends Error {
1924
+ name = "CancelPromptError";
1925
+ message = "Prompt was canceled";
1926
+ };
1927
+ var ExitPromptError = class extends Error {
1928
+ name = "ExitPromptError";
1929
+ };
1930
+ var HookError = class extends Error {
1931
+ name = "HookError";
1932
+ };
1933
+ var ValidationError = class extends Error {
1934
+ name = "ValidationError";
1935
+ };
1936
+
1937
+ // node_modules/@inquirer/core/dist/lib/use-state.js
1938
+ import { AsyncResource as AsyncResource2 } from "node:async_hooks";
1939
+
1940
+ // node_modules/@inquirer/core/dist/lib/hook-engine.js
1941
+ import { AsyncLocalStorage, AsyncResource } from "node:async_hooks";
1942
+ var hookStorage = new AsyncLocalStorage();
1943
+ function createStore(rl) {
1944
+ const store = {
1945
+ rl,
1946
+ hooks: [],
1947
+ hooksCleanup: [],
1948
+ hooksEffect: [],
1949
+ index: 0,
1950
+ handleChange() {
1951
+ }
1952
+ };
1953
+ return store;
1954
+ }
1955
+ function withHooks(rl, cb) {
1956
+ const store = createStore(rl);
1957
+ return hookStorage.run(store, () => {
1958
+ function cycle(render) {
1959
+ store.handleChange = () => {
1960
+ store.index = 0;
1961
+ render();
1962
+ };
1963
+ store.handleChange();
1964
+ }
1965
+ return cb(cycle);
1966
+ });
1967
+ }
1968
+ function getStore() {
1969
+ const store = hookStorage.getStore();
1970
+ if (!store) {
1971
+ throw new HookError("[Inquirer] Hook functions can only be called from within a prompt");
1972
+ }
1973
+ return store;
1974
+ }
1975
+ function readline() {
1976
+ return getStore().rl;
1977
+ }
1978
+ function withUpdates(fn) {
1979
+ const wrapped = (...args2) => {
1980
+ const store = getStore();
1981
+ let shouldUpdate = false;
1982
+ const oldHandleChange = store.handleChange;
1983
+ store.handleChange = () => {
1984
+ shouldUpdate = true;
1985
+ };
1986
+ const returnValue = fn(...args2);
1987
+ if (shouldUpdate) {
1988
+ oldHandleChange();
1989
+ }
1990
+ store.handleChange = oldHandleChange;
1991
+ return returnValue;
1992
+ };
1993
+ return AsyncResource.bind(wrapped);
1994
+ }
1995
+ function withPointer(cb) {
1996
+ const store = getStore();
1997
+ const { index } = store;
1998
+ const pointer = {
1999
+ get() {
2000
+ return store.hooks[index];
2001
+ },
2002
+ set(value) {
2003
+ store.hooks[index] = value;
2004
+ },
2005
+ initialized: index in store.hooks
2006
+ };
2007
+ const returnValue = cb(pointer);
2008
+ store.index++;
2009
+ return returnValue;
2010
+ }
2011
+ function handleChange() {
2012
+ getStore().handleChange();
2013
+ }
2014
+ var effectScheduler = {
2015
+ queue(cb) {
2016
+ const store = getStore();
2017
+ const { index } = store;
2018
+ store.hooksEffect.push(() => {
2019
+ store.hooksCleanup[index]?.();
2020
+ const cleanFn = cb(readline());
2021
+ if (cleanFn != null && typeof cleanFn !== "function") {
2022
+ throw new ValidationError("useEffect return value must be a cleanup function or nothing.");
2023
+ }
2024
+ store.hooksCleanup[index] = cleanFn;
2025
+ });
2026
+ },
2027
+ run() {
2028
+ const store = getStore();
2029
+ withUpdates(() => {
2030
+ store.hooksEffect.forEach((effect) => {
2031
+ effect();
2032
+ });
2033
+ store.hooksEffect.length = 0;
2034
+ })();
2035
+ },
2036
+ clearAll() {
2037
+ const store = getStore();
2038
+ store.hooksCleanup.forEach((cleanFn) => {
2039
+ cleanFn?.();
2040
+ });
2041
+ store.hooksEffect.length = 0;
2042
+ store.hooksCleanup.length = 0;
2043
+ }
2044
+ };
2045
+
2046
+ // node_modules/@inquirer/core/dist/lib/use-state.js
2047
+ function useState(defaultValue) {
2048
+ return withPointer((pointer) => {
2049
+ const setState = AsyncResource2.bind(function setState2(newValue) {
2050
+ if (pointer.get() !== newValue) {
2051
+ pointer.set(newValue);
2052
+ handleChange();
2053
+ }
2054
+ });
2055
+ if (pointer.initialized) {
2056
+ return [pointer.get(), setState];
2057
+ }
2058
+ const value = typeof defaultValue === "function" ? defaultValue() : defaultValue;
2059
+ pointer.set(value);
2060
+ return [value, setState];
2061
+ });
2062
+ }
2063
+
2064
+ // node_modules/@inquirer/core/dist/lib/use-effect.js
514
2065
  function useEffect(cb, depArray) {
515
2066
  withPointer((pointer) => {
516
2067
  const oldDeps = pointer.get();
@@ -2558,7 +4109,6 @@ async function resolveConfig() {
2558
4109
  }
2559
4110
  const resolved = {
2560
4111
  project: projectConfig.project,
2561
- environment: projectConfig.environment,
2562
4112
  host: projectConfig.host || globalConfig.host || DEFAULT_HOST,
2563
4113
  namespace: projectConfig.namespace || globalConfig.namespace || DEFAULT_NAMESPACE,
2564
4114
  authToken
@@ -2570,9 +4120,6 @@ function validateResolvedConfig(config) {
2570
4120
  if (!config.project) {
2571
4121
  errors.push("Project name is required");
2572
4122
  }
2573
- if (!config.environment) {
2574
- errors.push("Environment name is required");
2575
- }
2576
4123
  if (!config.host) {
2577
4124
  errors.push(
2578
4125
  "Host URL is required (set globally with: jssm config set host <url>)"
@@ -2617,140 +4164,395 @@ async function getProjects(host, apiKey) {
2617
4164
  const url = `${host}/projects`;
2618
4165
  return apiRequest(url, apiKey);
2619
4166
  }
2620
- async function createEnvironment(host, apiKey, project, name) {
2621
- const url = `${host}/projects/${project}/envs`;
2622
- return apiRequest(url, apiKey, {
2623
- method: "POST",
2624
- body: JSON.stringify({ name })
2625
- });
2626
- }
2627
- async function getEnvironments(host, apiKey, project) {
2628
- const url = `${host}/projects/${project}/envs`;
2629
- return apiRequest(url, apiKey);
2630
- }
2631
- async function pushEnvFile(host, apiKey, project, environment, content, filename = ".env") {
2632
- const url = `${host}/projects/${project}/envs/${environment}/push-file`;
4167
+ async function pushEnvFile(host, apiKey, project, content, filename = ".env", environment) {
4168
+ const url = `${host}/projects/${project}/files/push`;
4169
+ const body = { content, filename };
4170
+ if (environment) {
4171
+ body.environment = environment;
4172
+ }
2633
4173
  return apiRequest(url, apiKey, {
2634
4174
  method: "POST",
2635
- body: JSON.stringify({ content, filename })
4175
+ body: JSON.stringify(body)
2636
4176
  });
2637
4177
  }
2638
- async function pullEnvFile(host, apiKey, project, environment, filename = ".env") {
2639
- const url = `${host}/projects/${project}/envs/${environment}/pull-file?filename=${encodeURIComponent(
4178
+ async function pullEnvFile(host, apiKey, project, filename = ".env") {
4179
+ const url = `${host}/projects/${project}/files/pull?filename=${encodeURIComponent(
2640
4180
  filename
2641
4181
  )}`;
2642
4182
  const data = await apiRequest(url, apiKey);
2643
4183
  return data.content;
2644
4184
  }
2645
- async function listEnvFiles(host, apiKey, project, environment) {
2646
- const url = `${host}/projects/${project}/envs/${environment}/list-files`;
2647
- const data = await apiRequest(url, apiKey);
2648
- return data.files;
4185
+ async function listEnvFiles(host, apiKey, project) {
4186
+ const url = `${host}/projects/${project}/files/list`;
4187
+ const data = await apiRequest(url, apiKey);
4188
+ return data.files;
4189
+ }
4190
+
4191
+ // src/utils/repoDetector.ts
4192
+ import { readdir, readFile as readFile3, stat } from "fs/promises";
4193
+ import { join as join3, relative } from "path";
4194
+ function isEnvFile(filename) {
4195
+ return filename === ".env" || filename.startsWith(".env.");
4196
+ }
4197
+ async function isMonorepo(rootPath) {
4198
+ try {
4199
+ const indicators = [
4200
+ "lerna.json",
4201
+ "nx.json",
4202
+ "pnpm-workspace.yaml",
4203
+ "rush.json"
4204
+ ];
4205
+ for (const indicator of indicators) {
4206
+ try {
4207
+ await stat(join3(rootPath, indicator));
4208
+ return true;
4209
+ } catch {
4210
+ }
4211
+ }
4212
+ const commonDirs = ["packages", "apps", "services"];
4213
+ for (const dir of commonDirs) {
4214
+ try {
4215
+ const dirPath = join3(rootPath, dir);
4216
+ const dirStat = await stat(dirPath);
4217
+ if (dirStat.isDirectory()) {
4218
+ const entries = await readdir(dirPath, { withFileTypes: true });
4219
+ const subdirs = entries.filter((e) => e.isDirectory());
4220
+ if (subdirs.length >= 2) {
4221
+ return true;
4222
+ }
4223
+ }
4224
+ } catch {
4225
+ }
4226
+ }
4227
+ try {
4228
+ const packageJsonPath = join3(rootPath, "package.json");
4229
+ const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf-8"));
4230
+ if (packageJson.workspaces) {
4231
+ return true;
4232
+ }
4233
+ } catch {
4234
+ }
4235
+ return false;
4236
+ } catch {
4237
+ return false;
4238
+ }
4239
+ }
4240
+ async function findEnvFiles(rootPath, maxDepth = 10) {
4241
+ const envFiles = [];
4242
+ async function search(currentPath, depth) {
4243
+ if (maxDepth !== -1 && depth > maxDepth)
4244
+ return;
4245
+ try {
4246
+ const entries = await readdir(currentPath, { withFileTypes: true });
4247
+ for (const entry of entries) {
4248
+ const fullPath = join3(currentPath, entry.name);
4249
+ if (entry.isDirectory() && ![
4250
+ "node_modules",
4251
+ ".git",
4252
+ "dist",
4253
+ "build",
4254
+ ".next",
4255
+ "coverage",
4256
+ ".turbo",
4257
+ ".cache",
4258
+ "out",
4259
+ "target"
4260
+ ].includes(entry.name)) {
4261
+ await search(fullPath, depth + 1);
4262
+ } else if (entry.isFile() && isEnvFile(entry.name)) {
4263
+ try {
4264
+ const content = await readFile3(fullPath, "utf-8");
4265
+ const lines = content.split("\n");
4266
+ const variableCount = lines.filter((line) => {
4267
+ const trimmed = line.trim();
4268
+ return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
4269
+ }).length;
4270
+ envFiles.push({
4271
+ path: fullPath,
4272
+ relativePath: relative(rootPath, fullPath),
4273
+ variableCount
4274
+ });
4275
+ } catch {
4276
+ }
4277
+ }
4278
+ }
4279
+ } catch {
4280
+ }
4281
+ }
4282
+ await search(rootPath, 0);
4283
+ return envFiles;
4284
+ }
4285
+ async function getRepositoryType(rootPath) {
4286
+ const isMonorepoResult = await isMonorepo(rootPath);
4287
+ return isMonorepoResult ? "monorepo" : "normal";
2649
4288
  }
2650
4289
 
2651
- // src/utils/repoDetector.ts
2652
- import { readdir, readFile as readFile3, stat } from "fs/promises";
2653
- import { join as join3, relative } from "path";
2654
- function isEnvFile(filename) {
2655
- return filename === ".env" || filename.startsWith(".env.");
2656
- }
2657
- async function isMonorepo(rootPath) {
2658
- try {
2659
- const indicators = [
2660
- "lerna.json",
2661
- "nx.json",
2662
- "pnpm-workspace.yaml",
2663
- "rush.json"
2664
- ];
2665
- for (const indicator of indicators) {
2666
- try {
2667
- await stat(join3(rootPath, indicator));
2668
- return true;
2669
- } catch {
4290
+ // src/commands/init.ts
4291
+ async function initCommand(args2) {
4292
+ const flags = {};
4293
+ for (let i = 0; i < args2.length; i++) {
4294
+ if (args2[i].startsWith("-")) {
4295
+ const key = args2[i].replace(/^-+/, "");
4296
+ const value = args2[i + 1];
4297
+ if (value && !value.startsWith("-")) {
4298
+ flags[key] = value;
4299
+ i++;
4300
+ } else {
4301
+ flags[key] = "true";
2670
4302
  }
2671
4303
  }
2672
- const commonDirs = ["packages", "apps", "services"];
2673
- for (const dir of commonDirs) {
4304
+ }
4305
+ const configExists = await hasLocalConfig();
4306
+ if (configExists && !flags.force && !flags.f) {
4307
+ const projectConfig = await loadProjectConfig();
4308
+ if (projectConfig) {
4309
+ console.log("\u{1F4C1} JSSM project already initialized\n");
4310
+ console.log(` Project: ${projectConfig.project}`);
4311
+ console.log();
2674
4312
  try {
2675
- const dirPath = join3(rootPath, dir);
2676
- const dirStat = await stat(dirPath);
2677
- if (dirStat.isDirectory()) {
2678
- const entries = await readdir(dirPath, { withFileTypes: true });
2679
- const subdirs = entries.filter((e) => e.isDirectory());
2680
- if (subdirs.length >= 2) {
4313
+ const action = await dist_default6({
4314
+ message: "What would you like to do?",
4315
+ choices: [
4316
+ {
4317
+ name: "\u{1F4E5} Pull - Download .env files from server",
4318
+ value: "pull"
4319
+ },
4320
+ {
4321
+ name: "\u{1F4E4} Push - Upload local .env files to server",
4322
+ value: "push"
4323
+ },
4324
+ {
4325
+ name: "\u{1F504} Reinitialize - Set up a different project",
4326
+ value: "reinit"
4327
+ },
4328
+ { name: "\u274C Cancel", value: "cancel" }
4329
+ ]
4330
+ });
4331
+ if (action === "pull") {
4332
+ await pullCommand([]);
4333
+ return;
4334
+ } else if (action === "push") {
4335
+ await pushCommand([]);
4336
+ return;
4337
+ } else if (action === "cancel") {
4338
+ console.log("\n\u{1F44B} Cancelled");
4339
+ return;
4340
+ }
4341
+ console.log();
4342
+ } catch (error) {
4343
+ if (error.name === "ExitPromptError") {
4344
+ console.log("\n\u{1F44B} Cancelled");
4345
+ return;
4346
+ }
4347
+ throw error;
4348
+ }
4349
+ }
4350
+ }
4351
+ console.log("\u{1F680} JSSM Project Initialization\n");
4352
+ console.log("\u{1F510} Checking authentication...");
4353
+ const authData = await loadAuthData();
4354
+ if (!authData) {
4355
+ console.log("\n\u274C You are not logged in");
4356
+ console.log("\u{1F4A1} Please login or register first:");
4357
+ console.log(" jssm login");
4358
+ console.log(" jssm register");
4359
+ process.exit(1);
4360
+ }
4361
+ console.log(`\u2705 Logged in as ${authData.user.email}
4362
+ `);
4363
+ const globalConfig = await loadGlobalConfig();
4364
+ const host = flags.host || flags.h || globalConfig.host;
4365
+ if (!host) {
4366
+ console.error("\u274C Host URL is required");
4367
+ console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
4368
+ process.exit(1);
4369
+ }
4370
+ const authToken = authData.token;
4371
+ console.log("\u{1F50D} Analyzing repository...");
4372
+ const cwd = process.cwd();
4373
+ const repoType = await getRepositoryType(cwd);
4374
+ console.log(` Repository type: ${repoType}`);
4375
+ const envFiles = await findEnvFiles(cwd);
4376
+ if (envFiles.length > 0) {
4377
+ console.log(` Found ${envFiles.length} .env file(s)`);
4378
+ } else {
4379
+ console.log(` No .env files found`);
4380
+ }
4381
+ console.log();
4382
+ let projectName;
4383
+ try {
4384
+ console.log("\u{1F4E6} Loading your projects...");
4385
+ const projects = await getProjects(host, authToken);
4386
+ if (projects.length === 0) {
4387
+ console.log(" No existing projects found\n");
4388
+ projectName = await dist_default4({
4389
+ message: "Project name:",
4390
+ validate: (value) => {
4391
+ if (!value)
4392
+ return "Project name is required";
4393
+ if (!/^[a-z0-9-_.]+$/.test(value)) {
4394
+ return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
4395
+ }
4396
+ return true;
4397
+ }
4398
+ });
4399
+ console.log(`
4400
+ \u{1F4E6} Creating project "${projectName}"...`);
4401
+ await createProject(host, authToken, projectName, repoType);
4402
+ console.log(`\u2705 Project created
4403
+ `);
4404
+ } else {
4405
+ const projectChoices = [
4406
+ ...projects.map((p) => ({ name: p.name, value: p.name })),
4407
+ { name: "+ Create new project", value: "__new__" }
4408
+ ];
4409
+ const selectedProject = await dist_default6({
4410
+ message: "Select a project:",
4411
+ choices: projectChoices
4412
+ });
4413
+ if (selectedProject === "__new__") {
4414
+ projectName = await dist_default4({
4415
+ message: "New project name:",
4416
+ validate: (value) => {
4417
+ if (!value)
4418
+ return "Project name is required";
4419
+ if (!/^[a-z0-9-_.]+$/.test(value)) {
4420
+ return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
4421
+ }
4422
+ if (projects.some((p) => p.name === value)) {
4423
+ return "Project already exists";
4424
+ }
2681
4425
  return true;
2682
4426
  }
4427
+ });
4428
+ console.log(`
4429
+ \u{1F4E6} Creating project "${projectName}"...`);
4430
+ await createProject(host, authToken, projectName, repoType);
4431
+ console.log(`\u2705 Project created
4432
+ `);
4433
+ } else {
4434
+ projectName = selectedProject;
4435
+ }
4436
+ }
4437
+ if (envFiles.length > 0) {
4438
+ console.log("\u{1F4C4} .env files detected:");
4439
+ envFiles.forEach((file) => {
4440
+ console.log(
4441
+ ` ${file.relativePath} (${file.variableCount} variables)`
4442
+ );
4443
+ });
4444
+ console.log();
4445
+ const shouldUpload = await dist_default3({
4446
+ message: "Would you like to upload variables from .env files?",
4447
+ default: true
4448
+ });
4449
+ if (shouldUpload) {
4450
+ let selectedFileInfos;
4451
+ if (repoType === "monorepo" && envFiles.length > 1) {
4452
+ const fileChoices = envFiles.map((file) => ({
4453
+ name: `${file.relativePath} (${file.variableCount} variables)`,
4454
+ value: file.relativePath
4455
+ }));
4456
+ const selectedPaths = await dist_default2({
4457
+ message: "Select .env files to upload:",
4458
+ choices: fileChoices,
4459
+ validate: (answer) => {
4460
+ if (answer.length === 0) {
4461
+ return "Please select at least one file";
4462
+ }
4463
+ return true;
4464
+ }
4465
+ });
4466
+ selectedFileInfos = envFiles.filter(
4467
+ (f) => selectedPaths.includes(f.relativePath)
4468
+ );
4469
+ } else {
4470
+ selectedFileInfos = [envFiles[0]];
4471
+ }
4472
+ const totalVars = selectedFileInfos.reduce(
4473
+ (sum, f) => sum + f.variableCount,
4474
+ 0
4475
+ );
4476
+ console.log(
4477
+ `
4478
+ \u{1F4CB} Files to upload (${selectedFileInfos.length} files, ${totalVars} total variables):`
4479
+ );
4480
+ selectedFileInfos.forEach((f) => {
4481
+ console.log(` ${f.relativePath} (${f.variableCount} variables)`);
4482
+ });
4483
+ const confirmUpload = await dist_default3({
4484
+ message: "\nProceed with upload?",
4485
+ default: true
4486
+ });
4487
+ if (confirmUpload) {
4488
+ console.log(`
4489
+ \u2B06\uFE0F Uploading ${selectedFileInfos.length} file(s)...`);
4490
+ let successCount = 0;
4491
+ let failCount = 0;
4492
+ for (const fileInfo of selectedFileInfos) {
4493
+ try {
4494
+ const { readFile: readFileAsync } = await import("fs/promises");
4495
+ const content = await readFileAsync(fileInfo.path, "utf-8");
4496
+ await pushEnvFile(
4497
+ host,
4498
+ authToken,
4499
+ projectName,
4500
+ content,
4501
+ fileInfo.relativePath
4502
+ );
4503
+ console.log(` \u2705 ${fileInfo.relativePath}`);
4504
+ successCount++;
4505
+ } catch (error) {
4506
+ console.log(` \u274C ${fileInfo.relativePath}: ${error.message}`);
4507
+ failCount++;
4508
+ }
4509
+ }
4510
+ if (failCount === 0) {
4511
+ console.log(`\u2705 All files uploaded successfully`);
4512
+ } else {
4513
+ console.log(`
4514
+ \u26A0\uFE0F ${successCount} succeeded, ${failCount} failed`);
4515
+ }
4516
+ } else {
4517
+ console.log("\n\u23ED\uFE0F Skipping file upload");
2683
4518
  }
2684
- } catch {
2685
4519
  }
2686
4520
  }
2687
- try {
2688
- const packageJsonPath = join3(rootPath, "package.json");
2689
- const packageJson = JSON.parse(await readFile3(packageJsonPath, "utf-8"));
2690
- if (packageJson.workspaces) {
2691
- return true;
2692
- }
2693
- } catch {
4521
+ const projectConfig = {
4522
+ project: projectName
4523
+ };
4524
+ if (flags.host && flags.host !== globalConfig.host) {
4525
+ projectConfig.host = flags.host;
2694
4526
  }
2695
- return false;
2696
- } catch {
2697
- return false;
2698
- }
2699
- }
2700
- async function findEnvFiles(rootPath, maxDepth = 10) {
2701
- const envFiles = [];
2702
- async function search(currentPath, depth) {
2703
- if (maxDepth !== -1 && depth > maxDepth)
2704
- return;
2705
- try {
2706
- const entries = await readdir(currentPath, { withFileTypes: true });
2707
- for (const entry of entries) {
2708
- const fullPath = join3(currentPath, entry.name);
2709
- if (entry.isDirectory() && ![
2710
- "node_modules",
2711
- ".git",
2712
- "dist",
2713
- "build",
2714
- ".next",
2715
- "coverage",
2716
- ".turbo",
2717
- ".cache",
2718
- "out",
2719
- "target"
2720
- ].includes(entry.name)) {
2721
- await search(fullPath, depth + 1);
2722
- } else if (entry.isFile() && isEnvFile(entry.name)) {
2723
- try {
2724
- const content = await readFile3(fullPath, "utf-8");
2725
- const lines = content.split("\n");
2726
- const variableCount = lines.filter((line) => {
2727
- const trimmed = line.trim();
2728
- return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
2729
- }).length;
2730
- envFiles.push({
2731
- path: fullPath,
2732
- relativePath: relative(rootPath, fullPath),
2733
- variableCount
2734
- });
2735
- } catch {
2736
- }
2737
- }
2738
- }
2739
- } catch {
4527
+ if (flags.namespace && flags.namespace !== globalConfig.namespace) {
4528
+ projectConfig.namespace = flags.namespace;
4529
+ }
4530
+ await saveProjectConfig(projectConfig);
4531
+ console.log(`
4532
+ \u2705 Project initialized successfully!`);
4533
+ console.log(` Config file: .jssm`);
4534
+ console.log(` Project: ${projectName}`);
4535
+ console.log(` Repository type: ${repoType}`);
4536
+ console.log(`
4537
+ \u{1F4A1} Next steps:`);
4538
+ console.log(` - Run "jssm pull" to fetch variables`);
4539
+ console.log(` - Run "jssm sync" to sync variables to .env`);
4540
+ console.log(` - Run "jssm push" to upload local .env changes`);
4541
+ } catch (error) {
4542
+ if (error.name === "ExitPromptError") {
4543
+ console.log("\n\u274C Initialization cancelled");
4544
+ process.exit(0);
2740
4545
  }
4546
+ console.error(`
4547
+ \u274C Error: ${error.message}`);
4548
+ process.exit(1);
2741
4549
  }
2742
- await search(rootPath, 0);
2743
- return envFiles;
2744
- }
2745
- async function getRepositoryType(rootPath) {
2746
- const isMonorepoResult = await isMonorepo(rootPath);
2747
- return isMonorepoResult ? "monorepo" : "normal";
2748
4550
  }
2749
4551
 
2750
4552
  // src/commands/pull.ts
2751
4553
  import { writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
2752
4554
  import { join as join4, dirname } from "path";
2753
- async function pullCommand(args2) {
4555
+ async function pullCommand2(args2) {
2754
4556
  const flags = {};
2755
4557
  let pullAll = false;
2756
4558
  for (let i = 0; i < args2.length; i++) {
@@ -2768,7 +4570,7 @@ async function pullCommand(args2) {
2768
4570
  const config = await resolveConfig();
2769
4571
  if (!config) {
2770
4572
  console.error("\u274C No .jssm configuration found in current directory.");
2771
- console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
4573
+ console.error('\u{1F4A1} Run "jssm init -p <project>" to initialize.');
2772
4574
  process.exit(1);
2773
4575
  }
2774
4576
  const { valid, errors } = validateResolvedConfig(config);
@@ -2778,22 +4580,18 @@ async function pullCommand(args2) {
2778
4580
  process.exit(1);
2779
4581
  }
2780
4582
  const project = flags.p || flags.project || config.project;
2781
- const environment = flags.e || flags.env || config.environment;
2782
4583
  const output = flags.out;
2783
- if (project !== config.project || environment !== config.environment) {
2784
- console.log(`\u26A0\uFE0F Warning: Pulling from ${project}/${environment}`);
2785
- console.log(
2786
- ` This directory is initialized for ${config.project}/${config.environment}`
2787
- );
4584
+ if (project !== config.project) {
4585
+ console.log(`\u26A0\uFE0F Warning: Pulling from ${project}`);
4586
+ console.log(` This directory is initialized for ${config.project}`);
2788
4587
  }
2789
4588
  try {
2790
4589
  if (output) {
2791
- console.log(`\u{1F4E5} Pulling ${output} from ${project}/${environment}...`);
4590
+ console.log(`\u{1F4E5} Pulling ${output} from ${project}...`);
2792
4591
  const content = await pullEnvFile(
2793
4592
  config.host,
2794
4593
  config.authToken,
2795
4594
  project,
2796
- environment,
2797
4595
  output
2798
4596
  );
2799
4597
  const outputPath = join4(process.cwd(), output);
@@ -2806,196 +4604,33 @@ async function pullCommand(args2) {
2806
4604
  console.log(`\u2705 Wrote ${output} (${varCount} variables)`);
2807
4605
  return;
2808
4606
  }
2809
- console.log(`\u{1F4E5} Checking available files in ${project}/${environment}...`);
4607
+ console.log(`\u{1F4E5} Checking available files in ${project}...`);
2810
4608
  const availableFiles = await listEnvFiles(
2811
4609
  config.host,
2812
4610
  config.authToken,
2813
- project,
2814
- environment
4611
+ project
2815
4612
  );
2816
4613
  if (availableFiles.length === 0) {
2817
4614
  console.error("\u274C No .env files found on server");
2818
4615
  console.error("\u{1F4A1} Push files first with: jssm push");
2819
4616
  process.exit(1);
2820
4617
  }
2821
- let selectedFiles = [];
2822
- if (availableFiles.length === 1) {
2823
- selectedFiles = [availableFiles[0]];
2824
- console.log(`\u{1F4C4} Found ${availableFiles[0]} on server`);
2825
- } else if (pullAll) {
2826
- selectedFiles = availableFiles;
2827
- console.log(`\u{1F4C4} Found ${availableFiles.length} files on server`);
2828
- } else {
2829
- console.log(`\u{1F4C4} Found ${availableFiles.length} .env files on server:
2830
- `);
2831
- availableFiles.forEach((file) => {
2832
- console.log(` \u2022 ${file}`);
2833
- });
2834
- console.log();
2835
- const pullOption = await dist_default6({
2836
- message: "What would you like to pull?",
2837
- choices: [
2838
- {
2839
- name: "\u2728 All files",
2840
- value: "all"
2841
- },
2842
- {
2843
- name: "\u{1F4C1} Select specific files",
2844
- value: "specific"
2845
- }
2846
- ]
2847
- });
2848
- if (pullOption === "all") {
2849
- selectedFiles = availableFiles;
2850
- } else {
2851
- const fileChoices = availableFiles.map((file) => ({
2852
- name: file,
2853
- value: file,
2854
- checked: false
2855
- }));
2856
- selectedFiles = await dist_default2({
2857
- message: "Select .env file(s) to pull:",
2858
- choices: fileChoices,
2859
- validate: (answer) => {
2860
- if (answer.length === 0) {
2861
- return "Please select at least one file";
2862
- }
2863
- return true;
2864
- }
2865
- });
2866
- }
2867
- }
2868
- if (selectedFiles.length === 1) {
2869
- console.log(`
2870
- \u{1F4E5} Pulling ${selectedFiles[0]}...`);
2871
- } else {
2872
- console.log(`
2873
- \u{1F4E5} Pulling ${selectedFiles.length} files...
2874
- `);
2875
- }
2876
- let successCount = 0;
2877
- let failCount = 0;
2878
- for (const filename of selectedFiles) {
2879
- try {
2880
- const content = await pullEnvFile(
2881
- config.host,
2882
- config.authToken,
2883
- project,
2884
- environment,
2885
- filename
2886
- );
2887
- const outputPath = join4(process.cwd(), filename);
2888
- const dir = dirname(outputPath);
2889
- if (dir !== process.cwd()) {
2890
- await mkdir3(dir, { recursive: true });
2891
- }
2892
- await writeFile3(outputPath, content, "utf-8");
2893
- const varCount = countVariables(content);
2894
- if (selectedFiles.length === 1) {
2895
- console.log(`\u2705 Wrote ${filename} (${varCount} variables)`);
2896
- } else {
2897
- console.log(`\u2705 ${filename}: Pulled (${varCount} variables)`);
2898
- }
2899
- successCount++;
2900
- } catch (error) {
2901
- const message = error instanceof Error ? error.message : String(error);
2902
- console.error(`\u274C ${filename}: Failed to pull - ${message}`);
2903
- failCount++;
2904
- }
2905
- }
2906
- if (selectedFiles.length > 1) {
2907
- console.log(`
2908
- \u{1F4CA} Summary:`);
2909
- if (successCount > 0) {
2910
- console.log(` \u2705 Success: ${successCount} file(s)`);
2911
- }
2912
- if (failCount > 0) {
2913
- console.log(` \u274C Failed: ${failCount} file(s)`);
2914
- }
2915
- }
2916
- if (failCount > 0 && successCount === 0) {
2917
- process.exit(1);
2918
- }
2919
- } catch (error) {
2920
- const message = error instanceof Error ? error.message : String(error);
2921
- console.error("\u274C Failed to pull .env files:", message);
2922
- process.exit(1);
2923
- }
2924
- }
2925
- function countVariables(content) {
2926
- return content.split("\n").filter((line) => {
2927
- const trimmed = line.trim();
2928
- return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
2929
- }).length;
2930
- }
2931
-
2932
- // src/commands/push.ts
2933
- import { readFile as readFile4 } from "fs/promises";
2934
- import { join as join5 } from "path";
2935
- async function pushCommand(args2) {
2936
- const flags = {};
2937
- for (let i = 0; i < args2.length; i++) {
2938
- if (args2[i].startsWith("-")) {
2939
- const key = args2[i].replace(/^-+/, "");
2940
- const value = args2[i + 1];
2941
- if (value && !value.startsWith("-")) {
2942
- flags[key] = value;
2943
- i++;
2944
- }
2945
- }
2946
- }
2947
- const config = await resolveConfig();
2948
- if (!config) {
2949
- console.error("\u274C No .jssm configuration found in current directory.");
2950
- console.error('\u{1F4A1} Run "jssm init -p <project> -e <env>" to initialize.');
2951
- process.exit(1);
2952
- }
2953
- const { valid, errors } = validateResolvedConfig(config);
2954
- if (!valid) {
2955
- console.error("\u274C Configuration is incomplete:");
2956
- errors.forEach((e) => console.error(` \u2022 ${e}`));
2957
- process.exit(1);
2958
- }
2959
- const project = flags.p || flags.project || config.project;
2960
- const environment = flags.e || flags.env || config.environment;
2961
- let input = flags.in || flags.input;
2962
- let searchDepth = 10;
2963
- if (flags.depth) {
2964
- const parsedDepth = parseInt(flags.depth, 10);
2965
- if (!isNaN(parsedDepth)) {
2966
- searchDepth = parsedDepth;
2967
- }
2968
- }
2969
- if (project !== config.project || environment !== config.environment) {
2970
- console.log(`\u26A0\uFE0F Warning: Pushing to ${project}/${environment}`);
2971
- console.log(
2972
- ` This directory is initialized for ${config.project}/${config.environment}`
2973
- );
2974
- }
2975
- let selectedFiles = [];
2976
- if (!input) {
2977
- const cwd = process.cwd();
2978
- const envFiles = await findEnvFiles(cwd, searchDepth);
2979
- if (envFiles.length === 0) {
2980
- console.error("\u274C No .env files found");
2981
- console.error("\u{1F4A1} Create a .env file or specify one with --input <file>");
2982
- process.exit(1);
2983
- } else if (envFiles.length === 1) {
2984
- selectedFiles = [envFiles[0].relativePath];
2985
- console.log(
2986
- `\u{1F4C4} Found ${envFiles[0].relativePath} (${envFiles[0].variableCount} variables)`
2987
- );
4618
+ let selectedFiles = [];
4619
+ if (availableFiles.length === 1) {
4620
+ selectedFiles = [availableFiles[0]];
4621
+ console.log(`\u{1F4C4} Found ${availableFiles[0]} on server`);
4622
+ } else if (pullAll) {
4623
+ selectedFiles = availableFiles;
4624
+ console.log(`\u{1F4C4} Found ${availableFiles.length} files on server`);
2988
4625
  } else {
2989
- console.log(`\u{1F4C4} Found ${envFiles.length} .env files:
4626
+ console.log(`\u{1F4C4} Found ${availableFiles.length} .env files on server:
2990
4627
  `);
2991
- envFiles.forEach((file) => {
2992
- console.log(
2993
- ` \u2022 ${file.relativePath} (${file.variableCount} variables)`
2994
- );
4628
+ availableFiles.forEach((file) => {
4629
+ console.log(` \u2022 ${file}`);
2995
4630
  });
2996
4631
  console.log();
2997
- const pushOption = await dist_default6({
2998
- message: "What would you like to push?",
4632
+ const pullOption = await dist_default6({
4633
+ message: "What would you like to pull?",
2999
4634
  choices: [
3000
4635
  {
3001
4636
  name: "\u2728 All files",
@@ -3007,16 +4642,16 @@ async function pushCommand(args2) {
3007
4642
  }
3008
4643
  ]
3009
4644
  });
3010
- if (pushOption === "all") {
3011
- selectedFiles = envFiles.map((f) => f.relativePath);
4645
+ if (pullOption === "all") {
4646
+ selectedFiles = availableFiles;
3012
4647
  } else {
3013
- const fileChoices = envFiles.map((file) => ({
3014
- name: `${file.relativePath} (${file.variableCount} variables)`,
3015
- value: file.relativePath,
4648
+ const fileChoices = availableFiles.map((file) => ({
4649
+ name: file,
4650
+ value: file,
3016
4651
  checked: false
3017
4652
  }));
3018
- const selected = await dist_default2({
3019
- message: "Select .env file(s) to push:",
4653
+ selectedFiles = await dist_default2({
4654
+ message: "Select .env file(s) to pull:",
3020
4655
  choices: fileChoices,
3021
4656
  validate: (answer) => {
3022
4657
  if (answer.length === 0) {
@@ -3025,469 +4660,307 @@ async function pushCommand(args2) {
3025
4660
  return true;
3026
4661
  }
3027
4662
  });
3028
- selectedFiles = selected;
3029
4663
  }
3030
4664
  }
3031
- } else {
3032
- selectedFiles = [input];
3033
- }
3034
- if (selectedFiles.length === 1) {
3035
- console.log(
3036
- `
3037
- \u{1F4E4} Pushing ${selectedFiles[0]} to ${project}/${environment}...`
3038
- );
3039
- } else {
3040
- console.log(
3041
- `
3042
- \u{1F4E4} Pushing ${selectedFiles.length} files to ${project}/${environment}...
3043
- `
3044
- );
3045
- }
3046
- let successCount = 0;
3047
- let failCount = 0;
3048
- for (const file of selectedFiles) {
3049
- let fileContent = "";
3050
- let fileSize = 0;
3051
- try {
3052
- const inputPath = join5(process.cwd(), file);
3053
- fileContent = await readFile4(inputPath, "utf-8");
3054
- fileSize = Buffer.byteLength(fileContent, "utf-8");
3055
- const variables = parseVariables(fileContent, file);
3056
- if (variables.length === 0) {
3057
- console.log(`\u26A0\uFE0F ${file}: No variables found, skipping`);
3058
- continue;
3059
- }
3060
- const invalidVars = variables.filter((v) => !/^[A-Z0-9_]+$/.test(v.key));
3061
- if (invalidVars.length > 0) {
3062
- console.error(`\u274C ${file}: Invalid variable names found:`);
3063
- invalidVars.forEach(
3064
- (v) => console.error(
3065
- ` \u2022 ${v.key} (must contain only uppercase letters, numbers, and underscores)`
3066
- )
3067
- );
3068
- failCount++;
3069
- continue;
3070
- }
3071
- if (fileSize > 8192) {
3072
- console.error(
3073
- `\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
4665
+ if (selectedFiles.length === 1) {
4666
+ console.log(`
4667
+ \u{1F4E5} Pulling ${selectedFiles[0]}...`);
4668
+ } else {
4669
+ console.log(`
4670
+ \u{1F4E5} Pulling ${selectedFiles.length} files...
4671
+ `);
4672
+ }
4673
+ let successCount = 0;
4674
+ let failCount = 0;
4675
+ for (const filename of selectedFiles) {
4676
+ try {
4677
+ const content = await pullEnvFile(
4678
+ config.host,
4679
+ config.authToken,
4680
+ project,
4681
+ filename
3074
4682
  );
3075
- console.error(" Consider reducing comments or splitting variables");
4683
+ const outputPath = join4(process.cwd(), filename);
4684
+ const dir = dirname(outputPath);
4685
+ if (dir !== process.cwd()) {
4686
+ await mkdir3(dir, { recursive: true });
4687
+ }
4688
+ await writeFile3(outputPath, content, "utf-8");
4689
+ const varCount = countVariables(content);
4690
+ if (selectedFiles.length === 1) {
4691
+ console.log(`\u2705 Wrote ${filename} (${varCount} variables)`);
4692
+ } else {
4693
+ console.log(`\u2705 ${filename}: Pulled (${varCount} variables)`);
4694
+ }
4695
+ successCount++;
4696
+ } catch (error) {
4697
+ const message = error instanceof Error ? error.message : String(error);
4698
+ console.error(`\u274C ${filename}: Failed to pull - ${message}`);
3076
4699
  failCount++;
3077
- continue;
3078
- }
3079
- await pushEnvFile(
3080
- config.host,
3081
- config.authToken,
3082
- project,
3083
- environment,
3084
- fileContent,
3085
- file
3086
- // Use full relative path, not just filename
3087
- );
3088
- if (selectedFiles.length === 1) {
3089
- console.log(
3090
- `\u2705 Pushed ${file} (${variables.length} variables) to ${project}/${environment}`
3091
- );
3092
- } else {
3093
- console.log(`\u2705 ${file}: Pushed (${variables.length} variables)`);
3094
4700
  }
3095
- successCount++;
3096
- } catch (error) {
3097
- const message = error instanceof Error ? error.message : String(error);
3098
- console.error(`\u274C ${file}: Failed to push - ${message}`);
3099
- failCount++;
3100
4701
  }
3101
- }
3102
- if (selectedFiles.length > 1) {
3103
- console.log(`
4702
+ if (selectedFiles.length > 1) {
4703
+ console.log(`
3104
4704
  \u{1F4CA} Summary:`);
3105
- console.log(` \u2705 Success: ${successCount} file(s)`);
3106
- if (failCount > 0) {
3107
- console.log(` \u274C Failed: ${failCount} file(s)`);
3108
- }
3109
- }
3110
- if (failCount > 0) {
3111
- process.exit(1);
3112
- }
3113
- }
3114
- function parseVariables(content, filename) {
3115
- const variables = [];
3116
- if (filename.endsWith(".json")) {
3117
- try {
3118
- const obj = JSON.parse(content);
3119
- for (const [key, value] of Object.entries(obj)) {
3120
- variables.push({ key, value: String(value) });
3121
- }
3122
- return variables;
3123
- } catch (error) {
3124
- throw new Error("Invalid JSON file");
3125
- }
3126
- }
3127
- const lines = content.split("\n");
3128
- let pendingComment;
3129
- for (let i = 0; i < lines.length; i++) {
3130
- const line = lines[i];
3131
- const trimmed = line.trim();
3132
- if (trimmed.startsWith("#")) {
3133
- const commentText = trimmed.substring(1).trim();
3134
- if (commentText && !commentText.match(/^[=\-]+$/)) {
3135
- pendingComment = commentText;
3136
- }
3137
- continue;
3138
- }
3139
- if (!trimmed) {
3140
- pendingComment = void 0;
3141
- continue;
3142
- }
3143
- const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
3144
- if (match) {
3145
- const [, key, valueWithComment] = match;
3146
- const inlineCommentMatch = valueWithComment.match(
3147
- /^([^#]*?)\s*#\s*(.+)$/
3148
- );
3149
- let value;
3150
- let comment = pendingComment;
3151
- if (inlineCommentMatch) {
3152
- value = inlineCommentMatch[1].trim();
3153
- comment = inlineCommentMatch[2].trim();
3154
- } else {
3155
- value = valueWithComment.trim();
4705
+ if (successCount > 0) {
4706
+ console.log(` \u2705 Success: ${successCount} file(s)`);
3156
4707
  }
3157
- const cleanValue = value.replace(/^["']|["']$/g, "");
3158
- const variable = { key, value: cleanValue };
3159
- if (comment) {
3160
- variable.comment = comment;
4708
+ if (failCount > 0) {
4709
+ console.log(` \u274C Failed: ${failCount} file(s)`);
3161
4710
  }
3162
- variables.push(variable);
3163
- pendingComment = void 0;
3164
4711
  }
3165
- }
3166
- return variables;
3167
- }
3168
-
3169
- // src/commands/init.ts
3170
- async function initCommand(args2) {
3171
- const flags = {};
3172
- for (let i = 0; i < args2.length; i++) {
3173
- if (args2[i].startsWith("-")) {
3174
- const key = args2[i].replace(/^-+/, "");
3175
- const value = args2[i + 1];
3176
- if (value && !value.startsWith("-")) {
3177
- flags[key] = value;
3178
- i++;
3179
- } else {
3180
- flags[key] = "true";
3181
- }
4712
+ if (failCount > 0 && successCount === 0) {
4713
+ process.exit(1);
3182
4714
  }
3183
- }
3184
- const configExists = await hasLocalConfig();
3185
- if (configExists && !flags.force && !flags.f) {
3186
- const projectConfig = await loadProjectConfig();
3187
- if (projectConfig) {
3188
- console.log("\u{1F4C1} JSSM project already initialized\n");
3189
- console.log(` Project: ${projectConfig.project}`);
3190
- console.log(` Environment: ${projectConfig.environment}`);
3191
- console.log();
3192
- try {
3193
- const action = await dist_default6({
3194
- message: "What would you like to do?",
3195
- choices: [
3196
- {
3197
- name: "\u{1F4E5} Pull - Download .env files from server",
3198
- value: "pull"
3199
- },
3200
- {
3201
- name: "\u{1F4E4} Push - Upload local .env files to server",
3202
- value: "push"
3203
- },
3204
- {
3205
- name: "\u{1F504} Reinitialize - Set up a different project/environment",
3206
- value: "reinit"
3207
- },
3208
- { name: "\u274C Cancel", value: "cancel" }
3209
- ]
3210
- });
3211
- if (action === "pull") {
3212
- await pullCommand([]);
3213
- return;
3214
- } else if (action === "push") {
3215
- await pushCommand([]);
3216
- return;
3217
- } else if (action === "cancel") {
3218
- console.log("\n\u{1F44B} Cancelled");
3219
- return;
3220
- }
3221
- console.log();
3222
- } catch (error) {
3223
- if (error.name === "ExitPromptError") {
3224
- console.log("\n\u{1F44B} Cancelled");
3225
- return;
3226
- }
3227
- throw error;
4715
+ } catch (error) {
4716
+ const message = error instanceof Error ? error.message : String(error);
4717
+ console.error("\u274C Failed to pull .env files:", message);
4718
+ process.exit(1);
4719
+ }
4720
+ }
4721
+ function countVariables(content) {
4722
+ return content.split("\n").filter((line) => {
4723
+ const trimmed = line.trim();
4724
+ return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
4725
+ }).length;
4726
+ }
4727
+
4728
+ // src/commands/push.ts
4729
+ import { readFile as readFile4 } from "fs/promises";
4730
+ import { join as join5 } from "path";
4731
+ async function pushCommand2(args2) {
4732
+ const flags = {};
4733
+ for (let i = 0; i < args2.length; i++) {
4734
+ if (args2[i].startsWith("-")) {
4735
+ const key = args2[i].replace(/^-+/, "");
4736
+ const value = args2[i + 1];
4737
+ if (value && !value.startsWith("-")) {
4738
+ flags[key] = value;
4739
+ i++;
3228
4740
  }
3229
4741
  }
3230
4742
  }
3231
- console.log("\u{1F680} JSSM Project Initialization\n");
3232
- console.log("\u{1F510} Checking authentication...");
3233
- const authData = await loadAuthData();
3234
- if (!authData) {
3235
- console.log("\n\u274C You are not logged in");
3236
- console.log("\u{1F4A1} Please login or register first:");
3237
- console.log(" jssm login");
3238
- console.log(" jssm register");
4743
+ const config = await resolveConfig();
4744
+ if (!config) {
4745
+ console.error("\u274C No .jssm configuration found in current directory.");
4746
+ console.error('\u{1F4A1} Run "jssm init -p <project>" to initialize.');
3239
4747
  process.exit(1);
3240
4748
  }
3241
- console.log(`\u2705 Logged in as ${authData.user.email}
3242
- `);
3243
- const globalConfig = await loadGlobalConfig();
3244
- const host = flags.host || flags.h || globalConfig.host;
3245
- if (!host) {
3246
- console.error("\u274C Host URL is required");
3247
- console.error("\u{1F4A1} Set it globally: jssm config set host <url>");
4749
+ const { valid, errors } = validateResolvedConfig(config);
4750
+ if (!valid) {
4751
+ console.error("\u274C Configuration is incomplete:");
4752
+ errors.forEach((e) => console.error(` \u2022 ${e}`));
3248
4753
  process.exit(1);
3249
4754
  }
3250
- const authToken = authData.token;
3251
- console.log("\u{1F50D} Analyzing repository...");
3252
- const cwd = process.cwd();
3253
- const repoType = await getRepositoryType(cwd);
3254
- console.log(` Repository type: ${repoType}`);
3255
- const envFiles = await findEnvFiles(cwd);
3256
- if (envFiles.length > 0) {
3257
- console.log(` Found ${envFiles.length} .env file(s)`);
3258
- } else {
3259
- console.log(` No .env files found`);
4755
+ const project = flags.p || flags.project || config.project;
4756
+ const environment = flags.e || flags.env;
4757
+ let input = flags.in || flags.input;
4758
+ let searchDepth = 10;
4759
+ if (flags.depth) {
4760
+ const parsedDepth = parseInt(flags.depth, 10);
4761
+ if (!isNaN(parsedDepth)) {
4762
+ searchDepth = parsedDepth;
4763
+ }
3260
4764
  }
3261
- console.log();
3262
- let projectName;
3263
- let environmentName;
3264
- try {
3265
- console.log("\u{1F4E6} Loading your projects...");
3266
- const projects = await getProjects(host, authToken);
3267
- if (projects.length === 0) {
3268
- console.log(" No existing projects found\n");
3269
- projectName = await dist_default4({
3270
- message: "Project name:",
3271
- validate: (value) => {
3272
- if (!value)
3273
- return "Project name is required";
3274
- if (!/^[a-z0-9-_.]+$/.test(value)) {
3275
- return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
3276
- }
3277
- return true;
3278
- }
3279
- });
3280
- console.log(`
3281
- \u{1F4E6} Creating project "${projectName}"...`);
3282
- await createProject(host, authToken, projectName, repoType);
3283
- console.log(`\u2705 Project created
3284
- `);
4765
+ if (project !== config.project) {
4766
+ console.log(`\u26A0\uFE0F Warning: Pushing to ${project}`);
4767
+ console.log(` This directory is initialized for ${config.project}`);
4768
+ }
4769
+ let selectedFiles = [];
4770
+ if (!input) {
4771
+ const cwd = process.cwd();
4772
+ const envFiles = await findEnvFiles(cwd, searchDepth);
4773
+ if (envFiles.length === 0) {
4774
+ console.error("\u274C No .env files found");
4775
+ console.error("\u{1F4A1} Create a .env file or specify one with --input <file>");
4776
+ process.exit(1);
4777
+ } else if (envFiles.length === 1) {
4778
+ selectedFiles = [envFiles[0].relativePath];
4779
+ console.log(
4780
+ `\u{1F4C4} Found ${envFiles[0].relativePath} (${envFiles[0].variableCount} variables)`
4781
+ );
3285
4782
  } else {
3286
- const projectChoices = [
3287
- ...projects.map((p) => ({ name: p.name, value: p.name })),
3288
- { name: "+ Create new project", value: "__new__" }
3289
- ];
3290
- const selectedProject = await dist_default6({
3291
- message: "Select a project:",
3292
- choices: projectChoices
3293
- });
3294
- if (selectedProject === "__new__") {
3295
- projectName = await dist_default4({
3296
- message: "New project name:",
3297
- validate: (value) => {
3298
- if (!value)
3299
- return "Project name is required";
3300
- if (!/^[a-z0-9-_.]+$/.test(value)) {
3301
- return "Project name must contain only lowercase letters, numbers, hyphens, underscores, and dots";
3302
- }
3303
- if (projects.some((p) => p.name === value)) {
3304
- return "Project already exists";
3305
- }
3306
- return true;
3307
- }
3308
- });
3309
- console.log(`
3310
- \u{1F4E6} Creating project "${projectName}"...`);
3311
- await createProject(host, authToken, projectName, repoType);
3312
- console.log(`\u2705 Project created
4783
+ console.log(`\u{1F4C4} Found ${envFiles.length} .env files:
3313
4784
  `);
3314
- } else {
3315
- projectName = selectedProject;
3316
- }
3317
- }
3318
- console.log("\u{1F30D} Loading environments...");
3319
- const environments = await getEnvironments(host, authToken, projectName);
3320
- if (environments.length === 0) {
3321
- console.log(" No existing environments found\n");
3322
- environmentName = await dist_default4({
3323
- message: "Environment name:",
3324
- default: "development",
3325
- validate: (value) => {
3326
- if (!value)
3327
- return "Environment name is required";
3328
- if (!/^[a-z0-9-_]+$/.test(value)) {
3329
- return "Environment name must contain only lowercase letters, numbers, hyphens, and underscores";
3330
- }
3331
- return true;
3332
- }
4785
+ envFiles.forEach((file) => {
4786
+ console.log(
4787
+ ` \u2022 ${file.relativePath} (${file.variableCount} variables)`
4788
+ );
3333
4789
  });
3334
- console.log(`
3335
- \u{1F30D} Creating environment "${environmentName}"...`);
3336
- await createEnvironment(host, authToken, projectName, environmentName);
3337
- console.log(`\u2705 Environment created
3338
- `);
3339
- } else {
3340
- const envChoices = [
3341
- ...environments.map((e) => ({ name: e.name, value: e.name })),
3342
- { name: "+ Create new environment", value: "__new__" }
3343
- ];
3344
- const selectedEnv = await dist_default6({
3345
- message: "Select an environment:",
3346
- choices: envChoices
4790
+ console.log();
4791
+ const pushOption = await dist_default6({
4792
+ message: "What would you like to push?",
4793
+ choices: [
4794
+ {
4795
+ name: "\u2728 All files",
4796
+ value: "all"
4797
+ },
4798
+ {
4799
+ name: "\u{1F4C1} Select specific files",
4800
+ value: "specific"
4801
+ }
4802
+ ]
3347
4803
  });
3348
- if (selectedEnv === "__new__") {
3349
- environmentName = await dist_default4({
3350
- message: "New environment name:",
3351
- default: "development",
3352
- validate: (value) => {
3353
- if (!value)
3354
- return "Environment name is required";
3355
- if (!/^[a-z0-9-_]+$/.test(value)) {
3356
- return "Environment name must contain only lowercase letters, numbers, hyphens, and underscores";
3357
- }
3358
- if (environments.some((e) => e.name === value)) {
3359
- return "Environment already exists";
4804
+ if (pushOption === "all") {
4805
+ selectedFiles = envFiles.map((f) => f.relativePath);
4806
+ } else {
4807
+ const fileChoices = envFiles.map((file) => ({
4808
+ name: `${file.relativePath} (${file.variableCount} variables)`,
4809
+ value: file.relativePath,
4810
+ checked: false
4811
+ }));
4812
+ const selected = await dist_default2({
4813
+ message: "Select .env file(s) to push:",
4814
+ choices: fileChoices,
4815
+ validate: (answer) => {
4816
+ if (answer.length === 0) {
4817
+ return "Please select at least one file";
3360
4818
  }
3361
4819
  return true;
3362
4820
  }
3363
4821
  });
3364
- console.log(`
3365
- \u{1F30D} Creating environment "${environmentName}"...`);
3366
- await createEnvironment(host, authToken, projectName, environmentName);
3367
- console.log(`\u2705 Environment created
3368
- `);
3369
- } else {
3370
- environmentName = selectedEnv;
4822
+ selectedFiles = selected;
3371
4823
  }
3372
4824
  }
3373
- if (envFiles.length > 0) {
3374
- console.log("\u{1F4C4} .env files detected:");
3375
- envFiles.forEach((file) => {
3376
- console.log(
3377
- ` ${file.relativePath} (${file.variableCount} variables)`
4825
+ } else {
4826
+ selectedFiles = [input];
4827
+ }
4828
+ const envSuffix = environment ? ` (env: ${environment})` : "";
4829
+ if (selectedFiles.length === 1) {
4830
+ console.log(
4831
+ `
4832
+ \u{1F4E4} Pushing ${selectedFiles[0]} to ${project}${envSuffix}...`
4833
+ );
4834
+ } else {
4835
+ console.log(
4836
+ `
4837
+ \u{1F4E4} Pushing ${selectedFiles.length} files to ${project}${envSuffix}...
4838
+ `
4839
+ );
4840
+ }
4841
+ let successCount = 0;
4842
+ let failCount = 0;
4843
+ for (const file of selectedFiles) {
4844
+ let fileContent = "";
4845
+ let fileSize = 0;
4846
+ try {
4847
+ const inputPath = join5(process.cwd(), file);
4848
+ fileContent = await readFile4(inputPath, "utf-8");
4849
+ fileSize = Buffer.byteLength(fileContent, "utf-8");
4850
+ const variables = parseVariables(fileContent, file);
4851
+ if (variables.length === 0) {
4852
+ console.log(`\u26A0\uFE0F ${file}: No variables found, skipping`);
4853
+ continue;
4854
+ }
4855
+ const invalidVars = variables.filter((v) => !/^[A-Z0-9_]+$/.test(v.key));
4856
+ if (invalidVars.length > 0) {
4857
+ console.error(`\u274C ${file}: Invalid variable names found:`);
4858
+ invalidVars.forEach(
4859
+ (v) => console.error(
4860
+ ` \u2022 ${v.key} (must contain only uppercase letters, numbers, and underscores)`
4861
+ )
3378
4862
  );
3379
- });
3380
- console.log();
3381
- const shouldUpload = await dist_default3({
3382
- message: "Would you like to upload variables from .env files?",
3383
- default: true
3384
- });
3385
- if (shouldUpload) {
3386
- let selectedFileInfos;
3387
- if (repoType === "monorepo" && envFiles.length > 1) {
3388
- const fileChoices = envFiles.map((file) => ({
3389
- name: `${file.relativePath} (${file.variableCount} variables)`,
3390
- value: file.relativePath
3391
- }));
3392
- const selectedPaths = await dist_default2({
3393
- message: "Select .env files to upload:",
3394
- choices: fileChoices,
3395
- validate: (answer) => {
3396
- if (answer.length === 0) {
3397
- return "Please select at least one file";
3398
- }
3399
- return true;
3400
- }
3401
- });
3402
- selectedFileInfos = envFiles.filter(
3403
- (f) => selectedPaths.includes(f.relativePath)
3404
- );
3405
- } else {
3406
- selectedFileInfos = [envFiles[0]];
3407
- }
3408
- const totalVars = selectedFileInfos.reduce(
3409
- (sum, f) => sum + f.variableCount,
3410
- 0
4863
+ failCount++;
4864
+ continue;
4865
+ }
4866
+ if (fileSize > 8192) {
4867
+ console.error(
4868
+ `\u274C ${file}: File size (${fileSize} bytes) exceeds maximum (8192 bytes)`
3411
4869
  );
4870
+ console.error(" Consider reducing comments or splitting variables");
4871
+ failCount++;
4872
+ continue;
4873
+ }
4874
+ await pushEnvFile(
4875
+ config.host,
4876
+ config.authToken,
4877
+ project,
4878
+ fileContent,
4879
+ file,
4880
+ // Use full relative path, not just filename
4881
+ environment
4882
+ // Optional environment tag
4883
+ );
4884
+ if (selectedFiles.length === 1) {
3412
4885
  console.log(
3413
- `
3414
- \u{1F4CB} Files to upload (${selectedFileInfos.length} files, ${totalVars} total variables):`
4886
+ `\u2705 Pushed ${file} (${variables.length} variables) to ${project}${envSuffix}`
3415
4887
  );
3416
- selectedFileInfos.forEach((f) => {
3417
- console.log(` ${f.relativePath} (${f.variableCount} variables)`);
3418
- });
3419
- const confirmUpload = await dist_default3({
3420
- message: "\nProceed with upload?",
3421
- default: true
3422
- });
3423
- if (confirmUpload) {
3424
- console.log(`
3425
- \u2B06\uFE0F Uploading ${selectedFileInfos.length} file(s)...`);
3426
- let successCount = 0;
3427
- let failCount = 0;
3428
- for (const fileInfo of selectedFileInfos) {
3429
- try {
3430
- const { readFile: readFileAsync } = await import("fs/promises");
3431
- const content = await readFileAsync(fileInfo.path, "utf-8");
3432
- await pushEnvFile(
3433
- host,
3434
- authToken,
3435
- projectName,
3436
- environmentName,
3437
- content,
3438
- fileInfo.relativePath
3439
- );
3440
- console.log(` \u2705 ${fileInfo.relativePath}`);
3441
- successCount++;
3442
- } catch (error) {
3443
- console.log(` \u274C ${fileInfo.relativePath}: ${error.message}`);
3444
- failCount++;
3445
- }
3446
- }
3447
- if (failCount === 0) {
3448
- console.log(`\u2705 All files uploaded successfully`);
3449
- } else {
3450
- console.log(`
3451
- \u26A0\uFE0F ${successCount} succeeded, ${failCount} failed`);
3452
- }
3453
- } else {
3454
- console.log("\n\u23ED\uFE0F Skipping file upload");
3455
- }
4888
+ } else {
4889
+ console.log(`\u2705 ${file}: Pushed (${variables.length} variables)`);
3456
4890
  }
4891
+ successCount++;
4892
+ } catch (error) {
4893
+ const message = error instanceof Error ? error.message : String(error);
4894
+ console.error(`\u274C ${file}: Failed to push - ${message}`);
4895
+ failCount++;
3457
4896
  }
3458
- const namespace = flags.namespace || globalConfig.namespace || DEFAULT_NAMESPACE;
3459
- const projectConfig = {
3460
- project: projectName,
3461
- environment: environmentName
3462
- };
3463
- if (flags.host && flags.host !== globalConfig.host) {
3464
- projectConfig.host = flags.host;
3465
- }
3466
- if (flags.namespace && flags.namespace !== globalConfig.namespace) {
3467
- projectConfig.namespace = flags.namespace;
3468
- }
3469
- await saveProjectConfig(projectConfig);
3470
- console.log(`
3471
- \u2705 Project initialized successfully!`);
3472
- console.log(` Config file: .jssm`);
3473
- console.log(` Project: ${projectName}`);
3474
- console.log(` Environment: ${environmentName}`);
3475
- console.log(` Repository type: ${repoType}`);
4897
+ }
4898
+ if (selectedFiles.length > 1) {
3476
4899
  console.log(`
3477
- \u{1F4A1} Next steps:`);
3478
- console.log(` - Run "jssm pull" to fetch variables`);
3479
- console.log(` - Run "jssm sync" to sync variables to .env`);
3480
- console.log(` - Run "jssm push" to upload local .env changes`);
3481
- } catch (error) {
3482
- if (error.name === "ExitPromptError") {
3483
- console.log("\n\u274C Initialization cancelled");
3484
- process.exit(0);
4900
+ \u{1F4CA} Summary:`);
4901
+ console.log(` \u2705 Success: ${successCount} file(s)`);
4902
+ if (failCount > 0) {
4903
+ console.log(` \u274C Failed: ${failCount} file(s)`);
3485
4904
  }
3486
- console.error(`
3487
- \u274C Error: ${error.message}`);
4905
+ }
4906
+ if (failCount > 0) {
3488
4907
  process.exit(1);
3489
4908
  }
3490
4909
  }
4910
+ function parseVariables(content, filename) {
4911
+ const variables = [];
4912
+ if (filename.endsWith(".json")) {
4913
+ try {
4914
+ const obj = JSON.parse(content);
4915
+ for (const [key, value] of Object.entries(obj)) {
4916
+ variables.push({ key, value: String(value) });
4917
+ }
4918
+ return variables;
4919
+ } catch (error) {
4920
+ throw new Error("Invalid JSON file");
4921
+ }
4922
+ }
4923
+ const lines = content.split("\n");
4924
+ let pendingComment;
4925
+ for (let i = 0; i < lines.length; i++) {
4926
+ const line = lines[i];
4927
+ const trimmed = line.trim();
4928
+ if (trimmed.startsWith("#")) {
4929
+ const commentText = trimmed.substring(1).trim();
4930
+ if (commentText && !commentText.match(/^[=\-]+$/)) {
4931
+ pendingComment = commentText;
4932
+ }
4933
+ continue;
4934
+ }
4935
+ if (!trimmed) {
4936
+ pendingComment = void 0;
4937
+ continue;
4938
+ }
4939
+ const match = trimmed.match(/^([A-Z0-9_]+)=(.*)$/);
4940
+ if (match) {
4941
+ const [, key, valueWithComment] = match;
4942
+ const inlineCommentMatch = valueWithComment.match(
4943
+ /^([^#]*?)\s*#\s*(.+)$/
4944
+ );
4945
+ let value;
4946
+ let comment = pendingComment;
4947
+ if (inlineCommentMatch) {
4948
+ value = inlineCommentMatch[1].trim();
4949
+ comment = inlineCommentMatch[2].trim();
4950
+ } else {
4951
+ value = valueWithComment.trim();
4952
+ }
4953
+ const cleanValue = value.replace(/^["']|["']$/g, "");
4954
+ const variable = { key, value: cleanValue };
4955
+ if (comment) {
4956
+ variable.comment = comment;
4957
+ }
4958
+ variables.push(variable);
4959
+ pendingComment = void 0;
4960
+ }
4961
+ }
4962
+ return variables;
4963
+ }
3491
4964
 
3492
4965
  // src/commands/sync.ts
3493
4966
  import { writeFile as writeFile4 } from "fs/promises";
@@ -3521,151 +4994,29 @@ async function syncCommand() {
3521
4994
  const trimmed = line.trim();
3522
4995
  return trimmed && !trimmed.startsWith("#") && trimmed.includes("=");
3523
4996
  }).length;
3524
- console.log(`\u2705 Synced .env file (${varCount} variables)`);
3525
- console.log(` Project: ${config.project}`);
3526
- console.log(` Environment: ${config.environment}`);
3527
- } catch (error) {
3528
- const message = error instanceof Error ? error.message : String(error);
3529
- console.error("\u274C Failed to sync .env file:", message);
3530
- process.exit(1);
3531
- }
3532
- }
3533
-
3534
- // src/commands/project.ts
3535
- init_auth();
3536
- async function projectCommand(args2) {
3537
- const subcommand = args2[0];
3538
- if (subcommand === "create") {
3539
- await createProjectCommand(args2.slice(1));
3540
- } else if (subcommand === "list" || subcommand === "ls") {
3541
- await listProjectsCommand();
3542
- } else {
3543
- printProjectHelp();
3544
- }
3545
- }
3546
- async function createProjectCommand(args2) {
3547
- const flags = {};
3548
- for (let i = 0; i < args2.length; i++) {
3549
- if (args2[i].startsWith("-")) {
3550
- const key = args2[i].replace(/^-+/, "");
3551
- const value = args2[i + 1];
3552
- if (value && !value.startsWith("-")) {
3553
- flags[key] = value;
3554
- i++;
3555
- }
3556
- }
3557
- }
3558
- const name = flags.n || flags.name || args2[0];
3559
- const host = flags.host;
3560
- if (!name) {
3561
- console.error("Usage: jssm project create <name> [--host <api_url>]");
3562
- console.error("\nOptions:");
3563
- console.error(" -n, --name Project name");
3564
- console.error(" --host API host URL (optional if config exists)");
3565
- process.exit(1);
3566
- }
3567
- const authToken = await getAuthToken();
3568
- if (!authToken) {
3569
- console.error("\u274C Not logged in");
3570
- console.error("\u{1F4A1} Run: jssm login");
3571
- process.exit(1);
3572
- }
3573
- const globalConfig = await loadGlobalConfig();
3574
- const projectConfig = await loadProjectConfig();
3575
- const finalHost = host || projectConfig?.host || globalConfig.host;
3576
- if (!finalHost) {
3577
- console.error("\u274C Host is required");
3578
- console.error("\u{1F4A1} Set globally: jssm config set host <url>");
3579
- process.exit(1);
3580
- }
3581
- try {
3582
- console.log(`\u{1F4E6} Creating project "${name}"...`);
3583
- const project = await createProject(finalHost, authToken, name);
3584
- console.log(`\u2705 Project "${name}" created successfully`);
3585
- console.log(` ID: ${project._id}`);
3586
- console.log(` Created: ${new Date(project.createdAt).toLocaleString()}`);
3587
- console.log("\n\u{1F4A1} Next steps:");
3588
- console.log(
3589
- ` - Run "jssm env create <env-name> -p ${name}" to create an environment`
3590
- );
3591
- console.log(
3592
- ` - Run "jssm init -p ${name} -e <env-name>" to configure CLI`
3593
- );
3594
- } catch (error) {
3595
- const message = error instanceof Error ? error.message : String(error);
3596
- console.error(`\u274C Failed to create project: ${message}`);
3597
- process.exit(1);
3598
- }
3599
- }
3600
- async function listProjectsCommand() {
3601
- const authToken = await getAuthToken();
3602
- if (!authToken) {
3603
- console.error("\u274C Not logged in");
3604
- console.error("\u{1F4A1} Run: jssm login");
3605
- process.exit(1);
3606
- }
3607
- const globalConfig = await loadGlobalConfig();
3608
- const projectConfig = await loadProjectConfig();
3609
- const host = projectConfig?.host || globalConfig.host;
3610
- if (!host) {
3611
- console.error("\u274C Host is required");
3612
- console.error("\u{1F4A1} Set globally: jssm config set host <url>");
3613
- process.exit(1);
3614
- }
3615
- try {
3616
- console.log("\u{1F4E6} Fetching projects...\n");
3617
- const projects = await getProjects(host, authToken);
3618
- if (projects.length === 0) {
3619
- console.log("No projects found.");
3620
- console.log("\u{1F4A1} Create one with: jssm project create <name>");
3621
- return;
3622
- }
3623
- console.log(`Found ${projects.length} project(s):
3624
- `);
3625
- projects.forEach((project) => {
3626
- console.log(` \u2022 ${project.name}`);
3627
- console.log(` ID: ${project._id}`);
3628
- console.log(
3629
- ` Created: ${new Date(project.createdAt).toLocaleString()}`
3630
- );
3631
- console.log("");
3632
- });
4997
+ console.log(`\u2705 Synced .env file (${varCount} variables)`);
4998
+ console.log(` Project: ${config.project}`);
4999
+ console.log(` Environment: ${config.environment}`);
3633
5000
  } catch (error) {
3634
5001
  const message = error instanceof Error ? error.message : String(error);
3635
- console.error(`\u274C Failed to list projects: ${message}`);
5002
+ console.error("\u274C Failed to sync .env file:", message);
3636
5003
  process.exit(1);
3637
5004
  }
3638
5005
  }
3639
- function printProjectHelp() {
3640
- console.log(`
3641
- JSSM Project Management
3642
-
3643
- Usage:
3644
- jssm project <command> [options]
3645
-
3646
- Commands:
3647
- create Create a new project
3648
- list List all projects (alias: ls)
3649
-
3650
- Examples:
3651
- jssm project create my-app
3652
- jssm project list
3653
- `);
3654
- }
3655
5006
 
3656
- // src/commands/env.ts
5007
+ // src/commands/project.ts
3657
5008
  init_auth();
3658
- async function envCommand(args2) {
5009
+ async function projectCommand(args2) {
3659
5010
  const subcommand = args2[0];
3660
5011
  if (subcommand === "create") {
3661
- await createEnvCommand(args2.slice(1));
5012
+ await createProjectCommand(args2.slice(1));
3662
5013
  } else if (subcommand === "list" || subcommand === "ls") {
3663
- await listEnvsCommand(args2.slice(1));
5014
+ await listProjectsCommand();
3664
5015
  } else {
3665
- printEnvHelp();
5016
+ printProjectHelp();
3666
5017
  }
3667
5018
  }
3668
- async function createEnvCommand(args2) {
5019
+ async function createProjectCommand(args2) {
3669
5020
  const flags = {};
3670
5021
  for (let i = 0; i < args2.length; i++) {
3671
5022
  if (args2[i].startsWith("-")) {
@@ -3678,18 +5029,12 @@ async function createEnvCommand(args2) {
3678
5029
  }
3679
5030
  }
3680
5031
  const name = flags.n || flags.name || args2[0];
3681
- const project = flags.p || flags.project;
3682
5032
  const host = flags.host;
3683
5033
  if (!name) {
3684
- console.error(
3685
- "Usage: jssm env create <name> -p <project> [--host <api_url>]"
3686
- );
5034
+ console.error("Usage: jssm project create <name> [--host <api_url>]");
3687
5035
  console.error("\nOptions:");
3688
- console.error(" -n, --name Environment name");
3689
- console.error(" -p, --project Project name (required)");
3690
- console.error(
3691
- " --host API host URL (optional if global config exists)"
3692
- );
5036
+ console.error(" -n, --name Project name");
5037
+ console.error(" --host API host URL (optional if config exists)");
3693
5038
  process.exit(1);
3694
5039
  }
3695
5040
  const authToken = await getAuthToken();
@@ -3700,56 +5045,32 @@ async function createEnvCommand(args2) {
3700
5045
  }
3701
5046
  const globalConfig = await loadGlobalConfig();
3702
5047
  const projectConfig = await loadProjectConfig();
3703
- const finalProject = project || projectConfig?.project;
3704
5048
  const finalHost = host || projectConfig?.host || globalConfig.host;
3705
- if (!finalProject) {
3706
- console.error("\u274C Project name is required");
3707
- console.error('\u{1F4A1} Either provide -p <project>, or run "jssm init" first');
3708
- process.exit(1);
3709
- }
3710
5049
  if (!finalHost) {
3711
5050
  console.error("\u274C Host is required");
3712
5051
  console.error("\u{1F4A1} Set globally: jssm config set host <url>");
3713
5052
  process.exit(1);
3714
5053
  }
3715
5054
  try {
5055
+ console.log(`\u{1F4E6} Creating project "${name}"...`);
5056
+ const project = await createProject(finalHost, authToken, name);
5057
+ console.log(`\u2705 Project "${name}" created successfully`);
5058
+ console.log(` ID: ${project._id}`);
5059
+ console.log(` Created: ${new Date(project.createdAt).toLocaleString()}`);
5060
+ console.log("\n\u{1F4A1} Next steps:");
3716
5061
  console.log(
3717
- `\u{1F30D} Creating environment "${name}" in project "${finalProject}"...`
3718
- );
3719
- const env = await createEnvironment(
3720
- finalHost,
3721
- authToken,
3722
- finalProject,
3723
- name
5062
+ ` - Run "jssm env create <env-name> -p ${name}" to create an environment`
3724
5063
  );
3725
- console.log(`\u2705 Environment "${name}" created successfully`);
3726
- console.log(` ID: ${env._id}`);
3727
- console.log(` Project: ${finalProject}`);
3728
- console.log(` Created: ${new Date(env.createdAt).toLocaleString()}`);
3729
- console.log("\n\u{1F4A1} Next steps:");
3730
5064
  console.log(
3731
- ` - Run "jssm init -p ${finalProject} -e ${name}" to configure CLI`
5065
+ ` - Run "jssm init -p ${name} -e <env-name>" to configure CLI`
3732
5066
  );
3733
- console.log(" - Add variables via the web UI or API");
3734
5067
  } catch (error) {
3735
5068
  const message = error instanceof Error ? error.message : String(error);
3736
- console.error(`\u274C Failed to create environment: ${message}`);
5069
+ console.error(`\u274C Failed to create project: ${message}`);
3737
5070
  process.exit(1);
3738
5071
  }
3739
5072
  }
3740
- async function listEnvsCommand(args2) {
3741
- const flags = {};
3742
- for (let i = 0; i < args2.length; i++) {
3743
- if (args2[i].startsWith("-")) {
3744
- const key = args2[i].replace(/^-+/, "");
3745
- const value = args2[i + 1];
3746
- if (value && !value.startsWith("-")) {
3747
- flags[key] = value;
3748
- i++;
3749
- }
3750
- }
3751
- }
3752
- const project = flags.p || flags.project;
5073
+ async function listProjectsCommand() {
3753
5074
  const authToken = await getAuthToken();
3754
5075
  if (!authToken) {
3755
5076
  console.error("\u274C Not logged in");
@@ -3758,52 +5079,50 @@ async function listEnvsCommand(args2) {
3758
5079
  }
3759
5080
  const globalConfig = await loadGlobalConfig();
3760
5081
  const projectConfig = await loadProjectConfig();
3761
- const finalProject = project || projectConfig?.project;
3762
5082
  const host = projectConfig?.host || globalConfig.host;
3763
- if (!finalProject || !host) {
3764
- console.error("\u274C Project and host are required");
5083
+ if (!host) {
5084
+ console.error("\u274C Host is required");
3765
5085
  console.error("\u{1F4A1} Set globally: jssm config set host <url>");
3766
5086
  process.exit(1);
3767
5087
  }
3768
5088
  try {
3769
- console.log(`\u{1F30D} Fetching environments for project "${finalProject}"...
3770
- `);
3771
- const environments = await getEnvironments(host, authToken, finalProject);
3772
- if (environments.length === 0) {
3773
- console.log("No environments found.");
3774
- console.log(
3775
- `\u{1F4A1} Create one with: jssm env create <name> -p ${finalProject}`
3776
- );
5089
+ console.log("\u{1F4E6} Fetching projects...\n");
5090
+ const projects = await getProjects(host, authToken);
5091
+ if (projects.length === 0) {
5092
+ console.log("No projects found.");
5093
+ console.log("\u{1F4A1} Create one with: jssm project create <name>");
3777
5094
  return;
3778
5095
  }
3779
- console.log(`Found ${environments.length} environment(s):
5096
+ console.log(`Found ${projects.length} project(s):
3780
5097
  `);
3781
- environments.forEach((env) => {
3782
- console.log(` \u2022 ${env.name}`);
3783
- console.log(` ID: ${env._id}`);
3784
- console.log(` Created: ${new Date(env.createdAt).toLocaleString()}`);
5098
+ projects.forEach((project) => {
5099
+ console.log(` \u2022 ${project.name}`);
5100
+ console.log(` ID: ${project._id}`);
5101
+ console.log(
5102
+ ` Created: ${new Date(project.createdAt).toLocaleString()}`
5103
+ );
3785
5104
  console.log("");
3786
5105
  });
3787
5106
  } catch (error) {
3788
5107
  const message = error instanceof Error ? error.message : String(error);
3789
- console.error(`\u274C Failed to list environments: ${message}`);
5108
+ console.error(`\u274C Failed to list projects: ${message}`);
3790
5109
  process.exit(1);
3791
5110
  }
3792
5111
  }
3793
- function printEnvHelp() {
5112
+ function printProjectHelp() {
3794
5113
  console.log(`
3795
- JSSM Environment Management
5114
+ JSSM Project Management
3796
5115
 
3797
5116
  Usage:
3798
- jssm env <command> [options]
5117
+ jssm project <command> [options]
3799
5118
 
3800
5119
  Commands:
3801
- create Create a new environment
3802
- list List all environments (alias: ls)
5120
+ create Create a new project
5121
+ list List all projects (alias: ls)
3803
5122
 
3804
5123
  Examples:
3805
- jssm env create staging -p my-app
3806
- jssm env list -p my-app
5124
+ jssm project create my-app
5125
+ jssm project list
3807
5126
  `);
3808
5127
  }
3809
5128
 
@@ -4081,6 +5400,22 @@ async function loginCommand() {
4081
5400
  } else {
4082
5401
  console.error(`
4083
5402
  \u274C Login failed: ${result.error}`);
5403
+ if (result.isConnectionError && host !== DEFAULT_HOST) {
5404
+ console.log(`
5405
+ \u26A0\uFE0F Current host: ${host}`);
5406
+ console.log(` Default host: ${DEFAULT_HOST}`);
5407
+ const resetToDefault = await dist_default3({
5408
+ message: "Would you like to reset the host to default?",
5409
+ default: false
5410
+ });
5411
+ if (resetToDefault) {
5412
+ globalConfig.host = DEFAULT_HOST;
5413
+ await saveGlobalConfig(globalConfig);
5414
+ console.log(`
5415
+ \u2705 Host reset to default: ${DEFAULT_HOST}`);
5416
+ console.log(`\u{1F4A1} Please try logging in again with 'jssm login'`);
5417
+ }
5418
+ }
4084
5419
  process.exit(1);
4085
5420
  }
4086
5421
  } catch (error) {
@@ -4165,6 +5500,22 @@ async function registerCommand() {
4165
5500
  } else {
4166
5501
  console.error(`
4167
5502
  \u274C Registration failed: ${result.error}`);
5503
+ if (result.isConnectionError && host !== DEFAULT_HOST) {
5504
+ console.log(`
5505
+ \u26A0\uFE0F Current host: ${host}`);
5506
+ console.log(` Default host: ${DEFAULT_HOST}`);
5507
+ const resetToDefault = await dist_default3({
5508
+ message: "Would you like to reset the host to default?",
5509
+ default: false
5510
+ });
5511
+ if (resetToDefault) {
5512
+ globalConfig.host = DEFAULT_HOST;
5513
+ await saveGlobalConfig(globalConfig);
5514
+ console.log(`
5515
+ \u2705 Host reset to default: ${DEFAULT_HOST}`);
5516
+ console.log(`\u{1F4A1} Please try registering again with 'jssm register'`);
5517
+ }
5518
+ }
4168
5519
  process.exit(1);
4169
5520
  }
4170
5521
  } catch (error) {
@@ -4190,10 +5541,378 @@ async function logoutCommand() {
4190
5541
  console.log(`\u2705 Successfully logged out (was logged in as ${authData.user.email})`);
4191
5542
  }
4192
5543
 
5544
+ // src/commands/token.ts
5545
+ init_auth();
5546
+ var import_chalk = __toESM(require_source(), 1);
5547
+ async function createToken(args2) {
5548
+ const auth = await loadAuthData();
5549
+ const globalConfig = await loadGlobalConfig();
5550
+ const host = globalConfig.host || DEFAULT_HOST;
5551
+ if (!auth) {
5552
+ console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
5553
+ process.exit(1);
5554
+ }
5555
+ let project = "";
5556
+ let environment = "";
5557
+ let name = "";
5558
+ let expiresIn = "90d";
5559
+ for (let i = 0; i < args2.length; i++) {
5560
+ const arg = args2[i];
5561
+ if (arg === "-p" || arg === "--project") {
5562
+ project = args2[++i] || "";
5563
+ } else if (arg === "-e" || arg === "--env") {
5564
+ environment = args2[++i] || "";
5565
+ } else if (arg === "-n" || arg === "--name") {
5566
+ name = args2[++i] || "";
5567
+ } else if (arg === "--expires") {
5568
+ expiresIn = args2[++i] || "90d";
5569
+ }
5570
+ }
5571
+ if (!project || !environment) {
5572
+ try {
5573
+ const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
5574
+ project = project || jssmConfig.project;
5575
+ environment = environment || jssmConfig.environment;
5576
+ } catch {
5577
+ }
5578
+ }
5579
+ if (!project) {
5580
+ console.error(
5581
+ import_chalk.default.red(
5582
+ "Project required. Use -p <project> or run from a directory with .jssm"
5583
+ )
5584
+ );
5585
+ process.exit(1);
5586
+ }
5587
+ if (!environment) {
5588
+ console.error(
5589
+ import_chalk.default.red(
5590
+ "Environment required. Use -e <env> or run from a directory with .jssm"
5591
+ )
5592
+ );
5593
+ process.exit(1);
5594
+ }
5595
+ if (!name) {
5596
+ name = `token-${Date.now()}`;
5597
+ }
5598
+ console.log(
5599
+ import_chalk.default.blue(`Creating service token for ${project}/${environment}...`)
5600
+ );
5601
+ try {
5602
+ const response = await fetch(
5603
+ `${host}/api/projects/${project}/envs/${environment}/tokens`,
5604
+ {
5605
+ method: "POST",
5606
+ headers: {
5607
+ "Content-Type": "application/json",
5608
+ Authorization: `Bearer ${auth.token}`
5609
+ },
5610
+ body: JSON.stringify({ name, expiresIn })
5611
+ }
5612
+ );
5613
+ if (!response.ok) {
5614
+ const error = await response.json();
5615
+ console.error(
5616
+ import_chalk.default.red(`Failed to create token: ${error.error}`)
5617
+ );
5618
+ process.exit(1);
5619
+ }
5620
+ const data = await response.json();
5621
+ console.log();
5622
+ console.log(import_chalk.default.green("\u2713 Service token created successfully!"));
5623
+ console.log();
5624
+ console.log(
5625
+ import_chalk.default.yellow(
5626
+ "\u26A0\uFE0F IMPORTANT: Save this token now! It will not be shown again."
5627
+ )
5628
+ );
5629
+ console.log();
5630
+ console.log(import_chalk.default.bold("Token:"), import_chalk.default.cyan(data.token));
5631
+ console.log();
5632
+ console.log(import_chalk.default.dim("Token ID:"), data.id);
5633
+ console.log(import_chalk.default.dim("Name:"), data.name);
5634
+ console.log(import_chalk.default.dim("Expires:"), data.expiresAt || "Never");
5635
+ console.log();
5636
+ console.log(import_chalk.default.blue("Usage in Dockerfile:"));
5637
+ console.log(import_chalk.default.dim(` ENV JSSM_SERVICE_TOKEN=${data.token}`));
5638
+ console.log(import_chalk.default.dim(` ENV JSSM_HOST=${host}`));
5639
+ } catch (error) {
5640
+ console.error(import_chalk.default.red(`Error: ${error.message}`));
5641
+ process.exit(1);
5642
+ }
5643
+ }
5644
+ async function listTokens(args2) {
5645
+ const auth = await loadAuthData();
5646
+ const globalConfig = await loadGlobalConfig();
5647
+ const host = globalConfig.host || DEFAULT_HOST;
5648
+ if (!auth) {
5649
+ console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
5650
+ process.exit(1);
5651
+ }
5652
+ let project = "";
5653
+ let environment = "";
5654
+ for (let i = 0; i < args2.length; i++) {
5655
+ const arg = args2[i];
5656
+ if (arg === "-p" || arg === "--project") {
5657
+ project = args2[++i] || "";
5658
+ } else if (arg === "-e" || arg === "--env") {
5659
+ environment = args2[++i] || "";
5660
+ }
5661
+ }
5662
+ if (!project || !environment) {
5663
+ try {
5664
+ const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
5665
+ project = project || jssmConfig.project;
5666
+ environment = environment || jssmConfig.environment;
5667
+ } catch {
5668
+ }
5669
+ }
5670
+ if (!project || !environment) {
5671
+ console.error(
5672
+ import_chalk.default.red(
5673
+ "Project and environment required. Use -p and -e or run from a directory with .jssm"
5674
+ )
5675
+ );
5676
+ process.exit(1);
5677
+ }
5678
+ try {
5679
+ const response = await fetch(
5680
+ `${host}/api/projects/${project}/envs/${environment}/tokens`,
5681
+ {
5682
+ headers: { Authorization: `Bearer ${auth.token}` }
5683
+ }
5684
+ );
5685
+ if (!response.ok) {
5686
+ const error = await response.json();
5687
+ console.error(
5688
+ import_chalk.default.red(`Failed to list tokens: ${error.error}`)
5689
+ );
5690
+ process.exit(1);
5691
+ }
5692
+ const data = await response.json();
5693
+ console.log(
5694
+ import_chalk.default.blue(`
5695
+ Service tokens for ${project}/${environment}:
5696
+ `)
5697
+ );
5698
+ if (data.tokens.length === 0) {
5699
+ console.log(import_chalk.default.dim("No tokens found."));
5700
+ } else {
5701
+ for (const token of data.tokens) {
5702
+ console.log(import_chalk.default.bold(token.name));
5703
+ console.log(import_chalk.default.dim(` ID: ${token.id}`));
5704
+ console.log(import_chalk.default.dim(` Prefix: ${token.tokenPrefix}`));
5705
+ console.log(
5706
+ import_chalk.default.dim(` Created: ${new Date(token.createdAt).toLocaleString()}`)
5707
+ );
5708
+ console.log(
5709
+ import_chalk.default.dim(
5710
+ ` Expires: ${token.expiresAt ? new Date(token.expiresAt).toLocaleString() : "Never"}`
5711
+ )
5712
+ );
5713
+ console.log(
5714
+ import_chalk.default.dim(
5715
+ ` Last used: ${token.lastUsedAt ? new Date(token.lastUsedAt).toLocaleString() : "Never"}`
5716
+ )
5717
+ );
5718
+ console.log();
5719
+ }
5720
+ }
5721
+ } catch (error) {
5722
+ console.error(import_chalk.default.red(`Error: ${error.message}`));
5723
+ process.exit(1);
5724
+ }
5725
+ }
5726
+ async function revokeToken(args2) {
5727
+ const auth = await loadAuthData();
5728
+ const globalConfig = await loadGlobalConfig();
5729
+ const host = globalConfig.host || DEFAULT_HOST;
5730
+ if (!auth) {
5731
+ console.error(import_chalk.default.red("Not logged in. Run: jssm login"));
5732
+ process.exit(1);
5733
+ }
5734
+ let project = "";
5735
+ let environment = "";
5736
+ let tokenId = "";
5737
+ for (let i = 0; i < args2.length; i++) {
5738
+ const arg = args2[i];
5739
+ if (arg === "-p" || arg === "--project") {
5740
+ project = args2[++i] || "";
5741
+ } else if (arg === "-e" || arg === "--env") {
5742
+ environment = args2[++i] || "";
5743
+ } else if (arg === "-t" || arg === "--token-id") {
5744
+ tokenId = args2[++i] || "";
5745
+ } else if (!arg.startsWith("-") && !tokenId) {
5746
+ tokenId = arg;
5747
+ }
5748
+ }
5749
+ if (!project || !environment) {
5750
+ try {
5751
+ const jssmConfig = JSON.parse(await Bun.file(".jssm").text());
5752
+ project = project || jssmConfig.project;
5753
+ environment = environment || jssmConfig.environment;
5754
+ } catch {
5755
+ }
5756
+ }
5757
+ if (!project || !environment) {
5758
+ console.error(import_chalk.default.red("Project and environment required."));
5759
+ process.exit(1);
5760
+ }
5761
+ if (!tokenId) {
5762
+ console.error(
5763
+ import_chalk.default.red("Token ID required. Use: jssm token revoke <token-id>")
5764
+ );
5765
+ process.exit(1);
5766
+ }
5767
+ try {
5768
+ const response = await fetch(
5769
+ `${host}/api/projects/${project}/envs/${environment}/tokens/${tokenId}`,
5770
+ {
5771
+ method: "DELETE",
5772
+ headers: { Authorization: `Bearer ${auth.token}` }
5773
+ }
5774
+ );
5775
+ if (!response.ok) {
5776
+ const error = await response.json();
5777
+ console.error(
5778
+ import_chalk.default.red(`Failed to revoke token: ${error.error}`)
5779
+ );
5780
+ process.exit(1);
5781
+ }
5782
+ console.log(import_chalk.default.green("\u2713 Token revoked successfully"));
5783
+ } catch (error) {
5784
+ console.error(import_chalk.default.red(`Error: ${error.message}`));
5785
+ process.exit(1);
5786
+ }
5787
+ }
5788
+ function showTokenHelp() {
5789
+ console.log(`
5790
+ ${import_chalk.default.bold("JSSM Token Management")}
5791
+
5792
+ Manage service tokens for container-based secrets injection.
5793
+
5794
+ ${import_chalk.default.bold("Commands:")}
5795
+ jssm token create Create a new service token
5796
+ jssm token list List all tokens for a project/environment
5797
+ jssm token revoke Revoke a token
5798
+
5799
+ ${import_chalk.default.bold("Options:")}
5800
+ -p, --project <name> Project name
5801
+ -e, --env <name> Environment name
5802
+ -n, --name <name> Token name (for create)
5803
+ --expires <duration> Expiration: 30d, 90d, 1y, never (default: 90d)
5804
+
5805
+ ${import_chalk.default.bold("Examples:")}
5806
+ # Create a token for production
5807
+ jssm token create -p my-app -e production -n "deploy-token"
5808
+
5809
+ # Create a token that never expires
5810
+ jssm token create -p my-app -e staging --expires never
5811
+
5812
+ # List all tokens
5813
+ jssm token list -p my-app -e production
5814
+
5815
+ # Revoke a token
5816
+ jssm token revoke <token-id> -p my-app -e production
5817
+
5818
+ ${import_chalk.default.bold("Usage in Docker:")}
5819
+ ENV JSSM_SERVICE_TOKEN=jssm_xxx...
5820
+ ENV JSSM_HOST=https://jssm.example.com
5821
+ RUN wget -O /usr/local/bin/jssm-init \${JSSM_HOST}/scripts/jssm-init.sh && chmod +x /usr/local/bin/jssm-init
5822
+ ENTRYPOINT ["/usr/local/bin/jssm-init"]
5823
+ CMD ["node", "app.js"]
5824
+ `);
5825
+ }
5826
+
5827
+ // src/utils/versionCheck.ts
5828
+ var PACKAGE_NAME = "@saidulbadhon/jssm-cli";
5829
+ var CURRENT_VERSION = "1.5.5";
5830
+ async function getLatestVersion() {
5831
+ try {
5832
+ const response = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}`);
5833
+ if (!response.ok) {
5834
+ return null;
5835
+ }
5836
+ const data = await response.json();
5837
+ return data["dist-tags"]?.latest || null;
5838
+ } catch {
5839
+ return null;
5840
+ }
5841
+ }
5842
+ function isOlderVersion(version1, version2) {
5843
+ const v1Parts = version1.split(".").map(Number);
5844
+ const v2Parts = version2.split(".").map(Number);
5845
+ for (let i = 0; i < 3; i++) {
5846
+ const v1 = v1Parts[i] || 0;
5847
+ const v2 = v2Parts[i] || 0;
5848
+ if (v1 < v2)
5849
+ return true;
5850
+ if (v1 > v2)
5851
+ return false;
5852
+ }
5853
+ return false;
5854
+ }
5855
+ async function checkVersion(currentCommand) {
5856
+ const skipCommands = ["help", "--help", "-h", "--version", "-v", "version", void 0];
5857
+ if (skipCommands.includes(currentCommand)) {
5858
+ return true;
5859
+ }
5860
+ try {
5861
+ const latestVersion = await getLatestVersion();
5862
+ if (!latestVersion) {
5863
+ return true;
5864
+ }
5865
+ if (!isOlderVersion(CURRENT_VERSION, latestVersion)) {
5866
+ return true;
5867
+ }
5868
+ console.log("");
5869
+ console.log("\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557");
5870
+ console.log("\u2551 \u26A0\uFE0F UPDATE REQUIRED \u2551");
5871
+ console.log("\u2560\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563");
5872
+ console.log(`\u2551 Current version: ${CURRENT_VERSION.padEnd(40)}\u2551`);
5873
+ console.log(`\u2551 Latest version: ${latestVersion.padEnd(40)}\u2551`);
5874
+ console.log("\u2551 \u2551");
5875
+ console.log("\u2551 A new version of JSSM CLI is available! \u2551");
5876
+ console.log("\u2551 Please update to continue using the CLI. \u2551");
5877
+ console.log("\u2551 \u2551");
5878
+ console.log("\u2551 Run: npm install -g @saidulbadhon/jssm-cli@latest \u2551");
5879
+ console.log("\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D");
5880
+ console.log("");
5881
+ const shouldUpdate = await dist_default3({
5882
+ message: "Do you want to update now?",
5883
+ default: true
5884
+ });
5885
+ if (shouldUpdate) {
5886
+ console.log("\n\u{1F4E6} To update, run:");
5887
+ console.log(" npm install -g @saidulbadhon/jssm-cli@latest");
5888
+ console.log("\nOr if you used a different package manager:");
5889
+ console.log(" yarn global add @saidulbadhon/jssm-cli@latest");
5890
+ console.log(" pnpm add -g @saidulbadhon/jssm-cli@latest");
5891
+ console.log(" bun add -g @saidulbadhon/jssm-cli@latest");
5892
+ console.log("");
5893
+ process.exit(0);
5894
+ } else {
5895
+ console.log("\n\u274C Update required to continue. Please update and try again.\n");
5896
+ process.exit(1);
5897
+ }
5898
+ return false;
5899
+ } catch {
5900
+ return true;
5901
+ }
5902
+ }
5903
+ function getCurrentVersion() {
5904
+ return CURRENT_VERSION;
5905
+ }
5906
+
4193
5907
  // src/index.ts
4194
5908
  var args = process.argv.slice(2);
4195
5909
  var command = args[0];
4196
5910
  async function main() {
5911
+ if (command === "--version" || command === "-v" || command === "version") {
5912
+ console.log(`jssm v${getCurrentVersion()}`);
5913
+ return;
5914
+ }
5915
+ await checkVersion(command);
4197
5916
  switch (command) {
4198
5917
  case "login":
4199
5918
  await loginCommand();
@@ -4208,10 +5927,10 @@ async function main() {
4208
5927
  await initCommand(args.slice(1));
4209
5928
  break;
4210
5929
  case "pull":
4211
- await pullCommand(args.slice(1));
5930
+ await pullCommand2(args.slice(1));
4212
5931
  break;
4213
5932
  case "push":
4214
- await pushCommand(args.slice(1));
5933
+ await pushCommand2(args.slice(1));
4215
5934
  break;
4216
5935
  case "sync":
4217
5936
  await syncCommand();
@@ -4222,12 +5941,26 @@ async function main() {
4222
5941
  case "project":
4223
5942
  await projectCommand(args.slice(1));
4224
5943
  break;
4225
- case "env":
4226
- await envCommand(args.slice(1));
4227
- break;
4228
5944
  case "config":
4229
5945
  await configCommand(args.slice(1));
4230
5946
  break;
5947
+ case "token": {
5948
+ const subCommand = args[1];
5949
+ switch (subCommand) {
5950
+ case "create":
5951
+ await createToken(args.slice(2));
5952
+ break;
5953
+ case "list":
5954
+ await listTokens(args.slice(2));
5955
+ break;
5956
+ case "revoke":
5957
+ await revokeToken(args.slice(2));
5958
+ break;
5959
+ default:
5960
+ showTokenHelp();
5961
+ }
5962
+ break;
5963
+ }
4231
5964
  case "help":
4232
5965
  case "--help":
4233
5966
  case "-h":
@@ -4253,13 +5986,14 @@ Commands:
4253
5986
  logout Logout from your account
4254
5987
  init Initialize current directory (creates .jssm config file)
4255
5988
  status Show current configuration
4256
- pull Pull variables from configured project/environment
4257
- push Push variables from local file to configured project/environment
5989
+ pull Pull .env files from configured project
5990
+ push Push .env files to configured project
4258
5991
  sync Sync variables to .env file
4259
5992
  project Manage projects (create, list)
4260
- env Manage environments (create, list)
4261
5993
  config Manage global configuration (set, get, list)
5994
+ token Manage service tokens for container secrets (create, list, revoke)
4262
5995
  help Show this help message
5996
+ --version Show CLI version
4263
5997
 
4264
5998
  Setup (recommended):
4265
5999
  # 1. Set global host and login
@@ -4267,35 +6001,43 @@ Setup (recommended):
4267
6001
  jssm register # or: jssm login
4268
6002
 
4269
6003
  # 2. Initialize a project directory (creates .jssm file)
4270
- jssm init # Interactive mode - will prompt for project/env
6004
+ jssm init # Interactive mode - will prompt for project
4271
6005
 
4272
- # 3. Pull and push variables
4273
- jssm pull # Download variables from backend
4274
- jssm push # Upload variables from .env to backend
6006
+ # 3. Pull and push .env files
6007
+ jssm pull # Download .env files from backend
6008
+ jssm push # Upload .env files to backend
4275
6009
  jssm sync # Sync variables to .env file
4276
6010
 
4277
6011
  Quick Start (all-in-one):
4278
6012
  # Initialize with all options (for one-off use)
4279
- jssm init -p my-app -e production
6013
+ jssm init -p my-app
4280
6014
 
4281
6015
  Advanced:
4282
6016
  # Manage global configuration
4283
6017
  jssm config list
4284
6018
  jssm config set host http://api.example.com
4285
6019
 
4286
- # Create project and environment separately
6020
+ # Create project
4287
6021
  jssm project create my-app
4288
- jssm env create staging -p my-app
4289
- jssm env create production -p my-app
4290
6022
 
4291
- # List resources
6023
+ # List projects
4292
6024
  jssm project list
4293
- jssm env list -p my-app
6025
+
6026
+ Container Secrets (Docker/ECS/EKS):
6027
+ # Create a service token for container deployment
6028
+ jssm token create -p my-app -n "deploy-token"
6029
+
6030
+ # Use in Dockerfile
6031
+ ENV JSSM_SERVICE_TOKEN=jssm_xxx...
6032
+ ENV JSSM_HOST=https://jssm.example.com
6033
+ RUN wget -O /usr/local/bin/jssm-init \\$JSSM_HOST/scripts/jssm-init.sh
6034
+ ENTRYPOINT ["/usr/local/bin/jssm-init"]
6035
+ CMD ["node", "app.js"]
4294
6036
 
4295
6037
  Note:
4296
6038
  - Global config (~/.jssm/config) stores host and preferences
4297
6039
  - Auth data (~/.jssm/auth) stores your login session
4298
- - Project config (.jssm) stores project name and environment
6040
+ - Project config (.jssm) stores project name
4299
6041
  - Add .jssm to .gitignore (may contain sensitive overrides)
4300
6042
 
4301
6043
  For more information, visit: https://github.com/yourusername/jssm