clishop 1.0.0 → 1.0.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 +397 -220
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -397,6 +397,277 @@ function registerAgentCommands(program2) {
397
397
  import chalk3 from "chalk";
398
398
  import ora2 from "ora";
399
399
  import inquirer3 from "inquirer";
400
+
401
+ // src/countries.ts
402
+ var COUNTRY_ALIASES = {
403
+ // ISO codes
404
+ "us": "US",
405
+ "gb": "GB",
406
+ "uk": "GB",
407
+ "fr": "FR",
408
+ "de": "DE",
409
+ "it": "IT",
410
+ "ca": "CA",
411
+ "au": "AU",
412
+ "be": "BE",
413
+ "nl": "NL",
414
+ "ie": "IE",
415
+ "pl": "PL",
416
+ "se": "SE",
417
+ "dk": "DK",
418
+ "no": "NO",
419
+ "fi": "FI",
420
+ "at": "AT",
421
+ "ch": "CH",
422
+ "es": "ES",
423
+ "pt": "PT",
424
+ "cz": "CZ",
425
+ "sk": "SK",
426
+ "hu": "HU",
427
+ "ro": "RO",
428
+ "bg": "BG",
429
+ "hr": "HR",
430
+ "si": "SI",
431
+ "gr": "GR",
432
+ "ee": "EE",
433
+ "lv": "LV",
434
+ "lt": "LT",
435
+ "lu": "LU",
436
+ "li": "LI",
437
+ "mc": "MC",
438
+ "sm": "SM",
439
+ "mx": "MX",
440
+ "pr": "PR",
441
+ "nz": "NZ",
442
+ "ae": "AE",
443
+ "br": "BR",
444
+ "jp": "JP",
445
+ "cn": "CN",
446
+ "kr": "KR",
447
+ "in": "IN",
448
+ "sg": "SG",
449
+ "za": "ZA",
450
+ "il": "IL",
451
+ "tr": "TR",
452
+ "ru": "RU",
453
+ "ua": "UA",
454
+ "ph": "PH",
455
+ "co": "CO",
456
+ "ar": "AR",
457
+ "cl": "CL",
458
+ "th": "TH",
459
+ "my": "MY",
460
+ "id": "ID",
461
+ "vn": "VN",
462
+ "tw": "TW",
463
+ // English names
464
+ "united states": "US",
465
+ "united states of america": "US",
466
+ "usa": "US",
467
+ "america": "US",
468
+ "united kingdom": "GB",
469
+ "great britain": "GB",
470
+ "england": "GB",
471
+ "scotland": "GB",
472
+ "wales": "GB",
473
+ "britain": "GB",
474
+ "france": "FR",
475
+ "germany": "DE",
476
+ "italy": "IT",
477
+ "spain": "ES",
478
+ "portugal": "PT",
479
+ "canada": "CA",
480
+ "australia": "AU",
481
+ "new zealand": "NZ",
482
+ "belgium": "BE",
483
+ "netherlands": "NL",
484
+ "holland": "NL",
485
+ "the netherlands": "NL",
486
+ "ireland": "IE",
487
+ "poland": "PL",
488
+ "sweden": "SE",
489
+ "denmark": "DK",
490
+ "norway": "NO",
491
+ "finland": "FI",
492
+ "austria": "AT",
493
+ "switzerland": "CH",
494
+ "czech republic": "CZ",
495
+ "czechia": "CZ",
496
+ "slovakia": "SK",
497
+ "hungary": "HU",
498
+ "romania": "RO",
499
+ "bulgaria": "BG",
500
+ "croatia": "HR",
501
+ "slovenia": "SI",
502
+ "greece": "GR",
503
+ "estonia": "EE",
504
+ "latvia": "LV",
505
+ "lithuania": "LT",
506
+ "luxembourg": "LU",
507
+ "liechtenstein": "LI",
508
+ "monaco": "MC",
509
+ "san marino": "SM",
510
+ "mexico": "MX",
511
+ "puerto rico": "PR",
512
+ "united arab emirates": "AE",
513
+ "emirates": "AE",
514
+ "uae": "AE",
515
+ "brazil": "BR",
516
+ "japan": "JP",
517
+ "china": "CN",
518
+ "south korea": "KR",
519
+ "korea": "KR",
520
+ "india": "IN",
521
+ "singapore": "SG",
522
+ "south africa": "ZA",
523
+ "israel": "IL",
524
+ "turkey": "TR",
525
+ "russia": "RU",
526
+ "russian federation": "RU",
527
+ "ukraine": "UA",
528
+ "philippines": "PH",
529
+ "colombia": "CO",
530
+ "argentina": "AR",
531
+ "chile": "CL",
532
+ "thailand": "TH",
533
+ "malaysia": "MY",
534
+ "indonesia": "ID",
535
+ "vietnam": "VN",
536
+ "taiwan": "TW",
537
+ // Native names
538
+ "deutschland": "DE",
539
+ "italia": "IT",
540
+ "espana": "ES",
541
+ "espa\xF1a": "ES",
542
+ "belgique": "BE",
543
+ "belgie": "BE",
544
+ "belgi\xEB": "BE",
545
+ "belgien": "BE",
546
+ "nederland": "NL",
547
+ "osterreich": "AT",
548
+ "\xF6sterreich": "AT",
549
+ "schweiz": "CH",
550
+ "suisse": "CH",
551
+ "svizzera": "CH",
552
+ "polska": "PL",
553
+ "sverige": "SE",
554
+ "danmark": "DK",
555
+ "norge": "NO",
556
+ "suomi": "FI",
557
+ "hrvatska": "HR",
558
+ "slovensko": "SK",
559
+ "slovenija": "SI",
560
+ "eesti": "EE",
561
+ "latvija": "LV",
562
+ "lietuva": "LT",
563
+ "luxemburg": "LU",
564
+ "magyarorszag": "HU",
565
+ "magyarorsz\xE1g": "HU",
566
+ "turkiye": "TR",
567
+ "t\xFCrkiye": "TR",
568
+ "brasil": "BR",
569
+ "m\xE9xico": "MX",
570
+ // Common typos
571
+ "belguim": "BE",
572
+ "belgum": "BE",
573
+ "nethrelands": "NL",
574
+ "sweeden": "SE",
575
+ "philipines": "PH",
576
+ "phillipines": "PH",
577
+ "columbia": "CO"
578
+ };
579
+ var CODE_TO_NAME = {
580
+ US: "United States",
581
+ GB: "United Kingdom",
582
+ FR: "France",
583
+ DE: "Germany",
584
+ IT: "Italy",
585
+ CA: "Canada",
586
+ AU: "Australia",
587
+ BE: "Belgium",
588
+ NL: "Netherlands",
589
+ IE: "Ireland",
590
+ PL: "Poland",
591
+ SE: "Sweden",
592
+ DK: "Denmark",
593
+ NO: "Norway",
594
+ FI: "Finland",
595
+ AT: "Austria",
596
+ CH: "Switzerland",
597
+ ES: "Spain",
598
+ PT: "Portugal",
599
+ CZ: "Czech Republic",
600
+ SK: "Slovakia",
601
+ HU: "Hungary",
602
+ RO: "Romania",
603
+ BG: "Bulgaria",
604
+ HR: "Croatia",
605
+ SI: "Slovenia",
606
+ GR: "Greece",
607
+ EE: "Estonia",
608
+ LV: "Latvia",
609
+ LT: "Lithuania",
610
+ LU: "Luxembourg",
611
+ LI: "Liechtenstein",
612
+ MC: "Monaco",
613
+ SM: "San Marino",
614
+ MX: "Mexico",
615
+ PR: "Puerto Rico",
616
+ NZ: "New Zealand",
617
+ AE: "United Arab Emirates",
618
+ BR: "Brazil",
619
+ JP: "Japan",
620
+ CN: "China",
621
+ KR: "South Korea",
622
+ IN: "India",
623
+ SG: "Singapore",
624
+ ZA: "South Africa",
625
+ IL: "Israel",
626
+ TR: "Turkey",
627
+ RU: "Russia",
628
+ UA: "Ukraine",
629
+ PH: "Philippines",
630
+ CO: "Colombia",
631
+ AR: "Argentina",
632
+ CL: "Chile",
633
+ TH: "Thailand",
634
+ MY: "Malaysia",
635
+ ID: "Indonesia",
636
+ VN: "Vietnam",
637
+ TW: "Taiwan"
638
+ };
639
+ function stripDiacritics(str) {
640
+ return str.normalize("NFD").replace(/[\u0300-\u036f]/g, "");
641
+ }
642
+ function normalizeCountry(input) {
643
+ if (!input?.trim()) return { code: null, name: null, exact: false };
644
+ const lower = input.trim().toLowerCase();
645
+ const stripped = stripDiacritics(lower);
646
+ const direct = COUNTRY_ALIASES[lower] || COUNTRY_ALIASES[stripped];
647
+ if (direct) {
648
+ return { code: direct, name: CODE_TO_NAME[direct] || direct, exact: true };
649
+ }
650
+ if (/^[a-zA-Z]{2}$/.test(input.trim())) {
651
+ const upper = input.trim().toUpperCase();
652
+ const name = CODE_TO_NAME[upper];
653
+ if (name) return { code: upper, name, exact: true };
654
+ return { code: upper, name: null, exact: false };
655
+ }
656
+ const keys = Object.keys(COUNTRY_ALIASES);
657
+ const prefixMatch = keys.find((k) => k.length > 2 && (k.startsWith(lower) || k.startsWith(stripped)));
658
+ if (prefixMatch) {
659
+ const code = COUNTRY_ALIASES[prefixMatch];
660
+ return { code, name: CODE_TO_NAME[code] || code, exact: false };
661
+ }
662
+ const subMatch = keys.find((k) => k.length > 2 && (k.includes(lower) || k.includes(stripped)));
663
+ if (subMatch) {
664
+ const code = COUNTRY_ALIASES[subMatch];
665
+ return { code, name: CODE_TO_NAME[code] || code, exact: false };
666
+ }
667
+ return { code: null, name: null, exact: false };
668
+ }
669
+
670
+ // src/commands/address.ts
400
671
  function registerAddressCommands(program2) {
401
672
  const address = program2.command("address").description("Manage shipping addresses (scoped to the active agent)");
402
673
  address.command("list").alias("ls").description("List all addresses for the active agent").action(async () => {
@@ -482,6 +753,27 @@ Addresses for agent "${agent.name}":
482
753
  default: false
483
754
  }
484
755
  ]);
756
+ const countryResult = normalizeCountry(answers.country);
757
+ if (countryResult.code) {
758
+ if (countryResult.name && answers.country.toLowerCase() !== countryResult.code.toLowerCase()) {
759
+ console.log(chalk3.green(` \u2713 Country: ${countryResult.name} (${countryResult.code})`));
760
+ }
761
+ answers.country = countryResult.code;
762
+ } else {
763
+ console.log(chalk3.yellow(` \u26A0 Could not recognize "${answers.country}" as a known country.`));
764
+ const { keepCountry } = await inquirer3.prompt([
765
+ {
766
+ type: "confirm",
767
+ name: "keepCountry",
768
+ message: `Use "${answers.country}" anyway?`,
769
+ default: true
770
+ }
771
+ ]);
772
+ if (!keepCountry) {
773
+ console.log(chalk3.dim(" Try again with a country name or code (e.g. US, Belgium, DE)"));
774
+ return;
775
+ }
776
+ }
485
777
  let companyAnswers = { companyName: "", vatNumber: "" };
486
778
  if (answers.isCompany) {
487
779
  companyAnswers = await inquirer3.prompt([
@@ -586,8 +878,7 @@ Payment methods for agent "${agent.name}":
586
878
  for (const pm of methods) {
587
879
  const isDefault = pm.id === agent.defaultPaymentMethodId;
588
880
  const marker = isDefault ? chalk4.green("\u25CF ") : " ";
589
- const last4 = pm.last4 ? ` \u2022\u2022\u2022\u2022 ${pm.last4}` : "";
590
- console.log(`${marker}${chalk4.bold(pm.label)}${last4} ${chalk4.dim(`[${pm.type}]`)} ${chalk4.dim(`(${pm.id})`)}`);
881
+ console.log(`${marker}${chalk4.bold(pm.label)} ${chalk4.dim(`[${pm.type}]`)} ${chalk4.dim(`(${pm.id})`)}`);
591
882
  }
592
883
  console.log();
593
884
  } catch (error) {
@@ -610,7 +901,25 @@ Payment methods for agent "${agent.name}":
610
901
  console.log(chalk4.cyan.underline(` ${setupUrl}
611
902
  `));
612
903
  console.log(chalk4.dim("The CLI never collects raw card details. Payment is set up via the secure web portal."));
613
- console.log(chalk4.dim("Once completed, run 'clishop payment list' to see your new method.\n"));
904
+ console.log(chalk4.dim("Press Enter after completing the setup in your browser.\n"));
905
+ const inquirer11 = (await import("inquirer")).default;
906
+ await inquirer11.prompt([
907
+ { type: "input", name: "done", message: "Press Enter when done..." }
908
+ ]);
909
+ const checkSpinner = ora3("Checking for your payment method...").start();
910
+ const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
911
+ const methods = pmRes.data.paymentMethods || [];
912
+ if (methods.length > 0) {
913
+ const latest = methods[methods.length - 1];
914
+ if (!agent.defaultPaymentMethodId) {
915
+ updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
916
+ checkSpinner.succeed(chalk4.green(`Payment method "${latest.label}" added and set as default.`));
917
+ } else {
918
+ checkSpinner.succeed(chalk4.green(`Payment method "${latest.label}" added.`));
919
+ }
920
+ } else {
921
+ checkSpinner.warn(chalk4.yellow("No payment method found yet. Try again or run: clishop payment list"));
922
+ }
614
923
  } catch (error) {
615
924
  handleApiError(error);
616
925
  }
@@ -1648,6 +1957,8 @@ function formatPrice2(cents, currency) {
1648
1957
  }
1649
1958
  var STATUS_COLORS = {
1650
1959
  pending: chalk6.yellow,
1960
+ pending_confirmation: chalk6.hex("#f97316"),
1961
+ // orange
1651
1962
  confirmed: chalk6.blue,
1652
1963
  processing: chalk6.cyan,
1653
1964
  shipped: chalk6.magenta,
@@ -1768,7 +2079,17 @@ function registerOrderCommands(program2) {
1768
2079
  shippingAddressId: addressId,
1769
2080
  paymentMethodId: paymentId
1770
2081
  });
1771
- spinner.succeed(chalk6.green(`Order placed! Order ID: ${chalk6.bold(res.data.order.id)}`));
2082
+ const orderStatus = res.data.order?.status;
2083
+ if (orderStatus === "pending_confirmation") {
2084
+ spinner.succeed(chalk6.green(`Order placed! Order ID: ${chalk6.bold(res.data.order.id)}`));
2085
+ console.log();
2086
+ console.log(chalk6.yellow(" \u26A0 Confirmation required before this order ships."));
2087
+ console.log(chalk6.dim(" Check your email for a confirmation link, or confirm on the website:"));
2088
+ console.log(chalk6.cyan(` https://clishop.ai/orders/${res.data.order.id}`));
2089
+ console.log();
2090
+ } else {
2091
+ spinner.succeed(chalk6.green(`Order placed and confirmed! Order ID: ${chalk6.bold(res.data.order.id)}`));
2092
+ }
1772
2093
  } catch (error) {
1773
2094
  handleApiError(error);
1774
2095
  }
@@ -2520,8 +2841,7 @@ function registerStatusCommand(program2) {
2520
2841
  for (const pm of agent.paymentMethods) {
2521
2842
  const isDefault = pm.id === agent.defaultPaymentMethodId;
2522
2843
  const defaultBadge = isDefault ? chalk10.green(" \u2605 default") : "";
2523
- const last4 = pm.last4 ? ` \u2022\u2022\u2022\u2022 ${pm.last4}` : "";
2524
- console.log(` \u2022 ${chalk10.white(pm.label)}${last4}${defaultBadge}`);
2844
+ console.log(` \u2022 ${chalk10.white(pm.label)}${defaultBadge}`);
2525
2845
  console.log(chalk10.dim(` ${pm.type} via ${pm.provider || "unknown"} (${pm.id})`));
2526
2846
  }
2527
2847
  }
@@ -2542,6 +2862,7 @@ import chalk11 from "chalk";
2542
2862
  import ora9 from "ora";
2543
2863
  import inquirer7 from "inquirer";
2544
2864
  import open2 from "open";
2865
+ import { execFileSync } from "child_process";
2545
2866
  function divider(color = chalk11.cyan) {
2546
2867
  console.log(" " + color("\u2500".repeat(48)));
2547
2868
  }
@@ -2554,12 +2875,6 @@ function stepHeader(step, total, title) {
2554
2875
  );
2555
2876
  console.log();
2556
2877
  }
2557
- function formatPrice4(cents, currency = "USD") {
2558
- return new Intl.NumberFormat("en-US", {
2559
- style: "currency",
2560
- currency
2561
- }).format(cents / 100);
2562
- }
2563
2878
  function registerSetupCommand(program2) {
2564
2879
  program2.command("setup").description(
2565
2880
  "First-time setup wizard \u2014 account, agent, address, payment, first search"
@@ -2640,9 +2955,8 @@ async function runSetupWizard() {
2640
2955
  config.set("setupCompleted", true);
2641
2956
  return;
2642
2957
  }
2643
- stepHeader(1, 6, "Account");
2958
+ stepHeader(1, 5, "Account");
2644
2959
  let loggedIn = await isLoggedIn();
2645
- let isNewAccount = false;
2646
2960
  if (loggedIn) {
2647
2961
  const user = await getUserInfo();
2648
2962
  console.log(
@@ -2700,46 +3014,18 @@ async function runSetupWizard() {
2700
3014
  process.exitCode = 1;
2701
3015
  return;
2702
3016
  }
2703
- console.log();
2704
- console.log(
2705
- chalk11.dim(
2706
- " Your monthly spending limit controls the maximum your AI agent"
2707
- )
2708
- );
2709
- console.log(
2710
- chalk11.dim(
2711
- " can spend per month. Default: $200. You can only change this"
2712
- )
2713
- );
2714
- console.log(
2715
- chalk11.dim(
2716
- " later via the website or email confirmation."
2717
- )
2718
- );
2719
- console.log();
2720
- const { spendingLimit } = await inquirer7.prompt([
2721
- {
2722
- type: "number",
2723
- name: "spendingLimit",
2724
- message: "Monthly spending limit ($):",
2725
- default: 200
2726
- }
2727
- ]);
2728
- const limitInCents = Math.round((spendingLimit || 200) * 100);
2729
3017
  const spinner = ora9("Creating your account...").start();
2730
3018
  try {
2731
3019
  const user = await register(
2732
3020
  answers.email,
2733
3021
  answers.password,
2734
- answers.name,
2735
- limitInCents
3022
+ answers.name
2736
3023
  );
2737
3024
  spinner.succeed(
2738
3025
  chalk11.green(
2739
3026
  `Account created! Welcome, ${chalk11.bold(user.name)}.`
2740
3027
  )
2741
3028
  );
2742
- isNewAccount = true;
2743
3029
  } catch (error) {
2744
3030
  spinner.fail(
2745
3031
  chalk11.red(
@@ -2794,7 +3080,7 @@ async function runSetupWizard() {
2794
3080
  }
2795
3081
  }
2796
3082
  }
2797
- stepHeader(2, 6, "Agent");
3083
+ stepHeader(2, 5, "Agent");
2798
3084
  console.log(
2799
3085
  chalk11.dim(
2800
3086
  " Agents are safety profiles that control per-order limits and categories."
@@ -2858,87 +3144,7 @@ async function runSetupWizard() {
2858
3144
  } else {
2859
3145
  console.log(chalk11.green(" \u2713 Using default agent."));
2860
3146
  }
2861
- stepHeader(3, 6, "Monthly Spending Limit");
2862
- if (isNewAccount) {
2863
- console.log(
2864
- chalk11.green(" \u2713 Spending limit was set during registration.")
2865
- );
2866
- console.log(
2867
- chalk11.dim(
2868
- " To change it later, visit " + chalk11.white("https://clishop.ai/agents") + chalk11.dim(" or use email confirmation.")
2869
- )
2870
- );
2871
- } else {
2872
- try {
2873
- const api = getApiClient();
2874
- const res = await api.get("/spending-limit");
2875
- const { monthlySpendingLimitInCents, configured } = res.data;
2876
- const currentLimit = (monthlySpendingLimitInCents / 100).toFixed(0);
2877
- if (!configured) {
2878
- console.log(
2879
- chalk11.dim(
2880
- " Your monthly spending limit controls the maximum your AI agent"
2881
- )
2882
- );
2883
- console.log(
2884
- chalk11.dim(
2885
- " can spend per month. Default: $200. You can only change this"
2886
- )
2887
- );
2888
- console.log(
2889
- chalk11.dim(
2890
- " later via the website or email confirmation."
2891
- )
2892
- );
2893
- console.log();
2894
- const { spendingLimit } = await inquirer7.prompt([
2895
- {
2896
- type: "number",
2897
- name: "spendingLimit",
2898
- message: "Monthly spending limit ($):",
2899
- default: parseInt(currentLimit) || 200
2900
- }
2901
- ]);
2902
- const limitInCents = Math.round((spendingLimit || 200) * 100);
2903
- const spinner = ora9("Setting spending limit...").start();
2904
- try {
2905
- await api.patch("/spending-limit", { limitInCents });
2906
- spinner.succeed(
2907
- chalk11.green(
2908
- `Monthly spending limit set to $${(limitInCents / 100).toFixed(0)}.`
2909
- )
2910
- );
2911
- } catch (error) {
2912
- spinner.fail(
2913
- chalk11.red(
2914
- `Failed: ${error?.response?.data?.message || error.message}`
2915
- )
2916
- );
2917
- }
2918
- } else {
2919
- console.log(
2920
- chalk11.green(
2921
- ` \u2713 Monthly spending limit: $${currentLimit}/month (already configured).`
2922
- )
2923
- );
2924
- console.log(
2925
- chalk11.dim(
2926
- " To change it, visit " + chalk11.white("https://clishop.ai/agents") + chalk11.dim(" or it will require email confirmation.")
2927
- )
2928
- );
2929
- }
2930
- } catch (error) {
2931
- console.log(
2932
- chalk11.yellow(
2933
- ` \u26A0 Could not fetch spending limit: ${error?.response?.data?.message || error.message}`
2934
- )
2935
- );
2936
- console.log(
2937
- chalk11.dim(" You can set it later on the website.")
2938
- );
2939
- }
2940
- }
2941
- stepHeader(4, 6, "Shipping Address");
3147
+ stepHeader(3, 5, "Shipping Address");
2942
3148
  console.log(
2943
3149
  chalk11.dim(
2944
3150
  " Add an address so products can be delivered to you."
@@ -3042,6 +3248,15 @@ async function runSetupWizard() {
3042
3248
  ]);
3043
3249
  }
3044
3250
  addressCity = addr.city;
3251
+ const countryResult = normalizeCountry(addr.country);
3252
+ if (countryResult.code) {
3253
+ addr.country = countryResult.code;
3254
+ if (countryResult.name) {
3255
+ console.log(chalk11.green(` \u2713 Country: ${countryResult.name} (${countryResult.code})`));
3256
+ }
3257
+ } else {
3258
+ console.log(chalk11.yellow(` \u26A0 Could not recognize "${addr.country}" \u2014 using as entered.`));
3259
+ }
3045
3260
  addressCountry = addr.country;
3046
3261
  const spinner = ora9("Saving address...").start();
3047
3262
  try {
@@ -3097,10 +3312,12 @@ async function runSetupWizard() {
3097
3312
  validate: (v) => v.trim() ? true : "Country is required for searches to work"
3098
3313
  }
3099
3314
  ]);
3100
- addressCountry = country.trim();
3315
+ const countryResult = normalizeCountry(country.trim());
3316
+ addressCountry = countryResult.code || country.trim().toUpperCase();
3101
3317
  config.set("defaultCountry", addressCountry);
3318
+ const displayName = countryResult.name ? `${countryResult.name} (${addressCountry})` : addressCountry;
3102
3319
  console.log(
3103
- chalk11.green(` \u2713 Country set to "${addressCountry}" for product searches.`)
3320
+ chalk11.green(` \u2713 Country set to ${displayName} for product searches.`)
3104
3321
  );
3105
3322
  console.log(
3106
3323
  chalk11.dim(
@@ -3108,7 +3325,7 @@ async function runSetupWizard() {
3108
3325
  )
3109
3326
  );
3110
3327
  }
3111
- stepHeader(5, 6, "Payment Method");
3328
+ stepHeader(4, 5, "Payment Method");
3112
3329
  console.log(
3113
3330
  chalk11.dim(
3114
3331
  " For security, payment details are entered through a secure web"
@@ -3156,6 +3373,38 @@ async function runSetupWizard() {
3156
3373
  console.log(chalk11.dim(" (Browser opened automatically)"));
3157
3374
  } catch {
3158
3375
  }
3376
+ console.log();
3377
+ await inquirer7.prompt([
3378
+ {
3379
+ type: "input",
3380
+ name: "done",
3381
+ message: "Press Enter after completing the payment setup in your browser..."
3382
+ }
3383
+ ]);
3384
+ const pollSpinner = ora9("Checking for your payment method...").start();
3385
+ try {
3386
+ const agent2 = getActiveAgent();
3387
+ await ensureAgentOnBackend(agent2.name);
3388
+ const pmRes = await api.get("/payment-methods", {
3389
+ params: { agent: agent2.name }
3390
+ });
3391
+ const methods = pmRes.data.paymentMethods || [];
3392
+ if (methods.length > 0) {
3393
+ const latest = methods[methods.length - 1];
3394
+ updateAgent(agent2.name, { defaultPaymentMethodId: latest.id });
3395
+ pollSpinner.succeed(
3396
+ chalk11.green(`Payment method "${latest.label}" found and set as default.`)
3397
+ );
3398
+ } else {
3399
+ pollSpinner.warn(
3400
+ chalk11.yellow("No payment method found yet. You can add one later with: clishop payment add")
3401
+ );
3402
+ }
3403
+ } catch {
3404
+ pollSpinner.warn(
3405
+ chalk11.yellow("Could not verify payment method. You can check with: clishop payment list")
3406
+ );
3407
+ }
3159
3408
  } catch (error) {
3160
3409
  spinner.fail(
3161
3410
  chalk11.red(
@@ -3175,7 +3424,7 @@ async function runSetupWizard() {
3175
3424
  )
3176
3425
  );
3177
3426
  }
3178
- stepHeader(6, 6, "Your First Search");
3427
+ stepHeader(5, 5, "Your First Search");
3179
3428
  if (addressCity) {
3180
3429
  console.log(
3181
3430
  chalk11.dim(
@@ -3201,97 +3450,25 @@ async function runSetupWizard() {
3201
3450
  }
3202
3451
  ]);
3203
3452
  if (searchQuery.trim()) {
3204
- const spinner = ora9(`Searching for "${searchQuery}"...`).start();
3205
3453
  try {
3206
- const api = getApiClient();
3207
- const searchParams = {
3208
- q: searchQuery,
3209
- page: 1,
3210
- pageSize: 5,
3211
- extendedSearch: true,
3212
- extendedTimeout: 30
3213
- };
3454
+ const args = ["search", searchQuery.trim(), "--per-page", "5"];
3214
3455
  if (addressCountry) {
3215
- searchParams.country = addressCountry;
3456
+ args.push("--country", addressCountry);
3216
3457
  }
3217
3458
  if (addressCity) {
3218
- searchParams.city = addressCity;
3219
- }
3220
- spinner.text = `Searching for "${searchQuery}" (extended search across all stores)...`;
3221
- const res = await api.get("/products/search", {
3222
- params: searchParams,
3223
- timeout: 35e3
3459
+ args.push("--city", addressCity);
3460
+ }
3461
+ const nodeBin = process.argv[0];
3462
+ const scriptPath = process.argv[1];
3463
+ execFileSync(nodeBin, [scriptPath, ...args], {
3464
+ stdio: "inherit",
3465
+ timeout: 45e3,
3466
+ env: process.env
3224
3467
  });
3225
- spinner.stop();
3226
- const result = res.data;
3227
- const extended = result.extended;
3228
- const allProducts = [
3229
- ...result.products || [],
3230
- ...extended?.products || []
3231
- ];
3232
- if (allProducts.length === 0) {
3233
- console.log(
3234
- chalk11.yellow(
3235
- `
3236
- No results for "${searchQuery}".`
3237
- )
3238
- );
3239
- if (!addressCountry) {
3240
- console.log(
3241
- chalk11.yellow(
3242
- " This might be because no shipping country was configured."
3243
- )
3244
- );
3245
- console.log(
3246
- chalk11.dim(
3247
- " Add a shipping address with: " + chalk11.white("clishop address add")
3248
- )
3249
- );
3250
- } else {
3251
- console.log(
3252
- chalk11.dim(" Try other search terms later!")
3253
- );
3254
- }
3255
- } else {
3256
- const totalCount = (result.total || 0) + (extended?.total || 0);
3257
- console.log(
3258
- chalk11.bold(
3259
- `
3260
- Found ${totalCount} result${totalCount !== 1 ? "s" : ""} for "${searchQuery}":
3261
- `
3262
- )
3263
- );
3264
- for (let i = 0; i < Math.min(allProducts.length, 5); i++) {
3265
- const p = allProducts[i];
3266
- const price = formatPrice4(p.priceInCents, p.currency || "USD");
3267
- const stock = p.inStock !== false ? chalk11.green("In Stock") : chalk11.red("Out of Stock");
3268
- const num = i + 1;
3269
- console.log(
3270
- ` ${chalk11.dim(`[${num}]`)} ${chalk11.bold.cyan(p.name)} ${chalk11.bold.white(price)} ${stock}`
3271
- );
3272
- console.log(chalk11.dim(` ID: ${p.id}`));
3273
- if (p.description) {
3274
- console.log(
3275
- chalk11.dim(
3276
- ` ${p.description.length > 100 ? p.description.slice(0, 100) + "..." : p.description}`
3277
- )
3278
- );
3279
- }
3280
- console.log();
3281
- }
3282
- console.log(
3283
- chalk11.dim(" Buy a product with: ") + chalk11.white("clishop buy <product-id>")
3284
- );
3285
- console.log(
3286
- chalk11.dim(" Or search again with: ") + chalk11.white("clishop search <query>")
3287
- );
3288
- }
3289
3468
  } catch (error) {
3290
- spinner.fail(
3291
- chalk11.red(
3292
- `Search failed: ${error?.response?.data?.message || error.message}`
3293
- )
3294
- );
3469
+ if (error.status == null && error.signal === "SIGTERM") {
3470
+ console.log(chalk11.yellow("\n Search timed out. Try again later with: clishop search <query>"));
3471
+ }
3295
3472
  }
3296
3473
  }
3297
3474
  config.set("setupCompleted", true);
@@ -3326,7 +3503,7 @@ async function runSetupWizard() {
3326
3503
  import chalk12 from "chalk";
3327
3504
  import ora10 from "ora";
3328
3505
  import inquirer8 from "inquirer";
3329
- function formatPrice5(cents, currency) {
3506
+ function formatPrice4(cents, currency) {
3330
3507
  return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
3331
3508
  }
3332
3509
  var STATUS_COLORS2 = {
@@ -3663,7 +3840,7 @@ function registerAdvertiseCommands(program2) {
3663
3840
  const meta = [];
3664
3841
  if (ad.quantity > 1) meta.push(`qty: ${ad.quantity}`);
3665
3842
  if (ad.brand) meta.push(ad.brand);
3666
- if (ad.bidPriceInCents) meta.push(`max: ${formatPrice5(ad.bidPriceInCents, ad.currency)}`);
3843
+ if (ad.bidPriceInCents) meta.push(`max: ${formatPrice4(ad.bidPriceInCents, ad.currency)}`);
3667
3844
  if (ad.speedDays) meta.push(`${ad.speedDays}-day delivery`);
3668
3845
  if (ad.freeReturns) meta.push("free returns");
3669
3846
  if (ad.minReturnDays) meta.push(`${ad.minReturnDays}d return min`);
@@ -3705,7 +3882,7 @@ function registerAdvertiseCommands(program2) {
3705
3882
  if (ad.company) console.log(` Company: ${ad.company}`);
3706
3883
  if (ad.features) console.log(` Features: ${ad.features}`);
3707
3884
  console.log(` Quantity: ${ad.quantity}`);
3708
- if (ad.bidPriceInCents) console.log(` Max Bid: ${chalk12.bold(formatPrice5(ad.bidPriceInCents, ad.currency))}`);
3885
+ if (ad.bidPriceInCents) console.log(` Max Bid: ${chalk12.bold(formatPrice4(ad.bidPriceInCents, ad.currency))}`);
3709
3886
  if (ad.speedDays) console.log(` Speed: ${ad.speedDays}-day delivery`);
3710
3887
  const returnReqs = [];
3711
3888
  if (ad.freeReturns) returnReqs.push(chalk12.green("Free Returns required"));
@@ -3741,7 +3918,7 @@ function registerAdvertiseCommands(program2) {
3741
3918
  const bidStatusColor = BID_STATUS_COLORS[bid.status] || chalk12.white;
3742
3919
  const storeBadge = bid.store?.verified ? chalk12.green(" \u2713") : "";
3743
3920
  const storeRating = bid.store?.rating != null ? chalk12.dim(` (${bid.store.rating.toFixed(1)}\u2605)`) : "";
3744
- console.log(` ${chalk12.bold(bid.id)} ${bidStatusColor(bid.status.toUpperCase().padEnd(10))} ${chalk12.bold(formatPrice5(bid.priceInCents, bid.currency))}`);
3921
+ console.log(` ${chalk12.bold(bid.id)} ${bidStatusColor(bid.status.toUpperCase().padEnd(10))} ${chalk12.bold(formatPrice4(bid.priceInCents, bid.currency))}`);
3745
3922
  console.log(` Store: ${bid.store?.name || bid.storeId}${storeBadge}${storeRating}`);
3746
3923
  if (bid.shippingDays != null) console.log(` Delivery: ${bid.shippingDays}-day`);
3747
3924
  const bidReturns = [];
@@ -3749,7 +3926,7 @@ function registerAdvertiseCommands(program2) {
3749
3926
  if (bid.returnWindowDays) bidReturns.push(`${bid.returnWindowDays}-day return window`);
3750
3927
  if (bidReturns.length) console.log(` Returns: ${bidReturns.join(" \xB7 ")}`);
3751
3928
  if (bid.note) console.log(` Note: ${bid.note}`);
3752
- if (bid.product) console.log(` Product: ${bid.product.name} (${formatPrice5(bid.product.priceInCents, bid.product.currency)})`);
3929
+ if (bid.product) console.log(` Product: ${bid.product.name} (${formatPrice4(bid.product.priceInCents, bid.product.currency)})`);
3753
3930
  console.log(` Date: ${new Date(bid.createdAt).toLocaleString()}`);
3754
3931
  console.log();
3755
3932
  }
@@ -3784,7 +3961,7 @@ function registerAdvertiseCommands(program2) {
3784
3961
  console.log(chalk12.bold("\n Accept this bid?\n"));
3785
3962
  console.log(` Request: ${ad.title}`);
3786
3963
  console.log(` Store: ${bid.store?.name || bid.storeId}${bid.store?.verified ? chalk12.green(" \u2713") : ""}`);
3787
- console.log(` Price: ${chalk12.bold(formatPrice5(bid.priceInCents, bid.currency))}`);
3964
+ console.log(` Price: ${chalk12.bold(formatPrice4(bid.priceInCents, bid.currency))}`);
3788
3965
  if (bid.shippingDays != null) console.log(` Delivery: ${bid.shippingDays}-day`);
3789
3966
  if (bid.note) console.log(` Note: ${bid.note}`);
3790
3967
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clishop",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "mcpName": "io.github.StefDCL/clishop",
5
5
  "description": "CLISHOP — Order anything from your terminal",
6
6
  "main": "dist/index.js",