@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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Guild.ai
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
3
|
+
import { Command, Option } from 'commander';
|
|
4
4
|
import { render } from 'ink';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import open from 'open';
|
|
@@ -31,12 +31,14 @@ export function createAgentChatCommand() {
|
|
|
31
31
|
.argument('[prompt...]', 'Optional initial prompt for the agent')
|
|
32
32
|
.option('--path <dir>', 'Path to agent directory (defaults to current directory)')
|
|
33
33
|
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner~workspace-name)')
|
|
34
|
-
.option('--mode <format>', 'Input mode: json (one-shot) or jsonl (line-by-line)')
|
|
35
34
|
.option('--agent-version <id>', 'Chat with a specific version (UUID or version number)')
|
|
36
35
|
.option('--no-splash', 'Skip the splash screen animation')
|
|
37
36
|
.option('--resume <session-id>', 'Resume an existing session')
|
|
38
37
|
.option('--open', 'Open session in web dashboard')
|
|
39
38
|
.option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')
|
|
39
|
+
// Accept --mode so `guild agent chat --mode json` works when re-parsed.
|
|
40
|
+
// The actual value is read from process.argv by getOutputMode().
|
|
41
|
+
.addOption(new Option('--mode <format>').hideHelp())
|
|
40
42
|
.addHelpText('after', '\nTo chat with a published agent by name: guild chat --agent owner~agent-name')
|
|
41
43
|
.action(async (promptArgs, options) => {
|
|
42
44
|
try {
|
|
@@ -45,8 +47,9 @@ export function createAgentChatCommand() {
|
|
|
45
47
|
const { agentId, config } = await getAgentId(undefined, agentPath);
|
|
46
48
|
const initialPrompt = promptArgs.length > 0 ? promptArgs.join(' ') : 'Hello';
|
|
47
49
|
// If using JSON input, read it early (before auth) for fast failure on bad input
|
|
50
|
+
const outputMode = getOutputMode();
|
|
48
51
|
let inputData;
|
|
49
|
-
if (
|
|
52
|
+
if (outputMode === 'json') {
|
|
50
53
|
try {
|
|
51
54
|
inputData = await readStdinAsJSON();
|
|
52
55
|
}
|
|
@@ -98,10 +101,10 @@ export function createAgentChatCommand() {
|
|
|
98
101
|
}
|
|
99
102
|
}
|
|
100
103
|
// Branch: JSON/JSONL modes vs interactive
|
|
101
|
-
if (
|
|
104
|
+
if (outputMode === 'json' || outputMode === 'jsonl') {
|
|
102
105
|
// For JSON mode with piped input, use the piped data as the initial prompt
|
|
103
106
|
// so the agent receives it as its input (not the default 'Hello')
|
|
104
|
-
const sessionPrompt =
|
|
107
|
+
const sessionPrompt = outputMode === 'json' && inputData
|
|
105
108
|
? JSON.stringify(inputData)
|
|
106
109
|
: initialPrompt;
|
|
107
110
|
// Pre-resolve workspace so we can show the source label in output.
|
|
@@ -133,7 +136,7 @@ export function createAgentChatCommand() {
|
|
|
133
136
|
if (options.open && session.session_url) {
|
|
134
137
|
await open(session.session_url);
|
|
135
138
|
}
|
|
136
|
-
if (
|
|
139
|
+
if (outputMode === 'json' && inputData) {
|
|
137
140
|
// JSON one-shot mode — input was passed as initial_prompt during
|
|
138
141
|
// session creation, so the agent already has it. Just poll for the response.
|
|
139
142
|
try {
|
|
@@ -158,7 +161,7 @@ export function createAgentChatCommand() {
|
|
|
158
161
|
process.exit(1);
|
|
159
162
|
}
|
|
160
163
|
}
|
|
161
|
-
else if (
|
|
164
|
+
else if (outputMode === 'jsonl') {
|
|
162
165
|
// JSONL line-by-line mode
|
|
163
166
|
const rl = readline.createInterface({
|
|
164
167
|
input: process.stdin,
|
|
@@ -88,6 +88,8 @@ export function createAgentCloneCommand() {
|
|
|
88
88
|
output.progress(' 3. git add . && git commit -m "your changes"');
|
|
89
89
|
output.progress(" 4. Run 'guild agent save' to push and create a version");
|
|
90
90
|
output.progress(` 5. Run 'guild agent test' to test your changes`);
|
|
91
|
+
output.progress('');
|
|
92
|
+
output.progress(`Tip: Using a coding agent? Run 'guild setup' to install skills for Claude Code, Codex, etc.`);
|
|
91
93
|
}
|
|
92
94
|
catch (error) {
|
|
93
95
|
if (error instanceof GitError) {
|
|
@@ -143,6 +143,7 @@ export function createAgentForkCommand() {
|
|
|
143
143
|
ownerFlag: options.owner,
|
|
144
144
|
client,
|
|
145
145
|
interactive: isInteractive(),
|
|
146
|
+
requireExplicitOwner: true,
|
|
146
147
|
});
|
|
147
148
|
// Create forked agent
|
|
148
149
|
output.progress(`✓ Forking agent '${agentName}'...`);
|
|
@@ -189,6 +190,8 @@ export function createAgentForkCommand() {
|
|
|
189
190
|
output.progress(' 2. Make your changes to the code');
|
|
190
191
|
output.progress(` 3. Run 'guild agent save --message "your changes"'`);
|
|
191
192
|
output.progress(` 4. Run 'guild agent test' to test your changes`);
|
|
193
|
+
output.progress('');
|
|
194
|
+
output.progress(`Tip: Using a coding agent? Run 'guild setup' to install skills for Claude Code, Codex, etc.`);
|
|
192
195
|
}
|
|
193
196
|
catch (error) {
|
|
194
197
|
if (error instanceof GitError) {
|
|
@@ -59,6 +59,20 @@ async function promptForName(defaultName) {
|
|
|
59
59
|
});
|
|
60
60
|
return ask();
|
|
61
61
|
}
|
|
62
|
+
async function confirmCreation(ownerName, agentName) {
|
|
63
|
+
const rl = readline.createInterface({
|
|
64
|
+
input: process.stdin,
|
|
65
|
+
output: process.stdout,
|
|
66
|
+
});
|
|
67
|
+
return new Promise((resolve) => {
|
|
68
|
+
rl.question(`\nYou are about to create agent "${ownerName}~${agentName}".\n` +
|
|
69
|
+
'Warning: Owner and name cannot be changed after creation, and agents cannot be deleted.\n\n' +
|
|
70
|
+
'Continue? [y/N] ', (answer) => {
|
|
71
|
+
rl.close();
|
|
72
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
73
|
+
});
|
|
74
|
+
});
|
|
75
|
+
}
|
|
62
76
|
async function promptForTemplate() {
|
|
63
77
|
const { default: inquirer } = await import('inquirer');
|
|
64
78
|
const { template } = await inquirer.prompt([
|
|
@@ -80,17 +94,37 @@ export function createAgentInitCommand() {
|
|
|
80
94
|
.option('--template <template>', 'Agent template (LLM, AUTO_MANAGED_STATE, BLANK)')
|
|
81
95
|
.option('--fork <agent-id>', 'Fork from existing agent')
|
|
82
96
|
.option('--owner <owner>', 'Owner (name or ID)')
|
|
83
|
-
.option('--directory <path>', 'Directory to initialize (created if needed)')
|
|
97
|
+
.option('--directory <path>', 'Directory to initialize (default: ./<name>, created if needed)')
|
|
84
98
|
.option('--force', 'Overwrite existing guild.json', false)
|
|
85
99
|
.action(async (options) => {
|
|
86
|
-
//
|
|
100
|
+
// Get agent name first (needed to determine default directory)
|
|
101
|
+
let agentName = options.name;
|
|
102
|
+
if (!agentName) {
|
|
103
|
+
if (isInteractive()) {
|
|
104
|
+
const dirName = path.basename(process.cwd());
|
|
105
|
+
const defaultName = slugify(dirName);
|
|
106
|
+
agentName = await promptForName(defaultName);
|
|
107
|
+
if (!agentName) {
|
|
108
|
+
console.error('Error: Agent name cannot be empty');
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.error('Error: Agent name is required');
|
|
114
|
+
console.error('');
|
|
115
|
+
console.error('Provide a name:');
|
|
116
|
+
console.error(' guild agent init --name my-agent');
|
|
117
|
+
console.error('');
|
|
118
|
+
console.error('Or run interactively to be prompted for a name.');
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Resolve target directory: --directory overrides, otherwise ./<name>
|
|
87
123
|
const targetDir = options.directory
|
|
88
124
|
? path.resolve(process.cwd(), options.directory)
|
|
89
|
-
: process.cwd();
|
|
125
|
+
: path.resolve(process.cwd(), agentName);
|
|
90
126
|
// Create directory if it doesn't exist
|
|
91
|
-
|
|
92
|
-
await fs.mkdir(targetDir, { recursive: true });
|
|
93
|
-
}
|
|
127
|
+
await fs.mkdir(targetDir, { recursive: true });
|
|
94
128
|
const guildJsonPath = path.join(targetDir, 'guild.json');
|
|
95
129
|
try {
|
|
96
130
|
// Check if already initialized
|
|
@@ -107,29 +141,6 @@ export function createAgentInitCommand() {
|
|
|
107
141
|
console.error('To reinitialize, use: guild agent init --force');
|
|
108
142
|
process.exit(1);
|
|
109
143
|
}
|
|
110
|
-
// Get agent name
|
|
111
|
-
let agentName = options.name;
|
|
112
|
-
if (!agentName) {
|
|
113
|
-
if (isInteractive()) {
|
|
114
|
-
// Use slugified directory name as default
|
|
115
|
-
const dirName = path.basename(targetDir);
|
|
116
|
-
const defaultName = slugify(dirName);
|
|
117
|
-
agentName = await promptForName(defaultName);
|
|
118
|
-
if (!agentName) {
|
|
119
|
-
console.error('Error: Agent name cannot be empty');
|
|
120
|
-
process.exit(1);
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
console.error('Error: Agent name is required');
|
|
125
|
-
console.error('');
|
|
126
|
-
console.error('Provide a name:');
|
|
127
|
-
console.error(' guild agent init --name my-agent');
|
|
128
|
-
console.error('');
|
|
129
|
-
console.error('Or run interactively to be prompted for a name.');
|
|
130
|
-
process.exit(1);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
144
|
// Validate name (catches --name flag and non-interactive paths)
|
|
134
145
|
if (!isValidAgentName(agentName)) {
|
|
135
146
|
console.error(`Error: Invalid agent name "${agentName}"`);
|
|
@@ -176,14 +187,15 @@ export function createAgentInitCommand() {
|
|
|
176
187
|
process.exit(1);
|
|
177
188
|
}
|
|
178
189
|
// Create progress tracker for initialization steps
|
|
179
|
-
const
|
|
190
|
+
const stepNames = [
|
|
180
191
|
'Create agent in backend',
|
|
181
192
|
'Initialize git repository',
|
|
182
193
|
'Configure git remote',
|
|
183
194
|
'Wait for backend initialization',
|
|
184
195
|
'Pull scaffolding from remote',
|
|
185
196
|
'Create guild.json',
|
|
186
|
-
]
|
|
197
|
+
];
|
|
198
|
+
const steps = createSteps(stepNames);
|
|
187
199
|
steps.start();
|
|
188
200
|
// Step 1: Create agent in backend
|
|
189
201
|
const client = new GuildAPIClient();
|
|
@@ -192,7 +204,15 @@ export function createAgentInitCommand() {
|
|
|
192
204
|
ownerFlag: options.owner,
|
|
193
205
|
client,
|
|
194
206
|
interactive: isInteractive(),
|
|
207
|
+
requireExplicitOwner: true,
|
|
195
208
|
});
|
|
209
|
+
if (isInteractive()) {
|
|
210
|
+
const confirmed = await confirmCreation(owner.name, agentName);
|
|
211
|
+
if (!confirmed) {
|
|
212
|
+
console.log('Cancelled.');
|
|
213
|
+
process.exit(0);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
196
216
|
const agent = await client.post('/agents', {
|
|
197
217
|
name: agentName,
|
|
198
218
|
description: `Agent created via CLI`,
|
|
@@ -346,19 +366,13 @@ export function createAgentInitCommand() {
|
|
|
346
366
|
steps.complete('Agent initialized successfully');
|
|
347
367
|
// Display next steps
|
|
348
368
|
format.section('Next steps:');
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
else {
|
|
357
|
-
format.detail('1. Edit agent.ts to implement your agent logic');
|
|
358
|
-
format.detail('2. git add . && git commit -m "Initial implementation"');
|
|
359
|
-
format.detail("3. Run 'guild agent save' to push and create a version");
|
|
360
|
-
format.detail(`4. Run 'guild agent test' to test your agent`);
|
|
361
|
-
}
|
|
369
|
+
format.detail(`1. cd ${targetDir}`);
|
|
370
|
+
format.detail('2. Edit agent.ts to implement your agent logic');
|
|
371
|
+
format.detail('3. git add . && git commit -m "Initial implementation"');
|
|
372
|
+
format.detail("4. Run 'guild agent save' to push and create a version");
|
|
373
|
+
format.detail(`5. Run 'guild agent test' to test your agent`);
|
|
374
|
+
format.detail('');
|
|
375
|
+
format.detail(`Tip: Using a coding agent? Run 'guild setup' to install skills for Claude Code, Codex, etc.`);
|
|
362
376
|
}
|
|
363
377
|
catch (error) {
|
|
364
378
|
if (error instanceof GitError) {
|
|
@@ -4,8 +4,9 @@ import { Command } from 'commander';
|
|
|
4
4
|
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
|
-
import {
|
|
7
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
8
8
|
import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
|
|
9
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
9
10
|
const SORT_MAP = {
|
|
10
11
|
updated: 'updated_at',
|
|
11
12
|
newest: 'created_at',
|
|
@@ -23,8 +24,8 @@ export function createAgentListCommand() {
|
|
|
23
24
|
.option('--all', 'Show all agents including archived')
|
|
24
25
|
.option('--owner <name>', 'Filter by owner (user or org name). Without this flag, lists your own agents')
|
|
25
26
|
.option('--workspace <id>', 'Filter agents by workspace ID or name')
|
|
26
|
-
.option('--limit <number>',
|
|
27
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
27
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
28
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
28
29
|
.action(async (options) => {
|
|
29
30
|
const output = createOutputWriter();
|
|
30
31
|
if (options.archived && options.all) {
|
|
@@ -79,7 +80,7 @@ export function createAgentListCommand() {
|
|
|
79
80
|
if (options.archived) {
|
|
80
81
|
response.items = response.items.filter((a) => a.is_archived);
|
|
81
82
|
}
|
|
82
|
-
if (
|
|
83
|
+
if (isMachineReadable()) {
|
|
83
84
|
output.data(response);
|
|
84
85
|
}
|
|
85
86
|
else {
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
|
+
import { getGuildcoreUrl } from '../../lib/config.js';
|
|
6
|
+
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
7
|
+
import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
8
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
9
|
+
import { createOutputWriter, formatValidationLogs } from '../../lib/output.js';
|
|
10
|
+
export function createAgentLogsCommand() {
|
|
11
|
+
const cmd = new Command('logs');
|
|
12
|
+
cmd
|
|
13
|
+
.description('Show build/validation logs for an agent version')
|
|
14
|
+
.argument('[identifier]', 'Agent ID or full name (e.g., "owner~agent-name")')
|
|
15
|
+
.argument('[version-id]', 'ID of the version to show logs for (uses latest if omitted)')
|
|
16
|
+
.action(async (agentIdArg, versionIdArg) => {
|
|
17
|
+
const output = createOutputWriter();
|
|
18
|
+
// Get agent ID from argument or guild.json
|
|
19
|
+
const { agentId } = await getAgentId(agentIdArg);
|
|
20
|
+
const baseUrl = getGuildcoreUrl();
|
|
21
|
+
const client = new GuildAPIClient({ baseUrl });
|
|
22
|
+
try {
|
|
23
|
+
const resolvedId = await resolveAgentRef(client, agentId);
|
|
24
|
+
let versionId = versionIdArg;
|
|
25
|
+
// If no version ID provided, get the latest version
|
|
26
|
+
if (!versionId) {
|
|
27
|
+
const versions = await client.get(`/agents/${resolvedId}/versions?limit=1&offset=0`);
|
|
28
|
+
if (!versions.items || versions.items.length === 0) {
|
|
29
|
+
output.error('No versions found for this agent.', `The agent may still be initializing. Check status:\n guild agent get ${agentId}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
versionId = versions.items[0].id;
|
|
33
|
+
}
|
|
34
|
+
// Fetch validation steps for the version
|
|
35
|
+
const stepsResponse = await client.get(`/versions/${versionId}/validation/steps`);
|
|
36
|
+
if (isMachineReadable()) {
|
|
37
|
+
output.data(stepsResponse);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
formatValidationLogs(stepsResponse.steps);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
const formattedError = handleAxiosError(error);
|
|
45
|
+
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
46
|
+
output.error('Not authenticated.', 'Please authenticate first:\n guild auth login');
|
|
47
|
+
}
|
|
48
|
+
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
49
|
+
output.error('Cannot connect to Guild servers');
|
|
50
|
+
}
|
|
51
|
+
else if (formattedError.code === ErrorCodes.NOT_FOUND) {
|
|
52
|
+
output.error('Agent or version not found', `Check the agent and version IDs:\n guild agent list\n guild agent versions ${agentId}`);
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
output.error(`Failed to retrieve logs: ${formattedError.details}`);
|
|
56
|
+
}
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
return cmd;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=logs.js.map
|
|
@@ -4,7 +4,7 @@ import { Command } from 'commander';
|
|
|
4
4
|
import chalk from 'chalk';
|
|
5
5
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
6
6
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
7
|
-
import {
|
|
7
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
8
8
|
import { createOutputWriter } from '../../lib/output.js';
|
|
9
9
|
import { loadGlobalConfig } from '../../lib/guild-config.js';
|
|
10
10
|
export function createAgentOwnersCommand() {
|
|
@@ -12,7 +12,7 @@ export function createAgentOwnersCommand() {
|
|
|
12
12
|
cmd.description('List accounts that can own agents').action(async () => {
|
|
13
13
|
const output = createOutputWriter();
|
|
14
14
|
try {
|
|
15
|
-
const mode =
|
|
15
|
+
const mode = isMachineReadable();
|
|
16
16
|
const client = new GuildAPIClient();
|
|
17
17
|
const [me, orgs, globalConfig] = await Promise.all([
|
|
18
18
|
client.get('/me'),
|
|
@@ -34,7 +34,7 @@ export function createAgentOwnersCommand() {
|
|
|
34
34
|
is_default: defaultOwnerId === org.id,
|
|
35
35
|
})),
|
|
36
36
|
];
|
|
37
|
-
if (mode
|
|
37
|
+
if (mode) {
|
|
38
38
|
output.data({ owners });
|
|
39
39
|
return;
|
|
40
40
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
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 } from '../../lib/output.js';
|
|
8
8
|
import * as fs from 'fs/promises';
|
|
9
9
|
import * as path from 'path';
|
|
@@ -11,10 +11,7 @@ import { getAuthenticatedUrl } from '../../lib/auth.js';
|
|
|
11
11
|
import { runGit, GitError, formatGitError } from '../../lib/git.js';
|
|
12
12
|
export function createAgentPullCommand() {
|
|
13
13
|
const cmd = new Command('pull');
|
|
14
|
-
cmd
|
|
15
|
-
.description('Pull remote changes into local agent directory')
|
|
16
|
-
.option('--json', 'Output JSON only (no progress messages)', false)
|
|
17
|
-
.action(async (_options) => {
|
|
14
|
+
cmd.description('Pull remote changes into local agent directory').action(async () => {
|
|
18
15
|
const cwd = process.cwd();
|
|
19
16
|
const output = createOutputWriter();
|
|
20
17
|
try {
|
|
@@ -82,8 +79,7 @@ export function createAgentPullCommand() {
|
|
|
82
79
|
? pullError.stderr || pullError.stdout
|
|
83
80
|
: String(pullError);
|
|
84
81
|
// Check for rebase conflicts
|
|
85
|
-
if (errMessage.includes('CONFLICT') ||
|
|
86
|
-
errMessage.includes('could not apply')) {
|
|
82
|
+
if (errMessage.includes('CONFLICT') || errMessage.includes('could not apply')) {
|
|
87
83
|
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');
|
|
88
84
|
process.exit(1);
|
|
89
85
|
}
|
|
@@ -91,7 +87,7 @@ export function createAgentPullCommand() {
|
|
|
91
87
|
if (errMessage.includes('no tracking information') ||
|
|
92
88
|
errMessage.includes("couldn't find remote ref")) {
|
|
93
89
|
output.progress('✓ Already up to date (no remote branch yet)');
|
|
94
|
-
if (
|
|
90
|
+
if (isMachineReadable()) {
|
|
95
91
|
output.data({
|
|
96
92
|
success: true,
|
|
97
93
|
message: 'Already up to date (no remote branch yet)',
|
|
@@ -113,7 +109,7 @@ export function createAgentPullCommand() {
|
|
|
113
109
|
if (!gitPulledNewCommits) {
|
|
114
110
|
output.progress('✓ Already up to date');
|
|
115
111
|
}
|
|
116
|
-
if (
|
|
112
|
+
if (isMachineReadable()) {
|
|
117
113
|
output.data({
|
|
118
114
|
success: true,
|
|
119
115
|
message: gitPulledNewCommits
|
|
@@ -126,7 +122,7 @@ export function createAgentPullCommand() {
|
|
|
126
122
|
// SHA mismatch — warn user
|
|
127
123
|
output.progress(`⚠ Remote has a newer version (${latest.sha.slice(0, 7)}) not on this branch`);
|
|
128
124
|
output.progress(' Try: git fetch origin && git log --oneline origin/main');
|
|
129
|
-
if (
|
|
125
|
+
if (isMachineReadable()) {
|
|
130
126
|
output.data({
|
|
131
127
|
success: true,
|
|
132
128
|
message: 'SHA mismatch with latest version',
|
|
@@ -151,7 +147,7 @@ export function createAgentPullCommand() {
|
|
|
151
147
|
await fs.writeFile(filePath, file.content, 'utf-8');
|
|
152
148
|
}
|
|
153
149
|
output.progress(`✓ Downloaded ${files.length} files from latest draft version`);
|
|
154
|
-
if (
|
|
150
|
+
if (isMachineReadable()) {
|
|
155
151
|
output.data({
|
|
156
152
|
success: true,
|
|
157
153
|
message: `Downloaded ${files.length} files from draft version`,
|
|
@@ -165,7 +161,7 @@ export function createAgentPullCommand() {
|
|
|
165
161
|
if (!gitPulledNewCommits) {
|
|
166
162
|
output.progress('✓ Already up to date');
|
|
167
163
|
}
|
|
168
|
-
if (
|
|
164
|
+
if (isMachineReadable()) {
|
|
169
165
|
output.data({
|
|
170
166
|
success: true,
|
|
171
167
|
message: gitPulledNewCommits
|
|
@@ -3,7 +3,7 @@
|
|
|
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 } from '../../lib/output.js';
|
|
8
8
|
import * as fs from 'fs/promises';
|
|
9
9
|
import * as path from 'path';
|
|
@@ -16,11 +16,10 @@ export function createAgentSaveCommand() {
|
|
|
16
16
|
.description('Commit, push, and create a new agent version')
|
|
17
17
|
.option('-A, --all', 'Stage all changes and commit before pushing', false)
|
|
18
18
|
.option('-m, --message <text>', 'Commit message (required with --all)')
|
|
19
|
-
.option('--wait', 'Wait for validation to complete before returning', false)
|
|
20
|
-
.option('--publish', 'Publish after validation passes (implies --wait)', false)
|
|
21
|
-
.option('--bump [level]', 'Bump package.json version before saving (patch, or minor/major)', 'patch')
|
|
19
|
+
.option('--wait', 'Wait for validation to complete before returning (default: returns immediately)', false)
|
|
20
|
+
.option('--publish', 'Publish after validation passes (implies --wait) (default: does not publish)', false)
|
|
21
|
+
.option('--bump [level]', 'Bump package.json version before saving (patch, or minor/major) (default: patch)', 'patch')
|
|
22
22
|
.option('--no-bump', 'Skip automatic version bump')
|
|
23
|
-
.option('--json', 'Output JSON only (no progress messages)', false)
|
|
24
23
|
.action(async (options) => {
|
|
25
24
|
const cwd = process.cwd();
|
|
26
25
|
let guildConfig = null;
|
|
@@ -314,7 +313,7 @@ export function createAgentSaveCommand() {
|
|
|
314
313
|
// Output JSON to stdout only in --json mode.
|
|
315
314
|
// In interactive mode the progress messages above already
|
|
316
315
|
// show version details; dumping raw JSON is noise.
|
|
317
|
-
if (
|
|
316
|
+
if (isMachineReadable()) {
|
|
318
317
|
output.data({ version });
|
|
319
318
|
}
|
|
320
319
|
}
|
|
@@ -4,8 +4,9 @@ import { Command } from 'commander';
|
|
|
4
4
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
|
-
import {
|
|
7
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
8
8
|
import { createOutputWriter, formatAgentTable } from '../../lib/output.js';
|
|
9
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
9
10
|
const SORT_MAP = {
|
|
10
11
|
updated: 'updated_at',
|
|
11
12
|
newest: 'created_at',
|
|
@@ -19,8 +20,8 @@ export function createAgentSearchCommand() {
|
|
|
19
20
|
.argument('<query>', 'Search query')
|
|
20
21
|
.option('--sort <field>', 'Sort by: updated, newest, name, popular (default: updated)', 'updated')
|
|
21
22
|
.option('--published', 'Only show published agents')
|
|
22
|
-
.option('--limit <number>',
|
|
23
|
-
.option('--offset <number>', 'Offset for pagination', '0')
|
|
23
|
+
.option('--limit <number>', `Number of results to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
24
|
+
.option('--offset <number>', 'Offset for pagination (default: 0)', '0')
|
|
24
25
|
.action(async (query, options) => {
|
|
25
26
|
const output = createOutputWriter();
|
|
26
27
|
try {
|
|
@@ -42,7 +43,7 @@ export function createAgentSearchCommand() {
|
|
|
42
43
|
params.append('sort_by', sortField);
|
|
43
44
|
}
|
|
44
45
|
const response = await client.get(`/agents?${params.toString()}`);
|
|
45
|
-
if (
|
|
46
|
+
if (isMachineReadable()) {
|
|
46
47
|
output.data(response);
|
|
47
48
|
}
|
|
48
49
|
else {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// Copyright 2026 Guild.ai
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
3
|
+
import { Command, Option } from 'commander';
|
|
4
4
|
import { render } from 'ink';
|
|
5
5
|
import React from 'react';
|
|
6
6
|
import { readFileSync } from 'fs';
|
|
@@ -32,13 +32,15 @@ export function createAgentTestCommand() {
|
|
|
32
32
|
cmd
|
|
33
33
|
.description('Test agent in interactive REPL session')
|
|
34
34
|
.option('--workspace <identifier>', 'Workspace ID or full name (e.g., owner/workspace-name)')
|
|
35
|
-
.option('--mode <format>', 'Input mode: json (one-shot) or jsonl (line-by-line)')
|
|
36
35
|
.option('--agent-version <id>', 'Test a specific version (UUID or version number)')
|
|
37
36
|
.option('--resume <session-id>', 'Resume an existing test session')
|
|
38
37
|
.option('--open', 'Open session in web dashboard')
|
|
39
38
|
.option('--events <types>', 'Event types to stream (default: user). Shorthands: none, user, system, all, or comma-separated type names')
|
|
40
39
|
.option('--bundle <file>', 'Path to a pre-built gzip+base64 bundle file')
|
|
41
40
|
.option('--no-cache', 'Skip ephemeral build cache (force a fresh build)')
|
|
41
|
+
// Accept --mode so `guild agent test --mode json` works when re-parsed.
|
|
42
|
+
// The actual value is read from process.argv by getOutputMode().
|
|
43
|
+
.addOption(new Option('--mode <format>').hideHelp())
|
|
42
44
|
.action(async (options) => {
|
|
43
45
|
const cwd = process.cwd();
|
|
44
46
|
// Parse --events filter once, before any branching
|
|
@@ -85,9 +87,10 @@ export function createAgentTestCommand() {
|
|
|
85
87
|
}
|
|
86
88
|
// If using JSON/JSONL input, read and validate it early (before auth/session creation)
|
|
87
89
|
// This provides better UX - fail fast on bad input without needing auth
|
|
90
|
+
const outputMode = getOutputMode();
|
|
88
91
|
let inputData;
|
|
89
92
|
let jsonlInputs;
|
|
90
|
-
if (
|
|
93
|
+
if (outputMode === 'json') {
|
|
91
94
|
try {
|
|
92
95
|
inputData = await readStdinAsJSON();
|
|
93
96
|
}
|
|
@@ -101,7 +104,7 @@ export function createAgentTestCommand() {
|
|
|
101
104
|
process.exit(1);
|
|
102
105
|
}
|
|
103
106
|
}
|
|
104
|
-
else if (
|
|
107
|
+
else if (outputMode === 'jsonl') {
|
|
105
108
|
try {
|
|
106
109
|
const stdinContent = await readStdinAsText();
|
|
107
110
|
jsonlInputs = [];
|
|
@@ -321,7 +324,7 @@ export function createAgentTestCommand() {
|
|
|
321
324
|
await open(session.session_url);
|
|
322
325
|
}
|
|
323
326
|
// Branch: JSON input mode vs interactive REPL
|
|
324
|
-
if (
|
|
327
|
+
if (outputMode === 'json' && inputData) {
|
|
325
328
|
// JSON input mode: one-shot test
|
|
326
329
|
try {
|
|
327
330
|
// Send JSON as event content (inputData already read earlier)
|
|
@@ -384,7 +387,7 @@ export function createAgentTestCommand() {
|
|
|
384
387
|
process.exit(1);
|
|
385
388
|
}
|
|
386
389
|
}
|
|
387
|
-
else if (
|
|
390
|
+
else if (outputMode === 'jsonl' && jsonlInputs) {
|
|
388
391
|
// JSONL input mode: line-by-line processing (inputs already parsed and validated)
|
|
389
392
|
let processedCount = 0;
|
|
390
393
|
let lastEventId;
|
|
@@ -6,6 +6,7 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
6
6
|
import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
7
7
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
8
8
|
import { createOutputWriter } from '../../lib/output.js';
|
|
9
|
+
import { isInteractive } from '../../lib/stdin.js';
|
|
9
10
|
async function confirmVisibilityChange(agentName, makePublic) {
|
|
10
11
|
const rl = readline.createInterface({
|
|
11
12
|
input: process.stdin,
|
|
@@ -13,7 +14,7 @@ async function confirmVisibilityChange(agentName, makePublic) {
|
|
|
13
14
|
});
|
|
14
15
|
const action = makePublic ? 'PUBLIC' : 'PRIVATE';
|
|
15
16
|
const warning = makePublic
|
|
16
|
-
? 'This will make the agent visible to everyone.'
|
|
17
|
+
? 'This will make the agent visible to everyone.\nWarning: Once public, an agent cannot be made private again.'
|
|
17
18
|
: 'This will hide the agent from public discovery.';
|
|
18
19
|
return new Promise((resolve) => {
|
|
19
20
|
rl.question(`\nAre you sure you want to make "${agentName}" ${action}?\n${warning}\n\nContinue? [y/N] `, (answer) => {
|
|
@@ -59,6 +60,13 @@ export function createAgentUpdateCommand() {
|
|
|
59
60
|
}
|
|
60
61
|
// Confirm unless --yes is specified
|
|
61
62
|
if (!options.yes) {
|
|
63
|
+
if (!isInteractive()) {
|
|
64
|
+
output.error('Confirmation required for visibility changes.', 'Use --yes to skip confirmation in non-interactive mode:\n guild agent update ' +
|
|
65
|
+
(identifierArg ?? '') +
|
|
66
|
+
(makePublic ? ' --public' : ' --private') +
|
|
67
|
+
' --yes');
|
|
68
|
+
process.exit(1);
|
|
69
|
+
}
|
|
62
70
|
const confirmed = await confirmVisibilityChange(agent.full_name, makePublic);
|
|
63
71
|
if (!confirmed) {
|
|
64
72
|
output.progress('Cancelled.');
|
|
@@ -5,15 +5,16 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getGuildcoreUrl } from '../../lib/config.js';
|
|
6
6
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
7
7
|
import { getAgentId, resolveAgentRef } from '../../lib/agent-helpers.js';
|
|
8
|
-
import {
|
|
8
|
+
import { isMachineReadable } from '../../lib/output-mode.js';
|
|
9
9
|
import { createOutputWriter, formatVersionTable } from '../../lib/output.js';
|
|
10
|
+
import { DEFAULT_PAGE_LIMIT } from '../../lib/api-types.js';
|
|
10
11
|
export function createAgentVersionsCommand() {
|
|
11
12
|
const cmd = new Command('versions');
|
|
12
13
|
cmd
|
|
13
14
|
.description('List all versions of an agent')
|
|
14
15
|
.argument('[identifier]', 'Agent ID or full name (e.g., owner~agent-name)')
|
|
15
|
-
.option('--limit <number>',
|
|
16
|
-
.option('--offset <number>', 'Number of versions to skip', '0')
|
|
16
|
+
.option('--limit <number>', `Maximum number of versions to return (default: ${DEFAULT_PAGE_LIMIT})`, String(DEFAULT_PAGE_LIMIT))
|
|
17
|
+
.option('--offset <number>', 'Number of versions to skip (default: 0)', '0')
|
|
17
18
|
.action(async (agentIdArg, options) => {
|
|
18
19
|
const output = createOutputWriter();
|
|
19
20
|
// Get agent ID from argument or guild.json
|
|
@@ -25,7 +26,7 @@ export function createAgentVersionsCommand() {
|
|
|
25
26
|
try {
|
|
26
27
|
const resolvedId = await resolveAgentRef(client, agentId);
|
|
27
28
|
const result = await client.get(`/agents/${resolvedId}/versions?limit=${limit}&offset=${offset}`);
|
|
28
|
-
if (
|
|
29
|
+
if (isMachineReadable()) {
|
|
29
30
|
output.data(result);
|
|
30
31
|
}
|
|
31
32
|
else {
|