@orchagent/cli 0.3.7 → 0.3.8

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.
@@ -0,0 +1,245 @@
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
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.registerEnvCommand = registerEnvCommand;
40
+ const cli_table3_1 = __importDefault(require("cli-table3"));
41
+ const chalk_1 = __importDefault(require("chalk"));
42
+ const fs = __importStar(require("fs/promises"));
43
+ const config_1 = require("../lib/config");
44
+ const api_1 = require("../lib/api");
45
+ const errors_1 = require("../lib/errors");
46
+ const analytics_1 = require("../lib/analytics");
47
+ async function resolveWorkspaceId(config, slug) {
48
+ const configFile = await (0, config_1.loadConfig)();
49
+ const targetSlug = slug ?? configFile.workspace;
50
+ if (!targetSlug) {
51
+ // Use user's personal org
52
+ const org = await (0, api_1.getOrg)(config);
53
+ return org.id;
54
+ }
55
+ const response = await (0, api_1.request)(config, 'GET', '/workspaces');
56
+ const workspace = response.workspaces.find((w) => w.slug === targetSlug);
57
+ if (!workspace) {
58
+ throw new errors_1.CliError(`Workspace '${targetSlug}' not found`);
59
+ }
60
+ return workspace.id;
61
+ }
62
+ function statusColor(status) {
63
+ switch (status) {
64
+ case 'ready':
65
+ return chalk_1.default.green(status);
66
+ case 'building':
67
+ return chalk_1.default.yellow(status);
68
+ case 'failed':
69
+ return chalk_1.default.red(status);
70
+ case 'pending':
71
+ return chalk_1.default.gray(status);
72
+ default:
73
+ return chalk_1.default.gray(status ?? 'unknown');
74
+ }
75
+ }
76
+ async function listEnvs(config, options) {
77
+ const workspaceId = await resolveWorkspaceId(config, options.workspace);
78
+ const result = await (0, api_1.listEnvironments)(config, workspaceId);
79
+ if (result.environments.length === 0) {
80
+ console.log(chalk_1.default.gray('No environments found.'));
81
+ console.log(chalk_1.default.gray('Use `orch env create` to create one, or include a Dockerfile in your agent bundle.'));
82
+ return;
83
+ }
84
+ const table = new cli_table3_1.default({
85
+ head: [
86
+ chalk_1.default.cyan('Name'),
87
+ chalk_1.default.cyan('Status'),
88
+ chalk_1.default.cyan('Agents'),
89
+ chalk_1.default.cyan('Type'),
90
+ chalk_1.default.cyan('ID'),
91
+ ],
92
+ style: { head: [], border: [] },
93
+ });
94
+ for (const env of result.environments) {
95
+ const isDefault = env.environment.id === result.default_environment_id;
96
+ const name = isDefault
97
+ ? `${env.environment.name} ${chalk_1.default.yellow('(default)')}`
98
+ : env.environment.name;
99
+ table.push([
100
+ name,
101
+ statusColor(env.build?.status),
102
+ env.agent_count.toString(),
103
+ env.environment.is_predefined ? chalk_1.default.blue('predefined') : chalk_1.default.gray('custom'),
104
+ env.environment.id.slice(0, 8),
105
+ ]);
106
+ }
107
+ console.log();
108
+ console.log(chalk_1.default.bold('Environments:'));
109
+ console.log(table.toString());
110
+ console.log();
111
+ if (result.default_environment_id) {
112
+ const defaultEnv = result.environments.find((e) => e.environment.id === result.default_environment_id);
113
+ if (defaultEnv) {
114
+ console.log(chalk_1.default.gray(`Workspace default: ${chalk_1.default.white(defaultEnv.environment.name)}`));
115
+ console.log(chalk_1.default.gray('All new agents will use this environment unless they include their own Dockerfile.'));
116
+ }
117
+ }
118
+ }
119
+ async function getEnvStatus(config, environmentId) {
120
+ const result = await (0, api_1.getEnvironment)(config, environmentId);
121
+ console.log();
122
+ console.log(chalk_1.default.bold(`Environment: ${result.environment.name}`));
123
+ console.log();
124
+ console.log(` ID: ${result.environment.id}`);
125
+ console.log(` Status: ${statusColor(result.build?.status)}`);
126
+ console.log(` Agents: ${result.agent_count}`);
127
+ console.log(` Type: ${result.environment.is_predefined ? 'predefined' : 'custom'}`);
128
+ console.log(` Created: ${new Date(result.environment.created_at).toLocaleString()}`);
129
+ if (result.build?.status === 'failed') {
130
+ console.log();
131
+ console.log(chalk_1.default.red('Build Error:'));
132
+ console.log(chalk_1.default.red(` ${result.build.error_message || 'Unknown error'}`));
133
+ }
134
+ if (result.build?.build_logs) {
135
+ console.log();
136
+ console.log(chalk_1.default.gray('Build Logs:'));
137
+ console.log(chalk_1.default.gray(result.build.build_logs));
138
+ }
139
+ console.log();
140
+ console.log(chalk_1.default.gray('Dockerfile:'));
141
+ console.log(chalk_1.default.gray('---'));
142
+ console.log(result.environment.dockerfile_content);
143
+ console.log(chalk_1.default.gray('---'));
144
+ }
145
+ async function createEnv(config, options) {
146
+ let dockerfileContent;
147
+ try {
148
+ dockerfileContent = await fs.readFile(options.file, 'utf-8');
149
+ }
150
+ catch (err) {
151
+ throw new errors_1.CliError(`Failed to read Dockerfile: ${options.file}`);
152
+ }
153
+ console.log(chalk_1.default.gray(`Creating environment '${options.name}'...`));
154
+ const result = await (0, api_1.createEnvironment)(config, options.name, dockerfileContent);
155
+ if (result.reused) {
156
+ console.log(chalk_1.default.cyan('Existing environment with same Dockerfile found, reusing.'));
157
+ console.log(`Environment ID: ${result.environment.id}`);
158
+ }
159
+ else {
160
+ console.log(chalk_1.default.green('Environment created, build started.'));
161
+ console.log(`Environment ID: ${result.environment.id}`);
162
+ console.log();
163
+ console.log(chalk_1.default.gray(`Check build status: orch env status ${result.environment.id}`));
164
+ }
165
+ await (0, analytics_1.track)('env_create', {
166
+ environment_id: result.environment.id,
167
+ reused: result.reused,
168
+ });
169
+ }
170
+ async function deleteEnv(config, environmentId) {
171
+ console.log(chalk_1.default.gray(`Deleting environment ${environmentId}...`));
172
+ await (0, api_1.deleteEnvironment)(config, environmentId);
173
+ console.log(chalk_1.default.green('Environment deleted.'));
174
+ await (0, analytics_1.track)('env_delete', { environment_id: environmentId });
175
+ }
176
+ async function setDefault(config, environmentId, options) {
177
+ const workspaceId = await resolveWorkspaceId(config, options.workspace);
178
+ console.log(chalk_1.default.gray(`Setting default environment for workspace...`));
179
+ await (0, api_1.setWorkspaceDefaultEnvironment)(config, workspaceId, environmentId);
180
+ console.log(chalk_1.default.green('Default environment set for workspace.'));
181
+ console.log(chalk_1.default.gray('All new agents will use this environment unless they include their own Dockerfile.'));
182
+ await (0, analytics_1.track)('env_set_default', {
183
+ environment_id: environmentId,
184
+ workspace_id: workspaceId,
185
+ });
186
+ }
187
+ async function clearDefault(config, options) {
188
+ const workspaceId = await resolveWorkspaceId(config, options.workspace);
189
+ console.log(chalk_1.default.gray(`Clearing default environment for workspace...`));
190
+ await (0, api_1.setWorkspaceDefaultEnvironment)(config, workspaceId, null);
191
+ console.log(chalk_1.default.green('Default environment cleared. Agents will use base image.'));
192
+ await (0, analytics_1.track)('env_clear_default', { workspace_id: workspaceId });
193
+ }
194
+ function registerEnvCommand(program) {
195
+ const env = program
196
+ .command('env')
197
+ .description('Manage custom Docker environments for code agents');
198
+ env
199
+ .command('list')
200
+ .description('List environments in workspace')
201
+ .option('-w, --workspace <slug>', 'Workspace slug')
202
+ .action(async (options) => {
203
+ const config = await (0, config_1.getResolvedConfig)();
204
+ await listEnvs(config, options);
205
+ });
206
+ env
207
+ .command('status <environment-id>')
208
+ .description('Check environment build status')
209
+ .action(async (environmentId) => {
210
+ const config = await (0, config_1.getResolvedConfig)();
211
+ await getEnvStatus(config, environmentId);
212
+ });
213
+ env
214
+ .command('create')
215
+ .description('Create environment from Dockerfile')
216
+ .requiredOption('-f, --file <path>', 'Path to Dockerfile')
217
+ .requiredOption('-n, --name <name>', 'Environment name')
218
+ .action(async (options) => {
219
+ const config = await (0, config_1.getResolvedConfig)();
220
+ await createEnv(config, options);
221
+ });
222
+ env
223
+ .command('delete <environment-id>')
224
+ .description('Delete an environment')
225
+ .action(async (environmentId) => {
226
+ const config = await (0, config_1.getResolvedConfig)();
227
+ await deleteEnv(config, environmentId);
228
+ });
229
+ env
230
+ .command('set-default <environment-id>')
231
+ .description('Set workspace default environment (all agents use this)')
232
+ .option('-w, --workspace <slug>', 'Workspace slug (defaults to current)')
233
+ .action(async (environmentId, options) => {
234
+ const config = await (0, config_1.getResolvedConfig)();
235
+ await setDefault(config, environmentId, options);
236
+ });
237
+ env
238
+ .command('clear-default')
239
+ .description('Clear workspace default environment (agents use base image)')
240
+ .option('-w, --workspace <slug>', 'Workspace slug (defaults to current)')
241
+ .action(async (options) => {
242
+ const config = await (0, config_1.getResolvedConfig)();
243
+ await clearDefault(config, options);
244
+ });
245
+ }
@@ -25,6 +25,7 @@ const config_1 = require("./config");
25
25
  const install_1 = require("./install");
