grok-search-cli 0.1.2 → 0.1.3

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/cli.js CHANGED
@@ -1,162 +1,31 @@
1
1
  #!/usr/bin/env node
2
- import { generateText as e, streamText as t } from "ai";
3
- import { chmodSync as n, existsSync as r, mkdirSync as i, readFileSync as a, writeFileSync as o } from "node:fs";
4
- import s from "node:os";
5
- import c from "node:path";
6
- import l from "conf";
7
- import { createOpenAICompatible as ee } from "@ai-sdk/openai-compatible";
8
- import { createXai as te, xai as u } from "@ai-sdk/xai";
9
- import { fileURLToPath as ne } from "node:url";
10
- //#region src/config.ts
11
- var d = "grok-4-1-fast-non-reasoning", f = c.join(s.homedir(), ".config", "grok-search-cli");
12
- function p(e) {
13
- return typeof e == "string" && e.trim() || void 0;
14
- }
15
- function m() {
16
- return {
17
- XAI_API_KEY: "",
18
- XAI_MODEL: d,
19
- XAI_BASE_URL: "",
20
- XAI_COMPAT_MODE: !1,
21
- _examples: {
22
- xai: {
23
- XAI_API_KEY: "your_xai_api_key",
24
- XAI_MODEL: "grok-4-1-fast-non-reasoning"
25
- },
26
- openrouter: {
27
- XAI_API_KEY: "your_openrouter_api_key",
28
- XAI_MODEL: "x-ai/grok-4.1-fast",
29
- XAI_BASE_URL: "https://openrouter.ai/api/v1"
30
- },
31
- yunwu: {
32
- XAI_API_KEY: "your_yunwu_api_key",
33
- XAI_MODEL: "grok-4-fast",
34
- XAI_BASE_URL: "https://yunwu.ai/v1",
35
- XAI_COMPAT_MODE: !0
36
- }
37
- }
38
- };
39
- }
40
- function h() {
41
- try {
42
- return new l({
43
- projectName: "grok-search-cli",
44
- configName: "config",
45
- cwd: f,
46
- defaults: m()
47
- });
48
- } catch (e) {
49
- let t = e instanceof Error ? e.message : String(e);
50
- throw Error(`Failed to initialize user config: ${t}`);
51
- }
52
- }
53
- var g = h(), _ = g.path;
54
- function v() {
55
- if (i(c.dirname(_), { recursive: !0 }), !r(_)) {
56
- o(_, `${JSON.stringify(m(), null, 2)}\n`, "utf8");
57
- try {
58
- n(_, 384);
59
- } catch {}
60
- }
61
- return _;
62
- }
63
- function y() {
64
- let e = g.store;
65
- return {
66
- apiKey: p(process.env.XAI_API_KEY) ?? e?.XAI_API_KEY,
67
- model: p(process.env.XAI_MODEL) ?? e?.XAI_MODEL ?? d,
68
- baseUrl: p(process.env.XAI_BASE_URL) ?? e?.XAI_BASE_URL,
69
- compatModeRaw: process.env.XAI_COMPAT_MODE?.trim() ?? e?.XAI_COMPAT_MODE
70
- };
71
- }
72
- function b() {
73
- let e = g.store;
74
- return {
75
- apiKey: p(process.env.XAI_API_KEY) ? "env" : e?.XAI_API_KEY ? "config" : "missing",
76
- model: p(process.env.XAI_MODEL) ? "env" : e?.XAI_MODEL ? "config" : "default",
77
- baseUrl: p(process.env.XAI_BASE_URL) ? "env" : e?.XAI_BASE_URL ? "config" : "default",
78
- compatMode: process.env.XAI_COMPAT_MODE?.trim() ? "env" : e?.XAI_COMPAT_MODE == null ? "default" : "config"
79
- };
80
- }
81
- function x() {
82
- return y().model;
83
- }
84
- function S() {
85
- return y().apiKey;
86
- }
87
- function C() {
88
- return y().baseUrl;
89
- }
90
- function re() {
91
- let e = y(), t = b(), n = E(), r = T(e.baseUrl);
92
- return {
93
- configPath: _,
94
- apiKeyPresent: !!e.apiKey,
95
- model: e.model,
96
- baseUrl: e.baseUrl,
97
- providerKind: r,
98
- apiMode: n,
99
- sources: t
100
- };
101
- }
102
- function w(e) {
103
- if (!e) return !1;
104
- try {
105
- let { hostname: t } = new URL(e);
106
- return t === "openrouter.ai" || t.endsWith(".openrouter.ai");
107
- } catch {
108
- return !1;
109
- }
110
- }
111
- function T(e) {
112
- if (!e) return "xai";
113
- if (w(e)) return "openrouter";
114
- try {
115
- let { hostname: t } = new URL(e);
116
- if (t === "x.ai" || t.endsWith(".x.ai")) return "xai";
117
- } catch {}
118
- return "third-party";
119
- }
120
- function ie() {
121
- let { compatModeRaw: e, baseUrl: t } = y();
122
- return T(t) !== "openrouter" && /^(1|true|yes|on)$/i.test(String(e || ""));
123
- }
124
- function E() {
125
- return ie() ? "completion" : "responses";
126
- }
127
- function D(e) {
128
- return T(C()) === "openrouter" && e === "responses" ? "OpenRouter Responses API Beta" : e === "responses" ? "xAI Responses API" : "OpenAI-compatible /chat/completions";
129
- }
130
- function O(e, t) {
131
- if (e === "xai") {
132
- console.error(t === "responses" ? "xAI Responses API request failed. Check XAI_API_KEY, model name, and search parameters." : "xAI-compatible completion request failed. Check XAI_API_KEY, model name, and gateway settings.");
133
- return;
134
- }
135
- if (e === "openrouter") {
136
- console.error("OpenRouter request failed. This CLI uses OpenRouter Responses API web search for openrouter.ai endpoints.");
137
- return;
138
- }
139
- console.error("Third-party gateway request failed. Verify the gateway supports the selected API shape and that web search is enabled on the provider side.");
140
- }
141
- //#endregion
2
+ import { _ as e, a as t, c as n, d as r, f as i, g as a, h as o, i as s, l as c, m as l, n as u, p as d, r as f, s as p, t as m, u as h } from "./search-DcS355m9.js";
3
+ import { readFileSync as g } from "node:fs";
4
+ import _ from "node:path";
5
+ import { fileURLToPath as v } from "node:url";
142
6
  //#region src/args.ts
