hive-intelligence 1.6.7 → 1.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +10 -4
  2. package/agent-skills/.claude-plugin/plugin.json +10 -0
  3. package/agent-skills/README.md +2 -0
  4. package/agent-skills/SKILL.md +18 -6
  5. package/agent-skills/evals/trigger-queries.json +70 -0
  6. package/agent-skills/package.json +3 -1
  7. package/agent-skills/packs/hive/SKILL.md +404 -0
  8. package/agent-skills/packs/hive/evals/evals.json +50 -0
  9. package/agent-skills/packs/hive/evals/triggers.json +39 -0
  10. package/agent-skills/packs/hive-build-onboarding/SKILL.md +1 -1
  11. package/agent-skills/packs/hive-cli/SKILL.md +2 -2
  12. package/agent-skills/packs/hive-mcp/SKILL.md +9 -5
  13. package/agent-skills/packs/hive-prediction-markets/SKILL.md +145 -0
  14. package/agent-skills/packs/hive-prediction-markets/evals/evals.json +29 -0
  15. package/agent-skills/packs/hive-prediction-markets/evals/triggers.json +14 -0
  16. package/agent-skills/packs/hive-query/SKILL.md +4 -2
  17. package/agent-skills/packs/hive-stateful-monitoring/SKILL.md +3 -3
  18. package/agent-skills/references/agents-routing.md +4 -1
  19. package/agent-skills/scripts/validate-agent-skills-package.mjs +2 -0
  20. package/agent-skills/skills.sh.json +9 -1
  21. package/build/{api-client-6AM3HVHQ.js → api-client-POBN6Y5S.js} +12 -3
  22. package/build/{auth-4LPSQJXD.js → auth-6XVL5CE3.js} +1 -1
  23. package/build/call-args-BUB6YNHW.js +27 -0
  24. package/build/{chunk-GADPH72D.js → chunk-4QDGA6GP.js} +52 -1
  25. package/build/{chunk-2SPCKQBJ.js → chunk-5QAXJON7.js} +71 -0
  26. package/build/chunk-APBLB62S.js +474 -0
  27. package/build/chunk-AZFOTKS2.js +394 -0
  28. package/build/{chunk-GYVF75XB.js → chunk-FQNW6SZ6.js} +1 -1
  29. package/build/{chunk-32NRUWXA.js → chunk-KQVPKTEO.js} +3 -3
  30. package/build/{chunk-LW2DHE32.js → chunk-L4KVJDA7.js} +1 -1
  31. package/build/{chunk-J2PXISXW.js → chunk-LP7PDQCO.js} +4289 -626
  32. package/build/{chunk-P7NLFSZQ.js → chunk-RNVZIPNY.js} +100 -9
  33. package/build/chunk-XN3T6YOG.js +32 -0
  34. package/build/{chunk-KUF754NT.js → chunk-YLHNUAFT.js} +52 -12
  35. package/build/{chunk-G23ZAW36.js → chunk-ZBMMJ6LE.js} +3 -2
  36. package/build/{chunk-LP5ECG7A.js → chunk-ZDXMZPC6.js} +26 -2
  37. package/build/{chunk-S4HBVZ7O.js → chunk-ZSPPJW4G.js} +44 -7
  38. package/build/cli.js +120 -48
  39. package/build/{completion-YVSWWF6D.js → completion-ROZAH667.js} +1 -1
  40. package/build/{doctor-AM6QST7Z.js → doctor-KPYW2U7D.js} +42 -5
  41. package/build/{errors-EL6UMXNJ.js → errors-YQAVCXXO.js} +9 -1
  42. package/build/feedback-G2DFCCI6.js +113 -0
  43. package/build/{init-all-54G3CVZA.js → init-all-JXLG7LOX.js} +5 -5
  44. package/build/{mcpServer-NWOKFR7Q.js → mcpServer-SUDGFNIF.js} +2 -2
  45. package/build/monitor-worker.js +62 -10
  46. package/build/{namespace-PA2IDNRT.js → namespace-XMFFW47T.js} +1 -1
  47. package/build/{output-XGTE4EWJ.js → output-BBHBJI32.js} +5 -1
  48. package/build/release.json +4 -4
  49. package/build/routing-4VKAVRYR.js +43 -0
  50. package/build/{serve-XRNMHIJX.js → serve-BYC3LRLN.js} +1 -1
  51. package/build/server.js +317 -41
  52. package/build/stdio.js +2 -2
  53. package/build/{tools-FNPMELSU.js → tools-NJQPIJ53.js} +81 -33
  54. package/build/{uninstall-P3JJZCXT.js → uninstall-4TJ4SZLU.js} +26 -7
  55. package/build/{upgrade-ATIFZANV.js → upgrade-3NR3LAGU.js} +2 -2
  56. package/build/{watch-FG2C5Y2Z.js → watch-BUSEPVDM.js} +5 -3
  57. package/package.json +1 -1
