@guildai/cli 0.3.15 → 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 (61) 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/chat.js +85 -10
  26. package/dist/commands/config/get.js +7 -9
  27. package/dist/commands/config/list.js +13 -11
  28. package/dist/commands/config/path.js +6 -4
  29. package/dist/commands/config/set.js +17 -22
  30. package/dist/commands/doctor.js +9 -7
  31. package/dist/commands/session/create.js +7 -5
  32. package/dist/commands/session/events.js +5 -3
  33. package/dist/commands/session/get.js +5 -3
  34. package/dist/commands/session/list.js +5 -4
  35. package/dist/commands/session/send.js +7 -5
  36. package/dist/commands/session/tasks.js +5 -3
  37. package/dist/commands/setup.js +15 -14
  38. package/dist/commands/trigger/activate.js +7 -6
  39. package/dist/commands/trigger/create.js +16 -15
  40. package/dist/commands/trigger/deactivate.js +7 -6
  41. package/dist/commands/trigger/get.js +5 -4
  42. package/dist/commands/trigger/list.js +5 -5
  43. package/dist/commands/trigger/sessions.js +7 -6
  44. package/dist/commands/trigger/update.js +11 -10
  45. package/dist/commands/version.js +7 -5
  46. package/dist/commands/workspace/agent/add.js +16 -22
  47. package/dist/commands/workspace/agent/list.js +9 -30
  48. package/dist/commands/workspace/agent/remove.js +9 -15
  49. package/dist/commands/workspace/context/edit.js +13 -27
  50. package/dist/commands/workspace/context/get.js +8 -14
  51. package/dist/commands/workspace/context/list.js +7 -38
  52. package/dist/commands/workspace/context/publish.js +7 -11
  53. package/dist/commands/workspace/create.js +7 -11
  54. package/dist/commands/workspace/current.js +19 -31
  55. package/dist/commands/workspace/get.js +7 -11
  56. package/dist/commands/workspace/list.js +5 -8
  57. package/dist/commands/workspace/select.js +17 -22
  58. package/dist/components/TaskView.js +2 -0
  59. package/dist/lib/output.js +4 -4
  60. package/dist/lib/session-events.d.ts +7 -2
  61. package/package.json +1 -1
