@orchagent/cli 0.3.7 → 0.3.10

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");
@@ -160,6 +161,7 @@ function registerPublishCommand(program) {
160
161
  .option('--dry-run', 'Show what would be published without making changes')
161
162
  .option('--skills <skills>', 'Default skills (comma-separated, e.g., org/skill@v1,org/other@v1)')
162
163
  .option('--skills-locked', 'Lock default skills (callers cannot override via headers)')
164
+ .option('--docker', 'Include Dockerfile for custom environment (builds E2B template)')
163
165
  .action(async (options) => {
164
166
  if (options.private) {
165
167
  process.stderr.write('Warning: --private is deprecated (private is now the default). You can safely remove it.\n');
@@ -448,10 +450,23 @@ function registerPublishCommand(program) {
448
450
  const tempDir = await promises_1.default.mkdtemp(path_1.default.join(os_1.default.tmpdir(), 'orchagent-bundle-'));
449
451
  const bundlePath = path_1.default.join(tempDir, 'bundle.zip');
450
452
  try {
453
+ // Build include patterns - add Dockerfile if --docker flag is set
454
+ const includePatterns = [...(manifest.bundle?.include || [])];
455
+ if (options.docker) {
456
+ const dockerfilePath = path_1.default.join(cwd, 'Dockerfile');
457
+ try {
458
+ await promises_1.default.access(dockerfilePath);
459
+ includePatterns.push('Dockerfile');
460
+ process.stdout.write(` Including Dockerfile for custom environment\n`);
461
+ }
462
+ catch {
463
+ throw new errors_1.CliError('--docker flag specified but no Dockerfile found in project directory');
464
+ }
465
+ }
451
466
  const bundleResult = await (0, bundle_1.createCodeBundle)(cwd, bundlePath, {
452
467
  entrypoint: manifest.entrypoint,
453
468
  exclude: manifest.bundle?.exclude,
454
- include: manifest.bundle?.include,
469
+ include: includePatterns.length > 0 ? includePatterns : undefined,
455
470
  });
456
471
  process.stdout.write(` Created bundle: ${bundleResult.fileCount} files, ${(bundleResult.sizeBytes / 1024).toFixed(1)}KB\n`);
457
472
  // Validate bundle size
@@ -463,6 +478,20 @@ function registerPublishCommand(program) {
463
478
  process.stdout.write(` Uploading bundle...\n`);
464
479
  const uploadResult = await (0, api_1.uploadCodeBundle)(config, agentId, bundlePath, manifest.entrypoint);
465
480
  process.stdout.write(` Uploaded: ${uploadResult.code_hash.substring(0, 12)}...\n`);
481
+ // Show environment info if applicable
482
+ if (uploadResult.environment_id) {
483
+ if (uploadResult.environment_source === 'dockerfile_new') {
484
+ process.stdout.write(` ${chalk_1.default.cyan('Custom environment detected (Dockerfile)')}\n`);
485
+ process.stdout.write(` ${chalk_1.default.yellow('Environment building...')} Agent will be ready when build completes.\n`);
486
+ process.stdout.write(` ${chalk_1.default.gray(`Check status: orch env status ${uploadResult.environment_id}`)}\n`);
487
+ }
488
+ else if (uploadResult.environment_source === 'dockerfile_reused') {
489
+ process.stdout.write(` ${chalk_1.default.green('Custom environment (reusing existing build)')}\n`);
490
+ }
491
+ else if (uploadResult.environment_source === 'workspace_default') {
492
+ process.stdout.write(` ${chalk_1.default.cyan('Using workspace default environment')}\n`);
493
+ }
494
+ }
466
495
  }
467
496
  finally {
468
497
  // 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.10",
4
4
  "description": "Command-line interface for the orchagent AI agent marketplace",
5
5
  "license": "MIT",
6
6
  "author": "orchagent <hello@orchagent.io>",