@agentek/cli 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,558 @@
1
+ #!/usr/bin/env node
2
+ import { z } from 'zod';
3
+ import { isHex, http, zeroAddress } from 'viem';
4
+ import { mainnet, optimism, arbitrum, polygon, base } from 'viem/chains';
5
+ import { createAgentekClient } from '@agentek/tools/client';
6
+ import { allTools } from '@agentek/tools';
7
+ import { privateKeyToAccount } from 'viem/accounts';
8
+ import { zodToJsonSchema } from 'zod-to-json-schema';
9
+ import { existsSync, readFileSync, mkdirSync, writeFileSync, chmodSync } from 'fs';
10
+ import { homedir } from 'os';
11
+ import { join } from 'path';
12
+
13
+ var KNOWN_KEYS = [
14
+ { name: "PRIVATE_KEY", description: "Hex-encoded private key for signing transactions" },
15
+ { name: "ACCOUNT", description: "Hex address to use as the sender (read-only)" },
16
+ { name: "PERPLEXITY_API_KEY", description: "Perplexity AI search tools" },
17
+ { name: "ZEROX_API_KEY", description: "0x swap/quote tools" },
18
+ { name: "TALLY_API_KEY", description: "Tally governance tools" },
19
+ { name: "COINDESK_API_KEY", description: "CoinDesk news/data tools" },
20
+ { name: "COINMARKETCAL_API_KEY", description: "CoinMarketCal event tools" },
21
+ { name: "FIREWORKS_API_KEY", description: "Fireworks AI tools" },
22
+ { name: "PINATA_JWT", description: "Pinata IPFS tools" },
23
+ { name: "X_BEARER_TOKEN", description: "X/Twitter read tools (Bearer token)" },
24
+ { name: "X_API_KEY", description: "X/Twitter OAuth application key" },
25
+ { name: "X_API_KEY_SECRET", description: "X/Twitter OAuth application secret" },
26
+ { name: "X_ACCESS_TOKEN", description: "X/Twitter OAuth user access token" },
27
+ { name: "X_ACCESS_TOKEN_SECRET", description: "X/Twitter OAuth user access token secret" }
28
+ ];
29
+ var KNOWN_KEY_NAMES = new Set(KNOWN_KEYS.map((k) => k.name));
30
+ function defaultConfig() {
31
+ return { version: 1, keys: {} };
32
+ }
33
+ function getConfigDir() {
34
+ return process.env.AGENTEK_CONFIG_DIR || join(homedir(), ".agentek");
35
+ }
36
+ function getConfigPath() {
37
+ return join(getConfigDir(), "config.json");
38
+ }
39
+ function readConfig() {
40
+ const configPath = getConfigPath();
41
+ if (!existsSync(configPath)) return defaultConfig();
42
+ try {
43
+ const raw = readFileSync(configPath, "utf-8");
44
+ const parsed = JSON.parse(raw);
45
+ if (typeof parsed !== "object" || parsed === null) return defaultConfig();
46
+ return {
47
+ version: typeof parsed.version === "number" ? parsed.version : 1,
48
+ keys: typeof parsed.keys === "object" && parsed.keys !== null ? parsed.keys : {}
49
+ };
50
+ } catch {
51
+ return defaultConfig();
52
+ }
53
+ }
54
+ function writeConfig(config) {
55
+ const dir = getConfigDir();
56
+ if (!existsSync(dir)) {
57
+ mkdirSync(dir, { recursive: true, mode: 448 });
58
+ }
59
+ const configPath = getConfigPath();
60
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n", { mode: 384 });
61
+ chmodSync(configPath, 384);
62
+ }
63
+ function resolveAllKeys() {
64
+ const config = readConfig();
65
+ return KNOWN_KEYS.map((k) => {
66
+ const envVal = process.env[k.name];
67
+ if (envVal !== void 0 && envVal !== "") {
68
+ return { name: k.name, description: k.description, value: envVal, source: "env" };
69
+ }
70
+ const cfgVal = config.keys[k.name];
71
+ if (cfgVal !== void 0 && cfgVal !== "") {
72
+ return { name: k.name, description: k.description, value: cfgVal, source: "config" };
73
+ }
74
+ return { name: k.name, description: k.description, value: void 0, source: void 0 };
75
+ });
76
+ }
77
+ function resolveKeys() {
78
+ const resolved = resolveAllKeys();
79
+ const result = {};
80
+ for (const r of resolved) {
81
+ result[r.name] = r.value;
82
+ }
83
+ return result;
84
+ }
85
+ function isKnownKey(name) {
86
+ return KNOWN_KEY_NAMES.has(name);
87
+ }
88
+ function redactValue(value) {
89
+ if (value.length <= 8) return "****";
90
+ return value.slice(0, 4) + "..." + value.slice(-4);
91
+ }
92
+
93
+ // index.ts
94
+ var VERSION = "0.0.1";
95
+ var DEFAULT_TIMEOUT_MS = 12e4;
96
+ var KEY_GATED_TOOLS = {
97
+ askPerplexitySearch: ["PERPLEXITY_API_KEY"],
98
+ intent0xSwap: ["ZEROX_API_KEY"],
99
+ tallyProposals: ["TALLY_API_KEY"],
100
+ tallyChains: ["TALLY_API_KEY"],
101
+ tallyUserDaos: ["TALLY_API_KEY"],
102
+ intentGovernorVote: ["TALLY_API_KEY"],
103
+ intentGovernorVoteWithReason: ["TALLY_API_KEY"],
104
+ getLatestCoindeskNewsTool: ["COINDESK_API_KEY"],
105
+ getMarketEvents: ["COINMARKETCAL_API_KEY"],
106
+ generateAndPinImage: ["FIREWORKS_API_KEY", "PINATA_JWT"],
107
+ searchRecentTweets: ["X_BEARER_TOKEN"],
108
+ getTweetById: ["X_BEARER_TOKEN"],
109
+ getXUserByUsername: ["X_BEARER_TOKEN"],
110
+ getXUserTweets: ["X_BEARER_TOKEN"],
111
+ getHomeTimeline: ["X_API_KEY", "X_API_KEY_SECRET", "X_ACCESS_TOKEN", "X_ACCESS_TOKEN_SECRET"]
112
+ };
113
+ function withTimeout(promise, ms, label) {
114
+ return new Promise((resolve, reject) => {
115
+ const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);
116
+ promise.then(
117
+ (v) => {
118
+ clearTimeout(timer);
119
+ resolve(v);
120
+ },
121
+ (e) => {
122
+ clearTimeout(timer);
123
+ reject(e);
124
+ }
125
+ );
126
+ });
127
+ }
128
+ function bigintReplacer(_key, value) {
129
+ return typeof value === "bigint" ? value.toString() : value;
130
+ }
131
+ function outputJson(data) {
132
+ process.stdout.write(JSON.stringify(data, bigintReplacer, 2) + "\n");
133
+ process.exit(0);
134
+ }
135
+ function outputError(msg, opts) {
136
+ const payload = { error: msg };
137
+ if (opts?.code) payload.code = opts.code;
138
+ if (opts?.hint) payload.hint = opts.hint;
139
+ if (opts?.retryable !== void 0) payload.retryable = opts.retryable;
140
+ process.stderr.write(JSON.stringify(payload) + "\n");
141
+ process.exit(1);
142
+ }
143
+ function formatZodError(errMessage, toolName) {
144
+ const trimmed = errMessage.trim();
145
+ if (!trimmed.startsWith("[") && !trimmed.startsWith("{")) return void 0;
146
+ try {
147
+ const parsed = JSON.parse(trimmed);
148
+ const issues = Array.isArray(parsed) ? parsed : parsed?.name === "ZodError" && Array.isArray(parsed?.issues) ? parsed.issues : null;
149
+ if (!issues || issues.length === 0) return void 0;
150
+ if (!issues[0].code || !Array.isArray(issues[0].path)) return void 0;
151
+ const parts = issues.map((issue) => {
152
+ const path = issue.path.join(".") || "unknown";
153
+ const expected = issue.expected ? ` (expected ${issue.expected})` : "";
154
+ if (issue.code === "invalid_type" && issue.received === "undefined") {
155
+ return `Missing required parameter: ${path}${expected}`;
156
+ }
157
+ return `Invalid parameter "${path}": ${issue.message}${expected}`;
158
+ });
159
+ return {
160
+ message: parts.join("; "),
161
+ hint: `Run: agentek info ${toolName}`
162
+ };
163
+ } catch {
164
+ return void 0;
165
+ }
166
+ }
167
+ function formatChainError(errMessage, tool) {
168
+ if (!errMessage.toLowerCase().includes("not supported")) return void 0;
169
+ const chains = tool.supportedChains;
170
+ if (!chains || chains.length === 0) return void 0;
171
+ const chainList = chains.map((c) => `${c.name} (${c.id})`).join(", ");
172
+ return {
173
+ message: errMessage,
174
+ hint: `Supported chains: ${chainList}`
175
+ };
176
+ }
177
+ function printVersion() {
178
+ process.stdout.write(`${VERSION}
179
+ `);
180
+ process.exit(0);
181
+ }
182
+ function printUsage() {
183
+ process.stderr.write(`agentek v${VERSION} \u2014 CLI for Agentek tools
184
+
185
+ Usage:
186
+ agentek setup Show configuration status for all keys
187
+ agentek config set <KEY> <VALUE> Save a key to ~/.agentek/config.json
188
+ agentek config get <KEY> [--reveal] Show a key's value (redacted by default)
189
+ agentek config list List all known keys with status
190
+ agentek config delete <KEY> Remove a key from config
191
+ agentek list List all available tools
192
+ agentek search <keyword> Search tools by name or description
193
+ agentek info <tool-name> Show tool description and parameter schema
194
+ agentek exec <tool-name> [--key value] Execute a tool with the given parameters
195
+
196
+ Flags:
197
+ --key value Set a parameter (type-coerced via tool schema)
198
+ --key val --key v Repeated flags become arrays
199
+ --flag Boolean true (when schema expects boolean)
200
+ --json '{...}' Merge a JSON object into parameters
201
+ --timeout <ms> Override the default 120s tool execution timeout
202
+ --version, -v Print version number
203
+
204
+ Configuration:
205
+ Keys are stored in ~/.agentek/config.json (override with AGENTEK_CONFIG_DIR).
206
+ Environment variables always take precedence over config file values.
207
+ `);
208
+ process.exit(2);
209
+ }
210
+ function parseFlags(argv, schema) {
211
+ const result = {};
212
+ const shape = schema.shape;
213
+ let i = 0;
214
+ while (i < argv.length) {
215
+ const arg = argv[i];
216
+ if (!arg.startsWith("--")) {
217
+ i++;
218
+ continue;
219
+ }
220
+ let key;
221
+ let inlineValue;
222
+ const eqIdx = arg.indexOf("=", 2);
223
+ if (eqIdx !== -1) {
224
+ key = arg.slice(2, eqIdx);
225
+ inlineValue = arg.slice(eqIdx + 1);
226
+ } else {
227
+ key = arg.slice(2);
228
+ }
229
+ if (key === "json") {
230
+ const jsonStr = inlineValue ?? argv[++i];
231
+ if (jsonStr === void 0) outputError("--json requires a value");
232
+ try {
233
+ Object.assign(result, JSON.parse(jsonStr));
234
+ } catch {
235
+ outputError(`Invalid JSON for --json: ${jsonStr}`);
236
+ }
237
+ i++;
238
+ continue;
239
+ }
240
+ const fieldSchema = shape[key];
241
+ let rawValue = inlineValue;
242
+ if (rawValue === void 0) {
243
+ const next = argv[i + 1];
244
+ if (next !== void 0 && (!next.startsWith("--") || fieldSchema && isNumericSchema(fieldSchema) && /^--?\d/.test(next))) {
245
+ rawValue = next;
246
+ i++;
247
+ }
248
+ }
249
+ if (rawValue === void 0) {
250
+ result[key] = true;
251
+ i++;
252
+ continue;
253
+ }
254
+ const coerced = coerceValue(rawValue, fieldSchema);
255
+ if (fieldSchema && isArraySchema(fieldSchema)) {
256
+ const existing = result[key];
257
+ if (Array.isArray(existing)) {
258
+ existing.push(coerced);
259
+ } else {
260
+ result[key] = [coerced];
261
+ }
262
+ } else {
263
+ result[key] = coerced;
264
+ }
265
+ i++;
266
+ }
267
+ return result;
268
+ }
269
+ function isNumericSchema(schema) {
270
+ const inner = unwrapSchema(schema);
271
+ return inner instanceof z.ZodNumber;
272
+ }
273
+ function isArraySchema(schema) {
274
+ if (schema instanceof z.ZodArray) return true;
275
+ if (schema instanceof z.ZodOptional) return isArraySchema(schema.unwrap());
276
+ if (schema instanceof z.ZodDefault) return isArraySchema(schema.removeDefault());
277
+ return false;
278
+ }
279
+ function unwrapSchema(schema) {
280
+ if (schema instanceof z.ZodOptional) return unwrapSchema(schema.unwrap());
281
+ if (schema instanceof z.ZodDefault) return unwrapSchema(schema.removeDefault());
282
+ return schema;
283
+ }
284
+ function coerceValue(raw, schema) {
285
+ if (!schema) return raw;
286
+ let inner = unwrapSchema(schema);
287
+ if (inner instanceof z.ZodArray) {
288
+ inner = inner.element;
289
+ }
290
+ if (inner instanceof z.ZodNumber) {
291
+ const n = Number(raw);
292
+ if (!Number.isNaN(n)) return n;
293
+ return raw;
294
+ }
295
+ if (inner instanceof z.ZodBoolean) {
296
+ if (raw === "true" || raw === "1") return true;
297
+ if (raw === "false" || raw === "0") return false;
298
+ return raw;
299
+ }
300
+ return raw;
301
+ }
302
+ function levenshtein(a, b) {
303
+ const m = a.length;
304
+ const n = b.length;
305
+ const dp = Array.from({ length: n + 1 }, (_, i) => i);
306
+ for (let i = 1; i <= m; i++) {
307
+ let prev = dp[0];
308
+ dp[0] = i;
309
+ for (let j = 1; j <= n; j++) {
310
+ const tmp = dp[j];
311
+ dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);
312
+ prev = tmp;
313
+ }
314
+ }
315
+ return dp[n];
316
+ }
317
+ async function main() {
318
+ const args = process.argv.slice(2);
319
+ const command = args[0];
320
+ const rest = args.slice(1);
321
+ if (!command || command === "help" || command === "--help" || command === "-h") {
322
+ printUsage();
323
+ }
324
+ if (command === "--version" || command === "-v") {
325
+ printVersion();
326
+ }
327
+ if (!["list", "info", "exec", "search", "setup", "config"].includes(command)) {
328
+ printUsage();
329
+ }
330
+ if (command === "setup") {
331
+ const resolved = resolveAllKeys();
332
+ const configured = resolved.filter((r) => r.value !== void 0).length;
333
+ process.stderr.write(`agentek v${VERSION} \u2014 configuration status
334
+
335
+ `);
336
+ for (const r of resolved) {
337
+ const status = r.value ? `configured (${r.source})` : "missing";
338
+ const symbol = r.value ? "\u2713" : "\u2717";
339
+ process.stderr.write(` ${symbol} ${r.name.padEnd(26)} ${status.padEnd(20)} ${r.description}
340
+ `);
341
+ }
342
+ process.stderr.write(`
343
+ ${configured}/${resolved.length} keys configured
344
+ `);
345
+ process.exit(0);
346
+ }
347
+ if (command === "config") {
348
+ const sub = rest[0];
349
+ if (sub === "set") {
350
+ const key = rest[1];
351
+ const value = rest[2];
352
+ if (!key || value === void 0) outputError("Usage: agentek config set <KEY> <VALUE>");
353
+ if (!isKnownKey(key)) {
354
+ process.stderr.write(JSON.stringify({ warning: `${key} is not a known key` }) + "\n");
355
+ }
356
+ const config = readConfig();
357
+ config.keys[key] = value;
358
+ writeConfig(config);
359
+ outputJson({ ok: true, key });
360
+ } else if (sub === "get") {
361
+ const key = rest[1];
362
+ if (!key) outputError("Usage: agentek config get <KEY> [--reveal]");
363
+ const reveal = rest.includes("--reveal");
364
+ const config = readConfig();
365
+ const value = config.keys[key];
366
+ if (value === void 0) {
367
+ outputJson({ key, value: null });
368
+ } else {
369
+ outputJson({ key, value: reveal ? value : redactValue(value) });
370
+ }
371
+ } else if (sub === "list") {
372
+ const resolved = resolveAllKeys();
373
+ outputJson(resolved.map((r) => ({
374
+ key: r.name,
375
+ status: r.value ? "configured" : "missing",
376
+ source: r.source ?? null,
377
+ description: r.description
378
+ })));
379
+ } else if (sub === "delete") {
380
+ const key = rest[1];
381
+ if (!key) outputError("Usage: agentek config delete <KEY>");
382
+ const config = readConfig();
383
+ const existed = key in config.keys;
384
+ delete config.keys[key];
385
+ writeConfig(config);
386
+ outputJson({ ok: true, key, deleted: existed });
387
+ } else {
388
+ outputError("Usage: agentek config <set|get|list|delete>");
389
+ }
390
+ process.exit(0);
391
+ }
392
+ const keys = resolveKeys();
393
+ const PRIVATE_KEY = keys.PRIVATE_KEY;
394
+ const ACCOUNT = keys.ACCOUNT;
395
+ const PERPLEXITY_API_KEY = keys.PERPLEXITY_API_KEY;
396
+ const ZEROX_API_KEY = keys.ZEROX_API_KEY;
397
+ const TALLY_API_KEY = keys.TALLY_API_KEY;
398
+ const COINDESK_API_KEY = keys.COINDESK_API_KEY;
399
+ const COINMARKETCAL_API_KEY = keys.COINMARKETCAL_API_KEY;
400
+ const FIREWORKS_API_KEY = keys.FIREWORKS_API_KEY;
401
+ const PINATA_JWT = keys.PINATA_JWT;
402
+ const X_BEARER_TOKEN = keys.X_BEARER_TOKEN;
403
+ const X_API_KEY = keys.X_API_KEY;
404
+ const X_API_KEY_SECRET = keys.X_API_KEY_SECRET;
405
+ const X_ACCESS_TOKEN = keys.X_ACCESS_TOKEN;
406
+ const X_ACCESS_TOKEN_SECRET = keys.X_ACCESS_TOKEN_SECRET;
407
+ if (PRIVATE_KEY && !isHex(PRIVATE_KEY)) {
408
+ outputError("Invalid PRIVATE_KEY format, must be hex");
409
+ }
410
+ const chains = [mainnet, optimism, arbitrum, polygon, base];
411
+ const transports = chains.map(() => http());
412
+ const account = PRIVATE_KEY ? privateKeyToAccount(PRIVATE_KEY) : ACCOUNT && isHex(ACCOUNT) ? ACCOUNT : zeroAddress;
413
+ const agentekClient = createAgentekClient({
414
+ transports,
415
+ chains,
416
+ accountOrAddress: account,
417
+ tools: await allTools({
418
+ perplexityApiKey: PERPLEXITY_API_KEY,
419
+ zeroxApiKey: ZEROX_API_KEY,
420
+ tallyApiKey: TALLY_API_KEY,
421
+ coindeskApiKey: COINDESK_API_KEY,
422
+ coinMarketCalApiKey: COINMARKETCAL_API_KEY,
423
+ fireworksApiKey: FIREWORKS_API_KEY,
424
+ pinataJWT: PINATA_JWT,
425
+ xBearerToken: X_BEARER_TOKEN,
426
+ xApiKey: X_API_KEY,
427
+ xApiKeySecret: X_API_KEY_SECRET,
428
+ xAccessToken: X_ACCESS_TOKEN,
429
+ xAccessTokenSecret: X_ACCESS_TOKEN_SECRET
430
+ })
431
+ });
432
+ const toolsMap = agentekClient.getTools();
433
+ function suggestTool(input) {
434
+ const lower = input.toLowerCase();
435
+ let best;
436
+ let bestDist = Infinity;
437
+ for (const name of toolsMap.keys()) {
438
+ if (name.toLowerCase() === lower) return name;
439
+ const d = levenshtein(lower, name.toLowerCase());
440
+ if (d < bestDist) {
441
+ bestDist = d;
442
+ best = name;
443
+ }
444
+ }
445
+ if (best && bestDist <= Math.max(3, Math.floor(input.length * 0.4))) return best;
446
+ return void 0;
447
+ }
448
+ function unknownToolError(toolName) {
449
+ const requiredKeys = KEY_GATED_TOOLS[toolName];
450
+ if (requiredKeys) {
451
+ const keyList = requiredKeys.join(", ");
452
+ const setCommands = requiredKeys.map((k) => `agentek config set ${k} <value>`).join("\n ");
453
+ outputError(
454
+ `Tool "${toolName}" requires API key${requiredKeys.length > 1 ? "s" : ""}: ${keyList}`,
455
+ {
456
+ code: "MISSING_API_KEY",
457
+ hint: `Configure with:
458
+ ${setCommands}`,
459
+ retryable: true
460
+ }
461
+ );
462
+ }
463
+ const suggestion = suggestTool(toolName);
464
+ const hint = suggestion ? `Did you mean "${suggestion}"?` : void 0;
465
+ outputError(`Unknown tool: ${toolName}`, {
466
+ code: "UNKNOWN_TOOL",
467
+ hint
468
+ });
469
+ }
470
+ if (command === "list") {
471
+ const names = Array.from(toolsMap.keys()).sort();
472
+ outputJson(names);
473
+ }
474
+ if (command === "search") {
475
+ const keyword = rest[0];
476
+ if (!keyword) outputError("Usage: agentek search <keyword>");
477
+ const pattern = keyword.toLowerCase();
478
+ const matches = [];
479
+ for (const [name, tool] of toolsMap) {
480
+ if (name.toLowerCase().includes(pattern) || tool.description.toLowerCase().includes(pattern)) {
481
+ matches.push({ name, description: tool.description });
482
+ }
483
+ }
484
+ matches.sort((a, b) => a.name.localeCompare(b.name));
485
+ outputJson(matches);
486
+ }
487
+ if (command === "info") {
488
+ const toolName = rest[0];
489
+ if (!toolName) outputError("Usage: agentek info <tool-name>");
490
+ const tool = toolsMap.get(toolName);
491
+ if (!tool) unknownToolError(toolName);
492
+ outputJson({
493
+ name: tool.name,
494
+ description: tool.description,
495
+ parameters: zodToJsonSchema(tool.parameters),
496
+ supportedChains: tool.supportedChains?.map((c) => ({ id: c.id, name: c.name }))
497
+ });
498
+ }
499
+ if (command === "exec") {
500
+ const toolName = rest[0];
501
+ if (!toolName) outputError("Usage: agentek exec <tool-name> [--key value ...]");
502
+ const tool = toolsMap.get(toolName);
503
+ if (!tool) unknownToolError(toolName);
504
+ let timeoutMs = DEFAULT_TIMEOUT_MS;
505
+ const flagArgs = rest.slice(1);
506
+ const timeoutIdx = flagArgs.indexOf("--timeout");
507
+ if (timeoutIdx !== -1) {
508
+ const raw = flagArgs[timeoutIdx + 1];
509
+ const parsed = Number(raw);
510
+ if (!raw || Number.isNaN(parsed) || parsed <= 0) {
511
+ outputError("--timeout requires a positive number (milliseconds)");
512
+ }
513
+ timeoutMs = parsed;
514
+ flagArgs.splice(timeoutIdx, 2);
515
+ }
516
+ const flags = parseFlags(flagArgs, tool.parameters);
517
+ try {
518
+ const result = await withTimeout(
519
+ agentekClient.execute(toolName, flags),
520
+ timeoutMs,
521
+ toolName
522
+ );
523
+ outputJson(result);
524
+ } catch (err) {
525
+ const msg = err.message || String(err);
526
+ if (msg.includes("timed out after")) {
527
+ const doubled = timeoutMs * 2;
528
+ outputError(msg, {
529
+ code: "TIMEOUT",
530
+ hint: `Retry with a longer timeout: --timeout ${doubled}`,
531
+ retryable: true
532
+ });
533
+ }
534
+ const zodFormatted = formatZodError(msg, toolName);
535
+ if (zodFormatted) {
536
+ outputError(zodFormatted.message, {
537
+ code: "VALIDATION_ERROR",
538
+ hint: zodFormatted.hint,
539
+ retryable: true
540
+ });
541
+ }
542
+ const chainFormatted = formatChainError(msg, tool);
543
+ if (chainFormatted) {
544
+ outputError(chainFormatted.message, {
545
+ code: "CHAIN_NOT_SUPPORTED",
546
+ hint: chainFormatted.hint,
547
+ retryable: true
548
+ });
549
+ }
550
+ outputError(msg, { code: "EXECUTION_ERROR" });
551
+ }
552
+ }
553
+ }
554
+ main().catch((err) => {
555
+ outputError(err.message || String(err));
556
+ });
557
+ //# sourceMappingURL=index.mjs.map
558
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../config.ts","../index.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n// ── Known keys ──────────────────────────────────────────────────────────────\n\nexport interface KnownKey {\n name: string;\n description: string;\n}\n\nexport const KNOWN_KEYS: KnownKey[] = [\n { name: \"PRIVATE_KEY\", description: \"Hex-encoded private key for signing transactions\" },\n { name: \"ACCOUNT\", description: \"Hex address to use as the sender (read-only)\" },\n { name: \"PERPLEXITY_API_KEY\", description: \"Perplexity AI search tools\" },\n { name: \"ZEROX_API_KEY\", description: \"0x swap/quote tools\" },\n { name: \"TALLY_API_KEY\", description: \"Tally governance tools\" },\n { name: \"COINDESK_API_KEY\", description: \"CoinDesk news/data tools\" },\n { name: \"COINMARKETCAL_API_KEY\", description: \"CoinMarketCal event tools\" },\n { name: \"FIREWORKS_API_KEY\", description: \"Fireworks AI tools\" },\n { name: \"PINATA_JWT\", description: \"Pinata IPFS tools\" },\n { name: \"X_BEARER_TOKEN\", description: \"X/Twitter read tools (Bearer token)\" },\n { name: \"X_API_KEY\", description: \"X/Twitter OAuth application key\" },\n { name: \"X_API_KEY_SECRET\", description: \"X/Twitter OAuth application secret\" },\n { name: \"X_ACCESS_TOKEN\", description: \"X/Twitter OAuth user access token\" },\n { name: \"X_ACCESS_TOKEN_SECRET\", description: \"X/Twitter OAuth user access token secret\" },\n];\n\nconst KNOWN_KEY_NAMES = new Set(KNOWN_KEYS.map((k) => k.name));\n\n// ── Config file I/O ─────────────────────────────────────────────────────────\n\nexport interface AgentekConfig {\n version: number;\n keys: Record<string, string>;\n}\n\nfunction defaultConfig(): AgentekConfig {\n return { version: 1, keys: {} };\n}\n\nexport function getConfigDir(): string {\n return process.env.AGENTEK_CONFIG_DIR || join(homedir(), \".agentek\");\n}\n\nexport function getConfigPath(): string {\n return join(getConfigDir(), \"config.json\");\n}\n\nexport function readConfig(): AgentekConfig {\n const configPath = getConfigPath();\n if (!existsSync(configPath)) return defaultConfig();\n try {\n const raw = readFileSync(configPath, \"utf-8\");\n const parsed = JSON.parse(raw);\n if (typeof parsed !== \"object\" || parsed === null) return defaultConfig();\n return {\n version: typeof parsed.version === \"number\" ? parsed.version : 1,\n keys: typeof parsed.keys === \"object\" && parsed.keys !== null ? parsed.keys : {},\n };\n } catch {\n return defaultConfig();\n }\n}\n\nexport function writeConfig(config: AgentekConfig): void {\n const dir = getConfigDir();\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n const configPath = getConfigPath();\n writeFileSync(configPath, JSON.stringify(config, null, 2) + \"\\n\", { mode: 0o600 });\n chmodSync(configPath, 0o600);\n}\n\n// ── Key resolution ──────────────────────────────────────────────────────────\n\nexport interface ResolvedKey {\n name: string;\n description: string;\n value: string | undefined;\n source: \"env\" | \"config\" | undefined;\n}\n\nexport function resolveAllKeys(): ResolvedKey[] {\n const config = readConfig();\n return KNOWN_KEYS.map((k) => {\n const envVal = process.env[k.name];\n if (envVal !== undefined && envVal !== \"\") {\n return { name: k.name, description: k.description, value: envVal, source: \"env\" as const };\n }\n const cfgVal = config.keys[k.name];\n if (cfgVal !== undefined && cfgVal !== \"\") {\n return { name: k.name, description: k.description, value: cfgVal, source: \"config\" as const };\n }\n return { name: k.name, description: k.description, value: undefined, source: undefined };\n });\n}\n\n/** Resolve keys into a flat Record suitable for destructuring. */\nexport function resolveKeys(): Record<string, string | undefined> {\n const resolved = resolveAllKeys();\n const result: Record<string, string | undefined> = {};\n for (const r of resolved) {\n result[r.name] = r.value;\n }\n return result;\n}\n\n// ── Helpers ─────────────────────────────────────────────────────────────────\n\nexport function isKnownKey(name: string): boolean {\n return KNOWN_KEY_NAMES.has(name);\n}\n\nexport function redactValue(value: string): string {\n if (value.length <= 8) return \"****\";\n return value.slice(0, 4) + \"...\" + value.slice(-4);\n}\n","import { z } from \"zod\";\nimport { type Hex, http, isHex, zeroAddress } from \"viem\";\nimport { mainnet, optimism, arbitrum, polygon, base } from \"viem/chains\";\nimport { createAgentekClient, type BaseTool } from \"@agentek/tools/client\";\nimport { allTools } from \"@agentek/tools\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { zodToJsonSchema } from \"zod-to-json-schema\";\nimport {\n KNOWN_KEYS,\n readConfig,\n writeConfig,\n resolveKeys,\n resolveAllKeys,\n redactValue,\n isKnownKey,\n} from \"./config.js\";\n\nconst VERSION = \"0.0.1\";\nconst DEFAULT_TIMEOUT_MS = 120_000;\n\n/** Structured error codes for agent-friendly error classification. */\ntype ErrorCode =\n | \"UNKNOWN_TOOL\"\n | \"MISSING_API_KEY\"\n | \"VALIDATION_ERROR\"\n | \"CHAIN_NOT_SUPPORTED\"\n | \"TIMEOUT\"\n | \"EXECUTION_ERROR\"\n | \"INVALID_ARGS\";\n\n/**\n * Map of tool names that are only available when their API key(s) are configured.\n * When an unknown-tool error matches one of these, we surface a MISSING_API_KEY\n * error with a `config set` hint instead of a generic \"Unknown tool\" message.\n */\nconst KEY_GATED_TOOLS: Record<string, string[]> = {\n askPerplexitySearch: [\"PERPLEXITY_API_KEY\"],\n intent0xSwap: [\"ZEROX_API_KEY\"],\n tallyProposals: [\"TALLY_API_KEY\"],\n tallyChains: [\"TALLY_API_KEY\"],\n tallyUserDaos: [\"TALLY_API_KEY\"],\n intentGovernorVote: [\"TALLY_API_KEY\"],\n intentGovernorVoteWithReason: [\"TALLY_API_KEY\"],\n getLatestCoindeskNewsTool: [\"COINDESK_API_KEY\"],\n getMarketEvents: [\"COINMARKETCAL_API_KEY\"],\n generateAndPinImage: [\"FIREWORKS_API_KEY\", \"PINATA_JWT\"],\n searchRecentTweets: [\"X_BEARER_TOKEN\"],\n getTweetById: [\"X_BEARER_TOKEN\"],\n getXUserByUsername: [\"X_BEARER_TOKEN\"],\n getXUserTweets: [\"X_BEARER_TOKEN\"],\n getHomeTimeline: [\"X_API_KEY\", \"X_API_KEY_SECRET\", \"X_ACCESS_TOKEN\", \"X_ACCESS_TOKEN_SECRET\"],\n};\n\n/** Wrap a promise with a timeout. */\nfunction withTimeout<T>(promise: Promise<T>, ms: number, label: string): Promise<T> {\n return new Promise((resolve, reject) => {\n const timer = setTimeout(() => reject(new Error(`${label} timed out after ${ms}ms`)), ms);\n promise.then(\n (v) => { clearTimeout(timer); resolve(v); },\n (e) => { clearTimeout(timer); reject(e); },\n );\n });\n}\n\n/** JSON.stringify replacer that converts BigInt to string. */\nfunction bigintReplacer(_key: string, value: unknown): unknown {\n return typeof value === \"bigint\" ? value.toString() : value;\n}\n\n/** Write JSON to stdout and exit 0. */\nfunction outputJson(data: unknown): never {\n process.stdout.write(JSON.stringify(data, bigintReplacer, 2) + \"\\n\");\n process.exit(0);\n}\n\n/** Write JSON error to stderr and exit 1. */\nfunction outputError(\n msg: string,\n opts?: { code?: ErrorCode; hint?: string; retryable?: boolean },\n): never {\n const payload: Record<string, unknown> = { error: msg };\n if (opts?.code) payload.code = opts.code;\n if (opts?.hint) payload.hint = opts.hint;\n if (opts?.retryable !== undefined) payload.retryable = opts.retryable;\n process.stderr.write(JSON.stringify(payload) + \"\\n\");\n process.exit(1);\n}\n\n/**\n * Detect serialized ZodError JSON in an error message and format it into\n * a human-readable string with a hint to run `agentek info <tool>`.\n */\nfunction formatZodError(\n errMessage: string,\n toolName: string,\n): { message: string; hint: string } | undefined {\n // ZodError.message can be either:\n // - a JSON array of issues: [{\"code\":...,\"path\":...}]\n // - a JSON object: {\"issues\":[...],\"name\":\"ZodError\"}\n const trimmed = errMessage.trim();\n if (!trimmed.startsWith(\"[\") && !trimmed.startsWith(\"{\")) return undefined;\n try {\n const parsed = JSON.parse(trimmed);\n const issues = Array.isArray(parsed)\n ? parsed\n : (parsed?.name === \"ZodError\" && Array.isArray(parsed?.issues))\n ? parsed.issues\n : null;\n if (!issues || issues.length === 0) return undefined;\n // Verify it looks like Zod issues (must have `code` and `path`)\n if (!issues[0].code || !Array.isArray(issues[0].path)) return undefined;\n const parts = issues.map((issue: Record<string, unknown>) => {\n const path = (issue.path as string[]).join(\".\") || \"unknown\";\n const expected = issue.expected ? ` (expected ${issue.expected})` : \"\";\n if (issue.code === \"invalid_type\" && issue.received === \"undefined\") {\n return `Missing required parameter: ${path}${expected}`;\n }\n return `Invalid parameter \"${path}\": ${issue.message}${expected}`;\n });\n return {\n message: parts.join(\"; \"),\n hint: `Run: agentek info ${toolName}`,\n };\n } catch {\n return undefined;\n }\n}\n\n/**\n * Detect \"not supported\" chain errors and append the tool's supported chains.\n */\nfunction formatChainError(\n errMessage: string,\n tool: BaseTool,\n): { message: string; hint: string } | undefined {\n if (!errMessage.toLowerCase().includes(\"not supported\")) return undefined;\n const chains = tool.supportedChains;\n if (!chains || chains.length === 0) return undefined;\n const chainList = chains.map((c) => `${c.name} (${c.id})`).join(\", \");\n return {\n message: errMessage,\n hint: `Supported chains: ${chainList}`,\n };\n}\n\n/** Print version to stdout and exit 0. */\nfunction printVersion(): never {\n process.stdout.write(`${VERSION}\\n`);\n process.exit(0);\n}\n\n/** Print usage text to stderr and exit 2. */\nfunction printUsage(): never {\n process.stderr.write(`agentek v${VERSION} — CLI for Agentek tools\n\nUsage:\n agentek setup Show configuration status for all keys\n agentek config set <KEY> <VALUE> Save a key to ~/.agentek/config.json\n agentek config get <KEY> [--reveal] Show a key's value (redacted by default)\n agentek config list List all known keys with status\n agentek config delete <KEY> Remove a key from config\n agentek list List all available tools\n agentek search <keyword> Search tools by name or description\n agentek info <tool-name> Show tool description and parameter schema\n agentek exec <tool-name> [--key value] Execute a tool with the given parameters\n\nFlags:\n --key value Set a parameter (type-coerced via tool schema)\n --key val --key v Repeated flags become arrays\n --flag Boolean true (when schema expects boolean)\n --json '{...}' Merge a JSON object into parameters\n --timeout <ms> Override the default 120s tool execution timeout\n --version, -v Print version number\n\nConfiguration:\n Keys are stored in ~/.agentek/config.json (override with AGENTEK_CONFIG_DIR).\n Environment variables always take precedence over config file values.\n`);\n process.exit(2);\n}\n\n/**\n * Parse CLI flags into an object, using the tool's Zod schema for\n * type coercion and array detection.\n */\nfunction parseFlags(argv: string[], schema: z.ZodObject<any>): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n const shape = schema.shape;\n\n let i = 0;\n while (i < argv.length) {\n const arg = argv[i];\n\n if (!arg.startsWith(\"--\")) {\n i++;\n continue;\n }\n\n // Support both --key value and --key=value\n let key: string;\n let inlineValue: string | undefined;\n const eqIdx = arg.indexOf(\"=\", 2);\n if (eqIdx !== -1) {\n key = arg.slice(2, eqIdx);\n inlineValue = arg.slice(eqIdx + 1);\n } else {\n key = arg.slice(2);\n }\n\n // --json escape hatch: merge raw JSON into result\n if (key === \"json\") {\n const jsonStr = inlineValue ?? argv[++i];\n if (jsonStr === undefined) outputError(\"--json requires a value\");\n try {\n Object.assign(result, JSON.parse(jsonStr));\n } catch {\n outputError(`Invalid JSON for --json: ${jsonStr}`);\n }\n i++;\n continue;\n }\n\n const fieldSchema = shape[key];\n\n // Determine the value: inline (=) takes priority, then next arg\n let rawValue: string | undefined = inlineValue;\n if (rawValue === undefined) {\n const next = argv[i + 1];\n // Next arg is a value if it exists and is not a flag (or schema says number, allowing negatives)\n if (next !== undefined && (!next.startsWith(\"--\") || (fieldSchema && isNumericSchema(fieldSchema) && /^--?\\d/.test(next)))) {\n rawValue = next;\n i++; // consume the value arg\n }\n }\n\n if (rawValue === undefined) {\n // Boolean flag (no value)\n result[key] = true;\n i++;\n continue;\n }\n\n const coerced = coerceValue(rawValue, fieldSchema);\n\n // If the schema expects an array, accumulate values\n if (fieldSchema && isArraySchema(fieldSchema)) {\n const existing = result[key];\n if (Array.isArray(existing)) {\n existing.push(coerced);\n } else {\n result[key] = [coerced];\n }\n } else {\n result[key] = coerced;\n }\n\n i++;\n }\n\n return result;\n}\n\n/** Check if a Zod schema (possibly wrapped) expects a number. */\nfunction isNumericSchema(schema: z.ZodTypeAny): boolean {\n const inner = unwrapSchema(schema);\n return inner instanceof z.ZodNumber;\n}\n\n/** Check if a Zod schema (possibly wrapped in optional/default) is an array type. */\nfunction isArraySchema(schema: z.ZodTypeAny): boolean {\n if (schema instanceof z.ZodArray) return true;\n if (schema instanceof z.ZodOptional) return isArraySchema(schema.unwrap());\n if (schema instanceof z.ZodDefault) return isArraySchema(schema.removeDefault());\n return false;\n}\n\n/** Unwrap optional/default to get the inner schema. */\nfunction unwrapSchema(schema: z.ZodTypeAny): z.ZodTypeAny {\n if (schema instanceof z.ZodOptional) return unwrapSchema(schema.unwrap());\n if (schema instanceof z.ZodDefault) return unwrapSchema(schema.removeDefault());\n return schema;\n}\n\n/** Coerce a raw string value based on the Zod schema type. */\nfunction coerceValue(raw: string, schema?: z.ZodTypeAny): unknown {\n if (!schema) return raw;\n\n let inner = unwrapSchema(schema);\n\n // For arrays, coerce against the element type\n if (inner instanceof z.ZodArray) {\n inner = inner.element;\n }\n\n if (inner instanceof z.ZodNumber) {\n const n = Number(raw);\n if (!Number.isNaN(n)) return n;\n return raw;\n }\n\n if (inner instanceof z.ZodBoolean) {\n if (raw === \"true\" || raw === \"1\") return true;\n if (raw === \"false\" || raw === \"0\") return false;\n return raw;\n }\n\n // ZodEnum, ZodString, etc. — return as-is\n return raw;\n}\n\n/** Levenshtein distance between two strings. */\nfunction levenshtein(a: string, b: string): number {\n const m = a.length;\n const n = b.length;\n const dp: number[] = Array.from({ length: n + 1 }, (_, i) => i);\n for (let i = 1; i <= m; i++) {\n let prev = dp[0];\n dp[0] = i;\n for (let j = 1; j <= n; j++) {\n const tmp = dp[j];\n dp[j] = a[i - 1] === b[j - 1] ? prev : 1 + Math.min(prev, dp[j], dp[j - 1]);\n prev = tmp;\n }\n }\n return dp[n];\n}\n\nasync function main() {\n const args = process.argv.slice(2);\n const command = args[0];\n const rest = args.slice(1);\n\n if (!command || command === \"help\" || command === \"--help\" || command === \"-h\") {\n printUsage();\n }\n\n if (command === \"--version\" || command === \"-v\") {\n printVersion();\n }\n\n if (![\"list\", \"info\", \"exec\", \"search\", \"setup\", \"config\"].includes(command)) {\n printUsage();\n }\n\n // ── setup (short-circuits before allTools) ─────────────────────────────\n if (command === \"setup\") {\n const resolved = resolveAllKeys();\n const configured = resolved.filter((r) => r.value !== undefined).length;\n process.stderr.write(`agentek v${VERSION} — configuration status\\n\\n`);\n for (const r of resolved) {\n const status = r.value\n ? `configured (${r.source})`\n : \"missing\";\n const symbol = r.value ? \"✓\" : \"✗\";\n process.stderr.write(` ${symbol} ${r.name.padEnd(26)} ${status.padEnd(20)} ${r.description}\\n`);\n }\n process.stderr.write(`\\n ${configured}/${resolved.length} keys configured\\n`);\n process.exit(0);\n }\n\n // ── config (short-circuits before allTools) ────────────────────────────\n if (command === \"config\") {\n const sub = rest[0];\n\n if (sub === \"set\") {\n const key = rest[1];\n const value = rest[2];\n if (!key || value === undefined) outputError(\"Usage: agentek config set <KEY> <VALUE>\");\n if (!isKnownKey(key)) {\n process.stderr.write(JSON.stringify({ warning: `${key} is not a known key` }) + \"\\n\");\n }\n const config = readConfig();\n config.keys[key] = value;\n writeConfig(config);\n outputJson({ ok: true, key });\n } else if (sub === \"get\") {\n const key = rest[1];\n if (!key) outputError(\"Usage: agentek config get <KEY> [--reveal]\");\n const reveal = rest.includes(\"--reveal\");\n const config = readConfig();\n const value = config.keys[key];\n if (value === undefined) {\n outputJson({ key, value: null });\n } else {\n outputJson({ key, value: reveal ? value : redactValue(value) });\n }\n } else if (sub === \"list\") {\n const resolved = resolveAllKeys();\n outputJson(resolved.map((r) => ({\n key: r.name,\n status: r.value ? \"configured\" : \"missing\",\n source: r.source ?? null,\n description: r.description,\n })));\n } else if (sub === \"delete\") {\n const key = rest[1];\n if (!key) outputError(\"Usage: agentek config delete <KEY>\");\n const config = readConfig();\n const existed = key in config.keys;\n delete config.keys[key];\n writeConfig(config);\n outputJson({ ok: true, key, deleted: existed });\n } else {\n outputError(\"Usage: agentek config <set|get|list|delete>\");\n }\n\n process.exit(0);\n }\n\n // ── Environment (env vars override config file) ────────────────────────\n const keys = resolveKeys();\n const PRIVATE_KEY = keys.PRIVATE_KEY;\n const ACCOUNT = keys.ACCOUNT;\n const PERPLEXITY_API_KEY = keys.PERPLEXITY_API_KEY;\n const ZEROX_API_KEY = keys.ZEROX_API_KEY;\n const TALLY_API_KEY = keys.TALLY_API_KEY;\n const COINDESK_API_KEY = keys.COINDESK_API_KEY;\n const COINMARKETCAL_API_KEY = keys.COINMARKETCAL_API_KEY;\n const FIREWORKS_API_KEY = keys.FIREWORKS_API_KEY;\n const PINATA_JWT = keys.PINATA_JWT;\n const X_BEARER_TOKEN = keys.X_BEARER_TOKEN;\n const X_API_KEY = keys.X_API_KEY;\n const X_API_KEY_SECRET = keys.X_API_KEY_SECRET;\n const X_ACCESS_TOKEN = keys.X_ACCESS_TOKEN;\n const X_ACCESS_TOKEN_SECRET = keys.X_ACCESS_TOKEN_SECRET;\n\n if (PRIVATE_KEY && !isHex(PRIVATE_KEY)) {\n outputError(\"Invalid PRIVATE_KEY format, must be hex\");\n }\n\n // ── Blockchain setup ─────────────────────────────────────────────────\n const chains = [mainnet, optimism, arbitrum, polygon, base];\n const transports = chains.map(() => http());\n const account = PRIVATE_KEY\n ? privateKeyToAccount(PRIVATE_KEY as Hex)\n : (ACCOUNT && isHex(ACCOUNT) ? ACCOUNT as Hex : zeroAddress);\n\n // ── Agentek client ───────────────────────────────────────────────────\n const agentekClient = createAgentekClient({\n transports,\n chains,\n accountOrAddress: account,\n tools: await allTools({\n perplexityApiKey: PERPLEXITY_API_KEY,\n zeroxApiKey: ZEROX_API_KEY,\n tallyApiKey: TALLY_API_KEY,\n coindeskApiKey: COINDESK_API_KEY,\n coinMarketCalApiKey: COINMARKETCAL_API_KEY,\n fireworksApiKey: FIREWORKS_API_KEY,\n pinataJWT: PINATA_JWT,\n xBearerToken: X_BEARER_TOKEN,\n xApiKey: X_API_KEY,\n xApiKeySecret: X_API_KEY_SECRET,\n xAccessToken: X_ACCESS_TOKEN,\n xAccessTokenSecret: X_ACCESS_TOKEN_SECRET,\n }),\n });\n\n const toolsMap = agentekClient.getTools() as Map<string, BaseTool>;\n\n /** Find closest tool name match for \"did you mean?\" suggestions. */\n function suggestTool(input: string): string | undefined {\n const lower = input.toLowerCase();\n let best: string | undefined;\n let bestDist = Infinity;\n for (const name of toolsMap.keys()) {\n // Case-insensitive exact match\n if (name.toLowerCase() === lower) return name;\n // Levenshtein distance for close matches\n const d = levenshtein(lower, name.toLowerCase());\n if (d < bestDist) { bestDist = d; best = name; }\n }\n // Only suggest if reasonably close (max 3 edits or <40% of input length)\n if (best && bestDist <= Math.max(3, Math.floor(input.length * 0.4))) return best;\n return undefined;\n }\n\n /** Error with \"did you mean?\" hint for unknown tool names, or MISSING_API_KEY for key-gated tools. */\n function unknownToolError(toolName: string): never {\n const requiredKeys = KEY_GATED_TOOLS[toolName];\n if (requiredKeys) {\n const keyList = requiredKeys.join(\", \");\n const setCommands = requiredKeys.map((k) => `agentek config set ${k} <value>`).join(\"\\n \");\n outputError(\n `Tool \"${toolName}\" requires API key${requiredKeys.length > 1 ? \"s\" : \"\"}: ${keyList}`,\n {\n code: \"MISSING_API_KEY\",\n hint: `Configure with:\\n ${setCommands}`,\n retryable: true,\n },\n );\n }\n const suggestion = suggestTool(toolName);\n const hint = suggestion ? `Did you mean \"${suggestion}\"?` : undefined;\n outputError(`Unknown tool: ${toolName}`, {\n code: \"UNKNOWN_TOOL\",\n hint,\n });\n }\n\n // ── Commands ─────────────────────────────────────────────────────────\n\n if (command === \"list\") {\n const names = Array.from(toolsMap.keys()).sort();\n outputJson(names);\n }\n\n if (command === \"search\") {\n const keyword = rest[0];\n if (!keyword) outputError(\"Usage: agentek search <keyword>\");\n\n const pattern = keyword.toLowerCase();\n const matches: { name: string; description: string }[] = [];\n for (const [name, tool] of toolsMap) {\n if (\n name.toLowerCase().includes(pattern) ||\n tool.description.toLowerCase().includes(pattern)\n ) {\n matches.push({ name, description: tool.description });\n }\n }\n matches.sort((a, b) => a.name.localeCompare(b.name));\n outputJson(matches);\n }\n\n if (command === \"info\") {\n const toolName = rest[0];\n if (!toolName) outputError(\"Usage: agentek info <tool-name>\");\n\n const tool = toolsMap.get(toolName);\n if (!tool) unknownToolError(toolName);\n\n outputJson({\n name: tool!.name,\n description: tool!.description,\n parameters: zodToJsonSchema(tool!.parameters),\n supportedChains: tool!.supportedChains?.map((c) => ({ id: c.id, name: c.name })),\n });\n }\n\n if (command === \"exec\") {\n const toolName = rest[0];\n if (!toolName) outputError(\"Usage: agentek exec <tool-name> [--key value ...]\");\n\n const tool = toolsMap.get(toolName);\n if (!tool) unknownToolError(toolName);\n\n // Extract --timeout before parsing tool flags\n let timeoutMs = DEFAULT_TIMEOUT_MS;\n const flagArgs = rest.slice(1);\n const timeoutIdx = flagArgs.indexOf(\"--timeout\");\n if (timeoutIdx !== -1) {\n const raw = flagArgs[timeoutIdx + 1];\n const parsed = Number(raw);\n if (!raw || Number.isNaN(parsed) || parsed <= 0) {\n outputError(\"--timeout requires a positive number (milliseconds)\");\n }\n timeoutMs = parsed;\n flagArgs.splice(timeoutIdx, 2);\n }\n\n const flags = parseFlags(flagArgs, tool!.parameters);\n\n try {\n const result = await withTimeout(\n agentekClient.execute(toolName, flags),\n timeoutMs,\n toolName,\n );\n outputJson(result);\n } catch (err: any) {\n const msg: string = err.message || String(err);\n\n // ── Timeout errors ──────────────────────────────────────────────\n if (msg.includes(\"timed out after\")) {\n const doubled = timeoutMs * 2;\n outputError(msg, {\n code: \"TIMEOUT\",\n hint: `Retry with a longer timeout: --timeout ${doubled}`,\n retryable: true,\n });\n }\n\n // ── Zod validation errors ───────────────────────────────────────\n const zodFormatted = formatZodError(msg, toolName);\n if (zodFormatted) {\n outputError(zodFormatted.message, {\n code: \"VALIDATION_ERROR\",\n hint: zodFormatted.hint,\n retryable: true,\n });\n }\n\n // ── Chain not-supported errors ──────────────────────────────────\n const chainFormatted = formatChainError(msg, tool!);\n if (chainFormatted) {\n outputError(chainFormatted.message, {\n code: \"CHAIN_NOT_SUPPORTED\",\n hint: chainFormatted.hint,\n retryable: true,\n });\n }\n\n // ── Generic execution error ─────────────────────────────────────\n outputError(msg, { code: \"EXECUTION_ERROR\" });\n }\n }\n}\n\nmain().catch((err) => {\n outputError(err.message || String(err));\n});\n"]}
package/man/agentek.1 ADDED
@@ -0,0 +1,215 @@
1
+ .TH AGENTEK 1 "2026-02-26" "agentek 0.1.26" "Agentek CLI Manual"
2
+ .SH NAME
3
+ agentek \- CLI for blockchain and data tools
4
+ .SH SYNOPSIS
5
+ .B agentek
6
+ .BR setup
7
+ .br
8
+ .B agentek
9
+ .BR config " " \fIset|get|list|delete\fR " " [\fIargs ...\fR]
10
+ .br
11
+ .B agentek
12
+ .BR list
13
+ .br
14
+ .B agentek
15
+ .BR search " " \fIkeyword\fR
16
+ .br
17
+ .B agentek
18
+ .BR info " " \fItool-name\fR
19
+ .br
20
+ .B agentek
21
+ .BR exec " " \fItool-name\fR " " [\fI--key value ...\fR]
22
+ .br
23
+ .B agentek
24
+ .BR --version | -v
25
+ .SH DESCRIPTION
26
+ .B agentek
27
+ is a command-line interface that exposes 150+ blockchain and data tools as simple shell commands. Each tool has a typed parameter schema, accepts flags, and returns structured JSON on stdout.
28
+ .PP
29
+ Supported chains include Ethereum, Optimism, Arbitrum, Polygon, and Base.
30
+ .SH COMMANDS
31
+ .TP
32
+ .B setup
33
+ Print a human-readable status table showing all known API keys and whether each is configured (from environment or config file) or missing. Exits 0.
34
+ .TP
35
+ .BI config " set KEY VALUE"
36
+ Save
37
+ .I KEY
38
+ with
39
+ .I VALUE
40
+ to the config file. Prints JSON
41
+ .IR "{ ok, key }" .
42
+ .TP
43
+ .BI config " get KEY" " [--reveal]"
44
+ Print the config file value for
45
+ .IR KEY .
46
+ The value is redacted unless
47
+ .B --reveal
48
+ is given.
49
+ .TP
50
+ .B config list
51
+ Print a JSON array of all known keys with their status, source, and description.
52
+ .TP
53
+ .BI config " delete KEY"
54
+ Remove
55
+ .I KEY
56
+ from the config file. Prints JSON
57
+ .IR "{ ok, key, deleted }" .
58
+ .TP
59
+ .B list
60
+ Print a sorted JSON array of all available tool names to stdout.
61
+ .TP
62
+ .BI search " keyword"
63
+ Search tools by name or description (case-insensitive). Returns a sorted JSON array of
64
+ .RI "{ name, description }"
65
+ objects.
66
+ .TP
67
+ .BI info " tool-name"
68
+ Print a JSON object with the tool's name, description, parameter schema (JSON Schema), and supported chains.
69
+ .TP
70
+ .BI exec " tool-name" " [--key value ...]"
71
+ Execute the named tool with the given parameters and print the JSON result to stdout.
72
+ .SH FLAGS
73
+ .TP
74
+ .BI --key " value"
75
+ Set parameter
76
+ .I key
77
+ to
78
+ .IR value .
79
+ Values are coerced to the type expected by the tool's schema (number, boolean, string).
80
+ .TP
81
+ .BI --key = value
82
+ Inline form, equivalent to
83
+ .BI --key " value" .
84
+ .TP
85
+ .BI --key " v1" " --key" " v2"
86
+ Repeated flags for the same key produce an array
87
+ .IR [v1,\ v2] .
88
+ .TP
89
+ .B --flag
90
+ Boolean true when the schema expects a boolean.
91
+ .TP
92
+ .BI --json " '{...}'"
93
+ Merge a raw JSON object into the parameters.
94
+ .TP
95
+ .BI --timeout " ms"
96
+ Override the default 120-second tool execution timeout (value in milliseconds).
97
+ .TP
98
+ .BR --version ", " -v
99
+ Print the version number to stdout and exit.
100
+ .SH ENVIRONMENT
101
+ .TP
102
+ .B PRIVATE_KEY
103
+ Hex-encoded private key for signing transactions.
104
+ .TP
105
+ .B ACCOUNT
106
+ Hex address to use as the sender (read-only, no signing).
107
+ .TP
108
+ .B PERPLEXITY_API_KEY
109
+ API key for Perplexity AI search tools.
110
+ .TP
111
+ .B ZEROX_API_KEY
112
+ API key for 0x swap and quote tools.
113
+ .TP
114
+ .B TALLY_API_KEY
115
+ API key for Tally governance tools.
116
+ .TP
117
+ .B COINDESK_API_KEY
118
+ API key for CoinDesk news and data tools.
119
+ .TP
120
+ .B COINMARKETCAL_API_KEY
121
+ API key for CoinMarketCal event tools.
122
+ .TP
123
+ .B FIREWORKS_API_KEY
124
+ API key for Fireworks AI tools.
125
+ .TP
126
+ .B PINATA_JWT
127
+ JWT for Pinata IPFS tools.
128
+ .TP
129
+ .B X_BEARER_TOKEN
130
+ Bearer token for X/Twitter read tools.
131
+ .TP
132
+ .B X_API_KEY
133
+ X/Twitter OAuth application key.
134
+ .TP
135
+ .B X_API_KEY_SECRET
136
+ X/Twitter OAuth application secret.
137
+ .TP
138
+ .B X_ACCESS_TOKEN
139
+ X/Twitter OAuth user access token.
140
+ .TP
141
+ .B X_ACCESS_TOKEN_SECRET
142
+ X/Twitter OAuth user access token secret.
143
+ .SH CONFIGURATION
144
+ API keys can be persisted in
145
+ .B ~/.agentek/config.json
146
+ using the
147
+ .B config
148
+ subcommand. The directory is created with mode 0700 and the file with mode 0600.
149
+ .PP
150
+ Override the config directory by setting
151
+ .BR AGENTEK_CONFIG_DIR .
152
+ .PP
153
+ Environment variables always take precedence over config file values.
154
+ .SH EXIT CODES
155
+ .TP
156
+ .B 0
157
+ Success.
158
+ .TP
159
+ .B 1
160
+ Runtime error (tool execution failed, invalid input, or timeout).
161
+ .TP
162
+ .B 2
163
+ Usage error (unknown command, missing arguments).
164
+ .SH EXAMPLES
165
+ List all available tools:
166
+ .PP
167
+ .RS
168
+ .nf
169
+ agentek list
170
+ .fi
171
+ .RE
172
+ .PP
173
+ Search for balance-related tools:
174
+ .PP
175
+ .RS
176
+ .nf
177
+ agentek search balance
178
+ .fi
179
+ .RE
180
+ .PP
181
+ Inspect a tool's schema:
182
+ .PP
183
+ .RS
184
+ .nf
185
+ agentek info getBalance
186
+ .fi
187
+ .RE
188
+ .PP
189
+ Get the latest block number on Ethereum:
190
+ .PP
191
+ .RS
192
+ .nf
193
+ agentek exec getBlockNumber --chainId 1
194
+ .fi
195
+ .RE
196
+ .PP
197
+ Check an address's ETH balance:
198
+ .PP
199
+ .RS
200
+ .nf
201
+ agentek exec getBalance --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --chainId 1
202
+ .fi
203
+ .RE
204
+ .PP
205
+ Resolve an ENS name:
206
+ .PP
207
+ .RS
208
+ .nf
209
+ agentek exec getEnsAddress --name vitalik.eth --chainId 1
210
+ .fi
211
+ .RE
212
+ .SH SEE ALSO
213
+ .UR https://github.com/NaniDAO/agentek
214
+ Agentek on GitHub
215
+ .UE
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@agentek/cli",
3
+ "version": "0.0.1",
4
+ "description": "Command-line interface for Agentek tools",
5
+ "license": "AGPL-3.0",
6
+ "author": "NaniDAO",
7
+ "homepage": "https://nani.ooo",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/NaniDAO/agentek.git"
11
+ },
12
+ "type": "module",
13
+ "bin": {
14
+ "agentek": "dist/index.mjs"
15
+ },
16
+ "man": "./man/agentek.1",
17
+ "files": [
18
+ "dist",
19
+ "man",
20
+ "skill"
21
+ ],
22
+ "scripts": {
23
+ "build": "rm -rf dist && tsup",
24
+ "dev": "tsup --watch",
25
+ "start": "node dist/index.mjs"
26
+ },
27
+ "dependencies": {
28
+ "@agentek/tools": "workspace:^",
29
+ "viem": "^2.33.2",
30
+ "zod": "^3.25.76",
31
+ "zod-to-json-schema": "^3.24.5",
32
+ "zrouter-sdk": "^0.0.27"
33
+ },
34
+ "devDependencies": {
35
+ "@types/node": "^22.14.1",
36
+ "typescript": "^5.9.2"
37
+ },
38
+ "keywords": [
39
+ "ai",
40
+ "agents",
41
+ "blockchain",
42
+ "cli",
43
+ "tools"
44
+ ],
45
+ "engines": {
46
+ "node": ">=18.17.0"
47
+ }
48
+ }
@@ -0,0 +1,189 @@
1
+ ---
2
+ name: agentek-cli
3
+ description: Invoke any of 150+ blockchain and data tools from the shell using
4
+ the agentek CLI. Use this skill when the user wants to query blockchain data,
5
+ check token balances, resolve ENS names, get gas prices, fetch DeFi yields,
6
+ search tweets, or interact with any on-chain protocol across EVM chains
7
+ (Ethereum, Base, Arbitrum, Optimism, Polygon).
8
+ license: AGPL-3.0
9
+ compatibility: Requires Node.js >= 18.17.0 and npx or global install of @agentek/cli
10
+ metadata:
11
+ author: NaniDAO
12
+ version: "1.0"
13
+ ---
14
+
15
+ # agentek CLI
16
+
17
+ ## Overview
18
+
19
+ Agentek is a command-line interface that exposes 150+ blockchain and data tools as simple shell commands. Each tool has a typed schema, accepts flags, and returns structured JSON on stdout.
20
+
21
+ Install globally or run via npx:
22
+
23
+ ```bash
24
+ # Global install
25
+ npm install -g @agentek/cli
26
+
27
+ # Or run directly
28
+ npx @agentek/cli <command>
29
+ ```
30
+
31
+ ## Commands
32
+
33
+ ### Setup and configuration
34
+
35
+ Check which API keys are configured:
36
+
37
+ ```bash
38
+ agentek setup
39
+ ```
40
+
41
+ Save a key to the config file (`~/.agentek/config.json`):
42
+
43
+ ```bash
44
+ agentek config set PERPLEXITY_API_KEY pplx-xxxxxxxxxxxx
45
+ ```
46
+
47
+ View a saved key (redacted by default):
48
+
49
+ ```bash
50
+ agentek config get PERPLEXITY_API_KEY
51
+ agentek config get PERPLEXITY_API_KEY --reveal
52
+ ```
53
+
54
+ List all known keys with their status:
55
+
56
+ ```bash
57
+ agentek config list
58
+ ```
59
+
60
+ Remove a key from the config:
61
+
62
+ ```bash
63
+ agentek config delete PERPLEXITY_API_KEY
64
+ ```
65
+
66
+ Environment variables always take precedence over config file values.
67
+
68
+ ### Tool discovery and execution
69
+
70
+ The CLI follows a discovery workflow: **list** / **search** -> **info** -> **exec**.
71
+
72
+ ### 1. List all tools
73
+
74
+ ```bash
75
+ agentek list
76
+ ```
77
+
78
+ Returns a sorted JSON array of every available tool name.
79
+
80
+ ### 2. Search for tools
81
+
82
+ ```bash
83
+ agentek search balance
84
+ # [{"name":"getBalance","description":"..."},{"name":"getTokenBalance","description":"..."}]
85
+ ```
86
+
87
+ Searches tool names and descriptions (case-insensitive).
88
+
89
+ ### 3. Inspect a tool
90
+
91
+ ```bash
92
+ agentek info <tool-name>
93
+ ```
94
+
95
+ Returns a JSON object with the tool's `name`, `description`, `parameters` (JSON Schema), and `supportedChains`.
96
+
97
+ ### 4. Execute a tool
98
+
99
+ ```bash
100
+ agentek exec <tool-name> [--key value ...]
101
+ ```
102
+
103
+ Runs the tool with the given parameters and prints the JSON result to stdout.
104
+
105
+ ## Flag syntax
106
+
107
+ | Form | Meaning |
108
+ |------|---------|
109
+ | `--key value` | Set parameter `key` to `value` |
110
+ | `--key=value` | Same, inline form |
111
+ | `--key v1 --key v2` | Repeated flags become an array `[v1, v2]` |
112
+ | `--flag` | Boolean `true` (when schema expects boolean) |
113
+ | `--json '{"k":"v"}'` | Merge a raw JSON object into the parameters |
114
+ | `--timeout <ms>` | Override the default 120s tool execution timeout |
115
+
116
+ Values are automatically coerced to the type expected by the tool's schema (number, boolean, string).
117
+
118
+ ## Output contract
119
+
120
+ - **stdout** — Always valid JSON (the tool result or a JSON array for `list`).
121
+ - **stderr** — JSON object `{"error": "message"}` on failure.
122
+ - **Exit codes:**
123
+ - `0` — Success
124
+ - `1` — Runtime error (tool failed, invalid input, timeout)
125
+ - `2` — Usage error (bad command, missing arguments)
126
+
127
+ ## Environment variables
128
+
129
+ Set these before running commands that need them:
130
+
131
+ | Variable | Purpose |
132
+ |----------|---------|
133
+ | `PRIVATE_KEY` | Hex-encoded private key for signing transactions |
134
+ | `ACCOUNT` | Hex address to use as the sender (read-only, no signing) |
135
+ | `PERPLEXITY_API_KEY` | Perplexity AI search tools |
136
+ | `ZEROX_API_KEY` | 0x swap/quote tools |
137
+ | `TALLY_API_KEY` | Tally governance tools |
138
+ | `COINDESK_API_KEY` | CoinDesk news/data tools |
139
+ | `COINMARKETCAL_API_KEY` | CoinMarketCal event tools |
140
+ | `FIREWORKS_API_KEY` | Fireworks AI tools |
141
+ | `PINATA_JWT` | Pinata IPFS tools |
142
+ | `X_BEARER_TOKEN` | X/Twitter read tools |
143
+ | `X_API_KEY` | X/Twitter OAuth app key |
144
+ | `X_API_KEY_SECRET` | X/Twitter OAuth app secret |
145
+ | `X_ACCESS_TOKEN` | X/Twitter OAuth user access token |
146
+ | `X_ACCESS_TOKEN_SECRET` | X/Twitter OAuth user access token secret |
147
+
148
+ ## Examples
149
+
150
+ List all available tools:
151
+
152
+ ```bash
153
+ agentek list
154
+ # ["getBalance","getBlock","getBlockNumber",...]
155
+ ```
156
+
157
+ Inspect a tool before using it:
158
+
159
+ ```bash
160
+ agentek info getBalance
161
+ # { "name": "getBalance", "description": "...", "parameters": {...}, "supportedChains": [...] }
162
+ ```
163
+
164
+ Get the latest block number on Ethereum mainnet:
165
+
166
+ ```bash
167
+ agentek exec getBlockNumber --chainId 1
168
+ # { "blockNumber": "21547832" }
169
+ ```
170
+
171
+ Check an address's ETH balance:
172
+
173
+ ```bash
174
+ agentek exec getBalance --address 0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045 --chainId 1
175
+ ```
176
+
177
+ Resolve an ENS name:
178
+
179
+ ```bash
180
+ agentek exec getEnsAddress --name vitalik.eth --chainId 1
181
+ ```
182
+
183
+ ## Tips
184
+
185
+ - Always run `agentek info <tool>` before `exec` to see required parameters and their types.
186
+ - Use `--chainId` to target a specific chain. Common chain IDs: `1` (Ethereum), `10` (Optimism), `42161` (Arbitrum), `137` (Polygon), `8453` (Base).
187
+ - Tools that write on-chain require `PRIVATE_KEY`. Read-only tools work without it.
188
+ - Pipe output to `jq` for filtering: `agentek exec getBalance --address 0x... | jq '.balance'`.
189
+ - The CLI times out after 120 seconds per tool execution.