@qverisai/cli 0.5.0 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,9 +29,24 @@ export const ERROR_CODES = {
29
29
  },
30
30
  PARAMS_INVALID_JSON: {
31
31
  message: "Invalid JSON in --params",
32
- hint: "Check JSON syntax in --params value",
32
+ hint: "Check JSON syntax in --params value, or pass a file with --params @params.json",
33
33
  exit: EX_USAGE,
34
34
  },
35
+ INIT_PARAMS_REQUIRED: {
36
+ message: "Init could not infer safe parameters for the selected capability",
37
+ hint: "Run 'qveris inspect 1' to review required params, then rerun 'qveris init --resume --params <json>'",
38
+ exit: EX_USAGE,
39
+ },
40
+ TOOL_CALL_FAILED: {
41
+ message: "Capability call failed",
42
+ hint: "Review the error, adjust --params, then rerun 'qveris init --resume --params <json>'",
43
+ exit: EX_UNAVAILABLE,
44
+ },
45
+ PROVIDER_FAILURE: {
46
+ message: "Remote provider failed",
47
+ hint: "Try another discovered capability with 'qveris inspect 2' and 'qveris call 2', or rerun discovery with a broader query",
48
+ exit: EX_UNAVAILABLE,
49
+ },
35
50
  TOOL_NOT_FOUND: {
36
51
  message: "Tool not found",
37
52
  hint: "Run 'qveris discover' to find available tools",
@@ -44,12 +59,12 @@ export const ERROR_CODES = {
44
59
  },
45
60
  CREDITS_INSUFFICIENT: {
46
61
  message: "Insufficient credits",
47
- hint: "Purchase credits at https://qveris.ai/pricing",
62
+ hint: "Purchase credits at https://qveris.ai/pricing, then confirm balance with 'qveris credits'",
48
63
  exit: EX_NOPERM,
49
64
  },
50
65
  SESSION_EXPIRED: {
51
66
  message: "Session expired",
52
- hint: "Run 'qveris discover' to start a new session",
67
+ hint: "Run 'qveris discover' or 'qveris init' to start a new session",
53
68
  exit: EX_USAGE,
54
69
  },
55
70
  };
package/src/main.mjs CHANGED
@@ -52,6 +52,11 @@ export async function main(argv) {
52
52
  await runCall(rest[0], flags);
53
53
  break;
54
54
  }