@@ -1,4 +1,7 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ NEVER_RETRY_ERROR_CODES
4
+ } from "./chunk-ZSPPJW4G.js";
2
5
  import {
3
6
  SERVER_VERSION
4
7
  } from "./chunk-ZXKFJQDE.js";
@@ -9,6 +12,56 @@ import {
9
12
  } from "./chunk-6PC3HUAK.js";
10
13
 
11
14
  // src/cli/api-client.ts
15
+ function errorCodeFromBody(body) {
16
+ if (!body || typeof body !== "object") return null;
17
+ const error = body.error;
18
+ if (!error || typeof error !== "object") return null;
19
+ const direct = error.code;
20
+ if (typeof direct === "string") return direct;
21
+ const nested = error.data?.code;
22
+ return typeof nested === "string" ? nested : null;
23
+ }
24
+ async function peekErrorCode(response) {
25
+ if (typeof response.clone !== "function") return null;
26
+ try {
27
+ return errorCodeFromBody(await response.clone().json());
28
+ } catch {
29
+ return null;
30
+ }
31
+ }
32
+ function parseRetryAfter(header) {
33
+ if (header == null || header === "") return null;
34
+ const seconds = Number.parseInt(header, 10);
35
+ return Number.isFinite(seconds) && seconds >= 0 ? seconds : null;
36
+ }
37
+ function attachResponseMeta(data, response, now = Date.now()) {
38
+ const meta = { ...data.meta ?? {} };
39
+ const quotaHeader = response.headers?.get?.("x-quota-remaining");
40
+ if (quotaHeader != null && quotaHeader !== "") {
41
+ const quotaRemaining = Number.parseInt(quotaHeader, 10);
42
+ if (Number.isFinite(quotaRemaining)) meta.quota_remaining = quotaRemaining;
43
+ }
44
+ if ("credits_remaining" in meta) {
45
+ const credits = meta.credits_remaining;
46
+ if (credits === null || typeof credits === "number") {
47
+ meta.quota_remaining = credits;
48
+ }
49
+ }
50
+ const retryAfter = parseRetryAfter(response.headers?.get?.("retry-after"));
51
+ const bodyResetAt = [
52
+ data.reset_at,
53
+ data.error?.reset_at,
54
+ data.error?.data?.reset_at,
55
+ meta.reset_at
56
+ ].find((value) => typeof value === "string" && value !== "");
57
+ if (retryAfter !== null) meta.retry_after_seconds = retryAfter;
58
+ if (bodyResetAt) {
59
+ meta.reset_at = bodyResetAt;
60
+ } else if (retryAfter !== null) {
61
+ meta.reset_at = new Date(now + retryAfter * 1e3).toISOString();
62
+ }
63
+ return { ...data, meta };
64
+ }
12
65
  var MAX_RETRIES = 3;
13
66
  var BASE_DELAY_MS = 500;
14
67
  var MAX_DELAY_MS = 5e3;
