@guildai/cli 0.3.16 → 0.3.17

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.
Files changed (58) hide show
  1. package/dist/commands/agent/clone.js +21 -40
  2. package/dist/commands/agent/code.js +12 -32
  3. package/dist/commands/agent/create.js +14 -30
  4. package/dist/commands/agent/fork.js +27 -73
  5. package/dist/commands/agent/get.js +5 -4
  6. package/dist/commands/agent/grep.js +7 -9
  7. package/dist/commands/agent/init.js +2 -0
  8. package/dist/commands/agent/list.js +5 -12
  9. package/dist/commands/agent/publish.js +27 -44
  10. package/dist/commands/agent/pull.js +8 -35
  11. package/dist/commands/agent/revalidate.js +8 -16
  12. package/dist/commands/agent/save.js +23 -74
  13. package/dist/commands/agent/search.js +5 -12
  14. package/dist/commands/agent/tags/add.js +14 -24
  15. package/dist/commands/agent/tags/list.js +12 -23
  16. package/dist/commands/agent/tags/remove.js +16 -27
  17. package/dist/commands/agent/tags/set.js +14 -19
  18. package/dist/commands/agent/unpublish.js +12 -17
  19. package/dist/commands/agent/update.js +12 -29
  20. package/dist/commands/agent/versions.js +7 -11
  21. package/dist/commands/auth/login.js +4 -2
  22. package/dist/commands/auth/logout.js +3 -1
  23. package/dist/commands/auth/status.js +4 -3
  24. package/dist/commands/auth/token.js +3 -2
  25. package/dist/commands/config/get.js +7 -9
  26. package/dist/commands/config/list.js +13 -11
  27. package/dist/commands/config/path.js +6 -4
  28. package/dist/commands/config/set.js +17 -22
  29. package/dist/commands/doctor.js +9 -7
  30. package/dist/commands/session/create.js +7 -5
  31. package/dist/commands/session/events.js +5 -3
  32. package/dist/commands/session/get.js +5 -3
  33. package/dist/commands/session/list.js +5 -4
  34. package/dist/commands/session/send.js +7 -5
  35. package/dist/commands/session/tasks.js +5 -3
  36. package/dist/commands/setup.js +15 -14
  37. package/dist/commands/trigger/activate.js +7 -6
  38. package/dist/commands/trigger/create.js +16 -15
  39. package/dist/commands/trigger/deactivate.js +7 -6
  40. package/dist/commands/trigger/get.js +5 -4
  41. package/dist/commands/trigger/list.js +5 -5
  42. package/dist/commands/trigger/sessions.js +7 -6
  43. package/dist/commands/trigger/update.js +11 -10
  44. package/dist/commands/version.js +7 -5
  45. package/dist/commands/workspace/agent/add.js +16 -22
  46. package/dist/commands/workspace/agent/list.js +9 -30
  47. package/dist/commands/workspace/agent/remove.js +9 -15
  48. package/dist/commands/workspace/context/edit.js +13 -27
  49. package/dist/commands/workspace/context/get.js +8 -14
  50. package/dist/commands/workspace/context/list.js +7 -38
  51. package/dist/commands/workspace/context/publish.js +7 -11
  52. package/dist/commands/workspace/create.js +7 -11
  53. package/dist/commands/workspace/current.js +19 -31
  54. package/dist/commands/workspace/get.js +7 -11
  55. package/dist/commands/workspace/list.js +5 -8
  56. package/dist/commands/workspace/select.js +17 -22
  57. package/dist/lib/output.js +4 -4
  58. package/package.json +1 -1
@@ -4,7 +4,7 @@ import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { getWorkspaceId } from '../../lib/guild-config.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
7
- import { format } from '../../lib/progress.js';
7
+ import { createOutputWriter } from '../../lib/output.js';
8
8
  import { WEBHOOK_SERVICES, TIME_TRIGGER_FREQUENCIES, } from '../../lib/api-types.js';
