@tpmjs/cli 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +18 -0
  3. package/bin/run.js +0 -0
  4. package/dist/commands/agent/chat.js +75 -9
  5. package/dist/commands/agent/chat.js.map +1 -1
  6. package/dist/commands/agent/create.js +74 -8
  7. package/dist/commands/agent/create.js.map +1 -1
  8. package/dist/commands/agent/delete.js +77 -9
  9. package/dist/commands/agent/delete.js.map +1 -1
  10. package/dist/commands/agent/list.js +74 -8
  11. package/dist/commands/agent/list.js.map +1 -1
  12. package/dist/commands/agent/update.js +74 -8
  13. package/dist/commands/agent/update.js.map +1 -1
  14. package/dist/commands/auth/login.js +96 -19
  15. package/dist/commands/auth/login.js.map +1 -1
  16. package/dist/commands/auth/logout.js +20 -4
  17. package/dist/commands/auth/logout.js.map +1 -1
  18. package/dist/commands/auth/status.js +80 -11
  19. package/dist/commands/auth/status.js.map +1 -1
  20. package/dist/commands/auth/whoami.js +74 -8
  21. package/dist/commands/auth/whoami.js.map +1 -1
  22. package/dist/commands/collection/add.js +74 -8
  23. package/dist/commands/collection/add.js.map +1 -1
  24. package/dist/commands/collection/create.js +74 -8
  25. package/dist/commands/collection/create.js.map +1 -1
  26. package/dist/commands/collection/delete.js +75 -9
  27. package/dist/commands/collection/delete.js.map +1 -1
  28. package/dist/commands/collection/import.js +75 -9
  29. package/dist/commands/collection/import.js.map +1 -1
  30. package/dist/commands/collection/info.d.ts +17 -0
  31. package/dist/commands/collection/info.js +358 -0
  32. package/dist/commands/collection/info.js.map +1 -0
  33. package/dist/commands/collection/list.js +74 -8
  34. package/dist/commands/collection/list.js.map +1 -1
  35. package/dist/commands/collection/remove.js +75 -11
  36. package/dist/commands/collection/remove.js.map +1 -1
  37. package/dist/commands/collection/update.js +74 -8
  38. package/dist/commands/collection/update.js.map +1 -1
  39. package/dist/commands/doctor.js +75 -9
  40. package/dist/commands/doctor.js.map +1 -1
  41. package/dist/commands/mcp/config.js +20 -4
  42. package/dist/commands/mcp/config.js.map +1 -1
  43. package/dist/commands/mcp/serve.js +75 -9
  44. package/dist/commands/mcp/serve.js.map +1 -1
  45. package/dist/commands/playground.js +75 -9
  46. package/dist/commands/playground.js.map +1 -1
  47. package/dist/commands/publish/check.js +79 -13
  48. package/dist/commands/publish/check.js.map +1 -1
  49. package/dist/commands/publish/preview.js +20 -4
  50. package/dist/commands/publish/preview.js.map +1 -1
  51. package/dist/commands/run.d.ts +24 -0
  52. package/dist/commands/run.js +454 -0
  53. package/dist/commands/run.js.map +1 -0
  54. package/dist/commands/scenario/generate.d.ts +19 -0
  55. package/dist/commands/scenario/generate.js +633 -0
  56. package/dist/commands/scenario/generate.js.map +1 -0
  57. package/dist/commands/scenario/info.d.ts +18 -0
  58. package/dist/commands/scenario/info.js +636 -0
  59. package/dist/commands/scenario/info.js.map +1 -0
  60. package/dist/commands/scenario/list.d.ts +20 -0
  61. package/dist/commands/scenario/list.js +652 -0
  62. package/dist/commands/scenario/list.js.map +1 -0
  63. package/dist/commands/scenario/run.d.ts +18 -0
  64. package/dist/commands/scenario/run.js +663 -0
  65. package/dist/commands/scenario/run.js.map +1 -0
  66. package/dist/commands/scenario/test.d.ts +17 -0
  67. package/dist/commands/scenario/test.js +620 -0
  68. package/dist/commands/scenario/test.js.map +1 -0
  69. package/dist/commands/tool/execute.js +77 -9
  70. package/dist/commands/tool/execute.js.map +1 -1
  71. package/dist/commands/tool/info.js +84 -11
  72. package/dist/commands/tool/info.js.map +1 -1
  73. package/dist/commands/tool/init.js +23 -13
  74. package/dist/commands/tool/init.js.map +1 -1
  75. package/dist/commands/tool/search.js +75 -13
  76. package/dist/commands/tool/search.js.map +1 -1
  77. package/dist/commands/tool/trending.js +74 -8
  78. package/dist/commands/tool/trending.js.map +1 -1
  79. package/dist/commands/tool/validate.js +83 -11
  80. package/dist/commands/tool/validate.js.map +1 -1
  81. package/dist/commands/update.js +20 -4
  82. package/dist/commands/update.js.map +1 -1
  83. package/dist/hooks/init.js +1 -1
  84. package/dist/hooks/init.js.map +1 -1
  85. package/dist/index.d.ts +80 -0
  86. package/dist/index.js +74 -8
  87. package/dist/index.js.map +1 -1
  88. package/oclif.manifest.json +435 -1
  89. package/package.json +13 -12