@@ -44,6 +97,8 @@ async function fetchWithRetry(url, init, fetchFn = fetch) {
44
97
  if (response.ok || !isRetryable(response.status) || attempt === maxRetries) {
45
98
  return response;
46
99
  }
100
+ const code = await peekErrorCode(response);
101
+ if (code && NEVER_RETRY_ERROR_CODES.has(code)) return response;
47
102
  lastResponse = response;
48
103
  const retryAfter = response.headers?.get?.("retry-after") ?? null;
49
104
  const waitMs = computeDelay(attempt, retryAfter);
@@ -87,14 +142,7 @@ async function executeRemoteTool(toolName, args, timeoutMs = 3e4) {
87
142
  signal: controller.signal
88
143
  });
89
144
  const data = await response.json();
90
- const quotaHeader = response.headers?.get?.("x-quota-remaining");
91
- if (quotaHeader != null && quotaHeader !== "") {
92
- const quotaRemaining = Number.parseInt(quotaHeader, 10);
93
- if (Number.isFinite(quotaRemaining)) {
94
- data.meta = { ...data.meta ?? {}, quota_remaining: quotaRemaining };
95
- }
96
- }
97
- return data;
145
+ return attachResponseMeta(data, response);
98
146
  } catch (error) {
99
147
  if (error instanceof Error && error.name === "AbortError") {
100
148
  return {
@@ -192,10 +240,53 @@ async function getUsage() {
192
240
  });
193
241
  return response.json();
194
242
  }
243
+ var SMALL_REQUEST_TIMEOUT_MS = 1e4;
244
+ async function parseJsonBody(response) {
245
+ try {
246
+ const body = await response.json();
247
+ return body && typeof body === "object" ? body : null;
248
+ } catch {
249
+ return null;
250
+ }
251
+ }
252
+ async function postFeedback(payload) {
253
+ const url = buildApiUrl("/api/v1/feedback");
254
+ const response = await fetchWithRetry(url, {
255
+ method: "POST",
256
+ headers: getHeaders(resolveApiKey()),
257
+ body: JSON.stringify(payload),
258
+ signal: AbortSignal.timeout(SMALL_REQUEST_TIMEOUT_MS)
259
+ });
260
+ const body = await parseJsonBody(response);
261
+ if (!body) {
262
+ return {
263
+ ok: false,
264
+ error: {
265
+ code: "API_ERROR",
266
+ message: `Feedback endpoint answered HTTP ${response.status} without a JSON body`,
267
+ suggestion: `Check HIVE_API_URL (${resolveApiUrl()})`
268
+ },
269
+ meta: { http_status: response.status }
270
+ };
271
+ }
272
+ return attachResponseMeta(body, response);
273
+ }
274
+ async function getAnonQuota() {
275
+ const url = buildApiUrl("/api/v1/quota");
276
+ const response = await fetchWithRetry(url, {
277
+ headers: getHeaders(),
278
+ signal: AbortSignal.timeout(SMALL_REQUEST_TIMEOUT_MS)
279
+ });
280
+ return { status: response.status, body: await parseJsonBody(response) };
281
+ }
195
282
 
196
283
  export {
284
+ errorCodeFromBody,
285
+ attachResponseMeta,
197
286
  fetchWithRetry,
198
287
  executeRemoteTool,
199
288
  fetchToolCatalog,
200
- getUsage
289
+ getUsage,
290
+ postFeedback,
291
+ getAnonQuota
201
292
  };
@@ -0,0 +1,32 @@
1
+ import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ ensureConfigDir,
4
+ getConfigDir,
5
+ readJsonFile,
6
+ writeJsonFile
7
+ } from "./chunk-6PC3HUAK.js";
8
+
9
+ // src/cli/last-receipt.ts
10
+ import { join } from "path";
11
+ function lastReceiptPath() {
12
+ return join(getConfigDir(), "last-receipt.json");
13
+ }
14
+ function saveLastReceipt(receipt) {
15
+ try {
16
+ ensureConfigDir();
17
+ writeJsonFile(lastReceiptPath(), receipt);
18
+ } catch {
19
+ }
20
+ }
21
+ function readLastReceipt() {
22
+ const stored = readJsonFile(lastReceiptPath());
23
+ if (!stored || typeof stored.receipt_id !== "string" || typeof stored.tool !== "string" || typeof stored.at !== "string") {
24
+ return null;
25
+ }
26
+ return { receipt_id: stored.receipt_id, tool: stored.tool, at: stored.at };
27
+ }
28
+
29
+ export {
30
+ saveLastReceipt,
31
+ readLastReceipt
32
+ };
@@ -1,16 +1,23 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ saveLastReceipt
4
+ } from "./chunk-XN3T6YOG.js";
2
5
  import {
3
6
  executeRemoteTool
4
- } from "./chunk-P7NLFSZQ.js";
7
+ } from "./chunk-RNVZIPNY.js";
5
8
  import {
6
9
  trackCommand
7
10
  } from "./chunk-RU6QOFHH.js";
