hive-intelligence 1.1.4 → 1.4.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/README.md +182 -73
- package/agent-skills/.claude-plugin/plugin.json +4 -4
- package/agent-skills/.mcp.json +1 -4
- package/agent-skills/README.md +16 -10
- package/agent-skills/SKILL.md +30 -12
- package/agent-skills/package.json +1 -1
- package/agent-skills/packs/hive-build/SKILL.md +47 -19
- package/agent-skills/packs/hive-build/evals/evals.json +16 -3
- package/agent-skills/packs/hive-build/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-build-onboarding/SKILL.md +30 -37
- package/agent-skills/packs/hive-build-onboarding/evals/evals.json +1 -1
- package/agent-skills/packs/hive-build-onboarding/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-cli/SKILL.md +33 -35
- package/agent-skills/packs/hive-cli/evals/evals.json +1 -1
- package/agent-skills/packs/hive-cli/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-defi-research/SKILL.md +105 -19
- package/agent-skills/packs/hive-defi-research/evals/evals.json +6 -3
- package/agent-skills/packs/hive-defi-research/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-dex-pool-analysis/SKILL.md +106 -16
- package/agent-skills/packs/hive-dex-pool-analysis/evals/evals.json +5 -3
- package/agent-skills/packs/hive-dex-pool-analysis/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-market-research/SKILL.md +130 -21
- package/agent-skills/packs/hive-market-research/evals/evals.json +15 -2
- package/agent-skills/packs/hive-market-research/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-mcp/SKILL.md +69 -47
- package/agent-skills/packs/hive-mcp/evals/evals.json +3 -2
- package/agent-skills/packs/hive-mcp/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-mcp/references/client-install-matrix.md +62 -35
- package/agent-skills/packs/hive-mcp/references/clients.md +81 -68
- package/agent-skills/packs/hive-network-infrastructure/SKILL.md +105 -20
- package/agent-skills/packs/hive-network-infrastructure/evals/evals.json +4 -2
- package/agent-skills/packs/hive-network-infrastructure/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-nft-research/SKILL.md +105 -18
- package/agent-skills/packs/hive-nft-research/evals/evals.json +4 -2
- package/agent-skills/packs/hive-nft-research/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-prediction-markets/SKILL.md +108 -21
- package/agent-skills/packs/hive-prediction-markets/evals/evals.json +4 -2
- package/agent-skills/packs/hive-prediction-markets/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-query/SKILL.md +79 -33
- package/agent-skills/packs/hive-query/evals/evals.json +7 -5
- package/agent-skills/packs/hive-query/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-query/references/root-mcp-workflow.md +39 -18
- package/agent-skills/packs/hive-security-risk/SKILL.md +110 -19
- package/agent-skills/packs/hive-security-risk/evals/evals.json +4 -2
- package/agent-skills/packs/hive-security-risk/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-solana-analysis/SKILL.md +115 -19
- package/agent-skills/packs/hive-solana-analysis/evals/evals.json +4 -2
- package/agent-skills/packs/hive-solana-analysis/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-stateful-monitoring/SKILL.md +92 -47
- package/agent-skills/packs/hive-stateful-monitoring/evals/evals.json +7 -2
- package/agent-skills/packs/hive-stateful-monitoring/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-stateful-monitoring/references/b2b-subject-context.md +53 -0
- package/agent-skills/packs/hive-token-diligence/SKILL.md +119 -21
- package/agent-skills/packs/hive-token-diligence/evals/evals.json +6 -4
- package/agent-skills/packs/hive-token-diligence/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-tool-discovery/SKILL.md +48 -19
- package/agent-skills/packs/hive-tool-discovery/evals/evals.json +17 -3
- package/agent-skills/packs/hive-tool-discovery/evals/triggers.json +50 -0
- package/agent-skills/packs/hive-tool-discovery/references/discovery-surfaces.md +31 -6
- package/agent-skills/packs/hive-wallet-investigation/SKILL.md +111 -18
- package/agent-skills/packs/hive-wallet-investigation/evals/evals.json +5 -3
- package/agent-skills/packs/hive-wallet-investigation/evals/triggers.json +50 -0
- package/agent-skills/references/agents-routing.md +17 -7
- package/agent-skills/scripts/validate-agent-skills-package.mjs +68 -8
- package/bin/hive-mcp.js +5 -5
- package/build/{alias-3OPMQF4X.js → alias-BKAVOYQV.js} +2 -2
- package/build/api-client-WMWFWXC7.js +16 -0
- package/build/{auth-Q5Q24IRI.js → auth-HRFQWQMZ.js} +3 -11
- package/build/browser-auth-KXIO5BHM.js +20 -0
- package/build/{cache-T6KC5YEY.js → cache-TBDQ7QBU.js} +2 -2
- package/build/chunk-3OZFBWFK.js +180 -0
- package/build/{chunk-POT2MBEK.js → chunk-6PC3HUAK.js} +10 -3
- package/build/{chunk-NP6NSOG2.js → chunk-725R3KLJ.js} +26 -3
- package/build/chunk-7DYHWY4Y.js +125 -0
- package/build/{chunk-ZXB53E7H.js → chunk-AEU43ACS.js} +31 -7
- package/build/chunk-AQQAPAER.js +197 -0
- package/build/chunk-EPF36Q3Z.js +71 -0
- package/build/{upgrade-DTUIHVPS.js → chunk-GHCYCBA3.js} +4 -5
- package/build/{chunk-3WYWXTNN.js → chunk-ILVPOLA7.js} +12 -3
- package/build/{chunk-VBOKVQ74.js → chunk-L326MQZP.js} +6 -5
- package/build/{chunk-FRXMGRZQ.js → chunk-M6REON2I.js} +2 -2
- package/build/{chunk-7JWXBKEJ.js → chunk-P7NLFSZQ.js} +9 -60
- package/build/chunk-QDZ7MAVN.js +447 -0
- package/build/{chunk-ZTJVOWDQ.js → chunk-R6YZTFQL.js} +2 -0
- package/build/{chunk-YZ2PXBJK.js → chunk-RU6QOFHH.js} +6 -9
- package/build/{chunk-FH3YGSY5.js → chunk-TNQ7GJ6Q.js} +0 -59
- package/build/{chunk-5XXI25JE.js → chunk-TVQJY47C.js} +12 -160
- package/build/{chunk-JTUKQWIO.js → chunk-UFTNBCSA.js} +35515 -14994
- package/build/{chunk-ZCU7XQKF.js → chunk-ZXKFJQDE.js} +7 -1
- package/build/cli.js +3342 -3423
- package/build/{completion-46K674EL.js → completion-7KBW243H.js} +4 -4
- package/build/{config-XE6Q5P4I.js → config-KAEUX6RM.js} +23 -3
- package/build/{config-dir-MAWX5AUF.js → config-dir-5IH7MOOT.js} +2 -2
- package/build/{doctor-HGMQE6IN.js → doctor-GHUAUFS2.js} +12 -12
- package/build/{errors-J2PH3NLJ.js → errors-HGHUF575.js} +2 -2
- package/build/{format-5X2HIVDT.js → format-H7FOQSYY.js} +1 -1
- package/build/{init-JMDNM7ZZ.js → init-UCTCUYFA.js} +52 -8
- package/build/init-all-RG542NWG.js +427 -0
- package/build/mcpServer-D7OXUDU5.js +34 -0
- package/build/monitor-worker.js +296 -40
- package/build/{namespace-FSX2G3NM.js → namespace-L5DGCY7K.js} +2 -2
- package/build/{open-5A6ZQMGC.js → open-V2RNA3QT.js} +1 -1
- package/build/{output-V3D4YZ6U.js → output-ITGLBKIG.js} +2 -2
- package/build/release.json +8 -0
- package/build/{serve-AGCOXXFM.js → serve-K3IT7DS4.js} +3 -3
- package/build/server.js +6396 -3220
- package/build/{setup-RMETGJWK.js → setup-PTYFMTK5.js} +60 -55
- package/build/stdio.js +7 -6
- package/build/{telemetry-WCME5XEU.js → telemetry-HPLDYR7U.js} +5 -4
- package/build/{tools-KAB6QBZC.js → tools-D72ZH6P5.js} +15 -15
- package/build/{uninstall-FLJMBBSC.js → uninstall-SAOIPL6K.js} +19 -10
- package/build/{update-check-LNZQK3XA.js → update-check-IEXPOYYR.js} +4 -4
- package/build/upgrade-4S5XT5JG.js +14 -0
- package/build/{version-I6HDAF4L.js → version-Z4HJL4VV.js} +4 -2
- package/build/{watch-YNN255QX.js → watch-IOSRSCFE.js} +8 -7
- package/package.json +73 -35
- package/agent-skills/packs/hive-defi-research/references/workflow.md +0 -41
- package/agent-skills/packs/hive-dex-pool-analysis/references/workflow.md +0 -42
- package/agent-skills/packs/hive-market-research/references/workflow.md +0 -47
- package/agent-skills/packs/hive-network-infrastructure/references/workflow.md +0 -41
- package/agent-skills/packs/hive-nft-research/references/workflow.md +0 -42
- package/agent-skills/packs/hive-prediction-markets/references/workflow.md +0 -42
- package/agent-skills/packs/hive-security-risk/references/workflow.md +0 -46
- package/agent-skills/packs/hive-solana-analysis/references/workflow.md +0 -42
- package/agent-skills/packs/hive-token-diligence/references/workflow.md +0 -45
- package/agent-skills/packs/hive-wallet-investigation/references/workflow.md +0 -45
- package/build/api-client-EPF6FD7A.js +0 -28
- package/build/browser-auth-VPF5LZMZ.js +0 -8
- package/build/chunk-4F5CI6LX.js +0 -340
- package/build/chunk-CEWCB5YS.js +0 -71
- package/build/chunk-GZPDEXO4.js +0 -126
- package/build/chunk-IZPAMRHP.js +0 -43
- package/build/init-all-5SKNV75X.js +0 -273
- package/build/mcpServer-5TKKSKJM.js +0 -21
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
createToolNotFoundResult,
|
|
4
|
+
executeEndpoint,
|
|
5
|
+
getAllWrappedEndpoints,
|
|
6
|
+
getSharedClients,
|
|
7
|
+
getSupabaseAdmin,
|
|
8
|
+
resolveEndpoint,
|
|
9
|
+
secureLogger
|
|
10
|
+
} from "./chunk-UFTNBCSA.js";
|
|
11
|
+
|
|
12
|
+
// src/services/wallet-service.ts
|
|
13
|
+
async function consumeCredits(args) {
|
|
14
|
+
const { userId, cost, idempotencyKey, requestId, keyId } = args;
|
|
15
|
+
const { data, error } = await getSupabaseAdmin().rpc("consume_credits", {
|
|
16
|
+
p_user_id: userId,
|
|
17
|
+
p_cost: cost,
|
|
18
|
+
p_idempotency_key: idempotencyKey,
|
|
19
|
+
p_request_id: requestId ?? null,
|
|
20
|
+
p_key_id: keyId ?? null
|
|
21
|
+
});
|
|
22
|
+
if (error) {
|
|
23
|
+
secureLogger.error("consume_credits RPC failed", error, { userId });
|
|
24
|
+
throw new Error(`consume_credits failed: ${error.message}`);
|
|
25
|
+
}
|
|
26
|
+
const row = Array.isArray(data) ? data[0] : data;
|
|
27
|
+
if (!row) {
|
|
28
|
+
throw new Error("consume_credits returned no row");
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
code: row.code,
|
|
32
|
+
balance: row.balance ?? null,
|
|
33
|
+
monthlyGrant: row.monthly_grant ?? 0,
|
|
34
|
+
cycleEnd: row.cycle_end ?? null
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
async function ensureWallet(userId, planId) {
|
|
38
|
+
const { error } = await getSupabaseAdmin().rpc("ensure_wallet", {
|
|
39
|
+
p_user_id: userId,
|
|
40
|
+
p_plan_id: planId
|
|
41
|
+
});
|
|
42
|
+
if (error) {
|
|
43
|
+
secureLogger.error("ensure_wallet RPC failed", error, { userId });
|
|
44
|
+
throw new Error(`ensure_wallet failed: ${error.message}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
async function getWalletStatus(userId) {
|
|
48
|
+
const { data, error } = await getSupabaseAdmin().rpc("read_wallet", {
|
|
49
|
+
p_user_id: userId
|
|
50
|
+
});
|
|
51
|
+
const row = Array.isArray(data) ? data[0] : data;
|
|
52
|
+
if (error || !row) {
|
|
53
|
+
secureLogger.warn("getWalletStatus returned no row", {
|
|
54
|
+
userId,
|
|
55
|
+
hasError: !!error,
|
|
56
|
+
errorCode: error?.code,
|
|
57
|
+
errorMessage: error?.message
|
|
58
|
+
});
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
planId: row.plan_id,
|
|
63
|
+
balance: row.balance ?? null,
|
|
64
|
+
monthlyGrant: row.monthly_grant,
|
|
65
|
+
cycleStart: row.cycle_start,
|
|
66
|
+
cycleEnd: row.cycle_end,
|
|
67
|
+
updatedAt: row.updated_at
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
async function applyPlanChange(args) {
|
|
71
|
+
const { data, error } = await getSupabaseAdmin().rpc("apply_plan_change", {
|
|
72
|
+
p_event_id: args.eventId,
|
|
73
|
+
p_event_type: args.eventType,
|
|
74
|
+
p_user_id: args.userId,
|
|
75
|
+
p_new_plan_id: args.newPlanId ?? null,
|
|
76
|
+
p_grant_credits: args.grantCredits ?? false,
|
|
77
|
+
p_cycle_start: args.cycleStart ?? null,
|
|
78
|
+
p_cycle_end: args.cycleEnd ?? null,
|
|
79
|
+
p_billing_status: args.billingStatus ?? null,
|
|
80
|
+
p_customer_id: args.customerId ?? null,
|
|
81
|
+
p_subscription_id: args.subscriptionId ?? null,
|
|
82
|
+
p_subscription_status: args.subscriptionStatus ?? null,
|
|
83
|
+
p_price_id: args.priceId ?? null,
|
|
84
|
+
p_ledger_reason: args.ledgerReason ?? "plan_change",
|
|
85
|
+
p_term_end: args.termEnd ?? null
|
|
86
|
+
});
|
|
87
|
+
if (error) {
|
|
88
|
+
secureLogger.error("apply_plan_change RPC failed", error, {
|
|
89
|
+
userId: args.userId,
|
|
90
|
+
eventType: args.eventType
|
|
91
|
+
});
|
|
92
|
+
throw new Error(`apply_plan_change failed: ${error.message}`);
|
|
93
|
+
}
|
|
94
|
+
const row = Array.isArray(data) ? data[0] : data;
|
|
95
|
+
if (!row) {
|
|
96
|
+
throw new Error("apply_plan_change returned no row");
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
outcome: String(row.outcome ?? "applied"),
|
|
100
|
+
replayed: Boolean(row.replayed),
|
|
101
|
+
planId: row.plan_id ?? null,
|
|
102
|
+
balance: row.balance ?? null,
|
|
103
|
+
billingStatus: row.billing_status ?? null
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/services/tool-execution.ts
|
|
108
|
+
async function executeToolByName(toolName, args, options) {
|
|
109
|
+
const allEndpoints = getAllWrappedEndpoints();
|
|
110
|
+
const lookup = resolveEndpoint(allEndpoints, toolName);
|
|
111
|
+
if (!lookup.ok) {
|
|
112
|
+
const result2 = createToolNotFoundResult(toolName);
|
|
113
|
+
secureLogger.toolCall(toolName, false, result2.durationMs, {
|
|
114
|
+
transport: "rest",
|
|
115
|
+
runtimeStatus: "failing",
|
|
116
|
+
errorClass: "not_found",
|
|
117
|
+
receiptId: result2.hive.receipt_id,
|
|
118
|
+
receiptVersion: result2.hive.receipt_version,
|
|
119
|
+
requestId: options?.requestId,
|
|
120
|
+
serverVersion: result2.hive.server_version,
|
|
121
|
+
buildSha: result2.hive.build_sha,
|
|
122
|
+
inputDigest: result2.hive.input_digest,
|
|
123
|
+
resultDigest: result2.hive.result_digest
|
|
124
|
+
});
|
|
125
|
+
return {
|
|
126
|
+
ok: false,
|
|
127
|
+
error: result2.error,
|
|
128
|
+
durationMs: result2.durationMs,
|
|
129
|
+
meta: result2.hive
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const result = await executeEndpoint(lookup.endpoint, args, {
|
|
133
|
+
transport: "rest",
|
|
134
|
+
requestId: options?.requestId,
|
|
135
|
+
clients: getSharedClients(),
|
|
136
|
+
beforeExecution: options?.beforeExecution
|
|
137
|
+
});
|
|
138
|
+
if (result.validationErrors) {
|
|
139
|
+
return {
|
|
140
|
+
ok: false,
|
|
141
|
+
error: result.error,
|
|
142
|
+
validationErrors: result.validationErrors,
|
|
143
|
+
durationMs: result.durationMs,
|
|
144
|
+
meta: result.hive
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
if (result.ok) {
|
|
148
|
+
return {
|
|
149
|
+
ok: true,
|
|
150
|
+
data: result.data,
|
|
151
|
+
durationMs: result.durationMs,
|
|
152
|
+
meta: result.hive
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
if (result.error?.code === "PROVIDER_UNAVAILABLE") {
|
|
156
|
+
return {
|
|
157
|
+
ok: false,
|
|
158
|
+
error: result.error,
|
|
159
|
+
durationMs: result.durationMs,
|
|
160
|
+
meta: result.hive
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
if (result.error?.code === "INTERNAL_ERROR") {
|
|
164
|
+
secureLogger.error(`[tool-execution] ${toolName} threw`, result.error, {});
|
|
165
|
+
}
|
|
166
|
+
return {
|
|
167
|
+
ok: false,
|
|
168
|
+
error: result.error,
|
|
169
|
+
durationMs: result.durationMs,
|
|
170
|
+
meta: result.hive
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export {
|
|
175
|
+
consumeCredits,
|
|
176
|
+
ensureWallet,
|
|
177
|
+
getWalletStatus,
|
|
178
|
+
applyPlanChange,
|
|
179
|
+
executeToolByName
|
|
180
|
+
};
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
2
|
|
|
3
3
|
// src/cli/config-dir.ts
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
chmodSync,
|
|
6
|
+
existsSync,
|
|
7
|
+
mkdirSync,
|
|
8
|
+
readFileSync,
|
|
9
|
+
writeFileSync
|
|
10
|
+
} from "fs";
|
|
5
11
|
import { join } from "path";
|
|
6
12
|
import { homedir } from "os";
|
|
7
13
|
var DEFAULT_CONFIG = {
|
|
@@ -24,9 +30,9 @@ function getConfigDir() {
|
|
|
24
30
|
}
|
|
25
31
|
function ensureConfigDir() {
|
|
26
32
|
const dir = getConfigDir();
|
|
27
|
-
if (!existsSync(dir)) mkdirSync(dir, { recursive: true });
|
|
33
|
+
if (!existsSync(dir)) mkdirSync(dir, { recursive: true, mode: 448 });
|
|
28
34
|
const cacheDir = join(dir, "cache");
|
|
29
|
-
if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true });
|
|
35
|
+
if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true, mode: 448 });
|
|
30
36
|
}
|
|
31
37
|
function readJsonFile(filePath) {
|
|
32
38
|
try {
|
|
@@ -41,6 +47,7 @@ function writeJsonFile(filePath, data) {
|
|
|
41
47
|
encoding: "utf-8",
|
|
42
48
|
mode: 384
|
|
43
49
|
});
|
|
50
|
+
chmodSync(filePath, 384);
|
|
44
51
|
}
|
|
45
52
|
function getConfig() {
|
|
46
53
|
const filePath = join(getConfigDir(), "config.json");
|
|
@@ -149,7 +149,8 @@ function errorEnvelope(err, meta) {
|
|
|
149
149
|
error: {
|
|
150
150
|
code: err.code,
|
|
151
151
|
message: err.message,
|
|
152
|
-
...err.suggestion && { suggestion: err.suggestion }
|
|
152
|
+
...err.suggestion && { suggestion: err.suggestion },
|
|
153
|
+
...err.docUrl && { doc_url: err.docUrl }
|
|
153
154
|
},
|
|
154
155
|
meta
|
|
155
156
|
};
|
|
@@ -201,12 +202,34 @@ async function writeOutput(envelope) {
|
|
|
201
202
|
const provider = envelope.meta.provider ? dim(` (${envelope.meta.provider})`) : "";
|
|
202
203
|
const timing = envelope.meta.duration_ms != null ? dim(` ${envelope.meta.duration_ms}ms`) : "";
|
|
203
204
|
process.stderr.write(`${status}${provider}${timing}
|
|
204
|
-
|
|
205
205
|
`);
|
|
206
|
+
const receipt = [
|
|
207
|
+
envelope.meta.provider ? `provider=${envelope.meta.provider}` : void 0,
|
|
208
|
+
envelope.meta.source ? `source=${envelope.meta.source}` : void 0,
|
|
209
|
+
envelope.meta.origin_source ? `origin=${envelope.meta.origin_source}` : void 0,
|
|
210
|
+
envelope.meta.runtime_status ? `runtime=${envelope.meta.runtime_status}` : void 0,
|
|
211
|
+
envelope.meta.fetched_at ? `fetched=${envelope.meta.fetched_at}` : void 0,
|
|
212
|
+
envelope.meta.observed_at ? `observed=${envelope.meta.observed_at}` : void 0,
|
|
213
|
+
envelope.meta.cache_age_ms != null ? `cache_age_ms=${envelope.meta.cache_age_ms}` : void 0,
|
|
214
|
+
envelope.meta.cache_status ? `cache=${envelope.meta.cache_status}` : void 0,
|
|
215
|
+
envelope.meta.receipt_id ? `receipt=${envelope.meta.receipt_id}` : void 0
|
|
216
|
+
].filter((value) => Boolean(value));
|
|
217
|
+
if (receipt.length > 0) {
|
|
218
|
+
process.stderr.write(dim(`Evidence: ${receipt.join(" \xB7 ")}
|
|
219
|
+
`));
|
|
220
|
+
}
|
|
221
|
+
if (envelope.meta.truncated) {
|
|
222
|
+
process.stderr.write(yellow("Evidence warning: response was truncated.\n"));
|
|
223
|
+
}
|
|
224
|
+
for (const warning of envelope.meta.warnings ?? []) {
|
|
225
|
+
process.stderr.write(yellow(`Evidence warning: ${warning}
|
|
226
|
+
`));
|
|
227
|
+
}
|
|
228
|
+
process.stderr.write("\n");
|
|
206
229
|
}
|
|
207
230
|
if (envelope.ok && envelope.data != null) {
|
|
208
231
|
if (Array.isArray(envelope.data) && envelope.data.length > 0 && typeof envelope.data[0] === "object" && envelope.data[0] !== null) {
|
|
209
|
-
const { formatTable } = await import("./format-
|
|
232
|
+
const { formatTable } = await import("./format-H7FOQSYY.js");
|
|
210
233
|
process.stdout.write(
|
|
211
234
|
formatTable(envelope.data) + "\n"
|
|
212
235
|
);
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
executeRemoteTool
|
|
4
|
+
} from "./chunk-P7NLFSZQ.js";
|
|
5
|
+
import {
|
|
6
|
+
trackCommand
|
|
7
|
+
} from "./chunk-RU6QOFHH.js";
|
|
8
|
+
import {
|
|
9
|
+
debug,
|
|
10
|
+
dim,
|
|
11
|
+
shouldOutputJson,
|
|
12
|
+
writeOutput
|
|
13
|
+
} from "./chunk-725R3KLJ.js";
|
|
14
|
+
import {
|
|
15
|
+
resolveApiKey
|
|
16
|
+
} from "./chunk-6PC3HUAK.js";
|
|
17
|
+
|
|
18
|
+
// src/cli/execute.ts
|
|
19
|
+
import ora from "ora";
|
|
20
|
+
|
|
21
|
+
// src/cli/keyless-heroes.ts
|
|
22
|
+
var CHAIN_ID_TO_NAME = {
|
|
23
|
+
"1": "ethereum",
|
|
24
|
+
"10": "optimism",
|
|
25
|
+
"56": "bsc",
|
|
26
|
+
"137": "polygon",
|
|
27
|
+
"8453": "base",
|
|
28
|
+
"42161": "arbitrum",
|
|
29
|
+
"43114": "avalanche"
|
|
30
|
+
};
|
|
31
|
+
var ALCHEMY_NETWORK_TO_CHAIN = {
|
|
32
|
+
"eth-mainnet": "ethereum",
|
|
33
|
+
"opt-mainnet": "optimism",
|
|
34
|
+
"bnb-mainnet": "bsc",
|
|
35
|
+
"polygon-mainnet": "polygon",
|
|
36
|
+
"base-mainnet": "base",
|
|
37
|
+
"arb-mainnet": "arbitrum",
|
|
38
|
+
"avax-mainnet": "avalanche"
|
|
39
|
+
};
|
|
40
|
+
function firstListEntry(value) {
|
|
41
|
+
if (typeof value !== "string") return null;
|
|
42
|
+
const parts = value.split(",").map((part) => part.trim()).filter(Boolean);
|
|
43
|
+
return parts.length === 1 ? parts[0] : null;
|
|
44
|
+
}
|
|
45
|
+
function remapForKeylessHero(toolName, args) {
|
|
46
|
+
if (toolName === "get_price") {
|
|
47
|
+
const token = firstListEntry(args.ids);
|
|
48
|
+
if (!token) return null;
|
|
49
|
+
const vsCurrency = firstListEntry(args.vs_currencies) ?? "usd";
|
|
50
|
+
return {
|
|
51
|
+
tool: "get_token_price",
|
|
52
|
+
args: { token, vs_currency: vsCurrency },
|
|
53
|
+
note: "no API key \u2014 routed through the keyless get_token_price hero"
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (toolName === "get_token_security") {
|
|
57
|
+
const address = firstListEntry(args.contract_addresses);
|
|
58
|
+
if (!address) return null;
|
|
59
|
+
const chainId = typeof args.chain_id === "string" || typeof args.chain_id === "number" ? String(args.chain_id) : null;
|
|
60
|
+
const chain = chainId ? CHAIN_ID_TO_NAME[chainId] ?? chainId : void 0;
|
|
61
|
+
return {
|
|
62
|
+
tool: "check_token_safety",
|
|
63
|
+
args: chain ? { address, chain } : { address },
|
|
64
|
+
note: "no API key \u2014 routed through the keyless check_token_safety hero"
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
if (toolName === "alchemy_get_tokens_by_wallet") {
|
|
68
|
+
const address = typeof args.address === "string" && args.address.trim() ? args.address.trim() : null;
|
|
69
|
+
if (!address) return null;
|
|
70
|
+
const network = typeof args.network === "string" ? args.network.trim() : null;
|
|
71
|
+
const chain = network ? ALCHEMY_NETWORK_TO_CHAIN[network] : void 0;
|
|
72
|
+
return {
|
|
73
|
+
tool: "get_wallet_portfolio",
|
|
74
|
+
args: chain ? { address, chain } : { address },
|
|
75
|
+
note: "no API key \u2014 routed through the keyless get_wallet_portfolio hero"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// src/cli/execute.ts
|
|
82
|
+
async function executeTool(toolName, args, timeoutMs = 3e4) {
|
|
83
|
+
if (!resolveApiKey()) {
|
|
84
|
+
const remap = remapForKeylessHero(toolName, args);
|
|
85
|
+
if (remap) {
|
|
86
|
+
debug(remap.note);
|
|
87
|
+
toolName = remap.tool;
|
|
88
|
+
args = remap.args;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
debug(`Executing ${toolName} remotely`);
|
|
92
|
+
const showSpinner = !shouldOutputJson() && !!process.stderr.isTTY;
|
|
93
|
+
const spinner = showSpinner ? ora({ text: `Calling ${toolName}...`, stream: process.stderr }).start() : null;
|
|
94
|
+
const startMs = Date.now();
|
|
95
|
+
let response;
|
|
96
|
+
try {
|
|
97
|
+
response = await executeRemoteTool(toolName, args, timeoutMs);
|
|
98
|
+
spinner?.succeed(`${toolName} (${Date.now() - startMs}ms)`);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
spinner?.fail(`${toolName} failed (${Date.now() - startMs}ms)`);
|
|
101
|
+
throw err;
|
|
102
|
+
}
|
|
103
|
+
trackCommand(
|
|
104
|
+
toolName,
|
|
105
|
+
Date.now() - startMs,
|
|
106
|
+
response.ok ? void 0 : response.error?.code
|
|
107
|
+
);
|
|
108
|
+
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 \u2014 run \`hive auth login\` for a full key.`
|
|
114
|
+
) + "\n"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (!response.ok) {
|
|
118
|
+
const exitCode = response.error?.code === "TOOL_NOT_FOUND" ? 3 : response.error?.code === "PROVIDER_UNAVAILABLE" ? 5 : response.error?.code === "RATE_LIMITED" ? 6 : response.error?.code === "TIMEOUT" ? 124 : 4;
|
|
119
|
+
process.exit(exitCode);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
executeTool
|
|
125
|
+
};
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
getClaudeDesktopConfigPath,
|
|
4
|
+
getCodexConfigPath,
|
|
4
5
|
getCursorConfigPath,
|
|
5
6
|
getVscodeConfigPath
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QDZ7MAVN.js";
|
|
7
8
|
import {
|
|
8
9
|
HIVE_AGENT_SKILLS
|
|
9
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-L326MQZP.js";
|
|
10
11
|
|
|
11
12
|
// src/cli/detect-clients.ts
|
|
12
13
|
import { existsSync } from "fs";
|
|
@@ -24,6 +25,9 @@ function getGeminiCliConfigPath() {
|
|
|
24
25
|
function detectClaudeCode() {
|
|
25
26
|
return existsSync(getClaudeCodeConfigPath()) || existsSync(join(homedir(), ".claude"));
|
|
26
27
|
}
|
|
28
|
+
function detectCodex() {
|
|
29
|
+
return existsSync(join(homedir(), ".codex"));
|
|
30
|
+
}
|
|
27
31
|
function detectClaudeDesktop() {
|
|
28
32
|
const configPath = getClaudeDesktopConfigPath();
|
|
29
33
|
if (existsSync(configPath)) return true;
|
|
@@ -61,6 +65,7 @@ function detectGeminiCli() {
|
|
|
61
65
|
function detectClients() {
|
|
62
66
|
const claudeCode = detectClaudeCode();
|
|
63
67
|
const claudeDesktop = detectClaudeDesktop();
|
|
68
|
+
const codex = detectCodex();
|
|
64
69
|
const cursor = detectCursor();
|
|
65
70
|
const vscode = detectVscode();
|
|
66
71
|
const windsurf = detectWindsurf();
|
|
@@ -79,8 +84,16 @@ function detectClients() {
|
|
|
79
84
|
name: "Claude Desktop",
|
|
80
85
|
configPath: getClaudeDesktopConfigPath(),
|
|
81
86
|
detected: claudeDesktop,
|
|
87
|
+
programmable: false,
|
|
88
|
+
hint: claudeDesktop ? "Add the hosted endpoint in Settings > Connectors; the local config file is stdio-only" : "Claude Desktop application directory not found"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
id: "codex",
|
|
92
|
+
name: "OpenAI Codex",
|
|
93
|
+
configPath: getCodexConfigPath(),
|
|
94
|
+
detected: codex,
|
|
82
95
|
programmable: true,
|
|
83
|
-
hint:
|
|
96
|
+
hint: codex ? "Hive will use the official Codex MCP CLI and native OAuth login" : "~/.codex not found"
|
|
84
97
|
},
|
|
85
98
|
{
|
|
86
99
|
id: "cursor",
|
|
@@ -96,7 +109,7 @@ function detectClients() {
|
|
|
96
109
|
configPath: getVscodeConfigPath(),
|
|
97
110
|
detected: vscode,
|
|
98
111
|
programmable: true,
|
|
99
|
-
hint: vscode ?
|
|
112
|
+
hint: vscode ? "Hive will use the official code --add-mcp user-profile installer" : "VS Code user data dir not found"
|
|
100
113
|
},
|
|
101
114
|
{
|
|
102
115
|
id: "windsurf",
|
|
@@ -121,7 +134,15 @@ function detectClients() {
|
|
|
121
134
|
detected: false,
|
|
122
135
|
// No reliable filesystem signal — always print instructions
|
|
123
136
|
programmable: false,
|
|
124
|
-
hint: "
|
|
137
|
+
hint: "Create the Hive app manually in ChatGPT Settings > Apps, then complete OAuth."
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
id: "grok",
|
|
141
|
+
name: "Grok",
|
|
142
|
+
configPath: "https://grok.com/connectors",
|
|
143
|
+
detected: false,
|
|
144
|
+
programmable: false,
|
|
145
|
+
hint: "Add Hive manually at grok.com/connectors, then complete OAuth."
|
|
125
146
|
}
|
|
126
147
|
];
|
|
127
148
|
}
|
|
@@ -143,17 +164,20 @@ function getClientSkillsDir(client) {
|
|
|
143
164
|
switch (client) {
|
|
144
165
|
case "claude-code":
|
|
145
166
|
return join2(homedir2(), ".claude", "skills");
|
|
167
|
+
case "codex":
|
|
168
|
+
return join2(homedir2(), ".codex", "skills");
|
|
146
169
|
case "cursor":
|
|
147
170
|
return join2(homedir2(), ".cursor", "skills");
|
|
148
171
|
case "vscode":
|
|
149
|
-
return
|
|
172
|
+
return join2(homedir2(), ".copilot", "skills");
|
|
150
173
|
case "windsurf":
|
|
151
174
|
return null;
|
|
152
175
|
case "gemini-cli":
|
|
153
|
-
return
|
|
176
|
+
return join2(homedir2(), ".gemini", "skills");
|
|
154
177
|
case "claude-desktop":
|
|
155
178
|
return join2(homedir2(), ".claude", "skills");
|
|
156
179
|
case "chatgpt-desktop":
|
|
180
|
+
case "grok":
|
|
157
181
|
return null;
|
|
158
182
|
}
|
|
159
183
|
}
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { createRequire } from 'node:module'; const require = createRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// src/cli/browser-auth.ts
|
|
4
|
+
import { createServer } from "http";
|
|
5
|
+
import { randomBytes } from "crypto";
|
|
6
|
+
import { execFile } from "child_process";
|
|
7
|
+
import { platform } from "os";
|
|
8
|
+
var CLI_EXCHANGE_PATH = "/auth/cli/exchange";
|
|
9
|
+
var CLI_LOGIN_PATH = "/auth/cli";
|
|
10
|
+
var CLI_CALLBACK_PATH = "/callback";
|
|
11
|
+
function parseCliCallback(rawUrl, expectedState) {
|
|
12
|
+
const url = new URL(rawUrl, "http://localhost");
|
|
13
|
+
if (url.pathname !== CLI_CALLBACK_PATH) return { kind: "ignore" };
|
|
14
|
+
const returnedState = url.searchParams.get("state");
|
|
15
|
+
if (returnedState !== expectedState) return { kind: "state-mismatch" };
|
|
16
|
+
if (url.searchParams.get("key")) return { kind: "legacy-key" };
|
|
17
|
+
const code = url.searchParams.get("code");
|
|
18
|
+
if (!code) return { kind: "missing-code" };
|
|
19
|
+
return { kind: "code", code, state: returnedState };
|
|
20
|
+
}
|
|
21
|
+
function buildCliLoginUrl(baseUrl, port, state) {
|
|
22
|
+
const loginUrl = new URL(CLI_LOGIN_PATH, baseUrl);
|
|
23
|
+
loginUrl.searchParams.set("callback_port", String(port));
|
|
24
|
+
loginUrl.searchParams.set("state", state);
|
|
25
|
+
return loginUrl;
|
|
26
|
+
}
|
|
27
|
+
async function exchangeCliCode(args) {
|
|
28
|
+
const exchangeUrl = new URL(CLI_EXCHANGE_PATH, args.baseUrl);
|
|
29
|
+
const controller = new AbortController();
|
|
30
|
+
const timer = setTimeout(() => controller.abort(), 1e4);
|
|
31
|
+
try {
|
|
32
|
+
const response = await fetch(exchangeUrl, {
|
|
33
|
+
method: "POST",
|
|
34
|
+
headers: { "Content-Type": "application/json" },
|
|
35
|
+
body: JSON.stringify({ code: args.code, state: args.state }),
|
|
36
|
+
signal: controller.signal
|
|
37
|
+
});
|
|
38
|
+
if (!response.ok) {
|
|
39
|
+
throw new Error(`CLI auth exchange failed with HTTP ${response.status}`);
|
|
40
|
+
}
|
|
41
|
+
const payload = await response.json();
|
|
42
|
+
const key = typeof payload.key === "string" ? payload.key : typeof payload.api_key?.key === "string" ? payload.api_key.key : "";
|
|
43
|
+
if (!key) throw new Error("CLI auth exchange returned no API key.");
|
|
44
|
+
return {
|
|
45
|
+
key,
|
|
46
|
+
email: typeof payload.email === "string" ? payload.email : ""
|
|
47
|
+
};
|
|
48
|
+
} finally {
|
|
49
|
+
clearTimeout(timer);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function openBrowser(url) {
|
|
53
|
+
const plat = platform();
|
|
54
|
+
let cmd;
|
|
55
|
+
let args;
|
|
56
|
+
if (plat === "darwin") {
|
|
57
|
+
cmd = "open";
|
|
58
|
+
args = [url];
|
|
59
|
+
} else if (plat === "win32") {
|
|
60
|
+
cmd = "cmd";
|
|
61
|
+
args = ["/c", "start", "", url];
|
|
62
|
+
} else {
|
|
63
|
+
cmd = "xdg-open";
|
|
64
|
+
args = [url];
|
|
65
|
+
}
|
|
66
|
+
execFile(cmd, args, (err) => {
|
|
67
|
+
if (err) process.stderr.write(`
|
|
68
|
+
Open this URL manually:
|
|
69
|
+
${url}
|
|
70
|
+
|
|
71
|
+
`);
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
async function browserLogin(opts) {
|
|
75
|
+
const baseUrl = opts.baseUrl || "https://hiveintelligence.xyz";
|
|
76
|
+
const timeout = opts.timeout || 3e5;
|
|
77
|
+
const state = randomBytes(16).toString("hex");
|
|
78
|
+
return new Promise((resolve, reject) => {
|
|
79
|
+
let settled = false;
|
|
80
|
+
const server = createServer(async (req, res) => {
|
|
81
|
+
const outcome = parseCliCallback(req.url || "/", state);
|
|
82
|
+
if (outcome.kind === "ignore") {
|
|
83
|
+
res.writeHead(404);
|
|
84
|
+
res.end("Not found");
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (settled) {
|
|
88
|
+
res.writeHead(200);
|
|
89
|
+
res.end();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
if (outcome.kind === "state-mismatch") {
|
|
93
|
+
res.writeHead(403);
|
|
94
|
+
res.end("State mismatch \u2014 possible CSRF attack. Please try again.");
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (outcome.kind === "legacy-key") {
|
|
98
|
+
res.writeHead(400);
|
|
99
|
+
res.end(
|
|
100
|
+
"Insecure legacy callback rejected. Please update Hive auth and try again."
|
|
101
|
+
);
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
if (outcome.kind === "missing-code") {
|
|
105
|
+
res.writeHead(400);
|
|
106
|
+
res.end("Missing one-time code in callback");
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
settled = true;
|
|
110
|
+
let exchanged;
|
|
111
|
+
try {
|
|
112
|
+
exchanged = await exchangeCliCode({
|
|
113
|
+
baseUrl,
|
|
114
|
+
code: outcome.code,
|
|
115
|
+
state: outcome.state
|
|
116
|
+
});
|
|
117
|
+
} catch (error) {
|
|
118
|
+
clearTimeout(timer);
|
|
119
|
+
server.close();
|
|
120
|
+
res.writeHead(502);
|
|
121
|
+
res.end("Could not complete CLI auth exchange. Return to the terminal.");
|
|
122
|
+
reject(error);
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
res.writeHead(200, { "Content-Type": "text/html" });
|
|
126
|
+
res.end(`<!DOCTYPE html>
|
|
127
|
+
<html>
|
|
128
|
+
<head><title>Hive CLI \u2014 Authenticated</title>
|
|
129
|
+
<style>
|
|
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
|
+
.card { text-align: center; padding: 2rem; }
|
|
132
|
+
h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
|
|
133
|
+
p { color: #888; }
|
|
134
|
+
</style>
|
|
135
|
+
</head>
|
|
136
|
+
<body>
|
|
137
|
+
<div class="card">
|
|
138
|
+
<h1>Authenticated</h1>
|
|
139
|
+
<p>You can close this tab and return to the terminal.</p>
|
|
140
|
+
</div>
|
|
141
|
+
</body>
|
|
142
|
+
</html>`);
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
server.close();
|
|
145
|
+
resolve({
|
|
146
|
+
key: exchanged.key,
|
|
147
|
+
email: exchanged.email,
|
|
148
|
+
state: outcome.state
|
|
149
|
+
});
|
|
150
|
+
});
|
|
151
|
+
server.listen(0, "127.0.0.1", () => {
|
|
152
|
+
const addr = server.address();
|
|
153
|
+
if (!addr || typeof addr === "string") {
|
|
154
|
+
reject(new Error("Failed to start local server"));
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const port = addr.port;
|
|
158
|
+
const loginUrl = buildCliLoginUrl(baseUrl, port, state);
|
|
159
|
+
process.stderr.write(`
|
|
160
|
+
Opening browser to sign in...
|
|
161
|
+
`);
|
|
162
|
+
process.stderr.write(
|
|
163
|
+
`If the browser doesn't open, visit:
|
|
164
|
+
${loginUrl.toString()}
|
|
165
|
+
|
|
166
|
+
`
|
|
167
|
+
);
|
|
168
|
+
openBrowser(loginUrl.toString());
|
|
169
|
+
});
|
|
170
|
+
const timer = setTimeout(() => {
|
|
171
|
+
if (settled) return;
|
|
172
|
+
settled = true;
|
|
173
|
+
server.close();
|
|
174
|
+
reject(
|
|
175
|
+
new Error(
|
|
176
|
+
"Login timed out after 5 minutes. Run: hive auth login --manual"
|
|
177
|
+
)
|
|
178
|
+
);
|
|
179
|
+
}, timeout);
|
|
180
|
+
server.on("error", (err) => {
|
|
181
|
+
if (settled) return;
|
|
182
|
+
settled = true;
|
|
183
|
+
clearTimeout(timer);
|
|
184
|
+
reject(err);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export {
|
|
190
|
+
CLI_EXCHANGE_PATH,
|
|
191
|
+
CLI_LOGIN_PATH,
|
|
192
|
+
CLI_CALLBACK_PATH,
|
|
193
|
+
parseCliCallback,
|
|
194
|
+
buildCliLoginUrl,
|
|
195
|
+
exchangeCliCode,
|
|
196
|
+
browserLogin
|
|
197
|
+
};
|