@@ -0,0 +1,454 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import * as fs from 'fs';
3
+ import * as os from 'os';
4
+ import * as path from 'path';
5
+ import Conf from 'conf';
6
+ import Table from 'cli-table3';
7
+ import ora from 'ora';
8
+ import pc from 'picocolors';
9
+
10
+ // src/commands/run.ts
11
+ var CONFIG_DIR = path.join(os.homedir(), ".tpmjs");
12
+ var CREDENTIALS_FILE = path.join(CONFIG_DIR, "credentials.json");
13
+ path.join(CONFIG_DIR, "history");
14
+ function ensureConfigDir() {
15
+ if (!fs.existsSync(CONFIG_DIR)) {
16
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 448 });
17
+ }
18
+ }
19
+ var configStore = new Conf({
20
+ projectName: "tpmjs",
21
+ cwd: CONFIG_DIR,
22
+ configName: "config",
23
+ defaults: {
24
+ apiUrl: "https://tpmjs.com/api",
25
+ defaultOutput: "human",
26
+ verbose: false,
27
+ analytics: false
28
+ }
29
+ });
30
+ function getConfigValue(key) {
31
+ return configStore.get(key);
32
+ }
33
+ function loadCredentials() {
34
+ ensureConfigDir();
35
+ if (!fs.existsSync(CREDENTIALS_FILE)) {
36
+ return null;
37
+ }
38
+ try {
39
+ const content = fs.readFileSync(CREDENTIALS_FILE, "utf-8");
40
+ return JSON.parse(content);
41
+ } catch {
42
+ return null;
43
+ }
44
+ }
45
+ function getApiKey() {
46
+ if (process.env.TPMJS_API_KEY) {
47
+ return process.env.TPMJS_API_KEY;
48
+ }
49
+ const creds = loadCredentials();
50
+ if (creds?.apiKey) {
51
+ return creds.apiKey;
52
+ }
53
+ return void 0;
54
+ }
55
+ function getApiUrl() {
56
+ return process.env.TPMJS_API_URL ?? getConfigValue("apiUrl") ?? "https://tpmjs.com/api";
57
+ }
58
+ var OutputFormatter = class {
59
+ options;
60
+ constructor(options = {}) {
61
+ this.options = options;
62
+ }
63
+ // Output as JSON
64
+ json(data) {
65
+ console.log(JSON.stringify(data, null, 2));
66
+ }
67
+ // Output a table
68
+ table(data, columns) {
69
+ if (this.options.json) {
70
+ this.json(data);
71
+ return;
72
+ }
73
+ const table = new Table({
74
+ head: columns.map((col) => pc.bold(col.header)),
75
+ colWidths: columns.map((col) => col.width ?? null),
76
+ style: {
77
+ head: [],
78
+ border: []
79
+ }
80
+ });
81
+ for (const row of data) {
82
+ table.push(columns.map((col) => String(row[col.key] ?? "")));
83
+ }
84
+ console.log(table.toString());
85
+ }
86
+ // Success message
87
+ success(message) {
88
+ if (this.options.json) return;
89
+ console.log(pc.green("\u2713"), message);
90
+ }
91
+ // Error message
92
+ error(message, details) {
93
+ if (this.options.json) {
94
+ this.json({ error: message, details });
95
+ return;
96
+ }
97
+ console.error(pc.red("\u2717"), message);
98
+ if (details && this.options.verbose) {
99
+ console.error(pc.dim(details));
100
+ }
101
+ }
102
+ // Warning message
103
+ warning(message) {
104
+ if (this.options.json) return;
105
+ console.log(pc.yellow("\u26A0"), message);
106
+ }
107
+ // Info message
108
+ info(message) {
109
+ if (this.options.json) return;
110
+ console.log(pc.blue("\u2139"), message);
111
+ }
112
+ // Debug message (only in verbose mode)
113
+ debug(message) {
114
+ if (this.options.json) return;
115
+ if (this.options.verbose) {
116
+ console.log(pc.dim(`[debug] ${message}`));
117
+ }
118
+ }
119
+ // Plain text output
120
+ text(message) {
121
+ if (this.options.json) return;
122
+ console.log(message);
123
+ }
124
+ // Heading
125
+ heading(text) {
126
+ if (this.options.json) return;
127
+ console.log();
128
+ console.log(pc.bold(pc.underline(text)));
129
+ console.log();
130
+ }
131
+ // Subheading
132
+ subheading(text) {
133
+ if (this.options.json) return;
134
+ console.log(pc.bold(text));
135
+ }
136
+ // Key-value pair
137
+ keyValue(key, value) {
138
+ if (this.options.json) return;
139
+ console.log(`${pc.dim(`${key}:`)} ${value ?? pc.dim("(not set)")}`);
140
+ }
141
+ // List item
142
+ listItem(text, indent = 0) {
143
+ if (this.options.json) return;
144
+ const prefix = `${" ".repeat(indent)}\u2022`;
145
+ console.log(`${prefix} ${text}`);
146
+ }
147
+ // Spinner
148
+ spinner(message) {
149
+ return ora({
150
+ text: message,
151
+ isSilent: this.options.json
152
+ }).start();
153
+ }
154
+ // Blank line
155
+ newLine() {
156
+ if (this.options.json) return;
157
+ console.log();
158
+ }
159
+ // Horizontal rule
160
+ hr() {
161
+ if (this.options.json) return;
162
+ console.log(pc.dim("\u2500".repeat(50)));
163
+ }
164
+ // Alias for hr
165
+ divider() {
166
+ this.hr();
167
+ }
168
+ // Code block
169
+ code(text, language) {
170
+ if (this.options.json) {
171
+ this.json({ code: text, language });
172
+ return;
173
+ }
174
+ console.log(pc.dim(`\`\`\`${language ?? ""}`));
175
+ console.log(text);
176
+ console.log(pc.dim("```"));
177
+ }
178
+ // Highlight text
179
+ highlight(text) {
180
+ return pc.cyan(text);
181
+ }
182
+ // Dim text
183
+ dim(text) {
184
+ return pc.dim(text);
185
+ }
186
+ // Bold text
187
+ bold(text) {
188
+ return pc.bold(text);
189
+ }
190
+ // Link (just returns text in terminal)
191
+ link(text, url) {
192
+ return `\x1B]8;;${url}\x07${pc.underline(pc.blue(text))}\x1B]8;;\x07`;
193
+ }
194
+ // Color helpers
195
+ green(text) {
196
+ return pc.green(text);
197
+ }
198
+ red(text) {
199
+ return pc.red(text);
200
+ }
201
+ yellow(text) {
202
+ return pc.yellow(text);
203
+ }
204
+ blue(text) {
205
+ return pc.blue(text);
206
+ }
207
+ cyan(text) {
208
+ return pc.cyan(text);
209
+ }
210
+ };
211
+ function createOutput(flags) {
212
+ return new OutputFormatter({
213
+ json: flags.json,
214
+ verbose: flags.verbose
215
+ });
216
+ }
217
+
218
+ // src/commands/run.ts
219
+ function parseCollection(collection) {
220
+ const parts = collection.split("/");
221
+ if (parts.length !== 2) return null;
222
+ const [username, slug] = parts;
223
+ if (!username || !slug) return null;
224
+ return { username, slug };
225
+ }
226
+ function parseToolArgs(argsStr) {
227
+ try {
228
+ return JSON.parse(argsStr);
229
+ } catch {
230
+ return null;
231
+ }
232
+ }
233
+ function buildEnvVars(envFlags, output) {
234
+ const envVars = {};
235
+ for (const [key, value] of Object.entries(process.env)) {
236
+ if (value && (key.endsWith("_API_KEY") || key.endsWith("_TOKEN") || key.endsWith("_SECRET"))) {
237
+ envVars[key] = value;
238
+ }
239
+ }
240
+ if (envFlags) {
241
+ for (const envPair of envFlags) {
242
+ const [key, ...valueParts] = envPair.split("=");
243
+ if (key && valueParts.length > 0) {
244
+ envVars[key] = valueParts.join("=");
245
+ } else {
246
+ output.warning(`Invalid env var format: ${envPair}. Use: KEY=value`);
247
+ }
248
+ }
249
+ }
250
+ return envVars;
251
+ }
252
+ function displayVerboseInfo(output, mcpUrl, tool, toolArgs, envVars) {
253
+ output.info(`MCP Endpoint: ${mcpUrl}`);
254
+ output.info(`Tool: ${tool}`);
255
+ output.info(`Arguments: ${JSON.stringify(toolArgs, null, 2)}`);
256
+ if (Object.keys(envVars).length > 0) {
257
+ output.info(`Environment: ${Object.keys(envVars).join(", ")}`);
258
+ }
259
+ output.divider();
260
+ }
261
+ async function handleHttpError(response, output) {
262
+ const errorText = await response.text();
263
+ try {
264
+ const errorJson = JSON.parse(errorText);
265
+ output.error(errorJson.error?.message || errorJson.message || `HTTP ${response.status}`);
266
+ } catch {
267
+ output.error(`HTTP ${response.status}: ${errorText}`);
268
+ }
269
+ }
270
+ function displayContent(result, output) {
271
+ if (!result) {
272
+ output.text("(empty result)");
273
+ return;
274
+ }
275
+ if (result.content && Array.isArray(result.content)) {
276
+ for (const item of result.content) {
277
+ displayContentItem(item, output);
278
+ }
279
+ } else {
280
+ output.text(JSON.stringify(result, null, 2));
281
+ }
282
+ }
283
+ function displayContentItem(item, output) {
284
+ if (item.type === "text") {
285
+ try {
286
+ const parsed = JSON.parse(item.text);
287
+ output.text(JSON.stringify(parsed, null, 2));
288
+ } catch {
289
+ output.text(item.text);
290
+ }
291
+ } else if (item.type === "image") {
292
+ output.info("[Image content]");
293
+ } else {
294
+ output.text(JSON.stringify(item, null, 2));
295
+ }
296
+ }
297
+ function handleExecutionError(error, flags, output) {
298
+ if (error instanceof Error) {
299
+ if (error.name === "AbortError") {
300
+ output.error(`Request timed out after ${flags.timeout} seconds`);
301
+ } else {
302
+ output.error(error.message);
303
+ }
304
+ } else {
305
+ output.error("Unknown error occurred");
306
+ }
307
+ if (flags.verbose) {
308
+ output.info(`Full error: ${String(error)}`);
309
+ }
310
+ }
311
+ var Run = class _Run extends Command {
312
+ static description = "Execute a tool from a collection via MCP";
313
+ static examples = [
314
+ {
315
+ description: "First, list all tools in a collection",
316
+ command: "<%= config.bin %> collection info ajax/unsandbox"
317
+ },
318
+ {
319
+ description: "Execute Python code in the unsandbox collection",
320
+ command: `<%= config.bin %> run -c ajax/unsandbox -t unsandbox--execute --args '{"language":"python","code":"print(42)"}'`
321
+ },
322
+ {
323
+ description: "Pass environment variables for tool authentication",
324
+ command: `<%= config.bin %> run -c ajax/unsandbox -t unsandbox--execute -e UNSANDBOX_PUBLIC_KEY=xxx -e UNSANDBOX_SECRET_KEY=xxx --args '{"language":"python","code":"print(1)"}'`
325
+ },
326
+ {
327
+ description: "Output result as JSON",
328
+ command: `<%= config.bin %> run -c ajax/tools -t search --args '{"query":"test"}' --json`
329
+ },
330
+ {
331
+ description: "Show verbose output for debugging",
332
+ command: "<%= config.bin %> run -c ajax/unsandbox -t unsandbox--healthCheck --args '{}' -v"
333
+ }
334
+ ];
335
+ static flags = {
336
+ collection: Flags.string({
337
+ char: "c",
338
+ description: "Collection identifier (username/slug)",
339
+ required: true
340
+ }),
341
+ tool: Flags.string({
342
+ char: "t",
343
+ description: "Tool name (MCP format: package--toolName)",
344
+ required: true
345
+ }),
346
+ args: Flags.string({
347
+ char: "a",
348
+ description: "Tool arguments as JSON string",
349
+ default: "{}"
350
+ }),
351
+ env: Flags.string({
352
+ char: "e",
353
+ description: "Environment variables (key=value)",
354
+ multiple: true
355
+ }),
356
+ json: Flags.boolean({
357
+ description: "Output result as JSON",
358
+ default: false
359
+ }),
360
+ verbose: Flags.boolean({
361
+ char: "v",
362
+ description: "Show verbose output",
363
+ default: false
364
+ }),
365
+ timeout: Flags.integer({
366
+ description: "Request timeout in seconds",
367
+ default: 60
368
+ })
369
+ };
370
+ async run() {
371
+ const { flags } = await this.parse(_Run);
372
+ const output = createOutput(flags);
373
+ const collection = parseCollection(flags.collection);
374
+ if (!collection) {
375
+ output.error("Invalid collection format. Use: username/slug");
376
+ return;
377
+ }
378
+ const toolArgs = parseToolArgs(flags.args);
379
+ if (!toolArgs) {
380
+ output.error("Invalid JSON in --args flag");
381
+ return;
382
+ }
383
+ const envVars = buildEnvVars(flags.env, output);
384
+ const baseUrl = getApiUrl().replace(/\/api$/, "");
385
+ const mcpUrl = `${baseUrl}/api/mcp/${collection.username}/${collection.slug}/http`;
386
+ const apiKey = getApiKey();
387
+ if (!apiKey) {
388
+ output.warning("No API key configured. Some operations may fail.");
389
+ output.warning("Run `tpm auth login` to authenticate.");
390
+ }
391
+ if (flags.verbose) {
392
+ displayVerboseInfo(output, mcpUrl, flags.tool, toolArgs, envVars);
393
+ }
394
+ await this.executeToolCall(flags, output, mcpUrl, apiKey, toolArgs, envVars);
395
+ }
396
+ async executeToolCall(flags, output, mcpUrl, apiKey, toolArgs, envVars) {
397
+ const jsonRpcRequest = {
398
+ jsonrpc: "2.0",
399
+ id: Date.now(),
400
+ method: "tools/call",
401
+ params: {
402
+ name: flags.tool,
403
+ arguments: toolArgs,
404
+ ...Object.keys(envVars).length > 0 ? { env: envVars } : {}
405
+ }
406
+ };
407
+ const spinner = output.spinner(`Executing ${flags.tool}...`);
408
+ try {
409
+ const controller = new AbortController();
410
+ const timeoutId = setTimeout(() => controller.abort(), flags.timeout * 1e3);
411
+ const response = await fetch(mcpUrl, {
412
+ method: "POST",
413
+ headers: {
414
+ "Content-Type": "application/json",
415
+ ...apiKey ? { Authorization: `Bearer ${apiKey}` } : {}
416
+ },
417
+ body: JSON.stringify(jsonRpcRequest),
418
+ signal: controller.signal
419
+ });
420
+ clearTimeout(timeoutId);
421
+ if (!response.ok) {
422
+ spinner.fail("Request failed");
423
+ await handleHttpError(response, output);
424
+ return;
425
+ }
426
+ const result = await response.json();
427
+ spinner.stop();
428
+ this.handleResult(flags, output, result);
429
+ } catch (error) {
430
+ spinner.fail("Execution failed");
431
+ handleExecutionError(error, flags, output);
432
+ }
433
+ }
434
+ handleResult(flags, output, result) {
435
+ if (result.error) {
436
+ output.error(`Tool execution failed: ${result.error.message}`);
437
+ if (flags.verbose && result.error.data) {
438
+ output.info(`Error data: ${JSON.stringify(result.error.data, null, 2)}`);
439
+ }
440
+ return;
441
+ }
442
+ if (flags.json) {
443
+ output.json(result.result);
444
+ return;
445
+ }
446
+ output.success("Tool execution complete");
447
+ output.divider();
448
+ displayContent(result.result, output);
449
+ }
450
+ };
451
+
452
+ export { Run as default };
453
+ //# sourceMappingURL=run.js.map
454
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/lib/config.ts","../../src/lib/output.ts","../../src/commands/run.ts"],"names":[],"mappings":"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","file":"run.js","sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport Conf from 'conf';\n\nexport interface TpmConfig {\n apiUrl?: string;\n defaultOutput?: 'human' | 'json';\n verbose?: boolean;\n analytics?: boolean;\n env?: Record<string, string>;\n}\n\nexport interface TpmCredentials {\n apiKey?: string;\n refreshToken?: string;\n expiresAt?: string;\n}\n\nconst CONFIG_DIR = path.join(os.homedir(), '.tpmjs');\nconst CREDENTIALS_FILE = path.join(CONFIG_DIR, 'credentials.json');\nconst HISTORY_DIR = path.join(CONFIG_DIR, 'history');\n\n// Ensure config directory exists\nfunction ensureConfigDir(): void {\n if (!fs.existsSync(CONFIG_DIR)) {\n fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });\n }\n}\n\n// Config store using Conf\nconst configStore = new Conf<TpmConfig>({\n projectName: 'tpmjs',\n cwd: CONFIG_DIR,\n configName: 'config',\n defaults: {\n apiUrl: 'https://tpmjs.com/api',\n defaultOutput: 'human',\n verbose: false,\n analytics: false,\n },\n});\n\nexport function getConfig(): TpmConfig {\n return configStore.store;\n}\n\nexport function setConfig(config: Partial<TpmConfig>): void {\n for (const [key, value] of Object.entries(config)) {\n if (value !== undefined) {\n configStore.set(key, value);\n }\n }\n}\n\nexport function getConfigValue<K extends keyof TpmConfig>(key: K): TpmConfig[K] {\n return configStore.get(key);\n}\n\nexport function setConfigValue<K extends keyof TpmConfig>(key: K, value: TpmConfig[K]): void {\n configStore.set(key, value);\n}\n\nexport function resetConfig(): void {\n configStore.clear();\n}\n\n// Credentials management with secure file permissions\nexport function loadCredentials(): TpmCredentials | null {\n ensureConfigDir();\n\n if (!fs.existsSync(CREDENTIALS_FILE)) {\n return null;\n }\n\n try {\n const content = fs.readFileSync(CREDENTIALS_FILE, 'utf-8');\n return JSON.parse(content) as TpmCredentials;\n } catch {\n return null;\n }\n}\n\nexport function saveCredentials(credentials: TpmCredentials): void {\n ensureConfigDir();\n\n const content = JSON.stringify(credentials, null, 2);\n fs.writeFileSync(CREDENTIALS_FILE, content, { mode: 0o600 });\n}\n\nexport function deleteCredentials(): void {\n if (fs.existsSync(CREDENTIALS_FILE)) {\n fs.unlinkSync(CREDENTIALS_FILE);\n }\n}\n\nexport function hasCredentials(): boolean {\n const creds = loadCredentials();\n return creds !== null && !!creds.apiKey;\n}\n\n// Get API key from multiple sources (priority order)\nexport function getApiKey(): string | undefined {\n // 1. Environment variable\n if (process.env.TPMJS_API_KEY) {\n return process.env.TPMJS_API_KEY;\n }\n\n // 2. Credentials file\n const creds = loadCredentials();\n if (creds?.apiKey) {\n return creds.apiKey;\n }\n\n return undefined;\n}\n\n// Get API URL\nexport function getApiUrl(): string {\n return process.env.TPMJS_API_URL ?? getConfigValue('apiUrl') ?? 'https://tpmjs.com/api';\n}\n\n// History directory for conversation caching\nexport function getHistoryDir(): string {\n if (!fs.existsSync(HISTORY_DIR)) {\n fs.mkdirSync(HISTORY_DIR, { recursive: true, mode: 0o700 });\n }\n return HISTORY_DIR;\n}\n\n// Config directory path\nexport function getConfigDir(): string {\n ensureConfigDir();\n return CONFIG_DIR;\n}\n","import Table from 'cli-table3';\nimport ora, { type Ora } from 'ora';\nimport pc from 'picocolors';\n\nexport interface OutputOptions {\n json?: boolean;\n verbose?: boolean;\n noColor?: boolean;\n}\n\nexport class OutputFormatter {\n private options: OutputOptions;\n\n constructor(options: OutputOptions = {}) {\n this.options = options;\n }\n\n // Output as JSON\n json(data: unknown): void {\n console.log(JSON.stringify(data, null, 2));\n }\n\n // Output a table\n table<T extends Record<string, unknown>>(\n data: T[],\n columns: { key: keyof T; header: string; width?: number }[]\n ): void {\n if (this.options.json) {\n this.json(data);\n return;\n }\n\n const table = new Table({\n head: columns.map((col) => pc.bold(col.header)),\n colWidths: columns.map((col) => col.width ?? null),\n style: {\n head: [],\n border: [],\n },\n });\n\n for (const row of data) {\n table.push(columns.map((col) => String(row[col.key] ?? '')));\n }\n\n console.log(table.toString());\n }\n\n // Success message\n success(message: string): void {\n if (this.options.json) return;\n console.log(pc.green('✓'), message);\n }\n\n // Error message\n error(message: string, details?: string): void {\n if (this.options.json) {\n this.json({ error: message, details });\n return;\n }\n console.error(pc.red('✗'), message);\n if (details && this.options.verbose) {\n console.error(pc.dim(details));\n }\n }\n\n // Warning message\n warning(message: string): void {\n if (this.options.json) return;\n console.log(pc.yellow('⚠'), message);\n }\n\n // Info message\n info(message: string): void {\n if (this.options.json) return;\n console.log(pc.blue('ℹ'), message);\n }\n\n // Debug message (only in verbose mode)\n debug(message: string): void {\n if (this.options.json) return;\n if (this.options.verbose) {\n console.log(pc.dim(`[debug] ${message}`));\n }\n }\n\n // Plain text output\n text(message: string): void {\n if (this.options.json) return;\n console.log(message);\n }\n\n // Heading\n heading(text: string): void {\n if (this.options.json) return;\n console.log();\n console.log(pc.bold(pc.underline(text)));\n console.log();\n }\n\n // Subheading\n subheading(text: string): void {\n if (this.options.json) return;\n console.log(pc.bold(text));\n }\n\n // Key-value pair\n keyValue(key: string, value: string | number | boolean | undefined): void {\n if (this.options.json) return;\n console.log(`${pc.dim(`${key}:`)} ${value ?? pc.dim('(not set)')}`);\n }\n\n // List item\n listItem(text: string, indent = 0): void {\n if (this.options.json) return;\n const prefix = `${' '.repeat(indent)}•`;\n console.log(`${prefix} ${text}`);\n }\n\n // Spinner\n spinner(message: string): Ora {\n return ora({\n text: message,\n isSilent: this.options.json,\n }).start();\n }\n\n // Blank line\n newLine(): void {\n if (this.options.json) return;\n console.log();\n }\n\n // Horizontal rule\n hr(): void {\n if (this.options.json) return;\n console.log(pc.dim('─'.repeat(50)));\n }\n\n // Alias for hr\n divider(): void {\n this.hr();\n }\n\n // Code block\n code(text: string, language?: string): void {\n if (this.options.json) {\n this.json({ code: text, language });\n return;\n }\n console.log(pc.dim(`\\`\\`\\`${language ?? ''}`));\n console.log(text);\n console.log(pc.dim('```'));\n }\n\n // Highlight text\n highlight(text: string): string {\n return pc.cyan(text);\n }\n\n // Dim text\n dim(text: string): string {\n return pc.dim(text);\n }\n\n // Bold text\n bold(text: string): string {\n return pc.bold(text);\n }\n\n // Link (just returns text in terminal)\n link(text: string, url: string): string {\n // OSC 8 hyperlink support for modern terminals\n return `\\x1b]8;;${url}\\x07${pc.underline(pc.blue(text))}\\x1b]8;;\\x07`;\n }\n\n // Color helpers\n green(text: string): string {\n return pc.green(text);\n }\n\n red(text: string): string {\n return pc.red(text);\n }\n\n yellow(text: string): string {\n return pc.yellow(text);\n }\n\n blue(text: string): string {\n return pc.blue(text);\n }\n\n cyan(text: string): string {\n return pc.cyan(text);\n }\n}\n\n// Convenience function to create formatter from command flags\nexport function createOutput(flags: { json?: boolean; verbose?: boolean }): OutputFormatter {\n return new OutputFormatter({\n json: flags.json,\n verbose: flags.verbose,\n });\n}\n","import { Command, Flags } from '@oclif/core';\n\nimport { getApiKey, getApiUrl } from '../lib/config.js';\nimport { createOutput, type OutputFormatter } from '../lib/output.js';\n\ninterface JsonRpcResponse {\n jsonrpc: '2.0';\n id: string | number | null;\n result?: {\n content?: Array<{ type: string; text: string }>;\n [key: string]: unknown;\n };\n error?: {\n code: number;\n message: string;\n data?: unknown;\n };\n}\n\ninterface RunFlags {\n collection: string;\n tool: string;\n args: string;\n env?: string[];\n json: boolean;\n verbose: boolean;\n timeout: number;\n}\n\n/**\n * Parse and validate collection identifier\n */\nfunction parseCollection(collection: string): { username: string; slug: string } | null {\n const parts = collection.split('/');\n if (parts.length !== 2) return null;\n const [username, slug] = parts;\n if (!username || !slug) return null;\n return { username, slug };\n}\n\n/**\n * Parse JSON tool arguments\n */\nfunction parseToolArgs(argsStr: string): Record<string, unknown> | null {\n try {\n return JSON.parse(argsStr) as Record<string, unknown>;\n } catch {\n return null;\n }\n}\n\n/**\n * Build environment variables from process.env and explicit flags\n */\nfunction buildEnvVars(envFlags: string[] | undefined, output: OutputFormatter): Record<string, string> {\n const envVars: Record<string, string> = {};\n\n // Add process env vars that might be relevant\n for (const [key, value] of Object.entries(process.env)) {\n if (value && (key.endsWith('_API_KEY') || key.endsWith('_TOKEN') || key.endsWith('_SECRET'))) {\n envVars[key] = value;\n }\n }\n\n // Add explicitly passed env vars (override process env)\n if (envFlags) {\n for (const envPair of envFlags) {\n const [key, ...valueParts] = envPair.split('=');\n if (key && valueParts.length > 0) {\n envVars[key] = valueParts.join('=');\n } else {\n output.warning(`Invalid env var format: ${envPair}. Use: KEY=value`);\n }\n }\n }\n\n return envVars;\n}\n\n/**\n * Display verbose request info\n */\nfunction displayVerboseInfo(\n output: OutputFormatter,\n mcpUrl: string,\n tool: string,\n toolArgs: Record<string, unknown>,\n envVars: Record<string, string>\n): void {\n output.info(`MCP Endpoint: ${mcpUrl}`);\n output.info(`Tool: ${tool}`);\n output.info(`Arguments: ${JSON.stringify(toolArgs, null, 2)}`);\n if (Object.keys(envVars).length > 0) {\n output.info(`Environment: ${Object.keys(envVars).join(', ')}`);\n }\n output.divider();\n}\n\n/**\n * Handle HTTP error response\n */\nasync function handleHttpError(response: Response, output: OutputFormatter): Promise<void> {\n const errorText = await response.text();\n try {\n const errorJson = JSON.parse(errorText) as { error?: { message?: string }; message?: string };\n output.error(errorJson.error?.message || errorJson.message || `HTTP ${response.status}`);\n } catch {\n output.error(`HTTP ${response.status}: ${errorText}`);\n }\n}\n\n/**\n * Display MCP response content\n */\nfunction displayContent(result: JsonRpcResponse['result'], output: OutputFormatter): void {\n if (!result) {\n output.text('(empty result)');\n return;\n }\n\n if (result.content && Array.isArray(result.content)) {\n for (const item of result.content) {\n displayContentItem(item, output);\n }\n } else {\n output.text(JSON.stringify(result, null, 2));\n }\n}\n\n/**\n * Display a single content item\n */\nfunction displayContentItem(item: { type: string; text: string }, output: OutputFormatter): void {\n if (item.type === 'text') {\n try {\n const parsed = JSON.parse(item.text);\n output.text(JSON.stringify(parsed, null, 2));\n } catch {\n output.text(item.text);\n }\n } else if (item.type === 'image') {\n output.info('[Image content]');\n } else {\n output.text(JSON.stringify(item, null, 2));\n }\n}\n\n/**\n * Handle execution error\n */\nfunction handleExecutionError(error: unknown, flags: RunFlags, output: OutputFormatter): void {\n if (error instanceof Error) {\n if (error.name === 'AbortError') {\n output.error(`Request timed out after ${flags.timeout} seconds`);\n } else {\n output.error(error.message);\n }\n } else {\n output.error('Unknown error occurred');\n }\n\n if (flags.verbose) {\n output.info(`Full error: ${String(error)}`);\n }\n}\n\nexport default class Run extends Command {\n static description = 'Execute a tool from a collection via MCP';\n\n static examples = [\n {\n description: 'First, list all tools in a collection',\n command: '<%= config.bin %> collection info ajax/unsandbox',\n },\n {\n description: 'Execute Python code in the unsandbox collection',\n command:\n '<%= config.bin %> run -c ajax/unsandbox -t unsandbox--execute --args \\'{\"language\":\"python\",\"code\":\"print(42)\"}\\'',\n },\n {\n description: 'Pass environment variables for tool authentication',\n command:\n '<%= config.bin %> run -c ajax/unsandbox -t unsandbox--execute -e UNSANDBOX_PUBLIC_KEY=xxx -e UNSANDBOX_SECRET_KEY=xxx --args \\'{\"language\":\"python\",\"code\":\"print(1)\"}\\'',\n },\n {\n description: 'Output result as JSON',\n command: '<%= config.bin %> run -c ajax/tools -t search --args \\'{\"query\":\"test\"}\\' --json',\n },\n {\n description: 'Show verbose output for debugging',\n command: '<%= config.bin %> run -c ajax/unsandbox -t unsandbox--healthCheck --args \\'{}\\' -v',\n },\n ];\n\n static flags = {\n collection: Flags.string({\n char: 'c',\n description: 'Collection identifier (username/slug)',\n required: true,\n }),\n tool: Flags.string({\n char: 't',\n description: 'Tool name (MCP format: package--toolName)',\n required: true,\n }),\n args: Flags.string({\n char: 'a',\n description: 'Tool arguments as JSON string',\n default: '{}',\n }),\n env: Flags.string({\n char: 'e',\n description: 'Environment variables (key=value)',\n multiple: true,\n }),\n json: Flags.boolean({\n description: 'Output result as JSON',\n default: false,\n }),\n verbose: Flags.boolean({\n char: 'v',\n description: 'Show verbose output',\n default: false,\n }),\n timeout: Flags.integer({\n description: 'Request timeout in seconds',\n default: 60,\n }),\n };\n\n async run(): Promise<void> {\n const { flags } = await this.parse(Run);\n const output = createOutput(flags);\n\n // Parse and validate inputs\n const collection = parseCollection(flags.collection);\n if (!collection) {\n output.error('Invalid collection format. Use: username/slug');\n return;\n }\n\n const toolArgs = parseToolArgs(flags.args);\n if (!toolArgs) {\n output.error('Invalid JSON in --args flag');\n return;\n }\n\n // Build request components\n const envVars = buildEnvVars(flags.env, output);\n const baseUrl = getApiUrl().replace(/\\/api$/, '');\n const mcpUrl = `${baseUrl}/api/mcp/${collection.username}/${collection.slug}/http`;\n\n const apiKey = getApiKey();\n if (!apiKey) {\n output.warning('No API key configured. Some operations may fail.');\n output.warning('Run `tpm auth login` to authenticate.');\n }\n\n if (flags.verbose) {\n displayVerboseInfo(output, mcpUrl, flags.tool, toolArgs, envVars);\n }\n\n // Execute the request\n await this.executeToolCall(flags, output, mcpUrl, apiKey, toolArgs, envVars);\n }\n\n private async executeToolCall(\n flags: RunFlags,\n output: OutputFormatter,\n mcpUrl: string,\n apiKey: string | undefined,\n toolArgs: Record<string, unknown>,\n envVars: Record<string, string>\n ): Promise<void> {\n const jsonRpcRequest = {\n jsonrpc: '2.0',\n id: Date.now(),\n method: 'tools/call',\n params: {\n name: flags.tool,\n arguments: toolArgs,\n ...(Object.keys(envVars).length > 0 ? { env: envVars } : {}),\n },\n };\n\n const spinner = output.spinner(`Executing ${flags.tool}...`);\n\n try {\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), flags.timeout * 1000);\n\n const response = await fetch(mcpUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {}),\n },\n body: JSON.stringify(jsonRpcRequest),\n signal: controller.signal,\n });\n\n clearTimeout(timeoutId);\n\n if (!response.ok) {\n spinner.fail('Request failed');\n await handleHttpError(response, output);\n return;\n }\n\n const result = (await response.json()) as JsonRpcResponse;\n spinner.stop();\n\n this.handleResult(flags, output, result);\n } catch (error) {\n spinner.fail('Execution failed');\n handleExecutionError(error, flags, output);\n }\n }\n\n private handleResult(flags: RunFlags, output: OutputFormatter, result: JsonRpcResponse): void {\n if (result.error) {\n output.error(`Tool execution failed: ${result.error.message}`);\n if (flags.verbose && result.error.data) {\n output.info(`Error data: ${JSON.stringify(result.error.data, null, 2)}`);\n }\n return;\n }\n\n if (flags.json) {\n output.json(result.result);\n return;\n }\n\n output.success('Tool execution complete');\n output.divider();\n displayContent(result.result, output);\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import * as _oclif_core_interfaces from '@oclif/core/interfaces';
2
+ import { Command } from '@oclif/core';
3
+
4
+ declare class ScenarioGenerate extends Command {
5
+ static description: string;
6
+ static examples: string[];
7
+ static args: {
8
+ collection: _oclif_core_interfaces.Arg<string, Record<string, unknown>>;
9
+ };
10
+ static flags: {
11
+ count: _oclif_core_interfaces.OptionFlag<number, _oclif_core_interfaces.CustomOptions>;
12
+ 'skip-similarity-check': _oclif_core_interfaces.BooleanFlag<boolean>;
13
+ json: _oclif_core_interfaces.BooleanFlag<boolean>;
14
+ verbose: _oclif_core_interfaces.BooleanFlag<boolean>;
15
+ };
16
+ run(): Promise<void>;
17
+ }
18
+
19
+ export { ScenarioGenerate as default };