@guildai/cli 0.3.17 → 0.4.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 +2 -1
- package/dist/commands/agent/clone.js +2 -28
- package/dist/commands/agent/init.js +35 -15
- package/dist/commands/agent/list.js +8 -2
- package/dist/commands/agent/save.js +7 -2
- package/dist/commands/agent/search.js +8 -2
- package/dist/commands/agent/test.js +2 -1
- package/dist/commands/agent/versions.js +8 -2
- package/dist/commands/agent/workspaces.d.ts +3 -0
- package/dist/commands/agent/workspaces.js +51 -0
- package/dist/commands/chat.js +2 -0
- package/dist/commands/workspace/agent/list.js +7 -6
- package/dist/commands/workspace/context/list.js +8 -2
- package/dist/commands/workspace/context/publish.js +1 -1
- package/dist/index.js +5 -0
- package/dist/lib/agent-helpers.js +2 -2
- package/dist/lib/did-you-mean.d.ts +25 -0
- package/dist/lib/did-you-mean.js +143 -0
- package/dist/lib/generated-types.d.ts +1 -1
- package/dist/lib/generated-types.js +2 -0
- package/dist/lib/npmrc.js +9 -1
- package/dist/lib/output.d.ts +18 -4
- package/dist/lib/output.js +108 -15
- package/dist/lib/stdin.d.ts +6 -0
- package/dist/lib/stdin.js +18 -0
- package/docs/CLI_WORKFLOW.md +28 -28
- package/docs/getting-started.md +1 -1
- package/docs/output-format.md +1 -1
- package/docs/skills/agent-dev.md +76 -37
- package/package.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const WEBHOOK_SERVICES: readonly ["AZURE_DEVOPS", "BITBUCKET", "CYPRESS", "GITHUB", "GOOGLE_DOCS", "JIRA", "LINEAR", "NEWRELIC", "NOTION", "SLACK", "TESTRAIL", "ZENDESK"];
|
|
1
|
+
export declare const WEBHOOK_SERVICES: readonly ["AZURE_DEVOPS", "BITBUCKET", "CYPRESS", "GITHUB", "GOOGLE_DOCS", "GOOGLE_COMPUTE", "GOOGLE_LOGGING", "JIRA", "LINEAR", "NEWRELIC", "NOTION", "SLACK", "TESTRAIL", "ZENDESK"];
|
|
2
2
|
export type WebhookService = (typeof WEBHOOK_SERVICES)[number];
|
|
3
3
|
export declare const TIME_TRIGGER_FREQUENCIES: readonly ["HOURLY", "DAILY", "WEEKLY", "MONTHLY"];
|
|
4
4
|
export type TimeTriggerFrequency = (typeof TIME_TRIGGER_FREQUENCIES)[number];
|
package/dist/lib/npmrc.js
CHANGED
|
@@ -17,6 +17,7 @@ export async function configureNpmrc() {
|
|
|
17
17
|
}
|
|
18
18
|
try {
|
|
19
19
|
await execa('npm', [
|
|
20
|
+
'--workspaces=false',
|
|
20
21
|
'config',
|
|
21
22
|
'set',
|
|
22
23
|
'--location',
|
|
@@ -36,7 +37,14 @@ export async function cleanupNpmrc() {
|
|
|
36
37
|
const keys = [...SCOPES.map((s) => `${s}:registry`), `${scope}:_authToken`];
|
|
37
38
|
for (const key of keys) {
|
|
38
39
|
try {
|
|
39
|
-
await execa('npm', [
|
|
40
|
+
await execa('npm', [
|
|
41
|
+
'--workspaces=false',
|
|
42
|
+
'config',
|
|
43
|
+
'delete',
|
|
44
|
+
'--location',
|
|
45
|
+
'user',
|
|
46
|
+
key,
|
|
47
|
+
]);
|
|
40
48
|
}
|
|
41
49
|
catch {
|
|
42
50
|
// Key may not exist, that's fine
|
package/dist/lib/output.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type Spinner } from './progress.js';
|
|
2
|
-
import type { Agent, Pagination, Workspace, Trigger } from './api-types.js';
|
|
2
|
+
import type { Agent, AgentVersion, Context, Pagination, Workspace, WorkspaceAgent, Trigger } from './api-types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Session type from API responses
|
|
5
5
|
*/
|
|
@@ -19,6 +19,21 @@ interface Session {
|
|
|
19
19
|
* Shared by agent list and agent search commands.
|
|
20
20
|
*/
|
|
21
21
|
export declare function formatAgentTable(agents: Agent[], pagination: Pagination): void;
|
|
22
|
+
/**
|
|
23
|
+
* Format an agent version list as a human-readable table.
|
|
24
|
+
* Used by agent versions command.
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatVersionTable(versions: AgentVersion[], pagination: Pagination): void;
|
|
27
|
+
/**
|
|
28
|
+
* Format a context list as a human-readable table.
|
|
29
|
+
* Used by workspace context list command.
|
|
30
|
+
*/
|
|
31
|
+
export declare function formatContextTable(contexts: Context[], pagination: Pagination): void;
|
|
32
|
+
/**
|
|
33
|
+
* Format a workspace agent list as a human-readable table.
|
|
34
|
+
* Used by workspace agent list command.
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatWorkspaceAgentTable(agents: WorkspaceAgent[]): void;
|
|
22
37
|
/**
|
|
23
38
|
* Format a workspace list as a human-readable table.
|
|
24
39
|
* Used by workspace list command.
|
|
@@ -38,7 +53,7 @@ export declare function formatTriggerTable(triggers: Trigger[], pagination: Pagi
|
|
|
38
53
|
* Output writer interface for consistent CLI output
|
|
39
54
|
*
|
|
40
55
|
* Implementations:
|
|
41
|
-
* -
|
|
56
|
+
* - InteractiveOutputWriter: Colors, tables, spinners for interactive use
|
|
42
57
|
* - JSONOutputWriter: Pure JSON for scripting and automation
|
|
43
58
|
*/
|
|
44
59
|
export interface OutputWriter {
|
|
@@ -69,9 +84,8 @@ export interface OutputWriter {
|
|
|
69
84
|
* Uses colors, symbols, and formatting for readability.
|
|
70
85
|
* Progress goes to stderr.
|
|
71
86
|
*/
|
|
72
|
-
export declare class
|
|
87
|
+
export declare class InteractiveOutputWriter implements OutputWriter {
|
|
73
88
|
data(value: unknown): void;
|
|
74
|
-
private isAgentListResponse;
|
|
75
89
|
success(message: string, details?: Record<string, unknown>): void;
|
|
76
90
|
error(message: string, details?: string): void;
|
|
77
91
|
progress(message: string): void;
|
package/dist/lib/output.js
CHANGED
|
@@ -76,6 +76,112 @@ export function formatAgentTable(agents, pagination) {
|
|
|
76
76
|
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} agents`));
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
|
+
/**
|
|
80
|
+
* Format an agent version list as a human-readable table.
|
|
81
|
+
* Used by agent versions command.
|
|
82
|
+
*/
|
|
83
|
+
export function formatVersionTable(versions, pagination) {
|
|
84
|
+
if (versions.length === 0) {
|
|
85
|
+
console.log(chalk.dim('No versions found'));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const table = new Table({
|
|
89
|
+
columns: [
|
|
90
|
+
{ name: 'sha', title: 'SHA', alignment: 'left' },
|
|
91
|
+
{ name: 'version', title: 'VERSION', alignment: 'left', color: 'cyan' },
|
|
92
|
+
{ name: 'status', title: 'STATUS', alignment: 'left' },
|
|
93
|
+
{ name: 'validation', title: 'VALIDATION', alignment: 'left' },
|
|
94
|
+
{ name: 'summary', title: 'SUMMARY', alignment: 'left' },
|
|
95
|
+
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
96
|
+
],
|
|
97
|
+
});
|
|
98
|
+
versions.forEach((v) => {
|
|
99
|
+
const validationColor = v.validation_status === 'PASSED'
|
|
100
|
+
? chalk.green
|
|
101
|
+
: v.validation_status === 'FAILED'
|
|
102
|
+
? chalk.red
|
|
103
|
+
: chalk.dim;
|
|
104
|
+
table.addRow({
|
|
105
|
+
sha: v.sha.slice(0, 7),
|
|
106
|
+
version: v.version_number || '-',
|
|
107
|
+
status: v.status,
|
|
108
|
+
validation: validationColor(v.validation_status || '-'),
|
|
109
|
+
summary: truncate(v.summary || '', 30),
|
|
110
|
+
created: v.created_at ? formatRelativeTime(v.created_at) : '',
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
table.printTable();
|
|
114
|
+
const showing = Math.min(pagination.limit, versions.length);
|
|
115
|
+
if (pagination.has_more) {
|
|
116
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
117
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} versions. ` +
|
|
118
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
119
|
+
}
|
|
120
|
+
else if (pagination.total_count > showing) {
|
|
121
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} versions`));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Format a context list as a human-readable table.
|
|
126
|
+
* Used by workspace context list command.
|
|
127
|
+
*/
|
|
128
|
+
export function formatContextTable(contexts, pagination) {
|
|
129
|
+
if (contexts.length === 0) {
|
|
130
|
+
console.log(chalk.dim('No contexts found'));
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
const table = new Table({
|
|
134
|
+
columns: [
|
|
135
|
+
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
136
|
+
{ name: 'status', title: 'STATUS', alignment: 'left', color: 'cyan' },
|
|
137
|
+
{ name: 'type', title: 'TYPE', alignment: 'left' },
|
|
138
|
+
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
139
|
+
],
|
|
140
|
+
});
|
|
141
|
+
contexts.forEach((ctx) => {
|
|
142
|
+
table.addRow({
|
|
143
|
+
id: truncate(ctx.id, 12),
|
|
144
|
+
status: ctx.status,
|
|
145
|
+
type: ctx.type || '-',
|
|
146
|
+
created: ctx.created_at ? formatRelativeTime(ctx.created_at) : '',
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
table.printTable();
|
|
150
|
+
const showing = Math.min(pagination.limit, contexts.length);
|
|
151
|
+
if (pagination.has_more) {
|
|
152
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
153
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} contexts. ` +
|
|
154
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
155
|
+
}
|
|
156
|
+
else if (pagination.total_count > showing) {
|
|
157
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} contexts`));
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Format a workspace agent list as a human-readable table.
|
|
162
|
+
* Used by workspace agent list command.
|
|
163
|
+
*/
|
|
164
|
+
export function formatWorkspaceAgentTable(agents) {
|
|
165
|
+
if (agents.length === 0) {
|
|
166
|
+
console.log(chalk.dim('No agents installed in this workspace'));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
const table = new Table({
|
|
170
|
+
columns: [
|
|
171
|
+
{ name: 'name', title: 'NAME', alignment: 'left' },
|
|
172
|
+
{ name: 'version', title: 'VERSION', alignment: 'left', color: 'cyan' },
|
|
173
|
+
{ name: 'auto_update', title: 'AUTO-UPDATE', alignment: 'left' },
|
|
174
|
+
],
|
|
175
|
+
});
|
|
176
|
+
agents.forEach((wa) => {
|
|
177
|
+
table.addRow({
|
|
178
|
+
name: wa.agent.full_name || wa.agent.name,
|
|
179
|
+
version: wa.agent_version.version_number || wa.agent_version.sha.slice(0, 7),
|
|
180
|
+
auto_update: wa.should_autoupdate ? chalk.green('yes') : chalk.dim('no'),
|
|
181
|
+
});
|
|
182
|
+
});
|
|
183
|
+
table.printTable();
|
|
184
|
+
}
|
|
79
185
|
/**
|
|
80
186
|
* Format a workspace list as a human-readable table.
|
|
81
187
|
* Used by workspace list command.
|
|
@@ -199,23 +305,10 @@ export function formatTriggerTable(triggers, pagination) {
|
|
|
199
305
|
* Uses colors, symbols, and formatting for readability.
|
|
200
306
|
* Progress goes to stderr.
|
|
201
307
|
*/
|
|
202
|
-
export class
|
|
308
|
+
export class InteractiveOutputWriter {
|
|
203
309
|
data(value) {
|
|
204
|
-
// Special handling for agent list responses
|
|
205
|
-
if (this.isAgentListResponse(value)) {
|
|
206
|
-
formatAgentTable(value.items, value.pagination);
|
|
207
|
-
return;
|
|
208
|
-
}
|
|
209
|
-
// Fallback to pretty JSON for other data
|
|
210
310
|
console.log(JSON.stringify(value, null, 2));
|
|
211
311
|
}
|
|
212
|
-
isAgentListResponse(value) {
|
|
213
|
-
return (typeof value === 'object' &&
|
|
214
|
-
value !== null &&
|
|
215
|
-
'items' in value &&
|
|
216
|
-
'pagination' in value &&
|
|
217
|
-
Array.isArray(value.items));
|
|
218
|
-
}
|
|
219
312
|
success(message, details) {
|
|
220
313
|
process.stderr.write(chalk.green('✓') + ' ' + message + '\n');
|
|
221
314
|
if (details) {
|
|
@@ -273,7 +366,7 @@ export class JSONOutputWriter {
|
|
|
273
366
|
*/
|
|
274
367
|
export function createOutputWriter() {
|
|
275
368
|
const mode = getOutputMode();
|
|
276
|
-
return mode === 'json' ? new JSONOutputWriter() : new
|
|
369
|
+
return mode === 'json' ? new JSONOutputWriter() : new InteractiveOutputWriter();
|
|
277
370
|
}
|
|
278
371
|
/**
|
|
279
372
|
* Create a no-op spinner (for quiet/JSON modes)
|
package/dist/lib/stdin.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Exit with a helpful error when stdin is piped but no --mode flag was given.
|
|
3
|
+
* Call this before rendering an interactive UI (Ink render()) so users who
|
|
4
|
+
* accidentally pipe input without --mode get clear guidance instead of a hang.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureInteractiveStdin(command: string): void;
|
|
1
7
|
/**
|
|
2
8
|
* Read JSON from stdin with a timeout.
|
|
3
9
|
*/
|
package/dist/lib/stdin.js
CHANGED
|
@@ -1,4 +1,22 @@
|
|
|
1
1
|
// Copyright (c) 2026 Guild.ai All Rights Reserved
|
|
2
|
+
/**
|
|
3
|
+
* Exit with a helpful error when stdin is piped but no --mode flag was given.
|
|
4
|
+
* Call this before rendering an interactive UI (Ink render()) so users who
|
|
5
|
+
* accidentally pipe input without --mode get clear guidance instead of a hang.
|
|
6
|
+
*/
|
|
7
|
+
export function ensureInteractiveStdin(command) {
|
|
8
|
+
if (!process.stdin.isTTY) {
|
|
9
|
+
console.error('Error: stdin is piped but --mode was not specified');
|
|
10
|
+
console.error('');
|
|
11
|
+
console.error('When piping input, use --mode to set the input format:');
|
|
12
|
+
console.error(` echo '{"prompt":"hello"}' | ${command} --mode json`);
|
|
13
|
+
console.error(` cat inputs.jsonl | ${command} --mode jsonl`);
|
|
14
|
+
console.error('');
|
|
15
|
+
console.error('Or run interactively (no pipe):');
|
|
16
|
+
console.error(` ${command}`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
2
20
|
/**
|
|
3
21
|
* Read JSON from stdin with a timeout.
|
|
4
22
|
*/
|
package/docs/CLI_WORKFLOW.md
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Guild CLI Workflow
|
|
3
|
+
description: Agent development using the Guild CLI. Activated when user mentions guild agent commands, saving/publishing agents, clone/pull workflow, or agent testing. Covers CLI commands and common workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Guild CLI Agent Development Workflow
|
|
2
7
|
|
|
3
8
|
For local agent development using the Guild CLI. This workflow manages agent code via the Guild git server.
|
|
@@ -8,10 +13,11 @@ For local agent development using the Guild CLI. This workflow manages agent cod
|
|
|
8
13
|
|
|
9
14
|
```bash
|
|
10
15
|
# Create a new agent
|
|
11
|
-
guild agent
|
|
16
|
+
guild agent create my-agent --template LLM
|
|
12
17
|
|
|
13
18
|
# Clone an existing agent
|
|
14
|
-
guild agent clone guildai/
|
|
19
|
+
guild agent clone guildai/dev-assistant
|
|
20
|
+
cd dev-assistant
|
|
15
21
|
|
|
16
22
|
# Save changes (commits and syncs to Guild server)
|
|
17
23
|
guild agent save --message "Description of changes"
|
|
@@ -35,7 +41,6 @@ guild agent save --message "Description" --wait --publish
|
|
|
35
41
|
- ❌ Run `git pull` directly (use `guild agent pull`)
|
|
36
42
|
- ❌ Run `git commit` directly (use `guild agent save`)
|
|
37
43
|
- ❌ Edit `guild.json` (it's generated and gitignored)
|
|
38
|
-
- ❌ Push to GitHub (agents sync to Guild's git server)
|
|
39
44
|
|
|
40
45
|
## Common Commands
|
|
41
46
|
|
|
@@ -45,31 +50,32 @@ guild agent save --message "Description" --wait --publish
|
|
|
45
50
|
# Install Guild CLI skills for coding assistants (Claude Code, etc.)
|
|
46
51
|
guild setup
|
|
47
52
|
|
|
48
|
-
#
|
|
53
|
+
# Also create a CLAUDE.md template
|
|
49
54
|
guild setup --claude-md
|
|
50
55
|
```
|
|
51
56
|
|
|
52
57
|
### Creating Agents
|
|
53
58
|
|
|
54
59
|
```bash
|
|
55
|
-
#
|
|
56
|
-
guild agent
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
guild agent
|
|
60
|
-
guild agent init --name my-agent --template COMPILED
|
|
61
|
-
guild agent init --name my-agent --template BLANK
|
|
60
|
+
# Create with template (interactive — prompts for template if omitted)
|
|
61
|
+
guild agent create my-agent
|
|
62
|
+
guild agent create my-agent --template LLM
|
|
63
|
+
guild agent create my-agent --template AUTO_MANAGED_STATE
|
|
64
|
+
guild agent create my-agent --template BLANK
|
|
62
65
|
|
|
63
66
|
# Fork an existing agent
|
|
64
|
-
guild agent init --fork
|
|
67
|
+
guild agent init --fork owner/agent-name
|
|
68
|
+
|
|
69
|
+
# Clone to work on an existing agent
|
|
70
|
+
guild agent clone owner/agent-name
|
|
65
71
|
```
|
|
66
72
|
|
|
67
73
|
### Working with Existing Agents
|
|
68
74
|
|
|
69
75
|
```bash
|
|
70
76
|
# Clone to work on an agent
|
|
71
|
-
guild agent clone guildai/
|
|
72
|
-
cd
|
|
77
|
+
guild agent clone guildai/dev-assistant
|
|
78
|
+
cd dev-assistant
|
|
73
79
|
|
|
74
80
|
# Pull remote changes (from collaborators or web edits)
|
|
75
81
|
guild agent pull
|
|
@@ -114,19 +120,22 @@ guild agent versions --limit 1
|
|
|
114
120
|
# Interactive test session
|
|
115
121
|
guild agent test
|
|
116
122
|
|
|
123
|
+
# Test uncommitted changes without saving
|
|
124
|
+
guild agent test --ephemeral
|
|
125
|
+
|
|
117
126
|
# Test with specific input
|
|
118
127
|
guild agent chat "Hello, can you help me?"
|
|
119
128
|
```
|
|
120
129
|
|
|
121
130
|
## File Structure
|
|
122
131
|
|
|
123
|
-
After `guild agent
|
|
132
|
+
After `guild agent create`, you get:
|
|
124
133
|
|
|
125
134
|
```
|
|
126
135
|
my-agent/
|
|
127
136
|
├── .git/ # Git repo (remote is Guild server)
|
|
128
137
|
├── .gitignore # Includes guild.json
|
|
129
|
-
├── agent.ts # Your agent code
|
|
138
|
+
├── agent.ts # Your agent code (default; can also be in src/)
|
|
130
139
|
├── package.json # Dependencies
|
|
131
140
|
├── tsconfig.json # TypeScript config
|
|
132
141
|
└── guild.json # Agent ID (gitignored, local only)
|
|
@@ -143,28 +152,19 @@ my-agent/
|
|
|
143
152
|
|
|
144
153
|
### "No changes to commit"
|
|
145
154
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
git push origin main
|
|
150
|
-
```
|
|
155
|
+
All changes are already committed. Make a code change first, then run `guild agent save` again.
|
|
151
156
|
|
|
152
157
|
### "guild.json not found"
|
|
153
158
|
|
|
154
159
|
You're not in an agent directory. Either:
|
|
155
160
|
|
|
156
161
|
- `cd` into the agent directory
|
|
157
|
-
- Run `guild agent
|
|
162
|
+
- Run `guild agent create` to create one
|
|
158
163
|
|
|
159
164
|
### Validation Failed
|
|
160
165
|
|
|
161
|
-
Check the error
|
|
166
|
+
Check the error with `guild agent versions --limit 1`. Common issues:
|
|
162
167
|
|
|
163
168
|
- TypeScript compilation errors
|
|
164
169
|
- Missing dependencies
|
|
165
170
|
- Invalid schema
|
|
166
|
-
|
|
167
|
-
## See Also
|
|
168
|
-
|
|
169
|
-
- [Agent Development Guide](https://github.com/agents-for-dev/guildai__agent-builder__019a8e0d-5280-726e-0000-b896bbbc2320/blob/main/docs/AGENT_DEVELOPMENT.md) - Comprehensive patterns and SDK usage
|
|
170
|
-
- SDK: `@guildai/agents-sdk`
|
package/docs/getting-started.md
CHANGED
|
@@ -316,7 +316,7 @@ guild agent code # View source of latest version
|
|
|
316
316
|
|
|
317
317
|
## Key Rules
|
|
318
318
|
|
|
319
|
-
- Agent code lives
|
|
319
|
+
- Agent code lives in `agent.ts` (typically at the project root, but can be in a subdirectory like `src/`).
|
|
320
320
|
- Don't add `@guildai/agents-sdk`, `zod`, or `@guildai-services/*` to `package.json`. The runtime provides them. Only add third-party packages you actually use.
|
|
321
321
|
- Always call tools through `task.tools.<name>(args)`. Never access services directly.
|
|
322
322
|
- Always use `guild agent save` to commit and `guild agent pull` to sync. Don't use raw git commands.
|
package/docs/output-format.md
CHANGED
|
@@ -46,7 +46,7 @@ interface OutputWriter {
|
|
|
46
46
|
|
|
47
47
|
Two implementations:
|
|
48
48
|
|
|
49
|
-
- `
|
|
49
|
+
- `InteractiveOutputWriter` - Colors, symbols, formatted output
|
|
50
50
|
- `JSONOutputWriter` - Pure JSON
|
|
51
51
|
|
|
52
52
|
Commands use `createOutputWriter()` to get the right implementation based on flags.
|
package/docs/skills/agent-dev.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: Guild Agent Development
|
|
3
|
-
description:
|
|
3
|
+
description: Local agent development using the Guild CLI. Activated when user mentions creating agents, guild agent commands, saving/publishing agents, or agent development workflow. Handles proper CLI workflow and prevents direct git operations.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Guild Agent Development
|
|
7
7
|
|
|
8
|
-
Build agents for Guild using the CLI. **Always use the Guild CLI for agent operations
|
|
8
|
+
Build agents for Guild using the CLI. **Always use the Guild CLI for agent operations - never use raw git commands.**
|
|
9
9
|
|
|
10
10
|
## When to Use This
|
|
11
11
|
|
|
@@ -33,7 +33,7 @@ guild setup --claude-md
|
|
|
33
33
|
### Creating Agents
|
|
34
34
|
|
|
35
35
|
```bash
|
|
36
|
-
# Create from template (interactive
|
|
36
|
+
# Create from template (interactive - prompts for template)
|
|
37
37
|
guild agent create my-agent
|
|
38
38
|
|
|
39
39
|
# Create with specific template
|
|
@@ -80,18 +80,38 @@ guild agent test --ephemeral
|
|
|
80
80
|
guild agent chat "Hello, can you help me?"
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
##
|
|
83
|
+
## Guild CLI Is the ONLY Tool for Agent Operations
|
|
84
84
|
|
|
85
|
-
**
|
|
85
|
+
**ALL agent work — creating, saving, testing, debugging, investigating — goes through Guild CLI.**
|
|
86
|
+
|
|
87
|
+
### For Creating and Modifying
|
|
86
88
|
|
|
87
89
|
- ✅ `guild agent create`, `guild agent init`, `guild agent clone`
|
|
88
90
|
- ✅ `guild agent save --message "description"`
|
|
89
91
|
- ✅ `guild agent pull` (sync remote changes into local directory)
|
|
90
92
|
- ✅ `guild agent test`, `guild agent chat`
|
|
91
|
-
-
|
|
92
|
-
- ❌ NEVER use `git commit`, `git push`, `git pull` for agent operations
|
|
93
|
+
- ❌ NEVER use `git commit`, `git push`, `gh repo` for agent operations
|
|
93
94
|
- ❌ NEVER manually create `package.json`, `tsconfig.json`, or `guild.json`
|
|
94
95
|
|
|
96
|
+
### For Investigating and Debugging
|
|
97
|
+
|
|
98
|
+
- ✅ `guild agent clone <id>` to get agent source locally
|
|
99
|
+
- ✅ `guild agent versions <id>` to check version history
|
|
100
|
+
- ✅ `guild agent code <id>` to view source
|
|
101
|
+
- ✅ `guild agent get <id>` to view agent info
|
|
102
|
+
- ✅ `guild agent grep <pattern>` to search across all agent code
|
|
103
|
+
- ✅ Read local clones created by `guild agent clone`
|
|
104
|
+
- ❌ NEVER use `git clone`, `gh repo`, or direct API calls for agent source — always use Guild CLI
|
|
105
|
+
|
|
106
|
+
### If Guild CLI Can't Do Something
|
|
107
|
+
|
|
108
|
+
**STOP and tell the user:**
|
|
109
|
+
|
|
110
|
+
1. What you need to do
|
|
111
|
+
2. Why Guild CLI can't do it
|
|
112
|
+
3. Why you think `gh`/`git` is needed
|
|
113
|
+
4. Let the user decide — never reach for `gh`/`git` on your own
|
|
114
|
+
|
|
95
115
|
---
|
|
96
116
|
|
|
97
117
|
## SDK Reference
|
|
@@ -118,12 +138,14 @@ import { ask, output, callTools } from '@guildai/agents-sdk';
|
|
|
118
138
|
// Platform tools (from SDK)
|
|
119
139
|
import { guildTools, userInterfaceTools } from '@guildai/agents-sdk';
|
|
120
140
|
|
|
121
|
-
// Service tools (from separate packages
|
|
141
|
+
// Service tools (from separate packages - NOT from SDK)
|
|
122
142
|
import { gitHubTools } from '@guildai-services/guildai~github';
|
|
123
143
|
import { slackTools } from '@guildai-services/guildai~slack';
|
|
124
144
|
import { jiraTools } from '@guildai-services/guildai~jira';
|
|
125
145
|
import { bitbucketTools } from '@guildai-services/guildai~bitbucket';
|
|
126
146
|
import { azureDevOpsTools } from '@guildai-services/guildai~azure-devops';
|
|
147
|
+
import { pipedreamTools } from '@guildai-services/guildai~pipedream';
|
|
148
|
+
import { cypressTools } from '@guildai-services/guildai~cypress';
|
|
127
149
|
|
|
128
150
|
// Utilities
|
|
129
151
|
import { pick, progressLogNotifyEvent } from '@guildai/agents-sdk';
|
|
@@ -141,12 +163,16 @@ Service tools are in separate `@guildai-services/*` packages. The runtime resolv
|
|
|
141
163
|
|
|
142
164
|
| Service | Package | Export | Tool Name Prefix |
|
|
143
165
|
| -------------- | ---------------------------------------- | -------------------- | ---------------- |
|
|
144
|
-
| GitHub | `@guildai-services/guildai~github` | `gitHubTools` | `github_` |
|
|
145
|
-
| Slack | `@guildai-services/guildai~slack` | `slackTools` | `slack_` |
|
|
146
|
-
| Jira | `@guildai-services/guildai~jira` | `jiraTools` | `jira_` |
|
|
147
|
-
| Bitbucket | `@guildai-services/guildai~bitbucket` | `bitbucketTools` | `bitbucket_` |
|
|
148
166
|
| Azure DevOps | `@guildai-services/guildai~azure-devops` | `azureDevOpsTools` | `azure_devops_` |
|
|
167
|
+
| Bitbucket | `@guildai-services/guildai~bitbucket` | `bitbucketTools` | `bitbucket_` |
|
|
168
|
+
| Cypress | `@guildai-services/guildai~cypress` | `cypressTools` | `cypress_` |
|
|
169
|
+
| GitHub | `@guildai-services/guildai~github` | `gitHubTools` | `github_` |
|
|
149
170
|
| Guild | `@guildai/agents-sdk` | `guildTools` | `guild_` |
|
|
171
|
+
| Jira | `@guildai-services/guildai~jira` | `jiraTools` | `jira_` |
|
|
172
|
+
| Linear | `@guildai-services/guildai~linear` | `linearTools` | `linear_` |
|
|
173
|
+
| NewRelic | `@guildai-services/guildai~newrelic` | `newrelicTools` | `newrelic_` |
|
|
174
|
+
| Pipedream | `@guildai-services/guildai~pipedream` | `pipedreamTools` | `pipedream_` |
|
|
175
|
+
| Slack | `@guildai-services/guildai~slack` | `slackTools` | `slack_` |
|
|
150
176
|
| User Interface | `@guildai/agents-sdk` | `userInterfaceTools` | `ui_` |
|
|
151
177
|
|
|
152
178
|
### Tool Access via `task.tools.*`
|
|
@@ -169,7 +195,10 @@ const issues = await task.tools.jira_search_and_reconsile_issues_using_jql({
|
|
|
169
195
|
});
|
|
170
196
|
|
|
171
197
|
// User interface
|
|
172
|
-
const response = await task.tools.ui_prompt({
|
|
198
|
+
const response = await task.tools.ui_prompt({
|
|
199
|
+
type: 'text',
|
|
200
|
+
text: 'What repo?',
|
|
201
|
+
});
|
|
173
202
|
await task.tools.ui_notify(progressLogNotifyEvent('Processing...'));
|
|
174
203
|
|
|
175
204
|
// Guild
|
|
@@ -489,10 +518,23 @@ async function onToolResults(
|
|
|
489
518
|
|
|
490
519
|
### Slack-Specific Patterns
|
|
491
520
|
|
|
492
|
-
When posting to Slack, convert markdown to Slack's mrkdwn format
|
|
521
|
+
When posting to Slack, convert markdown to Slack's mrkdwn format. Use an inline converter
|
|
522
|
+
(`slackify-markdown` is CJS and breaks in the ESM agent runtime):
|
|
493
523
|
|
|
494
524
|
```typescript
|
|
495
|
-
|
|
525
|
+
// Simple markdown-to-Slack-mrkdwn converter (inline — do NOT use slackify-markdown)
|
|
526
|
+
function slackifyMarkdown(md: string): string {
|
|
527
|
+
return md
|
|
528
|
+
.replace(/\*\*(.+?)\*\*/g, '*$1*') // bold: **text** → *text*
|
|
529
|
+
.replace(/(?<!\*)\*(?!\*)(.+?)(?<!\*)\*(?!\*)/g, '_$1_') // italic: *text* → _text_
|
|
530
|
+
.replace(/~~(.+?)~~/g, '~$1~') // strikethrough
|
|
531
|
+
.replace(/^### (.+)$/gm, '*$1*') // h3 → bold
|
|
532
|
+
.replace(/^## (.+)$/gm, '*$1*') // h2 → bold
|
|
533
|
+
.replace(/^# (.+)$/gm, '*$1*') // h1 → bold
|
|
534
|
+
.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<$2|$1>') // links
|
|
535
|
+
.replace(/^> (.+)$/gm, '> $1') // blockquotes (same syntax)
|
|
536
|
+
.replace(/`([^`]+)`/g, '`$1`'); // inline code (same syntax)
|
|
537
|
+
}
|
|
496
538
|
|
|
497
539
|
// In your agent:
|
|
498
540
|
const responseText = '## Summary\n- Item 1\n- Item 2';
|
|
@@ -504,16 +546,6 @@ await task.tools.slack_chat_post_message({
|
|
|
504
546
|
});
|
|
505
547
|
```
|
|
506
548
|
|
|
507
|
-
Add `slackify-markdown` to `package.json` dependencies:
|
|
508
|
-
|
|
509
|
-
```json
|
|
510
|
-
{
|
|
511
|
-
"dependencies": {
|
|
512
|
-
"slackify-markdown": "^4.5.0"
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
```
|
|
516
|
-
|
|
517
549
|
---
|
|
518
550
|
|
|
519
551
|
## Anti-Hallucination Guide
|
|
@@ -522,7 +554,7 @@ Add `slackify-markdown` to `package.json` dependencies:
|
|
|
522
554
|
|
|
523
555
|
### NEVER `pick()` from `guildTools`
|
|
524
556
|
|
|
525
|
-
**Always spread `guildTools` fully. NEVER use `pick(guildTools, [...])`.**
|
|
557
|
+
**CRITICAL: Always spread `guildTools` fully. NEVER use `pick(guildTools, [...])`.**
|
|
526
558
|
|
|
527
559
|
The SDK's `Task` type conditionally provides `task.guild: GuildService` based on whether the **full** `guildTools` set is in the tools type. Using `pick()` creates a subset type that doesn't satisfy this constraint, causing:
|
|
528
560
|
|
|
@@ -620,19 +652,17 @@ export default agent({ run: async (input, task) => { ... } })
|
|
|
620
652
|
"version": "1.0.0",
|
|
621
653
|
"author": "Guild.ai",
|
|
622
654
|
"type": "module",
|
|
623
|
-
"dependencies": {
|
|
624
|
-
"slackify-markdown": "^4.5.0"
|
|
625
|
-
},
|
|
655
|
+
"dependencies": {},
|
|
626
656
|
"devDependencies": {
|
|
627
657
|
"typescript": "^5.0.0"
|
|
628
658
|
}
|
|
629
659
|
}
|
|
630
660
|
```
|
|
631
661
|
|
|
632
|
-
**
|
|
662
|
+
**CRITICAL:**
|
|
633
663
|
|
|
634
664
|
- Do NOT add `@guildai/agents-sdk`, `@guildai-services/*`, or `zod` to dependencies. The runtime provides them.
|
|
635
|
-
- DO add third-party packages your agent uses (e.g., `slackify-markdown`)
|
|
665
|
+
- DO add third-party ESM-compatible packages your agent uses to `dependencies`. Note: CJS-only packages (e.g., `slackify-markdown`) will break in the ESM agent runtime — use inline alternatives instead.
|
|
636
666
|
- `devDependencies` is for build tools only.
|
|
637
667
|
|
|
638
668
|
## Versioning
|
|
@@ -649,7 +679,7 @@ After `guild agent create` + `guild agent init`:
|
|
|
649
679
|
my-agent/
|
|
650
680
|
├── .git/ # Git repo (remote is Guild server)
|
|
651
681
|
├── .gitignore # Includes guild.json
|
|
652
|
-
├── agent.ts # Your agent code (
|
|
682
|
+
├── agent.ts # Your agent code (default location; can also be in src/)
|
|
653
683
|
├── package.json # Dependencies
|
|
654
684
|
├── tsconfig.json # TypeScript config
|
|
655
685
|
└── guild.json # Agent ID (gitignored, local only)
|
|
@@ -657,10 +687,10 @@ my-agent/
|
|
|
657
687
|
|
|
658
688
|
## Version Lifecycle
|
|
659
689
|
|
|
660
|
-
1. **Draft**
|
|
661
|
-
2. **Validating**
|
|
662
|
-
3. **Published**
|
|
663
|
-
4. **Failed**
|
|
690
|
+
1. **Draft** - After `guild agent save` (no `--publish`)
|
|
691
|
+
2. **Validating** - After `--publish`, running validation
|
|
692
|
+
3. **Published** - Validation passed, available for use
|
|
693
|
+
4. **Failed** - Validation failed, check errors
|
|
664
694
|
|
|
665
695
|
## CLI Commands
|
|
666
696
|
|
|
@@ -671,9 +701,9 @@ guild agent create <name> # Create new agent (prompts f
|
|
|
671
701
|
guild agent create <name> --template LLM # Create with specific template
|
|
672
702
|
guild agent init # Initialize local workspace
|
|
673
703
|
guild agent init --fork <agent-id> # Fork existing agent
|
|
704
|
+
guild agent pull # Pull remote changes
|
|
674
705
|
guild agent save --message "description" # Save changes
|
|
675
706
|
guild agent save --message "v1.0" --wait --publish # Save + validate + publish
|
|
676
|
-
guild agent pull # Pull remote changes
|
|
677
707
|
guild agent test # Interactive test
|
|
678
708
|
guild agent test --ephemeral # Ephemeral test
|
|
679
709
|
guild agent chat "Hello" # Test with input
|
|
@@ -688,6 +718,15 @@ guild agent revalidate # Re-run validation
|
|
|
688
718
|
guild agent code [agent-id] # View agent source
|
|
689
719
|
guild agent grep <pattern> # Search agent code files for a regex pattern
|
|
690
720
|
guild agent grep <pattern> --published # Search only published agents
|
|
721
|
+
guild agent owners # List accounts that can own agents
|
|
722
|
+
guild workspace select # Set default workspace (writes to guild.json if in agent dir)
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### Environment Variable Overrides
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
GUILD_WORKSPACE_ID=<id> guild agent test # Override workspace for this command
|
|
729
|
+
GUILD_OWNER_ID=<id> guild agent init --name my-agent # Override owner for agent creation
|
|
691
730
|
```
|
|
692
731
|
|
|
693
732
|
## Troubleshooting
|