@guildai/cli 0.3.16 → 0.3.18
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 +22 -67
- 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 -6
- 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 +30 -76
- package/dist/commands/agent/search.js +5 -6
- 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 +13 -11
- package/dist/commands/agent/workspaces.d.ts +3 -0
- package/dist/commands/agent/workspaces.js +51 -0
- 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/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 +12 -32
- 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 +12 -37
- 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/index.js +2 -0
- package/dist/lib/agent-helpers.js +2 -2
- package/dist/lib/generated-types.d.ts +1 -1
- package/dist/lib/generated-types.js +1 -0
- package/dist/lib/npmrc.js +9 -1
- package/dist/lib/output.d.ts +18 -4
- package/dist/lib/output.js +112 -19
- package/docs/getting-started.md +1 -1
- package/docs/output-format.md +1 -1
- package/docs/skills/agent-dev.md +18 -17
- package/package.json +1 -1
|
@@ -3,8 +3,8 @@ 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
6
|
import { getOutputMode } from '../../lib/output-mode.js';
|
|
7
|
+
import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
|
|
8
8
|
const SORT_MAP = {
|
|
9
9
|
updated: 'updated_at',
|
|
10
10
|
newest: 'created_at',
|
|
@@ -21,11 +21,11 @@ export function createAgentListCommand() {
|
|
|
21
21
|
.option('--limit <number>', 'Number of results to return', '20')
|
|
22
22
|
.option('--offset <number>', 'Offset for pagination', '0')
|
|
23
23
|
.action(async (options) => {
|
|
24
|
+
const output = createOutputWriter();
|
|
24
25
|
try {
|
|
25
26
|
const token = await getAuthToken();
|
|
26
27
|
if (!token) {
|
|
27
|
-
|
|
28
|
-
console.error('Run: guild auth login');
|
|
28
|
+
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
const client = new GuildAPIClient();
|
|
@@ -44,16 +44,15 @@ export function createAgentListCommand() {
|
|
|
44
44
|
}
|
|
45
45
|
const response = await client.get(`/agents?${params.toString()}`);
|
|
46
46
|
if (getOutputMode() === 'json') {
|
|
47
|
-
|
|
47
|
+
output.data(response);
|
|
48
48
|
}
|
|
49
49
|
else {
|
|
50
50
|
formatAgentTable(response.items, response.pagination);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
catch (error) {
|
|
54
|
-
const out = createOutputWriter();
|
|
55
54
|
const formattedError = handleAxiosError(error);
|
|
56
|
-
|
|
55
|
+
output.error(`Failed to list agents: ${formattedError.details}`);
|
|
57
56
|
process.exit(1);
|
|
58
57
|
}
|
|
59
58
|
});
|
|
@@ -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
|
}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Command } from 'commander';
|
|
3
3
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
4
4
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
5
|
+
import { getOutputMode } from '../../lib/output-mode.js';
|
|
5
6
|
import { createOutputWriter } from '../../lib/output.js';
|
|
6
7
|
import * as fs from 'fs/promises';
|
|
7
8
|
import * as path from 'path';
|
|
@@ -22,10 +23,7 @@ export function createAgentSaveCommand() {
|
|
|
22
23
|
const output = createOutputWriter();
|
|
23
24
|
// Check for --message
|
|
24
25
|
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"');
|
|
26
|
+
output.error('Commit message is required', 'Provide a message describing your changes:\n guild agent save --message "Add new feature"');
|
|
29
27
|
process.exit(1);
|
|
30
28
|
}
|
|
31
29
|
try {
|
|
@@ -36,15 +34,7 @@ export function createAgentSaveCommand() {
|
|
|
36
34
|
.then(() => true)
|
|
37
35
|
.catch(() => false);
|
|
38
36
|
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>');
|
|
37
|
+
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
38
|
process.exit(1);
|
|
49
39
|
}
|
|
50
40
|
// Read guild.json
|
|
@@ -77,9 +67,7 @@ export function createAgentSaveCommand() {
|
|
|
77
67
|
}
|
|
78
68
|
}
|
|
79
69
|
if (!hasUnpushedCommits) {
|
|
80
|
-
|
|
81
|
-
console.error('');
|
|
82
|
-
console.error('Working tree is clean. Make changes to your code before saving.');
|
|
70
|
+
output.error('No changes to commit', 'Working tree is clean. Make changes to your code before saving.');
|
|
83
71
|
process.exit(1);
|
|
84
72
|
}
|
|
85
73
|
output.progress('✓ Found unpushed commits, resuming push...');
|
|
@@ -97,7 +85,7 @@ export function createAgentSaveCommand() {
|
|
|
97
85
|
});
|
|
98
86
|
const authenticatedUrl = await getAuthenticatedUrl(remoteUrl.trim());
|
|
99
87
|
if (!authenticatedUrl) {
|
|
100
|
-
|
|
88
|
+
output.error('Not authenticated.', 'Run: guild auth login');
|
|
101
89
|
process.exit(1);
|
|
102
90
|
}
|
|
103
91
|
// Get current branch name
|
|
@@ -120,27 +108,14 @@ export function createAgentSaveCommand() {
|
|
|
120
108
|
// Check for rebase conflicts
|
|
121
109
|
if (errMessage.includes('CONFLICT') ||
|
|
122
110
|
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');
|
|
111
|
+
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
112
|
process.exit(1);
|
|
136
113
|
}
|
|
137
114
|
// If pull fails, check if it's because there's no upstream
|
|
138
115
|
if (!errMessage.includes('no tracking information') &&
|
|
139
116
|
!errMessage.includes("couldn't find remote ref")) {
|
|
140
117
|
// Real error we don't understand
|
|
141
|
-
|
|
142
|
-
console.error('');
|
|
143
|
-
console.error(errMessage);
|
|
118
|
+
output.error('Failed to sync with remote', errMessage);
|
|
144
119
|
process.exit(1);
|
|
145
120
|
}
|
|
146
121
|
// No upstream branch yet, that's fine - first push will set it
|
|
@@ -225,42 +200,34 @@ export function createAgentSaveCommand() {
|
|
|
225
200
|
delayMs: 1000,
|
|
226
201
|
});
|
|
227
202
|
if (!pollResult.success || !pollResult.response) {
|
|
228
|
-
|
|
229
|
-
console.error('');
|
|
230
|
-
console.error('Check status manually:');
|
|
231
|
-
console.error(' guild agent versions');
|
|
203
|
+
output.error('Validation did not complete in time', 'Check status manually:\n guild agent versions');
|
|
232
204
|
process.exit(1);
|
|
233
205
|
}
|
|
234
206
|
version = pollResult.response;
|
|
235
207
|
// Check validation status
|
|
236
208
|
if (version.validation_status === 'FAILED') {
|
|
237
|
-
|
|
238
|
-
console.error('');
|
|
209
|
+
let failureDetails = '';
|
|
239
210
|
// Fetch validation steps to show the actual error
|
|
240
211
|
try {
|
|
241
212
|
const stepsResponse = await client.get(`/versions/${version.id}/validation/steps`);
|
|
242
213
|
const failedSteps = stepsResponse.steps.filter((step) => step.status === 'FAILED');
|
|
243
214
|
if (failedSteps.length > 0) {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
}
|
|
249
|
-
console.error('');
|
|
250
|
-
}
|
|
215
|
+
const stepMessages = failedSteps.map((step) => step.content
|
|
216
|
+
? `Step "${step.name}" failed: ${step.content}`
|
|
217
|
+
: `Step "${step.name}" failed`);
|
|
218
|
+
failureDetails = stepMessages.join('\n');
|
|
251
219
|
}
|
|
252
220
|
else {
|
|
253
|
-
|
|
254
|
-
|
|
221
|
+
failureDetails =
|
|
222
|
+
'No failed steps found. Check validation logs for details.';
|
|
255
223
|
}
|
|
256
224
|
}
|
|
257
225
|
catch {
|
|
258
|
-
|
|
259
|
-
console.error('Could not fetch validation details.');
|
|
260
|
-
console.error('');
|
|
226
|
+
failureDetails = 'Could not fetch validation details.';
|
|
261
227
|
}
|
|
262
|
-
|
|
263
|
-
|
|
228
|
+
failureDetails +=
|
|
229
|
+
'\n\nFix the issues, then save a new version:\n guild agent save --message "Fix validation errors"';
|
|
230
|
+
output.error('Validation failed', failureDetails);
|
|
264
231
|
process.exit(1);
|
|
265
232
|
}
|
|
266
233
|
}
|
|
@@ -288,46 +255,33 @@ export function createAgentSaveCommand() {
|
|
|
288
255
|
output.progress('To publish this version:');
|
|
289
256
|
output.progress(' guild agent save --message "..." --publish');
|
|
290
257
|
}
|
|
291
|
-
// Output JSON to stdout
|
|
292
|
-
|
|
258
|
+
// Output JSON to stdout only in --json mode.
|
|
259
|
+
// In interactive mode the progress messages above already
|
|
260
|
+
// show version details; dumping raw JSON is noise.
|
|
261
|
+
if (getOutputMode() === 'json') {
|
|
262
|
+
output.data({ version });
|
|
263
|
+
}
|
|
293
264
|
}
|
|
294
265
|
catch (error) {
|
|
295
266
|
if (error instanceof GitError) {
|
|
296
|
-
|
|
297
|
-
console.error('');
|
|
298
|
-
console.error(formatGitError(error));
|
|
267
|
+
output.error('Git operation failed', formatGitError(error));
|
|
299
268
|
process.exit(1);
|
|
300
269
|
}
|
|
301
270
|
// Handle API errors
|
|
302
271
|
const formattedError = handleAxiosError(error);
|
|
303
272
|
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
304
|
-
|
|
305
|
-
console.error('');
|
|
306
|
-
console.error('Run: guild auth login');
|
|
273
|
+
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
307
274
|
process.exit(1);
|
|
308
275
|
}
|
|
309
276
|
if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
310
|
-
|
|
311
|
-
console.error('');
|
|
312
|
-
console.error('The agent may have been deleted.');
|
|
277
|
+
output.error(`Agent not found${guildConfig ? ': ' + guildConfig.agent_id : ''}`, 'The agent may have been deleted.');
|
|
313
278
|
process.exit(1);
|
|
314
279
|
}
|
|
315
280
|
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');
|
|
281
|
+
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
282
|
process.exit(1);
|
|
329
283
|
}
|
|
330
|
-
|
|
284
|
+
output.error(`Failed to save agent: ${formattedError.details}`);
|
|
331
285
|
process.exit(1);
|
|
332
286
|
}
|
|
333
287
|
});
|
|
@@ -3,8 +3,8 @@ 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
6
|
import { getOutputMode } from '../../lib/output-mode.js';
|
|
7
|
+
import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
|
|
8
8
|
const SORT_MAP = {
|
|
9
9
|
updated: 'updated_at',
|
|
10
10
|
newest: 'created_at',
|
|
@@ -21,11 +21,11 @@ export function createAgentSearchCommand() {
|
|
|
21
21
|
.option('--limit <number>', 'Number of results to return', '20')
|
|
22
22
|
.option('--offset <number>', 'Offset for pagination', '0')
|
|
23
23
|
.action(async (query, options) => {
|
|
24
|
+
const output = createOutputWriter();
|
|
24
25
|
try {
|
|
25
26
|
const token = await getAuthToken();
|
|
26
27
|
if (!token) {
|
|
27
|
-
|
|
28
|
-
console.error('Run: guild auth login');
|
|
28
|
+
output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
|
|
29
29
|
process.exit(1);
|
|
30
30
|
}
|
|
31
31
|
const client = new GuildAPIClient();
|
|
@@ -42,16 +42,15 @@ export function createAgentSearchCommand() {
|
|
|
42
42
|
}
|
|
43
43
|
const response = await client.get(`/agents?${params.toString()}`);
|
|
44
44
|
if (getOutputMode() === 'json') {
|
|
45
|
-
|
|
45
|
+
output.data(response);
|
|
46
46
|
}
|
|
47
47
|
else {
|
|
48
48
|
formatAgentTable(response.items, response.pagination);
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
catch (error) {
|
|
52
|
-
const out = createOutputWriter();
|
|
53
52
|
const formattedError = handleAxiosError(error);
|
|
54
|
-
|
|
53
|
+
output.error(`Failed to search agents: ${formattedError.details}`);
|
|
55
54
|
process.exit(1);
|
|
56
55
|
}
|
|
57
56
|
});
|