@orchagent/cli 0.3.77 → 0.3.78

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.
@@ -1,172 +1,22 @@
1
1
  "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
35
5
  Object.defineProperty(exports, "__esModule", { value: true });
36
6
  exports.registerKeysCommand = registerKeysCommand;
37
- const readline = __importStar(require("readline"));
38
- const config_1 = require("../lib/config");
39
- const api_1 = require("../lib/api");
40
- const errors_1 = require("../lib/errors");
41
- const VALID_PROVIDERS = ['openai', 'anthropic', 'gemini', 'ollama'];
42
- async function promptForKey(provider) {
43
- // Use hidden input to avoid exposing keys in terminal history/logs
44
- return new Promise((resolve, reject) => {
45
- const rl = readline.createInterface({
46
- input: process.stdin,
47
- output: process.stdout,
48
- });
49
- // Mask input by not echoing characters
50
- process.stdout.write(`Enter API key for ${provider}: `);
51
- if (process.stdin.isTTY) {
52
- // For TTY, read without echo
53
- const stdin = process.stdin;
54
- stdin.setRawMode(true);
55
- stdin.resume();
56
- stdin.setEncoding('utf8');
57
- let key = '';
58
- const onData = (char) => {
59
- if (char === '\n' || char === '\r') {
60
- stdin.setRawMode(false);
61
- stdin.removeListener('data', onData);
62
- rl.close();
63
- process.stdout.write('\n');
64
- resolve(key.trim());
65
- }
66
- else if (char === '\u0003') {
67
- // Ctrl+C
68
- stdin.setRawMode(false);
69
- rl.close();
70
- reject(new errors_1.CliError('Cancelled'));
71
- }
72
- else if (char === '\u007F' || char === '\b') {
73
- // Backspace
74
- if (key.length > 0) {
75
- key = key.slice(0, -1);
76
- }
77
- }
78
- else {
79
- key += char;
80
- }
81
- };
82
- stdin.on('data', onData);
83
- }
84
- else {
85
- // Non-TTY (piped input), just read normally
86
- rl.question('', (answer) => {
87
- rl.close();
88
- resolve(answer.trim());
89
- });
90
- }
91
- });
92
- }
93
- async function addKey(config, provider, options) {
94
- let apiKey = options.key;
95
- if (!apiKey) {
96
- apiKey = await promptForKey(provider);
97
- }
98
- if (!apiKey) {
99
- throw new errors_1.CliError('API key is required');
100
- }
101
- await (0, api_1.request)(config, 'POST', '/llm-keys', {
102
- body: JSON.stringify({
103
- provider,
104
- api_key: apiKey,
105
- endpoint_url: options.endpoint,
106
- }),
107
- headers: { 'Content-Type': 'application/json' },
108
- });
109
- process.stdout.write(`Saved ${provider} API key.\n`);
110
- }
111
- async function listKeys(config) {
112
- const keys = await (0, api_1.request)(config, 'GET', '/llm-keys');
113
- if (keys.length === 0) {
114
- process.stdout.write('No LLM keys configured.\n');
115
- process.stdout.write('\nAdd a key with: orchagent keys add <provider>\n');
116
- process.stdout.write('Providers: openai, anthropic, gemini, ollama\n');
117
- return;
118
- }
119
- process.stdout.write('Configured LLM keys:\n\n');
120
- for (const key of keys) {
121
- const endpoint = key.has_custom_endpoint ? ' (custom endpoint)' : '';
122
- process.stdout.write(` ${key.provider}${endpoint}\n`);
123
- }
124
- process.stdout.write('\n');
125
- }
126
- async function removeKey(config, provider) {
127
- await (0, api_1.request)(config, 'DELETE', `/llm-keys/${provider}`);
128
- process.stdout.write(`Removed ${provider} API key.\n`);
129
- }
7
+ const chalk_1 = __importDefault(require("chalk"));
130
8
  function registerKeysCommand(program) {
131
- const keys = program
9
+ program
132
10
  .command('keys')
133
- .description('Manage LLM API keys for calling agents');
134
- keys
135
- .command('add <provider>')
136
- .description('Add or update an LLM API key')
137
- .option('--key <key>', 'API key (will prompt if not provided)')
138
- .option('--endpoint <url>', 'Custom endpoint URL (enterprise proxy or self-hosted model)')
139
- .action(async (provider, options) => {
140
- const config = await (0, config_1.getResolvedConfig)();
141
- if (!config.apiKey) {
142
- throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
143
- }
144
- if (!VALID_PROVIDERS.includes(provider)) {
145
- throw new errors_1.CliError(`Invalid provider: ${provider}. Valid providers: ${VALID_PROVIDERS.join(', ')}`);
146
- }
147
- await addKey(config, provider, options);
148
- });
149
- keys
150
- .command('list')
151
- .description('List configured LLM API keys')
152
- .action(async () => {
153
- const config = await (0, config_1.getResolvedConfig)();
154
- if (!config.apiKey) {
155
- throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
156
- }
157
- await listKeys(config);
158
- });
159
- keys
160
- .command('remove <provider>')
161
- .description('Remove an LLM API key')
162
- .action(async (provider) => {
163
- const config = await (0, config_1.getResolvedConfig)();
164
- if (!config.apiKey) {
165
- throw new errors_1.CliError('Missing API key. Run `orchagent login` first.');
166
- }
167
- if (!VALID_PROVIDERS.includes(provider)) {
168
- throw new errors_1.CliError(`Invalid provider: ${provider}. Valid providers: ${VALID_PROVIDERS.join(', ')}`);
169
- }
170
- await removeKey(config, provider);
11
+ .description('(Deprecated) Use "orch secrets" instead')
12
+ .allowUnknownOption(true)
13
+ .action(() => {
14
+ process.stderr.write(chalk_1.default.yellow('\nThe `orch keys` command has been removed.\n\n') +
15
+ `LLM API keys are now managed through the unified workspace secrets vault.\n` +
16
+ `Use ${chalk_1.default.cyan('orch secrets')} instead:\n\n` +
17
+ ` ${chalk_1.default.cyan('orch secrets set ANTHROPIC_API_KEY <key>')} Add an LLM key\n` +
18
+ ` ${chalk_1.default.cyan('orch secrets list')} List all secrets\n` +
19
+ ` ${chalk_1.default.cyan('orch secrets delete ANTHROPIC_API_KEY')} Remove a key\n\n`);
20
+ process.exit(1);
171
21
  });
172
22
  }
package/dist/lib/api.js CHANGED
@@ -46,7 +46,6 @@ exports.updateOrg = updateOrg;
46
46
  exports.getPublicAgent = getPublicAgent;
47
47
  exports.listMyAgents = listMyAgents;
48
48
  exports.createAgent = createAgent;
49
- exports.listLlmKeys = listLlmKeys;
50
49
  exports.downloadCodeBundle = downloadCodeBundle;
51
50
  exports.uploadCodeBundle = uploadCodeBundle;
52
51
  exports.getMyAgent = getMyAgent;
@@ -306,9 +305,6 @@ async function createAgent(config, data, workspaceId) {
306
305
  headers,
307
306
  });
308
307
  }