11
+ import {
12
+ ExitCode
13
+ } from "./chunk-ZSPPJW4G.js";
8
14
  import {
9
15
  debug,
10
16
  dim,
17
+ isQuiet,
11
18
  shouldOutputJson,
12
19
  writeOutput
13
- } from "./chunk-LP5ECG7A.js";
20
+ } from "./chunk-ZDXMZPC6.js";
14
21
  import {
15
22
  resolveApiKey
16
23
  } from "./chunk-6PC3HUAK.js";
@@ -79,8 +86,38 @@ function remapForKeylessHero(toolName, args) {
79
86
  }
80
87
 
81
88
  // src/cli/execute.ts
89
+ var EXIT_CODE_BY_ERROR = {
90
+ TOOL_NOT_FOUND: ExitCode.TOOL_NOT_FOUND,
91
+ TOOL_RETIRED: ExitCode.TOOL_NOT_FOUND,
92
+ PROVIDER_UNAVAILABLE: ExitCode.AUTH_FAILURE,
93
+ RATE_LIMITED: ExitCode.RATE_LIMITED,
94
+ TIMEOUT: ExitCode.TIMEOUT,
95
+ // Cap lane (exit 6): the call is outside what this credential can do
96
+ // today; the human message carries the reset time.
97
+ ANON_QUOTA_EXCEEDED: ExitCode.RATE_LIMITED,
98
+ ANON_GLOBAL_CAP_EXCEEDED: ExitCode.RATE_LIMITED,
99
+ ANON_AUTH_REQUIRED: ExitCode.RATE_LIMITED,
100
+ QUOTA_EXCEEDED: ExitCode.RATE_LIMITED,
101
+ FEEDBACK_RATE_LIMITED: ExitCode.RATE_LIMITED,
102
+ // Account state, not a cap: no reset time, retrying cannot help.
103
+ NO_WALLET: ExitCode.API_ERROR
104
+ };
105
+ function exitCodeForError(code) {
106
+ return code && EXIT_CODE_BY_ERROR[code] || ExitCode.API_ERROR;
107
+ }
108
+ function creditFooter(meta, keyed) {
109
+ if (!meta) return null;
110
+ if (keyed) {
111
+ if (typeof meta.credits_used !== "number") return null;
112
+ const remaining = meta.credits_remaining === null ? "unlimited" : typeof meta.credits_remaining === "number" ? String(meta.credits_remaining) : null;
113
+ return remaining === null ? `credits: used ${meta.credits_used}` : `credits: used ${meta.credits_used}, remaining ${remaining}`;
114
+ }
115
+ if (typeof meta.quota_remaining !== "number") return null;
116
+ return `free calls left today: ${meta.quota_remaining} (run \`hive auth login\` for a full key)`;
117
+ }
82
118
  async function executeTool(toolName, args, timeoutMs = 3e4) {
83
- if (!resolveApiKey()) {
119
+ const keyed = Boolean(resolveApiKey());
120
+ if (!keyed) {
84
121
  const remap = remapForKeylessHero(toolName, args);
85
122
  if (remap) {
86
123
  debug(remap.note);
@@ -106,17 +143,20 @@ async function executeTool(toolName, args, timeoutMs = 3e4) {
106
143
  response.ok ? void 0 : response.error?.code
107
144
  );
108
145
  await writeOutput(response);
109
- const quotaRemaining = response.meta?.quota_remaining;
110
- if (typeof quotaRemaining === "number" && !resolveApiKey() && !shouldOutputJson()) {
111
- process.stderr.write(
112
- dim(
113
- `${quotaRemaining} free call${quotaRemaining === 1 ? "" : "s"} left today. Run \`hive auth login\` for a full key.`
114
- ) + "\n"
115
- );
146
+ const receiptId = response.meta?.receipt_id;
147
+ if (response.ok && typeof receiptId === "string" && receiptId) {
148
+ saveLastReceipt({
149
+ receipt_id: receiptId,
150
+ tool: toolName,
151
+ at: (/* @__PURE__ */ new Date()).toISOString()
152
+ });
153
+ }
154
+ const footer = creditFooter(response.meta, keyed);
155
+ if (footer && !shouldOutputJson() && !isQuiet()) {
156
+ process.stderr.write(dim(footer) + "\n");
116
157
  }
117
158
  if (!response.ok) {
118
- const exitCode = response.error?.code === "TOOL_NOT_FOUND" || response.error?.code === "TOOL_RETIRED" ? 3 : response.error?.code === "PROVIDER_UNAVAILABLE" ? 5 : response.error?.code === "RATE_LIMITED" ? 6 : response.error?.code === "TIMEOUT" ? 124 : 4;
119
- process.exit(exitCode);
159
+ process.exit(exitCodeForError(response.error?.code));
120
160
  }
121
161
  }
122
162
 
@@ -7,7 +7,7 @@ import {
7
7
  getSupabaseAdmin,
8
8
  resolveEndpoint,
9
9
  secureLogger
10
- } from "./chunk-J2PXISXW.js";
10
+ } from "./chunk-LP7PDQCO.js";
11
11
 
12
12
  // src/services/wallet-service.ts
13
13
  async function consumeCredits(args) {
@@ -134,7 +134,8 @@ async function executeToolByName(toolName, args, options) {
134
134
  requestId: options?.requestId,
135
135
  clients: getSharedClients(),
136
136
  analytics: options?.analytics,
137
- beforeExecution: options?.beforeExecution
137
+ beforeExecution: options?.beforeExecution,
138
+ creditCost: options?.creditCost
138
139
  });
139
140
  if (result.validationErrors) {
140
141
  return {
@@ -119,6 +119,9 @@ function shouldOutputJson() {
119
119
  if (globalOpts.pretty) return false;
120
120
  return !process.stdout.isTTY;
121
121
  }
122
+ function isQuiet() {
123
+ return Boolean(globalOpts.quiet);
124
+ }
122
125
  function colorEnabled() {
123
126
  if (globalOpts.noColor) return false;
124
127
  if (process.env.NO_COLOR) return false;
@@ -140,6 +143,20 @@ function dim(s) {
140
143
  function bold(s) {
141
144
  return colorEnabled() ? `\x1B[1m${s}\x1B[0m` : s;
142
145
  }
146
+ function formatDuration(totalSeconds) {
147
+ const seconds = Math.max(0, Math.round(totalSeconds));
148
+ const hours = Math.floor(seconds / 3600);
149
+ const minutes = Math.floor(seconds % 3600 / 60);
150
+ const rest = seconds % 60;
151
+ if (hours > 0) return `${hours}h ${minutes}m`;
152
+ if (minutes > 0) return `${minutes}m ${rest}s`;
153
+ return `${rest}s`;
154
+ }
155
+ function describeReset(meta) {
156
+ if (!meta.reset_at) return null;
157
+ const relative = typeof meta.retry_after_seconds === "number" ? ` (in ${formatDuration(meta.retry_after_seconds)})` : "";
158
+ return `Resets: ${meta.reset_at}${relative}`;
159
+ }
143
160
  function successEnvelope(data, meta) {
144
161
  return { ok: true, data, meta };
145
162
  }
@@ -219,7 +236,9 @@ async function writeOutput(envelope) {
219
236
  `));
220
237
  }
221
238
  if (envelope.meta.truncated) {
222
- process.stderr.write(yellow("Evidence warning: response was truncated.\n"));
239
+ process.stderr.write(
240
+ yellow("Evidence warning: response was truncated.\n")
241
+ );
223
242
  }
224
243
  for (const warning of envelope.meta.warnings ?? []) {
225
244
  process.stderr.write(yellow(`Evidence warning: ${warning}
@@ -247,11 +266,14 @@ async function writeOutput(envelope) {
247
266
  `)
248
267
  );
249
268
  }
250
- const nextAction = envelope.meta?.next_action;
269
+ const nextAction = envelope.meta.next_action;
251
270
  if (typeof nextAction === "string" && nextAction.trim()) {
252
271
  process.stderr.write(yellow(` Next: ${nextAction}
253
272
  `));
254
273
  }
274
+ const reset = describeReset(envelope.meta);
275
+ if (reset) process.stderr.write(yellow(` ${reset}
276
+ `));
255
277
  }
256
278
  }
257
279
  async function outputSuccess(data, meta) {
@@ -289,12 +311,14 @@ function formatCsv(data) {
289
311
  export {
290
312
  setOutputOptions,
291
313
  shouldOutputJson,
314
+ isQuiet,
292
315
  colorEnabled,
293
316
  red,
294
317
  green,
295
318
  yellow,
296
319
  dim,
297
320
  bold,
321
+ describeReset,
298
322
  successEnvelope,
299
323
  errorEnvelope,
300
324
  writeOutput,
@@ -12,6 +12,14 @@ var ExitCode = {
12
12
  RATE_LIMITED: 6,
13
13
  TIMEOUT: 124
14
14
  };
15
+ var NEVER_RETRY_ERROR_CODES = /* @__PURE__ */ new Set([
16
+ "ANON_QUOTA_EXCEEDED",
17
+ "ANON_GLOBAL_CAP_EXCEEDED",
18
+ "ANON_AUTH_REQUIRED",
19
+ "QUOTA_EXCEEDED",
20
+ "NO_WALLET",
21
+ "FEEDBACK_RATE_LIMITED"
22
+ ]);
15
23
  var ERROR_CODE_TO_EXIT = {
16
24
  GENERAL_ERROR: ExitCode.GENERAL_ERROR,
17
25
  INVALID_ARGS: ExitCode.INVALID_ARGS,
@@ -22,16 +30,45 @@ var ERROR_CODE_TO_EXIT = {
22
30
  AUTH_REQUIRED: ExitCode.AUTH_FAILURE,
23
31
  RATE_LIMITED: ExitCode.RATE_LIMITED,
24
32
  TIMEOUT: ExitCode.TIMEOUT,
25
- VALIDATION_ERROR: ExitCode.INVALID_ARGS
33
+ VALIDATION_ERROR: ExitCode.INVALID_ARGS,
34
+ // Cap lane: exit 6, the same class as RATE_LIMITED, because the fix is
35
+ // "wait for the reset or bring a key", not "fix the call".
36
+ ANON_QUOTA_EXCEEDED: ExitCode.RATE_LIMITED,
37
+ ANON_GLOBAL_CAP_EXCEEDED: ExitCode.RATE_LIMITED,
38
+ ANON_AUTH_REQUIRED: ExitCode.RATE_LIMITED,
39
+ QUOTA_EXCEEDED: ExitCode.RATE_LIMITED,
40
+ FEEDBACK_RATE_LIMITED: ExitCode.RATE_LIMITED,
41
+ // Account state, not a cap: there is no reset time and retrying cannot help.
42
+ NO_WALLET: ExitCode.API_ERROR,
43
+ // Credential rejected: same class as AUTH_REQUIRED, because the fix is the
44
+ // key, not the call.
45
+ UNAUTHORIZED: ExitCode.AUTH_FAILURE,
46
+ INVALID_API_KEY: ExitCode.AUTH_FAILURE,
47
+ // The server answered, the call failed there.
48
+ TOOL_ERROR: ExitCode.API_ERROR,
49
+ INTERNAL_ERROR: ExitCode.API_ERROR
26
50
  };
51
+ var ERROR_DOCS_BASE = "https://www.hiveintelligence.xyz/errors#";
52
+ function errorDocSlug(code) {
53
+ return code.toLowerCase().replace(/_/g, "-");
54
+ }
27
55
  var ERROR_DOC_URLS = {
28
56
  AUTH_REQUIRED: "https://www.hiveintelligence.xyz/errors#auth-required",
29
57
  RATE_LIMITED: "https://www.hiveintelligence.xyz/errors#rate-limited",
30
58
  TIMEOUT: "https://www.hiveintelligence.xyz/errors#timeout",
31
59
  PROVIDER_UNAVAILABLE: "https://www.hiveintelligence.xyz/errors#provider-unavailable",
32
60
  TOOL_NOT_FOUND: "https://www.hiveintelligence.xyz/errors#tool-not-found",
33
- TOOL_RETIRED: "https://www.hiveintelligence.xyz/errors#tool-retired"
61
+ TOOL_RETIRED: "https://www.hiveintelligence.xyz/errors#tool-retired",
62
+ ANON_QUOTA_EXCEEDED: `${ERROR_DOCS_BASE}${errorDocSlug("ANON_QUOTA_EXCEEDED")}`,
63
+ ANON_GLOBAL_CAP_EXCEEDED: `${ERROR_DOCS_BASE}${errorDocSlug("ANON_GLOBAL_CAP_EXCEEDED")}`,
64
+ ANON_AUTH_REQUIRED: `${ERROR_DOCS_BASE}${errorDocSlug("ANON_AUTH_REQUIRED")}`,
65
+ QUOTA_EXCEEDED: `${ERROR_DOCS_BASE}${errorDocSlug("QUOTA_EXCEEDED")}`,
66
+ NO_WALLET: `${ERROR_DOCS_BASE}${errorDocSlug("NO_WALLET")}`,
67
+ FEEDBACK_RATE_LIMITED: `${ERROR_DOCS_BASE}${errorDocSlug("FEEDBACK_RATE_LIMITED")}`
34
68
  };
69
+ function isCliErrorCode(code) {
70
+ return typeof code === "string" && code in ERROR_CODE_TO_EXIT;
71
+ }
35
72
  var CliError = class extends Error {
36
73
  code;
37
74
  exitCode;
@@ -61,11 +98,7 @@ function classifyError(error, toolName) {
61
98
  );
62
99
  }
63
100
  if (lower.includes("api key") || lower.includes("unauthorized") || lower.includes("not configured") || lower.includes("unavailable")) {
64
- return new CliError(
65
- "PROVIDER_UNAVAILABLE",
66
- msg,
67
- "Run: hive auth login"
68
- );
101
+ return new CliError("PROVIDER_UNAVAILABLE", msg, "Run: hive auth login");
69
102
  }
70
103
  if (lower.includes("not found") && toolName) {
71
104
  return new CliError(
@@ -82,7 +115,11 @@ function suggestSimilarTools(input, toolNames, maxDistance = 3) {
82
115
 
83
116
  export {
84
117
  ExitCode,
118
+ NEVER_RETRY_ERROR_CODES,
119
+ ERROR_CODE_TO_EXIT,
120
+ errorDocSlug,
85
121
  ERROR_DOC_URLS,
122
+ isCliErrorCode,
86
123
  CliError,
87
124
  classifyError,
88
125
  suggestSimilarTools