@orchagent/cli 0.2.4 → 0.2.6
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/commands/call.js +9 -0
- package/dist/commands/info.js +28 -0
- package/dist/commands/run.js +43 -12
- package/dist/index.js +7 -1
- package/package.json +3 -1
package/dist/commands/call.js
CHANGED
|
@@ -109,6 +109,15 @@ function registerCallCommand(program) {
|
|
|
109
109
|
.option('--no-skills', 'Ignore default skills')
|
|
110
110
|
.option('--file <path...>', 'File(s) to upload (can specify multiple)')
|
|
111
111
|
.option('--metadata <json>', 'JSON metadata to send with files')
|
|
112
|
+
.addHelpText('after', `
|
|
113
|
+
Examples:
|
|
114
|
+
orch call orchagent/invoice-scanner invoice.pdf
|
|
115
|
+
orch call orchagent/leak-finder --data '{"repo_url": "https://github.com/org/repo"}'
|
|
116
|
+
cat input.json | orch call acme/agent --data @-
|
|
117
|
+
orch call acme/image-processor photo.jpg --output result.png
|
|
118
|
+
|
|
119
|
+
Note: Use 'call' for server-side execution (requires login), 'run' for local execution.
|
|
120
|
+
`)
|
|
112
121
|
.action(async (agentRef, file, options) => {
|
|
113
122
|
const resolved = await (0, config_1.getResolvedConfig)();
|
|
114
123
|
if (!resolved.apiKey) {
|
package/dist/commands/info.js
CHANGED
|
@@ -14,6 +14,24 @@ function parseAgentRef(value) {
|
|
|
14
14
|
}
|
|
15
15
|
throw new errors_1.CliError('Invalid agent reference. Use org/agent format (e.g., joe/leak-finder)');
|
|
16
16
|
}
|
|
17
|
+
function formatSchema(schema, indent = ' ') {
|
|
18
|
+
const lines = [];
|
|
19
|
+
const props = schema.properties || {};
|
|
20
|
+
const required = schema.required || [];
|
|
21
|
+
for (const [key, value] of Object.entries(props)) {
|
|
22
|
+
let typeStr = value.type || 'any';
|
|
23
|
+
if (typeStr === 'array' && value.items?.type) {
|
|
24
|
+
typeStr = `${value.items.type}[]`;
|
|
25
|
+
}
|
|
26
|
+
const reqMark = required.includes(key) ? '' : '?';
|
|
27
|
+
let line = `${indent}${key}${reqMark}: ${typeStr}`;
|
|
28
|
+
if (value.description) {
|
|
29
|
+
line += ` - ${value.description}`;
|
|
30
|
+
}
|
|
31
|
+
lines.push(line);
|
|
32
|
+
}
|
|
33
|
+
return lines.join('\n');
|
|
34
|
+
}
|
|
17
35
|
function deriveReadmeUrl(sourceUrl) {
|
|
18
36
|
// Parse GitHub URLs like:
|
|
19
37
|
// git+https://github.com/user/repo.git#subdirectory=path
|
|
@@ -76,6 +94,16 @@ function registerInfoCommand(program) {
|
|
|
76
94
|
process.stdout.write(`Run: ${agentData.run_command}\n`);
|
|
77
95
|
}
|
|
78
96
|
}
|
|
97
|
+
// Display input schema if available
|
|
98
|
+
if (agentData.input_schema?.properties && Object.keys(agentData.input_schema.properties).length > 0) {
|
|
99
|
+
process.stdout.write('\nInput Schema:\n');
|
|
100
|
+
process.stdout.write(formatSchema(agentData.input_schema) + '\n');
|
|
101
|
+
}
|
|
102
|
+
// Display output schema if available
|
|
103
|
+
if (agentData.output_schema?.properties && Object.keys(agentData.output_schema.properties).length > 0) {
|
|
104
|
+
process.stdout.write('\nOutput Schema:\n');
|
|
105
|
+
process.stdout.write(formatSchema(agentData.output_schema) + '\n');
|
|
106
|
+
}
|
|
79
107
|
// Fetch and display README if available
|
|
80
108
|
if (agentData.source_url) {
|
|
81
109
|
const readmeUrl = deriveReadmeUrl(agentData.source_url);
|
package/dist/commands/run.js
CHANGED
|
@@ -289,7 +289,9 @@ async function unzipBundle(zipPath, destDir) {
|
|
|
289
289
|
});
|
|
290
290
|
});
|
|
291
291
|
}
|
|
292
|
-
async function executeBundleAgent(config, org, agentName, version, agentData, args) {
|
|
292
|
+
async function executeBundleAgent(config, org, agentName, version, agentData, args, inputOption) {
|
|
293
|
+
// Capture the user's working directory before we change anything
|
|
294
|
+
const userCwd = process.cwd();
|
|
293
295
|
// Create temp directory for the bundle
|
|
294
296
|
const tempDir = path_1.default.join(os_1.default.tmpdir(), `orchagent-${agentName}-${Date.now()}`);
|
|
295
297
|
await promises_1.default.mkdir(tempDir, { recursive: true });
|
|
@@ -331,30 +333,50 @@ async function executeBundleAgent(config, org, agentName, version, agentData, ar
|
|
|
331
333
|
catch {
|
|
332
334
|
throw new errors_1.CliError(`Entrypoint not found: ${entrypoint}`);
|
|
333
335
|
}
|
|
334
|
-
// Build input JSON from args
|
|
335
|
-
// The first arg should be the input (file path or JSON string)
|
|
336
|
+
// Build input JSON from --input option or positional args
|
|
336
337
|
let inputJson = '{}';
|
|
337
|
-
if (
|
|
338
|
+
if (inputOption) {
|
|
339
|
+
// --input was provided, use it directly (should be valid JSON)
|
|
340
|
+
try {
|
|
341
|
+
// Parse and re-stringify to validate JSON
|
|
342
|
+
const parsed = JSON.parse(inputOption);
|
|
343
|
+
// Resolve any relative paths in the input to absolute paths
|
|
344
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
345
|
+
for (const key of ['path', 'directory', 'file_path']) {
|
|
346
|
+
if (typeof parsed[key] === 'string' && !path_1.default.isAbsolute(parsed[key])) {
|
|
347
|
+
parsed[key] = path_1.default.resolve(userCwd, parsed[key]);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
inputJson = JSON.stringify(parsed);
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
throw new errors_1.CliError('Invalid JSON in --input option');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else if (args.length > 0) {
|
|
338
358
|
const firstArg = args[0];
|
|
359
|
+
// Resolve to absolute path relative to user's working directory
|
|
360
|
+
const resolvedArg = path_1.default.isAbsolute(firstArg) ? firstArg : path_1.default.resolve(userCwd, firstArg);
|
|
339
361
|
// Check if it's a file path
|
|
340
362
|
try {
|
|
341
|
-
const stat = await promises_1.default.stat(
|
|
363
|
+
const stat = await promises_1.default.stat(resolvedArg);
|
|
342
364
|
if (stat.isFile()) {
|
|
343
365
|
// Read file content as input
|
|
344
|
-
const fileContent = await promises_1.default.readFile(
|
|
366
|
+
const fileContent = await promises_1.default.readFile(resolvedArg, 'utf-8');
|
|
345
367
|
// Check if it's already JSON
|
|
346
368
|
try {
|
|
347
369
|
JSON.parse(fileContent);
|
|
348
370
|
inputJson = fileContent;
|
|
349
371
|
}
|
|
350
372
|
catch {
|
|
351
|
-
// Wrap as file_path in JSON
|
|
352
|
-
inputJson = JSON.stringify({ file_path:
|
|
373
|
+
// Wrap as file_path in JSON (use absolute path)
|
|
374
|
+
inputJson = JSON.stringify({ file_path: resolvedArg });
|
|
353
375
|
}
|
|
354
376
|
}
|
|
355
377
|
else if (stat.isDirectory()) {
|
|
356
|
-
// Pass directory path
|
|
357
|
-
inputJson = JSON.stringify({ directory:
|
|
378
|
+
// Pass directory path (use absolute path)
|
|
379
|
+
inputJson = JSON.stringify({ directory: resolvedArg });
|
|
358
380
|
}
|
|
359
381
|
}
|
|
360
382
|
catch {
|
|
@@ -364,7 +386,7 @@ async function executeBundleAgent(config, org, agentName, version, agentData, ar
|
|
|
364
386
|
inputJson = firstArg;
|
|
365
387
|
}
|
|
366
388
|
catch {
|
|
367
|
-
// Treat as a simple string input
|
|
389
|
+
// Treat as a simple string input (could be a URL)
|
|
368
390
|
inputJson = JSON.stringify({ input: firstArg });
|
|
369
391
|
}
|
|
370
392
|
}
|
|
@@ -474,6 +496,15 @@ function registerRunCommand(program) {
|
|
|
474
496
|
.option('--skills <skills>', 'Add skills (comma-separated)')
|
|
475
497
|
.option('--skills-only <skills>', 'Use only these skills')
|
|
476
498
|
.option('--no-skills', 'Ignore default skills')
|
|
499
|
+
.addHelpText('after', `
|
|
500
|
+
Examples:
|
|
501
|
+
orch run orchagent/leak-finder --input '{"path": "."}'
|
|
502
|
+
orch run orchagent/leak-finder --input '{"repo_url": "https://github.com/org/repo"}'
|
|
503
|
+
orch run joe/summarizer --input '{"text": "Hello world"}'
|
|
504
|
+
orch run orchagent/leak-finder --download-only
|
|
505
|
+
|
|
506
|
+
Note: Use 'run' for local execution, 'call' for server-side execution.
|
|
507
|
+
`)
|
|
477
508
|
.action(async (agentRef, args, options) => {
|
|
478
509
|
const resolved = await (0, config_1.getResolvedConfig)();
|
|
479
510
|
const parsed = parseAgentRef(agentRef);
|
|
@@ -536,7 +567,7 @@ function registerRunCommand(program) {
|
|
|
536
567
|
return;
|
|
537
568
|
}
|
|
538
569
|
// Execute the bundle-based code agent locally
|
|
539
|
-
await executeBundleAgent(resolved, org, parsed.agent, parsed.version, agentData, args);
|
|
570
|
+
await executeBundleAgent(resolved, org, parsed.agent, parsed.version, agentData, args, options.input);
|
|
540
571
|
return;
|
|
541
572
|
}
|
|
542
573
|
// Check for pip/source-based local execution (legacy)
|
package/dist/index.js
CHANGED
|
@@ -51,7 +51,13 @@ const program = new commander_1.Command();
|
|
|
51
51
|
program
|
|
52
52
|
.name('orchagent')
|
|
53
53
|
.description('OrchAgent CLI')
|
|
54
|
-
.version(package_json_1.default.version)
|
|
54
|
+
.version(package_json_1.default.version)
|
|
55
|
+
.addHelpText('after', `
|
|
56
|
+
Quick Reference:
|
|
57
|
+
run Download and run an agent locally (your machine)
|
|
58
|
+
call Execute an agent on OrchAgent servers (requires login)
|
|
59
|
+
info Show agent details and input/output schemas
|
|
60
|
+
`);
|
|
55
61
|
(0, commands_1.registerCommands)(program);
|
|
56
62
|
program
|
|
57
63
|
.parseAsync(process.argv)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orchagent/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.6",
|
|
4
4
|
"description": "Command-line interface for the OrchAgent AI agent marketplace",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "OrchAgent <hello@orchagent.io>",
|
|
@@ -38,6 +38,8 @@
|
|
|
38
38
|
"test": "vitest run",
|
|
39
39
|
"test:watch": "vitest",
|
|
40
40
|
"test:coverage": "vitest run --coverage",
|
|
41
|
+
"test:e2e": "vitest run --config vitest.e2e.config.ts",
|
|
42
|
+
"test:all": "vitest run && vitest run --config vitest.e2e.config.ts",
|
|
41
43
|
"prepublishOnly": "npm run build"
|
|
42
44
|
},
|
|
43
45
|
"dependencies": {
|