143
- function k(e) {
7
+ function y(e) {
144
8
  process.stderr.write(`${e}\n`), process.exit(1);
145
9
  }
146
- function ae() {
147
- let e = x();
10
+ function b() {
11
+ let e = o();
148
12
  process.stdout.write(`\
149
13
  Usage:
150
14
  grok-search "<prompt>" [options]
151
15
  grok-search doctor
152
16
  grok-search skill
153
17
 
154
- Options:
18
+ Commands:
155
19
  doctor Show config and credential diagnostics
156
20
  skill Print the bundled skill to stdout
21
+
22
+ Options:
157
23
  --model=<id> Override model. Default: ${e}
158
24
  --timeout=<seconds> Request timeout. Default: 60
159
- --json Output JSON
25
+ -h, --help Show this help
26
+
27
+ Advanced Options:
28
+ Most of these are optional and usually not needed for normal research.
160
29
  --verbose Print request and token diagnostics
161
30
  --allowed-domains=a.com,b.com Web Search allowed domains
162
31
  --excluded-domains=a.com,b.com Web Search excluded domains
@@ -166,22 +35,22 @@ Options:
166
35
  --to-date=YYYY-MM-DD X Search end date
167
36
  --image Enable image understanding
168
37
  --video Enable video understanding for X Search
169
- -h, --help Show this help
38
+ --json Output JSON instead of the default text stream
170
39
 
171
40
  Environment:
172
41
  XAI_API_KEY Required
173
42
  `);
174
43
  }
175
- function oe(e) {
44
+ function x(e) {
176
45
  return e ? e.split(",").map((e) => e.trim()).filter(Boolean) : [];
177
46
  }
178
- function A(e, t, n) {
47
+ function S(e, t, n) {
179
48
  let r = e.indexOf("=");
180
49
  return r >= 0 ? e.slice(r + 1) : t[n + 1];
181
50
  }
182
- function se() {
51
+ function C() {
183
52
  return {
184
- model: x(),
53
+ model: o(),
185
54
  timeoutMs: 6e4,
186
55
  json: !1,
187
56
  verbose: !1,
@@ -193,19 +62,19 @@ function se() {
193
62
  enableVideoUnderstanding: !1
194
63
  };
195
64
  }
196
- function j(e, t, n, r, i) {
197
- let a = A(e, t, n)?.trim();
198
- return a || k(`Missing value for ${r}`), i(a), e.includes("=") ? n : n + 1;
65
+ function w(e, t, n, r, i) {
66
+ let a = S(e, t, n)?.trim();
67
+ return a || y(`Missing value for ${r}`), i(a), e.includes("=") ? n : n + 1;
199
68
  }
200
- function M(e, t, n, r) {
201
- return r(oe(A(e, t, n))), e.includes("=") ? n : n + 1;
69
+ function T(e, t, n, r) {
70
+ return r(x(S(e, t, n))), e.includes("=") ? n : n + 1;
202
71
  }
203
- function ce(e, t, n, r) {
204
- let i = A(e, t, n)?.trim(), a = Number(i);
205
- return (!i || !Number.isFinite(a) || a <= 0) && k("Invalid value for --timeout. Use a number of seconds > 0."), r.timeoutMs = Math.round(a * 1e3), e.includes("=") ? n : n + 1;
72
+ function E(e, t, n, r) {
73
+ let i = S(e, t, n)?.trim(), a = Number(i);
74
+ return (!i || !Number.isFinite(a) || a <= 0) && y("Invalid value for --timeout. Use a number of seconds > 0."), r.timeoutMs = Math.round(a * 1e3), e.includes("=") ? n : n + 1;
206
75
  }
207
- function N(e) {
208
- let t = se(), n = [];
76
+ function D(e) {
77
+ let t = C(), n = [];
209
78
  for (let r = 0; r < e.length; r += 1) {
210
79
  let i = e[r];
211
80
  if (!i.startsWith("-")) {
@@ -229,493 +98,169 @@ function N(e) {
229
98
  continue;
230
99
  }
231
100
  if (i.startsWith("--model")) {
232
- r = j(i, e, r, "--model", (e) => {
101
+ r = w(i, e, r, "--model", (e) => {
233
102
  t.model = e;
234
103
  });
235
104
  continue;
236
105
  }
237
106
  if (i.startsWith("--timeout")) {
238
- r = ce(i, e, r, t);
107
+ r = E(i, e, r, t);
239
108
  continue;
240
109
  }
241
110
  if (i.startsWith("--allowed-domains")) {
242
- r = M(i, e, r, (e) => {
111
+ r = T(i, e, r, (e) => {
243
112
  t.allowedDomains = e;
244
113
  });
245
114
  continue;
246
115
  }
247
116
  if (i.startsWith("--excluded-domains")) {
248
- r = M(i, e, r, (e) => {
117
+ r = T(i, e, r, (e) => {
249
118
  t.excludedDomains = e;
250
119
  });
251
120
  continue;
252
121
  }
253
122
  if (i.startsWith("--allowed-handles")) {
254
- r = M(i, e, r, (e) => {
123
+ r = T(i, e, r, (e) => {
255
124
  t.allowedHandles = e;
256
125
  });
257
126
  continue;
258
127
  }
259
128
  if (i.startsWith("--excluded-handles")) {
260
- r = M(i, e, r, (e) => {
129
+ r = T(i, e, r, (e) => {
261
130
  t.excludedHandles = e;
262
131
  });
263
132
  continue;
264
133
  }
265
134
  if (i.startsWith("--from-date")) {
266
- r = j(i, e, r, "--from-date", (e) => {
135
+ r = w(i, e, r, "--from-date", (e) => {
267
136
  t.fromDate = e;
268
137
  });
269
138
  continue;
270
139
  }
271
140
  if (i.startsWith("--to-date")) {
272
- r = j(i, e, r, "--to-date", (e) => {
141
+ r = w(i, e, r, "--to-date", (e) => {
273
142
  t.toDate = e;
274
143
  });
275
144
  continue;
276
145
  }
277
- k(`Unknown option: ${i}`);
146
+ y(`Unknown option: ${i}`);
278
147
  }
279
148
  let r = n.join(" ").trim();
280
- return r || k("Missing prompt."), t.allowedDomains.length > 0 && t.excludedDomains.length > 0 && k("Use either --allowed-domains or --excluded-domains, not both."), t.allowedHandles.length > 0 && t.excludedHandles.length > 0 && k("Use either --allowed-handles or --excluded-handles, not both."), {
149
+ return r || y("Missing prompt."), t.allowedDomains.length > 0 && t.excludedDomains.length > 0 && y("Use either --allowed-domains or --excluded-domains, not both."), t.allowedHandles.length > 0 && t.excludedHandles.length > 0 && y("Use either --allowed-handles or --excluded-handles, not both."), {
281
150
  command: "all",
282
151
  prompt: r,
283
152
  options: t
284
153
  };
285
154
  }
286
- function P(e) {
287
- if ((e.length === 0 || e.includes("--help") || e.includes("-h")) && (ae(), process.exit(0)), e[0] === "skill") {
155
+ function O(e) {
156
+ if ((e.length === 0 || e.includes("--help") || e.includes("-h")) && (b(), process.exit(0)), e[0] === "skill") {
288
157
  let t = e.filter((e, t) => t > 0 && e.startsWith("-") && e !== "--help" && e !== "-h");
289
- return t.length > 0 && k(`Unknown option: ${t[0]}`), { command: "skill" };
158
+ return t.length > 0 && y(`Unknown option: ${t[0]}`), { command: "skill" };
290
159
  }
291
160
  if (e[0] === "doctor") {
292
161
  let t = e.filter((e, t) => t > 0 && e.startsWith("-") && e !== "--help" && e !== "-h");
293
- return t.length > 0 && k(`Unknown option: ${t[0]}`), { command: "doctor" };
162
+ return t.length > 0 && y(`Unknown option: ${t[0]}`), { command: "doctor" };
294
163
  }
295
- return N(e);
296
- }
297
- //#endregion
298
- //#region src/openrouter.ts
299
- function F(e) {
300
- let t = {};
301
- return e.allowedDomains.length > 0 && (t.allowed_domains = e.allowedDomains), e.excludedDomains.length > 0 && (t.excluded_domains = e.excludedDomains), I(t) ? {
302
- type: "openrouter:web_search",
303
- parameters: t
304
- } : { type: "openrouter:web_search" };
305
- }
306
- function I(e) {
307
- return Object.keys(e).length > 0;
308
- }
309
- function L(e, t, n) {
310
- return {
311
- model: t.model,
312
- input: e,
313
- tools: [F(t)],
314
- stream: n
315
- };
316
- }
317
- async function R(e) {
318
- if (!e.ok) throw Error(await e.text());
319
- return e;
320
- }
321
- function z(e) {
322
- return (e.output?.find((e) => e.type === "message"))?.content?.find((e) => e.type === "output_text")?.text ?? "";
323
- }
324
- function B(e) {
325
- return ((e.output?.find((e) => e.type === "message"))?.content?.find((e) => e.type === "output_text"))?.annotations?.filter((e) => e.type === "url_citation").map((e) => ({
326
- sourceType: "url_citation",
327
- url: e.url
328
- })) ?? [];
329
- }
330
- function V(e) {
331
- return {
332
- inputTokens: e?.input_tokens,
333
- outputTokens: e?.output_tokens,
334
- totalTokens: e?.total_tokens,
335
- outputTokenDetails: {
336
- textTokens: e?.output_tokens,
337
- reasoningTokens: void 0
338
- }
339
- };
340
- }
341
- function H(e) {
342
- return {
343
- text: z(e),
344
- finishReason: e.status ?? "unknown",
345
- usage: V(e.usage),
346
- sources: B(e)
347
- };
348
- }
349
- async function U(e) {
350
- return R(await fetch(`${e.baseUrl}/responses`, {
351
- method: "POST",
352
- headers: {
353
- Authorization: `Bearer ${e.apiKey}`,
354
- "Content-Type": "application/json"
355
- },
356
- body: JSON.stringify(e.body),
357
- signal: e.abortSignal
358
- }));
359
- }
360
- function W(e) {
361
- return (t) => ({
362
- ...t,
363
- tools: [F(e)]
364
- });
365
- }
366
- function G(e) {
367
- if (!e.startsWith("data: ")) return { type: "ignore" };
368
- let t = e.slice(6);
369
- if (t === "[DONE]") return { type: "done" };
370
- let n = JSON.parse(t);
371
- return n.type === "response.output_text.delta" && typeof n.delta == "string" ? {
372
- type: "delta",
373
- text: n.delta
374
- } : n.type === "response.completed" ? {
375
- type: "completed",
376
- response: n.response
377
- } : { type: "ignore" };
378
- }
379
- async function le(e) {
380
- return H(await (await U({
381
- baseUrl: e.baseUrl,
382
- apiKey: e.apiKey,
383
- body: L(e.prompt, e.options, !1),
384
- abortSignal: e.abortSignal
385
- })).json());
386
- }
387
- async function ue(e) {
388
- let t = (await U({
389
- baseUrl: e.baseUrl,
390
- apiKey: e.apiKey,
391
- body: L(e.prompt, e.options, !0),
392
- abortSignal: e.abortSignal
393
- })).body?.getReader();
394
- if (!t) throw Error("OpenRouter streaming response body is missing.");
395
- let n = new TextDecoder(), r = "", i, a, o = new Promise((e, t) => {
396
- i = e, a = t;
397
- }), s = !1, c = (async function* () {
398
- try {
399
- for (;;) {
400
- let { done: e, value: a } = await t.read();
401
- if (e) break;
402
- r += n.decode(a, { stream: !0 });
403
- let o = r.split("\n");
404
- r = o.pop() ?? "";
405
- for (let e of o) {
406
- let t = G(e);
407
- if (t.type === "delta") {
408
- yield t.text;
409
- continue;
410
- }
411
- if (t.type === "completed") {
412
- s = !0, i?.(t.response);
413
- continue;
414
- }
415
- if (t.type === "done") return;
416
- }
417
- }
418
- s || a?.(/* @__PURE__ */ Error("OpenRouter stream ended before response.completed."));
419
- } catch (e) {
420
- throw a?.(e), e;
421
- }
422
- })(), l = o.then(H);
423
- return {
424
- textStream: c,
425
- text: l.then((e) => e.text),
426
- finishReason: l.then((e) => e.finishReason),
427
- usage: l.then((e) => e.usage),
428
- sources: l.then((e) => e.sources)
429
- };
430
- }
431
- //#endregion
432
- //#region src/output.ts
433
- function K({ model: e, finishReason: t, requestApi: n, baseUrl: r, durationMs: i, firstTokenLatencyMs: a, usage: o }) {
434
- let s = o ?? {}, c = s.outputTokens, l = s.outputTokenDetails?.reasoningTokens;
435
- return {
436
- model: e,
437
- finishReason: t,
438
- requestApi: n,
439
- baseUrl: r,
440
- durationMs: i,
441
- firstTokenLatencyMs: a,
442
- tokensPerSecond: typeof c == "number" && i > 0 ? Number((c * 1e3 / i).toFixed(2)) : void 0,
443
- usage: {
444
- inputTokens: s.inputTokens,
445
- outputTokens: c,
446
- reasoningTokens: l,
447
- totalTokens: s.totalTokens
448
- }
449
- };
450
- }
451
- function de(e) {
452
- process.stdout.write("\nVerbose:\n"), process.stdout.write(`Model: ${e.model}\n`), process.stdout.write(`Finish reason: ${e.finishReason}\n`), process.stdout.write(`Request API: ${e.requestApi}\n`), e.baseUrl && process.stdout.write(`Base URL: ${e.baseUrl}\n`);
453
- let t = [`Duration: ${(e.durationMs / 1e3).toFixed(2)}s`];
454
- e.firstTokenLatencyMs != null && t.push(`first token ${(e.firstTokenLatencyMs / 1e3).toFixed(2)}s`), process.stdout.write(`${t.join(", ")}\n`);
455
- let n = [
456
- e.usage.inputTokens == null ? void 0 : `input=${e.usage.inputTokens}`,
457
- e.usage.outputTokens == null ? void 0 : `output=${e.usage.outputTokens}`,
458
- e.usage.reasoningTokens == null ? void 0 : `reasoning=${e.usage.reasoningTokens}`,
459
- e.usage.totalTokens == null ? void 0 : `total=${e.usage.totalTokens}`
460
- ].filter(Boolean);
461
- n.length > 0 && process.stdout.write(`Usage: ${n.join(", ")}\n`), e.tokensPerSecond != null && process.stdout.write(`TPS: ${e.tokensPerSecond}\n`);
462
- }
463
- function q(e) {
464
- process.stdout.write(`${e.text}\n`), e.verbose && de(e.verbose);
465
- }
466
- async function fe(e) {
467
- let t = !1, n = !1, r;
468
- for await (let i of e.stream.textStream) r ??= Date.now() - e.startedAt, t = !0, n = i.endsWith("\n"), process.stdout.write(i);
469
- (!t || !n) && process.stdout.write("\n");
470
- let i = await e.stream.usage, a = await e.stream.finishReason ?? "unknown", o = {
471
- ...e.payload,
472
- text: await e.stream.text,
473
- finishReason: a,
474
- usage: i ?? null,
475
- sources: await e.stream.sources ?? [],
476
- verbose: e.includeVerbose ? K({
477
- model: e.payload.model,
478
- finishReason: a,
479
- requestApi: e.requestApi,
480
- baseUrl: e.baseUrl,
481
- durationMs: Date.now() - e.startedAt,
482
- firstTokenLatencyMs: r,
483
- usage: i
484
- }) : void 0
485
- };
486
- process.stdout.write("\n"), q(o);
487
- }
488
- //#endregion
489
- //#region src/providers.ts
490
- function J(e) {
491
- return {
492
- web_search: u.tools.webSearch({
493
- allowedDomains: e.allowedDomains.length > 0 ? e.allowedDomains : void 0,
494
- excludedDomains: e.excludedDomains.length > 0 ? e.excludedDomains : void 0,
495
- enableImageUnderstanding: e.enableImageUnderstanding || void 0
496
- }),
497
- x_search: u.tools.xSearch({
498
- allowedXHandles: e.allowedHandles.length > 0 ? e.allowedHandles : void 0,
499
- excludedXHandles: e.excludedHandles.length > 0 ? e.excludedHandles : void 0,
500
- fromDate: e.fromDate,
501
- toDate: e.toDate,
502
- enableImageUnderstanding: e.enableImageUnderstanding || void 0,
503
- enableVideoUnderstanding: e.enableVideoUnderstanding || void 0
504
- })
505
- };
506
- }
507
- function Y() {
508
- let e = C();
509
- return e ? te({ baseURL: e }) : u;
510
- }
511
- function X(e) {
512
- let t = C();
513
- return ee({
514
- name: "compat",
515
- apiKey: S(),
516
- baseURL: t || "https://api.x.ai/v1",
517
- transformRequestBody: w(t) ? W(e) : void 0
518
- });
519
- }
520
- function pe(e) {
521
- return e.allowedDomains.length > 0 || e.excludedDomains.length > 0 || e.allowedHandles.length > 0 || e.excludedHandles.length > 0 || typeof e.fromDate == "string" || typeof e.toDate == "string" || e.enableImageUnderstanding || e.enableVideoUnderstanding;
522
- }
523
- function me(e) {
524
- return e.allowedHandles.length > 0 || e.excludedHandles.length > 0 || typeof e.fromDate == "string" || typeof e.toDate == "string" || e.enableImageUnderstanding || e.enableVideoUnderstanding;
164
+ return D(e);
525
165
  }
526
166
  //#endregion
527
167
  //#region src/skill.ts
528
- var Z = "grok-search-cli", he = ne(import.meta.url), Q = c.dirname(he);
529
- function ge(...e) {
530
- let t = [c.resolve(Q, "..", "skills", Z, ...e), c.resolve(Q, "..", "..", "skills", Z, ...e)];
168
+ var k = "grok-search-cli", A = v(import.meta.url), j = _.dirname(A);
169
+ function M(...e) {
170
+ let t = [_.resolve(j, "..", "skills", k, ...e), _.resolve(j, "..", "..", "skills", k, ...e)];
531
171
  for (let e of t) try {
532
- return a(e, "utf8");
172
+ return g(e, "utf8");
533
173
  } catch (e) {
534
174
  if (e.code !== "ENOENT") throw e;
535
175
  }
536
- throw Error(`Bundled skill file not found for ${Z}: ${e.join("/")}`);
176
+ throw Error(`Bundled skill file not found for ${k}: ${e.join("/")}`);
537
177
  }
538
- function _e() {
539
- return ge("SKILL.md");
178
+ function N() {
179
+ return M("SKILL.md");
540
180
  }
541
181
  //#endregion
542
182
  //#region src/cli.ts
543
- function ve() {
544
- let e = re();
183
+ function P() {
184
+ let e = l();
545
185
  if (process.stdout.write("Doctor:\n"), process.stdout.write(`Config path: ${e.configPath}\n`), process.stdout.write(`API key: ${e.apiKeyPresent ? "present" : "missing"} (${e.sources.apiKey})\n`), process.stdout.write(`Model: ${e.model} (${e.sources.model})\n`), process.stdout.write(`Base URL: ${e.baseUrl ?? "(xAI default)"} (${e.sources.baseUrl})\n`), process.stdout.write(`Compat mode source: ${e.sources.compatMode}\n`), process.stdout.write(`Provider: ${e.providerKind}\n`), process.stdout.write(`API mode: ${e.apiMode}\n`), process.stdout.write(`Status: ${e.apiKeyPresent ? "OK" : "NOT READY"}\n`), !e.apiKeyPresent) {
546
- let e = v();
186
+ let e = r();
547
187
  process.stdout.write(`Action: edit ${e}\n`);
548
188
  }
549
189
  }
550
- function ye() {
551
- let e = S();
552
- return e || k(`Missing XAI_API_KEY.\n\nEdit ${v()} or set XAI_API_KEY in your shell environment.\nThis CLI reads credentials from process.env first, then ${_}.`), e;
553
- }
554
- function be(e, t) {
555
- let n = C();
556
- return e === "completion" && pe(t) && !w(n);
557
- }
558
- function xe(e, t) {
559
- return $(e) && me(t);
560
- }
561
- function $(e) {
562
- return T(C()) === "openrouter" && e === "responses";
563
- }
564
- function Se(e) {
565
- return process.stdout.isTTY && !e;
566
- }
567
- function Ce(e) {
568
- return {
569
- command: e.command,
570
- apiMode: e.apiMode,
571
- model: e.model,
572
- prompt: e.prompt,
573
- text: e.result.text,
574
- finishReason: e.result.finishReason ?? "unknown",
575
- usage: e.result.usage ?? null,
576
- sources: e.result.sources ?? [],
577
- verbose: e.verbose ? K({
578
- model: e.model,
579
- finishReason: e.result.finishReason ?? "unknown",
580
- requestApi: e.requestApi,
581
- baseUrl: e.baseUrl,
582
- durationMs: Date.now() - e.startedAt,
583
- usage: e.result.usage ?? null
584
- }) : void 0
585
- };
586
- }
587
- function we(e) {
588
- if (e.apiMode === "responses") {
589
- let n = t({
590
- model: Y().responses(e.model),
591
- prompt: e.prompt,
592
- tools: J(e.options),
593
- abortSignal: e.abortSignal
594
- });
595
- return {
596
- textStream: n.textStream,
597
- text: n.text,
598
- finishReason: n.finishReason,
599
- usage: n.usage,
600
- sources: n.sources
601
- };
602
- }
603
- let n = t({
604
- model: X(e.options)(e.model),
605
- prompt: e.prompt,
606
- abortSignal: e.abortSignal
607
- });
608
- return {
609
- textStream: n.textStream,
610
- text: n.text,
611
- finishReason: n.finishReason,
612
- usage: n.usage,
613
- sources: n.sources
614
- };
615
- }
616
- async function Te(t) {
617
- if (t.apiMode === "responses") {
618
- let n = await e({
619
- model: Y().responses(t.model),
620
- prompt: t.prompt,
621
- tools: J(t.options),
622
- abortSignal: t.abortSignal
623
- });
624
- return {
625
- text: n.text,
626
- finishReason: n.finishReason ?? "unknown",
627
- usage: n.usage ?? null,
628
- sources: n.sources ?? []
629
- };
190
+ function F() {
191
+ try {
192
+ return s();
193
+ } catch (e) {
194
+ y(e instanceof Error ? e.message : String(e));
630
195
  }
631
- let n = await e({
632
- model: X(t.options)(t.model),
633
- prompt: t.prompt,
634
- abortSignal: t.abortSignal
635
- });
636
- return {
637
- text: n.text,
638
- finishReason: n.finishReason ?? "unknown",
639
- usage: n.usage ?? null,
640
- sources: n.sources ?? []
641
- };
642
196
  }
643
- async function Ee(e) {
644
- await fe({
645
- stream: $(e.apiMode) ? await ue({
646
- prompt: e.prompt,
647
- options: e.options,
648
- baseUrl: e.baseUrl || "https://openrouter.ai/api/v1",
649
- apiKey: e.apiKey,
650
- abortSignal: e.abortSignal
651
- }) : we(e),
197
+ async function I(e) {
198
+ await h({
199
+ stream: await n(e),
652
200
  payload: {
653
201
  command: "all",
654
202
  apiMode: e.apiMode,
655
- model: e.model,
203
+ model: e.options.model,
656
204
  prompt: e.prompt
657
205
  },
658
206
  includeVerbose: e.options.verbose,
659
207
  requestApi: e.requestApi,
660
- baseUrl: e.baseUrl,
208
+ baseUrl: e.runtimeConfig.baseUrl,
661
209
  startedAt: e.startedAt
662
210
  });
663
211
  }
664
- async function De(e) {
665
- let t = $(e.apiMode) ? await le({
666
- prompt: e.prompt,
667
- options: e.options,
668
- baseUrl: e.baseUrl || "https://openrouter.ai/api/v1",
669
- apiKey: e.apiKey,
670
- abortSignal: e.abortSignal
671
- }) : await Te(e), n = Ce({
212
+ async function L(e, t) {
213
+ let n = await p(e), r = f({
672
214
  command: "all",
673
215
  apiMode: e.apiMode,
674
- model: e.model,
216
+ model: e.options.model,
675
217
  prompt: e.prompt,
676
- result: t,
218
+ result: n,
677
219
  verbose: e.options.verbose,
678
220
  requestApi: e.requestApi,
679
- baseUrl: e.baseUrl,
221
+ baseUrl: e.runtimeConfig.baseUrl,
680
222
  startedAt: e.startedAt
681
223
  });
682
- if (e.options.json) {
683
- process.stdout.write(`${JSON.stringify(n, null, 2)}\n`);
224
+ if (t) {
225
+ process.stdout.write(`${JSON.stringify(r, null, 2)}\n`);
684
226
  return;
685
227
  }
686
- q(n);
228
+ c(r);
687
229
  }
688
- async function Oe() {
689
- let e = P(process.argv.slice(2));
230
+ async function R() {
231
+ let e = O(process.argv.slice(2));
690
232
  if (e.command === "skill") {
691
- process.stdout.write(`${_e()}\n`);
233
+ process.stdout.write(`${N()}\n`);
692
234
  return;
693
235
  }
694
236
  if (e.command === "doctor") {
695
- ve();
237
+ P();
696
238
  return;
697
239
  }
698
- let t = ye(), n = E(), r = C(), i = D(n), a = Date.now(), o = AbortSignal.timeout(e.options.timeoutMs);
699
- be(n, e.options) && console.error("Warning: compatibility mode is enabled, so tool-specific filters are not forwarded. Remove XAI_COMPAT_MODE to use xAI Responses API."), xe(n, e.options) && console.error("Warning: OpenRouter server-tool mode currently forwards web domain filters only. X-specific filters such as handles, dates, image, and video options are ignored.");
700
- let s = {
701
- prompt: e.prompt,
240
+ F();
241
+ let n = {
242
+ ...m(),
702
243
  model: e.options.model,
703
- apiMode: n,
704
- options: e.options,
705
- requestApi: i,
706
- baseUrl: r,
707
- startedAt: a,
708
- abortSignal: o,
709
- apiKey: t
710
- };
711
- if (Se(e.options.json)) {
712
- await Ee(s);
244
+ timeoutMs: e.options.timeoutMs,
245
+ verbose: e.options.verbose,
246
+ allowedDomains: e.options.allowedDomains,
247
+ excludedDomains: e.options.excludedDomains,
248
+ allowedHandles: e.options.allowedHandles,
249
+ excludedHandles: e.options.excludedHandles,
250
+ fromDate: e.options.fromDate,
251
+ toDate: e.options.toDate,
252
+ enableImageUnderstanding: e.options.enableImageUnderstanding,
253
+ enableVideoUnderstanding: e.options.enableVideoUnderstanding
254
+ }, r = u(e.prompt, n);
255
+ for (let e of t(r.apiMode, r.runtimeConfig.baseUrl, r.options)) console.error(e);
256
+ if (!e.options.json) {
257
+ await I(r);
713
258
  return;
714
259
  }
715
- await De(s);
260
+ await L(r, e.options.json);
716
261
  }
717
- Oe().catch((e) => {
718
- let t = e instanceof Error ? e.stack || e.message : String(e);
719
- O(T(C()), E()), process.stderr.write(`${t}\n`), process.exit(1);
262
+ R().catch((t) => {
263
+ let n = t instanceof Error ? t.stack || t.message : String(t);
264
+ e(a(d()), i()), process.stderr.write(`${n}\n`), process.exit(1);
720
265
  });
721
266
  //#endregion