@orchagent/cli 0.2.23 → 0.2.25

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.
@@ -100,6 +100,7 @@ function registerCallCommand(program) {
100
100
  .option('--endpoint <endpoint>', 'Override agent endpoint')
101
101
  .option('--tenant <tenant>', 'Tenant identifier for multi-tenant callers')
102
102
  .option('--data <json>', 'JSON payload (string or @file, @- for stdin)')
103
+ .option('--input <json>', 'Alias for --data')
103
104
  .option('--key <key>', 'LLM API key (overrides env vars)')
104
105
  .option('--provider <provider>', 'LLM provider (openai, anthropic, gemini)')
105
106
  .option('--json', 'Output raw JSON')
@@ -119,6 +120,9 @@ Examples:
119
120
  Note: Use 'call' for server-side execution (requires login), 'run' for local execution.
120
121
  `)
121
122
  .action(async (agentRef, file, options) => {
123
+ // Merge --input alias into --data
124
+ const dataValue = options.data || options.input;
125
+ options.data = dataValue;
122
126
  const resolved = await (0, config_1.getResolvedConfig)();
123
127
  if (!resolved.apiKey) {
124
128
  throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.registerDocsCommand = registerDocsCommand;
7
+ const open_1 = __importDefault(require("open"));
8
+ const DOCS_BASE = 'https://docs.orchagent.io';
9
+ const DOCS_ROUTES = {
10
+ '': '/',
11
+ 'cli': '/using-agents/cli-commands',
12
+ 'agents': '/building-agents/agent-types',
13
+ 'skills': '/building-agents/orchestration',
14
+ 'sdk': '/building-agents/sdk',
15
+ 'api': '/api-reference/overview',
16
+ 'quickstart': '/quickstart',
17
+ };
18
+ function registerDocsCommand(program) {
19
+ program
20
+ .command('docs')
21
+ .description('Open documentation in browser')
22
+ .argument('[topic]', 'Topic: cli, agents, skills, sdk, api, quickstart')
23
+ .action(async (topic) => {
24
+ if (topic && !(topic in DOCS_ROUTES)) {
25
+ const validTopics = Object.keys(DOCS_ROUTES).filter(k => k).join(', ');
26
+ process.stderr.write(`Unknown topic "${topic}". Valid topics: ${validTopics}\n`);
27
+ process.stderr.write('Opening docs homepage instead.\n\n');
28
+ }
29
+ const route = DOCS_ROUTES[topic ?? ''] ?? '/';
30
+ const url = `${DOCS_BASE}${route}`;
31
+ process.stdout.write(`Opening ${url}\n`);
32
+ await (0, open_1.default)(url);
33
+ });
34
+ }
@@ -20,6 +20,7 @@ const doctor_1 = require("./doctor");
20
20
  const status_1 = require("./status");
21
21
  const workspace_1 = require("./workspace");
22
22
  const tree_1 = require("./tree");
23
+ const docs_1 = require("./docs");
23
24
  function registerCommands(program) {
24
25
  (0, login_1.registerLoginCommand)(program);
25
26
  (0, whoami_1.registerWhoamiCommand)(program);
@@ -40,4 +41,5 @@ function registerCommands(program) {
40
41
  (0, status_1.registerStatusCommand)(program);
41
42
  (0, workspace_1.registerWorkspaceCommand)(program);
42
43
  (0, tree_1.registerTreeCommand)(program);
44
+ (0, docs_1.registerDocsCommand)(program);
43
45
  }
@@ -38,7 +38,7 @@ const readline = __importStar(require("readline"));
38
38
  const config_1 = require("../lib/config");
39
39
  const api_1 = require("../lib/api");
40
40
  const errors_1 = require("../lib/errors");
41
- const VALID_PROVIDERS = ['openai', 'anthropic', 'gemini'];
41
+ const VALID_PROVIDERS = ['openai', 'anthropic', 'gemini', 'ollama'];
42
42
  async function promptForKey(provider) {
43
43
  // Use hidden input to avoid exposing keys in terminal history/logs
44
44
  return new Promise((resolve, reject) => {
@@ -113,7 +113,7 @@ async function listKeys(config) {
113
113
  if (keys.length === 0) {
114
114
  process.stdout.write('No LLM keys configured.\n');
115
115
  process.stdout.write('\nAdd a key with: orchagent keys add <provider>\n');
116
- process.stdout.write('Providers: openai, anthropic, gemini\n');
116
+ process.stdout.write('Providers: openai, anthropic, gemini, ollama\n');
117
117
  return;
118
118
  }
119
119
  process.stdout.write('Configured LLM keys:\n\n');
@@ -176,6 +176,7 @@ async function promptUserForDeps(depStatuses) {
176
176
  process.stderr.write(` [2] Download ${downloadableCount} available deps, run locally\n`);
177
177
  }
178
178
  process.stderr.write(' [3] Cancel\n\n');
179
+ process.stderr.write('Tip: Use --with-deps to skip this prompt in scripts.\n\n');
179
180
  return new Promise((resolve) => {
180
181
  rl.question('Choose [1/2/3]: ', (answer) => {
181
182
  rl.close();
@@ -233,16 +234,26 @@ async function downloadDependenciesRecursively(config, depStatuses, visited = ne
233
234
  }
234
235
  }
235
236
  }
236
- async function executePromptLocally(agentData, inputData, skillPrompts = [], config) {
237
- const detected = await (0, llm_1.detectLlmKey)(agentData.supported_providers, config);
237
+ async function executePromptLocally(agentData, inputData, skillPrompts = [], config, providerOverride) {
238
+ // If provider override specified, validate and use only that provider
239
+ if (providerOverride) {
240
+ (0, llm_1.validateProvider)(providerOverride);
241
+ }
242
+ // Determine which providers to check for keys
243
+ const providersToCheck = providerOverride
244
+ ? [providerOverride]
245
+ : agentData.supported_providers;
246
+ const detected = await (0, llm_1.detectLlmKey)(providersToCheck, config);
238
247
  if (!detected) {
239
- const providers = agentData.supported_providers.join(', ');
240
- throw new errors_1.CliError(`No LLM key found. This agent requires: ${providers}\n` +
248
+ const providers = providersToCheck.join(', ');
249
+ throw new errors_1.CliError(`No LLM key found for: ${providers}\n` +
241
250
  `Set an environment variable (e.g., OPENAI_API_KEY) or configure in web dashboard`);
242
251
  }
243
252
  const { provider, key, model: serverModel } = detected;
244
253
  // Priority: server config model > agent default model > hardcoded default
245
254
  const model = serverModel || agentData.default_models?.[provider] || (0, llm_1.getDefaultModel)(provider);
255
+ // Show which provider is being used (helpful for debugging rate limits)
256
+ process.stderr.write(`Running with ${provider} (${model})...\n`);
246
257
  // Combine skill prompts with agent prompt (skills first, then agent)
247
258
  let basePrompt = agentData.prompt || '';
248
259
  if (skillPrompts.length > 0) {
@@ -663,12 +674,16 @@ function registerRunCommand(program) {
663
674
  .description('Download and run an agent locally')
664
675
  .option('--local', 'Run locally using local LLM keys (default for run command)')
665
676
  .option('--input <json>', 'JSON input data')
677
+ .option('--data <json>', 'Alias for --input')
666
678
  .option('--download-only', 'Just download the agent, do not execute')
667
679
  .option('--with-deps', 'Automatically download all dependencies (skip prompt)')
668
680
  .option('--json', 'Output raw JSON')
669
681
  .option('--skills <skills>', 'Add skills (comma-separated)')
670
682
  .option('--skills-only <skills>', 'Use only these skills')
671
683
  .option('--no-skills', 'Ignore default skills')
684
+ .option('--here', 'Shorthand for --input \'{"path": "."}\'')
685
+ .option('--path <dir>', 'Shorthand for --input \'{"path": "<dir>"}\'')
686
+ .option('--provider <name>', 'LLM provider to use (openai, anthropic, gemini, ollama)')
672
687
  .addHelpText('after', `
673
688
  Examples:
674
689
  orch run orchagent/leak-finder --input '{"path": "."}'
@@ -679,6 +694,17 @@ Examples:
679
694
  Note: Use 'run' for local execution, 'call' for server-side execution.
680
695
  `)
681
696
  .action(async (agentRef, args, options) => {
697
+ // Merge --data alias into --input
698
+ if (options.data && !options.input) {
699
+ options.input = options.data;
700
+ }
701
+ // Handle --here and --path shortcuts
702
+ if (options.here) {
703
+ options.input = JSON.stringify({ path: process.cwd() });
704
+ }
705
+ else if (options.path) {
706
+ options.input = JSON.stringify({ path: options.path });
707
+ }
682
708
  const resolved = await (0, config_1.getResolvedConfig)();
683
709
  const parsed = parseAgentRef(agentRef);
684
710
  const org = parsed.org ?? resolved.defaultOrg;
@@ -819,7 +845,7 @@ Note: Use 'run' for local execution, 'call' for server-side execution.
819
845
  }
820
846
  // Execute locally
821
847
  process.stderr.write(`Executing locally...\n\n`);
822
- const result = await executePromptLocally(agentData, inputData, skillPrompts, resolved);
848
+ const result = await executePromptLocally(agentData, inputData, skillPrompts, resolved, options.provider);
823
849
  if (options.json) {
824
850
  (0, output_1.printJson)(result);
825
851
  }
@@ -5,7 +5,6 @@ const config_1 = require("../lib/config");
5
5
  const api_1 = require("../lib/api");
6
6
  const output_1 = require("../lib/output");
7
7
  const analytics_1 = require("../lib/analytics");
8
- const errors_1 = require("../lib/errors");
9
8
  const DEFAULT_LIMIT = 20;
10
9
  function registerSearchCommand(program) {
11
10
  program
@@ -20,14 +19,9 @@ function registerSearchCommand(program) {
20
19
  .action(async (query, options) => {
21
20
  const config = await (0, config_1.getResolvedConfig)();
22
21
  const limit = parseInt(options.limit, 10) || DEFAULT_LIMIT;
23
- // Require query OR --popular/--recent
22
+ // Default to popular when no args
24
23
  if (!query && !options.popular && !options.recent) {
25
- throw new errors_1.CliError('Search requires a query or flag.\n\n' +
26
- 'Usage:\n' +
27
- ' orchagent search <query> Search by keyword\n' +
28
- ' orchagent search --popular Top agents by stars\n' +
29
- ' orchagent search --recent Most recently published\n\n' +
30
- 'Browse all agents at: https://orchagent.io/explore');
24
+ options.popular = true;
31
25
  }
32
26
  let agents;
33
27
  if (query) {
@@ -67,5 +61,6 @@ function registerSearchCommand(program) {
67
61
  if (agents.length === limit) {
68
62
  process.stdout.write(`\nShowing top ${limit} results. Use --limit <n> for more.\n`);
69
63
  }
64
+ process.stdout.write('\nTip: Run "orchagent info <agent>" to see input schema and details.\n');
70
65
  });
71
66
  }
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.registerStatusCommand = registerStatusCommand;
7
7
  const chalk_1 = __importDefault(require("chalk"));
8
+ const config_1 = require("../lib/config");
8
9
  const output_1 = require("../lib/output");
9
10
  const STATUS_URL = 'https://api.orchagent.io/health/detailed';
10
11
  const STATUS_PAGE_URL = 'https://status.orchagent.io';
@@ -86,6 +87,22 @@ function registerStatusCommand(program) {
86
87
  return;
87
88
  }
88
89
  printHumanStatus(data);
90
+ // Also verify actual API connectivity
91
+ const config = await (0, config_1.getResolvedConfig)();
92
+ const apiUrl = `${config.apiUrl.replace(/\/$/, '')}/health`;
93
+ try {
94
+ const apiResponse = await fetch(apiUrl, {
95
+ signal: AbortSignal.timeout(5000),
96
+ });
97
+ if (!apiResponse.ok) {
98
+ process.stderr.write('\n' + chalk_1.default.yellow('⚠️ Status page shows operational, but API returned error.') + '\n');
99
+ process.stderr.write(' Run "orchagent doctor" for detailed diagnostics.\n');
100
+ }
101
+ }
102
+ catch {
103
+ process.stderr.write('\n' + chalk_1.default.yellow('⚠️ Status page shows operational, but could not reach API.') + '\n');
104
+ process.stderr.write(' Run "orchagent doctor" for detailed diagnostics.\n');
105
+ }
89
106
  }
90
107
  catch (err) {
91
108
  if (options.json) {
package/dist/index.js CHANGED
@@ -60,6 +60,11 @@ Quick Reference:
60
60
  run Download and run an agent locally (your machine)
61
61
  call Execute an agent on orchagent servers (requires login)
62
62
  info Show agent details and input/output schemas
63
+
64
+ Documentation: https://docs.orchagent.io
65
+ orchagent docs Open docs in browser
66
+ orchagent docs cli CLI command reference
67
+ orchagent docs agents Building agents guide
63
68
  `);
64
69
  (0, commands_1.registerCommands)(program);
65
70
  program
@@ -39,6 +39,17 @@ async function checkServerLlmKeys() {
39
39
  };
40
40
  }
41
41
  const providers = keys.map((k) => k.provider);
42
+ // Warn if only one provider configured (no fallback for rate limits)
43
+ if (keys.length === 1) {
44
+ return {
45
+ category: 'llm',
46
+ name: 'server_llm_keys',
47
+ status: 'warning',
48
+ message: `Only 1 LLM provider configured (${providers[0]}). Consider adding a backup for rate limit fallback.`,
49
+ fix: 'Run: orchagent keys add <provider>',
50
+ details: { count: keys.length, providers },
51
+ };
52
+ }
42
53
  return {
43
54
  category: 'llm',
44
55
  name: 'server_llm_keys',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.2.23",
3
+ "version": "0.2.25",
4
4
  "description": "Command-line interface for the orchagent AI agent marketplace",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",