26
26
  const formats_1 = require("./formats");
27
27
  const update_1 = require("./update");
28
+ const env_1 = require("./env");
28
29
  function registerCommands(program) {
29
30
  (0, login_1.registerLoginCommand)(program);
30
31
  (0, whoami_1.registerWhoamiCommand)(program);
@@ -50,4 +51,5 @@ function registerCommands(program) {
50
51
  (0, install_1.registerInstallCommand)(program);
51
52
  (0, formats_1.registerFormatsCommand)(program);
52
53
  (0, update_1.registerUpdateCommand)(program);
54
+ (0, env_1.registerEnvCommand)(program);
53
55
  }
@@ -8,6 +8,7 @@ const promises_1 = __importDefault(require("fs/promises"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const os_1 = __importDefault(require("os"));
10
10
  const yaml_1 = __importDefault(require("yaml"));
11
+ const chalk_1 = __importDefault(require("chalk"));
11
12
  const config_1 = require("../lib/config");
12
13
  const api_1 = require("../lib/api");
13
14
  const errors_1 = require("../lib/errors");
@@ -463,6 +464,20 @@ function registerPublishCommand(program) {
463
464
  process.stdout.write(` Uploading bundle...\n`);
464
465
  const uploadResult = await (0, api_1.uploadCodeBundle)(config, agentId, bundlePath, manifest.entrypoint);
465
466
  process.stdout.write(` Uploaded: ${uploadResult.code_hash.substring(0, 12)}...\n`);
467
+ // Show environment info if applicable
468
+ if (uploadResult.environment_id) {
469
+ if (uploadResult.environment_source === 'dockerfile_new') {
470
+ process.stdout.write(` ${chalk_1.default.cyan('Custom environment detected (Dockerfile)')}\n`);
471
+ process.stdout.write(` ${chalk_1.default.yellow('Environment building...')} Agent will be ready when build completes.\n`);
472
+ process.stdout.write(` ${chalk_1.default.gray(`Check status: orch env status ${uploadResult.environment_id}`)}\n`);
473
+ }
474
+ else if (uploadResult.environment_source === 'dockerfile_reused') {
475
+ process.stdout.write(` ${chalk_1.default.green('Custom environment (reusing existing build)')}\n`);
476
+ }
477
+ else if (uploadResult.environment_source === 'workspace_default') {
478
+ process.stdout.write(` ${chalk_1.default.cyan('Using workspace default environment')}\n`);
479
+ }
480
+ }
466
481
  }
467
482
  finally {
468
483
  // Clean up temp files
package/dist/lib/api.js CHANGED
@@ -59,6 +59,11 @@ exports.deleteAgent = deleteAgent;
59
59
  exports.previewAgentVersion = previewAgentVersion;
60
60
  exports.reportInstall = reportInstall;
61
61
  exports.fetchUserProfile = fetchUserProfile;
62
+ exports.listEnvironments = listEnvironments;
63
+ exports.getEnvironment = getEnvironment;
64
+ exports.createEnvironment = createEnvironment;
65
+ exports.deleteEnvironment = deleteEnvironment;
66
+ exports.setWorkspaceDefaultEnvironment = setWorkspaceDefaultEnvironment;
62
67
  const errors_1 = require("./errors");
63
68
  const DEFAULT_TIMEOUT_MS = 15000;
64
69
  const CALL_TIMEOUT_MS = 120000; // 2 minutes for agent calls (can take time)
@@ -399,3 +404,40 @@ async function fetchUserProfile(config) {
399
404
  const result = await request(config, 'GET', '/users/me');
400
405
  return result.user;
401
406
  }
407
+ /**
408
+ * List environments in a workspace (plus predefined).
409
+ */
410
+ async function listEnvironments(config, workspaceId) {
411
+ const params = workspaceId ? `?workspace_id=${encodeURIComponent(workspaceId)}` : '';
412
+ return request(config, 'GET', `/environments${params}`);
413
+ }
414
+ /**
415
+ * Get environment details including build status.
416
+ */
417
+ async function getEnvironment(config, environmentId) {
418
+ return request(config, 'GET', `/environments/${environmentId}`);
419
+ }
420
+ /**
421
+ * Create a new environment from Dockerfile.
422
+ */
423
+ async function createEnvironment(config, name, dockerfileContent) {
424
+ return request(config, 'POST', '/environments', {
425
+ body: JSON.stringify({ name, dockerfile_content: dockerfileContent }),
426
+ headers: { 'Content-Type': 'application/json' },
427
+ });
428
+ }
429
+ /**
430
+ * Delete an environment (must have no agents using it).
431
+ */
432
+ async function deleteEnvironment(config, environmentId) {
433
+ return request(config, 'DELETE', `/environments/${environmentId}`);
434
+ }
435
+ /**
436
+ * Set workspace default environment.
437
+ */
438
+ async function setWorkspaceDefaultEnvironment(config, workspaceId, environmentId) {
439
+ return request(config, 'POST', `/environments/workspaces/${workspaceId}/default-environment`, {
440
+ body: JSON.stringify({ environment_id: environmentId }),
441
+ headers: { 'Content-Type': 'application/json' },
442
+ });
443
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.7",
3
+ "version": "0.3.8",
4
4
  "description": "Command-line interface for the orchagent AI agent marketplace",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",