hive-intelligence 1.4.0 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/README.md +2 -2
  2. package/build/{auth-HRFQWQMZ.js → auth-Y4GXW376.js} +1 -1
  3. package/build/{browser-auth-KXIO5BHM.js → browser-auth-F62BMD7W.js} +1 -1
  4. package/build/{chunk-UFTNBCSA.js → chunk-AGM2CIRL.js} +86 -16
  5. package/build/{chunk-AQQAPAER.js → chunk-BDO27NIP.js} +2 -2
  6. package/build/{chunk-GHCYCBA3.js → chunk-GB4XMTDE.js} +2 -2
  7. package/build/{chunk-TNQ7GJ6Q.js → chunk-GWZIAAQ2.js} +58 -40
  8. package/build/{chunk-7DYHWY4Y.js → chunk-SFN772RL.js} +4 -4
  9. package/build/{chunk-AEU43ACS.js → chunk-TVBPCELA.js} +2 -2
  10. package/build/{chunk-TVQJY47C.js → chunk-WF34ZD5I.js} +6 -6
  11. package/build/{chunk-3OZFBWFK.js → chunk-XQPEFCSY.js} +1 -1
  12. package/build/cli.js +27 -27
  13. package/build/{completion-7KBW243H.js → completion-C57PDJMY.js} +1 -1
  14. package/build/{doctor-GHUAUFS2.js → doctor-XG5IQCXK.js} +4 -4
  15. package/build/{init-UCTCUYFA.js → init-COHA3VZI.js} +3 -3
  16. package/build/{init-all-RG542NWG.js → init-all-YTQJLPLR.js} +14 -14
  17. package/build/{mcpServer-D7OXUDU5.js → mcpServer-XHIN5JER.js} +1 -1
  18. package/build/monitor-worker.js +2 -2
  19. package/build/{namespace-L5DGCY7K.js → namespace-YLCGHVRT.js} +1 -1
  20. package/build/release.json +4 -4
  21. package/build/{serve-K3IT7DS4.js → serve-PWMT5IRU.js} +1 -1
  22. package/build/server.js +22 -13
  23. package/build/stdio.js +1 -1
  24. package/build/{tools-D72ZH6P5.js → tools-XNFJBN7Q.js} +1 -1
  25. package/build/{uninstall-SAOIPL6K.js → uninstall-TKDP6C4F.js} +7 -7
  26. package/build/{upgrade-4S5XT5JG.js → upgrade-ODPKMIDC.js} +1 -1
  27. package/build/{watch-IOSRSCFE.js → watch-MXJSNGL2.js} +1 -1
  28. package/package.json +1 -1
package/README.md CHANGED
@@ -41,7 +41,7 @@ client setup, self-hosting, or provider-key experiments.
41
41
  - Bundled agent skills that teach assistants the right Hive workflow:
42
42
  discovery -> schema lookup -> bounded execution -> evidence receipt.
43
43
  - A broad provider catalog remains available behind discovery for agents that
44
- need a long-tail endpoint. The current catalog contains 615 tools, but that
44
+ need a long-tail endpoint. The current catalog contains 607 tools, but that
45
45
  coverage is not the primary product contract.
46
46
 
47
47
  ## Quickstart
@@ -109,7 +109,7 @@ Expected output shape:
109
109
  "source": "live",
110
110
  "receipt_id": "00000000-0000-4000-8000-000000000000",
111
111
  "receipt_version": "1.0",
112
- "server_version": "1.4.0",
112
+ "server_version": "1.5.0",
113
113
  "build_sha": null,
114
114
  "digest_algorithm": "sha256",
115
115
  "input_digest": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
@@ -12,7 +12,7 @@ import {
12
12
  runWhoami,
13
13
  saveProfile,
14
14
  switchProfile
15
- } from "./chunk-TVQJY47C.js";
15
+ } from "./chunk-WF34ZD5I.js";
16
16
  import "./chunk-6PC3HUAK.js";
17
17
  import "./chunk-ILVPOLA7.js";
18
18
  export {
@@ -7,7 +7,7 @@ import {
7
7
  buildCliLoginUrl,
8
8
  exchangeCliCode,
9
9
  parseCliCallback
10
- } from "./chunk-AQQAPAER.js";
10
+ } from "./chunk-BDO27NIP.js";
11
11
  import "./chunk-ILVPOLA7.js";
