@guildai/cli 0.9.1 → 0.11.0
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/chat.js +10 -7
- package/dist/commands/agent/clone.js +2 -0
- package/dist/commands/agent/fork.js +3 -0
- package/dist/commands/agent/init.js +58 -44
- package/dist/commands/agent/list.js +5 -4
- package/dist/commands/agent/logs.d.ts +3 -0
- package/dist/commands/agent/logs.js +62 -0
- package/dist/commands/agent/owners.js +3 -3
- package/dist/commands/agent/pull.js +8 -12
- package/dist/commands/agent/save.js +5 -6
- package/dist/commands/agent/search.js +5 -4
- package/dist/commands/agent/test.js +9 -6
- package/dist/commands/agent/update.js +9 -1
- package/dist/commands/agent/versions.js +5 -4
- package/dist/commands/agent/workspaces.js +5 -4
- package/dist/commands/auth/login.js +1 -3
- package/dist/commands/chat.d.ts +9 -0
- package/dist/commands/chat.js +136 -32
- package/dist/commands/config/get.js +4 -4
- package/dist/commands/config/list.js +2 -3
- package/dist/commands/config/path.js +2 -3
- package/dist/commands/config/set.js +12 -12
- package/dist/commands/credentials/endpoint-list.js +5 -4
- package/dist/commands/credentials/list.js +5 -4
- package/dist/commands/credentials/policy-list.js +5 -4
- package/dist/commands/doctor.js +5 -5
- package/dist/commands/integration/connect.js +2 -2
- package/dist/commands/integration/create.js +2 -2
- package/dist/commands/integration/get.js +2 -2
- package/dist/commands/integration/list.js +5 -4
- package/dist/commands/integration/operation/create.js +4 -4
- package/dist/commands/integration/operation/list.js +5 -4
- package/dist/commands/integration/update.js +2 -2
- package/dist/commands/integration/version/build.js +2 -2
- package/dist/commands/integration/version/create.js +2 -2
- package/dist/commands/integration/version/get.js +2 -2
- package/dist/commands/integration/version/list.js +5 -4
- package/dist/commands/integration/version/publish.js +2 -2
- package/dist/commands/integration/version/test.js +2 -2
- package/dist/commands/job/get.js +2 -2
- package/dist/commands/session/create.js +1 -1
- package/dist/commands/session/events.js +3 -2
- package/dist/commands/session/list.js +5 -4
- package/dist/commands/session/tasks.js +5 -4
- package/dist/commands/setup.d.ts +16 -0
- package/dist/commands/setup.js +76 -46
- package/dist/commands/trigger/list.js +5 -4
- package/dist/commands/trigger/sessions.js +3 -2
- package/dist/commands/workspace/agent/list.js +5 -4
- package/dist/commands/workspace/context/list.js +5 -4
- package/dist/commands/workspace/list.js +5 -4
- package/dist/index.js +15 -4
- package/dist/lib/api-types.d.ts +4 -0
- package/dist/lib/api-types.js +4 -0
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +2 -2
- package/dist/lib/output-mode.d.ts +9 -2
- package/dist/lib/output-mode.js +23 -2
- package/dist/lib/output.d.ts +7 -1
- package/dist/lib/output.js +36 -5
- package/dist/lib/owner-helpers.d.ts +3 -0
- package/dist/lib/owner-helpers.js +17 -10
- package/dist/lib/session-events.d.ts +13 -2
- package/dist/lib/session-events.js +15 -1
- package/dist/lib/session-polling.js +9 -3
- package/dist/lib/session-resume.d.ts +15 -1
- package/dist/lib/session-resume.js +149 -16
- package/dist/lib/splash.js +3 -2
- package/dist/lib/stdin.d.ts +5 -1
- package/dist/lib/stdin.js +8 -1
- package/dist/lib/version-helpers.js +24 -8
- package/package.json +1 -1
package/dist/commands/setup.js
CHANGED
|
@@ -79,9 +79,9 @@ const MCP_SERVER_CONFIG = {
|
|
|
79
79
|
command: 'guild',
|
|
80
80
|
args: ['mcp'],
|
|
81
81
|
};
|
|
82
|
-
async function setupMcp(options) {
|
|
82
|
+
async function setupMcp(targetDir, options) {
|
|
83
83
|
const output = createOutputWriter();
|
|
84
|
-
const mcpPath = path.join(
|
|
84
|
+
const mcpPath = path.join(targetDir, '.mcp.json');
|
|
85
85
|
let existing = {};
|
|
86
86
|
const exists = await fileExists(mcpPath);
|
|
87
87
|
if (exists) {
|
|
@@ -108,55 +108,74 @@ async function setupMcp(options) {
|
|
|
108
108
|
}
|
|
109
109
|
return 'created';
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
/**
|
|
112
|
+
* Run setup in a target directory. Exported so init/clone can call it.
|
|
113
|
+
* When called with `quiet: true`, suppresses progress output (used as a
|
|
114
|
+
* post-init/clone step where the caller handles its own progress UI).
|
|
115
|
+
*/
|
|
116
|
+
export async function runSetup(targetDir, options = {}) {
|
|
112
117
|
const output = createOutputWriter();
|
|
113
|
-
|
|
118
|
+
const force = options.force ?? false;
|
|
119
|
+
const claudeMd = options.claudeMd ?? false;
|
|
120
|
+
const codex = options.codex ?? false;
|
|
121
|
+
const agentsMd = options.agentsMd ?? false;
|
|
122
|
+
const mcp = options.mcp ?? true;
|
|
123
|
+
const quiet = options.quiet ?? false;
|
|
124
|
+
if (agentsMd && !codex) {
|
|
114
125
|
output.error('--agents-md requires --codex', 'Create Codex setup files with:\n guild setup --codex --agents-md');
|
|
115
126
|
process.exit(1);
|
|
116
127
|
}
|
|
117
|
-
if (
|
|
128
|
+
if (claudeMd && codex) {
|
|
118
129
|
output.error('--claude-md cannot be used with --codex', 'Create Claude setup with:\n guild setup --claude-md\n\nCreate Codex setup with:\n guild setup --codex --agents-md');
|
|
119
130
|
process.exit(1);
|
|
120
131
|
}
|
|
121
|
-
const skillFiles =
|
|
132
|
+
const skillFiles = codex ? CODEX_SKILL_FILES : CLAUDE_SKILL_FILES;
|
|
122
133
|
// Verify source docs exist
|
|
123
134
|
for (const file of skillFiles) {
|
|
124
135
|
if (!(await fileExists(file.src))) {
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
if (!quiet) {
|
|
137
|
+
output.error('Could not find Guild CLI docs. Reinstall the CLI: npm install -g @guildai/cli');
|
|
138
|
+
}
|
|
139
|
+
return { filesCreated: 0, filesSkipped: 0 };
|
|
127
140
|
}
|
|
128
141
|
}
|
|
129
|
-
|
|
130
|
-
|
|
142
|
+
if (!quiet) {
|
|
143
|
+
output.progress('Setting up Guild CLI skills...');
|
|
144
|
+
output.progress('');
|
|
145
|
+
}
|
|
131
146
|
let filesCreated = 0;
|
|
132
147
|
let filesSkipped = 0;
|
|
133
148
|
let codexProjectFilesChanged = false;
|
|
134
149
|
// Copy skill files
|
|
135
150
|
for (const file of skillFiles) {
|
|
136
|
-
const destPath = path.join(
|
|
151
|
+
const destPath = path.join(targetDir, file.dest);
|
|
137
152
|
const exists = await fileExists(destPath);
|
|
138
|
-
if (exists && !
|
|
139
|
-
|
|
153
|
+
if (exists && !force) {
|
|
154
|
+
if (!quiet) {
|
|
155
|
+
output.progress(`${file.label} already exists (use --force to overwrite)`);
|
|
156
|
+
}
|
|
140
157
|
filesSkipped++;
|
|
141
158
|
}
|
|
142
159
|
else {
|
|
143
160
|
await fs.mkdir(path.dirname(destPath), { recursive: true });
|
|
144
161
|
await fs.copyFile(file.src, destPath);
|
|
145
|
-
if (
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
162
|
+
if (!quiet) {
|
|
163
|
+
if (exists) {
|
|
164
|
+
output.success(`Updated ${file.label}`);
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
output.success(`Created ${file.label}`);
|
|
168
|
+
}
|
|
150
169
|
}
|
|
151
170
|
filesCreated++;
|
|
152
|
-
if (
|
|
171
|
+
if (codex) {
|
|
153
172
|
codexProjectFilesChanged = true;
|
|
154
173
|
}
|
|
155
174
|
}
|
|
156
175
|
}
|
|
157
|
-
// Handle
|
|
158
|
-
if (
|
|
159
|
-
const result = await setupMcp({ force
|
|
176
|
+
// Handle MCP config
|
|
177
|
+
if (mcp) {
|
|
178
|
+
const result = await setupMcp(targetDir, { force });
|
|
160
179
|
if (result === 'created') {
|
|
161
180
|
filesCreated++;
|
|
162
181
|
}
|
|
@@ -165,53 +184,64 @@ async function setup(options) {
|
|
|
165
184
|
}
|
|
166
185
|
}
|
|
167
186
|
// Handle CLAUDE.md template
|
|
168
|
-
if (
|
|
169
|
-
const claudeMdPath = path.join(
|
|
187
|
+
if (claudeMd) {
|
|
188
|
+
const claudeMdPath = path.join(targetDir, 'CLAUDE.md');
|
|
170
189
|
const exists = await fileExists(claudeMdPath);
|
|
171
190
|
if (exists) {
|
|
172
|
-
|
|
191
|
+
if (!quiet) {
|
|
192
|
+
output.progress('CLAUDE.md already exists (not overwriting)');
|
|
193
|
+
}
|
|
173
194
|
filesSkipped++;
|
|
174
195
|
}
|
|
175
196
|
else {
|
|
176
197
|
await fs.writeFile(claudeMdPath, CLAUDE_MD_TEMPLATE, 'utf-8');
|
|
177
|
-
|
|
198
|
+
if (!quiet) {
|
|
199
|
+
output.success('Created CLAUDE.md');
|
|
200
|
+
}
|
|
178
201
|
filesCreated++;
|
|
179
202
|
}
|
|
180
203
|
}
|
|
181
204
|
// Handle AGENTS.md template for Codex setup
|
|
182
|
-
if (
|
|
183
|
-
const agentsMdPath = path.join(
|
|
205
|
+
if (agentsMd) {
|
|
206
|
+
const agentsMdPath = path.join(targetDir, 'AGENTS.md');
|
|
184
207
|
const exists = await fileExists(agentsMdPath);
|
|
185
208
|
if (exists) {
|
|
186
|
-
|
|
209
|
+
if (!quiet) {
|
|
210
|
+
output.progress('AGENTS.md already exists (not overwriting)');
|
|
211
|
+
}
|
|
187
212
|
filesSkipped++;
|
|
188
213
|
}
|
|
189
214
|
else {
|
|
190
215
|
await fs.writeFile(agentsMdPath, AGENTS_MD_TEMPLATE, 'utf-8');
|
|
191
|
-
|
|
216
|
+
if (!quiet) {
|
|
217
|
+
output.success('Created AGENTS.md');
|
|
218
|
+
}
|
|
192
219
|
filesCreated++;
|
|
193
220
|
codexProjectFilesChanged = true;
|
|
194
221
|
}
|
|
195
222
|
}
|
|
196
|
-
// Summary
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
if (
|
|
200
|
-
|
|
223
|
+
// Summary (only in standalone mode)
|
|
224
|
+
if (!quiet) {
|
|
225
|
+
output.progress('');
|
|
226
|
+
if (filesCreated > 0 && filesSkipped === 0) {
|
|
227
|
+
if (force) {
|
|
228
|
+
output.success('Guild CLI skills updated.');
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
output.success('Guild CLI skills installed. Your coding assistant can now drive agent development.');
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else if (filesCreated === 0) {
|
|
235
|
+
output.progress('No files were modified. Use --force to overwrite existing files.');
|
|
201
236
|
}
|
|
202
237
|
else {
|
|
203
|
-
output.success('Guild CLI skills installed.
|
|
238
|
+
output.success('Guild CLI skills installed.');
|
|
239
|
+
}
|
|
240
|
+
if (codexProjectFilesChanged) {
|
|
241
|
+
output.progress('Restart Codex to pick up the new project instructions.');
|
|
204
242
|
}
|
|
205
243
|
}
|
|
206
|
-
|
|
207
|
-
output.progress('No files were modified. Use --force to overwrite existing files.');
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
output.success('Guild CLI skills installed.');
|
|
211
|
-
}
|
|
212
|
-
if (codexProjectFilesChanged) {
|
|
213
|
-
output.progress('Restart Codex to pick up the new project instructions.');
|
|
214
|
-
}
|
|
244
|
+
return { filesCreated, filesSkipped };
|
|
215
245
|
}
|
|
216
246
|
export function createSetupCommand() {
|
|
217
247
|
const cmd = new Command('setup');
|
|
@@ -223,7 +253,7 @@ export function createSetupCommand() {
|
|
|
223
253
|
.option('--agents-md', 'With --codex, also create an AGENTS.md template in the project root', false)
|
|
224
254
|
.option('--no-mcp', 'Skip MCP server configuration')
|
|
225
255
|
.action(async (options) => {
|
|
226
|
-
await
|
|
256
|
+
await runSetup(process.cwd(), options);
|
|
227
257
|
});
|
|
228
258
|
return cmd;
|
|
229
259
|
}
|
|
@@ -5,15 +5,16 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { getWorkspaceId } from '../../lib/guild-config.js';
|
|
7
7
|
import { handleAxiosError } from '../../lib/errors.js';
|
|
8
|
-
import {
|
|
8
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
9
9
|
import { createOutputWriter, formatTriggerTable } from '../../lib/output.js';
|
|
10
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
10
11
|
export function createTriggerListCommand() {
|
|
11
12
|
const cmd = new Command('list');
|
|
12
13
|
cmd
|
|
13
14
|
.description('List all triggers in a workspace')
|
|
14
15
|
.option('--workspace <id>', 'Workspace ID or name')
|
|
15
|
-
.option('--limit <number>',
|
|
16
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
16
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
17
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
17
18
|
.action(async (options) => {
|
|
18
19
|
const output = createOutputWriter();
|
|
19
20
|
try {
|
|
@@ -38,7 +39,7 @@ export function createTriggerListCommand() {
|
|
|
38
39
|
params.append('limit', options.limit);
|
|
39
40
|
params.append('offset', options.offset);
|
|
40
41
|
const response = await client.get(`/workspaces/${workspaceId}/triggers?${params.toString()}`);
|
|
41
|
-
if (
|
|
42
|
+
if (isMachineReadable()) {
|
|
42
43
|
console.log(JSON.stringify(response, null, 2));
|
|
43
44
|
}
|
|
44
45
|
else {
|
|
@@ -5,13 +5,14 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
7
7
|
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
8
9
|
export function createTriggerSessionsCommand() {
|
|
9
10
|
const cmd = new Command('sessions');
|
|
10
11
|
cmd
|
|
11
12
|
.description('List sessions spawned by a trigger')
|
|
12
13
|
.argument('<trigger-id>', 'Trigger ID')
|
|
13
|
-
.option('--limit <number>',
|
|
14
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
14
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
15
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
15
16
|
.action(async (triggerId, options) => {
|
|
16
17
|
const output = createOutputWriter();
|
|
17
18
|
try {
|
|
@@ -6,15 +6,16 @@ import { getAuthToken } from '../../../lib/auth.js';
|
|
|
6
6
|
import { getWorkspaceId } from '../../../lib/guild-config.js';
|
|
7
7
|
import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
|
|
8
8
|
import { createOutputWriter, formatWorkspaceAgentTable } from '../../../lib/output.js';
|
|
9
|
-
import {
|
|
9
|
+
import { isMachineReadable } from '../../../lib/output-mode.js';
|
|
10
10
|
import { resolveWorkspaceId } from '../../../lib/workspace-helpers.js';
|
|
11
|
+
import { DEFAULT_PAGE_LIMIT } from '../../../lib/api-types.js';
|
|
11
12
|
export function createWorkspaceAgentListCommand() {
|
|
12
13
|
const cmd = new Command('list');
|
|
13
14
|
cmd
|
|
14
15
|
.description('List agents in a workspace')
|
|
15
16
|
.option('--workspace <id>', 'Workspace ID or name')
|
|
16
|
-
.option('--limit <number>',
|
|
17
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
17
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
18
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
18
19
|
.action(async (options) => {
|
|
19
20
|
const output = createOutputWriter();
|
|
20
21
|
try {
|
|
@@ -51,7 +52,7 @@ export function createWorkspaceAgentListCommand() {
|
|
|
51
52
|
params.append('limit', options.limit);
|
|
52
53
|
params.append('offset', options.offset);
|
|
53
54
|
const response = await client.get(`/workspaces/${workspaceId}/workspace_agents?${params.toString()}`);
|
|
54
|
-
if (
|
|
55
|
+
if (isMachineReadable()) {
|
|
55
56
|
output.data(response);
|
|
56
57
|
}
|
|
57
58
|
else {
|
|
@@ -3,15 +3,16 @@
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { GuildAPIClient } from '../../../lib/api-client.js';
|
|
5
5
|
import { handleAxiosError, ErrorCodes } from '../../../lib/errors.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isMachineReadable } from '../../../lib/output-mode.js';
|
|
7
7
|
import { createOutputWriter, formatContextTable } from '../../../lib/output.js';
|
|
8
|
+
import { DEFAULT_PAGE_LIMIT } from '../../../lib/api-types.js';
|
|
8
9
|
export function createWorkspaceContextListCommand() {
|
|
9
10
|
const cmd = new Command('list');
|
|
10
11
|
cmd
|
|
11
12
|
.description('List context versions for a workspace')
|
|
12
13
|
.argument('<workspace>', 'Workspace ID or full name (e.g., owner/workspace-name)')
|
|
13
|
-
.option('--limit <number>',
|
|
14
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
14
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
15
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
15
16
|
.action(async (workspaceId, options) => {
|
|
16
17
|
const output = createOutputWriter();
|
|
17
18
|
try {
|
|
@@ -20,7 +21,7 @@ export function createWorkspaceContextListCommand() {
|
|
|
20
21
|
params.append('limit', options.limit);
|
|
21
22
|
params.append('offset', options.offset);
|
|
22
23
|
const response = await client.get(`/workspaces/${workspaceId}/contexts?${params.toString()}`);
|
|
23
|
-
if (
|
|
24
|
+
if (isMachineReadable()) {
|
|
24
25
|
output.data(response);
|
|
25
26
|
}
|
|
26
27
|
else {
|
|
@@ -3,14 +3,15 @@
|
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
5
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
6
|
-
import {
|
|
6
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
7
7
|
import { createOutputWriter, formatWorkspaceTable } from '../../lib/output.js';
|
|
8
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
8
9
|
export function createWorkspaceListCommand() {
|
|
9
10
|
const cmd = new Command('list');
|
|
10
11
|
cmd
|
|
11
12
|
.description('List workspaces')
|
|
12
|
-
.option('--limit <number>',
|
|
13
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
13
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
14
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
14
15
|
.option('--owner <name>', 'Filter workspaces by owner name (case-insensitive)')
|
|
15
16
|
.action(async (options) => {
|
|
16
17
|
const output = createOutputWriter();
|
|
@@ -43,7 +44,7 @@ export function createWorkspaceListCommand() {
|
|
|
43
44
|
params.append('offset', options.offset);
|
|
44
45
|
response = await client.get(`/me/workspaces?${params.toString()}`);
|
|
45
46
|
}
|
|
46
|
-
if (
|
|
47
|
+
if (isMachineReadable()) {
|
|
47
48
|
console.log(JSON.stringify(response, null, 2));
|
|
48
49
|
}
|
|
49
50
|
else {
|
package/dist/index.js
CHANGED
|
@@ -24,6 +24,7 @@ import { createAgentForkCommand } from './commands/agent/fork.js';
|
|
|
24
24
|
import { createAgentPublishCommand } from './commands/agent/publish.js';
|
|
25
25
|
import { createAgentUnpublishCommand } from './commands/agent/unpublish.js';
|
|
26
26
|
import { createAgentRevalidateCommand } from './commands/agent/revalidate.js';
|
|
27
|
+
import { createAgentLogsCommand } from './commands/agent/logs.js';
|
|
27
28
|
import { createAgentSearchCommand } from './commands/agent/search.js';
|
|
28
29
|
import { createAgentOwnersCommand } from './commands/agent/owners.js';
|
|
29
30
|
import { createAgentWorkspacesCommand } from './commands/agent/workspaces.js';
|
|
@@ -111,8 +112,11 @@ program
|
|
|
111
112
|
.description('Guild.ai CLI - Build, test, and deploy AI agents')
|
|
112
113
|
.version(packageJson.version)
|
|
113
114
|
.option('--debug', 'Enable debug mode with verbose logging')
|
|
114
|
-
.option('--
|
|
115
|
+
.option('--mode <format>', 'Output format: interactive (default), json, or jsonl')
|
|
116
|
+
// Backward compat: --json is a hidden alias for --mode json
|
|
117
|
+
.addOption(new Option('--json').default(false).hideHelp())
|
|
115
118
|
.option('--quiet, -q', 'Suppress progress and log messages')
|
|
119
|
+
.option('--non-interactive', 'Disable interactive prompts (for CI, scripts, and coding agents)')
|
|
116
120
|
// Dev shortcuts — hidden from help, use env vars GUILD_USE_SHARED / GUILD_USE_LOCAL instead
|
|
117
121
|
.addOption(new Option('--shared').default(false).hideHelp())
|
|
118
122
|
.addOption(new Option('--local').default(false).hideHelp())
|
|
@@ -135,11 +139,13 @@ program
|
|
|
135
139
|
.argument('[prompt...]', 'Optional initial prompt (multiple words)')
|
|
136
140
|
.option('--agent <identifier>', 'Agent ID or full name, e.g., foo~bar (default: assistant)')
|
|
137
141
|
.option('--once', 'One-shot mode: send message, wait for response, exit (non-interactive)')
|
|
138
|
-
.option('--mode <format>', 'Machine-readable output format: json or jsonl')
|
|
139
142
|
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner/workspace-name)')
|
|
140
143
|
.option('--no-splash', 'Skip the splash screen animation')
|
|
141
144
|
.option('--resume <session-id>', 'Resume an existing session')
|
|
142
145
|
.option('--events <types>', 'Event types to show (default: user). Shorthands: none, user, system, all, or comma-separated type names (e.g. agent_console,llm_start)')
|
|
146
|
+
// Accept --mode here so `guild chat --mode json` doesn't error.
|
|
147
|
+
// The actual value is read from process.argv by getOutputMode().
|
|
148
|
+
.addOption(new Option('--mode <format>').hideHelp())
|
|
143
149
|
.addHelpText('after', '\nTo chat with a local agent under development: guild agent chat')
|
|
144
150
|
.action(async (promptArgs, options) => {
|
|
145
151
|
const { handleChatAction } = await import('./commands/chat.js');
|
|
@@ -170,12 +176,14 @@ agentCmd
|
|
|
170
176
|
.argument('[prompt...]', 'Optional initial prompt for the agent')
|
|
171
177
|
.option('--path <dir>', 'Path to agent directory (defaults to current directory)')
|
|
172
178
|
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner~workspace-name)')
|
|
173
|
-
.option('--mode <format>', 'Input mode: json (one-shot) or jsonl (line-by-line)')
|
|
174
179
|
.option('--agent-version <id>', 'Chat with a specific version (UUID or version number)')
|
|
175
180
|
.option('--no-splash', 'Skip the splash screen animation')
|
|
176
181
|
.option('--resume <session-id>', 'Resume an existing session')
|
|
177
182
|
.option('--open', 'Open session in web dashboard')
|
|
178
183
|
.option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')
|
|
184
|
+
// Accept --mode here so `guild agent chat --mode json` doesn't error.
|
|
185
|
+
// The actual value is read from process.argv by getOutputMode().
|
|
186
|
+
.addOption(new Option('--mode <format>').hideHelp())
|
|
179
187
|
.addHelpText('after', '\nTo chat with a published agent by name: guild chat --agent owner~agent-name')
|
|
180
188
|
.action(async (promptArgs, options) => {
|
|
181
189
|
const { handleAgentChatAction } = await import('./commands/agent/chat.js');
|
|
@@ -190,13 +198,15 @@ agentCmd
|
|
|
190
198
|
.command('test')
|
|
191
199
|
.description('Test agent in interactive REPL session')
|
|
192
200
|
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner/workspace-name)')
|
|
193
|
-
.option('--mode <format>', 'Input mode: json (one-shot) or jsonl (line-by-line)')
|
|
194
201
|
.option('--agent-version <id>', 'Test a specific version (UUID or version number)')
|
|
195
202
|
.option('--resume <session-id>', 'Resume an existing test session')
|
|
196
203
|
.option('--open', 'Open session in web dashboard')
|
|
197
204
|
.option('--events <types>', 'Event types to stream (default: all). Shorthands: none, user, system, all, or comma-separated type names')
|
|
198
205
|
.option('--bundle <file>', 'Path to a pre-built gzip+base64 bundle file')
|
|
199
206
|
.option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')
|
|
207
|
+
// Accept --mode here so `guild agent test --mode json` doesn't error.
|
|
208
|
+
// The actual value is read from process.argv by getOutputMode().
|
|
209
|
+
.addOption(new Option('--mode <format>').hideHelp())
|
|
200
210
|
.action(async (options) => {
|
|
201
211
|
const { handleAgentTestAction } = await import('./commands/agent/test.js');
|
|
202
212
|
await handleAgentTestAction(options);
|
|
@@ -204,6 +214,7 @@ agentCmd
|
|
|
204
214
|
agentCmd.addCommand(createAgentPublishCommand());
|
|
205
215
|
agentCmd.addCommand(createAgentUnpublishCommand());
|
|
206
216
|
agentCmd.addCommand(createAgentRevalidateCommand());
|
|
217
|
+
agentCmd.addCommand(createAgentLogsCommand());
|
|
207
218
|
agentCmd.addCommand(createAgentSearchCommand());
|
|
208
219
|
agentCmd.addCommand(createAgentOwnersCommand());
|
|
209
220
|
agentCmd.addCommand(createAgentWorkspacesCommand());
|
package/dist/lib/api-types.d.ts
CHANGED
|
@@ -159,6 +159,10 @@ export interface Pagination {
|
|
|
159
159
|
offset: number;
|
|
160
160
|
has_more: boolean;
|
|
161
161
|
}
|
|
162
|
+
/** Default page size for standard list endpoints (matches backend). */
|
|
163
|
+
export declare const DEFAULT_PAGE_LIMIT = 20;
|
|
164
|
+
/** Default page size for high-volume endpoints (events, tasks, operations). */
|
|
165
|
+
export declare const DEFAULT_PAGE_LIMIT_LARGE = 100;
|
|
162
166
|
/**
|
|
163
167
|
* Generic paginated response wrapper.
|
|
164
168
|
* All list endpoints return { items: T[], pagination: Pagination }
|
package/dist/lib/api-types.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
// Copyright 2026 Guild.ai
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/** Default page size for standard list endpoints (matches backend). */
|
|
4
|
+
export const DEFAULT_PAGE_LIMIT = 20;
|
|
5
|
+
/** Default page size for high-volume endpoints (events, tasks, operations). */
|
|
6
|
+
export const DEFAULT_PAGE_LIMIT_LARGE = 100;
|
|
3
7
|
// Import and re-export generated types (from cli/scripts/sync-types-from-python.py)
|
|
4
8
|
import { WEBHOOK_SERVICES, TIME_TRIGGER_FREQUENCIES, } from './generated-types.js';
|
|
5
9
|
export { WEBHOOK_SERVICES, TIME_TRIGGER_FREQUENCIES, };
|
package/dist/lib/auth.d.ts
CHANGED
|
@@ -46,7 +46,7 @@ export declare function pollForToken(authUrl: string, code: string, interval: nu
|
|
|
46
46
|
* @param returnLabel - Optional friendly label for return button (e.g., "VSCode")
|
|
47
47
|
* @returns true if successful, false otherwise
|
|
48
48
|
*/
|
|
49
|
-
export declare function login(returnUrl?: string, returnLabel?: string
|
|
49
|
+
export declare function login(returnUrl?: string, returnLabel?: string): Promise<boolean>;
|
|
50
50
|
/**
|
|
51
51
|
* Perform logout
|
|
52
52
|
*/
|
package/dist/lib/auth.js
CHANGED
|
@@ -191,12 +191,12 @@ export async function pollForToken(authUrl, code, interval) {
|
|
|
191
191
|
* @param returnLabel - Optional friendly label for return button (e.g., "VSCode")
|
|
192
192
|
* @returns true if successful, false otherwise
|
|
193
193
|
*/
|
|
194
|
-
export async function login(returnUrl, returnLabel
|
|
194
|
+
export async function login(returnUrl, returnLabel) {
|
|
195
195
|
const authUrl = getGuildcoreUrl();
|
|
196
196
|
try {
|
|
197
197
|
console.log(chalk.bold('\nGuild.ai Authentication'));
|
|
198
198
|
const deviceCode = await startDeviceFlow(authUrl, returnUrl, returnLabel);
|
|
199
|
-
const skipBrowser =
|
|
199
|
+
const skipBrowser = !isInteractive();
|
|
200
200
|
if (skipBrowser) {
|
|
201
201
|
console.log(`\nVerification code: ${deviceCode.user_code}`);
|
|
202
202
|
console.log(`Open to authenticate: ${deviceCode.verification_uri_complete}\n`);
|
|
@@ -1,11 +1,18 @@
|
|
|
1
|
-
export type OutputMode = 'interactive' | 'json';
|
|
1
|
+
export type OutputMode = 'interactive' | 'json' | 'jsonl';
|
|
2
2
|
/**
|
|
3
3
|
* Detect output mode from CLI flags or config
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Priority: --mode <value> > --json (backward compat) > config
|
|
6
6
|
* Does NOT auto-detect pipes (user must request JSON explicitly).
|
|
7
7
|
*/
|
|
8
8
|
export declare function getOutputMode(): OutputMode;
|
|
9
|
+
/**
|
|
10
|
+
* Check if the current output mode is machine-readable (json or jsonl).
|
|
11
|
+
*
|
|
12
|
+
* Use this in list/get commands instead of `getOutputMode() === 'json'`
|
|
13
|
+
* so that both --mode json and --mode jsonl trigger non-interactive output.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isMachineReadable(): boolean;
|
|
9
16
|
/**
|
|
10
17
|
* Check if quiet mode is enabled (CLI flag or config)
|
|
11
18
|
*
|
package/dist/lib/output-mode.js
CHANGED
|
@@ -4,21 +4,42 @@
|
|
|
4
4
|
* Output mode detection for the CLI
|
|
5
5
|
*
|
|
6
6
|
* Interactive mode (default): Colors, tables, spinners, interactive
|
|
7
|
-
* JSON mode (--json): Pure JSON, non-interactive, machine-readable
|
|
7
|
+
* JSON mode (--mode json or --json): Pure JSON, non-interactive, machine-readable
|
|
8
|
+
* JSONL mode (--mode jsonl): Line-delimited JSON for streaming
|
|
8
9
|
*/
|
|
9
10
|
import { getConfigFlag } from './config-cache.js';
|
|
10
11
|
/**
|
|
11
12
|
* Detect output mode from CLI flags or config
|
|
12
13
|
*
|
|
13
|
-
*
|
|
14
|
+
* Priority: --mode <value> > --json (backward compat) > config
|
|
14
15
|
* Does NOT auto-detect pipes (user must request JSON explicitly).
|
|
15
16
|
*/
|
|
16
17
|
export function getOutputMode() {
|
|
18
|
+
// Check --mode <value> first (primary flag)
|
|
19
|
+
const modeIndex = process.argv.indexOf('--mode');
|
|
20
|
+
if (modeIndex !== -1 && modeIndex + 1 < process.argv.length) {
|
|
21
|
+
const value = process.argv[modeIndex + 1];
|
|
22
|
+
if (value === 'json' || value === 'jsonl') {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
// --mode interactive falls through to default
|
|
26
|
+
}
|
|
27
|
+
// Backward compat: --json is equivalent to --mode json
|
|
17
28
|
if (process.argv.includes('--json') || getConfigFlag('json')) {
|
|
18
29
|
return 'json';
|
|
19
30
|
}
|
|
20
31
|
return 'interactive';
|
|
21
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Check if the current output mode is machine-readable (json or jsonl).
|
|
35
|
+
*
|
|
36
|
+
* Use this in list/get commands instead of `getOutputMode() === 'json'`
|
|
37
|
+
* so that both --mode json and --mode jsonl trigger non-interactive output.
|
|
38
|
+
*/
|
|
39
|
+
export function isMachineReadable() {
|
|
40
|
+
const mode = getOutputMode();
|
|
41
|
+
return mode === 'json' || mode === 'jsonl';
|
|
42
|
+
}
|
|
22
43
|
/**
|
|
23
44
|
* Check if quiet mode is enabled (CLI flag or config)
|
|
24
45
|
*
|
package/dist/lib/output.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Spinner } from './progress.js';
|
|
2
|
-
import type { Agent, AgentVersion, Credentials, CredentialsPolicy, Context, Integration, IntegrationVersion, JobStep, Pagination, Session, Task, Workspace, WorkspaceAgent, Trigger } from './api-types.js';
|
|
2
|
+
import type { Agent, AgentVersion, Credentials, CredentialsPolicy, Context, Integration, IntegrationVersion, JobStep, Pagination, Session, Task, ValidationStep, Workspace, WorkspaceAgent, Trigger } from './api-types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Format an agent list as a human-readable table.
|
|
5
5
|
* Shared by agent list and agent search commands.
|
|
@@ -57,6 +57,12 @@ export declare function formatPoliciesTable(policies: CredentialsPolicy[], pagin
|
|
|
57
57
|
* Used by job get command.
|
|
58
58
|
*/
|
|
59
59
|
export declare function formatJobStepTable(steps: JobStep[]): void;
|
|
60
|
+
/**
|
|
61
|
+
* Format validation step logs as human-readable output.
|
|
62
|
+
* Prints each step's name, colored status, and full log content.
|
|
63
|
+
* Used by the `guild agent logs` command.
|
|
64
|
+
*/
|
|
65
|
+
export declare function formatValidationLogs(steps: ValidationStep[]): void;
|
|
60
66
|
/**
|
|
61
67
|
* Output writer interface for consistent CLI output
|
|
62
68
|
*
|
package/dist/lib/output.js
CHANGED
|
@@ -195,7 +195,7 @@ export function formatVersionTable(versions, pagination) {
|
|
|
195
195
|
? chalk.red
|
|
196
196
|
: chalk.dim;
|
|
197
197
|
table.addRow({
|
|
198
|
-
id: v.id
|
|
198
|
+
id: v.id,
|
|
199
199
|
version: v.version_number || '-',
|
|
200
200
|
status: v.status,
|
|
201
201
|
validation: validationColor(v.validation_status || '-'),
|
|
@@ -225,7 +225,7 @@ export function formatContextTable(contexts, pagination) {
|
|
|
225
225
|
});
|
|
226
226
|
contexts.forEach((ctx) => {
|
|
227
227
|
table.addRow({
|
|
228
|
-
id:
|
|
228
|
+
id: ctx.id,
|
|
229
229
|
status: ctx.status,
|
|
230
230
|
type: ctx.type || '-',
|
|
231
231
|
created: ctx.created_at ? formatRelativeTime(ctx.created_at) : '',
|
|
@@ -256,7 +256,7 @@ export function formatWorkspaceAgentTable(agents) {
|
|
|
256
256
|
const agentUrl = wa.agent.full_name ? `${base}/agents/${wa.agent.full_name}` : '';
|
|
257
257
|
table.addRow({
|
|
258
258
|
name: agentUrl ? hyperlink(name, agentUrl) : name,
|
|
259
|
-
version: wa.agent_version.version_number || wa.agent_version.id
|
|
259
|
+
version: wa.agent_version.version_number || wa.agent_version.id,
|
|
260
260
|
auto_update: wa.should_autoupdate ? chalk.green('yes') : chalk.dim('no'),
|
|
261
261
|
});
|
|
262
262
|
});
|
|
@@ -353,7 +353,7 @@ export function formatTaskTable(tasks, pagination) {
|
|
|
353
353
|
? chalk.yellow
|
|
354
354
|
: chalk.dim;
|
|
355
355
|
table.addRow({
|
|
356
|
-
id:
|
|
356
|
+
id: task.id,
|
|
357
357
|
name,
|
|
358
358
|
status: statusColor(task.status),
|
|
359
359
|
tokens: task.token_usage ? task.token_usage.total_tokens.toLocaleString() : '-',
|
|
@@ -506,6 +506,35 @@ export function formatJobStepTable(steps) {
|
|
|
506
506
|
});
|
|
507
507
|
table.printTable();
|
|
508
508
|
}
|
|
509
|
+
/**
|
|
510
|
+
* Format validation step logs as human-readable output.
|
|
511
|
+
* Prints each step's name, colored status, and full log content.
|
|
512
|
+
* Used by the `guild agent logs` command.
|
|
513
|
+
*/
|
|
514
|
+
export function formatValidationLogs(steps) {
|
|
515
|
+
if (steps.length === 0) {
|
|
516
|
+
console.log(chalk.dim('No steps found'));
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
const hr = chalk.dim('─'.repeat(60));
|
|
520
|
+
steps.forEach((step, index) => {
|
|
521
|
+
if (index > 0) {
|
|
522
|
+
console.log(hr);
|
|
523
|
+
}
|
|
524
|
+
const statusColor = step.status === 'SUCCEEDED'
|
|
525
|
+
? chalk.green
|
|
526
|
+
: step.status === 'FAILED' || step.status === 'ERRORED'
|
|
527
|
+
? chalk.red
|
|
528
|
+
: step.status === 'RUNNING'
|
|
529
|
+
? chalk.yellow
|
|
530
|
+
: chalk.dim;
|
|
531
|
+
console.log(`${chalk.bold(step.name)} ${statusColor(step.status)}`);
|
|
532
|
+
if (step.content) {
|
|
533
|
+
console.log();
|
|
534
|
+
console.log(step.content);
|
|
535
|
+
}
|
|
536
|
+
});
|
|
537
|
+
}
|
|
509
538
|
/**
|
|
510
539
|
* Human-friendly output writer
|
|
511
540
|
*
|
|
@@ -573,7 +602,9 @@ export class JSONOutputWriter {
|
|
|
573
602
|
*/
|
|
574
603
|
export function createOutputWriter() {
|
|
575
604
|
const mode = getOutputMode();
|
|
576
|
-
return mode === '
|
|
605
|
+
return mode === 'interactive'
|
|
606
|
+
? new InteractiveOutputWriter()
|
|
607
|
+
: new JSONOutputWriter();
|
|
577
608
|
}
|
|
578
609
|
/**
|
|
579
610
|
* Create a no-op spinner (for quiet/JSON modes)
|
|
@@ -13,6 +13,9 @@ export interface ResolveOwnerOptions {
|
|
|
13
13
|
ownerFlag?: string;
|
|
14
14
|
client: GuildAPIClient;
|
|
15
15
|
interactive: boolean;
|
|
16
|
+
/** When true, error if multiple accounts and no explicit owner in non-interactive mode.
|
|
17
|
+
* When false (default), fall back to current user. */
|
|
18
|
+
requireExplicitOwner?: boolean;
|
|
16
19
|
}
|
|
17
20
|
export declare function resolveOwnerId(options: ResolveOwnerOptions): Promise<OwnerChoice>;
|
|
18
21
|
//# sourceMappingURL=owner-helpers.d.ts.map
|