clishop 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-ML7L6BAH.js → chunk-EAXPWOMT.js} +6 -43
- package/dist/index.js +204 -781
- package/dist/mcp.js +63 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7,11 +7,10 @@ import {
|
|
|
7
7
|
handleApiError,
|
|
8
8
|
isKeytarAvailable,
|
|
9
9
|
isLoggedIn,
|
|
10
|
-
login,
|
|
11
10
|
logout,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "./chunk-
|
|
11
|
+
resolveBackend,
|
|
12
|
+
storeAuthFromSetup
|
|
13
|
+
} from "./chunk-EAXPWOMT.js";
|
|
15
14
|
import {
|
|
16
15
|
createAgent,
|
|
17
16
|
deleteAgent,
|
|
@@ -31,111 +30,7 @@ import chalk16 from "chalk";
|
|
|
31
30
|
// src/commands/auth.ts
|
|
32
31
|
import chalk from "chalk";
|
|
33
32
|
import ora from "ora";
|
|
34
|
-
import inquirer from "inquirer";
|
|
35
|
-
async function readPasswordFromStdin() {
|
|
36
|
-
const chunks = [];
|
|
37
|
-
for await (const chunk of process.stdin) {
|
|
38
|
-
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(String(chunk)));
|
|
39
|
-
}
|
|
40
|
-
return Buffer.concat(chunks).toString("utf8").trim();
|
|
41
|
-
}
|
|
42
33
|
function registerAuthCommands(program2) {
|
|
43
|
-
program2.command("login").description("Log in to your CLISHOP account").option("-e, --email <email>", "Email address").option("-p, --password <password>", "Password (less secure: exposed to shell history)").option("--password-stdin", "Read password from stdin").action(async (opts) => {
|
|
44
|
-
try {
|
|
45
|
-
if (opts.password && opts.passwordStdin) {
|
|
46
|
-
console.error(chalk.red("\n\u2717 Use either --password or --password-stdin, not both."));
|
|
47
|
-
process.exitCode = 1;
|
|
48
|
-
return;
|
|
49
|
-
}
|
|
50
|
-
if (await isLoggedIn()) {
|
|
51
|
-
const user = await getUserInfo();
|
|
52
|
-
const { confirm } = await inquirer.prompt([
|
|
53
|
-
{
|
|
54
|
-
type: "confirm",
|
|
55
|
-
name: "confirm",
|
|
56
|
-
message: `You are already logged in as ${chalk.cyan(user?.email || "unknown")}. Log in as a different user?`,
|
|
57
|
-
default: false
|
|
58
|
-
}
|
|
59
|
-
]);
|
|
60
|
-
if (!confirm) return;
|
|
61
|
-
}
|
|
62
|
-
let email = opts.email;
|
|
63
|
-
let password = opts.password;
|
|
64
|
-
if (opts.passwordStdin) {
|
|
65
|
-
password = await readPasswordFromStdin();
|
|
66
|
-
if (!password) {
|
|
67
|
-
console.error(chalk.red("\n\u2717 No password was provided on stdin."));
|
|
68
|
-
process.exitCode = 1;
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (opts.password) {
|
|
73
|
-
console.log(chalk.yellow("\u26A0 Warning: --password can leak credentials via shell history/process list."));
|
|
74
|
-
console.log(chalk.yellow(" Prefer --password-stdin or the interactive masked prompt.\n"));
|
|
75
|
-
}
|
|
76
|
-
if (!email || !password) {
|
|
77
|
-
const answers = await inquirer.prompt([
|
|
78
|
-
...!email ? [{ type: "input", name: "email", message: "Email:" }] : [],
|
|
79
|
-
...!password ? [{ type: "password", name: "password", message: "Password:", mask: "*" }] : []
|
|
80
|
-
]);
|
|
81
|
-
email = email || answers.email;
|
|
82
|
-
password = password || answers.password;
|
|
83
|
-
}
|
|
84
|
-
const spinner = ora("Logging in...").start();
|
|
85
|
-
try {
|
|
86
|
-
const user = await login(email, password);
|
|
87
|
-
spinner.succeed(chalk.green(`Logged in as ${chalk.bold(user.name)} (${user.email})`));
|
|
88
|
-
} catch (loginErr) {
|
|
89
|
-
const msg = loginErr?.response?.data?.message || loginErr.message;
|
|
90
|
-
spinner.fail(chalk.red(`Login failed: ${msg}`));
|
|
91
|
-
process.exitCode = 1;
|
|
92
|
-
}
|
|
93
|
-
} catch (error) {
|
|
94
|
-
const msg = error?.response?.data?.message || error.message;
|
|
95
|
-
console.error(chalk.red(`
|
|
96
|
-
\u2717 Login failed: ${msg}`));
|
|
97
|
-
process.exitCode = 1;
|
|
98
|
-
}
|
|
99
|
-
});
|
|
100
|
-
program2.command("register").description("Create a new CLISHOP account").action(async () => {
|
|
101
|
-
try {
|
|
102
|
-
const answers = await inquirer.prompt([
|
|
103
|
-
{ type: "input", name: "name", message: "Full name:" },
|
|
104
|
-
{ type: "input", name: "email", message: "Email:" },
|
|
105
|
-
{
|
|
106
|
-
type: "password",
|
|
107
|
-
name: "password",
|
|
108
|
-
message: "Password:",
|
|
109
|
-
mask: "*"
|
|
110
|
-
},
|
|
111
|
-
{
|
|
112
|
-
type: "password",
|
|
113
|
-
name: "confirmPassword",
|
|
114
|
-
message: "Confirm password:",
|
|
115
|
-
mask: "*"
|
|
116
|
-
}
|
|
117
|
-
]);
|
|
118
|
-
if (answers.password !== answers.confirmPassword) {
|
|
119
|
-
console.error(chalk.red("\u2717 Passwords do not match."));
|
|
120
|
-
process.exitCode = 1;
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
const spinner = ora("Creating account...").start();
|
|
124
|
-
try {
|
|
125
|
-
const user = await register(answers.email, answers.password, answers.name);
|
|
126
|
-
spinner.succeed(chalk.green(`Account created! Welcome, ${chalk.bold(user.name)}.`));
|
|
127
|
-
} catch (regErr) {
|
|
128
|
-
const msg = regErr?.response?.data?.message || regErr.message;
|
|
129
|
-
spinner.fail(chalk.red(`Registration failed: ${msg}`));
|
|
130
|
-
process.exitCode = 1;
|
|
131
|
-
}
|
|
132
|
-
} catch (error) {
|
|
133
|
-
const msg = error?.response?.data?.message || error.message;
|
|
134
|
-
console.error(chalk.red(`
|
|
135
|
-
\u2717 Registration failed: ${msg}`));
|
|
136
|
-
process.exitCode = 1;
|
|
137
|
-
}
|
|
138
|
-
});
|
|
139
34
|
program2.command("logout").description("Log out of your CLISHOP account").action(async () => {
|
|
140
35
|
const spinner = ora("Logging out...").start();
|
|
141
36
|
await logout();
|
|
@@ -155,7 +50,7 @@ function registerAuthCommands(program2) {
|
|
|
155
50
|
});
|
|
156
51
|
program2.command("whoami").description("Show the currently logged-in user").action(async () => {
|
|
157
52
|
if (!await isLoggedIn()) {
|
|
158
|
-
console.log(chalk.yellow("Not
|
|
53
|
+
console.log(chalk.yellow("Not set up yet. Run: clishop setup"));
|
|
159
54
|
return;
|
|
160
55
|
}
|
|
161
56
|
const user = await getUserInfo();
|
|
@@ -171,7 +66,7 @@ function registerAuthCommands(program2) {
|
|
|
171
66
|
|
|
172
67
|
// src/commands/agent.ts
|
|
173
68
|
import chalk2 from "chalk";
|
|
174
|
-
import
|
|
69
|
+
import inquirer from "inquirer";
|
|
175
70
|
function printAgent(agent, isActive) {
|
|
176
71
|
const marker = isActive ? chalk2.green("\u25CF ") : " ";
|
|
177
72
|
console.log(`${marker}${chalk2.bold(agent.name)}`);
|
|
@@ -265,7 +160,7 @@ function registerAgentCommands(program2) {
|
|
|
265
160
|
chalk2.dim(" ") + chalk2.white("clishop agent spending-limit <amount>")
|
|
266
161
|
);
|
|
267
162
|
console.log();
|
|
268
|
-
const answers = await
|
|
163
|
+
const answers = await inquirer.prompt([
|
|
269
164
|
{
|
|
270
165
|
type: "number",
|
|
271
166
|
name: "maxOrderAmount",
|
|
@@ -377,7 +272,7 @@ function registerAgentCommands(program2) {
|
|
|
377
272
|
});
|
|
378
273
|
agent.command("delete <name>").alias("rm").description("Delete an agent").action(async (name) => {
|
|
379
274
|
try {
|
|
380
|
-
const { confirm } = await
|
|
275
|
+
const { confirm } = await inquirer.prompt([
|
|
381
276
|
{
|
|
382
277
|
type: "confirm",
|
|
383
278
|
name: "confirm",
|
|
@@ -400,7 +295,7 @@ function registerAgentCommands(program2) {
|
|
|
400
295
|
// src/commands/address.ts
|
|
401
296
|
import chalk3 from "chalk";
|
|
402
297
|
import ora2 from "ora";
|
|
403
|
-
import
|
|
298
|
+
import inquirer2 from "inquirer";
|
|
404
299
|
|
|
405
300
|
// src/countries.ts
|
|
406
301
|
var COUNTRY_ALIASES = {
|
|
@@ -677,7 +572,7 @@ function getCountryName(code) {
|
|
|
677
572
|
// src/commands/address.ts
|
|
678
573
|
async function askCountry() {
|
|
679
574
|
while (true) {
|
|
680
|
-
const { rawCountry } = await
|
|
575
|
+
const { rawCountry } = await inquirer2.prompt([
|
|
681
576
|
{
|
|
682
577
|
type: "input",
|
|
683
578
|
name: "rawCountry",
|
|
@@ -688,7 +583,7 @@ async function askCountry() {
|
|
|
688
583
|
const result = normalizeCountry(rawCountry.trim());
|
|
689
584
|
if (result.code && result.name) {
|
|
690
585
|
console.log(chalk3.green(` \u2713 Country: ${result.name} (${result.code})`));
|
|
691
|
-
const { confirm } = await
|
|
586
|
+
const { confirm } = await inquirer2.prompt([
|
|
692
587
|
{
|
|
693
588
|
type: "confirm",
|
|
694
589
|
name: "confirm",
|
|
@@ -748,7 +643,7 @@ Addresses for agent "${agent.name}":
|
|
|
748
643
|
address.command("add").description("Add a new address").action(async () => {
|
|
749
644
|
try {
|
|
750
645
|
const agent = getActiveAgent();
|
|
751
|
-
const answers = await
|
|
646
|
+
const answers = await inquirer2.prompt([
|
|
752
647
|
{ type: "input", name: "label", message: "Label (e.g. Home, Office):" },
|
|
753
648
|
{
|
|
754
649
|
type: "input",
|
|
@@ -785,10 +680,10 @@ Addresses for agent "${agent.name}":
|
|
|
785
680
|
{ type: "input", name: "region", message: "State / Province / Region (optional):" }
|
|
786
681
|
]);
|
|
787
682
|
const countryInfo = await askCountry();
|
|
788
|
-
const { instructionsInput } = await
|
|
683
|
+
const { instructionsInput } = await inquirer2.prompt([
|
|
789
684
|
{ type: "input", name: "instructionsInput", message: "Delivery instructions (optional):" }
|
|
790
685
|
]);
|
|
791
|
-
const { isCompanyAddr } = await
|
|
686
|
+
const { isCompanyAddr } = await inquirer2.prompt([
|
|
792
687
|
{
|
|
793
688
|
type: "confirm",
|
|
794
689
|
name: "isCompanyAddr",
|
|
@@ -798,7 +693,7 @@ Addresses for agent "${agent.name}":
|
|
|
798
693
|
]);
|
|
799
694
|
let companyAnswers = { companyName: "", vatNumber: "" };
|
|
800
695
|
if (isCompanyAddr) {
|
|
801
|
-
companyAnswers = await
|
|
696
|
+
companyAnswers = await inquirer2.prompt([
|
|
802
697
|
{
|
|
803
698
|
type: "input",
|
|
804
699
|
name: "companyName",
|
|
@@ -808,7 +703,7 @@ Addresses for agent "${agent.name}":
|
|
|
808
703
|
{ type: "input", name: "vatNumber", message: "VAT number (optional):" }
|
|
809
704
|
]);
|
|
810
705
|
}
|
|
811
|
-
const { setDefault } = await
|
|
706
|
+
const { setDefault } = await inquirer2.prompt([
|
|
812
707
|
{
|
|
813
708
|
type: "confirm",
|
|
814
709
|
name: "setDefault",
|
|
@@ -845,7 +740,7 @@ Addresses for agent "${agent.name}":
|
|
|
845
740
|
});
|
|
846
741
|
address.command("remove <id>").alias("rm").description("Remove an address by ID").action(async (id) => {
|
|
847
742
|
try {
|
|
848
|
-
const { confirm } = await
|
|
743
|
+
const { confirm } = await inquirer2.prompt([
|
|
849
744
|
{
|
|
850
745
|
type: "confirm",
|
|
851
746
|
name: "confirm",
|
|
@@ -886,9 +781,10 @@ import ora4 from "ora";
|
|
|
886
781
|
// src/commands/setup.ts
|
|
887
782
|
import chalk4 from "chalk";
|
|
888
783
|
import ora3 from "ora";
|
|
889
|
-
import
|
|
784
|
+
import inquirer3 from "inquirer";
|
|
890
785
|
import open from "open";
|
|
891
786
|
import { execFileSync } from "child_process";
|
|
787
|
+
import axios from "axios";
|
|
892
788
|
async function openBrowser(url) {
|
|
893
789
|
try {
|
|
894
790
|
if (process.platform === "win32") {
|
|
@@ -913,658 +809,150 @@ async function openBrowser(url) {
|
|
|
913
809
|
function divider(color = chalk4.cyan) {
|
|
914
810
|
console.log(" " + color("\u2500".repeat(48)));
|
|
915
811
|
}
|
|
916
|
-
function stepHeader(step, total, title) {
|
|
917
|
-
console.log();
|
|
918
|
-
divider();
|
|
919
|
-
console.log();
|
|
920
|
-
console.log(
|
|
921
|
-
chalk4.bold.white(` STEP ${step} of ${total}`) + chalk4.dim(" \xB7 ") + chalk4.bold(title)
|
|
922
|
-
);
|
|
923
|
-
console.log();
|
|
924
|
-
}
|
|
925
812
|
function registerSetupCommand(program2) {
|
|
926
813
|
program2.command("setup").description(
|
|
927
|
-
"
|
|
928
|
-
).action(async () => {
|
|
929
|
-
await runSetupWizard();
|
|
814
|
+
"Set up your CLISHOP account \u2014 links your payment method via a secure browser link"
|
|
815
|
+
).option("--email <email>", "Email address (skips prompt)").option("--name <name>", "Full name (skips prompt)").action(async (opts) => {
|
|
816
|
+
await runSetupWizard(opts.email, opts.name);
|
|
930
817
|
});
|
|
931
818
|
}
|
|
932
|
-
async function runSetupWizard() {
|
|
819
|
+
async function runSetupWizard(emailArg, nameArg) {
|
|
933
820
|
const config = getConfig();
|
|
821
|
+
const loggedIn = await isLoggedIn();
|
|
822
|
+
if (loggedIn) {
|
|
823
|
+
const user = await getUserInfo();
|
|
824
|
+
try {
|
|
825
|
+
const api = getApiClient();
|
|
826
|
+
const agent = getActiveAgent();
|
|
827
|
+
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
828
|
+
const methods = pmRes.data.paymentMethods || [];
|
|
829
|
+
if (methods.length > 0) {
|
|
830
|
+
console.log();
|
|
831
|
+
console.log(chalk4.green(` \u2713 Already set up as ${chalk4.bold(user?.name || user?.email || "unknown")} with a payment method linked.`));
|
|
832
|
+
console.log(chalk4.dim(" Nothing to do. Run ") + chalk4.white("clishop search <query>") + chalk4.dim(" to get started."));
|
|
833
|
+
console.log();
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
} catch {
|
|
837
|
+
}
|
|
838
|
+
console.log();
|
|
839
|
+
console.log(chalk4.green(` \u2713 Logged in as ${chalk4.bold(user?.name || user?.email || "unknown")}`));
|
|
840
|
+
console.log(chalk4.dim(" No payment method linked yet. Let's fix that."));
|
|
841
|
+
console.log();
|
|
842
|
+
await runPaymentLinkFlow(config);
|
|
843
|
+
return;
|
|
844
|
+
}
|
|
934
845
|
console.log();
|
|
935
846
|
divider(chalk4.cyan);
|
|
936
847
|
console.log();
|
|
937
848
|
console.log(chalk4.bold.cyan(" W E L C O M E T O C L I S H O P"));
|
|
938
849
|
console.log(chalk4.dim(" Order anything from your terminal."));
|
|
939
|
-
console.log(chalk4.dim(` Build: ${"2026-03-
|
|
850
|
+
console.log(chalk4.dim(` Build: ${"2026-03-31T19:16:20.769Z"}`));
|
|
940
851
|
console.log();
|
|
941
852
|
divider(chalk4.cyan);
|
|
942
853
|
console.log();
|
|
943
854
|
console.log(
|
|
944
|
-
chalk4.dim("
|
|
945
|
-
);
|
|
946
|
-
console.log(
|
|
947
|
-
chalk4.dim(" It only takes a minute. You can re-run it anytime with:")
|
|
948
|
-
);
|
|
949
|
-
console.log(chalk4.dim(" ") + chalk4.white("clishop setup"));
|
|
950
|
-
console.log();
|
|
951
|
-
console.log(
|
|
952
|
-
chalk4.bold.yellow(" \u{1F4CB} PATH Setup")
|
|
953
|
-
);
|
|
954
|
-
console.log(
|
|
955
|
-
chalk4.dim(" Make sure clishop is in your PATH so your AI agents can use it.")
|
|
855
|
+
chalk4.dim(" Set up your account in one step. You'll get a link to")
|
|
956
856
|
);
|
|
957
857
|
console.log(
|
|
958
|
-
chalk4.dim("
|
|
858
|
+
chalk4.dim(" securely link your payment method in the browser.")
|
|
959
859
|
);
|
|
960
860
|
console.log(
|
|
961
|
-
chalk4.dim("
|
|
861
|
+
chalk4.dim(" Your AI agent can then add addresses and place orders for you.")
|
|
962
862
|
);
|
|
863
|
+
console.log();
|
|
963
864
|
console.log(
|
|
964
|
-
chalk4.dim("
|
|
865
|
+
chalk4.dim(" By creating an account you agree to the CLISHOP")
|
|
965
866
|
);
|
|
966
867
|
console.log(
|
|
967
|
-
chalk4.dim("
|
|
868
|
+
chalk4.dim(" Terms & Conditions: ") + chalk4.cyan.underline("https://clishop.ai/terms")
|
|
968
869
|
);
|
|
969
870
|
console.log(
|
|
970
|
-
chalk4.dim("
|
|
871
|
+
chalk4.dim(" Privacy Policy: ") + chalk4.cyan.underline("https://clishop.ai/privacy")
|
|
971
872
|
);
|
|
972
873
|
console.log();
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
874
|
+
let email = emailArg;
|
|
875
|
+
let name = nameArg;
|
|
876
|
+
if (!email || !name) {
|
|
877
|
+
const answers = await inquirer3.prompt([
|
|
878
|
+
...!email ? [{ type: "input", name: "email", message: "Email:" }] : [],
|
|
879
|
+
...!name ? [{ type: "input", name: "name", message: "Your name:" }] : []
|
|
880
|
+
]);
|
|
881
|
+
email = email || answers.email;
|
|
882
|
+
name = name || answers.name;
|
|
883
|
+
}
|
|
884
|
+
const spinner = ora3("Creating your account and payment link...").start();
|
|
885
|
+
let setupUrl;
|
|
886
|
+
let deviceCode;
|
|
887
|
+
try {
|
|
888
|
+
const baseUrl2 = getApiBaseUrl();
|
|
889
|
+
const res = await axios.post(`${baseUrl2}/auth/setup-link`, { email, name });
|
|
890
|
+
setupUrl = res.data.setupUrl;
|
|
891
|
+
deviceCode = res.data.deviceCode;
|
|
892
|
+
spinner.stop();
|
|
893
|
+
} catch (error) {
|
|
894
|
+
const msg = error?.response?.data?.message || error.message;
|
|
895
|
+
spinner.fail(chalk4.red(`Setup failed: ${msg}`));
|
|
990
896
|
console.log();
|
|
991
|
-
console.log(
|
|
992
|
-
chalk4.dim(" Complete the setup there, then return here and run:")
|
|
993
|
-
);
|
|
994
|
-
console.log(chalk4.dim(" ") + chalk4.white("clishop login"));
|
|
897
|
+
console.log(chalk4.dim(" You can try again with: ") + chalk4.white("clishop setup"));
|
|
995
898
|
console.log();
|
|
996
|
-
|
|
997
|
-
if (!opened) {
|
|
998
|
-
console.log(
|
|
999
|
-
chalk4.yellow(" Could not open browser automatically. Please visit the link above.")
|
|
1000
|
-
);
|
|
1001
|
-
}
|
|
1002
|
-
config.set("setupCompleted", true);
|
|
899
|
+
process.exitCode = 1;
|
|
1003
900
|
return;
|
|
1004
901
|
}
|
|
1005
|
-
stepHeader(1, 5, "Account");
|
|
1006
|
-
let loggedIn = await isLoggedIn();
|
|
1007
|
-
if (loggedIn) {
|
|
1008
|
-
const user = await getUserInfo();
|
|
1009
|
-
console.log(
|
|
1010
|
-
chalk4.green(
|
|
1011
|
-
` \u2713 Already logged in as ${chalk4.bold(user?.name || user?.email || "unknown")}`
|
|
1012
|
-
)
|
|
1013
|
-
);
|
|
1014
|
-
console.log();
|
|
1015
|
-
const { continueAs } = await inquirer4.prompt([
|
|
1016
|
-
{
|
|
1017
|
-
type: "confirm",
|
|
1018
|
-
name: "continueAs",
|
|
1019
|
-
message: `Continue as ${user?.email}?`,
|
|
1020
|
-
default: true
|
|
1021
|
-
}
|
|
1022
|
-
]);
|
|
1023
|
-
if (!continueAs) {
|
|
1024
|
-
loggedIn = false;
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
if (!loggedIn) {
|
|
1028
|
-
const { authChoice } = await inquirer4.prompt([
|
|
1029
|
-
{
|
|
1030
|
-
type: "select",
|
|
1031
|
-
name: "authChoice",
|
|
1032
|
-
message: "Do you have a CLISHOP account?",
|
|
1033
|
-
choices: [
|
|
1034
|
-
{ name: "No \u2014 create a new account", value: "register" },
|
|
1035
|
-
{ name: "Yes \u2014 log in to existing account", value: "login" }
|
|
1036
|
-
]
|
|
1037
|
-
}
|
|
1038
|
-
]);
|
|
1039
|
-
if (authChoice === "register") {
|
|
1040
|
-
console.log();
|
|
1041
|
-
console.log(
|
|
1042
|
-
chalk4.dim(" By creating an account you agree to the CLISHOP")
|
|
1043
|
-
);
|
|
1044
|
-
console.log(
|
|
1045
|
-
chalk4.dim(" Terms & Conditions: ") + chalk4.cyan.underline("https://clishop.ai/terms")
|
|
1046
|
-
);
|
|
1047
|
-
console.log(
|
|
1048
|
-
chalk4.dim(" Privacy Policy: ") + chalk4.cyan.underline("https://clishop.ai/privacy")
|
|
1049
|
-
);
|
|
1050
|
-
console.log();
|
|
1051
|
-
const answers = await inquirer4.prompt([
|
|
1052
|
-
{ type: "input", name: "name", message: "Your name:" },
|
|
1053
|
-
{ type: "input", name: "email", message: "Email:" },
|
|
1054
|
-
{
|
|
1055
|
-
type: "password",
|
|
1056
|
-
name: "password",
|
|
1057
|
-
message: "Password:",
|
|
1058
|
-
mask: "*"
|
|
1059
|
-
},
|
|
1060
|
-
{
|
|
1061
|
-
type: "password",
|
|
1062
|
-
name: "confirmPassword",
|
|
1063
|
-
message: "Confirm password:",
|
|
1064
|
-
mask: "*"
|
|
1065
|
-
}
|
|
1066
|
-
]);
|
|
1067
|
-
if (answers.password !== answers.confirmPassword) {
|
|
1068
|
-
console.error(chalk4.red("\n \u2717 Passwords do not match."));
|
|
1069
|
-
console.log(
|
|
1070
|
-
chalk4.dim(" Run ") + chalk4.white("clishop setup") + chalk4.dim(" to try again.\n")
|
|
1071
|
-
);
|
|
1072
|
-
process.exitCode = 1;
|
|
1073
|
-
return;
|
|
1074
|
-
}
|
|
1075
|
-
const spinner = ora3("Creating your account...").start();
|
|
1076
|
-
try {
|
|
1077
|
-
const user = await register(
|
|
1078
|
-
answers.email,
|
|
1079
|
-
answers.password,
|
|
1080
|
-
answers.name
|
|
1081
|
-
);
|
|
1082
|
-
spinner.succeed(
|
|
1083
|
-
chalk4.green(
|
|
1084
|
-
`Account created! Welcome, ${chalk4.bold(user.name)}.`
|
|
1085
|
-
)
|
|
1086
|
-
);
|
|
1087
|
-
} catch (error) {
|
|
1088
|
-
spinner.fail(
|
|
1089
|
-
chalk4.red(
|
|
1090
|
-
`Registration failed: ${error?.response?.data?.message || error.message}`
|
|
1091
|
-
)
|
|
1092
|
-
);
|
|
1093
|
-
console.log();
|
|
1094
|
-
console.log(
|
|
1095
|
-
chalk4.dim(
|
|
1096
|
-
" Make sure the backend is running at: " + chalk4.white(config.get("apiBaseUrl"))
|
|
1097
|
-
)
|
|
1098
|
-
);
|
|
1099
|
-
console.log(
|
|
1100
|
-
chalk4.dim(" Then run ") + chalk4.white("clishop setup") + chalk4.dim(" again.\n")
|
|
1101
|
-
);
|
|
1102
|
-
process.exitCode = 1;
|
|
1103
|
-
return;
|
|
1104
|
-
}
|
|
1105
|
-
} else {
|
|
1106
|
-
const answers = await inquirer4.prompt([
|
|
1107
|
-
{ type: "input", name: "email", message: "Email:" },
|
|
1108
|
-
{
|
|
1109
|
-
type: "password",
|
|
1110
|
-
name: "password",
|
|
1111
|
-
message: "Password:",
|
|
1112
|
-
mask: "*"
|
|
1113
|
-
}
|
|
1114
|
-
]);
|
|
1115
|
-
const spinner = ora3("Logging in...").start();
|
|
1116
|
-
try {
|
|
1117
|
-
const user = await login(answers.email, answers.password);
|
|
1118
|
-
spinner.succeed(
|
|
1119
|
-
chalk4.green(`Logged in as ${chalk4.bold(user.name)}.`)
|
|
1120
|
-
);
|
|
1121
|
-
} catch (error) {
|
|
1122
|
-
spinner.fail(
|
|
1123
|
-
chalk4.red(
|
|
1124
|
-
`Login failed: ${error?.response?.data?.message || error.message}`
|
|
1125
|
-
)
|
|
1126
|
-
);
|
|
1127
|
-
console.log();
|
|
1128
|
-
console.log(
|
|
1129
|
-
chalk4.dim(
|
|
1130
|
-
" Make sure the backend is running at: " + chalk4.white(config.get("apiBaseUrl"))
|
|
1131
|
-
)
|
|
1132
|
-
);
|
|
1133
|
-
console.log(
|
|
1134
|
-
chalk4.dim(" Then run ") + chalk4.white("clishop setup") + chalk4.dim(" again.\n")
|
|
1135
|
-
);
|
|
1136
|
-
process.exitCode = 1;
|
|
1137
|
-
return;
|
|
1138
|
-
}
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
stepHeader(2, 5, "Agent");
|
|
1142
|
-
console.log(
|
|
1143
|
-
chalk4.dim(
|
|
1144
|
-
" Agents are safety profiles that control per-order limits and categories."
|
|
1145
|
-
)
|
|
1146
|
-
);
|
|
1147
|
-
console.log(
|
|
1148
|
-
chalk4.dim(" A default agent is ready. You can customize it or create a new one.")
|
|
1149
|
-
);
|
|
1150
|
-
console.log(
|
|
1151
|
-
chalk4.dim(" Default settings: ") + chalk4.white("$200 max per order") + chalk4.dim(", ") + chalk4.white("confirmation required") + chalk4.dim(" for every order.")
|
|
1152
|
-
);
|
|
1153
|
-
console.log(
|
|
1154
|
-
chalk4.dim(" When an order is placed, you'll receive an ") + chalk4.white("email") + chalk4.dim(" and can also confirm on the ") + chalk4.white("website") + chalk4.dim(".")
|
|
1155
|
-
);
|
|
1156
902
|
console.log();
|
|
1157
|
-
|
|
1158
|
-
{
|
|
1159
|
-
type: "confirm",
|
|
1160
|
-
name: "agentChoice",
|
|
1161
|
-
message: "Configure a custom agent instead?",
|
|
1162
|
-
default: false
|
|
1163
|
-
}
|
|
1164
|
-
]);
|
|
1165
|
-
if (agentChoice) {
|
|
1166
|
-
const answers = await inquirer4.prompt([
|
|
1167
|
-
{
|
|
1168
|
-
type: "input",
|
|
1169
|
-
name: "name",
|
|
1170
|
-
message: "Agent name:",
|
|
1171
|
-
validate: (v) => v.trim() ? true : "Name is required"
|
|
1172
|
-
},
|
|
1173
|
-
{
|
|
1174
|
-
type: "number",
|
|
1175
|
-
name: "maxOrderAmount",
|
|
1176
|
-
message: "Max order amount per order ($) (optional, default $200):",
|
|
1177
|
-
default: 200
|
|
1178
|
-
},
|
|
1179
|
-
{
|
|
1180
|
-
type: "confirm",
|
|
1181
|
-
name: "requireConfirmation",
|
|
1182
|
-
message: "Require confirmation before ordering?",
|
|
1183
|
-
default: true
|
|
1184
|
-
}
|
|
1185
|
-
]);
|
|
1186
|
-
const maxAmount = answers.maxOrderAmount || 200;
|
|
1187
|
-
if (answers.requireConfirmation) {
|
|
1188
|
-
console.log();
|
|
1189
|
-
console.log(
|
|
1190
|
-
chalk4.dim(" \u{1F512} When an order is placed you can confirm it via ") + chalk4.white("email") + chalk4.dim(" or on the ") + chalk4.white("website dashboard") + chalk4.dim(" \u2014 both are always available.")
|
|
1191
|
-
);
|
|
1192
|
-
}
|
|
1193
|
-
try {
|
|
1194
|
-
const agent = createAgent(answers.name.trim(), {
|
|
1195
|
-
maxOrderAmount: maxAmount,
|
|
1196
|
-
requireConfirmation: answers.requireConfirmation
|
|
1197
|
-
});
|
|
1198
|
-
setActiveAgent(agent.name);
|
|
1199
|
-
const syncSpinner = ora3("Syncing agent to backend...").start();
|
|
1200
|
-
await ensureAgentOnBackend(
|
|
1201
|
-
agent.name,
|
|
1202
|
-
maxAmount * 100,
|
|
1203
|
-
answers.requireConfirmation
|
|
1204
|
-
);
|
|
1205
|
-
syncSpinner.succeed(
|
|
1206
|
-
chalk4.green(
|
|
1207
|
-
`Agent "${chalk4.bold(agent.name)}" created and set as active.`
|
|
1208
|
-
)
|
|
1209
|
-
);
|
|
1210
|
-
} catch (error) {
|
|
1211
|
-
console.error(chalk4.red(`
|
|
1212
|
-
\u2717 ${error.message}`));
|
|
1213
|
-
console.log(chalk4.dim(" Continuing with the default agent."));
|
|
1214
|
-
}
|
|
1215
|
-
} else {
|
|
1216
|
-
console.log(chalk4.green(" \u2713 Using default agent (max $200/order, confirmation required)."));
|
|
1217
|
-
}
|
|
1218
|
-
stepHeader(3, 5, "Shipping Address");
|
|
1219
|
-
console.log(
|
|
1220
|
-
chalk4.dim(
|
|
1221
|
-
" Add an address so products can be delivered to you."
|
|
1222
|
-
)
|
|
1223
|
-
);
|
|
1224
|
-
console.log(
|
|
1225
|
-
chalk4.dim(
|
|
1226
|
-
" A shipping country is required for product searches to work correctly."
|
|
1227
|
-
)
|
|
1228
|
-
);
|
|
903
|
+
console.log(chalk4.bold(" Open this link to link your payment method:"));
|
|
1229
904
|
console.log();
|
|
1230
|
-
|
|
1231
|
-
let addressCountry = "";
|
|
1232
|
-
{
|
|
1233
|
-
const addr = await inquirer4.prompt([
|
|
1234
|
-
{
|
|
1235
|
-
type: "input",
|
|
1236
|
-
name: "label",
|
|
1237
|
-
message: "Label (e.g. Home, Office):",
|
|
1238
|
-
default: "Home"
|
|
1239
|
-
},
|
|
1240
|
-
{
|
|
1241
|
-
type: "input",
|
|
1242
|
-
name: "firstName",
|
|
1243
|
-
message: "First name:",
|
|
1244
|
-
validate: (v) => v.trim() ? true : "First name is required"
|
|
1245
|
-
},
|
|
1246
|
-
{
|
|
1247
|
-
type: "input",
|
|
1248
|
-
name: "lastName",
|
|
1249
|
-
message: "Last name:",
|
|
1250
|
-
validate: (v) => v.trim() ? true : "Last name is required"
|
|
1251
|
-
},
|
|
1252
|
-
{
|
|
1253
|
-
type: "input",
|
|
1254
|
-
name: "phone",
|
|
1255
|
-
message: "Phone number with country code (e.g. +32412345678, optional):"
|
|
1256
|
-
},
|
|
1257
|
-
{
|
|
1258
|
-
type: "input",
|
|
1259
|
-
name: "line1",
|
|
1260
|
-
message: "Street name and number:",
|
|
1261
|
-
validate: (v) => v.trim() ? true : "Required"
|
|
1262
|
-
},
|
|
1263
|
-
{
|
|
1264
|
-
type: "input",
|
|
1265
|
-
name: "line2",
|
|
1266
|
-
message: "Apartment, suite, floor, etc. (optional):"
|
|
1267
|
-
},
|
|
1268
|
-
{
|
|
1269
|
-
type: "input",
|
|
1270
|
-
name: "postalCode",
|
|
1271
|
-
message: "Postal / ZIP code:",
|
|
1272
|
-
validate: (v) => v.trim() ? true : "Required"
|
|
1273
|
-
},
|
|
1274
|
-
{
|
|
1275
|
-
type: "input",
|
|
1276
|
-
name: "city",
|
|
1277
|
-
message: "City:",
|
|
1278
|
-
validate: (v) => v.trim() ? true : "Required"
|
|
1279
|
-
},
|
|
1280
|
-
{
|
|
1281
|
-
type: "input",
|
|
1282
|
-
name: "region",
|
|
1283
|
-
message: "State / Province / Region (optional):"
|
|
1284
|
-
}
|
|
1285
|
-
]);
|
|
1286
|
-
let resolvedCountryCode = "";
|
|
1287
|
-
let resolvedCountryName = "";
|
|
1288
|
-
while (true) {
|
|
1289
|
-
const { rawCountry } = await inquirer4.prompt([
|
|
1290
|
-
{
|
|
1291
|
-
type: "input",
|
|
1292
|
-
name: "rawCountry",
|
|
1293
|
-
message: "Country (full name, e.g. Belgium, United States):",
|
|
1294
|
-
validate: (v) => v.trim() ? true : "Country is required"
|
|
1295
|
-
}
|
|
1296
|
-
]);
|
|
1297
|
-
const countryResult = normalizeCountry(rawCountry.trim());
|
|
1298
|
-
if (countryResult.code && countryResult.name) {
|
|
1299
|
-
console.log(chalk4.green(` \u2713 Country: ${countryResult.name} (${countryResult.code})`));
|
|
1300
|
-
const { confirmCountry } = await inquirer4.prompt([
|
|
1301
|
-
{
|
|
1302
|
-
type: "confirm",
|
|
1303
|
-
name: "confirmCountry",
|
|
1304
|
-
message: `Is "${countryResult.name}" correct?`,
|
|
1305
|
-
default: true
|
|
1306
|
-
}
|
|
1307
|
-
]);
|
|
1308
|
-
if (confirmCountry) {
|
|
1309
|
-
resolvedCountryCode = countryResult.code;
|
|
1310
|
-
resolvedCountryName = countryResult.name;
|
|
1311
|
-
break;
|
|
1312
|
-
}
|
|
1313
|
-
continue;
|
|
1314
|
-
}
|
|
1315
|
-
console.log(chalk4.yellow(` \u26A0 Could not recognize "${rawCountry}" as a known country.`));
|
|
1316
|
-
console.log(chalk4.dim(" Please try again with a full country name (e.g. Belgium, Germany, United States)."));
|
|
1317
|
-
}
|
|
1318
|
-
addressCountry = resolvedCountryCode;
|
|
1319
|
-
const { instructionsInput } = await inquirer4.prompt([
|
|
1320
|
-
{
|
|
1321
|
-
type: "input",
|
|
1322
|
-
name: "instructionsInput",
|
|
1323
|
-
message: "Delivery instructions (optional):"
|
|
1324
|
-
}
|
|
1325
|
-
]);
|
|
1326
|
-
const { isCompanySetup } = await inquirer4.prompt([
|
|
1327
|
-
{
|
|
1328
|
-
type: "confirm",
|
|
1329
|
-
name: "isCompanySetup",
|
|
1330
|
-
message: "Is this a company/business address?",
|
|
1331
|
-
default: false
|
|
1332
|
-
}
|
|
1333
|
-
]);
|
|
1334
|
-
let companyInfo = { companyName: "", vatNumber: "" };
|
|
1335
|
-
if (isCompanySetup) {
|
|
1336
|
-
companyInfo = await inquirer4.prompt([
|
|
1337
|
-
{
|
|
1338
|
-
type: "input",
|
|
1339
|
-
name: "companyName",
|
|
1340
|
-
message: "Company name:",
|
|
1341
|
-
validate: (v) => v.trim() ? true : "Required for company addresses"
|
|
1342
|
-
},
|
|
1343
|
-
{
|
|
1344
|
-
type: "input",
|
|
1345
|
-
name: "vatNumber",
|
|
1346
|
-
message: "VAT number (optional):"
|
|
1347
|
-
}
|
|
1348
|
-
]);
|
|
1349
|
-
}
|
|
1350
|
-
addressCity = addr.city;
|
|
1351
|
-
const spinner = ora3("Saving address...").start();
|
|
1352
|
-
try {
|
|
1353
|
-
const api = getApiClient();
|
|
1354
|
-
const agent = getActiveAgent();
|
|
1355
|
-
await ensureAgentOnBackend(agent.name);
|
|
1356
|
-
if (agent.name !== "default") {
|
|
1357
|
-
await ensureAgentOnBackend("default");
|
|
1358
|
-
}
|
|
1359
|
-
const res = await api.post("/addresses", {
|
|
1360
|
-
agent: agent.name,
|
|
1361
|
-
label: addr.label,
|
|
1362
|
-
firstName: addr.firstName.trim(),
|
|
1363
|
-
lastName: addr.lastName.trim(),
|
|
1364
|
-
phone: addr.phone || void 0,
|
|
1365
|
-
companyName: companyInfo.companyName || void 0,
|
|
1366
|
-
vatNumber: companyInfo.vatNumber || void 0,
|
|
1367
|
-
line1: addr.line1,
|
|
1368
|
-
line2: addr.line2 || void 0,
|
|
1369
|
-
city: addr.city,
|
|
1370
|
-
region: addr.region || void 0,
|
|
1371
|
-
postalCode: addr.postalCode,
|
|
1372
|
-
country: resolvedCountryCode,
|
|
1373
|
-
instructions: instructionsInput || void 0
|
|
1374
|
-
});
|
|
1375
|
-
const addressId = res.data.address.id;
|
|
1376
|
-
updateAgent(agent.name, { defaultAddressId: addressId });
|
|
1377
|
-
if (agent.name !== "default") {
|
|
1378
|
-
try {
|
|
1379
|
-
await api.post("/addresses", {
|
|
1380
|
-
agent: "default",
|
|
1381
|
-
label: addr.label,
|
|
1382
|
-
firstName: addr.firstName.trim(),
|
|
1383
|
-
lastName: addr.lastName.trim(),
|
|
1384
|
-
phone: addr.phone || void 0,
|
|
1385
|
-
companyName: companyInfo.companyName || void 0,
|
|
1386
|
-
vatNumber: companyInfo.vatNumber || void 0,
|
|
1387
|
-
line1: addr.line1,
|
|
1388
|
-
line2: addr.line2 || void 0,
|
|
1389
|
-
city: addr.city,
|
|
1390
|
-
region: addr.region || void 0,
|
|
1391
|
-
postalCode: addr.postalCode,
|
|
1392
|
-
country: resolvedCountryCode,
|
|
1393
|
-
instructions: instructionsInput || void 0
|
|
1394
|
-
});
|
|
1395
|
-
updateAgent("default", { defaultAddressId: addressId });
|
|
1396
|
-
} catch {
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
spinner.succeed(
|
|
1400
|
-
chalk4.green(
|
|
1401
|
-
`Address "${addr.label}" saved and set as default${agent.name !== "default" ? ` for both "${agent.name}" and "default" agents` : ""}.`
|
|
1402
|
-
)
|
|
1403
|
-
);
|
|
1404
|
-
} catch (error) {
|
|
1405
|
-
spinner.fail(
|
|
1406
|
-
chalk4.red(
|
|
1407
|
-
`Failed to save address: ${error?.response?.data?.message || error.message}`
|
|
1408
|
-
)
|
|
1409
|
-
);
|
|
1410
|
-
console.log(
|
|
1411
|
-
chalk4.dim(
|
|
1412
|
-
" You can add an address later with: " + chalk4.white("clishop address add")
|
|
1413
|
-
)
|
|
1414
|
-
);
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
stepHeader(4, 5, "Payment Method");
|
|
1418
|
-
console.log(
|
|
1419
|
-
chalk4.dim(
|
|
1420
|
-
" For security, payment details are entered through a secure web"
|
|
1421
|
-
)
|
|
1422
|
-
);
|
|
1423
|
-
console.log(
|
|
1424
|
-
chalk4.dim(" page. The CLI never sees your card number.")
|
|
1425
|
-
);
|
|
905
|
+
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
1426
906
|
console.log();
|
|
1427
|
-
const
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
name: "addPayment",
|
|
1431
|
-
message: "Set up a payment method now?",
|
|
1432
|
-
default: true
|
|
1433
|
-
}
|
|
1434
|
-
]);
|
|
1435
|
-
if (addPayment) {
|
|
1436
|
-
const spinner = ora3("Requesting secure payment setup link...").start();
|
|
1437
|
-
try {
|
|
1438
|
-
const api = getApiClient();
|
|
1439
|
-
const agent = getActiveAgent();
|
|
1440
|
-
await ensureAgentOnBackend(agent.name);
|
|
1441
|
-
const res = await api.post("/payment-methods/setup", {
|
|
1442
|
-
agent: agent.name
|
|
1443
|
-
});
|
|
1444
|
-
spinner.stop();
|
|
1445
|
-
const { setupUrl } = res.data;
|
|
1446
|
-
console.log();
|
|
1447
|
-
console.log(
|
|
1448
|
-
chalk4.bold(
|
|
1449
|
-
" Open this link in your browser to add a payment method:"
|
|
1450
|
-
)
|
|
1451
|
-
);
|
|
1452
|
-
console.log();
|
|
1453
|
-
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
1454
|
-
console.log();
|
|
1455
|
-
console.log(
|
|
1456
|
-
chalk4.dim(
|
|
1457
|
-
" Once done, verify with: " + chalk4.white("clishop payment list")
|
|
1458
|
-
)
|
|
1459
|
-
);
|
|
1460
|
-
const paymentOpened = await openBrowser(setupUrl);
|
|
1461
|
-
if (paymentOpened) {
|
|
1462
|
-
console.log(chalk4.dim(" (Browser opened automatically)"));
|
|
1463
|
-
}
|
|
1464
|
-
console.log();
|
|
1465
|
-
await inquirer4.prompt([
|
|
1466
|
-
{
|
|
1467
|
-
type: "input",
|
|
1468
|
-
name: "done",
|
|
1469
|
-
message: "Press Enter after completing the payment setup in your browser..."
|
|
1470
|
-
}
|
|
1471
|
-
]);
|
|
1472
|
-
const pollSpinner = ora3("Checking for your payment method...").start();
|
|
1473
|
-
try {
|
|
1474
|
-
const agent2 = getActiveAgent();
|
|
1475
|
-
await ensureAgentOnBackend(agent2.name);
|
|
1476
|
-
const pmRes = await api.get("/payment-methods", {
|
|
1477
|
-
params: { agent: agent2.name }
|
|
1478
|
-
});
|
|
1479
|
-
const methods = pmRes.data.paymentMethods || [];
|
|
1480
|
-
if (methods.length > 0) {
|
|
1481
|
-
const latest = methods[methods.length - 1];
|
|
1482
|
-
updateAgent(agent2.name, { defaultPaymentMethodId: latest.id });
|
|
1483
|
-
pollSpinner.succeed(
|
|
1484
|
-
chalk4.green(`Payment method "${latest.label}" found and set as default.`)
|
|
1485
|
-
);
|
|
1486
|
-
} else {
|
|
1487
|
-
pollSpinner.warn(
|
|
1488
|
-
chalk4.yellow("No payment method found yet. You can add one later with: clishop payment add")
|
|
1489
|
-
);
|
|
1490
|
-
}
|
|
1491
|
-
} catch {
|
|
1492
|
-
pollSpinner.warn(
|
|
1493
|
-
chalk4.yellow("Could not verify payment method. You can check with: clishop payment list")
|
|
1494
|
-
);
|
|
1495
|
-
}
|
|
1496
|
-
} catch (error) {
|
|
1497
|
-
spinner.fail(
|
|
1498
|
-
chalk4.red(
|
|
1499
|
-
`Could not get setup link: ${error?.response?.data?.message || error.message}`
|
|
1500
|
-
)
|
|
1501
|
-
);
|
|
1502
|
-
console.log(
|
|
1503
|
-
chalk4.dim(
|
|
1504
|
-
" You can set up payment later with: " + chalk4.white("clishop payment add")
|
|
1505
|
-
)
|
|
1506
|
-
);
|
|
1507
|
-
}
|
|
1508
|
-
} else {
|
|
1509
|
-
console.log(
|
|
1510
|
-
chalk4.dim(
|
|
1511
|
-
"\n You can set one up later with: " + chalk4.white("clishop payment add")
|
|
1512
|
-
)
|
|
1513
|
-
);
|
|
1514
|
-
}
|
|
1515
|
-
stepHeader(5, 5, "Your First Search");
|
|
1516
|
-
if (addressCity) {
|
|
1517
|
-
console.log(
|
|
1518
|
-
chalk4.dim(
|
|
1519
|
-
` Let's find something! Products can be shipped to ${chalk4.white(addressCity)}.`
|
|
1520
|
-
)
|
|
1521
|
-
);
|
|
1522
|
-
} else if (addressCountry) {
|
|
1523
|
-
console.log(
|
|
1524
|
-
chalk4.dim(
|
|
1525
|
-
` Let's find something! Searching products available in ${chalk4.white(addressCountry)}.`
|
|
1526
|
-
)
|
|
1527
|
-
);
|
|
907
|
+
const opened = await openBrowser(setupUrl);
|
|
908
|
+
if (opened) {
|
|
909
|
+
console.log(chalk4.dim(" (Browser opened automatically)"));
|
|
1528
910
|
} else {
|
|
1529
|
-
console.log(chalk4.
|
|
911
|
+
console.log(chalk4.yellow(" Could not open browser automatically. Please visit the link above."));
|
|
1530
912
|
}
|
|
1531
913
|
console.log();
|
|
1532
|
-
const
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
}
|
|
1539
|
-
]);
|
|
1540
|
-
if (searchQuery.trim()) {
|
|
914
|
+
const pollSpinner = ora3("Waiting for you to complete payment setup...").start();
|
|
915
|
+
const baseUrl = getApiBaseUrl();
|
|
916
|
+
const maxAttempts = 120;
|
|
917
|
+
let completed = false;
|
|
918
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
919
|
+
await new Promise((r) => setTimeout(r, 5e3));
|
|
1541
920
|
try {
|
|
1542
|
-
const
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
921
|
+
const res = await axios.post(`${baseUrl}/auth/device/poll`, { deviceCode });
|
|
922
|
+
const data = res.data;
|
|
923
|
+
if (data.status === "complete" && data.token && data.refreshToken && data.user) {
|
|
924
|
+
await storeAuthFromSetup({
|
|
925
|
+
token: data.token,
|
|
926
|
+
refreshToken: data.refreshToken,
|
|
927
|
+
user: data.user
|
|
928
|
+
});
|
|
929
|
+
config.set("setupCompleted", true);
|
|
930
|
+
pollSpinner.succeed(chalk4.green("Payment linked and account activated!"));
|
|
931
|
+
completed = true;
|
|
932
|
+
break;
|
|
933
|
+
}
|
|
934
|
+
if (data.status === "expired") {
|
|
935
|
+
pollSpinner.fail(chalk4.red("Setup link expired. Run ") + chalk4.white("clishop setup") + chalk4.red(" to try again."));
|
|
936
|
+
process.exitCode = 1;
|
|
937
|
+
return;
|
|
1559
938
|
}
|
|
939
|
+
} catch {
|
|
1560
940
|
}
|
|
1561
941
|
}
|
|
1562
|
-
|
|
942
|
+
if (!completed) {
|
|
943
|
+
pollSpinner.fail(chalk4.red("Timed out waiting for setup. Run ") + chalk4.white("clishop setup") + chalk4.red(" to try again."));
|
|
944
|
+
process.exitCode = 1;
|
|
945
|
+
return;
|
|
946
|
+
}
|
|
1563
947
|
console.log();
|
|
1564
948
|
divider(chalk4.green);
|
|
1565
949
|
console.log();
|
|
1566
950
|
console.log(chalk4.bold.green(" \u2713 You're all set!"));
|
|
1567
951
|
console.log();
|
|
952
|
+
console.log(chalk4.dim(" Your agent can now add addresses and place orders."));
|
|
953
|
+
console.log(chalk4.dim(" To add a shipping address manually:"));
|
|
954
|
+
console.log(chalk4.white(" clishop address add"));
|
|
955
|
+
console.log();
|
|
1568
956
|
console.log(chalk4.dim(" Here are some commands to get you started:"));
|
|
1569
957
|
console.log();
|
|
1570
958
|
console.log(
|
|
@@ -1576,20 +964,51 @@ async function runSetupWizard() {
|
|
|
1576
964
|
console.log(
|
|
1577
965
|
chalk4.white(" clishop order list ") + chalk4.dim("View your orders")
|
|
1578
966
|
);
|
|
1579
|
-
console.log(
|
|
1580
|
-
chalk4.white(" clishop agent list ") + chalk4.dim("Manage your agents")
|
|
1581
|
-
);
|
|
1582
967
|
console.log(
|
|
1583
968
|
chalk4.white(" clishop --help ") + chalk4.dim("See all commands")
|
|
1584
969
|
);
|
|
1585
970
|
console.log();
|
|
1586
|
-
console.log(
|
|
1587
|
-
chalk4.dim(" \u{1F4AC} Join our Discord community: ") + chalk4.cyan.underline("https://discord.gg/vwXMbzD4bx")
|
|
1588
|
-
);
|
|
1589
|
-
console.log();
|
|
1590
971
|
divider(chalk4.green);
|
|
1591
972
|
console.log();
|
|
1592
973
|
}
|
|
974
|
+
async function runPaymentLinkFlow(config) {
|
|
975
|
+
const spinner = ora3("Requesting secure payment setup link...").start();
|
|
976
|
+
try {
|
|
977
|
+
const api = getApiClient();
|
|
978
|
+
const agent = getActiveAgent();
|
|
979
|
+
await ensureAgentOnBackend(agent.name);
|
|
980
|
+
const res = await api.post("/payment-methods/setup", { agent: agent.name });
|
|
981
|
+
spinner.stop();
|
|
982
|
+
const { setupUrl } = res.data;
|
|
983
|
+
console.log();
|
|
984
|
+
console.log(chalk4.bold(" Open this link to link your payment method:"));
|
|
985
|
+
console.log();
|
|
986
|
+
console.log(" " + chalk4.cyan.underline(setupUrl));
|
|
987
|
+
console.log();
|
|
988
|
+
const opened = await openBrowser(setupUrl);
|
|
989
|
+
if (opened) {
|
|
990
|
+
console.log(chalk4.dim(" (Browser opened automatically)"));
|
|
991
|
+
}
|
|
992
|
+
console.log();
|
|
993
|
+
await inquirer3.prompt([
|
|
994
|
+
{ type: "input", name: "done", message: "Press Enter after completing payment setup in your browser..." }
|
|
995
|
+
]);
|
|
996
|
+
const checkSpinner = ora3("Checking for your payment method...").start();
|
|
997
|
+
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
998
|
+
const methods = pmRes.data.paymentMethods || [];
|
|
999
|
+
if (methods.length > 0) {
|
|
1000
|
+
const latest = methods[methods.length - 1];
|
|
1001
|
+
updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
|
|
1002
|
+
checkSpinner.succeed(chalk4.green(`Payment method "${latest.label}" linked and set as default.`));
|
|
1003
|
+
config.set("setupCompleted", true);
|
|
1004
|
+
} else {
|
|
1005
|
+
checkSpinner.warn(chalk4.yellow("No payment method found yet. Run ") + chalk4.white("clishop setup") + chalk4.yellow(" to try again."));
|
|
1006
|
+
}
|
|
1007
|
+
} catch (error) {
|
|
1008
|
+
spinner.fail(chalk4.red(`Could not get setup link: ${error?.response?.data?.message || error.message}`));
|
|
1009
|
+
}
|
|
1010
|
+
console.log();
|
|
1011
|
+
}
|
|
1593
1012
|
|
|
1594
1013
|
// src/commands/payment.ts
|
|
1595
1014
|
function registerPaymentCommands(program2) {
|
|
@@ -1606,7 +1025,7 @@ function registerPaymentCommands(program2) {
|
|
|
1606
1025
|
spinner.stop();
|
|
1607
1026
|
const methods = res.data.paymentMethods;
|
|
1608
1027
|
if (methods.length === 0) {
|
|
1609
|
-
console.log(chalk5.yellow("\nNo payment methods found.
|
|
1028
|
+
console.log(chalk5.yellow("\nNo payment methods found. Run: clishop setup\n"));
|
|
1610
1029
|
return;
|
|
1611
1030
|
}
|
|
1612
1031
|
console.log(chalk5.bold(`
|
|
@@ -1622,7 +1041,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1622
1041
|
handleApiError(error);
|
|
1623
1042
|
}
|
|
1624
1043
|
});
|
|
1625
|
-
payment.command("add").description("Add
|
|
1044
|
+
payment.command("add").description("Add an additional payment method (opens browser). First-time setup? Use 'clishop setup' instead.").action(async () => {
|
|
1626
1045
|
try {
|
|
1627
1046
|
const agent = getActiveAgent();
|
|
1628
1047
|
await ensureAgentOnBackend(agent.name);
|
|
@@ -1639,8 +1058,8 @@ Payment methods for agent "${agent.name}":
|
|
|
1639
1058
|
`));
|
|
1640
1059
|
console.log(chalk5.dim("The CLI never collects raw card details. Payment is set up via the secure web portal."));
|
|
1641
1060
|
console.log(chalk5.dim("Press Enter after completing the setup in your browser.\n"));
|
|
1642
|
-
const
|
|
1643
|
-
await
|
|
1061
|
+
const inquirer10 = (await import("inquirer")).default;
|
|
1062
|
+
await inquirer10.prompt([
|
|
1644
1063
|
{ type: "input", name: "done", message: "Press Enter when done..." }
|
|
1645
1064
|
]);
|
|
1646
1065
|
const checkSpinner = ora4("Checking for your payment method...").start();
|
|
@@ -1686,7 +1105,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1686
1105
|
// src/commands/search.ts
|
|
1687
1106
|
import chalk6 from "chalk";
|
|
1688
1107
|
import ora5 from "ora";
|
|
1689
|
-
import
|
|
1108
|
+
import inquirer4 from "inquirer";
|
|
1690
1109
|
function formatPrice(cents, currency) {
|
|
1691
1110
|
return new Intl.NumberFormat("en-US", {
|
|
1692
1111
|
style: "currency",
|
|
@@ -2477,7 +1896,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2477
1896
|
short: p.name.length > 40 ? p.name.slice(0, 37) + "..." : p.name
|
|
2478
1897
|
};
|
|
2479
1898
|
});
|
|
2480
|
-
const { selectedIds } = await
|
|
1899
|
+
const { selectedIds } = await inquirer4.prompt([
|
|
2481
1900
|
{
|
|
2482
1901
|
type: "checkbox",
|
|
2483
1902
|
name: "selectedIds",
|
|
@@ -2713,7 +2132,7 @@ Product Information \u2014 ${total} result(s)
|
|
|
2713
2132
|
// src/commands/order.ts
|
|
2714
2133
|
import chalk7 from "chalk";
|
|
2715
2134
|
import ora6 from "ora";
|
|
2716
|
-
import
|
|
2135
|
+
import inquirer5 from "inquirer";
|
|
2717
2136
|
function formatPrice2(cents, currency) {
|
|
2718
2137
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
2719
2138
|
}
|
|
@@ -2760,7 +2179,7 @@ function registerOrderCommands(program2) {
|
|
|
2760
2179
|
return;
|
|
2761
2180
|
}
|
|
2762
2181
|
if (!paymentId) {
|
|
2763
|
-
console.error(chalk7.red("\n\u2717 No payment method
|
|
2182
|
+
console.error(chalk7.red("\n\u2717 No payment method linked. Run: clishop setup"));
|
|
2764
2183
|
process.exitCode = 1;
|
|
2765
2184
|
return;
|
|
2766
2185
|
}
|
|
@@ -2821,7 +2240,7 @@ function registerOrderCommands(program2) {
|
|
|
2821
2240
|
console.log(` Total: ${chalk7.bold(formatPrice2(totalCents, product.currency))}`);
|
|
2822
2241
|
console.log(` Agent: ${agent.name}`);
|
|
2823
2242
|
console.log();
|
|
2824
|
-
const { confirm } = await
|
|
2243
|
+
const { confirm } = await inquirer5.prompt([
|
|
2825
2244
|
{
|
|
2826
2245
|
type: "confirm",
|
|
2827
2246
|
name: "confirm",
|
|
@@ -2968,7 +2387,7 @@ function registerOrderCommands(program2) {
|
|
|
2968
2387
|
});
|
|
2969
2388
|
order.command("cancel <id>").description("Cancel an order").action(async (id) => {
|
|
2970
2389
|
try {
|
|
2971
|
-
const { confirm } = await
|
|
2390
|
+
const { confirm } = await inquirer5.prompt([
|
|
2972
2391
|
{
|
|
2973
2392
|
type: "confirm",
|
|
2974
2393
|
name: "confirm",
|
|
@@ -2990,7 +2409,7 @@ function registerOrderCommands(program2) {
|
|
|
2990
2409
|
// src/commands/review.ts
|
|
2991
2410
|
import chalk8 from "chalk";
|
|
2992
2411
|
import ora7 from "ora";
|
|
2993
|
-
import
|
|
2412
|
+
import inquirer6 from "inquirer";
|
|
2994
2413
|
function renderStars2(rating) {
|
|
2995
2414
|
const filled = Math.round(rating);
|
|
2996
2415
|
const empty = 10 - filled;
|
|
@@ -3043,7 +2462,7 @@ function registerReviewCommands(program2) {
|
|
|
3043
2462
|
let storeReview = void 0;
|
|
3044
2463
|
for (const item of unreviewedItems) {
|
|
3045
2464
|
console.log(chalk8.bold(` Product: ${item.productName}`));
|
|
3046
|
-
const { wantReview } = await
|
|
2465
|
+
const { wantReview } = await inquirer6.prompt([
|
|
3047
2466
|
{
|
|
3048
2467
|
type: "confirm",
|
|
3049
2468
|
name: "wantReview",
|
|
@@ -3052,7 +2471,7 @@ function registerReviewCommands(program2) {
|
|
|
3052
2471
|
}
|
|
3053
2472
|
]);
|
|
3054
2473
|
if (!wantReview) continue;
|
|
3055
|
-
const answers = await
|
|
2474
|
+
const answers = await inquirer6.prompt([
|
|
3056
2475
|
{
|
|
3057
2476
|
type: "select",
|
|
3058
2477
|
name: "rating",
|
|
@@ -3083,7 +2502,7 @@ function registerReviewCommands(program2) {
|
|
|
3083
2502
|
}
|
|
3084
2503
|
if (!storeAlreadyReviewed) {
|
|
3085
2504
|
console.log(chalk8.bold(` Store: ${reviewable.store.name}`));
|
|
3086
|
-
const { wantStoreReview } = await
|
|
2505
|
+
const { wantStoreReview } = await inquirer6.prompt([
|
|
3087
2506
|
{
|
|
3088
2507
|
type: "confirm",
|
|
3089
2508
|
name: "wantStoreReview",
|
|
@@ -3092,7 +2511,7 @@ function registerReviewCommands(program2) {
|
|
|
3092
2511
|
}
|
|
3093
2512
|
]);
|
|
3094
2513
|
if (wantStoreReview) {
|
|
3095
|
-
const storeAnswers = await
|
|
2514
|
+
const storeAnswers = await inquirer6.prompt([
|
|
3096
2515
|
{
|
|
3097
2516
|
type: "select",
|
|
3098
2517
|
name: "rating",
|
|
@@ -3152,7 +2571,7 @@ function registerReviewCommands(program2) {
|
|
|
3152
2571
|
});
|
|
3153
2572
|
review.command("add <productId>").description("Write a review for a product").option("--order <orderId>", "Associate with an order").action(async (productId, opts) => {
|
|
3154
2573
|
try {
|
|
3155
|
-
const answers = await
|
|
2574
|
+
const answers = await inquirer6.prompt([
|
|
3156
2575
|
{
|
|
3157
2576
|
type: "select",
|
|
3158
2577
|
name: "rating",
|
|
@@ -3185,7 +2604,7 @@ function registerReviewCommands(program2) {
|
|
|
3185
2604
|
});
|
|
3186
2605
|
review.command("store <storeId>").description("Write a review for a store").option("--order <orderId>", "Associate with an order").action(async (storeId, opts) => {
|
|
3187
2606
|
try {
|
|
3188
|
-
const answers = await
|
|
2607
|
+
const answers = await inquirer6.prompt([
|
|
3189
2608
|
{
|
|
3190
2609
|
type: "select",
|
|
3191
2610
|
name: "rating",
|
|
@@ -3287,7 +2706,7 @@ function registerReviewCommands(program2) {
|
|
|
3287
2706
|
});
|
|
3288
2707
|
review.command("delete <reviewId>").alias("rm").description("Delete one of your reviews").option("--store", "Delete a store review").action(async (reviewId, opts) => {
|
|
3289
2708
|
try {
|
|
3290
|
-
const { confirm } = await
|
|
2709
|
+
const { confirm } = await inquirer6.prompt([
|
|
3291
2710
|
{
|
|
3292
2711
|
type: "confirm",
|
|
3293
2712
|
name: "confirm",
|
|
@@ -3526,7 +2945,7 @@ function registerStatusCommand(program2) {
|
|
|
3526
2945
|
program2.command("status").description("Show full account overview \u2014 user, agents, addresses, payment methods").option("--json", "Output raw JSON").action(async (opts) => {
|
|
3527
2946
|
try {
|
|
3528
2947
|
if (!await isLoggedIn()) {
|
|
3529
|
-
console.log(chalk11.yellow("\nNot
|
|
2948
|
+
console.log(chalk11.yellow("\nNot set up yet. Run: clishop setup\n"));
|
|
3530
2949
|
return;
|
|
3531
2950
|
}
|
|
3532
2951
|
const spinner = ora9("Fetching account overview...").start();
|
|
@@ -3598,7 +3017,7 @@ function registerStatusCommand(program2) {
|
|
|
3598
3017
|
console.log();
|
|
3599
3018
|
console.log(chalk11.bold(` \u{1F4B3} Payment Methods (${agent.paymentMethods.length})`));
|
|
3600
3019
|
if (agent.paymentMethods.length === 0) {
|
|
3601
|
-
console.log(chalk11.dim(" None \u2014 run: clishop
|
|
3020
|
+
console.log(chalk11.dim(" None \u2014 run: clishop setup"));
|
|
3602
3021
|
} else {
|
|
3603
3022
|
for (const pm of agent.paymentMethods) {
|
|
3604
3023
|
const isDefault = pm.id === agent.defaultPaymentMethodId;
|
|
@@ -3622,7 +3041,7 @@ function registerStatusCommand(program2) {
|
|
|
3622
3041
|
// src/commands/advertise.ts
|
|
3623
3042
|
import chalk12 from "chalk";
|
|
3624
3043
|
import ora10 from "ora";
|
|
3625
|
-
import
|
|
3044
|
+
import inquirer7 from "inquirer";
|
|
3626
3045
|
function formatPrice4(cents, currency) {
|
|
3627
3046
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
3628
3047
|
}
|
|
@@ -3646,7 +3065,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3646
3065
|
const agent = getActiveAgent();
|
|
3647
3066
|
console.log(chalk12.bold("\n \u{1F4E2} Advertise a Request\n"));
|
|
3648
3067
|
console.log(chalk12.dim(" Can't find what you need? Describe it and vendors will bid to fulfill it.\n"));
|
|
3649
|
-
const answers = await
|
|
3068
|
+
const answers = await inquirer7.prompt([
|
|
3650
3069
|
{
|
|
3651
3070
|
type: "input",
|
|
3652
3071
|
name: "title",
|
|
@@ -3693,7 +3112,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3693
3112
|
]);
|
|
3694
3113
|
let recurringNote;
|
|
3695
3114
|
if (answers.recurring) {
|
|
3696
|
-
const recAnswer = await
|
|
3115
|
+
const recAnswer = await inquirer7.prompt([
|
|
3697
3116
|
{
|
|
3698
3117
|
type: "input",
|
|
3699
3118
|
name: "recurringNote",
|
|
@@ -3702,7 +3121,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3702
3121
|
]);
|
|
3703
3122
|
recurringNote = recAnswer.recurringNote || void 0;
|
|
3704
3123
|
}
|
|
3705
|
-
const priceAnswers = await
|
|
3124
|
+
const priceAnswers = await inquirer7.prompt([
|
|
3706
3125
|
{
|
|
3707
3126
|
type: "input",
|
|
3708
3127
|
name: "bidPrice",
|
|
@@ -3711,7 +3130,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3711
3130
|
]);
|
|
3712
3131
|
let currency = "USD";
|
|
3713
3132
|
if (priceAnswers.bidPrice && parseFloat(priceAnswers.bidPrice) > 0) {
|
|
3714
|
-
const currencyAnswer = await
|
|
3133
|
+
const currencyAnswer = await inquirer7.prompt([
|
|
3715
3134
|
{
|
|
3716
3135
|
type: "list",
|
|
3717
3136
|
name: "currency",
|
|
@@ -3732,7 +3151,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3732
3151
|
}
|
|
3733
3152
|
]);
|
|
3734
3153
|
if (currencyAnswer.currency === "OTHER") {
|
|
3735
|
-
const customCurrency = await
|
|
3154
|
+
const customCurrency = await inquirer7.prompt([
|
|
3736
3155
|
{
|
|
3737
3156
|
type: "input",
|
|
3738
3157
|
name: "code",
|
|
@@ -3745,14 +3164,14 @@ function registerAdvertiseCommands(program2) {
|
|
|
3745
3164
|
currency = currencyAnswer.currency;
|
|
3746
3165
|
}
|
|
3747
3166
|
}
|
|
3748
|
-
const speedAnswer = await
|
|
3167
|
+
const speedAnswer = await inquirer7.prompt([
|
|
3749
3168
|
{
|
|
3750
3169
|
type: "input",
|
|
3751
3170
|
name: "speedDays",
|
|
3752
3171
|
message: "Desired delivery speed in days (optional):"
|
|
3753
3172
|
}
|
|
3754
3173
|
]);
|
|
3755
|
-
const returnAnswers = await
|
|
3174
|
+
const returnAnswers = await inquirer7.prompt([
|
|
3756
3175
|
{
|
|
3757
3176
|
type: "confirm",
|
|
3758
3177
|
name: "freeReturns",
|
|
@@ -3784,7 +3203,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3784
3203
|
addrChoices.push({ name: chalk12.dim(skipOption), value: skipOption });
|
|
3785
3204
|
const defaultAddr = addresses.find((a) => a.id === agent.defaultAddressId);
|
|
3786
3205
|
const defaultDisplay = defaultAddr ? `${defaultAddr.label} \u2014 ${defaultAddr.line1}` : "";
|
|
3787
|
-
const { selectedAddress } = await
|
|
3206
|
+
const { selectedAddress } = await inquirer7.prompt([
|
|
3788
3207
|
{
|
|
3789
3208
|
type: "list",
|
|
3790
3209
|
name: "selectedAddress",
|
|
@@ -3818,7 +3237,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3818
3237
|
// Default: all user's payment methods selected
|
|
3819
3238
|
}))
|
|
3820
3239
|
];
|
|
3821
|
-
const { selectedPayments } = await
|
|
3240
|
+
const { selectedPayments } = await inquirer7.prompt([
|
|
3822
3241
|
{
|
|
3823
3242
|
type: "checkbox",
|
|
3824
3243
|
name: "selectedPayments",
|
|
@@ -3832,7 +3251,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3832
3251
|
paymentMethods = JSON.stringify(selectedPayments);
|
|
3833
3252
|
}
|
|
3834
3253
|
} else {
|
|
3835
|
-
console.log(chalk12.dim(" No payment methods found.
|
|
3254
|
+
console.log(chalk12.dim(" No payment methods found. Run: clishop setup"));
|
|
3836
3255
|
}
|
|
3837
3256
|
} catch {
|
|
3838
3257
|
paySpinner.stop();
|
|
@@ -4085,7 +3504,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
4085
3504
|
if (bid.shippingDays != null) console.log(` Delivery: ${bid.shippingDays}-day`);
|
|
4086
3505
|
if (bid.note) console.log(` Note: ${bid.note}`);
|
|
4087
3506
|
console.log();
|
|
4088
|
-
const { confirm } = await
|
|
3507
|
+
const { confirm } = await inquirer7.prompt([
|
|
4089
3508
|
{
|
|
4090
3509
|
type: "confirm",
|
|
4091
3510
|
name: "confirm",
|
|
@@ -4106,7 +3525,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
4106
3525
|
});
|
|
4107
3526
|
advertise.command("reject <advertiseId> <bidId>").description("Reject a vendor's bid").action(async (advertiseId, bidId) => {
|
|
4108
3527
|
try {
|
|
4109
|
-
const { confirm } = await
|
|
3528
|
+
const { confirm } = await inquirer7.prompt([
|
|
4110
3529
|
{
|
|
4111
3530
|
type: "confirm",
|
|
4112
3531
|
name: "confirm",
|
|
@@ -4125,7 +3544,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
4125
3544
|
});
|
|
4126
3545
|
advertise.command("cancel <id>").description("Cancel an advertised request").action(async (id) => {
|
|
4127
3546
|
try {
|
|
4128
|
-
const { confirm } = await
|
|
3547
|
+
const { confirm } = await inquirer7.prompt([
|
|
4129
3548
|
{
|
|
4130
3549
|
type: "confirm",
|
|
4131
3550
|
name: "confirm",
|
|
@@ -4147,7 +3566,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
4147
3566
|
// src/commands/support.ts
|
|
4148
3567
|
import chalk13 from "chalk";
|
|
4149
3568
|
import ora11 from "ora";
|
|
4150
|
-
import
|
|
3569
|
+
import inquirer8 from "inquirer";
|
|
4151
3570
|
var CATEGORY_CHOICES = [
|
|
4152
3571
|
{ name: "General question", value: "general" },
|
|
4153
3572
|
{ name: "Damaged item", value: "damaged" },
|
|
@@ -4181,7 +3600,7 @@ function registerSupportCommands(program2) {
|
|
|
4181
3600
|
const support = program2.command("support").description("Manage support tickets for orders");
|
|
4182
3601
|
support.command("create <orderId>").alias("new").description("Create a support ticket for an order").action(async (orderId) => {
|
|
4183
3602
|
try {
|
|
4184
|
-
const answers = await
|
|
3603
|
+
const answers = await inquirer8.prompt([
|
|
4185
3604
|
{
|
|
4186
3605
|
type: "select",
|
|
4187
3606
|
name: "category",
|
|
@@ -4312,7 +3731,7 @@ function registerSupportCommands(program2) {
|
|
|
4312
3731
|
});
|
|
4313
3732
|
support.command("reply <ticketId>").description("Reply to a support ticket").action(async (ticketId) => {
|
|
4314
3733
|
try {
|
|
4315
|
-
const { message } = await
|
|
3734
|
+
const { message } = await inquirer8.prompt([
|
|
4316
3735
|
{
|
|
4317
3736
|
type: "editor",
|
|
4318
3737
|
name: "message",
|
|
@@ -4337,7 +3756,7 @@ function registerSupportCommands(program2) {
|
|
|
4337
3756
|
});
|
|
4338
3757
|
support.command("close <ticketId>").description("Close a resolved ticket").action(async (ticketId) => {
|
|
4339
3758
|
try {
|
|
4340
|
-
const { confirm } = await
|
|
3759
|
+
const { confirm } = await inquirer8.prompt([
|
|
4341
3760
|
{
|
|
4342
3761
|
type: "confirm",
|
|
4343
3762
|
name: "confirm",
|
|
@@ -4359,7 +3778,7 @@ function registerSupportCommands(program2) {
|
|
|
4359
3778
|
// src/commands/feedback.ts
|
|
4360
3779
|
import chalk14 from "chalk";
|
|
4361
3780
|
import ora12 from "ora";
|
|
4362
|
-
import
|
|
3781
|
+
import inquirer9 from "inquirer";
|
|
4363
3782
|
var STATUS_COLORS4 = {
|
|
4364
3783
|
open: chalk14.green,
|
|
4365
3784
|
acknowledged: chalk14.cyan,
|
|
@@ -4392,7 +3811,7 @@ function registerFeedbackCommands(program2) {
|
|
|
4392
3811
|
if (!title || !description || !stepsToReproduce || !actualBehavior || !expectedBehavior) {
|
|
4393
3812
|
console.log(chalk14.bold("\n\u{1F41B} Report a Bug\n"));
|
|
4394
3813
|
console.log(chalk14.dim("Help us fix issues by describing what went wrong.\n"));
|
|
4395
|
-
const answers = await
|
|
3814
|
+
const answers = await inquirer9.prompt([
|
|
4396
3815
|
...!title ? [{
|
|
4397
3816
|
type: "input",
|
|
4398
3817
|
name: "title",
|
|
@@ -4464,7 +3883,7 @@ function registerFeedbackCommands(program2) {
|
|
|
4464
3883
|
if (!title || !description) {
|
|
4465
3884
|
console.log(chalk14.bold("\n\u{1F4A1} Suggest an Improvement\n"));
|
|
4466
3885
|
console.log(chalk14.dim("Tell us how we can make CLISHOP better.\n"));
|
|
4467
|
-
const answers = await
|
|
3886
|
+
const answers = await inquirer9.prompt([
|
|
4468
3887
|
...!title ? [{
|
|
4469
3888
|
type: "input",
|
|
4470
3889
|
name: "title",
|
|
@@ -4589,7 +4008,7 @@ import chalk15 from "chalk";
|
|
|
4589
4008
|
import { join } from "path";
|
|
4590
4009
|
import { homedir } from "os";
|
|
4591
4010
|
import { mkdirSync } from "fs";
|
|
4592
|
-
import
|
|
4011
|
+
import axios2 from "axios";
|
|
4593
4012
|
function registerDoctorCommand(program2) {
|
|
4594
4013
|
program2.command("doctor").description("Check system compatibility and auth status").action(async () => {
|
|
4595
4014
|
const checks = [];
|
|
@@ -4620,11 +4039,11 @@ function registerDoctorCommand(program2) {
|
|
|
4620
4039
|
checks.push({
|
|
4621
4040
|
name: "Authenticated",
|
|
4622
4041
|
ok: !!token,
|
|
4623
|
-
detail: token ? "Token present" : "Not
|
|
4042
|
+
detail: token ? "Token present" : "Not set up \u2014 run: clishop setup"
|
|
4624
4043
|
});
|
|
4625
4044
|
const apiUrl = getApiBaseUrl();
|
|
4626
4045
|
try {
|
|
4627
|
-
await
|
|
4046
|
+
await axios2.get(`${apiUrl}/health`, { timeout: 5e3 });
|
|
4628
4047
|
checks.push({ name: "API reachable", ok: true, detail: apiUrl });
|
|
4629
4048
|
} catch {
|
|
4630
4049
|
checks.push({
|
|
@@ -4645,7 +4064,11 @@ function registerDoctorCommand(program2) {
|
|
|
4645
4064
|
// src/index.ts
|
|
4646
4065
|
var program = new Command();
|
|
4647
4066
|
program.name("clishop").version("1.3.1").description(
|
|
4648
|
-
chalk16.bold("CLISHOP") +
|
|
4067
|
+
chalk16.bold("CLISHOP") + ` \u2014 Order anything from your terminal.
|
|
4068
|
+
|
|
4069
|
+
Run 'clishop setup' to get started with a single payment link.
|
|
4070
|
+
Use agents to set safety limits, addresses, and payment methods.
|
|
4071
|
+
The "default" agent is used when no agent is specified.`
|
|
4649
4072
|
).option("--agent <name>", "Use a specific agent for this command").hook("preAction", (thisCommand) => {
|
|
4650
4073
|
const agentOpt = thisCommand.opts().agent;
|
|
4651
4074
|
if (agentOpt) {
|