clishop 1.5.2 → 1.5.4
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/README.md +12 -24
- package/dist/{chunk-EM4ZGZOU.js → chunk-UO2N5F5R.js} +19 -2
- package/dist/index.js +99 -130
- package/dist/mcp.js +10 -7
- package/openclaw/.mcp.json +8 -0
- package/openclaw/skills/clishop/SKILL.md +150 -0
- package/package.json +4 -2
- package/server.json +23 -0
package/README.md
CHANGED
|
@@ -33,7 +33,7 @@ CLISHOP is an open-source CLI that lets AI agents and humans search for products
|
|
|
33
33
|
|
|
34
34
|
- One query searches every store in the network. Results are filtered to what actually ships to your address.
|
|
35
35
|
- Set spending caps per order, require email confirmation before anything ships, or let it go through automatically — your call.
|
|
36
|
-
- Ships as a native [MCP server](https://modelcontextprotocol.io/) with
|
|
36
|
+
- Ships as a native [MCP server](https://modelcontextprotocol.io/) with 46 tools. Works with VS Code Copilot, Claude, Cursor, Windsurf, and anything else that speaks MCP.
|
|
37
37
|
- Can't find what you need? Post an advertise request and let vendors compete to fulfill it.
|
|
38
38
|
- Support tickets, product reviews, store reviews — all from the terminal.
|
|
39
39
|
- Anyone can sell on CLISHOP by deploying a [Dark Store](https://github.com/DavooxBv2/CLISHOP-DARKSTORE). No website needed.
|
|
@@ -76,33 +76,21 @@ npm link
|
|
|
76
76
|
|
|
77
77
|
You can create your account on [clishop.ai](https://clishop.ai) or do everything from the CLI.
|
|
78
78
|
|
|
79
|
-
###
|
|
79
|
+
### Setup
|
|
80
80
|
|
|
81
|
-
|
|
82
|
-
clishop setup
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
This starts the interactive setup flow, creates a resumable setup session, shows a secure payment link, and waits for completion.
|
|
81
|
+
Setup only needs an email address. Search first, then add your address and payment method when you're ready to buy.
|
|
86
82
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
For OpenClaw, MCP clients, Claude-style shells, and other tool runners, use the explicit setup session commands instead of scraping terminal output:
|
|
83
|
+
For OpenClaw, MCP clients, Claude-style shells, and other tool runners, use:
|
|
90
84
|
|
|
91
85
|
```bash
|
|
92
86
|
clishop setup start --email user@example.com --json
|
|
93
|
-
clishop setup status --setup-id <setup_id> --json
|
|
94
|
-
clishop setup wait --setup-id <setup_id> --timeout 300 --json
|
|
95
|
-
clishop setup cancel --setup-id <setup_id> --json
|
|
96
87
|
```
|
|
97
88
|
|
|
98
|
-
`setup start` returns immediately with
|
|
99
|
-
|
|
100
|
-
- `setup_id`: the resumable setup session handle for the agent
|
|
101
|
-
- `setup_url`: the link the human must open in a browser
|
|
102
|
-
- `expires_at`: when the session expires
|
|
103
|
-
- `poll_after_seconds`: suggested polling interval
|
|
89
|
+
`setup start` returns immediately with account-ready status and stores auth locally.
|
|
104
90
|
|
|
105
|
-
|
|
91
|
+
- Search products right away with `clishop search <query>`
|
|
92
|
+
- Add a shipping address later with `clishop address add`
|
|
93
|
+
- Add a payment method later with `clishop payment add`
|
|
106
94
|
|
|
107
95
|
After setup is complete, add a shipping address and start ordering:
|
|
108
96
|
|
|
@@ -196,17 +184,17 @@ npm run lint # Type-check
|
|
|
196
184
|
|
|
197
185
|
## MCP Server
|
|
198
186
|
|
|
199
|
-
CLISHOP ships as a native MCP server with
|
|
187
|
+
CLISHOP ships as a native MCP server with 46 tools. Any MCP-compatible client gets shopping capabilities out of the box.
|
|
200
188
|
|
|
201
189
|
```bash
|
|
202
190
|
clishop-mcp # If installed globally
|
|
203
191
|
npx -y clishop --mcp # Without installing
|
|
204
192
|
```
|
|
205
193
|
|
|
206
|
-
The MCP onboarding tools now follow the same
|
|
194
|
+
The MCP onboarding tools now follow the same email-first model:
|
|
207
195
|
|
|
208
|
-
- `setup`
|
|
209
|
-
- `setup_status`
|
|
196
|
+
- `setup` creates the account immediately from the email address
|
|
197
|
+
- `setup_status` remains available only for legacy setup IDs
|
|
210
198
|
|
|
211
199
|
See the [MCP setup guides](https://clishop.ai/docs#mcp-overview) for VS Code, Claude Desktop, Cursor, and Windsurf configuration.
|
|
212
200
|
|
|
@@ -155,10 +155,27 @@ async function postSetupRequest(path, body) {
|
|
|
155
155
|
}
|
|
156
156
|
async function startSetupSession(email) {
|
|
157
157
|
const data = await postSetupRequest("/auth/setup-link", { email });
|
|
158
|
-
|
|
158
|
+
const setupId = data.setupId || data.deviceCode || data.user?.id;
|
|
159
|
+
if (data.token && data.refreshToken && data.user && setupId) {
|
|
160
|
+
await storeAuthFromSetup({
|
|
161
|
+
token: data.token,
|
|
162
|
+
refreshToken: data.refreshToken,
|
|
163
|
+
user: data.user
|
|
164
|
+
});
|
|
165
|
+
return {
|
|
166
|
+
ok: true,
|
|
167
|
+
setup_id: setupId,
|
|
168
|
+
status: "completed",
|
|
169
|
+
next_action: "search_products",
|
|
170
|
+
expires_at: data.expiresAt,
|
|
171
|
+
poll_after_seconds: 0,
|
|
172
|
+
account_id: data.accountId || data.user.id,
|
|
173
|
+
human_message: data.humanMessage || "Account ready. Search now, then add address and payment when you are ready to buy."
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
if (!data.setupUrl || !setupId || !data.expiresIn || !data.pollInterval) {
|
|
159
177
|
throw new Error(data?.message || "Failed to create setup session.");
|
|
160
178
|
}
|
|
161
|
-
const setupId = data.setupId || data.deviceCode;
|
|
162
179
|
const expiresAt = data.expiresAt || new Date(Date.now() + data.expiresIn * 1e3).toISOString();
|
|
163
180
|
return {
|
|
164
181
|
ok: true,
|
package/dist/index.js
CHANGED
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
resolveBackend,
|
|
15
15
|
startSetupSession,
|
|
16
16
|
waitForSetupSession
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-UO2N5F5R.js";
|
|
18
18
|
import {
|
|
19
19
|
createAgent,
|
|
20
20
|
deleteAgent,
|
|
@@ -785,7 +785,6 @@ import ora3 from "ora";
|
|
|
785
785
|
|
|
786
786
|
// src/commands/setup.ts
|
|
787
787
|
import chalk4 from "chalk";
|
|
788
|
-
import inquirer3 from "inquirer";
|
|
789
788
|
import open from "open";
|
|
790
789
|
import { execFileSync } from "child_process";
|
|
791
790
|
var DEFAULT_SETUP_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
@@ -846,24 +845,51 @@ function printSetupLink(message, setupUrl) {
|
|
|
846
845
|
function printSetupEmailInstructions() {
|
|
847
846
|
console.log(chalk4.yellow(" Email is required to start setup."));
|
|
848
847
|
console.log();
|
|
849
|
-
console.log(chalk4.dim("
|
|
850
|
-
console.log(chalk4.white(" clishop setup user@example.com"));
|
|
851
|
-
console.log();
|
|
852
|
-
console.log(chalk4.dim(" Agent-safe JSON:"));
|
|
848
|
+
console.log(chalk4.dim(" Start setup with:"));
|
|
853
849
|
console.log(chalk4.white(" clishop setup start --email user@example.com --json"));
|
|
854
850
|
console.log();
|
|
855
851
|
}
|
|
856
852
|
function printSetupStartResult(result) {
|
|
853
|
+
if (result.status === "completed") {
|
|
854
|
+
console.log();
|
|
855
|
+
console.log(chalk4.bold(" Account created."));
|
|
856
|
+
if (result.account_id) {
|
|
857
|
+
console.log(chalk4.dim(` Account: ${result.account_id}`));
|
|
858
|
+
}
|
|
859
|
+
console.log();
|
|
860
|
+
console.log(chalk4.dim(result.human_message));
|
|
861
|
+
console.log();
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
857
864
|
console.log();
|
|
858
865
|
console.log(chalk4.bold(" Setup session created."));
|
|
859
866
|
console.log(chalk4.dim(` Setup ID: ${result.setup_id}`));
|
|
860
|
-
|
|
867
|
+
if (result.expires_at) {
|
|
868
|
+
console.log(chalk4.dim(` Expires: ${new Date(result.expires_at).toLocaleString()}`));
|
|
869
|
+
}
|
|
861
870
|
printSetupLink("Give this link to your human to configure the payment method:", result.setup_url);
|
|
862
871
|
console.log(chalk4.dim(" Check progress later with:"));
|
|
863
872
|
console.log(chalk4.white(` clishop setup status --setup-id ${result.setup_id}`));
|
|
864
873
|
console.log(chalk4.white(` clishop setup wait --setup-id ${result.setup_id}`));
|
|
865
874
|
console.log();
|
|
866
875
|
}
|
|
876
|
+
function printSetupReadyBanner(userLabel) {
|
|
877
|
+
console.log();
|
|
878
|
+
divider(chalk4.green);
|
|
879
|
+
console.log();
|
|
880
|
+
console.log(chalk4.bold.green(` \u2713 Account ready${userLabel ? ` for ${userLabel}` : ""}`));
|
|
881
|
+
console.log();
|
|
882
|
+
console.log(chalk4.dim(" Search first. Add an address and payment method only when you're ready to buy."));
|
|
883
|
+
console.log();
|
|
884
|
+
console.log(chalk4.dim(" Next steps:"));
|
|
885
|
+
console.log(chalk4.white(" clishop search <query> ") + chalk4.dim("Search for products"));
|
|
886
|
+
console.log(chalk4.white(" clishop address add ") + chalk4.dim("Add a shipping address later"));
|
|
887
|
+
console.log(chalk4.white(" clishop payment add ") + chalk4.dim("Add a payment method when needed"));
|
|
888
|
+
console.log(chalk4.white(" clishop buy <id> ") + chalk4.dim("Buy after choosing address + payment"));
|
|
889
|
+
console.log();
|
|
890
|
+
divider(chalk4.green);
|
|
891
|
+
console.log();
|
|
892
|
+
}
|
|
867
893
|
function printSetupStatusResult(result) {
|
|
868
894
|
console.log();
|
|
869
895
|
if (!result.ok) {
|
|
@@ -884,7 +910,7 @@ function printSetupStatusResult(result) {
|
|
|
884
910
|
console.log();
|
|
885
911
|
break;
|
|
886
912
|
case "completed":
|
|
887
|
-
console.log(chalk4.green(" \u2713
|
|
913
|
+
console.log(chalk4.green(" \u2713 Setup complete."));
|
|
888
914
|
console.log(chalk4.dim(` Setup ID: ${result.setup_id}`));
|
|
889
915
|
if (result.account_id) {
|
|
890
916
|
console.log(chalk4.dim(` Account: ${result.account_id}`));
|
|
@@ -947,6 +973,9 @@ async function runSetupStartCommand(email, json = false) {
|
|
|
947
973
|
}
|
|
948
974
|
try {
|
|
949
975
|
const result = await startSetupSession(normalizedEmail);
|
|
976
|
+
if (result.ok && result.status === "completed") {
|
|
977
|
+
getConfig().set("setupCompleted", true);
|
|
978
|
+
}
|
|
950
979
|
if (json) {
|
|
951
980
|
writeJson(sanitizeSetupPayload(result));
|
|
952
981
|
return;
|
|
@@ -1046,10 +1075,10 @@ async function runSetupWaitCommand(setupId, timeoutSeconds, json = false) {
|
|
|
1046
1075
|
}
|
|
1047
1076
|
}
|
|
1048
1077
|
function registerSetupCommand(program2) {
|
|
1049
|
-
const setup = program2.command("setup").description("
|
|
1078
|
+
const setup = program2.command("setup").description("Create your CLISHOP account or manage legacy setup sessions").argument("[email]", "Email address").action(async (email) => {
|
|
1050
1079
|
await runSetupWizard(email);
|
|
1051
1080
|
});
|
|
1052
|
-
setup.command("start").description("Create
|
|
1081
|
+
setup.command("start").description("Create your account and return immediately").requiredOption("--email <email>", "Email address").option("--json", "Output machine-readable JSON").action(async (opts) => {
|
|
1053
1082
|
await runSetupStartCommand(opts.email, opts.json);
|
|
1054
1083
|
});
|
|
1055
1084
|
setup.command("status").description("Check the status of a setup session").requiredOption("--setup-id <setupId>", "Setup session ID").option("--json", "Output machine-readable JSON").action(async (opts) => {
|
|
@@ -1076,25 +1105,8 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
|
|
|
1076
1105
|
const loggedIn = await isLoggedIn();
|
|
1077
1106
|
if (loggedIn) {
|
|
1078
1107
|
const user = await getUserInfo();
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
const agent = getActiveAgent();
|
|
1082
|
-
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
1083
|
-
const methods = pmRes.data.paymentMethods || [];
|
|
1084
|
-
if (methods.length > 0) {
|
|
1085
|
-
console.log();
|
|
1086
|
-
console.log(chalk4.green(` \u2713 Already set up as ${chalk4.bold(user?.name || user?.email || "unknown")} with a payment method linked.`));
|
|
1087
|
-
console.log(chalk4.dim(" Nothing to do. Run ") + chalk4.white("clishop search <query>") + chalk4.dim(" to get started."));
|
|
1088
|
-
console.log();
|
|
1089
|
-
return;
|
|
1090
|
-
}
|
|
1091
|
-
} catch {
|
|
1092
|
-
}
|
|
1093
|
-
console.log();
|
|
1094
|
-
console.log(chalk4.green(` \u2713 Logged in as ${chalk4.bold(user?.name || user?.email || "unknown")}`));
|
|
1095
|
-
console.log(chalk4.dim(" No payment method linked yet. Let's fix that."));
|
|
1096
|
-
console.log();
|
|
1097
|
-
await runPaymentLinkFlow(config);
|
|
1108
|
+
config.set("setupCompleted", true);
|
|
1109
|
+
printSetupReadyBanner(user?.name || user?.email || "unknown");
|
|
1098
1110
|
return;
|
|
1099
1111
|
}
|
|
1100
1112
|
console.log();
|
|
@@ -1102,14 +1114,14 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
|
|
|
1102
1114
|
console.log();
|
|
1103
1115
|
console.log(chalk4.bold.cyan(" W E L C O M E T O C L I S H O P"));
|
|
1104
1116
|
console.log(chalk4.dim(" Order anything from your terminal."));
|
|
1105
|
-
console.log(chalk4.dim(` npm: v${"1.5.
|
|
1106
|
-
console.log(chalk4.dim(` Build: ${"2026-04-
|
|
1117
|
+
console.log(chalk4.dim(` npm: v${"1.5.4"}`));
|
|
1118
|
+
console.log(chalk4.dim(` Build: ${"2026-04-05T11:19:52.708Z"}`));
|
|
1107
1119
|
console.log();
|
|
1108
1120
|
divider(chalk4.cyan);
|
|
1109
1121
|
console.log();
|
|
1110
|
-
console.log(chalk4.dim(" Set up your account
|
|
1111
|
-
console.log(chalk4.dim("
|
|
1112
|
-
console.log(chalk4.dim("
|
|
1122
|
+
console.log(chalk4.dim(" Set up your account with your email first."));
|
|
1123
|
+
console.log(chalk4.dim(" Search for products right away."));
|
|
1124
|
+
console.log(chalk4.dim(" Add your address and payment method later, only when you're ready to buy."));
|
|
1113
1125
|
console.log();
|
|
1114
1126
|
console.log(chalk4.dim(" By creating an account you agree to the CLISHOP"));
|
|
1115
1127
|
console.log(chalk4.dim(" Terms & Conditions: ") + chalk4.cyan.underline("https://clishop.ai/terms"));
|
|
@@ -1128,7 +1140,7 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
|
|
|
1128
1140
|
}
|
|
1129
1141
|
let startResult;
|
|
1130
1142
|
try {
|
|
1131
|
-
console.log(chalk4.dim(" Creating your account
|
|
1143
|
+
console.log(chalk4.dim(" Creating your account..."));
|
|
1132
1144
|
startResult = await startSetupSession(email);
|
|
1133
1145
|
} catch (error) {
|
|
1134
1146
|
console.log(chalk4.red(` \u2717 Setup failed: ${error?.message || "Unknown error"}`));
|
|
@@ -1138,6 +1150,11 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
|
|
|
1138
1150
|
process.exitCode = 1;
|
|
1139
1151
|
return;
|
|
1140
1152
|
}
|
|
1153
|
+
if (startResult.status === "completed") {
|
|
1154
|
+
config.set("setupCompleted", true);
|
|
1155
|
+
printSetupReadyBanner(email);
|
|
1156
|
+
return;
|
|
1157
|
+
}
|
|
1141
1158
|
printSetupStartResult(startResult);
|
|
1142
1159
|
console.log(chalk4.dim(" Waiting for you to complete payment setup..."));
|
|
1143
1160
|
console.log(chalk4.dim(" You can resume later with the setup ID shown above."));
|
|
@@ -1151,57 +1168,7 @@ async function runSetupWizard(emailArg, { json = false } = {}) {
|
|
|
1151
1168
|
return;
|
|
1152
1169
|
}
|
|
1153
1170
|
config.set("setupCompleted", true);
|
|
1154
|
-
|
|
1155
|
-
divider(chalk4.green);
|
|
1156
|
-
console.log();
|
|
1157
|
-
console.log(chalk4.bold.green(" \u2713 You're all set!"));
|
|
1158
|
-
console.log();
|
|
1159
|
-
console.log(chalk4.dim(" Your agent can now add addresses and place orders."));
|
|
1160
|
-
console.log(chalk4.dim(" To add a shipping address manually:"));
|
|
1161
|
-
console.log(chalk4.white(" clishop address add"));
|
|
1162
|
-
console.log();
|
|
1163
|
-
console.log(chalk4.dim(" Here are some commands to get you started:"));
|
|
1164
|
-
console.log();
|
|
1165
|
-
console.log(chalk4.white(" clishop search <query> ") + chalk4.dim("Search for products"));
|
|
1166
|
-
console.log(chalk4.white(" clishop buy <id> ") + chalk4.dim("Quick-buy a product"));
|
|
1167
|
-
console.log(chalk4.white(" clishop order list ") + chalk4.dim("View your orders"));
|
|
1168
|
-
console.log(chalk4.white(" clishop --help ") + chalk4.dim("See all commands"));
|
|
1169
|
-
console.log();
|
|
1170
|
-
divider(chalk4.green);
|
|
1171
|
-
console.log();
|
|
1172
|
-
}
|
|
1173
|
-
async function runPaymentLinkFlow(config) {
|
|
1174
|
-
console.log(chalk4.dim(" Requesting secure payment setup link..."));
|
|
1175
|
-
try {
|
|
1176
|
-
const api = getApiClient();
|
|
1177
|
-
const agent = getActiveAgent();
|
|
1178
|
-
await ensureAgentOnBackend(agent.name);
|
|
1179
|
-
const res = await api.post("/payment-methods/setup", { agent: agent.name });
|
|
1180
|
-
const { setupUrl } = res.data;
|
|
1181
|
-
printSetupLink("Open this link to link your payment method:", setupUrl);
|
|
1182
|
-
const opened = await openBrowser(setupUrl);
|
|
1183
|
-
if (opened) {
|
|
1184
|
-
console.log(chalk4.dim(" (Browser opened automatically)"));
|
|
1185
|
-
}
|
|
1186
|
-
console.log();
|
|
1187
|
-
await inquirer3.prompt([
|
|
1188
|
-
{ type: "input", name: "done", message: "Press Enter after completing payment setup in your browser..." }
|
|
1189
|
-
]);
|
|
1190
|
-
console.log(chalk4.dim(" Checking for your payment method..."));
|
|
1191
|
-
const pmRes = await api.get("/payment-methods", { params: { agent: agent.name } });
|
|
1192
|
-
const methods = pmRes.data.paymentMethods || [];
|
|
1193
|
-
if (methods.length > 0) {
|
|
1194
|
-
const latest = methods[methods.length - 1];
|
|
1195
|
-
updateAgent(agent.name, { defaultPaymentMethodId: latest.id });
|
|
1196
|
-
console.log(chalk4.green(` \u2713 Payment method "${latest.label}" linked and set as default.`));
|
|
1197
|
-
config.set("setupCompleted", true);
|
|
1198
|
-
} else {
|
|
1199
|
-
console.log(chalk4.yellow(" \u26A0 No payment method found yet. Run ") + chalk4.white("clishop setup") + chalk4.yellow(" to try again."));
|
|
1200
|
-
}
|
|
1201
|
-
} catch (error) {
|
|
1202
|
-
console.log(chalk4.red(` \u2717 Could not get setup link: ${error?.response?.data?.message || error.message}`));
|
|
1203
|
-
}
|
|
1204
|
-
console.log();
|
|
1171
|
+
printSetupReadyBanner(email);
|
|
1205
1172
|
}
|
|
1206
1173
|
|
|
1207
1174
|
// src/commands/payment.ts
|
|
@@ -1219,7 +1186,7 @@ function registerPaymentCommands(program2) {
|
|
|
1219
1186
|
spinner.stop();
|
|
1220
1187
|
const methods = res.data.paymentMethods;
|
|
1221
1188
|
if (methods.length === 0) {
|
|
1222
|
-
console.log(chalk5.yellow("\nNo payment methods found. Run: clishop
|
|
1189
|
+
console.log(chalk5.yellow("\nNo payment methods found. Run: clishop payment add\n"));
|
|
1223
1190
|
return;
|
|
1224
1191
|
}
|
|
1225
1192
|
console.log(chalk5.bold(`
|
|
@@ -1235,7 +1202,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1235
1202
|
handleApiError(error);
|
|
1236
1203
|
}
|
|
1237
1204
|
});
|
|
1238
|
-
payment.command("add").description("Add
|
|
1205
|
+
payment.command("add").description("Add a payment method (opens browser)").action(async () => {
|
|
1239
1206
|
try {
|
|
1240
1207
|
const agent = getActiveAgent();
|
|
1241
1208
|
await ensureAgentOnBackend(agent.name);
|
|
@@ -1252,8 +1219,8 @@ Payment methods for agent "${agent.name}":
|
|
|
1252
1219
|
`));
|
|
1253
1220
|
console.log(chalk5.dim("The CLI never collects raw card details. Payment is set up via the secure web portal."));
|
|
1254
1221
|
console.log(chalk5.dim("Press Enter after completing the setup in your browser.\n"));
|
|
1255
|
-
const
|
|
1256
|
-
await
|
|
1222
|
+
const inquirer9 = (await import("inquirer")).default;
|
|
1223
|
+
await inquirer9.prompt([
|
|
1257
1224
|
{ type: "input", name: "done", message: "Press Enter when done..." }
|
|
1258
1225
|
]);
|
|
1259
1226
|
const checkSpinner = ora3("Checking for your payment method...").start();
|
|
@@ -1299,7 +1266,7 @@ Payment methods for agent "${agent.name}":
|
|
|
1299
1266
|
// src/commands/search.ts
|
|
1300
1267
|
import chalk6 from "chalk";
|
|
1301
1268
|
import ora4 from "ora";
|
|
1302
|
-
import
|
|
1269
|
+
import inquirer3 from "inquirer";
|
|
1303
1270
|
function formatPrice(cents, currency) {
|
|
1304
1271
|
return new Intl.NumberFormat("en-US", {
|
|
1305
1272
|
style: "currency",
|
|
@@ -2092,7 +2059,7 @@ Results for "${query}" \u2014 ${result.total} found (page ${result.page})
|
|
|
2092
2059
|
short: p.name.length > 40 ? p.name.slice(0, 37) + "..." : p.name
|
|
2093
2060
|
};
|
|
2094
2061
|
});
|
|
2095
|
-
const { selectedIds } = await
|
|
2062
|
+
const { selectedIds } = await inquirer3.prompt([
|
|
2096
2063
|
{
|
|
2097
2064
|
type: "checkbox",
|
|
2098
2065
|
name: "selectedIds",
|
|
@@ -2328,7 +2295,7 @@ Product Information \u2014 ${total} result(s)
|
|
|
2328
2295
|
// src/commands/order.ts
|
|
2329
2296
|
import chalk7 from "chalk";
|
|
2330
2297
|
import ora5 from "ora";
|
|
2331
|
-
import
|
|
2298
|
+
import inquirer4 from "inquirer";
|
|
2332
2299
|
function formatPrice2(cents, currency) {
|
|
2333
2300
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
2334
2301
|
}
|
|
@@ -2406,7 +2373,10 @@ function registerOrderCommands(program2) {
|
|
|
2406
2373
|
return;
|
|
2407
2374
|
}
|
|
2408
2375
|
if (!paymentId) {
|
|
2409
|
-
console.error(chalk7.red("\n\u2717 No payment method linked
|
|
2376
|
+
console.error(chalk7.red("\n\u2717 No payment method linked for this agent."));
|
|
2377
|
+
console.error();
|
|
2378
|
+
console.error(chalk7.dim(" Add one when you're ready to buy with:"));
|
|
2379
|
+
console.error(chalk7.white(" clishop payment add"));
|
|
2410
2380
|
process.exitCode = 1;
|
|
2411
2381
|
return;
|
|
2412
2382
|
}
|
|
@@ -2467,7 +2437,7 @@ function registerOrderCommands(program2) {
|
|
|
2467
2437
|
console.log(` Total: ${chalk7.bold(formatPrice2(totalCents, product.currency))}`);
|
|
2468
2438
|
console.log(` Agent: ${agent.name}`);
|
|
2469
2439
|
console.log();
|
|
2470
|
-
const { confirm } = await
|
|
2440
|
+
const { confirm } = await inquirer4.prompt([
|
|
2471
2441
|
{
|
|
2472
2442
|
type: "confirm",
|
|
2473
2443
|
name: "confirm",
|
|
@@ -2614,7 +2584,7 @@ function registerOrderCommands(program2) {
|
|
|
2614
2584
|
});
|
|
2615
2585
|
order.command("cancel <id>").description("Cancel an order").action(async (id) => {
|
|
2616
2586
|
try {
|
|
2617
|
-
const { confirm } = await
|
|
2587
|
+
const { confirm } = await inquirer4.prompt([
|
|
2618
2588
|
{
|
|
2619
2589
|
type: "confirm",
|
|
2620
2590
|
name: "confirm",
|
|
@@ -2636,7 +2606,7 @@ function registerOrderCommands(program2) {
|
|
|
2636
2606
|
// src/commands/review.ts
|
|
2637
2607
|
import chalk8 from "chalk";
|
|
2638
2608
|
import ora6 from "ora";
|
|
2639
|
-
import
|
|
2609
|
+
import inquirer5 from "inquirer";
|
|
2640
2610
|
function renderStars2(rating) {
|
|
2641
2611
|
const filled = Math.round(rating);
|
|
2642
2612
|
const empty = 10 - filled;
|
|
@@ -2689,7 +2659,7 @@ function registerReviewCommands(program2) {
|
|
|
2689
2659
|
let storeReview = void 0;
|
|
2690
2660
|
for (const item of unreviewedItems) {
|
|
2691
2661
|
console.log(chalk8.bold(` Product: ${item.productName}`));
|
|
2692
|
-
const { wantReview } = await
|
|
2662
|
+
const { wantReview } = await inquirer5.prompt([
|
|
2693
2663
|
{
|
|
2694
2664
|
type: "confirm",
|
|
2695
2665
|
name: "wantReview",
|
|
@@ -2698,7 +2668,7 @@ function registerReviewCommands(program2) {
|
|
|
2698
2668
|
}
|
|
2699
2669
|
]);
|
|
2700
2670
|
if (!wantReview) continue;
|
|
2701
|
-
const answers = await
|
|
2671
|
+
const answers = await inquirer5.prompt([
|
|
2702
2672
|
{
|
|
2703
2673
|
type: "select",
|
|
2704
2674
|
name: "rating",
|
|
@@ -2729,7 +2699,7 @@ function registerReviewCommands(program2) {
|
|
|
2729
2699
|
}
|
|
2730
2700
|
if (!storeAlreadyReviewed) {
|
|
2731
2701
|
console.log(chalk8.bold(` Store: ${reviewable.store.name}`));
|
|
2732
|
-
const { wantStoreReview } = await
|
|
2702
|
+
const { wantStoreReview } = await inquirer5.prompt([
|
|
2733
2703
|
{
|
|
2734
2704
|
type: "confirm",
|
|
2735
2705
|
name: "wantStoreReview",
|
|
@@ -2738,7 +2708,7 @@ function registerReviewCommands(program2) {
|
|
|
2738
2708
|
}
|
|
2739
2709
|
]);
|
|
2740
2710
|
if (wantStoreReview) {
|
|
2741
|
-
const storeAnswers = await
|
|
2711
|
+
const storeAnswers = await inquirer5.prompt([
|
|
2742
2712
|
{
|
|
2743
2713
|
type: "select",
|
|
2744
2714
|
name: "rating",
|
|
@@ -2798,7 +2768,7 @@ function registerReviewCommands(program2) {
|
|
|
2798
2768
|
});
|
|
2799
2769
|
review.command("add <productId>").description("Write a review for a product").option("--order <orderId>", "Associate with an order").action(async (productId, opts) => {
|
|
2800
2770
|
try {
|
|
2801
|
-
const answers = await
|
|
2771
|
+
const answers = await inquirer5.prompt([
|
|
2802
2772
|
{
|
|
2803
2773
|
type: "select",
|
|
2804
2774
|
name: "rating",
|
|
@@ -2831,7 +2801,7 @@ function registerReviewCommands(program2) {
|
|
|
2831
2801
|
});
|
|
2832
2802
|
review.command("store <storeId>").description("Write a review for a store").option("--order <orderId>", "Associate with an order").action(async (storeId, opts) => {
|
|
2833
2803
|
try {
|
|
2834
|
-
const answers = await
|
|
2804
|
+
const answers = await inquirer5.prompt([
|
|
2835
2805
|
{
|
|
2836
2806
|
type: "select",
|
|
2837
2807
|
name: "rating",
|
|
@@ -2933,7 +2903,7 @@ function registerReviewCommands(program2) {
|
|
|
2933
2903
|
});
|
|
2934
2904
|
review.command("delete <reviewId>").alias("rm").description("Delete one of your reviews").option("--store", "Delete a store review").action(async (reviewId, opts) => {
|
|
2935
2905
|
try {
|
|
2936
|
-
const { confirm } = await
|
|
2906
|
+
const { confirm } = await inquirer5.prompt([
|
|
2937
2907
|
{
|
|
2938
2908
|
type: "confirm",
|
|
2939
2909
|
name: "confirm",
|
|
@@ -3245,7 +3215,7 @@ function registerStatusCommand(program2) {
|
|
|
3245
3215
|
console.log();
|
|
3246
3216
|
console.log(chalk11.bold(` \u{1F4B3} Payment Methods (${agent.paymentMethods.length})`));
|
|
3247
3217
|
if (agent.paymentMethods.length === 0) {
|
|
3248
|
-
console.log(chalk11.dim(" None \u2014 run: clishop
|
|
3218
|
+
console.log(chalk11.dim(" None \u2014 run: clishop payment add"));
|
|
3249
3219
|
} else {
|
|
3250
3220
|
for (const pm of agent.paymentMethods) {
|
|
3251
3221
|
const isDefault = pm.id === agent.defaultPaymentMethodId;
|
|
@@ -3269,7 +3239,7 @@ function registerStatusCommand(program2) {
|
|
|
3269
3239
|
// src/commands/advertise.ts
|
|
3270
3240
|
import chalk12 from "chalk";
|
|
3271
3241
|
import ora9 from "ora";
|
|
3272
|
-
import
|
|
3242
|
+
import inquirer6 from "inquirer";
|
|
3273
3243
|
function formatPrice4(cents, currency) {
|
|
3274
3244
|
return new Intl.NumberFormat("en-US", { style: "currency", currency }).format(cents / 100);
|
|
3275
3245
|
}
|
|
@@ -3293,7 +3263,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3293
3263
|
const agent = getActiveAgent();
|
|
3294
3264
|
console.log(chalk12.bold("\n \u{1F4E2} Advertise a Request\n"));
|
|
3295
3265
|
console.log(chalk12.dim(" Can't find what you need? Describe it and vendors will bid to fulfill it.\n"));
|
|
3296
|
-
const answers = await
|
|
3266
|
+
const answers = await inquirer6.prompt([
|
|
3297
3267
|
{
|
|
3298
3268
|
type: "input",
|
|
3299
3269
|
name: "title",
|
|
@@ -3340,7 +3310,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3340
3310
|
]);
|
|
3341
3311
|
let recurringNote;
|
|
3342
3312
|
if (answers.recurring) {
|
|
3343
|
-
const recAnswer = await
|
|
3313
|
+
const recAnswer = await inquirer6.prompt([
|
|
3344
3314
|
{
|
|
3345
3315
|
type: "input",
|
|
3346
3316
|
name: "recurringNote",
|
|
@@ -3349,7 +3319,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3349
3319
|
]);
|
|
3350
3320
|
recurringNote = recAnswer.recurringNote || void 0;
|
|
3351
3321
|
}
|
|
3352
|
-
const priceAnswers = await
|
|
3322
|
+
const priceAnswers = await inquirer6.prompt([
|
|
3353
3323
|
{
|
|
3354
3324
|
type: "input",
|
|
3355
3325
|
name: "bidPrice",
|
|
@@ -3358,7 +3328,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3358
3328
|
]);
|
|
3359
3329
|
let currency = "USD";
|
|
3360
3330
|
if (priceAnswers.bidPrice && parseFloat(priceAnswers.bidPrice) > 0) {
|
|
3361
|
-
const currencyAnswer = await
|
|
3331
|
+
const currencyAnswer = await inquirer6.prompt([
|
|
3362
3332
|
{
|
|
3363
3333
|
type: "list",
|
|
3364
3334
|
name: "currency",
|
|
@@ -3379,7 +3349,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3379
3349
|
}
|
|
3380
3350
|
]);
|
|
3381
3351
|
if (currencyAnswer.currency === "OTHER") {
|
|
3382
|
-
const customCurrency = await
|
|
3352
|
+
const customCurrency = await inquirer6.prompt([
|
|
3383
3353
|
{
|
|
3384
3354
|
type: "input",
|
|
3385
3355
|
name: "code",
|
|
@@ -3392,14 +3362,14 @@ function registerAdvertiseCommands(program2) {
|
|
|
3392
3362
|
currency = currencyAnswer.currency;
|
|
3393
3363
|
}
|
|
3394
3364
|
}
|
|
3395
|
-
const speedAnswer = await
|
|
3365
|
+
const speedAnswer = await inquirer6.prompt([
|
|
3396
3366
|
{
|
|
3397
3367
|
type: "input",
|
|
3398
3368
|
name: "speedDays",
|
|
3399
3369
|
message: "Desired delivery speed in days (optional):"
|
|
3400
3370
|
}
|
|
3401
3371
|
]);
|
|
3402
|
-
const returnAnswers = await
|
|
3372
|
+
const returnAnswers = await inquirer6.prompt([
|
|
3403
3373
|
{
|
|
3404
3374
|
type: "confirm",
|
|
3405
3375
|
name: "freeReturns",
|
|
@@ -3431,7 +3401,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3431
3401
|
addrChoices.push({ name: chalk12.dim(skipOption), value: skipOption });
|
|
3432
3402
|
const defaultAddr = addresses.find((a) => a.id === agent.defaultAddressId);
|
|
3433
3403
|
const defaultDisplay = defaultAddr ? `${defaultAddr.label} \u2014 ${defaultAddr.line1}` : "";
|
|
3434
|
-
const { selectedAddress } = await
|
|
3404
|
+
const { selectedAddress } = await inquirer6.prompt([
|
|
3435
3405
|
{
|
|
3436
3406
|
type: "list",
|
|
3437
3407
|
name: "selectedAddress",
|
|
@@ -3465,7 +3435,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3465
3435
|
// Default: all user's payment methods selected
|
|
3466
3436
|
}))
|
|
3467
3437
|
];
|
|
3468
|
-
const { selectedPayments } = await
|
|
3438
|
+
const { selectedPayments } = await inquirer6.prompt([
|
|
3469
3439
|
{
|
|
3470
3440
|
type: "checkbox",
|
|
3471
3441
|
name: "selectedPayments",
|
|
@@ -3479,7 +3449,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3479
3449
|
paymentMethods = JSON.stringify(selectedPayments);
|
|
3480
3450
|
}
|
|
3481
3451
|
} else {
|
|
3482
|
-
console.log(chalk12.dim(" No payment methods found. Run: clishop
|
|
3452
|
+
console.log(chalk12.dim(" No payment methods found. Run: clishop payment add"));
|
|
3483
3453
|
}
|
|
3484
3454
|
} catch {
|
|
3485
3455
|
paySpinner.stop();
|
|
@@ -3732,7 +3702,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3732
3702
|
if (bid.shippingDays != null) console.log(` Delivery: ${bid.shippingDays}-day`);
|
|
3733
3703
|
if (bid.note) console.log(` Note: ${bid.note}`);
|
|
3734
3704
|
console.log();
|
|
3735
|
-
const { confirm } = await
|
|
3705
|
+
const { confirm } = await inquirer6.prompt([
|
|
3736
3706
|
{
|
|
3737
3707
|
type: "confirm",
|
|
3738
3708
|
name: "confirm",
|
|
@@ -3753,7 +3723,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3753
3723
|
});
|
|
3754
3724
|
advertise.command("reject <advertiseId> <bidId>").description("Reject a vendor's bid").action(async (advertiseId, bidId) => {
|
|
3755
3725
|
try {
|
|
3756
|
-
const { confirm } = await
|
|
3726
|
+
const { confirm } = await inquirer6.prompt([
|
|
3757
3727
|
{
|
|
3758
3728
|
type: "confirm",
|
|
3759
3729
|
name: "confirm",
|
|
@@ -3772,7 +3742,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3772
3742
|
});
|
|
3773
3743
|
advertise.command("cancel <id>").description("Cancel an advertised request").action(async (id) => {
|
|
3774
3744
|
try {
|
|
3775
|
-
const { confirm } = await
|
|
3745
|
+
const { confirm } = await inquirer6.prompt([
|
|
3776
3746
|
{
|
|
3777
3747
|
type: "confirm",
|
|
3778
3748
|
name: "confirm",
|
|
@@ -3794,7 +3764,7 @@ function registerAdvertiseCommands(program2) {
|
|
|
3794
3764
|
// src/commands/support.ts
|
|
3795
3765
|
import chalk13 from "chalk";
|
|
3796
3766
|
import ora10 from "ora";
|
|
3797
|
-
import
|
|
3767
|
+
import inquirer7 from "inquirer";
|
|
3798
3768
|
var CATEGORY_CHOICES = [
|
|
3799
3769
|
{ name: "General question", value: "general" },
|
|
3800
3770
|
{ name: "Damaged item", value: "damaged" },
|
|
@@ -3828,7 +3798,7 @@ function registerSupportCommands(program2) {
|
|
|
3828
3798
|
const support = program2.command("support").description("Manage support tickets for orders");
|
|
3829
3799
|
support.command("create <orderId>").alias("new").description("Create a support ticket for an order").action(async (orderId) => {
|
|
3830
3800
|
try {
|
|
3831
|
-
const answers = await
|
|
3801
|
+
const answers = await inquirer7.prompt([
|
|
3832
3802
|
{
|
|
3833
3803
|
type: "select",
|
|
3834
3804
|
name: "category",
|
|
@@ -3959,7 +3929,7 @@ function registerSupportCommands(program2) {
|
|
|
3959
3929
|
});
|
|
3960
3930
|
support.command("reply <ticketId>").description("Reply to a support ticket").action(async (ticketId) => {
|
|
3961
3931
|
try {
|
|
3962
|
-
const { message } = await
|
|
3932
|
+
const { message } = await inquirer7.prompt([
|
|
3963
3933
|
{
|
|
3964
3934
|
type: "editor",
|
|
3965
3935
|
name: "message",
|
|
@@ -3984,7 +3954,7 @@ function registerSupportCommands(program2) {
|
|
|
3984
3954
|
});
|
|
3985
3955
|
support.command("close <ticketId>").description("Close a resolved ticket").action(async (ticketId) => {
|
|
3986
3956
|
try {
|
|
3987
|
-
const { confirm } = await
|
|
3957
|
+
const { confirm } = await inquirer7.prompt([
|
|
3988
3958
|
{
|
|
3989
3959
|
type: "confirm",
|
|
3990
3960
|
name: "confirm",
|
|
@@ -4006,7 +3976,7 @@ function registerSupportCommands(program2) {
|
|
|
4006
3976
|
// src/commands/feedback.ts
|
|
4007
3977
|
import chalk14 from "chalk";
|
|
4008
3978
|
import ora11 from "ora";
|
|
4009
|
-
import
|
|
3979
|
+
import inquirer8 from "inquirer";
|
|
4010
3980
|
var STATUS_COLORS4 = {
|
|
4011
3981
|
open: chalk14.green,
|
|
4012
3982
|
acknowledged: chalk14.cyan,
|
|
@@ -4039,7 +4009,7 @@ function registerFeedbackCommands(program2) {
|
|
|
4039
4009
|
if (!title || !description || !stepsToReproduce || !actualBehavior || !expectedBehavior) {
|
|
4040
4010
|
console.log(chalk14.bold("\n\u{1F41B} Report a Bug\n"));
|
|
4041
4011
|
console.log(chalk14.dim("Help us fix issues by describing what went wrong.\n"));
|
|
4042
|
-
const answers = await
|
|
4012
|
+
const answers = await inquirer8.prompt([
|
|
4043
4013
|
...!title ? [{
|
|
4044
4014
|
type: "input",
|
|
4045
4015
|
name: "title",
|
|
@@ -4111,7 +4081,7 @@ function registerFeedbackCommands(program2) {
|
|
|
4111
4081
|
if (!title || !description) {
|
|
4112
4082
|
console.log(chalk14.bold("\n\u{1F4A1} Suggest an Improvement\n"));
|
|
4113
4083
|
console.log(chalk14.dim("Tell us how we can make CLISHOP better.\n"));
|
|
4114
|
-
const answers = await
|
|
4084
|
+
const answers = await inquirer8.prompt([
|
|
4115
4085
|
...!title ? [{
|
|
4116
4086
|
type: "input",
|
|
4117
4087
|
name: "title",
|
|
@@ -4291,11 +4261,10 @@ function registerDoctorCommand(program2) {
|
|
|
4291
4261
|
|
|
4292
4262
|
// src/index.ts
|
|
4293
4263
|
var program = new Command();
|
|
4294
|
-
program.name("clishop").version("1.5.
|
|
4264
|
+
program.name("clishop").version("1.5.4").description(
|
|
4295
4265
|
chalk16.bold("CLISHOP") + ` \u2014 Order anything from your terminal.
|
|
4296
4266
|
|
|
4297
|
-
Run 'clishop setup'
|
|
4298
|
-
'clishop setup start --email <email> --json' for agent-safe setup.
|
|
4267
|
+
Run 'clishop setup <email>' or 'clishop setup start --email <email> --json' to create your account.
|
|
4299
4268
|
Use agents to set safety limits, addresses, and payment methods.
|
|
4300
4269
|
The "default" agent is used when no agent is specified.`
|
|
4301
4270
|
).option("--agent <name>", "Use a specific agent for this command").hook("preAction", (thisCommand) => {
|
|
@@ -4340,7 +4309,7 @@ async function main() {
|
|
|
4340
4309
|
}
|
|
4341
4310
|
console.error(
|
|
4342
4311
|
chalk16.yellow(
|
|
4343
|
-
"CLISHOP setup is incomplete. Run 'clishop setup start --email <email> --json' in non-interactive environments."
|
|
4312
|
+
"CLISHOP setup is incomplete. Run 'clishop setup start --email <email> --json' in non-interactive environments, or 'clishop setup <email>' in the CLI."
|
|
4344
4313
|
)
|
|
4345
4314
|
);
|
|
4346
4315
|
process.exit(1);
|
package/dist/mcp.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getUserInfo,
|
|
7
7
|
isLoggedIn,
|
|
8
8
|
startSetupSession
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-UO2N5F5R.js";
|
|
10
10
|
import {
|
|
11
11
|
__export,
|
|
12
12
|
getActiveAgent,
|
|
@@ -13813,7 +13813,7 @@ function safeCall(fn) {
|
|
|
13813
13813
|
var server = new McpServer(
|
|
13814
13814
|
{
|
|
13815
13815
|
name: "clishop",
|
|
13816
|
-
version: "1.
|
|
13816
|
+
version: "1.5.4"
|
|
13817
13817
|
},
|
|
13818
13818
|
{
|
|
13819
13819
|
capabilities: {
|
|
@@ -13823,7 +13823,7 @@ var server = new McpServer(
|
|
|
13823
13823
|
);
|
|
13824
13824
|
server.registerTool("setup", {
|
|
13825
13825
|
title: "Setup",
|
|
13826
|
-
description: "
|
|
13826
|
+
description: "Create or sign in a CLISHOP account using an email address. Setup now completes immediately; add address and payment later when the user is ready to buy.",
|
|
13827
13827
|
inputSchema: {
|
|
13828
13828
|
email: external_exports.string().email().describe("User's email address")
|
|
13829
13829
|
},
|
|
@@ -13835,15 +13835,18 @@ server.registerTool("setup", {
|
|
|
13835
13835
|
}, async (args) => {
|
|
13836
13836
|
return safeCall(async () => {
|
|
13837
13837
|
const data = await startSetupSession(args.email);
|
|
13838
|
+
if (data.ok && data.status === "completed") {
|
|
13839
|
+
getConfig().set("setupCompleted", true);
|
|
13840
|
+
}
|
|
13838
13841
|
return {
|
|
13839
13842
|
...data,
|
|
13840
|
-
message: "
|
|
13843
|
+
message: data.status === "completed" ? "Account ready. Search products now. Only add address and payment once the user decides to buy." : "Legacy setup session created. Call setup_status with the setup_id if you still need to wait for completion."
|
|
13841
13844
|
};
|
|
13842
13845
|
});
|
|
13843
13846
|
});
|
|
13844
13847
|
server.registerTool("setup_status", {
|
|
13845
13848
|
title: "Setup Status",
|
|
13846
|
-
description: "Check
|
|
13849
|
+
description: "Check a legacy setup session by setup_id. Modern email-only setup completes immediately and usually does not need this tool.",
|
|
13847
13850
|
inputSchema: {
|
|
13848
13851
|
setupId: external_exports.string().describe("The setup_id returned by the setup tool")
|
|
13849
13852
|
},
|
|
@@ -13994,7 +13997,7 @@ server.registerTool("buy_product", {
|
|
|
13994
13997
|
throw new Error("No shipping address set. Add one first via the add_address tool.");
|
|
13995
13998
|
}
|
|
13996
13999
|
if (!paymentId) {
|
|
13997
|
-
throw new Error("No payment method linked.
|
|
14000
|
+
throw new Error("No payment method linked. Add one with the payment method tools before placing the order.");
|
|
13998
14001
|
}
|
|
13999
14002
|
const api = getApiClient();
|
|
14000
14003
|
let product;
|
|
@@ -14330,7 +14333,7 @@ server.registerTool("account_status", {
|
|
|
14330
14333
|
return safeCall(async () => {
|
|
14331
14334
|
const loggedIn = await isLoggedIn();
|
|
14332
14335
|
if (!loggedIn) {
|
|
14333
|
-
return { loggedIn: false, message: "Not set up yet. Use the setup tool
|
|
14336
|
+
return { loggedIn: false, message: "Not set up yet. Use the setup tool with an email address to create the account." };
|
|
14334
14337
|
}
|
|
14335
14338
|
const api = getApiClient();
|
|
14336
14339
|
const cfg = getConfig();
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clishop
|
|
3
|
+
description: "Order anything from your terminal — search products, compare prices across stores, place orders, manage addresses and payments. Built for AI agents and humans."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# CLISHOP — Buy anything from your terminal
|
|
7
|
+
|
|
8
|
+
CLISHOP is an open-source MCP server and CLI that lets AI agents search for products across multiple stores, compare prices, and place real orders — all from the terminal.
|
|
9
|
+
|
|
10
|
+
**46 MCP tools** for the full shopping lifecycle: search → compare → buy → track → review → return.
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npm install -g clishop
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Use the email-first setup command:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
clishop setup start --email user@example.com --json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Then search products, and only add an address or payment method when the user is ready to buy.
|
|
25
|
+
|
|
26
|
+
### MCP Server
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
clishop-mcp # If installed globally
|
|
30
|
+
npx -y clishop --mcp # Without installing
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Tools
|
|
34
|
+
|
|
35
|
+
| Tool | Description | Read-only |
|
|
36
|
+
|------|-------------|-----------|
|
|
37
|
+
| `setup` | Create or sign in with an email address (completes immediately) | ❌ |
|
|
38
|
+
| `setup_status` | Check a legacy setup session by setup_id | ✅ |
|
|
39
|
+
| `search_products` | Search across all connected stores with filters (price, brand, category, shipping, ratings) | ✅ |
|
|
40
|
+
| `get_product` | Get detailed info about a specific product | ✅ |
|
|
41
|
+
| `buy_product` | Place an order (respects agent safety limits) | ❌ |
|
|
42
|
+
| `list_orders` | List orders, optionally filtered by status | ✅ |
|
|
43
|
+
| `get_order` | Full order details including tracking and shipments | ✅ |
|
|
44
|
+
| `cancel_order` | Cancel a pending or confirmed order | ❌ |
|
|
45
|
+
| `list_addresses` | List saved shipping addresses | ✅ |
|
|
46
|
+
| `add_address` | Add a new shipping address | ❌ |
|
|
47
|
+
| `remove_address` | Remove a saved address | ❌ |
|
|
48
|
+
| `set_default_address` | Set the default shipping address for the active agent | ❌ |
|
|
49
|
+
| `list_payment_methods` | List saved payment methods | ✅ |
|
|
50
|
+
| `remove_payment_method` | Remove a saved payment method | ❌ |
|
|
51
|
+
| `set_default_payment_method` | Set the default payment method for the active agent | ❌ |
|
|
52
|
+
| `list_stores` | Browse available stores | ✅ |
|
|
53
|
+
| `get_store` | View store details | ✅ |
|
|
54
|
+
| `store_catalog` | Browse a store's product catalog | ✅ |
|
|
55
|
+
| `account_status` | Full account overview (user, agents, addresses, payments) | ✅ |
|
|
56
|
+
| `list_agents` | List safety profiles (spending limits, allowed categories) | ✅ |
|
|
57
|
+
| `get_agent` | View details of a specific agent | ✅ |
|
|
58
|
+
| `create_agent` | Create a new agent (safety profile) with spending limits | ❌ |
|
|
59
|
+
| `update_agent` | Update an agent's settings (limits, categories, defaults) | ❌ |
|
|
60
|
+
| `switch_agent` | Switch the active agent | ❌ |
|
|
61
|
+
| `get_spending_limit` | View the current monthly spending limit | ✅ |
|
|
62
|
+
| `set_spending_limit` | Change the monthly spending limit | ❌ |
|
|
63
|
+
| `add_product_review` | Write a product review (1-10 rating) | ❌ |
|
|
64
|
+
| `add_store_review` | Write a store review (1-10 rating) | ❌ |
|
|
65
|
+
| `list_reviews` | List all your product and store reviews | ✅ |
|
|
66
|
+
| `get_product_rating` | View rating details for a product | ✅ |
|
|
67
|
+
| `get_store_rating` | View rating details for a store | ✅ |
|
|
68
|
+
| `delete_review` | Delete one of your reviews | ❌ |
|
|
69
|
+
| `create_advertise_request` | Post a request for vendors to bid on | ❌ |
|
|
70
|
+
| `list_advertise_requests` | List your advertised requests | ✅ |
|
|
71
|
+
| `get_advertise_request` | View an advertised request and its bids | ✅ |
|
|
72
|
+
| `accept_advertise_bid` | Accept a vendor's bid | ❌ |
|
|
73
|
+
| `reject_advertise_bid` | Reject a vendor's bid | ❌ |
|
|
74
|
+
| `cancel_advertise_request` | Cancel an open advertised request | ❌ |
|
|
75
|
+
| `create_support_ticket` | Create a support ticket for an order | ❌ |
|
|
76
|
+
| `list_support_tickets` | List support tickets | ✅ |
|
|
77
|
+
| `get_support_ticket` | View a support ticket and its message history | ✅ |
|
|
78
|
+
| `reply_to_support_ticket` | Send a reply to a support ticket | ❌ |
|
|
79
|
+
| `close_support_ticket` | Close a resolved support ticket | ❌ |
|
|
80
|
+
| `submit_feedback` | Report a bug or suggest an improvement | ❌ |
|
|
81
|
+
| `list_feedback` | List your submitted bug reports and suggestions | ✅ |
|
|
82
|
+
| `get_feedback` | View details of a specific feedback item | ✅ |
|
|
83
|
+
|
|
84
|
+
## External Endpoints
|
|
85
|
+
|
|
86
|
+
All network requests go to the CLISHOP API:
|
|
87
|
+
|
|
88
|
+
| Endpoint | Method | Data sent | Purpose |
|
|
89
|
+
|----------|--------|-----------|---------|
|
|
90
|
+
| `/auth/setup-link` | POST | Email address | Create account / sign in |
|
|
91
|
+
| `/products/search` | GET | Search query, filters (category, brand, price range, country) | Product search |
|
|
92
|
+
| `/products/:id` | GET | Product ID | Product details |
|
|
93
|
+
| `/products/extended/:id` | GET | Product ID | Extended product lookup across vendor stores |
|
|
94
|
+
| `/orders` | GET | Status filter, page | List user's orders |
|
|
95
|
+
| `/orders` | POST | Product ID, quantity, address ID, payment ID, agent name | Place an order |
|
|
96
|
+
| `/orders/:id` | GET | Order ID | Order details |
|
|
97
|
+
| `/orders/:id/tracking` | GET | Order ID | Shipment tracking |
|
|
98
|
+
| `/orders/:id/cancel` | POST | Order ID | Cancel an order |
|
|
99
|
+
| `/addresses` | GET | Agent name | List addresses |
|
|
100
|
+
| `/addresses` | POST | Full address fields (name, street, city, country, etc.) | Add address |
|
|
101
|
+
| `/addresses/:id` | DELETE | Address ID | Remove address |
|
|
102
|
+
| `/payment-methods` | GET | Agent name | List payment methods |
|
|
103
|
+
| `/payment-methods/:id` | DELETE | Payment method ID | Remove payment method |
|
|
104
|
+
| `/stores` | GET | Query, filters | Browse stores |
|
|
105
|
+
| `/stores/:id` | GET | Store ID/slug | Store details |
|
|
106
|
+
| `/stores/:id/products` | GET | Query, filters | Store catalog |
|
|
107
|
+
| `/agents` | GET | — | List agents |
|
|
108
|
+
| `/spending-limit` | GET/PATCH | Limit in cents | Get/set spending limit |
|
|
109
|
+
| `/products/:id/reviews` | POST | Rating, title, body | Product review |
|
|
110
|
+
| `/stores/:id/reviews` | POST | Rating, title, body | Store review |
|
|
111
|
+
| `/reviews/mine` | GET | — | List own reviews |
|
|
112
|
+
| `/products/:id/rating` | GET | — | Product rating details |
|
|
113
|
+
| `/stores/:id/rating` | GET | — | Store rating details |
|
|
114
|
+
| `/advertise` | GET/POST | Title, description, brand, quantity, max bid price | Advertise requests |
|
|
115
|
+
| `/advertise/:id` | GET | — | Advertise request details |
|
|
116
|
+
| `/advertise/:id/bids/:id/accept` | POST | — | Accept bid |
|
|
117
|
+
| `/advertise/:id/bids/:id/reject` | POST | — | Reject bid |
|
|
118
|
+
| `/advertise/:id/cancel` | POST | — | Cancel advertise request |
|
|
119
|
+
| `/support` | GET/POST | Ticket details or status filter | Support tickets |
|
|
120
|
+
| `/support/:id` | GET | — | Support ticket details |
|
|
121
|
+
| `/support/:id/reply` | POST | Message | Reply to support ticket |
|
|
122
|
+
| `/support/:id/status` | PATCH | Status | Close support ticket |
|
|
123
|
+
| `/feedback` | GET/POST | Feedback type, title, description | Feedback |
|
|
124
|
+
| `/feedback/:id` | GET | — | Feedback details |
|
|
125
|
+
|
|
126
|
+
All requests are sent over **HTTPS** to `https://clishop-backend.vercel.app/api`.
|
|
127
|
+
|
|
128
|
+
## Security & Privacy
|
|
129
|
+
|
|
130
|
+
- **Authentication:** Session tokens are stored in the OS keychain via [keytar](https://github.com/nicknisi/keytar), never in plain-text config files.
|
|
131
|
+
- **No local data collection:** CLISHOP does not collect analytics, telemetry, or tracking data locally.
|
|
132
|
+
- **Agent safety profiles:** Spending limits (`maxOrderAmount`), category allow/block lists, and confirmation requirements are enforced client-side before any order is placed.
|
|
133
|
+
- **Data sent to API:** Only the data required for each operation (search queries, addresses, order details) is sent to the CLISHOP backend API. No additional metadata is collected.
|
|
134
|
+
- **Vendor stores:** When extended search is enabled, the CLISHOP backend fans out search queries to registered vendor Dark Stores in real-time. Product data flows through the CLISHOP API — the CLI never contacts vendor stores directly.
|
|
135
|
+
|
|
136
|
+
## Trust Statement
|
|
137
|
+
|
|
138
|
+
By using this skill, your search queries, shipping addresses, payment method references, and order details are sent to the CLISHOP API (`clishop-backend.vercel.app`). The API acts as a gateway to registered vendor stores. No data is sold or shared with third parties beyond what is necessary to fulfill orders.
|
|
139
|
+
|
|
140
|
+
## Model Invocation Note
|
|
141
|
+
|
|
142
|
+
This skill is designed for autonomous invocation by AI agents via the Model Context Protocol (MCP). When an MCP client (e.g. Claude Desktop, Cursor, VS Code Copilot) calls these tools, the agent may search for products, place orders, and manage account data on the user's behalf — subject to the safety thresholds configured in the user's agent profile.
|
|
143
|
+
|
|
144
|
+
## Links
|
|
145
|
+
|
|
146
|
+
- 🌐 [clishop.ai](https://clishop.ai)
|
|
147
|
+
- 📖 [Docs](https://clishop.ai/docs)
|
|
148
|
+
- 💬 [Discord](https://discord.gg/vwXMbzD4bx)
|
|
149
|
+
- 🏪 [Dark Store template](https://github.com/DavooxBv2/CLISHOP-DARKSTORE)
|
|
150
|
+
- 📦 [npm](https://www.npmjs.com/package/clishop)
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clishop",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.4",
|
|
4
4
|
"mcpName": "io.github.StefDCL/clishop",
|
|
5
5
|
"description": "CLISHOP — Order anything from your terminal",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"files": [
|
|
8
|
-
"dist"
|
|
8
|
+
"dist",
|
|
9
|
+
"openclaw",
|
|
10
|
+
"server.json"
|
|
9
11
|
],
|
|
10
12
|
"bin": {
|
|
11
13
|
"clishop": "dist/index.js",
|
package/server.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
+
"name": "io.github.StefDCL/clishop",
|
|
4
|
+
"description": "Order anything from your terminal — search, buy, track, and manage via MCP tools.",
|
|
5
|
+
"repository": {
|
|
6
|
+
"url": "https://github.com/DavooxBv2/CLISHOP",
|
|
7
|
+
"source": "github"
|
|
8
|
+
},
|
|
9
|
+
"version": "1.5.4",
|
|
10
|
+
"packages": [
|
|
11
|
+
{
|
|
12
|
+
"registryType": "npm",
|
|
13
|
+
"identifier": "clishop",
|
|
14
|
+
"version": "1.5.4",
|
|
15
|
+
"runtime": "node",
|
|
16
|
+
"args": ["--mcp"],
|
|
17
|
+
"transport": {
|
|
18
|
+
"type": "stdio"
|
|
19
|
+
},
|
|
20
|
+
"environmentVariables": []
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|