@orchagent/cli 0.3.90 → 0.3.91

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.
@@ -40,11 +40,13 @@ exports.registerSkillCommand = registerSkillCommand;
40
40
  const promises_1 = __importDefault(require("fs/promises"));
41
41
  const path_1 = __importDefault(require("path"));
42
42
  const os_1 = __importDefault(require("os"));
43
+ const chalk_1 = __importDefault(require("chalk"));
43
44
  const config_1 = require("../lib/config");
44
45
  const api_1 = require("../lib/api");
45
46
  const errors_1 = require("../lib/errors");
46
47
  const analytics_1 = require("../lib/analytics");
47
48
  const installed_1 = require("../lib/installed");
49
+ const agents_1 = require("./agents");
48
50
  const package_json_1 = __importDefault(require("../../package.json"));
49
51
  const DEFAULT_VERSION = 'latest';
50
52
  function stripFrontmatter(content) {
@@ -208,15 +210,89 @@ function registerSkillCommand(program) {
208
210
  // orch skill list
209
211
  skill
210
212
  .command('list')
211
- .description('Browse available skills')
213
+ .description('List your published and installed skills')
212
214
  .option('--json', 'Output raw JSON')
213
- .action(async () => {
214
- process.stdout.write('Install a skill:\n' +
215
- ' orch skill install <org>/<skill-name>\n\n' +
216
- 'View installed skills:\n' +
217
- ' orch update --check\n\n' +
218
- 'Learn more: https://docs.orchagent.io/skills\n');
219
- process.exit(0);
215
+ .action(async (options) => {
216
+ const config = await (0, config_1.getResolvedConfig)();
217
+ const jsonMode = options.json === true;
218
+ // Fetch published skills (only if authenticated)
219
+ let publishedSkills = [];
220
+ if (config.apiKey) {
221
+ const configFile = await (0, config_1.loadConfig)();
222
+ const orgSlug = configFile.workspace ?? config.defaultOrg;
223
+ const workspaceId = orgSlug ? await (0, api_1.resolveWorkspaceIdForOrg)(config, orgSlug) : undefined;
224
+ const allAgents = await (0, api_1.listMyAgents)(config, workspaceId);
225
+ publishedSkills = allAgents.filter(a => a.type === 'skill');
226
+ }
227
+ // Fetch locally installed skills
228
+ const installed = await (0, installed_1.getInstalled)();
229
+ // JSON output
230
+ if (jsonMode) {
231
+ const { agents: latestSkills } = (0, agents_1.latestOnly)(publishedSkills);
232
+ process.stdout.write(JSON.stringify({
233
+ published: latestSkills,
234
+ installed,
235
+ }, null, 2) + '\n');
236
+ return;
237
+ }
238
+ // Empty state
239
+ if (publishedSkills.length === 0 && installed.length === 0) {
240
+ process.stdout.write('No skills found.\n\n' +
241
+ 'Install a skill:\n' +
242
+ ' orch skill install <org>/<skill-name>\n\n' +
243
+ 'Create a skill:\n' +
244
+ ' orch skill create <name>\n');
245
+ return;
246
+ }
247
+ // Published skills table
248
+ if (publishedSkills.length > 0) {
249
+ const { agents: latestSkills, versionCounts } = (0, agents_1.latestOnly)(publishedSkills);
250
+ const Table = (await Promise.resolve().then(() => __importStar(require('cli-table3')))).default;
251
+ const table = new Table({
252
+ head: [
253
+ chalk_1.default.bold('Skill'),
254
+ chalk_1.default.bold('Version'),
255
+ chalk_1.default.bold('Description'),
256
+ ],
257
+ });
258
+ for (const skill of latestSkills) {
259
+ const desc = skill.description
260
+ ? skill.description.length > 60
261
+ ? skill.description.slice(0, 57) + '...'
262
+ : skill.description
263
+ : '-';
264
+ let version = skill.version;
265
+ const count = versionCounts.get(skill.name) ?? 1;
266
+ if (count > 1) {
267
+ version = `${skill.version} (${count} total)`;
268
+ }
269
+ table.push([skill.name, version, desc]);
270
+ }
271
+ process.stdout.write(`Published Skills\n${table.toString()}\n`);
272
+ process.stdout.write(`\n${latestSkills.length} skill${latestSkills.length === 1 ? '' : 's'}`);
273
+ if (publishedSkills.length > latestSkills.length) {
274
+ process.stdout.write(` (${publishedSkills.length} versions total)`);
275
+ }
276
+ process.stdout.write('\n');
277
+ }
278
+ // Installed skills table
279
+ if (installed.length > 0) {
280
+ const Table = (await Promise.resolve().then(() => __importStar(require('cli-table3')))).default;
281
+ const table = new Table({
282
+ head: [
283
+ chalk_1.default.bold('Skill'),
284
+ chalk_1.default.bold('Version'),
285
+ chalk_1.default.bold('Tool'),
286
+ chalk_1.default.bold('Scope'),
287
+ ],
288
+ });
289
+ for (const entry of installed) {
290
+ table.push([entry.agent, entry.version, entry.format, entry.scope]);
291
+ }
292
+ if (publishedSkills.length > 0)
293
+ process.stdout.write('\n');
294
+ process.stdout.write(`Installed Skills\n${table.toString()}\n`);
295
+ }
220
296
  });
221
297
  // orch skill create [name]
222
298
  skill
@@ -15,15 +15,24 @@ const output_1 = require("../lib/output");
15
15
  async function resolveWorkspaceId(config, slug) {
16
16
  const configFile = await (0, config_1.loadConfig)();
17
17
  const targetSlug = slug ?? configFile.workspace;
18
- if (!targetSlug) {
19
- throw new errors_1.CliError('No workspace specified. Use --workspace <slug> or run `orch workspace use <slug>` first.');
20
- }
21
18
  const response = await (0, api_1.request)(config, 'GET', '/workspaces');
22
- const workspace = response.workspaces.find((w) => w.slug === targetSlug);
23
- if (!workspace) {
24
- throw new errors_1.CliError(`Workspace '${targetSlug}' not found.`);
19
+ if (targetSlug) {
20
+ const workspace = response.workspaces.find((w) => w.slug === targetSlug);
21
+ if (!workspace) {
22
+ throw new errors_1.CliError(`Workspace '${targetSlug}' not found.`);
23
+ }
24
+ return workspace.id;
25
+ }
26
+ // No workspace specified — auto-select if user has exactly one
27
+ if (response.workspaces.length === 0) {
28
+ throw new errors_1.CliError('No workspaces found. Create one with `orch workspace create <name>`.');
29
+ }
30
+ if (response.workspaces.length === 1) {
31
+ return response.workspaces[0].id;
25
32
  }
26
- return workspace.id;
33
+ const slugs = response.workspaces.map((w) => w.slug).join(', ');
34
+ throw new errors_1.CliError(`Multiple workspaces available: ${slugs}\n` +
35
+ 'Specify one with --workspace <slug> or run `orch workspace use <slug>`.');
27
36
  }
28
37
  function isUuid(value) {
29
38
  return /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(value);
@@ -20,7 +20,13 @@ function registerTreeCommand(program) {
20
20
  if (!config.apiKey) {
21
21
  throw new errors_1.CliError('Authentication required. Run: orch login');
22
22
  }
23
- const { org, agent, version } = (0, agent_ref_1.parseAgentRef)(agentArg);
23
+ const parsed = (0, agent_ref_1.parseAgentRef)(agentArg);
24
+ const configFile = await (0, config_1.loadConfig)();
25
+ const org = parsed.org ?? configFile.workspace ?? config.defaultOrg;
26
+ if (!org) {
27
+ throw new errors_1.CliError('Missing org. Use org/agent format or set default org.');
28
+ }
29
+ const { agent, version } = parsed;
24
30
  const tree = await (0, api_1.request)(config, 'GET', `/agents/${org}/${agent}/${version}/tree`);
25
31
  if (options.json) {
26
32
  console.log(JSON.stringify(tree, null, 2));
@@ -16,15 +16,24 @@ function deriveSlug(name) {
16
16
  async function resolveWorkspaceId(config, slug) {
17
17
  const configFile = await (0, config_1.loadConfig)();
18
18
  const targetSlug = slug ?? configFile.workspace;
19
- if (!targetSlug) {
20
- throw new errors_1.CliError('No workspace specified. Use --workspace <slug> or run `orchagent workspace use <slug>` first.');
21
- }
22
19
  const response = await (0, api_1.request)(config, 'GET', '/workspaces');
23
- const workspace = response.workspaces.find((w) => w.slug === targetSlug);
24
- if (!workspace) {
25
- throw new errors_1.CliError(`Workspace '${targetSlug}' not found.`);
20
+ if (targetSlug) {
21
+ const workspace = response.workspaces.find((w) => w.slug === targetSlug);
22
+ if (!workspace) {
23
+ throw new errors_1.CliError(`Workspace '${targetSlug}' not found.`);
24
+ }
25
+ return workspace.id;
26
+ }
27
+ // No workspace specified — auto-select if user has exactly one
28
+ if (response.workspaces.length === 0) {
29
+ throw new errors_1.CliError('No workspaces found. Create one with `orch workspace create <name>`.');
30
+ }
31
+ if (response.workspaces.length === 1) {
32
+ return response.workspaces[0].id;
26
33
  }
27
- return workspace.id;
34
+ const slugs = response.workspaces.map((w) => w.slug).join(', ');
35
+ throw new errors_1.CliError(`Multiple workspaces available: ${slugs}\n` +
36
+ 'Specify one with --workspace <slug> or run `orch workspace use <slug>`.');
28
37
  }
29
38
  async function listWorkspaces(config, options) {
30
39
  const response = await (0, api_1.request)(config, 'GET', '/workspaces');
@@ -6,8 +6,11 @@ function parseAgentRef(value, defaultVersion = 'latest') {
6
6
  const [ref, versionPart] = value.split('@');
7
7
  const version = versionPart?.trim() || defaultVersion;
8
8
  const segments = ref.split('/');
9
+ if (segments.length === 1) {
10
+ return { org: undefined, agent: segments[0], version };
11
+ }
9
12
  if (segments.length === 2) {
10
13
  return { org: segments[0], agent: segments[1], version };
11
14
  }
12
- throw new errors_1.CliError('Invalid agent reference. Use org/agent[@version] format');
15
+ throw new errors_1.CliError('Invalid agent reference. Use agent or org/agent[@version] format');
13
16
  }
@@ -59,6 +59,7 @@ async function waitForCallback(port, timeoutMs) {
59
59
  let server = null;
60
60
  const cleanup = () => {
61
61
  if (server) {
62
+ server.closeAllConnections();
62
63
  server.close();
63
64
  server = null;
64
65
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orchagent/cli",
3
- "version": "0.3.90",
3
+ "version": "0.3.91",
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>",