12
12
  export {
13
13
  CLI_CALLBACK_PATH,
@@ -81725,9 +81725,16 @@ function generateStructuredDescription(toolName, existingDescription, inputSchem
81725
81725
  }
81726
81726
  function buildSummary(toolName, existing) {
81727
81727
  let summary = existing.replace(/\*\*/g, "").trim();
81728
- if (!/^(Get|Fetch|Retrieve|Search|Filter|Check|List|Return|Query)/i.test(
81729
- summary
81730
- )) {
81728
+ const boilerplate = /^this endpoint (?:allows you to|lets you|is used to|can be used to)\s+/i;
81729
+ if (boilerplate.test(summary)) {
81730
+ summary = summary.replace(boilerplate, "");
81731
+ summary = summary.charAt(0).toUpperCase() + summary.slice(1);
81732
+ } else if (
81733
+ // Ensure it starts with a verb
81734
+ !/^(Get|Fetch|Retrieve|Search|Filter|Check|List|Return|Query)/i.test(
81735
+ summary
81736
+ )
81737
+ ) {
81731
81738
  const verb = inferVerb(toolName);
81732
81739
  summary = `${verb} ${summary.charAt(0).toLowerCase()}${summary.slice(1)}`;
81733
81740
  }
@@ -86755,6 +86762,54 @@ function heroTools(endpoints, options = {}) {
86755
86762
  response_format: RESPONSE_FORMAT
86756
86763
  });
86757
86764
  const MAX_CONCISE_TOKENS = 15;
86765
+ const NATIVE_SYMBOLS = {
86766
+ eth: "ETH",
86767
+ ethereum: "ETH",
86768
+ mainnet: "ETH",
86769
+ base: "ETH",
86770
+ polygon: "POL",
86771
+ matic: "POL",
86772
+ arbitrum: "ETH",
86773
+ arb: "ETH",
86774
+ optimism: "ETH",
86775
+ opt: "ETH",
86776
+ bsc: "BNB",
86777
+ bnb: "BNB",
86778
+ avalanche: "AVAX",
86779
+ avax: "AVAX",
86780
+ solana: "SOL"
86781
+ };
86782
+ const decodeBalance = (raw, decimals) => {
86783
+ if (raw == null) return null;
86784
+ if (typeof raw === "number")
86785
+ return Number.isFinite(raw) ? String(raw) : null;
86786
+ if (typeof raw !== "string") return null;
86787
+ const text = raw.trim();
86788
+ if (!text) return null;
86789
+ let units;
86790
+ try {
86791
+ units = BigInt(text);
86792
+ } catch {
86793
+ return text;
86794
+ }
86795
+ const scale = typeof decimals === "number" && Number.isInteger(decimals) && decimals > 0 ? decimals : 0;
86796
+ if (scale === 0) return units.toString();
86797
+ const base = 10n ** BigInt(scale);
86798
+ const whole = units / base;
86799
+ const frac = (units % base).toString().padStart(scale, "0").replace(/0+$/, "");
86800
+ return frac ? `${whole}.${frac.slice(0, 8)}` : whole.toString();
86801
+ };
86802
+ const usdFromPrices = (token, balance) => {
86803
+ if (!Array.isArray(token.tokenPrices)) return null;
86804
+ const usd = token.tokenPrices.find(
86805
+ (price) => isRecord3(price) && price.currency === "usd"
86806
+ );
86807
+ const rate = usd && isRecord3(usd) ? Number(usd.value) : NaN;
86808
+ const quantity = balance == null ? NaN : Number(balance);
86809
+ const value = rate * quantity;
86810
+ if (!Number.isFinite(value)) return null;
86811
+ return value >= 0.01 ? Math.round(value * 100) / 100 : value;
86812
+ };
86758
86813
  const firstArray = (payload, keys) => {
86759
86814
  for (const key of keys) {
86760
86815
  const direct = payload[key];
@@ -86767,25 +86822,40 @@ function heroTools(endpoints, options = {}) {
86767
86822
  return [];
86768
86823
  };
86769
86824
  const trimWalletPortfolio = (address, chainLabel) => (payload) => {
86825
+ const walletLower = address.trim().toLowerCase();
86770
86826
  const tokens = firstArray(payload, ["tokens", "items", "balances"]);
86771
- const summarized = tokens.slice(0, MAX_CONCISE_TOKENS).map((token) => {
86827
+ const summarized = tokens.map((token) => {
86772
86828
  if (!isRecord3(token)) return token;
86773
86829
  const metadata93 = isRecord3(token.tokenMetadata) ? token.tokenMetadata : isRecord3(token.token) ? token.token : void 0;
86830
+ const fallbackAddress = typeof token.address === "string" && token.address.trim().toLowerCase() === walletLower ? null : token.address ?? null;
86831
+ const tokenAddress = token.tokenAddress ?? token.mint ?? fallbackAddress;
86832
+ const isNative = tokenAddress == null;
86833
+ const rawDecimals = token.decimals ?? metadata93?.decimals;
86834
+ const decimals = typeof rawDecimals === "number" ? rawDecimals : isNative ? 18 : void 0;
86835
+ const balance = decodeBalance(
86836
+ token.balance ?? token.amount ?? token.tokenBalance ?? token.uiAmount ?? null,
86837
+ decimals
86838
+ );
86774
86839
  return {
86775
- symbol: token.symbol ?? metadata93?.symbol ?? token.tokenSymbol ?? null,
86840
+ symbol: token.symbol ?? metadata93?.symbol ?? token.tokenSymbol ?? (isNative ? NATIVE_SYMBOLS[chainLabel] ?? null : null),
86776
86841
  name: token.name ?? metadata93?.name ?? null,
86777
- address: token.tokenAddress ?? token.mint ?? token.address ?? null,
86778
- balance: token.balance ?? token.amount ?? token.tokenBalance ?? token.uiAmount ?? null,
86779
- usd_value: token.totalValueUsd ?? token.valueUsd ?? token.usd_value ?? token.totalValueUsdCents ?? null
86842
+ address: tokenAddress,
86843
+ balance,
86844
+ usd_value: token.totalValueUsd ?? token.valueUsd ?? token.usd_value ?? (typeof token.totalValueUsdCents === "number" ? token.totalValueUsdCents / 100 : usdFromPrices(token, balance))
86780
86845
  };
86781
86846
  });
86847
+ const held = summarized.filter(
86848
+ (token) => !isRecord3(token) || token.balance !== "0"
86849
+ );
86782
86850
  return {
86783
86851
  address,
86784
86852
  chain: chainLabel,
86785
- token_count: tokens.length,
86786
- tokens: summarized,
86787
- ...tokens.length > MAX_CONCISE_TOKENS ? {
86788
- note: `Showing the first ${MAX_CONCISE_TOKENS} of ${tokens.length} tokens. Use response_format=detailed for the full list.`
86853
+ token_count: held.length,
86854
+ tokens: held.slice(0, MAX_CONCISE_TOKENS),
86855
+ ...held.length > MAX_CONCISE_TOKENS ? {
86856
+ note: `Showing the first ${MAX_CONCISE_TOKENS} of ${held.length} held tokens (zero balances omitted). Use response_format=detailed for the full provider payload.`
86857
+ } : summarized.length > held.length ? {
86858
+ note: `${summarized.length - held.length} zero-balance tokens omitted. Use response_format=detailed for the full provider payload.`
86789
86859
  } : {}
86790
86860
  };
86791
86861
  };
@@ -87635,7 +87705,7 @@ var TASK_TOOLSET_ROUTES = {
87635
87705
  steps: [
87636
87706
  step(
87637
87707
  "funding",
87638
- "Read normalized funding across all five RWA venues with per-venue runtime status; respect funding_mechanism \u2014 both-sides rollover (borrow_apr_annual) is never sign-comparable with a funding transfer.",
87708
+ "Read normalized funding across all five RWA venues with per-venue runtime status; respect funding_mechanism, since both-sides rollover (borrow_apr_annual) is never sign-comparable with a funding transfer.",
87639
87709
  "rwa_get_funding_rates",
87640
87710
  "rwa_get_hyperliquid_dex_perps",
87641
87711
  `${PROVIDER_FALLBACK} The flagship builder dexes carry the deepest RWA books when the full fan-out is unavailable.`
@@ -88557,7 +88627,7 @@ var TASK_TOOLSET_CATALOG = [
88557
88627
  id: "rwa_perp_analysis",
88558
88628
  kind: "product",
88559
88629
  label: "RWA Perp Analysis",
88560
- purpose: "Analyze tokenized real-world-asset perps \u2014 stocks, pre-IPO names, ETFs, indices, commodities, FX \u2014 across Hyperliquid HIP-3 builder dexes, Ostium, Avantis, Lighter, and Extended: cross-venue funding, mechanism-true carry, open interest, and price-suspect checks.",
88630
+ purpose: "Analyze tokenized real-world-asset perps (stocks, pre-IPO names, ETFs, indices, commodities, FX) across Hyperliquid HIP-3 builder dexes, Ostium, Avantis, Lighter, and Extended: cross-venue funding, mechanism-true carry, open interest, and price-suspect checks.",
88561
88631
  outcome: "A cross-venue RWA perp report with normalized funding (raw + annualized per venue mechanism), asset-class and delisted/price-suspect flags on every row, per-venue runtime status, and receipts.",
88562
88632
  requiredIdentifiers: ["underlying ticker, venue, or asset class"],
88563
88633
  optionalIdentifiers: ["builder dex name", "time range"],
@@ -90309,7 +90379,7 @@ var HIVE_RESOURCES = [
90309
90379
  ];
90310
90380
  var RUNTIME_STATUS_SEMANTICS = {
90311
90381
  ok: "Provider call is expected to work with current configuration.",
90312
- invalid_input: "The arguments failed validation or named an unsupported venue/method. The provider was not the problem \u2014 fix the input (check the schema, use a supported value) and retry. This is NOT an outage, auth, rate-limit, or plan issue.",
90382
+ invalid_input: "The arguments failed validation or named an unsupported venue/method. The provider was not the problem: fix the input (check the schema, use a supported value) and retry. This is NOT an outage, auth, rate-limit, or plan issue.",
90313
90383
  missing_key: "Provider credentials are not configured for this runtime.",
90314
90384
  plan_required: "The tool exists but the upstream account plan, quota, or credits prevent execution.",
90315
90385
  rate_limited: "The upstream or Hive rate limit was hit. Retry after backoff or Retry-After.",
@@ -99279,7 +99349,7 @@ function buildServerInstructions(scope) {
99279
99349
  ].join(" ");
99280
99350
  }
99281
99351
  return [
99282
- `Hive serves live crypto market data to AI agents over a compact ${ROOT_META_TOOL_COUNT}-tool root. Loop: search_tools -> get_api_endpoint_schema -> ${READ_ENDPOINT_INVOKER} for reads (${STATEFUL_WRITE_ENDPOINT_INVOKER} only after explicit user approval; validate_task_result before structured answers). Every material response carries a _hive receipt \u2014 provider, fetched_at, runtime_status, _hive.receipt_id \u2014 cite it when answering.`,
99352
+ `Hive serves live crypto market data to AI agents over a compact ${ROOT_META_TOOL_COUNT}-tool root. Loop: search_tools -> get_api_endpoint_schema -> ${READ_ENDPOINT_INVOKER} for reads (${STATEFUL_WRITE_ENDPOINT_INVOKER} only after explicit user approval; validate_task_result before structured answers). Every material response carries a _hive receipt (provider, fetched_at, runtime_status, _hive.receipt_id); cite it when answering.`,
99283
99353
  `For the three dominant intents call the hero tools directly: get_token_price, check_token_safety, get_wallet_portfolio (response_format "concise" default, "detailed" available).`,
99284
99354
  `Degraded providers are reported, not hidden: search_tools marks each tool's availability, and unavailable tools return runtime_status with cause and next_action instead of data. Follow next_action; never retry an unchanged failing call in a loop.`,
99285
99355
  `Discovery is free and cheap: resources hive://toolsets, hive://providers, hive://tools; the ${UNDERLYING_TOOL_COUNT}-tool catalog stays reachable through search_tools or scoped category endpoints. Use limit/page/per_page to keep responses small; a material execution costs 1 credit on the hosted service.`
@@ -91,7 +91,7 @@ async function browserLogin(opts) {
91
91
  }
92
92
  if (outcome.kind === "state-mismatch") {
93
93
  res.writeHead(403);
94
- res.end("State mismatch \u2014 possible CSRF attack. Please try again.");
94
+ res.end("State mismatch (possible CSRF attack). Please try again.");
95
95
  return;
96
96
  }
97
97
  if (outcome.kind === "legacy-key") {
@@ -125,7 +125,7 @@ async function browserLogin(opts) {
125
125
  res.writeHead(200, { "Content-Type": "text/html" });
126
126
  res.end(`<!DOCTYPE html>
127
127
  <html>
128
- <head><title>Hive CLI \u2014 Authenticated</title>
128
+ <head><title>Hive CLI: Authenticated</title>
129
129
  <style>
130
130
  body { font-family: -apple-system, BlinkMacSystemFont, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #0a0a0a; color: #fafafa; }
131
131
  .card { text-align: center; padding: 2rem; }
@@ -146,7 +146,7 @@ Update available: ${SERVER_VERSION} -> ${latest}
146
146
  if (mode === "global") {
147
147
  info(
148
148
  actions.includes("updated global install") ? `Updated global hive-intelligence to ${latest}.
149
- ` : `Global update failed \u2014 run: npm install -g ${REGISTRY_PACKAGE}@latest
149
+ ` : `Global update failed. Run: npm install -g ${REGISTRY_PACKAGE}@latest
150
150
  `
151
151
  );
152
152
  }
@@ -156,7 +156,7 @@ Update available: ${SERVER_VERSION} -> ${latest}
156
156
  }
157
157
  if (mode === "local") {
158
158
  info(
159
- "Running from a local checkout \u2014 pull the latest source with git instead.\n"
159
+ "Running from a local checkout; pull the latest source with git instead.\n"
160
160
  );
161
161
  }
162
162
  info(
@@ -4,7 +4,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
4
4
  var NAMESPACE = [
5
5
  {
6
6
  name: "market",
7
- description: "Crypto market data \u2014 prices, charts, rankings, stablecoins",
7
+ description: "Crypto market data: prices, charts, rankings, stablecoins",
8
8
  commands: [
9
9
  {
10
10
  name: "price",
@@ -92,7 +92,7 @@ var NAMESPACE = [
92
92
  },
93
93
  {
94
94
  name: "defi",
95
- description: "DeFi protocol analytics \u2014 TVL, fees, yields, bridges",
95
+ description: "DeFi protocol analytics: TVL, fees, yields, bridges",
96
96
  commands: [
97
97
  {
98
98
  name: "tvl",
@@ -131,61 +131,69 @@ var NAMESPACE = [
131
131
  { name: "chains", description: "Chain TVL rankings", tool: "get_chains" },
132
132
  {
133
133
  name: "bridges",
134
- description: "Cross-chain bridges",
135
- tool: "defillama_get_bridges"
134
+ description: "Cross-chain bridge aggregator volumes",
135
+ tool: "defillama_get_bridge_aggregator_volumes"
136
136
  }
137
137
  ]
138
138
  },
139
139
  {
140
140
  name: "portfolio",
141
- description: "Wallet portfolios \u2014 balances, DeFi positions, NFTs, history",
141
+ description: "Wallet portfolios: balances, DeFi positions, NFTs, history",
142
142
  commands: [
143
143
  {
144
144
  name: "balance",
145
145
  description: "Wallet total balance",
146
- tool: "get_wallet_balance",
146
+ tool: "get_wallet_balances",
147
147
  args: {
148
- id: {
148
+ walletAddress: {
149
149
  flag: "--address <addr>",
150
150
  description: "Wallet address",
151
151
  required: true
152
+ },
153
+ networkId: {
154
+ flag: "--network-id <id>",
155
+ description: "EVM chain ID",
156
+ required: true
152
157
  }
153
158
  }
154
159
  },
155
160
  {
156
161
  name: "tokens",
157
162
  description: "Token holdings",
158
- tool: "get_wallet_token_balances",
163
+ tool: "moralis_get_wallet_token_balances",
159
164
  args: {
160
- id: {
165
+ address: {
161
166
  flag: "--address <addr>",
162
167
  description: "Wallet address",
163
168
  required: true
164
- }
169
+ },
170
+ chain: { flag: "--chain <name>", description: "Chain name" }
165
171
  }
166
172
  },
167
173
  {
168
174
  name: "positions",
169
175
  description: "DeFi positions",
170
- tool: "get_wallet_defi_positions",
176
+ tool: "moralis_get_wallet_defi_positions",
171
177
  args: {
172
- id: {
178
+ address: {
173
179
  flag: "--address <addr>",
174
180
  description: "Wallet address",
175
181
  required: true
176
- }
182
+ },
183
+ chain: { flag: "--chain <name>", description: "Chain name" }
177
184
  }
178
185
  },
179
186
  {
180
187
  name: "nfts",
181
188
  description: "NFT holdings",
182
- tool: "get_wallet_nft_collections",
189
+ tool: "moralis_get_wallet_nft_collections",
183
190
  args: {
184
- id: {
191
+ address: {
185
192
  flag: "--address <addr>",
186
193
  description: "Wallet address",
187
194
  required: true
188
- }
195
+ },
196
+ chain: { flag: "--chain <name>", description: "Chain name" }
189
197
  }
190
198
  },
191
199
  {
@@ -204,14 +212,14 @@ var NAMESPACE = [
204
212
  },
205
213
  {
206
214
  name: "security",
207
- description: "Token and contract security \u2014 scans, approvals, simulations",
215
+ description: "Token and contract security: scans, approvals, simulations",
208
216
  commands: [
209
217
  {
210
218
  name: "scan",
211
219
  description: "Token security analysis",
212
220
  tool: "get_token_security",
213
221
  args: {
214
- chain_id: {
222
+ chainId: {
215
223
  flag: "--chain <id>",
216
224
  description: "Chain ID (1=ETH, 56=BSC)",
217
225
  required: true
@@ -228,7 +236,7 @@ var NAMESPACE = [
228
236
  description: "Audit token approvals",
229
237
  tool: "check_approval_security",
230
238
  args: {
231
- chain_id: {
239
+ chainId: {
232
240
  flag: "--chain <id>",
233
241
  description: "Chain ID",
234
242
  required: true
@@ -277,23 +285,18 @@ var NAMESPACE = [
277
285
  description: "Chain ID",
278
286
  required: true
279
287
  },
280
- contract_addresses: {
288
+ contract_address: {
281
289
  flag: "--address <addr>",
282
290
  description: "Contract",
283
291
  required: true
284
292
  }
285
293
  }
286
- },
287
- {
288
- name: "hacks",
289
- description: "Recent DeFi hacks",
290
- tool: "defillama_get_hacks"
291
294
  }
292
295
  ]
293
296
  },
294
297
  {
295
298
  name: "exchange",
296
- description: "Centralized exchange data \u2014 tickers, orderbooks, trades, funding",
299
+ description: "Centralized exchange data: tickers, orderbooks, trades, funding",
297
300
  commands: [
298
301
  {
299
302
  name: "ticker",
@@ -372,7 +375,7 @@ var NAMESPACE = [
372
375
  },
373
376
  {
374
377
  name: "dex",
375
- description: "DEX analytics \u2014 pools, trending pairs, trades, volume",
378
+ description: "DEX analytics: pools, trending pairs, trades, volume",
376
379
  commands: [
377
380
  {
378
381
  name: "trending",
@@ -399,9 +402,14 @@ var NAMESPACE = [
399
402
  args: {
400
403
  network: {
401
404
  flag: "--network <name>",
402
- description: "Network (eth, bsc, solana)"
405
+ description: "Network (eth, bsc, solana)",
406
+ required: true
403
407
  },
404
- pool_address: { flag: "--pool <addr>", description: "Pool address" }
408
+ token_address: {
409
+ flag: "--address <addr>",
410
+ description: "Token contract address",
411
+ required: true
412
+ }
405
413
  }
406
414
  },
407
415
  {
@@ -430,7 +438,7 @@ var NAMESPACE = [
430
438
  },
431
439
  {
432
440
  name: "wallet",
433
- description: "On-chain wallet data \u2014 balances, transfers, transactions, approvals",
441
+ description: "On-chain wallet data: balances, transfers, transactions, approvals",
434
442
  commands: [
435
443
  {
436
444
  name: "balances",
@@ -474,33 +482,42 @@ var NAMESPACE = [
474
482
  {
475
483
  name: "approvals",
476
484
  description: "Token approval audit",
477
- tool: "goplus_check_approval_security_v2",
485
+ tool: "check_approval_security_v2",
478
486
  args: {
479
487
  address: {
480
488
  flag: "--address <addr>",
481
489
  description: "Wallet address",
482
490
  required: true
483
491
  },
484
- chain_id: { flag: "--chain-id <id>", description: "EVM chain ID" }
492
+ chain_id: {
493
+ flag: "--chain-id <id>",
494
+ description: "EVM chain ID",
495
+ required: true
496
+ }
485
497
  }
486
498
  }
487
499
  ]
488
500
  },
489
501
  {
490
502
  name: "nft",
491
- description: "NFT analytics \u2014 collections, markets, trends, holders",
503
+ description: "NFT analytics: collections, markets, trends, holders",
492
504
  commands: [
493
505
  {
494
506
  name: "trending",
495
- description: "Trending NFT collections",
496
- tool: "get_nft_market_trends"
507
+ description: "Trending NFT collections, by 24h volume",
508
+ tool: "get_nft_markets",
509
+ fixedArgs: { order: "h24_volume_usd_desc" }
497
510
  },
498
511
  {
499
512
  name: "collection",
500
513
  description: "Collection details",
501
- tool: "get_nft_collection",
514
+ tool: "get_nft",
502
515
  args: {
503
- slug: { flag: "--slug <name>", description: "Collection slug" }
516
+ id: {
517
+ flag: "--slug <name>",
518
+ description: "Collection slug",
519
+ required: true
520
+ }
504
521
  }
505
522
  },
506
523
  {
@@ -511,20 +528,21 @@ var NAMESPACE = [
511
528
  {
512
529
  name: "search",
513
530
  description: "Search NFT collections",
514
- tool: "search_nfts",
531
+ tool: "alchemy_search_contract_metadata",
515
532
  args: {
516
533
  query: {
517
534
  flag: "--query <text>",
518
535
  description: "Search term",
519
536
  required: true
520
- }
537
+ },
538
+ network: { flag: "--network <name>", description: "Alchemy network" }
521
539
  }
522
540
  }
523
541
  ]
524
542
  },
525
543
  {
526
544
  name: "network",
527
- description: "Blockchain infrastructure \u2014 chains, gas, blocks, transactions",
545
+ description: "Blockchain infrastructure: chains, gas, blocks, transactions",
528
546
  commands: [
529
547
  {
530
548
  name: "chains",
@@ -50,7 +50,7 @@ function remapForKeylessHero(toolName, args) {
50
50
  return {
51
51
  tool: "get_token_price",
52
52
  args: { token, vs_currency: vsCurrency },
53
- note: "no API key \u2014 routed through the keyless get_token_price hero"
53
+ note: "no API key; routed through the keyless get_token_price hero"
54
54
  };
55
55
  }
56
56
  if (toolName === "get_token_security") {
@@ -61,7 +61,7 @@ function remapForKeylessHero(toolName, args) {
61
61
  return {
62
62
  tool: "check_token_safety",
63
63
  args: chain ? { address, chain } : { address },
64
- note: "no API key \u2014 routed through the keyless check_token_safety hero"
64
+ note: "no API key; routed through the keyless check_token_safety hero"
65
65
  };
66
66
  }
67
67
  if (toolName === "alchemy_get_tokens_by_wallet") {
@@ -72,7 +72,7 @@ function remapForKeylessHero(toolName, args) {
72
72
  return {
73
73
  tool: "get_wallet_portfolio",
74
74
  args: chain ? { address, chain } : { address },
75
- note: "no API key \u2014 routed through the keyless get_wallet_portfolio hero"
75
+ note: "no API key; routed through the keyless get_wallet_portfolio hero"
76
76
  };
77
77
  }
78
78
  return null;
@@ -110,7 +110,7 @@ async function executeTool(toolName, args, timeoutMs = 3e4) {
110
110
  if (typeof quotaRemaining === "number" && !resolveApiKey() && !shouldOutputJson()) {
111
111
  process.stderr.write(
112
112
  dim(
113
- `${quotaRemaining} free call${quotaRemaining === 1 ? "" : "s"} left today \u2014 run \`hive auth login\` for a full key.`
113
+ `${quotaRemaining} free call${quotaRemaining === 1 ? "" : "s"} left today. Run \`hive auth login\` for a full key.`
114
114
  ) + "\n"
115
115
  );
116
116
  }
@@ -212,7 +212,7 @@ function installSkillsForClient(client) {
212
212
  installed: [],
213
213
  skipped: [...SKILL_PACK_NAMES],
214
214
  destination: null,
215
- reason: "Client has no native skills directory \u2014 tools come over MCP"
215
+ reason: "Client has no native skills directory; tools come over MCP"
216
216
  };
217
217
  }
218
218
  const packsRoot = findBundledPacksDir();
@@ -222,7 +222,7 @@ function installSkillsForClient(client) {
222
222
  installed: [],
223
223
  skipped: [...SKILL_PACK_NAMES],
224
224
  destination: dest,
225
- reason: "Bundled skill packs not found \u2014 package install may be incomplete"
225
+ reason: "Bundled skill packs not found; the package install may be incomplete"
226
226
  };
227
227
  }
228
228
  if (!existsSync2(dest)) mkdirSync(dest, { recursive: true });
@@ -116,7 +116,7 @@ async function runLogin(opts) {
116
116
  const profileName = opts.profile ?? "default";
117
117
  if (opts.manual) {
118
118
  process.stderr.write(`
119
- Hive CLI \u2014 Login (profile: ${profileName})
119
+ Hive CLI: Login (profile: ${profileName})
120
120
 
121
121
  `);
122
122
  let apiKey;
@@ -180,7 +180,7 @@ Validating against ${apiUrl}...
180
180
  process.stderr.write("Key validated successfully.\n");
181
181
  } else if (resp.status === 401 || resp.status === 403) {
182
182
  process.stderr.write(
183
- `Warning: Server returned ${resp.status} \u2014 key may be invalid.
183
+ `Warning: Server returned ${resp.status}; the key may be invalid.
184
184
  `
185
185
  );
186
186
  } else {
@@ -189,7 +189,7 @@ Validating against ${apiUrl}...
189
189
  }
190
190
  } catch {
191
191
  process.stderr.write(
192
- "Warning: Could not reach server \u2014 saving anyway.\n"
192
+ "Warning: Could not reach the server; saving anyway.\n"
193
193
  );
194
194
  }
195
195
  saveProfile(profileName, apiKey, apiUrl);
@@ -201,10 +201,10 @@ Profile "${profileName}" saved. Key: ${maskKey(apiKey)}
201
201
  return;
202
202
  }
203
203
  process.stderr.write(`
204
- Hive CLI \u2014 Login (profile: ${profileName})
204
+ Hive CLI: Login (profile: ${profileName})
205
205
  `);
206
206
  try {
207
- const { browserLogin } = await import("./browser-auth-KXIO5BHM.js");
207
+ const { browserLogin } = await import("./browser-auth-F62BMD7W.js");
208
208
  const apiUrl = process.env.HIVE_API_URL || "https://mcp.hiveintelligence.xyz";
209
209
  const websiteUrl = process.env.HIVE_WEBSITE_URL || "https://hiveintelligence.xyz";
210
210
  const result = await browserLogin({ baseUrl: websiteUrl });
@@ -302,7 +302,7 @@ async function runUsage() {
302
302
  const code = result.error?.code;
303
303
  const err = code === "AUTH_REQUIRED" || code === "INVALID_TOKEN" ? new CliError(
304
304
  "AUTH_REQUIRED",
305
- code === "INVALID_TOKEN" ? "API key was rejected \u2014 usage requires a valid account key." : "No API key found \u2014 usage requires an account key.",
305
+ code === "INVALID_TOKEN" ? "API key was rejected; usage requires a valid account key." : "No API key found; usage requires an account key.",
306
306
  "Run: hive auth login (or set HIVE_API_KEY)"
307
307
  ) : classifyError(result.error?.message ?? "Failed to fetch usage");
308
308
  await outputError(err, {});
@@ -7,7 +7,7 @@ import {
7
7
  getSupabaseAdmin,
8
8
  resolveEndpoint,
9
9
  secureLogger
10
- } from "./chunk-UFTNBCSA.js";
10
+ } from "./chunk-AGM2CIRL.js";
11
11
 
12
12
  // src/services/wallet-service.ts
13
13
  async function consumeCredits(args) {
package/build/cli.js CHANGED
@@ -2,13 +2,13 @@
2
2
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
3
3
  import {
4
4
  executeTool
5
- } from "./chunk-7DYHWY4Y.js";
5
+ } from "./chunk-SFN772RL.js";
6
6
  import {
7
7
  ExitCode
8
8
  } from "./chunk-R6YZTFQL.js";
9
9
  import {
10
10
  NAMESPACE
11
- } from "./chunk-TNQ7GJ6Q.js";
11
+ } from "./chunk-GWZIAAQ2.js";
12
12
  import "./chunk-P7NLFSZQ.js";
13
13
  import "./chunk-RU6QOFHH.js";
14
14
  import {
@@ -3414,7 +3414,7 @@ process.on("SIGINT", () => process.exit(130));
3414
3414
  process.on("SIGTERM", () => process.exit(143));
3415
3415
  var program2 = new Command();
3416
3416
  program2.name("hive").version(SERVER_VERSION).description(
3417
- "Hive Intelligence \u2014 managed crypto market data, DeFi, wallets, security, DEX, NFTs, and prediction markets for AI agents and developers"
3417
+ "Hive Intelligence: managed crypto market data, DeFi, wallets, security, DEX, NFTs, and prediction markets for AI agents and developers"
3418
3418
  ).exitOverride().configureOutput({
3419
3419
  writeErr: (str) => process.stderr.write(str),
3420
3420
  outputError: (str, write) => {
@@ -3440,7 +3440,7 @@ program2.hook("preAction", (thisCommand) => {
3440
3440
  setCliFlags({ apiKey: opts.apiKey, noRetry: opts.retry === false });
3441
3441
  });
3442
3442
  program2.action(async () => {
3443
- const { startStdio } = await import("./serve-K3IT7DS4.js");
3443
+ const { startStdio } = await import("./serve-PWMT5IRU.js");
3444
3444
  await startStdio(program2.opts().envFile);
3445
3445
  });
3446
3446
  program2.command("serve").description("Start the MCP server").option("--http", "Start HTTP server instead of stdio").option("--port <number>", "HTTP server port", "8080").action(async (opts) => {
@@ -3453,10 +3453,10 @@ program2.command("serve").description("Start the MCP server").option("--http", "
3453
3453
  );
3454
3454
  process.exit(ExitCode.INVALID_ARGS);
3455
3455
  }
3456
- const { startHttp } = await import("./serve-K3IT7DS4.js");
3456
+ const { startHttp } = await import("./serve-PWMT5IRU.js");
3457
3457
  await startHttp(port, program2.opts().envFile);
3458
3458
  } else {
3459
- const { startStdio } = await import("./serve-K3IT7DS4.js");
3459
+ const { startStdio } = await import("./serve-PWMT5IRU.js");
3460
3460
  await startStdio(program2.opts().envFile);
3461
3461
  }
3462
3462
  });
@@ -3474,10 +3474,10 @@ for (const domain of NAMESPACE) {
3474
3474
  }
3475
3475
  subCmd.option("--args <json>", "Pass all arguments as JSON");
3476
3476
  subCmd.action(async (opts) => {
3477
- let args = {};
3477
+ let args = { ...sub.fixedArgs ?? {} };
3478
3478
  if (opts.args) {
3479
3479
  try {
3480
- args = JSON.parse(opts.args);
3480
+ args = { ...args, ...JSON.parse(opts.args) };
3481
3481
  } catch {
3482
3482
  process.stderr.write("Error: Invalid JSON in --args\n");
3483
3483
  process.exit(ExitCode.INVALID_ARGS);
@@ -3529,15 +3529,15 @@ for (const domain of NAMESPACE) {
3529
3529
  }
3530
3530
  var toolsCmd = program2.command("tools").description("Discover and execute tools");
3531
3531
  toolsCmd.command("list").description("List all registered tools").option("--category <name>", "Filter by category").option("--provider <name>", "Filter by provider prefix").option("--limit <n>", "Max tools to show", "50").option("--offset <n>", "Skip first N tools", "0").action(async (opts) => {
3532
- const { listTools } = await import("./tools-D72ZH6P5.js");
3532
+ const { listTools } = await import("./tools-XNFJBN7Q.js");
3533
3533
  await listTools(opts);
3534
3534
  });
3535
3535
  toolsCmd.command("search <query>").description("Search tools by name or description").action(async (query) => {
3536
- const { searchTools } = await import("./tools-D72ZH6P5.js");
3536
+ const { searchTools } = await import("./tools-XNFJBN7Q.js");
3537
3537
  await searchTools(query);
3538
3538
  });
3539
3539
  toolsCmd.command("info <name>").description("Show detailed tool schema and description").action(async (name) => {
3540
- const { toolInfo } = await import("./tools-D72ZH6P5.js");
3540
+ const { toolInfo } = await import("./tools-XNFJBN7Q.js");
3541
3541
  await toolInfo(name);
3542
3542
  });
3543
3543
  toolsCmd.command("call <name>").description("Execute a tool by name").option("--args <json>", "Tool arguments as JSON (or pipe JSON via stdin)").action(async (name, opts) => {
@@ -3566,7 +3566,7 @@ toolsCmd.command("call <name>").description("Execute a tool by name").option("--
3566
3566
  await executeTool(name, args, timeout);
3567
3567
  });
3568
3568
  toolsCmd.command("refresh").description("Force-refresh the tool catalog cache").action(async () => {
3569
- const { refreshTools } = await import("./tools-D72ZH6P5.js");
3569
+ const { refreshTools } = await import("./tools-XNFJBN7Q.js");
3570
3570
  await refreshTools();
3571
3571
  });
3572
3572
  var configCmd = program2.command("config").description("Generate configuration for MCP clients");
@@ -3616,7 +3616,7 @@ program2.command("init").description(
3616
3616
  "Override the Hive API URL (e.g. for staging or self-hosted)"
3617
3617
  ).action(async (opts) => {
3618
3618
  if (opts.minimal && !opts.all && !opts.browser) {
3619
- const { runInit } = await import("./init-UCTCUYFA.js");
3619
+ const { runInit } = await import("./init-COHA3VZI.js");
3620
3620
  await runInit(opts);
3621
3621
  return;
3622
3622
  }
@@ -3625,7 +3625,7 @@ program2.command("init").description(
3625
3625
  await runSetup();
3626
3626
  return;
3627
3627
  }
3628
- const { runInitAll } = await import("./init-all-RG542NWG.js");
3628
+ const { runInitAll } = await import("./init-all-YTQJLPLR.js");
3629
3629
  const exitCode = await runInitAll({
3630
3630
  all: Boolean(opts.all),
3631
3631
  browser: Boolean(opts.browser),
@@ -3643,7 +3643,7 @@ program2.command("uninstall").description(
3643
3643
  "--all",
3644
3644
  "Clean every known client (default; explicit flag for symmetry with `init --all`)"
3645
3645
  ).option("--dry-run", "Preview removals without changing anything").action(async (opts) => {
3646
- const { runUninstall } = await import("./uninstall-SAOIPL6K.js");
3646
+ const { runUninstall } = await import("./uninstall-TKDP6C4F.js");
3647
3647
  const exitCode = await runUninstall({
3648
3648
  all: opts.all !== false,
3649
3649
  dryRun: Boolean(opts.dryRun),
@@ -3652,19 +3652,19 @@ program2.command("uninstall").description(
3652
3652
  if (exitCode !== 0) process.exit(exitCode);
3653
3653
  });
3654
3654
  program2.command("doctor").description("Diagnose environment and server connectivity").option("--probe", "Run live API probes (slower)").action(async (opts) => {
3655
- const { runDoctor } = await import("./doctor-GHUAUFS2.js");
3655
+ const { runDoctor } = await import("./doctor-XG5IQCXK.js");
3656
3656
  await runDoctor(opts);
3657
3657
  });
3658
3658
  program2.command("upgrade").description("Update Hive to the latest published version").action(async () => {
3659
- const { runUpgrade } = await import("./upgrade-4S5XT5JG.js");
3659
+ const { runUpgrade } = await import("./upgrade-ODPKMIDC.js");
3660
3660
  await runUpgrade();
3661
3661
  });
3662
3662
  program2.command("completion <shell>").description("Generate shell completion script (bash, zsh, fish, powershell)").option("--install", "Auto-install to shell rc file").action(async (shell, opts) => {
3663
3663
  if (opts.install) {
3664
- const { installCompletion } = await import("./completion-7KBW243H.js");
3664
+ const { installCompletion } = await import("./completion-C57PDJMY.js");
3665
3665
  await installCompletion(shell);
3666
3666
  } else {
3667
- const { generateCompletion } = await import("./completion-7KBW243H.js");
3667
+ const { generateCompletion } = await import("./completion-C57PDJMY.js");
3668
3668
  await generateCompletion(shell);
3669
3669
  }
3670
3670
  });
@@ -3676,31 +3676,31 @@ program2.command("keys").description("Retired \u2014 manage API keys in the dash
3676
3676
  });
3677
3677
  var authCmd = program2.command("auth").description("Manage authentication profiles");
3678
3678
  authCmd.command("login").description("Log in via browser (or --manual to paste API key)").option("--profile <name>", "Profile name", "default").option("--manual", "Manually paste API key instead of browser login").action(async (opts) => {
3679
- const { runLogin } = await import("./auth-HRFQWQMZ.js");
3679
+ const { runLogin } = await import("./auth-Y4GXW376.js");
3680
3680
  await runLogin(opts);
3681
3681
  });
3682
3682
  authCmd.command("logout").description("Remove stored credentials").action(async () => {
3683
- const { runLogout } = await import("./auth-HRFQWQMZ.js");
3683
+ const { runLogout } = await import("./auth-Y4GXW376.js");
3684
3684
  await runLogout();
3685
3685
  });
3686
3686
  authCmd.command("whoami").description("Show current profile").action(async () => {
3687
- const { runWhoami } = await import("./auth-HRFQWQMZ.js");
3687
+ const { runWhoami } = await import("./auth-Y4GXW376.js");
3688
3688
  await runWhoami();
3689
3689
  });
3690
3690
  authCmd.command("profiles").description("List all profiles").action(async () => {
3691
- const { runProfiles } = await import("./auth-HRFQWQMZ.js");
3691
+ const { runProfiles } = await import("./auth-Y4GXW376.js");
3692
3692
  await runProfiles();
3693
3693
  });
3694
3694
  authCmd.command("switch <name>").description("Switch active profile").action(async (name) => {
3695
- const { runSwitch } = await import("./auth-HRFQWQMZ.js");
3695
+ const { runSwitch } = await import("./auth-Y4GXW376.js");
3696
3696
  await runSwitch(name);
3697
3697
  });
3698
3698
  program2.command("usage").description("Show your API usage and plan limits").action(async () => {
3699
- const { runUsage } = await import("./auth-HRFQWQMZ.js");
3699
+ const { runUsage } = await import("./auth-Y4GXW376.js");
3700
3700
  await runUsage();
3701
3701
  });
3702
3702
  program2.command("status").description("Quick health and version check").action(async () => {
3703
- const { runStatus } = await import("./doctor-GHUAUFS2.js");
3703
+ const { runStatus } = await import("./doctor-XG5IQCXK.js");
3704
3704
  await runStatus();
3705
3705
  });
3706
3706
  program2.command("open [target]").description("Open Hive dashboard, docs, status, or GitHub in browser").action(async (target) => {
@@ -3731,7 +3731,7 @@ program2.command("watch <domain> <command>").description("Poll a tool on interva
3731
3731
  }
3732
3732
  const interval = parseInt(opts.interval, 10);
3733
3733
  const timeout = parseInt(program2.opts().timeout, 10);
3734
- const { runWatch } = await import("./watch-IOSRSCFE.js");
3734
+ const { runWatch } = await import("./watch-MXJSNGL2.js");
3735
3735
  await runWatch(cmdDef.tool, args, interval, timeout);
3736
3736
  });
3737
3737
  var aliasCmd = program2.command("alias").description("Manage command aliases");
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
2
  import {
3
3
  NAMESPACE
4
- } from "./chunk-TNQ7GJ6Q.js";
4
+ } from "./chunk-GWZIAAQ2.js";
5
5
  import "./chunk-ILVPOLA7.js";
6
6
 
7
7
  // src/cli/completion.ts
@@ -48,7 +48,7 @@ async function runDoctor(opts) {
48
48
  checks.push({
49
49
  check: "Server health",
50
50
  status: "PASS",
51
- detail: `${resp.status} \u2014 ${serverStatus}`
51
+ detail: `${resp.status}: ${serverStatus}`
52
52
  });
53
53
  } else {
54
54
  checks.push({
@@ -109,7 +109,7 @@ async function runDoctor(opts) {
109
109
  checks.push({
110
110
  check: "Updates",
111
111
  status: "WARN",
112
- detail: `v${SERVER_VERSION} -> v${latest} available \u2014 run: hive upgrade`
112
+ detail: `v${SERVER_VERSION} -> v${latest} available. Run: hive upgrade`
113
113
  });
114
114
  } else {
115
115
  checks.push({
@@ -204,9 +204,9 @@ ${fails === 0 ? "All checks passed" : `${fails} issues found`}${warns ? ` (${war
204
204
  if (fails > 0) process.exit(1);
205
205
  }
206
206
  async function runStatus() {
207
- const { SERVER_VERSION } = await import("./mcpServer-D7OXUDU5.js");
207
+ const { SERVER_VERSION } = await import("./mcpServer-XHIN5JER.js");
208
208
  const { resolveApiKey, resolveApiUrl } = await import("./config-dir-5IH7MOOT.js");
209
- const { getActiveProfile, maskKey } = await import("./auth-HRFQWQMZ.js");
209
+ const { getActiveProfile, maskKey } = await import("./auth-Y4GXW376.js");
210
210
  const apiUrl = resolveApiUrl();
211
211
  const apiKey = resolveApiKey();
212
212
  const profile = getActiveProfile();
@@ -112,7 +112,7 @@ Validating API key against ${baseUrl}...`);
112
112
  console.log("API key validated successfully.\n");
113
113
  } else if (resp.status === 401 || resp.status === 403) {
114
114
  console.log(
115
- `Warning: Server returned ${resp.status} \u2014 key may be invalid.
115
+ `Warning: Server returned ${resp.status}; the key may be invalid.
116
116
  `
117
117
  );
118
118
  } else {
@@ -123,14 +123,14 @@ Validating API key against ${baseUrl}...`);
123
123
  }
124
124
  } catch {
125
125
  console.log(
126
- `Warning: Could not reach ${baseUrl} \u2014 check the URL and try again.
126
+ `Warning: Could not reach ${baseUrl}; check the URL and try again.
127
127
  `
128
128
  );
129
129
  }
130
130
  }
131
131
  const lines = Object.entries(existing).map(([k, v]) => `${k}=${v}`).join("\n");
132
132
  if (opts.dryRun) {
133
- console.log("Dry run \u2014 would write to .env:\n");
133
+ console.log("Dry run: would write to .env:\n");
134
134
  console.log(redactEnvForDisplay(lines));
135
135
  console.log("");
136
136
  return;
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  detectClients,
4
4
  installSkillsForClients
5
- } from "./chunk-AEU43ACS.js";
5
+ } from "./chunk-TVBPCELA.js";
6
6
  import {
7
7
  getClaudeDesktopInstructions,
8
8
  getCodexInstructions,
@@ -19,13 +19,13 @@ import {
19
19
  } from "./chunk-QDZ7MAVN.js";
20
20
  import {
21
21
  browserLogin
22
- } from "./chunk-AQQAPAER.js";
22
+ } from "./chunk-BDO27NIP.js";
23
23
  import {
24
24
  saveProfile
25
- } from "./chunk-TVQJY47C.js";
25
+ } from "./chunk-WF34ZD5I.js";
26
26
  import {
27
27
  detectInstallMode
28
- } from "./chunk-GHCYCBA3.js";
28
+ } from "./chunk-GB4XMTDE.js";
29
29
  import "./chunk-M6REON2I.js";
30
30
  import "./chunk-L326MQZP.js";
31
31
  import "./chunk-ZXKFJQDE.js";
@@ -205,7 +205,7 @@ async function verifyConnection(apiUrlOverride) {
205
205
  if (res.status === 401) {
206
206
  return {
207
207
  ok: true,
208
- detail: "Hosted MCP reachable \u2014 server answered with an auth challenge; finish sign-in inside each client."
208
+ detail: "Hosted MCP reachable: server answered with an auth challenge; finish sign-in inside each client."
209
209
  };
210
210
  }
211
211
  if (!res.ok) {
@@ -229,12 +229,12 @@ async function verifyConnection(apiUrlOverride) {
229
229
  const code = body.error.data?.code || "classified error";
230
230
  return {
231
231
  ok: true,
232
- detail: `Hosted MCP reachable \u2014 server answered with a classified response (${code})`
232
+ detail: `Hosted MCP reachable: server answered with a classified response (${code})`
233
233
  };
234
234
  }
235
235
  return {
236
236
  ok: true,
237
- detail: "Hosted MCP reachable \u2014 anonymous hero call answered"
237
+ detail: "Hosted MCP reachable: anonymous hero call answered"
238
238
  };
239
239
  } catch {
240
240
  return {
@@ -255,8 +255,8 @@ async function runInitAll(opts = {}) {
255
255
  dryRun: Boolean(opts.dryRun)
256
256
  };
257
257
  if (!opts.json) {
258
- w(bold("\nHive Intelligence \u2014 Init"));
259
- if (summary.dryRun) info("(dry-run \u2014 nothing will be written)");
258
+ w(bold("\nHive Intelligence: Init"));
259
+ if (summary.dryRun) info("(dry-run: nothing will be written)");
260
260
  }
261
261
  if (opts.browser) {
262
262
  step("Authenticating via browser");
@@ -304,7 +304,7 @@ async function runInitAll(opts = {}) {
304
304
  } else if (!opts.all) {
305
305
  continue;
306
306
  } else {
307
- info(`${c.name} \u2014 not detected (${c.hint || "skipped"})`);
307
+ info(`${c.name}: not detected (${c.hint || "skipped"})`);
308
308
  }
309
309
  }
310
310
  const browserOnly = Boolean(opts.browser && !opts.all);
@@ -327,10 +327,10 @@ async function runInitAll(opts = {}) {
327
327
  ok(`${result.name} ${dim("\u2192 " + result.path)}`);
328
328
  if (result.restartHint) info(result.restartHint);
329
329
  } else if (result.manual && result.steps) {
330
- warn(`${result.name} \u2014 manual setup required:`);
330
+ warn(`${result.name}: manual setup required:`);
331
331
  for (const stepText of result.steps) info(` \u2022 ${stepText}`);
332
332
  } else {
333
- bad(`${result.name} \u2014 ${result.error || "unknown error"}`);
333
+ bad(`${result.name}: ${result.error || "unknown error"}`);
334
334
  }
335
335
  }
336
336
  for (const manualId of ["chatgpt-desktop", "grok"]) {
@@ -347,7 +347,7 @@ async function runInitAll(opts = {}) {
347
347
  steps
348
348
  });
349
349
  info(
350
- `${client.name} \u2014 manual setup (${manualId === "grok" ? "grok.com/connectors" : "Settings \u2192 Apps"})`
350
+ `${client.name}: manual setup (${manualId === "grok" ? "grok.com/connectors" : "Settings \u2192 Apps"})`
351
351
  );
352
352
  }
353
353
  if (!opts.skipSkills && !browserOnly) {
@@ -377,7 +377,7 @@ async function runInitAll(opts = {}) {
377
377
  ok(verified.detail);
378
378
  } else {
379
379
  warn(
380
- `Could not verify (${verified.detail}) \u2014 run \`hive doctor\` for details (this can be a transient network issue)`
380
+ `Could not verify (${verified.detail}). Run \`hive doctor\` for details; this can be a transient network issue`
381
381
  );
382
382
  }
383
383
  }
@@ -9,7 +9,7 @@ import {
9
9
  getToolsForScope,
10
10
  memoizedJsonSchemaToZodInputSchema,
11
11
  memoizedJsonSchemaToZodOutputSchema
12
- } from "./chunk-UFTNBCSA.js";
12
+ } from "./chunk-AGM2CIRL.js";
13
13
  import "./chunk-L326MQZP.js";
14
14
  import "./chunk-EPF36Q3Z.js";
15
15
  import {
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  consumeCredits,
4
4
  executeToolByName
5
- } from "./chunk-3OZFBWFK.js";
5
+ } from "./chunk-XQPEFCSY.js";
6
6
  import {
7
7
  HyperliquidAPI,
8
8
  MIN_MONITOR_CADENCE_MS,
@@ -15,7 +15,7 @@ import {
15
15
  monitorCadenceIntervalMs,
16
16
  runScheduledHealthCanaries,
17
17
  secureLogger
18
- } from "./chunk-UFTNBCSA.js";
18
+ } from "./chunk-AGM2CIRL.js";
19
19
  import "./chunk-L326MQZP.js";
20
20
  import "./chunk-EPF36Q3Z.js";
21
21
  import "./chunk-ZXKFJQDE.js";
@@ -3,7 +3,7 @@ import {
3
3
  NAMESPACE,
4
4
  getAllDomainCommands,
5
5
  resolveCommand
6
- } from "./chunk-TNQ7GJ6Q.js";
6
+ } from "./chunk-GWZIAAQ2.js";
7
7
  import "./chunk-ILVPOLA7.js";
8
8
  export {
9
9
  NAMESPACE,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "package": "hive-intelligence",
3
- "version": "1.4.0",
4
- "buildSha": "a414ce5540417c1851e0d99029dac69c8880801e",
5
- "imageDigest": "sha256:e19e3ce819accf7817c2b8bc2c79e040ae4f4c5f755991b8c4b0e5d474bc5aaf",
3
+ "version": "1.5.0",
4
+ "buildSha": "be07c11603a1109e3ef62c73c735e044c60f651f",
5
+ "imageDigest": "sha256:8d521047d21e80541a0ed4cc71741612d8ddac0881761e0a4467524d068c430e",
6
6
  "deployedUrl": "https://mcp.hiveintelligence.xyz",
7
- "manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.4.0/releases/v1.4.0.json"
7
+ "manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.5.0/releases/v1.5.0.json"
8
8
  }
@@ -7,7 +7,7 @@ async function startStdio(envFile) {
7
7
  dotenv.config({ path: envFile || ".env", quiet: true });
8
8
  console.log = (...args) => console.error("[LOG]", ...args);
9
9
  const { StdioServerTransport } = await import("@modelcontextprotocol/sdk/server/stdio.js");
10
- const { createHiveMcpServer, SERVER_NAME, SERVER_VERSION } = await import("./mcpServer-D7OXUDU5.js");
10
+ const { createHiveMcpServer, SERVER_NAME, SERVER_VERSION } = await import("./mcpServer-XHIN5JER.js");
11
11
  const { getPendingUpdateVersion } = await import("./update-check-IEXPOYYR.js");
12
12
  const transport = new StdioServerTransport();
13
13
  const pendingUpdate = getPendingUpdateVersion();
package/build/server.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  ensureWallet,
7
7
  executeToolByName,
8
8
  getWalletStatus
9
- } from "./chunk-3OZFBWFK.js";
9
+ } from "./chunk-XQPEFCSY.js";
10
10
  import {
11
11
  CategoryEndpoints,
12
12
  HERO_TOOL_NAMES,
@@ -95,7 +95,7 @@ import {
95
95
  validateEndpointArgs,
96
96
  verifyApiKey,
97
97
  waitForRedisAvailability
98
- } from "./chunk-UFTNBCSA.js";
98
+ } from "./chunk-AGM2CIRL.js";
99
99
  import {
100
100
  HIVE_AGENT_SKILLS
101
101
  } from "./chunk-L326MQZP.js";
@@ -735,6 +735,15 @@ var require_ipaddr = __commonJS({
735
735
 
736
736
  // src/server.ts
737
737
  import dotenv from "dotenv";
738
+
739
+ // src/config/trustProxy.ts
740
+ var DEFAULT_TRUSTED_PROXY_ADDRESSES = "34.102.187.55";
741
+ function resolveTrustedProxies(raw = getEnvVar("TRUSTED_PROXY_ADDRESSES")) {
742
+ const addresses = (raw ?? DEFAULT_TRUSTED_PROXY_ADDRESSES).split(",").map((entry) => entry.trim()).filter(Boolean);
743
+ return [...addresses, "loopback", "uniquelocal", "169.254.0.0/16"];
744
+ }
745
+
746
+ // src/server.ts
738
747
  import { randomUUID as randomUUID4, timingSafeEqual as timingSafeEqual6 } from "crypto";
739
748
  import { resolve } from "path";
740
749
  import { fileURLToPath } from "url";
@@ -3185,7 +3194,7 @@ function replayResponse(res, cached) {
3185
3194
  error: {
3186
3195
  type: "invalid_request_error",
3187
3196
  code: "SECRET_ALREADY_ISSUED",
3188
- message: "This request was already completed and its one-time secret was returned only in the original response. It cannot be retrieved again \u2014 create a new key if you no longer have it."
3197
+ message: "This request was already completed and its one-time secret was returned only in the original response. It cannot be retrieved again; create a new key if you no longer have it."
3189
3198
  }
3190
3199
  });
3191
3200
  return;
@@ -3341,7 +3350,7 @@ router3.post(
3341
3350
  plan: planId,
3342
3351
  b2b_subjects_enabled: b2b_subjects_enabled ?? false,
3343
3352
  ...result.subjectSigningSecret ? { subject_signing_secret: result.subjectSigningSecret } : {},
3344
- warning: "Save this key \u2014 it will not be shown again."
3353
+ warning: "Save this key; it will not be shown again."
3345
3354
  }
3346
3355
  });
3347
3356
  } catch (err) {
@@ -4122,13 +4131,13 @@ async function releaseCheckoutLock(userId) {
4122
4131
  var CHECKOUT_RACE_LOST = apiError(
4123
4132
  "invalid_request_error",
4124
4133
  "CHECKOUT_IN_PROGRESS",
4125
- "Another checkout request for this account is still being created. Next action: wait a couple of seconds and retry \u2014 two simultaneous requests can only ever produce one charge."
4134
+ "Another checkout request for this account is still being created. Next action: wait a couple of seconds and retry; two simultaneous requests can only ever produce one charge."
4126
4135
  );
4127
4136
  function checkoutAlreadyOpen(chargeId) {
4128
4137
  return apiError(
4129
4138
  "invalid_request_error",
4130
4139
  "CHECKOUT_IN_PROGRESS",
4131
- `A payment page for this account is already open${chargeId ? ` (charge ${chargeId})` : ""}. Next action: finish that payment, or release the hold with POST /api/v1/billing/checkout/abandon if that page was abandoned \u2014 otherwise it clears on its own ${OPEN_CHARGE_WINDOW_MINUTES} minutes after the page was opened.`
4140
+ `A payment page for this account is already open${chargeId ? ` (charge ${chargeId})` : ""}. Next action: finish that payment, or release the hold with POST /api/v1/billing/checkout/abandon if that page was abandoned; otherwise it clears on its own ${OPEN_CHARGE_WINDOW_MINUTES} minutes after the page was opened.`
4132
4141
  );
4133
4142
  }
4134
4143
  function withCheckoutLock(req, res, next) {
@@ -5451,9 +5460,9 @@ import { LATEST_PROTOCOL_VERSION } from "@modelcontextprotocol/sdk/types.js";
5451
5460
  // src/services/anon-quota.ts
5452
5461
  import { createHash as createHash4 } from "crypto";
5453
5462
  import { z as z3 } from "zod";
5454
- var ANON_QUOTA_EXHAUSTED_MESSAGE = "Anonymous free quota reached (resets 00:00 UTC). For continued access set HIVE_API_KEY \u2014 create one free at https://hiveintelligence.xyz/dashboard/keys \u2014 or sign in via OAuth.";
5455
- var ANON_GLOBAL_CAP_MESSAGE = "Hive's shared anonymous allowance for today is spent (resets 00:00 UTC). This is a service-wide cap, not your personal one, and a key is not rate-limited by it: set HIVE_API_KEY \u2014 create one free at https://hiveintelligence.xyz/dashboard/keys \u2014 or sign in via OAuth.";
5456
- var ANON_QUOTA_UNAVAILABLE_MESSAGE = "Anonymous access is temporarily unavailable because the quota backend is unreachable. Retry in a moment, or set HIVE_API_KEY \u2014 create one free at https://hiveintelligence.xyz/dashboard/keys \u2014 for keyed access now.";
5463
+ var ANON_QUOTA_EXHAUSTED_MESSAGE = "Anonymous free quota reached (resets 00:00 UTC). For continued access set HIVE_API_KEY (create one free at https://hiveintelligence.xyz/dashboard/keys) or sign in via OAuth.";
5464
+ var ANON_GLOBAL_CAP_MESSAGE = "Hive's shared anonymous allowance for today is spent (resets 00:00 UTC). This is a service-wide cap, not your personal one, and a key is not rate-limited by it: set HIVE_API_KEY (create one free at https://hiveintelligence.xyz/dashboard/keys) or sign in via OAuth.";
5465
+ var ANON_QUOTA_UNAVAILABLE_MESSAGE = "Anonymous access is temporarily unavailable because the quota backend is unreachable. Retry in a moment, or set HIVE_API_KEY (create one free at https://hiveintelligence.xyz/dashboard/keys) for keyed access now.";
5457
5466
  var ANON_IP_HASH_DOMAIN = "hive-anon-lane-v1";
5458
5467
  var capSchema = z3.coerce.number().int().min(1).max(1e4);
5459
5468
  var globalCapSchema = z3.coerce.number().int().min(1).max(1e6);
@@ -5682,7 +5691,7 @@ function buildServerCard() {
5682
5691
  freeTier: {
5683
5692
  monthlyCredits: 1e4,
5684
5693
  requestsPerMinute: 30,
5685
- description: "Demo tier \u2014 no credit card required"
5694
+ description: "Demo tier, no credit card required"
5686
5695
  }
5687
5696
  },
5688
5697
  authCompatibility,
@@ -6596,7 +6605,7 @@ var port = getPort();
6596
6605
  function createHttpApp() {
6597
6606
  return app;
6598
6607
  }
6599
- app.set("trust proxy", 1);
6608
+ app.set("trust proxy", resolveTrustedProxies());
6600
6609
  app.use(requestIdMiddleware);
6601
6610
  app.use((_req, res, next) => {
6602
6611
  if (isShuttingDown) {
@@ -6925,7 +6934,7 @@ async function debitMcpCredits(args) {
6925
6934
  return {
6926
6935
  ok: false,
6927
6936
  noWallet: true,
6928
- error: "This account has no credit wallet provisioned. This is an account setup issue, not a quota limit \u2014 visit https://hiveintelligence.xyz/dashboard to initialize billing or contact support."
6937
+ error: "This account has no credit wallet provisioned. This is an account setup issue, not a quota limit. Visit https://hiveintelligence.xyz/dashboard to initialize billing or contact support."
6929
6938
  };
6930
6939
  }
6931
6940
  if (debit.code === "insufficient") {
@@ -7724,7 +7733,7 @@ function createStatelessMcpHandler(scope) {
7724
7733
  return {
7725
7734
  type: "authentication_error",
7726
7735
  code: "ANON_AUTH_REQUIRED",
7727
- message: "This tool requires authentication. Set HIVE_API_KEY \u2014 create one free at https://hiveintelligence.xyz/dashboard/keys \u2014 or sign in via OAuth.",
7736
+ message: "This tool requires authentication. Set HIVE_API_KEY (create one free at https://hiveintelligence.xyz/dashboard/keys) or sign in via OAuth.",
7728
7737
  runtimeStatus: "failing"
7729
7738
  };
7730
7739
  }
package/build/stdio.js CHANGED
@@ -6,7 +6,7 @@ import {
6
6
  import {
7
7
  createHiveMcpServer,
8
8
  secureLogger
9
- } from "./chunk-UFTNBCSA.js";
9
+ } from "./chunk-AGM2CIRL.js";
10
10
  import "./chunk-L326MQZP.js";
11
11
  import "./chunk-EPF36Q3Z.js";
12
12
  import {
@@ -40,7 +40,7 @@ async function listTools(opts) {
40
40
  tools = tools.filter((t) => t.name.toLowerCase().startsWith(prefix + "_"));
41
41
  }
42
42
  if (opts.category) {
43
- const { NAMESPACE } = await import("./namespace-L5DGCY7K.js");
43
+ const { NAMESPACE } = await import("./namespace-YLCGHVRT.js");
44
44
  const cat = opts.category.toLowerCase();
45
45
  const ns = NAMESPACE.find(
46
46
  (d) => d.name === cat || d.description.toLowerCase().includes(cat)
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  detectClients,
4
4
  removeSkillsForClients
5
- } from "./chunk-AEU43ACS.js";
5
+ } from "./chunk-TVBPCELA.js";
6
6
  import {
7
7
  removeClaudeCodeUserConfig,
8
8
  removeClaudeDesktopConfig,
@@ -51,8 +51,8 @@ async function runUninstall(opts = {}) {
51
51
  dryRun: Boolean(opts.dryRun)
52
52
  };
53
53
  if (!opts.json) {
54
- w(bold("\nHive Intelligence \u2014 Uninstall"));
55
- if (summary.dryRun) info("(dry-run \u2014 nothing will be changed)");
54
+ w(bold("\nHive Intelligence: Uninstall"));
55
+ if (summary.dryRun) info("(dry-run: nothing will be changed)");
56
56
  }
57
57
  const clients = detectClients();
58
58
  if (!opts.json) w(bold("\nRemoving from client configs"));
@@ -60,7 +60,7 @@ async function runUninstall(opts = {}) {
60
60
  for (const c of clients) {
61
61
  if (c.id === "chatgpt-desktop" || c.id === "grok") {
62
62
  info(
63
- c.id === "grok" ? "Grok \u2014 remove Hive once at grok.com/connectors" : "OpenAI / ChatGPT apps \u2014 remove the Hive app connector manually"
63
+ c.id === "grok" ? "Grok: remove Hive once at grok.com/connectors" : "OpenAI / ChatGPT apps: remove the Hive app connector manually"
64
64
  );
65
65
  continue;
66
66
  }
@@ -81,14 +81,14 @@ async function runUninstall(opts = {}) {
81
81
  ...result.instructions && { instructions: result.instructions }
82
82
  });
83
83
  if (result.removed) ok(`${c.name} ${dim("(" + result.path + ")")}`);
84
- else if (!result.manual) info(`${c.name} \u2014 no Hive entry to remove`);
84
+ else if (!result.manual) info(`${c.name}: no Hive entry to remove`);
85
85
  if (result.manual && result.instructions) {
86
- warn(`${c.name} \u2014 finish in the app: ${result.instructions}`);
86
+ warn(`${c.name} (finish in the app): ${result.instructions}`);
87
87
  }
88
88
  clientIds.push(c.id);
89
89
  } catch (err) {
90
90
  warn(
91
- `${c.name} \u2014 failed: ${err instanceof Error ? err.message : err}`
91
+ `${c.name} failed: ${err instanceof Error ? err.message : err}`
92
92
  );
93
93
  }
94
94
  }
@@ -2,7 +2,7 @@ import { createRequire } from 'node:module'; const require = createRequire(impor
2
2
  import {
3
3
  detectInstallMode,
4
4
  runUpgrade
5
- } from "./chunk-GHCYCBA3.js";
5
+ } from "./chunk-GB4XMTDE.js";
6
6
  import "./chunk-M6REON2I.js";
7
7
  import "./chunk-ZXKFJQDE.js";
8
8
  import "./chunk-725R3KLJ.js";
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
2
  import {
3
3
  executeTool
4
- } from "./chunk-7DYHWY4Y.js";
4
+ } from "./chunk-SFN772RL.js";
5
5
  import "./chunk-P7NLFSZQ.js";
6
6
  import "./chunk-RU6QOFHH.js";
7
7
  import "./chunk-EPF36Q3Z.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hive-intelligence",
3
- "version": "1.4.0",
3
+ "version": "1.5.0",
4
4
  "description": "Evidence-backed crypto due diligence for AI agents, with sources, freshness, and a runtime receipt on every call.",
5
5
  "mcpName": "xyz.hiveintelligence/mcp",
6
6
  "type": "module",