hive-intelligence 1.8.0 → 1.10.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.
package/build/cli.js CHANGED
@@ -3453,10 +3453,15 @@ program2.hook("preAction", (thisCommand) => {
3453
3453
  setCliFlags({ apiKey: opts.apiKey, noRetry: opts.retry === false });
3454
3454
  });
3455
3455
  program2.action(async () => {
3456
- const { startStdio } = await import("./serve-MOP4WYH6.js");
3456
+ const { startStdio } = await import("./serve-2ICWEUMC.js");
3457
3457
  await startStdio(program2.opts().envFile);
3458
3458
  });
3459
- 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) => {
3459
+ program2.command("serve").description(
3460
+ "Start the MCP server (stdio proxies to hosted Hive; --local runs providers here)"
3461
+ ).option("--http", "Start HTTP server instead of stdio").option(
3462
+ "--local",
3463
+ "Self-host: run provider tools in this process with your own provider keys (same as HIVE_STDIO_MODE=local)"
3464
+ ).option("--port <number>", "HTTP server port", "8080").action(async (opts) => {
3460
3465
  if (opts.http) {
3461
3466
  const port = parseInt(opts.port, 10);
3462
3467
  if (isNaN(port) || port < 1 || port > 65535) {
@@ -3466,11 +3471,11 @@ program2.command("serve").description("Start the MCP server").option("--http", "
3466
3471
  );
3467
3472
  process.exit(ExitCode.INVALID_ARGS);
3468
3473
  }
3469
- const { startHttp } = await import("./serve-MOP4WYH6.js");
3474
+ const { startHttp } = await import("./serve-2ICWEUMC.js");
3470
3475
  await startHttp(port, program2.opts().envFile);
3471
3476
  } else {
3472
- const { startStdio } = await import("./serve-MOP4WYH6.js");
3473
- await startStdio(program2.opts().envFile);
3477
+ const { startStdio } = await import("./serve-2ICWEUMC.js");
3478
+ await startStdio(program2.opts().envFile, { local: opts.local });
3474
3479
  }
3475
3480
  });
3476
3481
  for (const domain of NAMESPACE) {
@@ -3556,15 +3561,15 @@ for (const domain of NAMESPACE) {
3556
3561
  }
3557
3562
  var toolsCmd = program2.command("tools").description("Discover and execute tools");
3558
3563
  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) => {
3559
- const { listTools } = await import("./tools-NJQPIJ53.js");
3564
+ const { listTools } = await import("./tools-J6VPDGYP.js");
3560
3565
  await listTools(opts);
3561
3566
  });
3562
3567
  toolsCmd.command("search <query>").description("Search tools by name or description").action(async (query) => {
3563
- const { searchTools } = await import("./tools-NJQPIJ53.js");
3568
+ const { searchTools } = await import("./tools-J6VPDGYP.js");
3564
3569
  await searchTools(query);
3565
3570
  });
3566
3571
  toolsCmd.command("info <name>").description("Show a tool's parameters, response schema, and description").action(async (name) => {
3567
- const { toolInfo } = await import("./tools-NJQPIJ53.js");
3572
+ const { toolInfo } = await import("./tools-J6VPDGYP.js");
3568
3573
  await toolInfo(name, RESERVED_OPTION_NAMES);
3569
3574
  });
3570
3575
  toolsCmd.command("call <name>").description("Execute a tool by name").option("--args <json>", "Tool arguments as JSON (or pipe JSON via stdin)").allowUnknownOption(true).allowExcessArguments(true).addHelpText(
@@ -3604,7 +3609,7 @@ Examples:
3604
3609
  stdinJson,
3605
3610
  reservedNames: RESERVED_OPTION_NAMES,
3606
3611
  lookupSchema: async (toolName) => {
3607
- const { loadToolCatalog } = await import("./tools-NJQPIJ53.js");
3612
+ const { loadToolCatalog } = await import("./tools-J6VPDGYP.js");
3608
3613
  const catalog = await loadToolCatalog();
3609
3614
  return catalog.find((t) => t.name === toolName)?.inputSchema;
3610
3615
  }
@@ -3622,7 +3627,7 @@ Examples:
3622
3627
  await executeTool(plan.toolName, plan.args, timeout);
3623
3628
  });