309
- async function listLlmKeys(config) {
310
- return request(config, 'GET', '/llm-keys');
311
- }
312
308
  /**
313
309
  * Download a code-runtime bundle for local execution.
314
310
  */
@@ -1,8 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.runLlmChecks = runLlmChecks;
4
- const config_1 = require("../../config");
5
- const api_1 = require("../../api");
6
4
  // All supported LLM providers (single source of truth)
7
5
  const PROVIDERS = [
8
6
  { id: 'openai', displayName: 'OpenAI', envVars: ['OPENAI_API_KEY'], keyPrefix: 'sk-' },
@@ -26,13 +24,18 @@ function getFormatHint(provider, value) {
26
24
  return null;
27
25
  }
28
26
  /**
29
- * Gather per-provider status from server keys and local env vars.
27
+ * Run all LLM configuration checks with per-provider breakdown.
28
+ *
29
+ * Checks local environment variables for LLM provider keys.
30
+ * Server-side keys are managed through the workspace secrets vault
31
+ * (use `orch secrets list` to check).
30
32
  */
31
- function gatherProviderStatuses(serverProviders) {
32
- return PROVIDERS.map((provider) => {
33
- // Server status
34
- const server = serverProviders === null ? null : serverProviders.includes(provider.id);
35
- // Local status — check each env var
33
+ async function runLlmChecks(options) {
34
+ const results = [];
35
+ // Per-provider results (local env vars only)
36
+ let configuredCount = 0;
37
+ let firstUnconfigured;
38
+ for (const provider of PROVIDERS) {
36
39
  let local = false;
37
40
  let localEnvVar;
38
41
  let formatHint;
@@ -47,96 +50,37 @@ function gatherProviderStatuses(serverProviders) {
47
50
  break;
48
51
  }
49
52
  }
50
- return {
51
- providerId: provider.id,
52
- displayName: provider.displayName,
53
- server,
54
- local,
55
- localEnvVar,
56
- formatHint,
57
- };
58
- });
59
- }
60
- /**
61
- * Build a human-readable location string from server/local status.
62
- */
63
- function locationString(status) {
64
- if (status.server === null) {
65
- // Server unknown (offline)
66
- if (status.local)
67
- return 'Server unknown, local configured';
68
- return 'Server unknown, not local';
69
- }
70
- if (status.server && status.local)
71
- return 'Configured (server + local)';
72
- if (status.server)
73
- return 'Configured (server)';
74
- if (status.local)
75
- return 'Configured (local)';
76
- return 'Not configured';
77
- }
78
- /**
79
- * Run all LLM configuration checks with per-provider breakdown.
80
- *
81
- * When skipServer is true, server status is null for all providers
82
- * (shown as "unknown" in output). Use this when the gateway is unreachable.
83
- */
84
- async function runLlmChecks(options) {
85
- let serverProviders = null;
86
- if (!options?.skipServer) {
87
- try {
88
- const config = await (0, config_1.getResolvedConfig)();
89
- if (config.apiKey) {
90
- const keys = await (0, api_1.listLlmKeys)(config);
91
- serverProviders = keys.map((k) => k.provider);
92
- }
93
- }
94
- catch (err) {
95
- // If we can't reach the server, treat as unknown
96
- if (err instanceof api_1.ApiError && err.status === 401) {
97
- // Auth failed — server providers unknown
98
- }
99
- // Network error or other — server providers unknown
100
- }
101
- }
102
- const statuses = gatherProviderStatuses(serverProviders);
103
- const results = [];
104
- // Per-provider results
105
- for (const status of statuses) {
106
- const configured = status.server === true || status.local;
53
+ if (local)
54
+ configuredCount++;
55
+ else if (!firstUnconfigured)
56
+ firstUnconfigured = provider.id;
107
57
  results.push({
108
58
  category: 'llm',
109
- name: `llm_provider_${status.providerId}`,
110
- status: configured ? 'success' : 'info',
111
- message: `${status.providerId} — ${locationString(status)}`,
59
+ name: `llm_provider_${provider.id}`,
60
+ status: local ? 'success' : 'info',
61
+ message: `${provider.id} — ${local ? 'Configured (local)' : 'Not configured locally'}`,
112
62
  details: {
113
- providerId: status.providerId,
114
- displayName: status.displayName,
115
- server: status.server,
116
- local: status.local,
117
- ...(status.localEnvVar && { localEnvVar: status.localEnvVar }),
118
- ...(status.formatHint && { formatHint: status.formatHint }),
63
+ providerId: provider.id,
64
+ displayName: provider.displayName,
65
+ server: null,
66
+ local,
67
+ ...(localEnvVar && { localEnvVar }),
68
+ ...(formatHint && { formatHint }),
119
69
  },
120
70
  });
121
71
  }
122
72
  // Summary result
123
- const configuredCount = statuses.filter((s) => s.server === true || s.local).length;
124
- const firstUnconfigured = statuses.find((s) => s.server !== true && !s.local);
125
73
  let summaryStatus;
126
74
  let summaryMessage;
127
75
  let summaryFix;
128
76
  if (configuredCount === 0) {
129
77
  summaryStatus = 'warning';
130
- summaryMessage = 'No LLM providers configured';
131
- summaryFix = firstUnconfigured ? `Run: orchagent keys add ${firstUnconfigured.providerId}` : undefined;
78
+ summaryMessage = 'No LLM providers configured locally';
79
+ summaryFix = 'For cloud runs, add keys to your workspace vault: orch secrets set ANTHROPIC_API_KEY <key>';
132
80
  }
133
81
  else {
134
82
  summaryStatus = 'success';
135
- summaryMessage =
136
- configuredCount < 2
137
- ? 'Tip: Multiple providers enable automatic rate limit fallback.'
138
- : `${configuredCount} providers configured`;
139
- summaryFix = firstUnconfigured ? `Run: orchagent keys add ${firstUnconfigured.providerId}` : undefined;
83
+ summaryMessage = `${configuredCount} local provider${configuredCount > 1 ? 's' : ''} configured`;
140
84
  }
141
85
  results.push({
142
86
  category: 'llm',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.77",
3
+ "version": "0.3.78",
4
4
  "description": "Command-line interface for orchagent — deploy and run AI agents for your team",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",