@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.
- package/dist/commands/agent/clone.js +21 -40
- package/dist/commands/agent/code.js +12 -32
- package/dist/commands/agent/create.js +14 -30
- package/dist/commands/agent/fork.js +27 -73
- package/dist/commands/agent/get.js +5 -4
- package/dist/commands/agent/grep.js +7 -9
- package/dist/commands/agent/init.js +2 -0
- package/dist/commands/agent/list.js +5 -12
- package/dist/commands/agent/publish.js +27 -44
- package/dist/commands/agent/pull.js +8 -35
- package/dist/commands/agent/revalidate.js +8 -16
- package/dist/commands/agent/save.js +23 -74
- package/dist/commands/agent/search.js +5 -12
- package/dist/commands/agent/tags/add.js +14 -24
- package/dist/commands/agent/tags/list.js +12 -23
- package/dist/commands/agent/tags/remove.js +16 -27
- package/dist/commands/agent/tags/set.js +14 -19
- package/dist/commands/agent/unpublish.js +12 -17
- package/dist/commands/agent/update.js +12 -29
- package/dist/commands/agent/versions.js +7 -11
- package/dist/commands/auth/login.js +4 -2
- package/dist/commands/auth/logout.js +3 -1
- package/dist/commands/auth/status.js +4 -3
- package/dist/commands/auth/token.js +3 -2
- package/dist/commands/chat.js +85 -10
- package/dist/commands/config/get.js +7 -9
- package/dist/commands/config/list.js +13 -11
- package/dist/commands/config/path.js +6 -4
- package/dist/commands/config/set.js +17 -22
- package/dist/commands/doctor.js +9 -7
- package/dist/commands/session/create.js +7 -5
- package/dist/commands/session/events.js +5 -3
- package/dist/commands/session/get.js +5 -3
- package/dist/commands/session/list.js +5 -4
- package/dist/commands/session/send.js +7 -5
- package/dist/commands/session/tasks.js +5 -3
- package/dist/commands/setup.js +15 -14
- package/dist/commands/trigger/activate.js +7 -6
- package/dist/commands/trigger/create.js +16 -15
- package/dist/commands/trigger/deactivate.js +7 -6
- package/dist/commands/trigger/get.js +5 -4
- package/dist/commands/trigger/list.js +5 -5
- package/dist/commands/trigger/sessions.js +7 -6
- package/dist/commands/trigger/update.js +11 -10
- package/dist/commands/version.js +7 -5
- package/dist/commands/workspace/agent/add.js +16 -22
- package/dist/commands/workspace/agent/list.js +9 -30
- package/dist/commands/workspace/agent/remove.js +9 -15
- package/dist/commands/workspace/context/edit.js +13 -27
- package/dist/commands/workspace/context/get.js +8 -14
- package/dist/commands/workspace/context/list.js +7 -38
- package/dist/commands/workspace/context/publish.js +7 -11
- package/dist/commands/workspace/create.js +7 -11
- package/dist/commands/workspace/current.js +19 -31
- package/dist/commands/workspace/get.js +7 -11
- package/dist/commands/workspace/list.js +5 -8
- package/dist/commands/workspace/select.js +17 -22
- package/dist/components/TaskView.js +2 -0
- package/dist/lib/output.js +4 -4
- package/dist/lib/session-events.d.ts +7 -2
- 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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
92
|
-
|
|
75
|
+
const stepMessages = failedSteps.map((step) => {
|
|
76
|
+
let msg = `Step "${step.name}" failed:`;
|
|
93
77
|
if (step.content) {
|
|
94
|
-
|
|
78
|
+
msg += `\n ${step.content}`;
|
|
95
79
|
}
|
|
96
|
-
|
|
97
|
-
}
|
|
80
|
+
return msg;
|
|
81
|
+
});
|
|
82
|
+
failureDetails = stepMessages.join('\n\n');
|
|
98
83
|
}
|
|
99
84
|
else {
|
|
100
|
-
|
|
101
|
-
|
|
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
|
-
|
|
107
|
-
console.error('');
|
|
91
|
+
failureDetails = 'Could not fetch validation details.';
|
|
108
92
|
}
|
|
109
|
-
|
|
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
|
-
|
|
118
|
-
|
|
119
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
120
|
+
output.error('Cannot connect to Guild servers');
|
|
138
121
|
process.exit(1);
|
|
139
122
|
}
|
|
140
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
41
|
+
output.error('Cannot connect to Guild servers');
|
|
46
42
|
}
|
|
47
43
|
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
48
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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
|
-
|
|
254
|
-
|
|
220
|
+
failureDetails =
|
|
221
|
+
'No failed steps found. Check validation logs for details.';
|
|
255
222
|
}
|
|
256
223
|
}
|
|
257
224
|
catch {
|
|
258
|
-
|
|
259
|
-
console.error('Could not fetch validation details.');
|
|
260
|
-
console.error('');
|
|
225
|
+
failureDetails = 'Could not fetch validation details.';
|
|
261
226
|
}
|
|
262
|
-
|
|
263
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
63
|
-
process.exit(1);
|
|
55
|
+
output.error('Not authenticated.', 'Run: guild auth login');
|
|
64
56
|
}
|
|
65
|
-
if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
66
|
-
|
|
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
|
-
|
|
73
|
-
|
|
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
|
});
|