3624
3629
  toolsCmd.command("refresh").description("Force-refresh the tool catalog cache").action(async () => {
3625
- const { refreshTools } = await import("./tools-NJQPIJ53.js");
3630
+ const { refreshTools } = await import("./tools-J6VPDGYP.js");
3626
3631
  await refreshTools();
3627
3632
  });
3628
3633
  var configCmd = program2.command("config").description("Generate configuration for MCP clients");
@@ -3681,7 +3686,7 @@ program2.command("init").description(
3681
3686
  await runSetup();
3682
3687
  return;
3683
3688
  }
3684
- const { runInitAll } = await import("./init-all-JXLG7LOX.js");
3689
+ const { runInitAll } = await import("./init-all-SPEWION5.js");
3685
3690
  const exitCode = await runInitAll({
3686
3691
  all: Boolean(opts.all),
3687
3692
  browser: Boolean(opts.browser),
@@ -3733,12 +3738,15 @@ program2.command("feedback <message>").description(
3733
3738
  const { runFeedback } = await import("./feedback-G2DFCCI6.js");
3734
3739
  await runFeedback(message, { tool: opts.tool, receipt: opts.receipt });
3735
3740
  });
3736
- program2.command("doctor").description("Diagnose environment and server connectivity").option("--probe", "Run live API probes (slower)").action(async (opts) => {
3737
- const { runDoctor } = await import("./doctor-5HAAZU4R.js");
3741
+ program2.command("doctor").description("Diagnose environment and server connectivity").option("--probe", "Run live API probes (slower)").option(
3742
+ "--fix",
3743
+ "Rewrite stale Hive entries in MCP client configs (backs each file up first)"
3744
+ ).action(async (opts) => {
3745
+ const { runDoctor } = await import("./doctor-SMUVDZZ2.js");
3738
3746
  await runDoctor(opts);
3739
3747
  });
3740
3748
  program2.command("upgrade").description("Update Hive to the latest published version").action(async () => {
3741
- const { runUpgrade } = await import("./upgrade-3NR3LAGU.js");
3749
+ const { runUpgrade } = await import("./upgrade-BJADUTO6.js");
3742
3750
  await runUpgrade();
3743
3751
  });
3744
3752
  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) => {
@@ -3782,7 +3790,7 @@ program2.command("usage").description("Show your API usage and plan limits").act
3782
3790
  await runUsage();
3783
3791
  });
3784
3792
  program2.command("status").description("Quick health and version check").action(async () => {
3785
- const { runStatus } = await import("./doctor-5HAAZU4R.js");
3793
+ const { runStatus } = await import("./doctor-SMUVDZZ2.js");
3786
3794
  await runStatus();
3787
3795
  });
3788
3796
  program2.command("open [target]").description("Open Hive dashboard, docs, status, or GitHub in browser").action(async (target) => {
@@ -0,0 +1,235 @@
1
+ import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ getClaudeCodeUserConfigPath,
4
+ getClaudeDesktopConfigPath,
5
+ getCodexConfigPath,
6
+ getCursorConfigPath,
7
+ getGeminiCliSettingsPath,
8
+ getWindsurfMcpConfigPath
9
+ } from "./chunk-QDZ7MAVN.js";
10
+ import "./chunk-6PC3HUAK.js";
11
+ import "./chunk-OMO7XLC5.js";
12
+
13
+ // src/cli/config-audit.ts
14
+ import { spawnSync } from "child_process";
15
+ import { copyFileSync, existsSync, readFileSync, writeFileSync } from "fs";
16
+ import { homedir, platform } from "os";
17
+ import { join } from "path";
18
+ var CANONICAL_MCP_URL = "https://mcp.hiveintelligence.xyz/mcp";
19
+ var CANONICAL_STDIO_ARGS = [
20
+ "-y",
21
+ "-p",
22
+ "hive-intelligence@latest",
23
+ "hive"
24
+ ];
25
+ var LEGACY_URL = /^https?:\/\/(www\.)?hiveintelligence\.xyz\/mcp\/?$/;
26
+ var HIVE_BINARIES = /* @__PURE__ */ new Set([
27
+ "hive",
28
+ "hive-mcp",
29
+ "hive-intelligence",
30
+ "hive-mcp-server"
31
+ ]);
32
+ var URL_FIELDS = ["url", "serverUrl", "httpUrl"];
33
+ function vscodeUserMcpPath() {
34
+ const os = platform();
35
+ const base = os === "darwin" ? join(homedir(), "Library", "Application Support") : os === "win32" ? join(homedir(), "AppData", "Roaming") : join(homedir(), ".config");
36
+ return join(base, "Code", "User", "mcp.json");
37
+ }
38
+ function defaultConfigTargets() {
39
+ return [
40
+ { client: "Claude Desktop", path: getClaudeDesktopConfigPath() },
41
+ { client: "Claude Code", path: getClaudeCodeUserConfigPath() },
42
+ { client: "Cursor", path: getCursorConfigPath() },
43
+ { client: "VS Code", path: vscodeUserMcpPath() },
44
+ { client: "Windsurf", path: getWindsurfMcpConfigPath() },
45
+ { client: "Gemini CLI", path: getGeminiCliSettingsPath() },
46
+ { client: "Codex", path: getCodexConfigPath() }
47
+ ];
48
+ }
49
+ function isHiveEntry(entry) {
50
+ return /hive-intelligence|hiveintelligence\.xyz|(^|[\s"/\\])hive-mcp(@|"|$)|"(hive|hive-mcp-server)"/.test(
51
+ JSON.stringify({
52
+ command: entry.command,
53
+ args: entry.args,
54
+ ...Object.fromEntries(URL_FIELDS.map((f) => [f, entry[f]]))
55
+ })
56
+ );
57
+ }
58
+ function basename(command) {
59
+ return command.split(/[\\/]/).pop().replace(/\.(cmd|exe|js)$/i, "");
60
+ }
61
+ function inspectEntry(entry, fix) {
62
+ const found = [];
63
+ const command = typeof entry.command === "string" ? entry.command : "";
64
+ const args = Array.isArray(entry.args) ? entry.args.filter((a) => typeof a === "string") : [];
65
+ if (command && HIVE_BINARIES.has(basename(command))) {
66
+ found.push({
67
+ kind: "global_binary",
68
+ detail: `runs the globally installed "${command}", which stays on whatever version was installed`
69
+ });
70
+ if (fix) {
71
+ entry.command = "npx";
72
+ entry.args = [...CANONICAL_STDIO_ARGS, ...args];
73
+ }
74
+ } else if (/^(npx|bunx|pnpx)$/.test(basename(command))) {
75
+ const pkgFlag = args.findIndex((a) => a === "-p" || a === "--package");
76
+ const specIndex = pkgFlag >= 0 ? pkgFlag + 1 : args.findIndex((a) => !a.startsWith("-"));
77
+ const spec = args[specIndex] ?? "";
78
+ if (/^hive-mcp(@.*)?$/.test(spec)) {
79
+ found.push({
80
+ kind: "wrong_package",
81
+ detail: `"${command} ${args.join(" ")}" resolves to a stale global install or the unrelated npm package "hive-mcp", not Hive`
82
+ });
83
+ if (fix)
84
+ entry.args = [...CANONICAL_STDIO_ARGS, ...args.slice(specIndex + 1)];
85
+ } else if (/^hive-intelligence(@(?!latest$).*)?$/.test(spec)) {
86
+ found.push({
87
+ kind: "pinned_version",
88
+ detail: `"${spec}" is not @latest, so npx can keep running an old version`
89
+ });
90
+ if (fix) {
91
+ const next = [...args];
92
+ next[specIndex] = "hive-intelligence@latest";
93
+ entry.args = next;
94
+ }
95
+ }
96
+ }
97
+ const legacy = [
98
+ ...URL_FIELDS.filter(
99
+ (f) => typeof entry[f] === "string" && LEGACY_URL.test(entry[f])
100
+ ),
101
+ ...args.some((a) => LEGACY_URL.test(a)) ? ["args"] : []
102
+ ];
103
+ if (legacy.length > 0) {
104
+ found.push({
105
+ kind: "legacy_url",
106
+ detail: `points at the retired hiveintelligence.xyz/mcp URL; the server is ${CANONICAL_MCP_URL}`
107
+ });
108
+ if (fix) {
109
+ for (const f of legacy) {
110
+ if (f === "args") {
111
+ entry.args = entry.args.map(
112
+ (a) => typeof a === "string" && LEGACY_URL.test(a) ? CANONICAL_MCP_URL : a
113
+ );
114
+ } else {
115
+ entry[f] = CANONICAL_MCP_URL;
116
+ }
117
+ }
118
+ }
119
+ }
120
+ return found;
121
+ }
122
+ function serverMaps(json) {
123
+ const maps = [];
124
+ const add = (scope, value) => {
125
+ if (value && typeof value === "object" && !Array.isArray(value)) {
126
+ maps.push({ scope, map: value });
127
+ }
128
+ };
129
+ add("user", json.mcpServers);
130
+ add("user", json.servers);
131
+ const projects = json.projects;
132
+ if (projects && typeof projects === "object") {
133
+ for (const [dir, project] of Object.entries(projects)) {
134
+ add(`project ${dir}`, project?.mcpServers);
135
+ }
136
+ }
137
+ return maps;
138
+ }
139
+ function auditJsonConfig(json, target, fix = false) {
140
+ const issues = [];
141
+ for (const { scope, map } of serverMaps(json)) {
142
+ const hiveNames = Object.keys(map).filter(
143
+ (name) => map[name] && typeof map[name] === "object" && isHiveEntry(map[name])
144
+ );
145
+ for (const name of hiveNames) {
146
+ for (const found of inspectEntry(map[name], fix)) {
147
+ issues.push({ ...target, scope, server: name, ...found });
148
+ }
149
+ }
150
+ if (hiveNames.length > 1) {
151
+ const keep = hiveNames.includes("hive") ? "hive" : hiveNames[0];
152
+ for (const name of hiveNames.filter((n) => n !== keep)) {
153
+ issues.push({
154
+ ...target,
155
+ scope,
156
+ server: name,
157
+ kind: "duplicate",
158
+ detail: `duplicates the "${keep}" entry; two Hive servers expose the same tools twice`
159
+ });
160
+ if (fix) delete map[name];
161
+ }
162
+ }
163
+ }
164
+ return issues;
165
+ }
166
+ function auditClientConfigs(opts = {}) {
167
+ const result = { issues: [], scanned: [], fixed: [] };
168
+ for (const target of opts.targets ?? defaultConfigTargets()) {
169
+ if (!existsSync(target.path)) continue;
170
+ const raw = readFileSync(target.path, "utf-8");
171
+ result.scanned.push(target.path);
172
+ if (target.path.endsWith(".toml")) {
173
+ if (/["'](https?:\/\/(www\.)?hiveintelligence\.xyz\/mcp\/?)["']/.test(raw)) {
174
+ result.issues.push({
175
+ ...target,
176
+ scope: "user",
177
+ server: "hive",
178
+ kind: "legacy_url",
179
+ detail: `points at the retired hiveintelligence.xyz/mcp URL. Run: codex mcp remove hive && codex mcp add hive --url ${CANONICAL_MCP_URL}`
180
+ });
181
+ }
182
+ continue;
183
+ }
184
+ let json;
185
+ try {
186
+ json = JSON.parse(raw);
187
+ } catch {
188
+ continue;
189
+ }
190
+ const issues = auditJsonConfig(json, target, opts.fix);
191
+ result.issues.push(...issues);
192
+ if (opts.fix && issues.length > 0) {
193
+ const stamp = (opts.now ?? /* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-");
194
+ const backup = `${target.path}.hive-backup-${stamp}`;
195
+ copyFileSync(target.path, backup);
196
+ writeFileSync(target.path, JSON.stringify(json, null, 2) + "\n", "utf-8");
197
+ result.fixed.push({ path: target.path, backup });
198
+ }
199
+ }
200
+ return result;
201
+ }
202
+ function readGlobalInstalls(globalRoot) {
203
+ if (!globalRoot) return [];
204
+ const installs = [];
205
+ for (const name of ["hive-intelligence", "hive-mcp"]) {
206
+ const path = join(globalRoot, name);
207
+ try {
208
+ const pkg = JSON.parse(
209
+ readFileSync(join(path, "package.json"), "utf-8")
210
+ );
211
+ installs.push({ name, version: pkg.version ?? "unknown", path });
212
+ } catch {
213
+ }
214
+ }
215
+ return installs;
216
+ }
217
+ function npmGlobalRoot() {
218
+ const result = spawnSync("npm", ["root", "-g"], {
219
+ encoding: "utf8",
220
+ timeout: 5e3,
221
+ stdio: ["ignore", "pipe", "ignore"],
222
+ shell: platform() === "win32"
223
+ });
224
+ const root = result.status === 0 ? result.stdout.trim() : "";
225
+ return root || null;
226
+ }
227
+ export {
228
+ CANONICAL_MCP_URL,
229
+ CANONICAL_STDIO_ARGS,
230
+ auditClientConfigs,
231
+ auditJsonConfig,
232
+ defaultConfigTargets,
233
+ npmGlobalRoot,
234
+ readGlobalInstalls
235
+ };
@@ -41,6 +41,61 @@ function describeQuotaCheck(quota) {
41
41
  const reason = quota.body?.error?.message ?? `HTTP ${quota.status}`;
42
42
  return { check, status: "WARN", detail: `quota: ${reason}` };
43
43
  }
44
+ async function describeInstallChecks(latest, fix) {
45
+ const { auditClientConfigs, readGlobalInstalls, npmGlobalRoot } = await import("./config-audit-7GC42QX7.js");
46
+ const { isNewerVersion } = await import("./update-check-36QU6PKA.js");
47
+ const checks = [];
48
+ for (const install of readGlobalInstalls(npmGlobalRoot())) {
49
+ if (install.name === "hive-mcp") {
50
+ checks.push({
51
+ check: "Global install",
52
+ status: "WARN",
53
+ detail: `npm package "hive-mcp" v${install.version} at ${install.path} is not Hive (different author). Run: npm uninstall -g hive-mcp`
54
+ });
55
+ } else if (latest && isNewerVersion(latest, install.version)) {
56
+ checks.push({
57
+ check: "Global install",
58
+ status: "WARN",
59
+ detail: `hive-intelligence v${install.version} at ${install.path} is stale (latest v${latest}); bare "hive" and "npx hive-mcp" run it. Run: npx -y -p hive-intelligence@latest hive upgrade`
60
+ });
61
+ } else {
62
+ checks.push({
63
+ check: "Global install",
64
+ status: "PASS",
65
+ detail: `hive-intelligence v${install.version}`
66
+ });
67
+ }
68
+ }
69
+ const audit = auditClientConfigs({ fix });
70
+ for (const issue of audit.issues) {
71
+ checks.push({
72
+ check: `Config: ${issue.client}`,
73
+ status: fix && audit.fixed.some((f) => f.path === issue.path) ? "FIXED" : "WARN",
74
+ detail: `"${issue.server}" (${issue.scope}) ${issue.detail}`
75
+ });
76
+ }
77
+ for (const { path, backup } of audit.fixed) {
78
+ checks.push({
79
+ check: "Config backup",
80
+ status: "INFO",
81
+ detail: `${path} rewritten; original saved to ${backup}. Restart that client.`
82
+ });
83
+ }
84
+ if (audit.issues.length === 0) {
85
+ checks.push({
86
+ check: "Client configs",
87
+ status: "PASS",
88
+ detail: `${audit.scanned.length} MCP config file(s) checked; no stale Hive entries`
89
+ });
90
+ } else if (!fix && audit.issues.some((i) => !i.path.endsWith(".toml"))) {
91
+ checks.push({
92
+ check: "Client configs",
93
+ status: "INFO",
94
+ detail: "Run: hive doctor --fix (backs up each file before rewriting it)"
95
+ });
96
+ }
97
+ return checks;
98
+ }
44
99
  async function runDoctor(opts) {
45
100
  const checks = [];
46
101
  const apiKey = process.env.HIVE_API_KEY;
@@ -131,10 +186,10 @@ async function runDoctor(opts) {
131
186
  });
132
187
  }
133
188
  }
189
+ const { SERVER_VERSION } = await import("./version-ITRM4X2U.js");
190
+ const { fetchLatestVersion, isNewerVersion } = await import("./update-check-36QU6PKA.js");
191
+ const latest = await fetchLatestVersion(5e3);
134
192
  {
135
- const { SERVER_VERSION } = await import("./version-ITRM4X2U.js");
136
- const { fetchLatestVersion, isNewerVersion } = await import("./update-check-36QU6PKA.js");
137
- const latest = await fetchLatestVersion(5e3);
138
193
  if (latest === null) {
139
194
  checks.push({
140
195
  check: "Updates",
@@ -155,6 +210,7 @@ async function runDoctor(opts) {
155
210
  });
156
211
  }
157
212
  }
213
+ checks.push(...await describeInstallChecks(latest, Boolean(opts.fix)));
158
214
  if (opts.probe) {
159
215
  const probeUrl = `${getApiUrl()}/health?run=true`;
160
216
  debug(`Probe: GET ${probeUrl}`);
@@ -240,7 +296,7 @@ ${fails === 0 ? "All checks passed" : `${fails} issues found`}${warns ? ` (${war
240
296
  if (fails > 0) process.exit(1);
241
297
  }
242
298
  async function runStatus() {
243
- const { SERVER_VERSION } = await import("./mcpServer-LNRRWXSV.js");
299
+ const { SERVER_VERSION } = await import("./mcpServer-T3DYYFCC.js");
244
300
  const { resolveApiKey, resolveApiUrl } = await import("./config-dir-2QLA5PXD.js");
245
301
  const { getActiveProfile, maskKey } = await import("./auth-6XVL5CE3.js");
246
302
  const apiUrl = resolveApiUrl();
@@ -286,6 +342,7 @@ Hive CLI v${SERVER_VERSION}
286
342
  `);
287
343
  }
288
344
  export {
345
+ describeInstallChecks,
289
346
  describeQuotaCheck,
290
347
  runDoctor,
291
348
  runStatus
@@ -1,8 +1,17 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
+ import {
3
+ detectInstallMode
4
+ } from "./chunk-5IQUEFCD.js";
2
5
  import {
3
6
  detectClients,
4
7
  installSkillsForClients
5
8
  } from "./chunk-FQNW6SZ6.js";
9
+ import {
10
+ browserLogin
11
+ } from "./chunk-BDO27NIP.js";
12
+ import {
13
+ saveProfile
14
+ } from "./chunk-KQVPKTEO.js";
6
15
  import {
7
16
  getClaudeDesktopInstructions,
8
17
  getCodexInstructions,
@@ -17,15 +26,6 @@ import {
17
26
  writeVscodeConfig,
18
27
  writeWindsurfConfig
19
28
  } from "./chunk-QDZ7MAVN.js";
20
- import {
21
- browserLogin
22
- } from "./chunk-BDO27NIP.js";
23
- import {
24
- saveProfile
25
- } from "./chunk-KQVPKTEO.js";
26
- import {
27
- detectInstallMode
28
- } from "./chunk-L4KVJDA7.js";
29
29
  import "./chunk-M6REON2I.js";
30
30
  import "./chunk-4QDGA6GP.js";
31
31
  import "./chunk-ZXKFJQDE.js";
@@ -9,7 +9,7 @@ import {
9
9
  getToolsForScope,
10
10
  memoizedJsonSchemaToZodInputSchema,
11
11
  memoizedJsonSchemaToZodOutputSchema
12
- } from "./chunk-HWV3XFXH.js";
12
+ } from "./chunk-Z42XNN47.js";
13
13
  import "./chunk-4QDGA6GP.js";
14
14
  import "./chunk-EPF36Q3Z.js";
15
15
  import {
@@ -1,8 +1,10 @@
1
1
  import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
2
2
  import {
3
3
  consumeCredits,
4
- executeToolByName
5
- } from "./chunk-ORJIFYF4.js";
4
+ executeToolByName,
5
+ refundCredits,
6
+ refundSettled
7
+ } from "./chunk-E2FAHUXM.js";
6
8
  import {
7
9
  HyperliquidAPI,
8
10
  MIN_MONITOR_CADENCE_MS,
@@ -15,7 +17,7 @@ import {
15
17
  monitorCadenceIntervalMs,
16
18
  runScheduledHealthCanaries,
17
19
  secureLogger
18
- } from "./chunk-HWV3XFXH.js";
20
+ } from "./chunk-Z42XNN47.js";
19
21
  import "./chunk-4QDGA6GP.js";
20
22
  import "./chunk-EPF36Q3Z.js";
21
23
  import "./chunk-ZXKFJQDE.js";
@@ -258,7 +260,8 @@ function buildTokenWorkflowPlan(monitor) {
258
260
  {
259
261
  toolName: "get_token_top_holders",
260
262
  snapshotKey: "holders",
261
- args: { network: normalizeGeckoNetwork(monitor.target), address }
263
+ // The tool now defaults to the plan maximum (50); snapshots keep 10.
264
+ args: { network: normalizeGeckoNetwork(monitor.target), address, limit: 10 }
262
265
  }
263
266
  ];
264
267
  }
@@ -640,6 +643,29 @@ async function defaultConsumeCredit(args) {
640
643
  requestId: args.runId
641
644
  });
642
645
  }
646
+ async function defaultRefundCredit(args) {
647
+ const refund = await refundCredits({
648
+ userId: args.userId,
649
+ debitIdempotencyKey: `monitor-run:${args.runId}`,
650
+ detail: { monitor_run: args.runId, reason: args.reason }
651
+ });
652
+ return refundSettled(refund.code);
653
+ }
654
+ async function refundMonitorRunCredit(args) {
655
+ try {
656
+ return await args.refundCredit({
657
+ userId: args.monitor.user_id,
658
+ runId: args.runId,
659
+ reason: args.reason
660
+ });
661
+ } catch (error) {
662
+ secureLogger.error("Monitor run credit refund failed", error, {
663
+ monitorId: args.monitor.id,
664
+ runId: args.runId
665
+ });
666
+ return false;
667
+ }
668
+ }
643
669
  async function debitMonitorRunCredit(args) {
644
670
  try {
645
671
  const debit = await args.consumeCredit({
@@ -976,6 +1002,7 @@ async function processMonitor(monitor, options) {
976
1002
  });
977
1003
  const completedAt = options.now.toISOString();
978
1004
  const nextRunAt = computeNextRunAt(monitor.cadence, options.now);
1005
+ let charged = false;
979
1006
  try {
980
1007
  const debit = await debitMonitorRunCredit({
981
1008
  monitor,
@@ -1007,6 +1034,7 @@ async function processMonitor(monitor, options) {
1007
1034
  alerts: 0
1008
1035
  };
1009
1036
  }
1037
+ charged = true;
1010
1038
  const previous = await options.store.getLatestSnapshot(monitor.id);
1011
1039
  const workflow = await executeMonitorWorkflow(
1012
1040
  monitor,
@@ -1101,6 +1129,13 @@ async function processMonitor(monitor, options) {
1101
1129
  });
1102
1130
  observations++;
1103
1131
  }
1132
+ const everyCallFailed = workflow.toolCalls.length > 0 && workflow.failedCalls.length === workflow.toolCalls.length;
1133
+ const creditRefunded = everyCallFailed ? await refundMonitorRunCredit({
1134
+ monitor,
1135
+ runId: run.id,
1136
+ reason: "every tool call failed",
1137
+ refundCredit: options.refundCredit
1138
+ }) : false;
1104
1139
  await options.store.finishRun({
1105
1140
  runId: run.id,
1106
1141
  status: "completed",
@@ -1109,7 +1144,8 @@ async function processMonitor(monitor, options) {
1109
1144
  metadata: {
1110
1145
  fingerprint: workflow.fingerprint,
1111
1146
  failed_call_count: workflow.failedCalls.length,
1112
- rule_evaluation_count: ruleEvaluations.length
1147
+ rule_evaluation_count: ruleEvaluations.length,
1148
+ ...creditRefunded && { credit_refunded: true }
1113
1149
  }
1114
1150
  });
1115
1151
  await options.store.releaseMonitor({
@@ -1129,6 +1165,14 @@ async function processMonitor(monitor, options) {
1129
1165
  };
1130
1166
  } catch (error) {
1131
1167
  const message = error instanceof Error ? error.message : String(error);
1168
+ if (charged) {
1169
+ await refundMonitorRunCredit({
1170
+ monitor,
1171
+ runId: run.id,
1172
+ reason: "run failed",
1173
+ refundCredit: options.refundCredit
1174
+ });
1175
+ }
1132
1176
  await options.store.finishRun({
1133
1177
  runId: run.id,
1134
1178
  status: "failed",
@@ -1165,6 +1209,7 @@ async function runDueMonitors(options = {}) {
1165
1209
  const now = options.now ?? /* @__PURE__ */ new Date();
1166
1210
  const executeTool = options.executeTool ?? executeToolByName;
1167
1211
  const consumeCredit = options.consumeCredit ?? defaultConsumeCredit;
1212
+ const refundCredit = options.refundCredit ?? defaultRefundCredit;
1168
1213
  const source = options.source ?? "scheduled";
1169
1214
  const claimed = await store.claimDueMonitors({
1170
1215
  batchSize,
@@ -1191,7 +1236,8 @@ async function runDueMonitors(options = {}) {
1191
1236
  now,
1192
1237
  source,
1193
1238
  executeTool,
1194
- consumeCredit
1239
+ consumeCredit,
1240
+ refundCredit
1195
1241
  })
1196
1242
  );
1197
1243
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "package": "hive-intelligence",
3
- "version": "1.8.0",
4
- "buildSha": "eac2d1b060973dfe826ff082d35708e2b80ac05c",
5
- "imageDigest": "sha256:cbc418fc3433b677d78aeef00b1b7b37ccaa440e00c6cab390ed327fd31f6669",
3
+ "version": "1.10.0",
4
+ "buildSha": "f1683e07eb36c1b0dcbe0cbfa12d1542013e041b",
5
+ "imageDigest": "sha256:1363e537ef7d24bc29744fd9f8978debdcb7a044c084d366b4e1ef202b6976c7",
6
6
  "deployedUrl": "https://mcp.hiveintelligence.xyz",
7
- "manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.8.0/releases/v1.8.0.json"
7
+ "manifest": "https://raw.githubusercontent.com/hive-intel/hive-sdk/v1.10.0/releases/v1.10.0.json"
8
8
  }