55
+ case "init": {
56
+ const { runInit } = await import("./commands/init.mjs");
57
+ await runInit(rest.join(" "), flags);
58
+ break;
59
+ }
55
60
  case "login": {
56
61
  const { runLogin } = await import("./commands/login.mjs");
57
62
  await runLogin(flags);
@@ -90,6 +95,14 @@ export async function main(argv) {
90
95
  await runConfig(subcommand, subArgs, flags);
91
96
  break;
92
97
  }
98
+ case "mcp": {
99
+ const subcommand = rest[0];
100
+ const subArgs = rest.slice(1);
101
+ if (!subcommand) { console.error(" Usage: qveris mcp <configure|validate> [target]"); process.exitCode = 2; return; }
102
+ const { runMcp } = await import("./commands/mcp.mjs");
103
+ await runMcp(subcommand, subArgs, flags);
104
+ break;
105
+ }
93
106
  case "interactive":
94
107
  case "repl": {
95
108
  const { runInteractive } = await import("./commands/interactive.mjs");
@@ -129,6 +142,7 @@ const VALUE_FLAGS = {
129
142
  "api-key": "apiKey", "base-url": "baseUrl", timeout: "timeout",
130
143
  limit: "limit", "discovery-id": "discoveryId", params: "params",
131
144
  "max-size": "maxSize", codegen: "codegen", token: "token",
145
+ query: "query", "tool-id": "toolId", target: "target", output: "output",
132
146
  mode: "mode", "start-date": "startDate", "end-date": "endDate",
133
147
  bucket: "bucket", "execution-id": "executionId", "search-id": "searchId",
134
148
  "event-type": "eventType", kind: "kind", success: "success",
@@ -192,6 +206,18 @@ function extractGlobalFlags(args) {
192
206
  flags.version = true; break;
193
207
  case "--dry-run":
194
208
  flags.dryRun = true; break;
209
+ case "--write":
210
+ flags.write = true; break;
211
+ case "--print":
212
+ flags.print = true; break;
213
+ case "--include-key":
214
+ flags.includeKey = true; break;
215
+ case "--validate":
216
+ flags.validate = true; break;
217
+ case "--probe":
218
+ flags.probe = true; break;
219
+ case "--resume":
220
+ flags.resume = true; break;
195
221
  case "--no-browser":
196
222
  flags.noBrowser = true; break;
197
223
  case "--clear":
@@ -214,6 +240,14 @@ function extractGlobalFlags(args) {
214
240
  flags.codegen = takeNext(args, i++, arg); break;
215
241
  case "--token":
216
242
  flags.token = takeNext(args, i++, arg); break;
243
+ case "--target":
244
+ flags.target = takeNext(args, i++, arg); break;
245
+ case "--output":
246
+ flags.output = takeNext(args, i++, arg); break;
247
+ case "--query":
248
+ flags.query = takeNext(args, i++, arg); break;
249
+ case "--tool-id":
250
+ flags.toolId = takeNext(args, i++, arg); break;
217
251
  case "--mode":
218
252
  flags.mode = takeNext(args, i++, arg); break;
219
253
  case "--start-date":
@@ -262,6 +296,7 @@ function printUsage(flags = {}) {
262
296
  qveris <command> [args] [flags]
263
297
 
264
298
  ${bold("Core Commands:")}
299
+ ${cyan("init")} Guided first-call wizard
265
300
  ${cyan("discover")} <query> Find capabilities by natural language
266
301
  ${cyan("inspect")} <tool_id|index> View tool details, parameters, and stats
267
302
  ${cyan("call")} <tool_id|index> Execute a capability
@@ -276,6 +311,7 @@ function printUsage(flags = {}) {
276
311
 
277
312
  ${bold("Configuration:")}
278
313
  ${cyan("config")} set|get|list|reset Manage CLI settings
314
+ ${cyan("mcp")} configure|validate Generate and validate MCP client config
279
315
 
280
316
  ${bold("Utilities:")}
281
317
  ${cyan("interactive")} Launch interactive REPL mode
@@ -288,6 +324,14 @@ function printUsage(flags = {}) {
288
324
  --api-key <key> Override API key
289
325
  --base-url <url> Override API base URL
290
326
  --timeout <seconds> Request timeout
327
+ --target <target> MCP target: cursor | claude-desktop | claude-code | opencode | openclaw | generic
328
+ --output <path> MCP config output path
329
+ --write Write MCP config to disk
330
+ --include-key Include resolved API key instead of placeholder
331
+ --probe Start MCP server and verify visible tools during validation
332
+ --query <query> Init discovery query override
333
+ --tool-id <id> Init selected capability override
334
+ --resume Resume init from the last discovery session
291
335
  --mode <mode> summary | search | export-file for usage/ledger
292
336
  --start-date <date> Usage/ledger range start (YYYY-MM-DD)
293
337
  --end-date <date> Usage/ledger range end (YYYY-MM-DD)
@@ -304,10 +348,15 @@ function printUsage(flags = {}) {
304
348
  QVERIS_BASE_URL Custom API base URL
305
349
 
306
350
  ${bold("Examples:")}
351
+ qveris init
352
+ qveris init --query "weather forecast API"
353
+ qveris init --resume --params '{"city": "London"}'
307
354
  qveris discover "weather forecast API"
308
355
  qveris inspect 1
309
356
  qveris call 1 --params '{"city": "London"}'
310
357
  qveris call 1 --params @params.json --codegen curl
358
+ qveris mcp configure --target cursor --write --include-key
359
+ qveris mcp validate --target cursor
311
360
  qveris usage --mode search --execution-id <id>
312
361
  qveris ledger --mode search --min-credits 50 --direction consume
313
362
  qveris interactive
@@ -23,7 +23,7 @@ export function formatDiscoverResult(result) {
23
23
  const toolId = t.tool_id ?? "";
24
24
  const desc = stringifyDesc(t.description);
25
25
  const provider = t.provider_name ?? "";
26
- const categories = Array.isArray(t.categories) ? t.categories.join(", ") : "";
26
+ const categories = formatCategories(t.categories);
27
27
  const region = t.region ?? "global";
28
28
  const stats = t.stats ?? {};
29
29
 
@@ -92,7 +92,7 @@ export function formatInspectResult(tools) {
92
92
  const desc = stringifyDesc(t.description);
93
93
  const provider = t.provider_name ?? "";
94
94
  const providerDesc = stringifyDesc(t.provider_description);
95
- const categories = Array.isArray(t.categories) ? t.categories.join(", ") : "";
95
+ const categories = formatCategories(t.categories);
96
96
  const region = t.region ?? "global";
97
97
  const docsUrl = t.docs_url ?? "";
98
98
  const stats = t.stats ?? {};
@@ -290,6 +290,27 @@ function formatSchema(schema, indent = "", depth = 0) {
290
290
  return lines.join("\n");
291
291
  }
292
292
 
293
+ /** Categories may be strings or objects like {slug, name, description}. */
294
+ function formatCategories(categories) {
295
+ if (!Array.isArray(categories)) return "";
296
+ const seen = new Set();
297
+ const names = [];
298
+ for (const c of categories) {
299
+ let label = "";
300
+ if (typeof c === "string") label = c;
301
+ else if (c && typeof c === "object") {
302
+ label = stringifyDesc(c.name) || (typeof c.slug === "string" ? c.slug : "");
303
+ }
304
+ label = label.trim();
305
+ if (!label) continue;
306
+ const key = label.toLowerCase();
307
+ if (seen.has(key)) continue;
308
+ seen.add(key);
309
+ names.push(label);
310
+ }
311
+ return names.join(", ");
312
+ }
313
+
293
314
  /** Handle description that may be a string, i18n object {en: "...", zh: "..."}, or other. */
294
315
  function stringifyDesc(desc) {
295
316
  if (!desc) return "";