@@ -3,8 +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 } from '../../lib/errors.js';
6
- import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
7
- import { getOutputMode } from '../../lib/output-mode.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
8
7
  const SORT_MAP = {
9
8
  updated: 'updated_at',
10
9
  newest: 'created_at',
@@ -21,11 +20,11 @@ export function createAgentListCommand() {
21
20
  .option('--limit <number>', 'Number of results to return', '20')
22
21
  .option('--offset <number>', 'Offset for pagination', '0')
23
22
  .action(async (options) => {
23
+ const output = createOutputWriter();
24
24
  try {
25
25
  const token = await getAuthToken();
26
26
  if (!token) {
27
- console.error('Not authenticated. Please log in first.');
28
- console.error('Run: guild auth login');
27
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
29
28
  process.exit(1);
30
29
  }
31
30
  const client = new GuildAPIClient();
@@ -43,17 +42,11 @@ export function createAgentListCommand() {
43
42
  params.append('sort_by', sortField);
44
43
  }
45
44
  const response = await client.get(`/agents?${params.toString()}`);
46
- if (getOutputMode() === 'json') {
47
- console.log(JSON.stringify(response, null, 2));
48
- }
49
- else {
50
- formatAgentTable(response.items, response.pagination);
51
- }
45
+ output.data(response);
52
46
  }
53
47
  catch (error) {
54
- const out = createOutputWriter();
55
48
  const formattedError = handleAxiosError(error);
56
- out.error(`Failed to list agents: ${formattedError.details}`);
49
+ output.error(`Failed to list agents: ${formattedError.details}`);
57
50
  process.exit(1);
58
51
  }
59
52
  });
@@ -4,6 +4,7 @@ import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getAgentId } from '../../lib/agent-helpers.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
6
  import { pollUntilComplete } from '../../lib/polling.js';
7
+ import { createOutputWriter } from '../../lib/output.js';
7
8
  export function createAgentPublishCommand() {
8
9
  const cmd = new Command('publish');
9
10
  cmd
@@ -11,6 +12,7 @@ export function createAgentPublishCommand() {
11
12
  .argument('[identifier]', 'Agent ID or full name (e.g., owner/agent-name)')
12
13
  .option('--wait', 'Wait for validation to complete before publishing')
13
14
  .action(async (agentIdArg, options) => {
15
+ const output = createOutputWriter();
14
16
  try {
15
17
  const client = new GuildAPIClient();
16
18
  // Resolve agent ID
@@ -23,19 +25,13 @@ export function createAgentPublishCommand() {
23
25
  .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
24
26
  if (draftVersions.length === 0) {
25
27
  const agentName = config?.name || agentId;
26
- console.error(`No draft versions available for agent: ${agentName}`);
27
- console.error('');
28
- console.error('Create a new version:');
29
- console.error(` guild agent save --message "your changes"`);
28
+ output.error(`No draft versions available for agent: ${agentName}`, 'Create a new version:\n guild agent save --message "your changes"');
30
29
  process.exit(1);
31
30
  }
32
31
  const versionToPublish = draftVersions[0];
33
32
  // Check if already published
34
33
  if (versionToPublish.status === 'PUBLISHED') {
35
- console.error(`Version ${versionToPublish.id} is already published`);
36
- console.error('');
37
- console.error('To unpublish:');
38
- console.error(' guild agent unpublish');
34
+ output.error(`Version ${versionToPublish.id} is already published`, 'To unpublish:\n guild agent unpublish');
39
35
  process.exit(1);
40
36
  }
41
37
  // Check validation status before attempting publish
@@ -56,10 +52,7 @@ export function createAgentPublishCommand() {
56
52
  delayMs: 1000,
57
53
  });
58
54
  if (!result.success || !result.response) {
59
- console.error('Validation did not complete in time');
60
- console.error('');
61
- console.error('Check status manually:');
62
- console.error(' guild agent versions');
55
+ output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
63
56
  process.exit(1);
64
57
  }
65
58
  currentVersion = result.response;
@@ -68,76 +61,66 @@ export function createAgentPublishCommand() {
68
61
  // by the main validation check
69
62
  }
70
63
  else {
71
- console.error('Cannot publish: validation is still in progress');
72
- console.error('');
73
- console.error(`Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}`);
74
- console.error('');
75
- console.error('The version number is extracted from package.json during validation.');
76
- console.error('');
77
- console.error('Options:');
78
- console.error(' • Wait for validation: guild agent publish --wait');
79
- console.error(' • Check status: guild agent versions');
64
+ output.error('Cannot publish: validation is still in progress', `Validation status: ${validationStatus === 'PENDING' ? 'Waiting to start' : 'Running'}\n\nThe version number is extracted from package.json during validation.\n\nOptions:\n • Wait for validation: guild agent publish --wait\n • Check status: guild agent versions`);
80
65
  process.exit(1);
81
66
  }
82
67
  }
83
68
  if (validationStatus === 'FAILED') {
84
- console.error('Cannot publish: validation failed');
85
- console.error('');
86
69
  // Fetch validation steps to show the actual error
70
+ let failureDetails = '';
87
71
  try {
88
72
  const stepsResponse = await client.get(`/versions/${currentVersion.id}/validation/steps`);
89
73
  const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
90
74
  if (failedSteps.length > 0) {
91
- for (const step of failedSteps) {
92
- console.error(`Step "${step.name}" failed:`);
75
+ const stepMessages = failedSteps.map((step) => {
76
+ let msg = `Step "${step.name}" failed:`;
93
77
  if (step.content) {
94
- console.error(step.content);
78
+ msg += `\n ${step.content}`;
95
79
  }
96
- console.error('');
97
- }
80
+ return msg;
81
+ });
82
+ failureDetails = stepMessages.join('\n\n');
98
83
  }
99
84
  else {
100
- console.error('No failed steps found. Check validation logs for details.');
101
- console.error('');
85
+ failureDetails =
86
+ 'No failed steps found. Check validation logs for details.';
102
87
  }
103
88
  }
104
89
  catch {
105
90
  // If we can't fetch steps, just show generic message
106
- console.error('Could not fetch validation details.');
107
- console.error('');
91
+ failureDetails = 'Could not fetch validation details.';
108
92
  }
109
- console.error('Fix the issues, then save a new version:');
110
- console.error(' guild agent save --message "Fix validation errors"');
93
+ output.error('Cannot publish: validation failed', `${failureDetails}\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"`);
111
94
  process.exit(1);
112
95
  }
113
96
  // Note: version_number is only set after validation extracts it from package.json,
114
97
  // and only enforced at publish time (drafts don't require versions)
115
98
  // Publish version
116
99
  await client.post(`/versions/${currentVersion.id}/publish`, {});
117
- console.log(`✓ Published version ${currentVersion.id}`);
118
- console.log(` Agent: ${currentVersion.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`);
119
- console.log(` Status: DRAFT → PUBLISHED`);
100
+ const details = {
101
+ agent: `${currentVersion.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`,
102
+ status: 'DRAFT → PUBLISHED',
103
+ };
120
104
  if (currentVersion.version_number) {
121
- console.log(` Version: ${currentVersion.version_number}`);
105
+ details.version = currentVersion.version_number;
122
106
  }
107
+ output.success(`Published version ${currentVersion.id}`, details);
123
108
  }
124
109
  catch (error) {
125
110
  const formattedError = handleAxiosError(error);
126
111
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
127
- console.error('Not authenticated. Run: guild auth login');
112
+ output.error('Not authenticated. Run: guild auth login');
128
113
  process.exit(1);
129
114
  }
130
115
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
131
- console.error('Agent not found');
132
- console.error('');
133
- console.error('Run: guild agent list');
116
+ output.error('Agent not found', 'Run: guild agent list');
134
117
  process.exit(1);
135
118
  }
136
119
  if (formattedError.code === ErrorCodes.CONN_REFUSED) {
137
- console.error('Cannot connect to Guild servers');
120
+ output.error('Cannot connect to Guild servers');
138
121
  process.exit(1);
139
122
  }
140
- console.error(`Failed to publish: ${formattedError.details}`);
123
+ output.error(`Failed to publish: ${formattedError.details}`);
141
124
  process.exit(1);
142
125
  }
143
126
  });
