@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
@@ -3,47 +3,36 @@ 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 createAgentTagsListCommand() {
7
8
  const cmd = new Command('list');
8
9
  cmd
9
10
  .description('List tags for an agent')
10
11
  .argument('[agent-id]', 'Agent ID (optional if in agent directory)')
11
12
  .action(async (agentIdArg) => {
13
+ const output = createOutputWriter();
12
14
  try {
13
15
  const client = new GuildAPIClient();
14
16
  // Resolve agent ID
15
- const { agentId, config } = await getAgentId(agentIdArg);
17
+ const { agentId } = await getAgentId(agentIdArg);
16
18
  // Fetch tags
17
19
  const response = await client.get(`/agents/${agentId}/tags`);
18
- const agentName = config?.name || `agent ${agentId}`;
19
- console.log(`Tags for agent: ${agentName}${config ? '' : ` (${agentId})`}`);
20
- console.log('');
21
- if (response.names.length === 0) {
22
- console.log(' No tags set');
23
- }
24
- else {
25
- response.names.forEach((tag) => {
26
- console.log(` • ${tag}`);
27
- });
28
- }
20
+ output.data(response);
29
21
  }
30
22
  catch (error) {
31
23
  const formattedError = handleAxiosError(error);
32
24
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
33
- console.error('Not authenticated. Run: guild auth login');
34
- process.exit(1);
25
+ output.error('Not authenticated.', 'Run: guild auth login');
35
26
  }
36
- if (formattedError.code === ErrorCodes.NOT_FOUND) {
37
- console.error('Agent not found');
38
- console.error('');
39
- console.error('Run: guild agent list');
40
- process.exit(1);
27
+ else if (formattedError.code === ErrorCodes.NOT_FOUND) {
28
+ output.error('Agent not found.', 'Run: guild agent list');
41
29
  }
42
- if (formattedError.code === ErrorCodes.CONN_REFUSED) {
43
- console.error('Cannot connect to Guild servers');
44
- process.exit(1);
30
+ else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
31
+ output.error('Cannot connect to Guild servers');
32
+ }
33
+ else {
34
+ output.error(`Failed to fetch tags: ${formattedError.details}`);
45
35
  }
46
- console.error(`Failed to fetch tags: ${formattedError.details}`);
47
36
  process.exit(1);
48
37
  }
49
38
  });
@@ -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 createAgentTagsRemoveCommand() {
7
8
  const cmd = new Command('remove');
8
9
  cmd
@@ -10,6 +11,7 @@ export function createAgentTagsRemoveCommand() {
10
11
  .argument('[agent-id]', 'Agent ID (optional if in agent directory)')
11
12
  .argument('<tags...>', 'Tags to remove')
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 createAgentTagsRemoveCommand() {
32
34
  // Now resolve agent ID properly
33
35
  const { agentId, config } = await getAgentId(agentIdArg);
34
36
  if (tagsToRemove.length === 0) {
35
- console.error('Error: At least one tag is required');
36
- console.error('');
37
- console.error('Usage: guild agent tags remove [agent-id] <tag...>');
37
+ output.error('At least one tag is required.', 'Usage: guild agent tags remove [agent-id] <tag...>');
38
38
  process.exit(1);
39
39
  }
40
40
  // Fetch current tags
@@ -47,44 +47,33 @@ export function createAgentTagsRemoveCommand() {
47
47
  // Update tags
48
48
  await client.post(`/agents/${agentId}/tags`, { names: updatedTags });
49
49
  const agentName = config?.name || `agent ${agentId}`;
50
- console.log(`✓ Updated tags for agent: ${agentName}${config ? '' : ` (${agentId})`}`);
51
- console.log('');
52
- if (updatedTags.length === 0) {
53
- console.log(' No tags set');
54
- }
55
- else {
56
- updatedTags.forEach((tag) => {
57
- console.log(` • ${tag}`);
58
- });
59
- }
50
+ const label = `${agentName}${config ? '' : ` (${agentId})`}`;
51
+ output.success(`Updated tags for agent: ${label}`);
52
+ output.data({ names: updatedTags });
60
53
  // Show warning for tags that weren't present
61
54
  if (notPresentTags.length > 0) {
62
- console.log('');
63
55
  if (notPresentTags.length === 1) {
64
- console.log(`Note: Tag '${notPresentTags[0]}' was not present`);
56
+ output.progress(`Note: Tag '${notPresentTags[0]}' was not present`);
65
57
  }
66
58
  else {
67
- console.log(`Note: Tags not present: ${notPresentTags.map((t) => `'${t}'`).join(', ')}`);
59
+ output.progress(`Note: Tags not present: ${notPresentTags.map((t) => `'${t}'`).join(', ')}`);
68
60
  }
69
61
  }
70
62
  }
71
63
  catch (error) {
72
64
  const formattedError = handleAxiosError(error);
73
65
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
74
- console.error('Not authenticated. Run: guild auth login');
75
- process.exit(1);
66
+ output.error('Not authenticated.', 'Run: guild auth login');
76
67
  }
77
- if (formattedError.code === ErrorCodes.NOT_FOUND) {
78
- console.error('Agent not found');
79
- console.error('');
80
- console.error('Run: guild agent list');
81
- process.exit(1);
68
+ else if (formattedError.code === ErrorCodes.NOT_FOUND) {
69
+ output.error('Agent not found.', 'Run: guild agent list');
82
70
  }
83
- if (formattedError.code === ErrorCodes.CONN_REFUSED) {
84
- console.error('Cannot connect to Guild servers');
85
- process.exit(1);
71
+ else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
72
+ output.error('Cannot connect to Guild servers');
73
+ }
74
+ else {
75
+ output.error(`Failed to remove tags: ${formattedError.details}`);
86
76
  }
87
- console.error(`Failed to remove tags: ${formattedError.details}`);
88
77
  process.exit(1);
89
78
  }
90
79
  });
@@ -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 createAgentTagsSetCommand() {
7
8
  const cmd = new Command('set');
8
9
  cmd
@@ -10,6 +11,7 @@ export function createAgentTagsSetCommand() {
10
11
  .argument('[agent-id]', 'Agent ID (optional if in agent directory)')
11
12
  .argument('[tags...]', 'Tags to set (omit to clear all tags)')
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
@@ -36,36 +38,29 @@ export function createAgentTagsSetCommand() {
36
38
  // Update tags (direct replacement)
37
39
  await client.post(`/agents/${agentId}/tags`, { names: tagsToSet });
38
40
  const agentName = config?.name || `agent ${agentId}`;
41
+ const label = `${agentName}${config ? '' : ` (${agentId})`}`;
39
42
  if (tagsToSet.length === 0) {
40
- console.log(`✓ Cleared all tags for agent: ${agentName}${config ? '' : ` (${agentId})`}`);
41
- console.log('');
42
- console.log(' No tags set');
43
+ output.success(`Cleared all tags for agent: ${label}`);
43
44
  }
44
45
  else {
45
- console.log(`✓ Updated tags for agent: ${agentName}${config ? '' : ` (${agentId})`}`);
46
- console.log('');
47
- tagsToSet.forEach((tag) => {
48
- console.log(` • ${tag}`);
49
- });
46
+ output.success(`Updated tags for agent: ${label}`);
50
47
  }
48
+ output.data({ names: tagsToSet });
51
49
  }
52
50
  catch (error) {
53
51
  const formattedError = handleAxiosError(error);
54
52
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
55
- console.error('Not authenticated. Run: guild auth login');
56
- process.exit(1);
53
+ output.error('Not authenticated.', 'Run: guild auth login');
57
54
  }
58
- if (formattedError.code === ErrorCodes.NOT_FOUND) {
59
- console.error('Agent not found');
60
- console.error('');
61
- console.error('Run: guild agent list');
62
- process.exit(1);
55
+ else if (formattedError.code === ErrorCodes.NOT_FOUND) {
56
+ output.error('Agent not found.', 'Run: guild agent list');
63
57
  }
64
- if (formattedError.code === ErrorCodes.CONN_REFUSED) {
65
- console.error('Cannot connect to Guild servers');
66
- process.exit(1);
58
+ else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
59
+ output.error('Cannot connect to Guild servers');
60
+ }
61
+ else {
62
+ output.error(`Failed to set tags: ${formattedError.details}`);
67
63
  }
68
- console.error(`Failed to set tags: ${formattedError.details}`);
69
64
  process.exit(1);
70
65
  }
71
66
  });
@@ -3,12 +3,14 @@ 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 createAgentUnpublishCommand() {
7
8
  const cmd = new Command('unpublish');
8
9
  cmd
9
10
  .description('Unpublish the latest published version of an agent')
10
11
  .argument('[identifier]', 'Agent ID or full name (e.g., owner/agent-name)')
11
12
  .action(async (agentIdArg) => {
13
+ const output = createOutputWriter();
12
14
  try {
13
15
  const client = new GuildAPIClient();
14
16
  // Resolve agent ID
@@ -21,44 +23,37 @@ export function createAgentUnpublishCommand() {
21
23
  .sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
22
24
  if (publishedVersions.length === 0) {
23
25
  const agentName = config?.name || agentId;
24
- console.error(`No published versions available for agent: ${agentName}`);
25
- console.error('');
26
- console.error('Publish a draft version:');
27
- console.error(' guild agent publish');
26
+ output.error(`No published versions available for agent: ${agentName}`, 'Publish a draft version:\n guild agent publish');
28
27
  process.exit(1);
29
28
  }
30
29
  const versionToUnpublish = publishedVersions[0];
31
30
  // Check if already draft
32
31
  if (versionToUnpublish.status === 'DRAFT') {
33
- console.error(`Version ${versionToUnpublish.id} is already a draft`);
34
- console.error('');
35
- console.error('To publish:');
36
- console.error(' guild agent publish');
32
+ output.error(`Version ${versionToUnpublish.id} is already a draft`, 'To publish:\n guild agent publish');
37
33
  process.exit(1);
38
34
  }
39
35
  // Unpublish version
40
36
  await client.post(`/versions/${versionToUnpublish.id}/unpublish`, {});
41
- console.log(`✓ Unpublished version ${versionToUnpublish.id}`);
42
- console.log(` Agent: ${versionToUnpublish.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`);
43
- console.log(` Status: PUBLISHED → DRAFT`);
37
+ output.success(`Unpublished version ${versionToUnpublish.id}`, {
38
+ agent: `${versionToUnpublish.agent?.name || config?.name || agentId}${config ? '' : ` (${agentId})`}`,
39
+ status: 'PUBLISHED → DRAFT',
40
+ });
44
41
  }
45
42
  catch (error) {
46
43
  const formattedError = handleAxiosError(error);
47
44
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
48
- console.error('Not authenticated. Run: guild auth login');
45
+ output.error('Not authenticated. Run: guild auth login');
49
46
  process.exit(1);
50
47
  }
51
48
  if (formattedError.code === ErrorCodes.NOT_FOUND) {
52
- console.error('Agent not found');
53
- console.error('');
54
- console.error('Run: guild agent list');
49
+ output.error('Agent not found', 'Run: guild agent list');
55
50
  process.exit(1);
56
51
  }
57
52
  if (formattedError.code === ErrorCodes.CONN_REFUSED) {
58
- console.error('Cannot connect to Guild servers');
53
+ output.error('Cannot connect to Guild servers');
59
54
  process.exit(1);
60
55
  }
61
- console.error(`Failed to unpublish version: ${formattedError.details}`);
56
+ output.error(`Failed to unpublish version: ${formattedError.details}`);
62
57
  process.exit(1);
63
58
  }
64
59
  });
@@ -4,6 +4,7 @@ import * as readline from 'readline';
4
4
  import { GuildAPIClient } from '../../lib/api-client.js';
5
5
  import { getGuildcoreUrl } from '../../lib/config.js';
6
6
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
7
+ import { createOutputWriter } from '../../lib/output.js';
7
8
  async function confirmVisibilityChange(agentName, makePublic) {
8
9
  const rl = readline.createInterface({
9
10
  input: process.stdin,
@@ -29,27 +30,15 @@ export function createAgentUpdateCommand() {
29
30
  .option('--private', 'Make the agent private (only visible to owner)')
30
31
  .option('--yes', 'Skip confirmation prompt for visibility changes')
31
32
  .action(async (agentId, options) => {
33
+ const output = createOutputWriter();
32
34
  // Validate that at least one option is provided
33
35
  if (!options.public && !options.private) {
34
- console.error('No update options provided.');
35
- console.error('');
36
- console.error('Usage: guild agent update <agent-id> [options]');
37
- console.error('');
38
- console.error('Options:');
39
- console.error(' --public Make the agent public');
40
- console.error(' --private Make the agent private');
41
- console.error(' --yes Skip confirmation prompt');
42
- console.error('');
43
- console.error('Examples:');
44
- console.error(' guild agent update my-agent --public');
45
- console.error(' guild agent update my-agent --private --yes');
46
- console.error('');
47
- console.error('Note: Agent descriptions are set from README.md when publishing.');
36
+ output.error('No update options provided.', 'Usage: guild agent update <agent-id> [options]\n\nOptions:\n --public Make the agent public\n --private Make the agent private\n --yes Skip confirmation prompt\n\nExamples:\n guild agent update my-agent --public\n guild agent update my-agent --private --yes\n\nNote: Agent descriptions are set from README.md when publishing.');
48
37
  process.exit(1);
49
38
  }
50
39
  // Validate that --public and --private are not both specified
51
40
  if (options.public && options.private) {
52
- console.error('Cannot specify both --public and --private');
41
+ output.error('Cannot specify both --public and --private');
53
42
  process.exit(1);
54
43
  }
55
44
  const baseUrl = getGuildcoreUrl();
@@ -63,14 +52,14 @@ export function createAgentUpdateCommand() {
63
52
  const makePublic = Boolean(options.public);
64
53
  // Check if already in desired state
65
54
  if (agent.is_public === makePublic) {
66
- console.log(`Agent "${agent.full_name}" is already ${makePublic ? 'public' : 'private'}.`);
55
+ output.progress(`Agent "${agent.full_name}" is already ${makePublic ? 'public' : 'private'}.`);
67
56
  process.exit(0);
68
57
  }
69
58
  // Confirm unless --yes is specified
70
59
  if (!options.yes) {
71
60
  const confirmed = await confirmVisibilityChange(agent.full_name, makePublic);
72
61
  if (!confirmed) {
73
- console.log('Cancelled.');
62
+ output.progress('Cancelled.');
74
63
  process.exit(0);
75
64
  }
76
65
  }
@@ -89,33 +78,27 @@ export function createAgentUpdateCommand() {
89
78
  if (changingVisibility) {
90
79
  changes.push(`visibility: ${result.is_public ? 'public' : 'private'}`);
91
80
  }
92
- console.log(JSON.stringify({
81
+ output.data({
93
82
  success: 'Agent updated',
94
83
  id: result.id,
95
84
  full_name: result.full_name,
96
85
  is_public: result.is_public,
97
86
  changes: changes,
98
- }, null, 2));
87
+ });
99
88
  }
100
89
  catch (error) {
101
90
  const formattedError = handleAxiosError(error);
102
91
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
103
- console.error('Not logged in.');
104
- console.error('');
105
- console.error('Please authenticate first:');
106
- console.error(' guild auth login');
92
+ output.error('Not logged in.', 'Please authenticate first:\n guild auth login');
107
93
  }
108
94
  else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
109
- console.error('Cannot connect to Guild servers');
95
+ output.error('Cannot connect to Guild servers');
110
96
  }
111
97
  else if (formattedError.code === ErrorCodes.NOT_FOUND) {
112
- console.error(`Agent not found: ${agentId}`);
113
- console.error('');
114
- console.error('Check the agent ID:');
115
- console.error(' guild agent list');
98
+ output.error(`Agent not found: ${agentId}`, 'Check the agent ID:\n guild agent list');
116
99
  }
117
100
  else {
118
- console.error(`Failed to update agent: ${formattedError.details}`);
101
+ output.error(`Failed to update agent: ${formattedError.details}`);
119
102
  }
120
103
  process.exit(1);
121
104
  }
@@ -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 createAgentVersionsCommand() {
8
9
  const cmd = new Command('versions');
9
10
  cmd
@@ -12,6 +13,7 @@ export function createAgentVersionsCommand() {
12
13
  .option('--limit <number>', 'Maximum number of versions to return', '20')
13
14
  .option('--offset <number>', 'Number of versions to skip', '0')
14
15
  .action(async (agentIdArg, options) => {
16
+ const output = createOutputWriter();
15
17
  // Get agent ID from argument or guild.json
16
18
  const { agentId } = await getAgentId(agentIdArg);
17
19
  const baseUrl = getGuildcoreUrl();
@@ -20,27 +22,21 @@ export function createAgentVersionsCommand() {
20
22
  const offset = parseInt(options.offset, 10);
21
23
  try {
22
24
  const result = await client.get(`/agents/${agentId}/versions?limit=${limit}&offset=${offset}`);
23
- console.log(JSON.stringify(result, null, 2));
25
+ output.data(result);
24
26
  }
25
27
  catch (error) {
26
28
  const formattedError = handleAxiosError(error);
27
29
  if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
28
- console.error('Not logged in.');
29
- console.error('');
30
- console.error('Please authenticate first:');
31
- console.error(' guild auth login');
30
+ output.error('Not logged in.', 'Please authenticate first:\n guild auth login');
32
31
  }
33
32
  else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
34
- console.error('Cannot connect to Guild servers');
33
+ output.error('Cannot connect to Guild servers');
35
34
  }
36
35
  else if (formattedError.code === ErrorCodes.NOT_FOUND) {
37
- console.error(`Agent not found: ${agentId}`);
38
- console.error('');
39
- console.error('Check the agent ID:');
40
- console.error(' guild agent list');
36
+ output.error(`Agent not found: ${agentId}`, 'Check the agent ID:\n guild agent list');
41
37
  }
42
38
  else {
43
- console.error(`Failed to list agent versions: ${formattedError.details}`);
39
+ output.error(`Failed to list agent versions: ${formattedError.details}`);
44
40
  }
45
41
  process.exit(1);
46
42
  }
@@ -3,6 +3,7 @@ import { Command } from 'commander';
3
3
  import { login } from '../../lib/auth.js';
4
4
  import { configureNpmrc } from '../../lib/npmrc.js';
5
5
  import { debug } from '../../lib/errors.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
6
7
  export function createAuthLoginCommand() {
7
8
  const cmd = new Command('login');
8
9
  cmd
@@ -10,15 +11,16 @@ export function createAuthLoginCommand() {
10
11
  .option('--return-url <url>', 'Custom URL to redirect to after authentication')
11
12
  .option('--return-label <text>', 'Friendly label for return button (e.g., "VSCode")')
12
13
  .action(async (options) => {
14
+ const output = createOutputWriter();
13
15
  const success = await login(options.returnUrl, options.returnLabel);
14
16
  if (success) {
15
17
  try {
16
18
  await configureNpmrc();
17
- console.log('Configured registry in ~/.npmrc');
19
+ output.progress('Configured registry in ~/.npmrc');
18
20
  }
19
21
  catch (error) {
20
22
  debug('npmrc configuration failed:', error);
21
- console.warn('Could not configure npm registry in ~/.npmrc');
23
+ output.error('Could not configure npm registry in ~/.npmrc');
22
24
  }
23
25
  }
24
26
  process.exit(success ? 0 : 1);
@@ -3,16 +3,18 @@ import { Command } from 'commander';
3
3
  import { logout } from '../../lib/auth.js';
4
4
  import { cleanupNpmrc } from '../../lib/npmrc.js';
5
5
  import { debug } from '../../lib/errors.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
6
7
  export function createAuthLogoutCommand() {
7
8
  const cmd = new Command('logout');
8
9
  cmd.description('Logout from Guild.ai').action(async () => {
10
+ const output = createOutputWriter();
9
11
  await logout();
10
12
  try {
11
13
  await cleanupNpmrc();
12
14
  }
13
15
  catch (error) {
14
16
  debug('npmrc cleanup failed:', error);
15
- console.warn('Could not clean up npm registry entries from ~/.npmrc');
17
+ output.error('Could not clean up npm registry entries from ~/.npmrc');
16
18
  }
17
19
  process.exit(0);
18
20
  });
@@ -1,16 +1,17 @@
1
1
  // Copyright (c) 2026 Guild.ai All Rights Reserved
2
2
  import { Command } from 'commander';
3
3
  import { getAuthStatus } from '../../lib/auth.js';
4
- import chalk from 'chalk';
4
+ import { createOutputWriter } from '../../lib/output.js';
5
5
  export function createAuthStatusCommand() {
6
6
  const cmd = new Command('status');
7
7
  cmd.description('Check authentication status').action(async () => {
8
+ const output = createOutputWriter();
8
9
  const { authenticated } = await getAuthStatus();
9
10
  if (authenticated) {
10
- console.log(chalk.green('\n✓ Authenticated\n'));
11
+ output.success('Authenticated');
11
12
  }
12
13
  else {
13
- console.log(chalk.red('\n✗ Not authenticated\n'));
14
+ output.error('Not authenticated');
14
15
  }
15
16
  process.exit(0);
16
17
  });
@@ -1,13 +1,14 @@
1
1
  // Copyright (c) 2026 Guild.ai All Rights Reserved
2
2
  import { Command } from 'commander';
3
- import chalk from 'chalk';
4
3
  import { getAuthToken } from '../../lib/auth.js';
4
+ import { createOutputWriter } from '../../lib/output.js';
5
5
  export function createAuthTokenCommand() {
6
6
  const cmd = new Command('token');
7
7
  cmd.description('Print auth token to stdout (for scripting)').action(async () => {
8
+ const output = createOutputWriter();
8
9
  const token = await getAuthToken();
9
10
  if (!token) {
10
- console.error(chalk.red('Not authenticated. Run: guild auth login'));
11
+ output.error('Not authenticated. Run: guild auth login');
11
12
  process.exit(1);
12
13
  }
13
14
  console.log(token);
@@ -2,6 +2,7 @@
2
2
  import { Command } from 'commander';
3
3
  import { loadConfig, } from '../../lib/guild-config.js';
4
4
  import { getOutputMode } from '../../lib/output-mode.js';
5
+ import { createOutputWriter } from '../../lib/output.js';
5
6
  /**
6
7
  * All valid config keys across global and local configs.
7
8
  * Note: default_workspace_name is internal (auto-resolved from API).
@@ -21,14 +22,11 @@ export function createConfigGetCommand() {
21
22
  .description('Get a configuration value')
22
23
  .argument('<key>', `Config key (${ALL_VALID_KEYS.join(', ')})`)
23
24
  .action(async (key) => {
25
+ const output = createOutputWriter();
24
26
  const config = await loadConfig();
25
27
  const mode = getOutputMode();
26
28
  if (!ALL_VALID_KEYS.includes(key)) {
27
- console.error(`Unknown config key: ${key}`);
28
- console.error('');
29
- console.error('Valid keys:');
30
- console.error(` Global: ${VALID_GLOBAL_KEYS.join(', ')}`);
31
- console.error(` Local: ${VALID_LOCAL_KEYS.join(', ')}`);
29
+ output.error(`Unknown config key: ${key}\n\nValid keys:\n Global: ${VALID_GLOBAL_KEYS.join(', ')}\n Local: ${VALID_LOCAL_KEYS.join(', ')}`);
32
30
  process.exit(1);
33
31
  }
34
32
  // Look up in global first, then local
@@ -46,18 +44,18 @@ export function createConfigGetCommand() {
46
44
  }
47
45
  if (value === undefined) {
48
46
  if (mode === 'json') {
49
- console.log(JSON.stringify({ key, value: null, source: null }));
47
+ output.data({ key, value: null, source: null });
50
48
  }
51
49
  else {
52
- console.error(`Key not found: ${key}`);
50
+ output.error(`Key not found: ${key}`);
53
51
  }
54
52
  process.exit(1);
55
53
  }
56
54
  if (mode === 'json') {
57
- console.log(JSON.stringify({ key, value, source }, null, 2));
55
+ output.data({ key, value, source });
58
56
  }
59
57
  else {
60
- console.log(value);
58
+ output.data(value);
61
59
  }
62
60
  });
63
61
  return cmd;
@@ -3,39 +3,41 @@ import { Command } from 'commander';
3
3
  import chalk from 'chalk';
4
4
  import { loadConfig } from '../../lib/guild-config.js';
5
5
  import { getOutputMode } from '../../lib/output-mode.js';
6
+ import { createOutputWriter } from '../../lib/output.js';
6
7
  export function createConfigListCommand() {
7
8
  const cmd = new Command('list');
8
9
  cmd.description('Show all configuration values').action(async () => {
10
+ const output = createOutputWriter();
9
11
  const config = await loadConfig();
10
12
  const mode = getOutputMode();
11
13
  if (mode === 'json') {
12
- console.log(JSON.stringify({
14
+ output.data({
13
15
  global: config.global || null,
14
16
  local: config.local || null,
15
- }, null, 2));
17
+ });
16
18
  return;
17
19
  }
18
20
  const hasGlobal = config.global && Object.keys(config.global).length > 0;
19
21
  const hasLocal = config.local && Object.keys(config.local).length > 0;
20
22
  if (!hasGlobal && !hasLocal) {
21
- console.log('No configuration found.');
22
- console.log('');
23
- console.log('Set a default workspace:');
24
- console.log(chalk.dim(' guild workspace select'));
23
+ output.progress('No configuration found.');
24
+ output.progress('');
25
+ output.progress('Set a default workspace:');
26
+ output.progress(chalk.dim(' guild workspace select'));
25
27
  return;
26
28
  }
27
29
  if (hasGlobal) {
28
- console.log(chalk.bold('Global config') + chalk.dim(' (~/.guild/config.json):'));
30
+ output.progress(chalk.bold('Global config') + chalk.dim(' (~/.guild/config.json):'));
29
31
  for (const [key, value] of Object.entries(config.global)) {
30
- console.log(` ${key}: ${chalk.cyan(String(value))}`);
32
+ output.progress(` ${key}: ${chalk.cyan(String(value))}`);
31
33
  }
32
34
  }
33
35
  if (hasLocal) {
34
36
  if (hasGlobal)
35
- console.log('');
36
- console.log(chalk.bold('Local config') + chalk.dim(' (guild.json):'));
37
+ output.progress('');
38
+ output.progress(chalk.bold('Local config') + chalk.dim(' (guild.json):'));
37
39
  for (const [key, value] of Object.entries(config.local)) {
38
- console.log(` ${key}: ${chalk.cyan(String(value))}`);
40
+ output.progress(` ${key}: ${chalk.cyan(String(value))}`);
39
41
  }
40
42
  }
41
43
  });