9
9
  export function createTriggerCreateCommand() {
10
10
  const cmd = new Command('create');
@@ -25,16 +25,17 @@ export function createTriggerCreateCommand() {
25
25
  .option('--days-of-month <days>', 'Days of month (comma-separated: 1,15,-1)')
26
26
  .option('--input <json>', 'Agent input as JSON object')
27
27
  .action(async (options) => {
28
+ const output = createOutputWriter();
28
29
  try {
29
30
  const token = await getAuthToken();
30
31
  if (!token) {
31
- format.error('Not authenticated. Run: guild auth login');
32
+ output.error('Not authenticated. Run: guild auth login');
32
33
  process.exit(1);
33
34
  }
34
35
  // Validate trigger type
35
36
  const triggerType = options.type.toLowerCase();
36
37
  if (triggerType !== 'webhook' && triggerType !== 'time') {
37
- format.error('--type must be "webhook" or "time"');
38
+ output.error('--type must be "webhook" or "time"');
38
39
  process.exit(1);
39
40
  }
40
41
  // Resolve workspace
@@ -42,7 +43,7 @@ export function createTriggerCreateCommand() {
42
43
  if (!workspaceId) {
43
44
  const resolved = await getWorkspaceId();
44
45
  if (!resolved) {
45
- format.error('No workspace specified. Run: guild workspace select');
46
+ output.error('No workspace specified. Run: guild workspace select');
46
47
  process.exit(1);
47
48
  }
48
49
  workspaceId = resolved.workspaceId;
@@ -54,7 +55,7 @@ export function createTriggerCreateCommand() {
54
55
  wa.agent.name === options.agent ||
55
56
  wa.agent.id === options.agent);
56
57
  if (!workspaceAgent) {
57
- format.error(`Agent "${options.agent}" not found. Run: guild workspace agent add ${options.agent}`);
58
+ output.error(`Agent "${options.agent}" not found. Run: guild workspace agent add ${options.agent}`);
58
59
  process.exit(1);
59
60
  }
60
61
  // Build request body based on trigger type
@@ -62,12 +63,12 @@ export function createTriggerCreateCommand() {
62
63
  if (triggerType === 'webhook') {
63
64
  // Validate webhook-specific options
64
65
  if (!options.service) {
65
- format.error(`--service is required for webhook triggers. Valid: ${WEBHOOK_SERVICES.join(', ')}`);
66
+ output.error(`--service is required for webhook triggers. Valid: ${WEBHOOK_SERVICES.join(', ')}`);
66
67
  process.exit(1);
67
68
  }
68
69
  const service = options.service.toUpperCase();
69
70
  if (!WEBHOOK_SERVICES.includes(service)) {
70
- format.error(`Invalid service "${options.service}". Valid: ${WEBHOOK_SERVICES.join(', ')}`);
71
+ output.error(`Invalid service "${options.service}". Valid: ${WEBHOOK_SERVICES.join(', ')}`);
71
72
  process.exit(1);
72
73
  }
73
74
  body = {
@@ -86,7 +87,7 @@ export function createTriggerCreateCommand() {
86
87
  body.service_config = JSON.parse(options.serviceConfig);
87
88
  }
88
89
  catch {
89
- format.error('--service-config must be valid JSON');
90
+ output.error('--service-config must be valid JSON');
90
91
  process.exit(1);
91
92
  }
92
93
  }
@@ -94,12 +95,12 @@ export function createTriggerCreateCommand() {
94
95
  else {
95
96
  // Time trigger
96
97
  if (!options.frequency) {
97
- format.error(`--frequency is required for time triggers. Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
98
+ output.error(`--frequency is required for time triggers. Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
98
99
  process.exit(1);
99
100
  }
100
101
  const frequency = options.frequency.toUpperCase();
101
102
  if (!TIME_TRIGGER_FREQUENCIES.includes(frequency)) {
102
- format.error(`Invalid frequency "${options.frequency}". Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
103
+ output.error(`Invalid frequency "${options.frequency}". Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
103
104
  process.exit(1);
104
105
  }
105
106
  // Parse agent input
@@ -109,7 +110,7 @@ export function createTriggerCreateCommand() {
109
110
  agentInput = JSON.parse(options.input);
110
111
  }
111
112
  catch {
112
- format.error('--input must be valid JSON');
113
+ output.error('--input must be valid JSON');
113
114
  process.exit(1);
114
115
  }
115
116
  }
@@ -130,19 +131,19 @@ export function createTriggerCreateCommand() {
130
131
  }
131
132
  }
132
133
  const response = await client.post(`/workspaces/${workspaceId}/triggers`, body);
133
- console.log(JSON.stringify(response, null, 2));
134
+ output.data(response);
134
135
  }
135
136
  catch (error) {
136
137
  const formattedError = handleAxiosError(error);
137
138
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
138
- format.error('Not authenticated. Run: guild auth login');
139
+ output.error('Not authenticated. Run: guild auth login');
139
140
  process.exit(1);
140
141
  }
141
142
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
142
- format.error('Workspace not found. Run: guild workspace select');
143
+ output.error('Workspace not found. Run: guild workspace select');
143
144
  process.exit(1);
144
145
  }
145
- format.error(formattedError.details);
146
+ output.error(formattedError.details);
146
147
  process.exit(1);
147
148
  }
148
149
  });
@@ -3,34 +3,35 @@ import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
- import { format } from '../../lib/progress.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
7
7
  export function createTriggerDeactivateCommand() {
8
8
  const cmd = new Command('deactivate');
9
9
  cmd
10
10
  .description('Deactivate a trigger')
11
11
  .argument('<trigger-id>', 'Trigger ID')
12
12
  .action(async (triggerId) => {
13
+ const output = createOutputWriter();
13
14
  try {
14
15
  const token = await getAuthToken();
15
16
  if (!token) {
16
- format.error('Not authenticated. Run: guild auth login');
17
+ output.error('Not authenticated. Run: guild auth login');
17
18
  process.exit(1);
18
19
  }
19
20
  const client = new GuildAPIClient();
20
21
  const response = await client.post(`/triggers/${triggerId}/deactivate`, {});
21
- console.log(JSON.stringify(response, null, 2));
22
+ output.data(response);
22
23
  }
23
24
  catch (error) {
24
25
  const formattedError = handleAxiosError(error);
25
26
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
26
- format.error('Not authenticated. Run: guild auth login');
27
+ output.error('Not authenticated. Run: guild auth login');
27
28
  process.exit(1);
28
29
  }
29
30
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
30
- format.error('Trigger not found.');
31
+ output.error('Trigger not found.');
31
32
  process.exit(1);
32
33
  }
33
- format.error(formattedError.details);
34
+ output.error(formattedError.details);
34
35
  process.exit(1);
35
36
  }
36
37
  });
@@ -3,26 +3,27 @@ import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { handleAxiosError } from '../../lib/errors.js';
6
- import { format } from '../../lib/progress.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
7
7
  export function createTriggerGetCommand() {
8
8
  const cmd = new Command('get');
9
9
  cmd
10
10
  .description('Get trigger details')
11
11
  .argument('<trigger-id>', 'Trigger ID')
12
12
  .action(async (triggerId) => {
13
+ const output = createOutputWriter();
13
14
  try {
14
15
  const token = await getAuthToken();
15
16
  if (!token) {
16
- format.error('Not authenticated. Run: guild auth login');
17
+ output.error('Not authenticated. Run: guild auth login');
17
18
  process.exit(1);
18
19
  }
19
20
  const client = new GuildAPIClient();
20
21
  const response = await client.get(`/triggers/${triggerId}`);
21
- console.log(JSON.stringify(response, null, 2));
22
+ output.data(response);
22
23
  }
23
24
  catch (error) {
24
25
  const formattedError = handleAxiosError(error);
25
- format.error(formattedError.details);
26
+ output.error(formattedError.details);
26
27
  process.exit(1);
27
28
  }
28
29
  });
@@ -4,9 +4,8 @@ import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { getWorkspaceId } from '../../lib/guild-config.js';
6
6
  import { handleAxiosError } from '../../lib/errors.js';
7
- import { format } from '../../lib/progress.js';
8
7
  import { getOutputMode } from '../../lib/output-mode.js';
9
- import { formatTriggerTable } from '../../lib/output.js';
8
+ import { createOutputWriter, formatTriggerTable } from '../../lib/output.js';
10
9
  export function createTriggerListCommand() {
11
10
  const cmd = new Command('list');
12
11
  cmd
@@ -15,10 +14,11 @@ export function createTriggerListCommand() {
15
14
  .option('--limit <number>', 'Number of results to return', '20')
16
15
  .option('--offset <number>', 'Offset for pagination', '0')
17
16
  .action(async (options) => {
17
+ const output = createOutputWriter();
18
18
  try {
19
19
  const token = await getAuthToken();
20
20
  if (!token) {
21
- format.error('Not authenticated. Run: guild auth login');
21
+ output.error('Not authenticated. Run: guild auth login');
22
22
  process.exit(1);
23
23
  }
24
24
  // Resolve workspace
@@ -26,7 +26,7 @@ export function createTriggerListCommand() {
26
26
  if (!workspaceId) {
27
27
  const resolved = await getWorkspaceId();
28
28
  if (!resolved) {
29
- format.error('No workspace specified. Run: guild workspace select');
29
+ output.error('No workspace specified. Run: guild workspace select');
30
30
  process.exit(1);
31
31
  }
32
32
  workspaceId = resolved.workspaceId;
@@ -46,7 +46,7 @@ export function createTriggerListCommand() {
46
46
  }
47
47
  catch (error) {
48
48
  const formattedError = handleAxiosError(error);
49
- format.error(formattedError.details);
49
+ output.error(formattedError.details);
50
50
  process.exit(1);
51
51
  }
52
52
  });
@@ -3,7 +3,7 @@ import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
- import { format } from '../../lib/progress.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
7
7
  export function createTriggerSessionsCommand() {
8
8
  const cmd = new Command('sessions');
9
9
  cmd
@@ -12,10 +12,11 @@ export function createTriggerSessionsCommand() {
12
12
  .option('--limit <number>', 'Number of results to return', '20')
13
13
  .option('--offset <number>', 'Offset for pagination', '0')
14
14
  .action(async (triggerId, options) => {
15
+ const output = createOutputWriter();
15
16
  try {
16
17
  const token = await getAuthToken();
17
18
  if (!token) {
18
- format.error('Not authenticated. Run: guild auth login');
19
+ output.error('Not authenticated. Run: guild auth login');
19
20
  process.exit(1);
20
21
  }
21
22
  const client = new GuildAPIClient();
@@ -24,19 +25,19 @@ export function createTriggerSessionsCommand() {
24
25
  params.append('limit', options.limit);
25
26
  params.append('offset', options.offset);
26
27
  const response = await client.get(`/triggers/${triggerId}/sessions?${params.toString()}`);
27
- console.log(JSON.stringify(response, null, 2));
28
+ output.data(response);
28
29
  }
29
30
  catch (error) {
30
31
  const formattedError = handleAxiosError(error);
31
32
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
32
- format.error('Not authenticated. Run: guild auth login');
33
+ output.error('Not authenticated. Run: guild auth login');
33
34
  process.exit(1);
34
35
  }
35
36
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
36
- format.error('Trigger not found.');
37
+ output.error('Trigger not found.');
37
38
  process.exit(1);
38
39
  }
39
- format.error(formattedError.details);
40
+ output.error(formattedError.details);
40
41
  process.exit(1);
41
42
  }
42
43
  });
@@ -3,7 +3,7 @@ import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../lib/auth.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
- import { format } from '../../lib/progress.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
7
7
  import { TIME_TRIGGER_FREQUENCIES, } from '../../lib/api-types.js';
8
8
  export function createTriggerUpdateCommand() {
9
9
  const cmd = new Command('update');
@@ -21,10 +21,11 @@ export function createTriggerUpdateCommand() {
21
21
  .option('--days-of-month <days>', 'Days of month, comma-separated (for time triggers)')
22
22
  .option('--input <json>', 'Agent input as JSON object (for time triggers)')
23
23
  .action(async (triggerId, options) => {
24
+ const output = createOutputWriter();
24
25
  try {
25
26
  const token = await getAuthToken();
26
27
  if (!token) {
27
- format.error('Not authenticated. Run: guild auth login');
28
+ output.error('Not authenticated. Run: guild auth login');
28
29
  process.exit(1);
29
30
  }
30
31
  const client = new GuildAPIClient();
@@ -42,7 +43,7 @@ export function createTriggerUpdateCommand() {
42
43
  body.service_config = JSON.parse(options.serviceConfig);
43
44
  }
44
45
  catch {
45
- format.error('--service-config must be valid JSON');
46
+ output.error('--service-config must be valid JSON');
46
47
  process.exit(1);
47
48
  }
48
49
  }
@@ -50,7 +51,7 @@ export function createTriggerUpdateCommand() {
50
51
  if (options.frequency !== undefined) {
51
52
  const frequency = options.frequency.toUpperCase();
52
53
  if (!TIME_TRIGGER_FREQUENCIES.includes(frequency)) {
53
- format.error(`Invalid frequency "${options.frequency}". Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
54
+ output.error(`Invalid frequency "${options.frequency}". Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
54
55
  process.exit(1);
55
56
  }
56
57
  body.frequency = frequency;
@@ -69,28 +70,28 @@ export function createTriggerUpdateCommand() {
69
70
  body.agent_input = JSON.parse(options.input);
70
71
  }
71
72
  catch {
72
- format.error('--input must be valid JSON');
73
+ output.error('--input must be valid JSON');
73
74
  process.exit(1);
74
75
  }
75
76
  }
76
77
  if (Object.keys(body).length === 0) {
77
- format.error('No update options provided. Run: guild trigger update --help');
78
+ output.error('No update options provided. Run: guild trigger update --help');
78
79
  process.exit(1);
79
80
  }
80
81
  const response = await client.patch(`/triggers/${triggerId}`, body);
81
- console.log(JSON.stringify(response, null, 2));
82
+ output.data(response);
82
83
  }
83
84
  catch (error) {
84
85
  const formattedError = handleAxiosError(error);
85
86
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
86
- format.error('Not authenticated. Run: guild auth login');
87
+ output.error('Not authenticated. Run: guild auth login');
87
88
  process.exit(1);
88
89
  }
89
90
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
90
- format.error('Trigger not found.');
91
+ output.error('Trigger not found.');
91
92
  process.exit(1);
92
93
  }
93
- format.error(formattedError.details);
94
+ output.error(formattedError.details);
94
95
  process.exit(1);
95
96
  }
96
97
  });
@@ -1,20 +1,22 @@
1
1
  // Copyright (c) 2026 Guild.ai All Rights Reserved
2
2
  import { Command } from 'commander';
3
- import chalk from 'chalk';
4
3
  import { readFileSync } from 'fs';
5
4
  import path from 'path';
6
5
  import { fileURLToPath } from 'url';
7
- import { brand } from '../lib/colors.js';
6
+ import { createOutputWriter } from '../lib/output.js';
8
7
  // ESM equivalent of __dirname
9
8
  const __filename = fileURLToPath(import.meta.url);
10
9
  const __dirname = path.dirname(__filename);
11
10
  export function createVersionCommand() {
12
11
  const cmd = new Command('version');
13
12
  cmd.description('Show Guild CLI version').action(() => {
13
+ const output = createOutputWriter();
14
14
  const packageJson = JSON.parse(readFileSync(path.join(__dirname, '../../package.json'), 'utf-8'));
15
- console.log(chalk.bold.green('Guild CLI'));
16
- console.log(`Version: ${brand(packageJson.version)}`);
17
- console.log(chalk.dim('\nUnified interface for Guild.ai agent development'));
15
+ output.data({
16
+ name: 'Guild CLI',
17
+ version: packageJson.version,
18
+ description: 'Unified interface for Guild.ai agent development',
19
+ });
18
20
  });
19
21
  return cmd;
20
22
  }
@@ -4,6 +4,7 @@ import { GuildAPIClient } from '../../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../../lib/auth.js';
5
5
  import { getWorkspaceId } from '../../../lib/guild-config.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
7
+ import { createOutputWriter } from '../../../lib/output.js';
7
8
  export function createWorkspaceAgentAddCommand() {
8
9
  const cmd = new Command('add');
9
10
  cmd
@@ -12,11 +13,11 @@ export function createWorkspaceAgentAddCommand() {
12
13
  .option('--workspace <id>', 'Target workspace ID or name')
13
14
  .option('--no-autoupdate', 'Disable automatic updates for this agent')
14
15
  .action(async (agentIdentifier, options) => {
16
+ const output = createOutputWriter();
15
17
  try {
16
18
  const token = await getAuthToken();
17
19
  if (!token) {
18
- console.error('Not authenticated. Please log in first.');
19
- console.error('Run: guild auth login');
20
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
20
21
  process.exit(1);
21
22
  }
22
23
  const client = new GuildAPIClient();
@@ -25,13 +26,7 @@ export function createWorkspaceAgentAddCommand() {
25
26
  if (!workspaceId) {
26
27
  const resolved = await getWorkspaceId();
27
28
  if (!resolved) {
28
- console.error('Error: No workspace specified.');
29
- console.error('');
30
- console.error('Either use --workspace flag:');
31
- console.error(' guild workspace agent add <agent> --workspace <workspace-id>');
32
- console.error('');
33
- console.error('Or select a default workspace:');
34
- console.error(' guild workspace select');
29
+ output.error('No workspace specified.', 'Either use --workspace flag:\n guild workspace agent add <agent> --workspace <workspace-id>\n\nOr select a default workspace:\n guild workspace select');
35
30
  process.exit(1);
36
31
  }
37
32
  workspaceId = resolved.workspaceId;
@@ -45,7 +40,7 @@ export function createWorkspaceAgentAddCommand() {
45
40
  catch (error) {
46
41
  const formattedError = handleAxiosError(error);
47
42
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
48
- console.error(`Error: Agent "${agentIdentifier}" not found`);
43
+ output.error(`Agent "${agentIdentifier}" not found`);
49
44
  process.exit(1);
50
45
  }
51
46
  if (formattedError.code === ErrorCodes.FORBIDDEN ||
@@ -65,17 +60,16 @@ export function createWorkspaceAgentAddCommand() {
65
60
  ? `v${response.agent_version.version_number}`
66
61
  : response.agent_version.sha.slice(0, 7);
67
62
  const workspaceName = response.workspace?.name || 'workspace';
68
- console.log(`✓ Added ${response.agent.full_name} to workspace "${workspaceName}"`);
69
- console.log('');
70
- console.log(`Agent: ${response.agent.full_name}`);
71
- console.log(`Version: ${versionDisplay}`);
72
- console.log(`Autoupdate: ${response.should_autoupdate ? 'enabled' : 'disabled'}`);
63
+ output.success(`Added ${response.agent.full_name} to workspace "${workspaceName}"`, {
64
+ Agent: response.agent.full_name,
65
+ Version: versionDisplay,
66
+ Autoupdate: response.should_autoupdate ? 'enabled' : 'disabled',
67
+ });
73
68
  }
74
69
  catch (error) {
75
70
  const formattedError = handleAxiosError(error);
76
71
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
77
- console.error('Not authenticated. Please log in first.');
78
- console.error('Run: guild auth login');
72
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
79
73
  process.exit(1);
80
74
  }
81
75
  if (formattedError.code === ErrorCodes.BAD_REQUEST) {
@@ -83,21 +77,21 @@ export function createWorkspaceAgentAddCommand() {
83
77
  const details = formattedError.details || '';
84
78
  if (details.includes('already added') ||
85
79
  details.includes('already installed')) {
86
- console.error(`Error: This agent is already installed in the workspace`);
80
+ output.error('This agent is already installed in the workspace');
87
81
  }
88
82
  else if (details.includes('No published version')) {
89
- console.error(`Error: No published version found for this agent`);
83
+ output.error('No published version found for this agent');
90
84
  }
91
85
  else {
92
- console.error(`Error: ${details}`);
86
+ output.error(details);
93
87
  }
94
88
  process.exit(1);
95
89
  }
96
90
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
97
- console.error(`Error: Workspace not found`);
91
+ output.error('Workspace not found');
98
92
  process.exit(1);
99
93
  }
100
- console.error(`Failed to add agent: ${formattedError.details}`);
94
+ output.error(`Failed to add agent: ${formattedError.details}`);
101
95
  process.exit(1);
102
96
  }
103
97
  });
@@ -4,6 +4,7 @@ import { GuildAPIClient } from '../../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../../lib/auth.js';
5
5
  import { getWorkspaceId } from '../../../lib/guild-config.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
7
+ import { createOutputWriter } from '../../../lib/output.js';
7
8
  export function createWorkspaceAgentListCommand() {
8
9
  const cmd = new Command('list');
9
10
  cmd
@@ -12,11 +13,11 @@ export function createWorkspaceAgentListCommand() {
12
13
  .option('--limit <number>', 'Number of results to return', '20')
13
14
  .option('--offset <number>', 'Offset for pagination', '0')
14
15
  .action(async (options) => {
16
+ const output = createOutputWriter();
15
17
  try {
16
18
  const token = await getAuthToken();
17
19
  if (!token) {
18
- console.error('Not authenticated. Please log in first.');
19
- console.error('Run: guild auth login');
20
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
20
21
  process.exit(1);
21
22
  }
22
23
  const client = new GuildAPIClient();
@@ -25,13 +26,7 @@ export function createWorkspaceAgentListCommand() {
25
26
  if (!workspaceId) {
26
27
  const resolved = await getWorkspaceId();
27
28
  if (!resolved) {
28
- console.error('Error: No workspace specified.');
29
- console.error('');
30
- console.error('Either use --workspace flag:');
31
- console.error(' guild workspace agent list --workspace <workspace-id>');
32
- console.error('');
33
- console.error('Or select a default workspace:');
34
- console.error(' guild workspace select');
29
+ output.error('No workspace specified.', 'Either use --workspace flag:\n guild workspace agent list --workspace <workspace-id>\n\nOr select a default workspace:\n guild workspace select');
35
30
  process.exit(1);
36
31
  }
37
32
  workspaceId = resolved.workspaceId;
@@ -43,38 +38,22 @@ export function createWorkspaceAgentListCommand() {
43
38
  const response = await client.get(`/workspaces/${workspaceId}/workspace_agents?${params.toString()}`);
44
39
  const agents = response.items;
45
40
  if (agents.length === 0) {
46
- console.log('No agents installed in this workspace.');
47
- console.log('');
48
- console.log('Add an agent with:');
49
- console.log(' guild workspace agent add <agent>');
41
+ output.data({ items: [], message: 'No agents installed in this workspace.' });
50
42
  return;
51
43
  }
52
- console.log(`Agents in workspace (${agents.length}):`);
53
- console.log('');
54
- for (const wa of agents) {
55
- let versionDisplay = 'unknown';
56
- if (wa.agent_version?.version_number) {
57
- versionDisplay = `v${wa.agent_version.version_number}`;
58
- }
59
- else if (wa.agent_version?.sha) {
60
- versionDisplay = wa.agent_version.sha.slice(0, 7);
61
- }
62
- const autoupdate = wa.should_autoupdate ? '' : ' [autoupdate: off]';
63
- console.log(` • ${wa.agent.full_name} (${versionDisplay})${autoupdate}`);
64
- }
44
+ output.data(response);
65
45
  }
66
46
  catch (error) {
67
47
  const formattedError = handleAxiosError(error);
68
48
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
69
- console.error('Not authenticated. Please log in first.');
70
- console.error('Run: guild auth login');
49
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
71
50
  process.exit(1);
72
51
  }
73
52
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
74
- console.error('Error: Workspace not found');
53
+ output.error('Workspace not found');
75
54
  process.exit(1);
76
55
  }
77
- console.error(`Failed to list agents: ${formattedError.details}`);
56
+ output.error(`Failed to list agents: ${formattedError.details}`);
78
57
  process.exit(1);
79
58
  }
80
59
  });
@@ -4,6 +4,7 @@ import { GuildAPIClient } from '../../../lib/api-client.js';
4
4
  import { getAuthToken } from '../../../lib/auth.js';
5
5
  import { getWorkspaceId } from '../../../lib/guild-config.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
7
+ import { createOutputWriter } from '../../../lib/output.js';
7
8
  export function createWorkspaceAgentRemoveCommand() {
8
9
  const cmd = new Command('remove');
9
10
  cmd
@@ -11,11 +12,11 @@ export function createWorkspaceAgentRemoveCommand() {
11
12
  .argument('<agent>', 'Agent identifier (e.g., owner/agent-name or UUID)')
12
13
  .option('--workspace <id>', 'Workspace ID or name')
13
14
  .action(async (agentIdentifier, options) => {
15
+ const output = createOutputWriter();
14
16
  try {
15
17
  const token = await getAuthToken();
16
18
  if (!token) {
17
- console.error('Not authenticated. Please log in first.');
18
- console.error('Run: guild auth login');
19
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
19
20
  process.exit(1);
20
21
  }
21
22
  const client = new GuildAPIClient();
@@ -24,13 +25,7 @@ export function createWorkspaceAgentRemoveCommand() {
24
25
  if (!workspaceId) {
25
26
  const resolved = await getWorkspaceId();
26
27
  if (!resolved) {
27
- console.error('Error: No workspace specified.');
28
- console.error('');
29
- console.error('Either use --workspace flag:');
30
- console.error(' guild workspace agent remove <agent> --workspace <workspace-id>');
31
- console.error('');
32
- console.error('Or select a default workspace:');
33
- console.error(' guild workspace select');
28
+ output.error('No workspace specified.', 'Either use --workspace flag:\n guild workspace agent remove <agent> --workspace <workspace-id>\n\nOr select a default workspace:\n guild workspace select');
34
29
  process.exit(1);
35
30
  }
36
31
  workspaceId = resolved.workspaceId;
@@ -43,25 +38,24 @@ export function createWorkspaceAgentRemoveCommand() {
43
38
  wa.agent.name === agentIdentifier ||
44
39
  wa.agent.id === agentIdentifier);
45
40
  if (!workspaceAgent) {
46
- console.error(`Error: Agent "${agentIdentifier}" is not installed in this workspace`);
41
+ output.error(`Agent "${agentIdentifier}" is not installed in this workspace`);
47
42
  process.exit(1);
48
43
  }
49
44
  // Remove the workspace agent
50
45
  await client.delete(`/workspace_agents/${workspaceAgent.id}`);
51
- console.log(`✓ Removed ${workspaceAgent.agent.full_name} from workspace`);
46
+ output.success(`Removed ${workspaceAgent.agent.full_name} from workspace`);
52
47
  }
53
48
  catch (error) {
54
49
  const formattedError = handleAxiosError(error);
55
50
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
56
- console.error('Not authenticated. Please log in first.');
57
- console.error('Run: guild auth login');
51
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
58
52
  process.exit(1);
59
53
  }
60
54
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
61
- console.error('Error: Workspace or agent not found');
55
+ output.error('Workspace or agent not found');
62
56
  process.exit(1);
63
57
  }
64
- console.error(`Failed to remove agent: ${formattedError.details}`);
58
+ output.error(`Failed to remove agent: ${formattedError.details}`);
65
59
  process.exit(1);
66
60
  }
67
61
  });