@@ -23,15 +23,7 @@ export function createAgentPullCommand() {
23
23
  .then(() => true)
24
24
  .catch(() => false);
25
25
  if (!guildJsonExists) {
26
- console.error('Error: Not in an agent directory');
27
- console.error('');
28
- console.error('guild.json not found in current directory.');
29
- console.error('');
30
- console.error('Initialize an agent directory:');
31
- console.error(' guild agent init --name my-agent');
32
- console.error('');
33
- console.error('Or clone an existing agent:');
34
- console.error(' guild agent clone <agent-id>');
26
+ output.error('Not in an agent directory', 'guild.json not found in current directory.\n\nInitialize an agent directory:\n guild agent init --name my-agent\n\nOr clone an existing agent:\n guild agent clone <agent-id>');
35
27
  process.exit(1);
36
28
  }
37
29
  // Read guild.json
@@ -40,15 +32,13 @@ export function createAgentPullCommand() {
40
32
  const client = new GuildAPIClient();
41
33
  const agent = await client.get(`/agents/${guildConfig.agent_id}`);
42
34
  if (!agent.git_url) {
43
- console.error('Error: Agent does not have a git repository');
44
- console.error('');
45
- console.error('This agent may not have been initialized with git.');
35
+ output.error('Agent does not have a git repository', 'This agent may not have been initialized with git.');
46
36
  process.exit(1);
47
37
  }
48
38
  // Get authenticated URL
49
39
  const authenticatedUrl = await getAuthenticatedUrl(agent.git_url);
50
40
  if (!authenticatedUrl) {
51
- console.error('Error: Not authenticated. Run: guild auth login');
41
+ output.error('Not authenticated.', 'Run: guild auth login');
52
42
  process.exit(1);
53
43
  }
54
44
  // Get current branch name
@@ -93,17 +83,7 @@ export function createAgentPullCommand() {
93
83
  // Check for rebase conflicts
94
84
  if (errMessage.includes('CONFLICT') ||
95
85
  errMessage.includes('could not apply')) {
96
- console.error('Error: Merge conflict detected');
97
- console.error('');
98
- console.error('Your changes conflict with remote changes.');
99
- console.error('');
100
- console.error('To resolve:');
101
- console.error(' 1. Fix conflicts in the listed files');
102
- console.error(' 2. git add <resolved-files>');
103
- console.error(' 3. git rebase --continue');
104
- console.error('');
105
- console.error('Or abort the rebase:');
106
- console.error(' git rebase --abort');
86
+ output.error('Merge conflict detected', 'Your changes conflict with remote changes.\n\nTo resolve:\n 1. Fix conflicts in the listed files\n 2. git add <resolved-files>\n 3. git rebase --continue\n\nOr abort the rebase:\n git rebase --abort');
107
87
  process.exit(1);
108
88
  }
109
89
  // No upstream branch — nothing to pull
@@ -122,26 +102,19 @@ export function createAgentPullCommand() {
122
102
  }
123
103
  catch (error) {
124
104
  if (error instanceof GitError) {
125
- console.error('Error: Git operation failed');
126
- console.error('');
127
- console.error(formatGitError(error));
105
+ output.error('Git operation failed', formatGitError(error));
128
106
  process.exit(1);
129
107
  }
130
108
  const formattedError = handleAxiosError(error);
131
109
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
132
- console.error('Not authenticated. Please log in first.');
133
- console.error('');
134
- console.error('Run: guild auth login');
110
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
135
111
  process.exit(1);
136
112
  }
137
113
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
138
- console.error('Error: Agent not found');
139
- console.error('');
140
- console.error('The agent may have been deleted.');
141
- console.error('Check your guild.json agent_id.');
114
+ output.error('Agent not found', 'The agent may have been deleted.\nCheck your guild.json agent_id.');
142
115
  process.exit(1);
143
116
  }
144
- console.error(`Failed to pull: ${formattedError.details}`);
117
+ output.error(`Failed to pull: ${formattedError.details}`);
145
118
  process.exit(1);
146
119
  }
147
120
  });
@@ -4,6 +4,7 @@ import { GuildAPIClient } from '../../lib/api-client.js';
4
4
  import { getGuildcoreUrl } from '../../lib/config.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
6
  import { getAgentId } from '../../lib/agent-helpers.js';
7
+ import { createOutputWriter } from '../../lib/output.js';
7
8
  export function createAgentRevalidateCommand() {
8
9
  const cmd = new Command('revalidate');
9
10
  cmd
@@ -11,6 +12,7 @@ export function createAgentRevalidateCommand() {
11
12
  .argument('[identifier]', 'Agent ID or full name (e.g., owner/agent-name)')
12
13
  .argument('[version-id]', 'ID of the version to revalidate (uses latest if omitted)')
13
14
  .action(async (agentIdArg, versionIdArg) => {
15
+ const output = createOutputWriter();
14
16
  // Get agent ID from argument or guild.json
15
17
  const { agentId } = await getAgentId(agentIdArg);
16
18
  const baseUrl = getGuildcoreUrl();
@@ -21,38 +23,28 @@ export function createAgentRevalidateCommand() {
21
23
  if (!versionId) {
22
24
  const versions = await client.get(`/agents/${agentId}/versions?limit=1&offset=0`);
23
25
  if (!versions.items || versions.items.length === 0) {
24
- console.error('No versions found for this agent.');
25
- console.error('');
26
- console.error('The agent may still be initializing. Check status:');
27
- console.error(` guild agent get ${agentId}`);
26
+ output.error('No versions found for this agent.', `The agent may still be initializing. Check status:\n guild agent get ${agentId}`);
28
27
  process.exit(1);
29
28
  }
30
29
  versionId = versions.items[0].id;
31
30
  }
32
31
  // Revalidate the version
33
32
  const result = await client.post(`/agents/${agentId}/versions/${versionId}/revalidate`);
34
- console.log(JSON.stringify(result, null, 2));
33
+ output.data(result);
35
34
  }
36
35
  catch (error) {
37
36
  const formattedError = handleAxiosError(error);
38
37
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
39
- console.error('Not authenticated.');
40
- console.error('');
41
- console.error('Please authenticate first:');
42
- console.error(' guild auth login');
38
+ output.error('Not authenticated.', 'Please authenticate first:\n guild auth login');
43
39
  }
44
40
  else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
45
- console.error('Cannot connect to Guild servers');
41
+ output.error('Cannot connect to Guild servers');
46
42
  }
47
43
  else if (formattedError.code === ErrorCodes.NOT_FOUND) {
48
- console.error(`Agent or version not found`);
49
- console.error('');
50
- console.error('Check the agent and version IDs:');
51
- console.error(' guild agent list');
52
- console.error(` guild agent versions ${agentId}`);
44
+ output.error('Agent or version not found', `Check the agent and version IDs:\n guild agent list\n guild agent versions ${agentId}`);
53
45
  }
54
46
  else {
55
- console.error(`Failed to revalidate version: ${formattedError.details}`);
47
+ output.error(`Failed to revalidate version: ${formattedError.details}`);
56
48
  }
57
49
  process.exit(1);
58
50
  }
@@ -22,10 +22,7 @@ export function createAgentSaveCommand() {
22
22
  const output = createOutputWriter();
23
23
  // Check for --message
24
24
  if (!options.message) {
25
- console.error('Error: Commit message is required');
26
- console.error('');
27
- console.error('Provide a message describing your changes:');
28
- console.error(' guild agent save --message "Add new feature"');
25
+ output.error('Commit message is required', 'Provide a message describing your changes:\n guild agent save --message "Add new feature"');
29
26
  process.exit(1);
30
27
  }
31
28
  try {
@@ -36,15 +33,7 @@ export function createAgentSaveCommand() {
36
33
  .then(() => true)
37
34
  .catch(() => false);
38
35
  if (!guildJsonExists) {
39
- console.error('Error: Not in an agent directory');
40
- console.error('');
41
- console.error('guild.json not found in current directory.');
42
- console.error('');
43
- console.error('Initialize an agent directory:');
44
- console.error(' guild agent init --name my-agent');
45
- console.error('');
46
- console.error('Or clone an existing agent:');
47
- console.error(' guild agent clone <agent-id>');
36
+ output.error('Not in an agent directory', 'guild.json not found in current directory.\n\nInitialize an agent directory:\n guild agent init --name my-agent\n\nOr clone an existing agent:\n guild agent clone <agent-id>');
48
37
  process.exit(1);
49
38
  }
50
39
  // Read guild.json
@@ -77,9 +66,7 @@ export function createAgentSaveCommand() {
77
66
  }
78
67
  }
79
68
  if (!hasUnpushedCommits) {
80
- console.error('Error: No changes to commit');
81
- console.error('');
82
- console.error('Working tree is clean. Make changes to your code before saving.');
69
+ output.error('No changes to commit', 'Working tree is clean. Make changes to your code before saving.');
83
70
  process.exit(1);
84
71
  }
85
72
  output.progress('✓ Found unpushed commits, resuming push...');
@@ -97,7 +84,7 @@ export function createAgentSaveCommand() {
97
84
  });
98
85
  const authenticatedUrl = await getAuthenticatedUrl(remoteUrl.trim());
99
86
  if (!authenticatedUrl) {
100
- console.error('Error: Not authenticated. Run: guild auth login');
87
+ output.error('Not authenticated.', 'Run: guild auth login');
101
88
  process.exit(1);
102
89
  }
103
90
  // Get current branch name
@@ -120,27 +107,14 @@ export function createAgentSaveCommand() {
120
107
  // Check for rebase conflicts
121
108
  if (errMessage.includes('CONFLICT') ||
122
109
  errMessage.includes('could not apply')) {
123
- console.error('Error: Merge conflict detected');
124
- console.error('');
125
- console.error('Your changes conflict with remote changes.');
126
- console.error('');
127
- console.error('To resolve:');
128
- console.error(' 1. Fix conflicts in the listed files');
129
- console.error(' 2. git add <resolved-files>');
130
- console.error(' 3. git rebase --continue');
131
- console.error(' 4. guild agent save --message "..."');
132
- console.error('');
133
- console.error('Or abort the rebase:');
134
- console.error(' git rebase --abort');
110
+ output.error('Merge conflict detected', 'Your changes conflict with remote changes.\n\nTo resolve:\n 1. Fix conflicts in the listed files\n 2. git add <resolved-files>\n 3. git rebase --continue\n 4. guild agent save --message "..."\n\nOr abort the rebase:\n git rebase --abort');
135
111
  process.exit(1);
136
112
  }
137
113
  // If pull fails, check if it's because there's no upstream
138
114
  if (!errMessage.includes('no tracking information') &&
139
115
  !errMessage.includes("couldn't find remote ref")) {
140
116
  // Real error we don't understand
141
- console.error('Error: Failed to sync with remote');
142
- console.error('');
143
- console.error(errMessage);
117
+ output.error('Failed to sync with remote', errMessage);
144
118
  process.exit(1);
145
119
  }
146
120
  // No upstream branch yet, that's fine - first push will set it
@@ -225,42 +199,34 @@ export function createAgentSaveCommand() {
225
199
  delayMs: 1000,
226
200
  });
227
201
  if (!pollResult.success || !pollResult.response) {
228
- console.error('Validation did not complete in time');
229
- console.error('');
230
- console.error('Check status manually:');
231
- console.error(' guild agent versions');
202
+ output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
232
203
  process.exit(1);
233
204
  }
234
205
  version = pollResult.response;
235
206
  // Check validation status
236
207
  if (version.validation_status === 'FAILED') {
237
- console.error('Validation failed');
238
- console.error('');
208
+ let failureDetails = '';
239
209
  // Fetch validation steps to show the actual error
240
210
  try {
241
211
  const stepsResponse = await client.get(`/versions/${version.id}/validation/steps`);
242
212
  const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
243
213
  if (failedSteps.length > 0) {
244
- for (const step of failedSteps) {
245
- console.error(`Step "${step.name}" failed:`);
246
- if (step.content) {
247
- console.error(step.content);
248
- }
249
- console.error('');
250
- }
214
+ const stepMessages = failedSteps.map((step) => step.content
215
+ ? `Step "${step.name}" failed: ${step.content}`
216
+ : `Step "${step.name}" failed`);
217
+ failureDetails = stepMessages.join('\n');
251
218
  }
252
219
  else {
253
- console.error('No failed steps found. Check validation logs for details.');
254
- console.error('');
220
+ failureDetails =
221
+ 'No failed steps found. Check validation logs for details.';
255
222
  }
256
223
  }
257
224
  catch {
258
- // If we can't fetch steps, just show generic message
259
- console.error('Could not fetch validation details.');
260
- console.error('');
225
+ failureDetails = 'Could not fetch validation details.';
261
226
  }
262
- console.error('Fix the issues, then save a new version:');
263
- console.error(' guild agent save --message "Fix validation errors"');
227
+ failureDetails +=
228
+ '\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"';
229
+ output.error('Validation failed', failureDetails);
264
230
  process.exit(1);
265
231
  }
266
232
  }
@@ -293,41 +259,24 @@ export function createAgentSaveCommand() {
293
259
  }
294
260
  catch (error) {
295
261
  if (error instanceof GitError) {
296
- console.error('Error: Git operation failed');
297
- console.error('');
298
- console.error(formatGitError(error));
262
+ output.error('Git operation failed', formatGitError(error));
299
263
  process.exit(1);
300
264
  }
301
265
  // Handle API errors
302
266
  const formattedError = handleAxiosError(error);
303
267
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
304
- console.error('Not authenticated. Please log in first.');
305
- console.error('');
306
- console.error('Run: guild auth login');
268
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
307
269
  process.exit(1);
308
270
  }
309
271
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
310
- console.error(`Error: Agent not found${guildConfig ? ': ' + guildConfig.agent_id : ''}`);
311
- console.error('');
312
- console.error('The agent may have been deleted.');
272
+ output.error(`Agent not found${guildConfig ? ': ' + guildConfig.agent_id : ''}`, 'The agent may have been deleted.');
313
273
  process.exit(1);
314
274
  }
315
275
  if (formattedError.details.includes('does not exist')) {
316
- console.error('Error: Commit not found in repository');
317
- console.error('');
318
- console.error('This might mean:');
319
- console.error(" • The commit wasn't pushed to the remote repository");
320
- console.error(' • The git remote is configured incorrectly');
321
- console.error(" • There's a sync issue with the backend");
322
- console.error('');
323
- console.error('Verify the commit exists:');
324
- console.error(' git log --oneline');
325
- console.error('');
326
- console.error('Verify the remote:');
327
- console.error(' git remote -v');
276
+ output.error('Commit not found in repository', "This might mean:\n • The commit wasn't pushed to the remote repository\n • The git remote is configured incorrectly\n • There's a sync issue with the backend\n\nVerify the commit exists:\n git log --oneline\n\nVerify the remote:\n git remote -v");
328
277
  process.exit(1);
329
278
  }
330
- console.error(`Failed to save agent: ${formattedError.details}`);
279
+ output.error(`Failed to save agent: ${formattedError.details}`);
331
280
  process.exit(1);
332
281
  }
333
282
  });
@@ -3,8 +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 } from '../../lib/errors.js';
6
- import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
7
- import { getOutputMode } from '../../lib/output-mode.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
8
7
  const SORT_MAP = {
9
8
  updated: 'updated_at',
10
9
  newest: 'created_at',
@@ -21,11 +20,11 @@ export function createAgentSearchCommand() {
21
20
  .option('--limit <number>', 'Number of results to return', '20')
22
21
  .option('--offset <number>', 'Offset for pagination', '0')
23
22
  .action(async (query, options) => {
23
+ const output = createOutputWriter();
24
24
  try {
25
25
  const token = await getAuthToken();
26
26
  if (!token) {
27
- console.error('Not authenticated. Please log in first.');
28
- console.error('Run: guild auth login');
27
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
29
28
  process.exit(1);
30
29
  }
31
30
  const client = new GuildAPIClient();
@@ -41,17 +40,11 @@ export function createAgentSearchCommand() {
41
40
  params.append('sort_by', sortField);
42
41
  }
43
42
  const response = await client.get(`/agents?${params.toString()}`);
44
- if (getOutputMode() === 'json') {
45
- console.log(JSON.stringify(response, null, 2));
46
- }
47
- else {
48
- formatAgentTable(response.items, response.pagination);
49
- }
43
+ output.data(response);
50
44
  }
51
45
  catch (error) {
52
- const out = createOutputWriter();
53
46
  const formattedError = handleAxiosError(error);
54
- out.error(`Failed to search agents: ${formattedError.details}`);
47
+ output.error(`Failed to search agents: ${formattedError.details}`);
55
48
  process.exit(1);
56
49
  }
57
50
  });
@@ -3,6 +3,7 @@ import { Command } from 'commander';
3
3
  import { GuildAPIClient } from '../../../lib/api-client.js';
4
4
  import { getAgentId } from '../../../lib/agent-helpers.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
6
+ import { createOutputWriter } from '../../../lib/output.js';
6
7
  export function createAgentTagsAddCommand() {
7
8
  const cmd = new Command('add');
8
9
  cmd
@@ -10,6 +11,7 @@ export function createAgentTagsAddCommand() {
10
11
  .argument('[agent-id]', 'Agent ID (optional if in agent directory)')
11
12
  .argument('<tags...>', 'Tags to add')
12
13
  .action(async (agentIdOrFirstTag, remainingTags) => {
14
+ const output = createOutputWriter();
13
15
  try {
14
16
  const client = new GuildAPIClient();
15
17
  // Parse arguments - need to determine if first arg is agent-id or tag
@@ -32,9 +34,7 @@ export function createAgentTagsAddCommand() {
32
34
  // Now resolve agent ID properly
33
35
  const { agentId, config } = await getAgentId(agentIdArg);
34
36
  if (tagsToAdd.length === 0) {
35
- console.error('Error: At least one tag is required');
36
- console.error('');
37
- console.error('Usage: guild agent tags add [agent-id] <tag...>');
37
+ output.error('At least one tag is required.', 'Usage: guild agent tags add [agent-id] <tag...>');
38
38
  process.exit(1);
39
39
  }
40
40
  // Fetch current tags
@@ -45,34 +45,24 @@ export function createAgentTagsAddCommand() {
45
45
  // Update tags
46
46
  await client.post(`/agents/${agentId}/tags`, { names: updatedTags });
47
47
  const agentName = config?.name || `agent ${agentId}`;
48
- console.log(`✓ Updated tags for agent: ${agentName}${config ? '' : ` (${agentId})`}`);
49
- console.log('');
50
- if (updatedTags.length === 0) {
51
- console.log(' No tags set');
52
- }
53
- else {
54
- updatedTags.forEach((tag) => {
55
- console.log(` • ${tag}`);
56
- });
57
- }
48
+ const label = `${agentName}${config ? '' : ` (${agentId})`}`;
49
+ output.success(`Updated tags for agent: ${label}`);
50
+ output.data({ names: updatedTags });
58
51
  }
59
52
  catch (error) {
60
53
  const formattedError = handleAxiosError(error);
61
54
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
62
- console.error('Not authenticated. Run: guild auth login');
63
- process.exit(1);
55
+ output.error('Not authenticated.', 'Run: guild auth login');
64
56
  }
65
- if (formattedError.code === ErrorCodes.NOT_FOUND) {
66
- console.error('Agent not found');
67
- console.error('');
68
- console.error('Run: guild agent list');
69
- process.exit(1);
57
+ else if (formattedError.code === ErrorCodes.NOT_FOUND) {
58
+ output.error('Agent not found.', 'Run: guild agent list');
70
59
  }
71
- if (formattedError.code === ErrorCodes.CONN_REFUSED) {
72
- console.error('Cannot connect to Guild servers');
73
- process.exit(1);
60
+ else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
61
+ output.error('Cannot connect to Guild servers');
62
+ }
63
+ else {
64
+ output.error(`Failed to add tags: ${formattedError.details}`);
74
65
  }
75
- console.error(`Failed to add tags: ${formattedError.details}`);
76
66
  process.exit(1);
77
67
  }
78
68
  });