@guildai/cli 0.5.3 → 0.5.5

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.
@@ -1,440 +0,0 @@
1
- # Building Agents with the Guild CLI
2
-
3
- ## Prerequisites
4
-
5
- Before you begin, make sure you have:
6
-
7
- - **Node.js 18+** and **npm** — [nodejs.org](https://nodejs.org)
8
- - **A Guild account** — Guild.ai is in closed beta. Request an invitation at hello@guild.ai
9
-
10
- ## Install the CLI
11
-
12
- ```bash
13
- npm install -g @guildai/cli
14
- ```
15
-
16
- Then authenticate with Guild:
17
-
18
- ```bash
19
- guild auth login
20
- ```
21
-
22
- This opens your browser to complete sign-in at [app.guild.ai](https://app.guild.ai). It also configures your local npm registry so the CLI can install Guild packages.
23
-
24
- Verify everything is working:
25
-
26
- ```bash
27
- guild auth status
28
- # ✓ Authenticated
29
- ```
30
-
31
- Then select your default workspace:
32
-
33
- ```bash
34
- guild workspace select
35
- ```
36
-
37
- If you have one workspace, it's selected automatically. If you have several, pick one from the list. This tells the CLI where to run agent tests and chat sessions.
38
-
39
- If you run into issues, see [Troubleshooting](#troubleshooting) below.
40
-
41
- ### Set up coding assistant skills (optional)
42
-
43
- If you use Claude Code or another coding assistant, install Guild CLI skills into your project:
44
-
45
- ```bash
46
- guild setup
47
- ```
48
-
49
- This deposits SDK reference and CLI workflow docs into `.claude/skills/` so your coding assistant understands Guild agent development patterns.
50
-
51
- ## Hello World
52
-
53
- Let's create a simple agent that greets users.
54
-
55
- ### 1. Create the agent
56
-
57
- ```bash
58
- mkdir hello-agent && cd hello-agent
59
- guild agent init --name hello-agent --template LLM
60
- ```
61
-
62
- This creates the agent in the Guild backend, initializes a local git repo, and pulls starter files:
63
-
64
- ```
65
- hello-agent/
66
- ├── agent.ts # Your agent code (edit this)
67
- ├── package.json # Dependencies (runtime packages are pre-configured)
68
- ├── tsconfig.json # TypeScript config
69
- ├── guild.json # Local config (managed by the CLI, don't edit)
70
- └── .gitignore
71
- ```
72
-
73
- ### 2. Edit the agent
74
-
75
- Open `agent.ts` and replace the contents:
76
-
77
- ```typescript
78
- import { llmAgent, guildTools, userInterfaceTools } from '@guildai/agents-sdk';
79
-
80
- export default llmAgent({
81
- description: 'A friendly greeting agent',
82
- tools: { ...guildTools, ...userInterfaceTools },
83
- systemPrompt: `You are a friendly assistant. Greet users warmly and answer their questions.`,
84
- mode: 'multi-turn',
85
- });
86
- ```
87
-
88
- ### 3. Test it
89
-
90
- ```bash
91
- guild agent test --ephemeral
92
- ```
93
-
94
- This opens an interactive chat session. Type a message and press Enter:
95
-
96
- ```
97
- You: Hello!
98
- Agent: Hello! Welcome — I'm happy to help. What can I do for you today?
99
- ```
100
-
101
- Press `Ctrl+C` to exit.
102
-
103
- ### 4. Save and publish
104
-
105
- ```bash
106
- guild agent save -A --message "First version" --wait --publish
107
- ```
108
-
109
- - `-A` stages and commits all changes before pushing
110
- - `--wait` blocks until validation passes
111
- - `--publish` makes the agent available in the Guild catalog
112
-
113
- Check status:
114
-
115
- ```bash
116
- guild agent get
117
- guild agent versions
118
- ```
119
-
120
- That's it — your first agent is live.
121
-
122
- ## Installing Skills
123
-
124
- If you use [Claude Code](https://docs.anthropic.com/en/docs/claude-code), install Guild CLI skills into your project:
125
-
126
- ```bash
127
- guild setup
128
- ```
129
-
130
- This deposits SDK reference and CLI workflow docs into `.claude/skills/` so Claude Code understands Guild agent development patterns. Support for other coding assistants is coming soon.
131
-
132
- ## Create an Agent
133
-
134
- If you skipped the Hello World, here's the quick version:
135
-
136
- ```bash
137
- mkdir my-agent && cd my-agent
138
- guild agent init
139
- ```
140
-
141
- The CLI will prompt for a name and template. Or skip the prompts:
142
-
143
- ```bash
144
- guild agent init --name my-agent --template LLM
145
- ```
146
-
147
- ### Templates
148
-
149
- | Template | Use when |
150
- | -------------------- | -------------------------------------------------------------------- |
151
- | `LLM` | The LLM is the logic. You write a prompt and pick tools. Start here. |
152
- | `AUTO_MANAGED_STATE` | You write procedural TypeScript that calls tools inline. |
153
- | `BLANK` | You want full control over the agent lifecycle. |
154
-
155
- ## Write Your Agent
156
-
157
- Edit `agent.ts`. The template gives you a working starting point — modify it to fit your use case.
158
-
159
- ### LLM Agent
160
-
161
- Define a system prompt and the tools the LLM can use. No procedural code needed.
162
-
163
- ```typescript
164
- import { llmAgent, guildTools, userInterfaceTools } from '@guildai/agents-sdk';
165
- import { gitHubTools } from '@guildai-services/guildai~github';
166
-
167
- export default llmAgent({
168
- description: 'Answers questions about GitHub repositories',
169
- tools: { ...gitHubTools, ...guildTools, ...userInterfaceTools },
170
- systemPrompt: `You help users understand their GitHub repositories.
171
- Use the GitHub tools to look up real data when asked.`,
172
- mode: 'multi-turn',
173
- });
174
- ```
175
-
176
- `mode: "multi-turn"` keeps the conversation going after each response. Use `"one-shot"` (default) when the agent should respond once and finish.
177
-
178
- ### Code-First Agent
179
-
180
- Write TypeScript that calls tools directly. The runtime manages state between tool calls via continuations. Requires the `"use agent"` directive at the top of the file.
181
-
182
- ```typescript
183
- 'use agent';
184
-
185
- import { agent, guildTools, userInterfaceTools, type Task } from '@guildai/agents-sdk';
186
- import { gitHubTools } from '@guildai-services/guildai~github';
187
- import { z } from 'zod';
188
-
189
- const tools = { ...gitHubTools, ...guildTools, ...userInterfaceTools };
190
- type Tools = typeof tools;
191
-
192
- const inputSchema = z.object({
193
- type: z.literal('text'),
194
- text: z.string().describe('Repository in owner/repo format'),
195
- });
196
-
197
- const outputSchema = z.object({
198
- type: z.literal('text'),
199
- text: z.string(),
200
- });
201
-
202
- async function run(input: z.infer<typeof inputSchema>, task: Task<Tools>) {
203
- const prs = await task.tools.github_search_issues_and_pull_requests({
204
- q: `is:pr is:open repo:${input.text}`,
205
- per_page: 10,
206
- });
207
-
208
- if (!prs.items?.length) {
209
- return { type: 'text' as const, text: 'No open PRs.' };
210
- }
211
-
212
- const summary = prs.items.map((pr) => `- #${pr.number}: ${pr.title}`).join('\n');
213
-
214
- return { type: 'text' as const, text: summary };
215
- }
216
-
217
- export default agent({
218
- description: 'Lists open PRs in a GitHub repo',
219
- inputSchema,
220
- outputSchema,
221
- tools,
222
- run,
223
- });
224
- ```
225
-
226
- ### Tools Overview
227
-
228
- Every agent has access to three categories of tools:
229
-
230
- - **Service tools** (e.g., `gitHubTools`, `slackTools`) — call third-party APIs. When a user first triggers a service tool, Guild prompts them to connect their account via OAuth.
231
- - **`guildTools`** — query the Guild platform (look up agents, workspaces, sessions, triggers).
232
- - **`userInterfaceTools`** — interact with the user during a session (ask questions, send progress updates).
233
-
234
- All tool calls go through `task.tools`:
235
-
236
- ```typescript
237
- // Service tools
238
- const pr = await task.tools.github_pulls_get({ owner, repo, pull_number: 42 });
239
- await task.tools.slack_chat_post_message({ channel: 'C123', text: 'PR merged' });
240
-
241
- // User interface tools
242
- const answer = await task.tools.ui_prompt({ type: 'text', text: 'Which repo?' });
243
- ```
244
-
245
- ## Available Services
246
-
247
- Import service tools from their packages. These are provided by the runtime — don't add them to `package.json`.
248
-
249
- | Service | Import |
250
- | ------------ | --------------------------------------------------------------------------- |
251
- | GitHub | `import { gitHubTools } from "@guildai-services/guildai~github"` |
252
- | Slack | `import { slackTools } from "@guildai-services/guildai~slack"` |
253
- | Jira | `import { jiraTools } from "@guildai-services/guildai~jira"` |
254
- | Bitbucket | `import { bitbucketTools } from "@guildai-services/guildai~bitbucket"` |
255
- | Azure DevOps | `import { azureDevOpsTools } from "@guildai-services/guildai~azure-devops"` |
256
-
257
- ## Available Models
258
-
259
- Guild agents can use the following LLM providers and models:
260
-
261
- | Provider | Models |
262
- | --------- | --------------------------------- |
263
- | Anthropic | Claude Sonnet 4, Claude Haiku 3.5 |
264
- | OpenAI | GPT-4o, GPT-4o mini |
265
- | Google | Gemini 2.0 Flash |
266
-
267
- Model selection is handled by the runtime. LLM agents use the platform's default model unless configured otherwise.
268
-
269
- ## Development Loop
270
-
271
- The typical workflow is: pull → edit → test → save.
272
-
273
- ### 1. Pull latest changes
274
-
275
- If others are working on the same agent, pull their changes first:
276
-
277
- ```bash
278
- guild agent pull
279
- ```
280
-
281
- This pulls git commits and also checks for unpublished changes made via the web editor. If someone edited the agent in the UI, pull downloads those files automatically.
282
-
283
- ### 2. Test locally
284
-
285
- ```bash
286
- guild agent test # Interactive chat session
287
- guild agent chat "Hello" # Send a single message
288
- ```
289
-
290
- `guild agent test` opens an interactive session where you can chat with your agent. Changes to `agent.ts` take effect on the next save — you don't need to restart.
291
-
292
- ### 3. Save your work
293
-
294
- Commit with git, then push via Guild:
295
-
296
- ```bash
297
- git add . && git commit -m "Add Slack notifications"
298
- guild agent save
299
- ```
300
-
301
- Or stage+commit+push in one step:
302
-
303
- ```bash
304
- guild agent save -A --message "Add Slack notifications"
305
- ```
306
-
307
- This pushes your commits and creates a new version in the Guild backend. Versions start as drafts.
308
-
309
- ### 4. Publish
310
-
311
- ```bash
312
- guild agent save -A --message "Ready to ship" --wait --publish
313
- ```
314
-
315
- `--wait` blocks until validation passes. `--publish` makes the agent available in the catalog. You can also publish separately:
316
-
317
- ```bash
318
- guild agent publish
319
- ```
320
-
321
- ### Check status
322
-
323
- ```bash
324
- guild agent get # Agent info and current version
325
- guild agent versions # Version history
326
- guild agent code # View source of latest version
327
- ```
328
-
329
- ## Key Rules
330
-
331
- - Agent code lives in `agent.ts` (typically at the project root, but can be in a subdirectory like `src/`).
332
- - 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.
333
- - Always call tools through `task.tools.<name>(args)`. Never access services directly.
334
- - Use `git add` and `git commit` to manage your working tree. Use `guild agent save` to push and create versions. Don't use `git push` directly (a pre-push hook blocks it).
335
- - Don't edit `guild.json` — it's managed by the CLI.
336
-
337
- ## Other Commands
338
-
339
- ```bash
340
- guild agent clone owner/agent-name # Clone an existing agent to work on locally
341
- guild agent init --fork owner/name # Fork an agent as a starting point
342
- guild agent pull # Pull remote changes into local directory
343
- guild agent unpublish # Remove from catalog
344
- guild agent revalidate # Re-run validation on latest version
345
- ```
346
-
347
- ## Diagnostics
348
-
349
- Run `guild doctor` to check your setup:
350
-
351
- ```bash
352
- guild doctor
353
- ```
354
-
355
- ```
356
- Checking Guild CLI setup...
357
-
358
- ✓ Authentication Logged in
359
- ✓ Server Connected to https://app.guild.ai/api (125ms)
360
- ✓ Global config ~/.guild/config.json
361
- ✓ Default workspace my-workspace
362
- - Local config Not in an agent directory
363
- ✓ Git Installed
364
-
365
- 5 passed, 0 failed, 1 skipped
366
- ```
367
-
368
- ## Troubleshooting
369
-
370
- ### "Connection refused" or "Cannot connect to server"
371
-
372
- 1. Check your internet connection
373
- 2. Run `guild doctor` to see which check is failing
374
-
375
- ### "Workspace not found" or wrong workspace
376
-
377
- Your default workspace may not match the target server. Override with an environment variable:
378
-
379
- ```bash
380
- GUILD_WORKSPACE_ID=<workspace-id> guild chat "hello"
381
- ```
382
-
383
- Or set a new default:
384
-
385
- ```bash
386
- guild workspace select
387
- ```
388
-
389
- ### "Not authenticated" from Guild CLI
390
-
391
- Run `guild auth login` to re-authenticate:
392
-
393
- ```bash
394
- guild auth login
395
- guild auth status
396
- ```
397
-
398
- ### "No agent ID provided and not in an agent directory"
399
-
400
- You need to either run the command from inside an agent directory (one with a `guild.json` file), or pass the agent ID explicitly:
401
-
402
- ```bash
403
- # Option 1: cd into the agent directory
404
- cd my-agent
405
- guild agent get
406
-
407
- # Option 2: pass the agent ID
408
- guild agent get <agent-id>
409
- ```
410
-
411
- ### "No changes to save"
412
-
413
- Working tree is clean and there are no unpushed commits. Make a code change, commit it, then run `guild agent save` again. If a previous save committed locally but failed to push (e.g., network error), just run `guild agent save` again — it detects the unpushed commits and resumes.
414
-
415
- ### Validation failures
416
-
417
- After saving, if validation fails:
418
-
419
- ```bash
420
- # Check the latest version for errors
421
- guild agent versions --limit 1
422
-
423
- # Fix the issue, commit, and save again
424
- git add . && git commit -m "Fix validation error"
425
- guild agent save --wait
426
- ```
427
-
428
- ### Agent test not responding
429
-
430
- If `guild agent test` hangs or produces no output:
431
-
432
- 1. Check your agent code compiles: look for TypeScript errors in `agent.ts`
433
- 2. Make sure you've saved at least once: `guild agent save -A --message "initial"`
434
- 3. Try a single message instead: `guild agent chat "hello"`
435
-
436
- ## Next Steps
437
-
438
- - Browse agents at [app.guild.ai/agents](https://app.guild.ai/agents)
439
- - Fork an existing agent: `guild agent init --fork owner/agent-name`
440
- - Clone one to study: `guild agent clone owner/agent-name`
@@ -1,126 +0,0 @@
1
- # Output Format Design
2
-
3
- ## Global Flags
4
-
5
- **`--json`** - Machine-readable JSON output
6
-
7
- - Explicit opt-in (not auto-detected from pipes)
8
- - Non-interactive mode
9
- - Pure JSON to stdout
10
- - Errors go to stderr as JSON
11
-
12
- **`--quiet` / `-q`** - Suppress progress messages
13
-
14
- - Keeps errors
15
- - Hides progress spinners and status updates
16
- - Works in both human and JSON modes
17
-
18
- ## Output Streams
19
-
20
- **stdout** - Structured data
21
-
22
- - Command results
23
- - Lists, objects, values
24
- - Always parseable
25
-
26
- **stderr** - Messages
27
-
28
- - Progress updates
29
- - Status information
30
- - Errors
31
- - Suppressible with `--quiet`
32
-
33
- ## Implementation
34
-
35
- The output system uses an `OutputWriter` interface:
36
-
37
- ```typescript
38
- interface OutputWriter {
39
- data(value: unknown): void;
40
- success(message: string, details?: Record<string, unknown>): void;
41
- error(message: string, details?: string): void;
42
- progress(message: string): void;
43
- spinner(message: string): Spinner;
44
- }
45
- ```
46
-
47
- Two implementations:
48
-
49
- - `InteractiveOutputWriter` - Colors, symbols, formatted output
50
- - `JSONOutputWriter` - Pure JSON
51
-
52
- Commands use `createOutputWriter()` to get the right implementation based on flags.
53
-
54
- ## Flag Checking
55
-
56
- ```typescript
57
- // src/lib/output-mode.ts
58
- export function getOutputMode(): OutputMode {
59
- if (process.argv.includes('--json')) return 'json';
60
- return 'human';
61
- }
62
-
63
- export function isQuietMode(): boolean {
64
- return process.argv.includes('--quiet') || process.argv.includes('-q');
65
- }
66
- ```
67
-
68
- Just checks for `--json` flag. No pipe detection or environment inspection.
69
-
70
- ## Command Patterns
71
-
72
- **Data commands** (list, get, etc.):
73
-
74
- - Output JSON by default
75
- - `--json` flag has no effect (already JSON)
76
- - Use for automation and scripting
77
-
78
- **Interactive commands** (chat, test REPL):
79
-
80
- - Human-friendly by default
81
- - `--mode=json` specifies JSON input/output format (for chat/agent commands)
82
- - `--once` controls interactivity (one-shot vs continuous)
83
- - Chat provides human-readable formatting by default
84
-
85
- ## Examples
86
-
87
- ```bash
88
- # Data command - JSON by default
89
- guild agent list
90
- # {"agents": [...], "pagination": {...}}
91
-
92
- # Interactive command - human-friendly
93
- guild chat
94
- # [colored output, prompts, spinners]
95
-
96
- # One-shot mode - human-readable (default)
97
- guild chat --once "hello"
98
- # Hello! How can I help you today?
99
-
100
- # One-shot mode - JSON output
101
- echo '{"prompt": "hello"}' | guild chat --once --mode=json
102
- # {"session_id": "...", "events": [...]}
103
-
104
- # Suppress progress messages
105
- guild agent create my-agent --quiet
106
- # Only shows result, no progress updates
107
- ```
108
-
109
- ## Design Decisions
110
-
111
- **No pipe auto-detection**: Explicit `--json` required. Prevents accidental format switching.
112
-
113
- **Separate streams**: Data to stdout, messages to stderr. Clean separation for piping.
114
-
115
- **JSON by default for data**: `agent list`, `workspace list`, etc. output JSON. The `guild chat` interface provides human-readable interaction.
116
-
117
- **Quiet mode independent**: Works with both human and JSON modes. Suppresses progress, keeps errors.
118
-
119
- ## Hyperlinks
120
-
121
- Table cells for entity names and IDs are wrapped in [OSC8 terminal hyperlinks](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) that link to the corresponding dashboard pages. In supported terminals (iTerm2, VS Code Terminal, Windows Terminal), these cells are clickable.
122
-
123
- **Environment controls:**
124
-
125
- - `FORCE_HYPERLINK=1` — Force hyperlinks in non-TTY environments
126
- - `FORCE_HYPERLINK=0` — Disable hyperlinks entirely
@@ -1,143 +0,0 @@
1
- # Session Events Architecture
2
-
3
- This document describes the shared session event type system introduced in PR #835 to support the new messaging architecture from PR #819.
4
-
5
- ## Overview
6
-
7
- The CLI now uses a unified event-driven architecture for session communication, replacing the previous heuristic-based approach. All event type definitions are centralized in `src/lib/session-events.ts` to eliminate duplication and provide a single source of truth.
8
-
9
- ## Event Type Categories
10
-
11
- ### 1. Runtime System Events
12
-
13
- These events track the lifecycle of agent task execution:
14
-
15
- - **`runtime_start`** - Agent task has started
16
- - **`runtime_running`** - Agent task is actively running
17
- - **`runtime_waiting`** - Agent task is waiting (e.g., for user input)
18
- - **`runtime_error`** - Runtime error occurred during execution
19
- - **`runtime_done`** - Agent task completed successfully
20
-
21
- ### 2. Agent Notification Events
22
-
23
- These events carry agent responses and updates:
24
-
25
- - **`agent_notification_message`** - Agent text responses
26
- - Content: `{ type: 'text', data: string }`
27
- - Rendered as markdown in CLI
28
- - **`agent_notification_progress`** - Agent progress updates
29
- - Content: `{ type: 'text', data: string }`
30
- - Displayed in spinner status line
31
- - **`agent_notification_error`** - Agent error notifications
32
- - Content: `{ type: 'text', data: string }`
33
- - Displayed as error messages in red
34
-
35
- ### 3. Agent Console Events
36
-
37
- Debug and logging output from agents:
38
-
39
- - **`agent_console`** - Console output with levels
40
- - Levels: `debug`, `info`, `warn`, `error`
41
- - Content: `string`
42
-
43
- ### 4. User Events
44
-
45
- - **`user_message`** - Messages sent by the user
46
- - Content: `string`
47
- - Includes `author_id` field
48
-
49
- ### 5. Legacy Events (Backward Compatibility)
50
-
51
- - **`agent_message`** - Legacy format from pre-PR #819
52
- - Message types: `MESSAGE`, `PROGRESS_LOG`, `DEBUG_LOG`, `DONE`
53
- - Content: `string`
54
- - Maintained for transition period
55
-
56
- ## Usage in CLI Commands
57
-
58
- ### Importing Types
59
-
60
- ```typescript
61
- import { SessionEvent, Session, AgentMessageEvent } from '../lib/session-events.js';
62
- ```
63
-
64
- ### Event Processing Example
65
-
66
- ```typescript
67
- // Handle different event types
68
- events.forEach((event: SessionEvent) => {
69
- switch (event.type) {
70
- case 'agent_notification_message':
71
- // Display agent response
72
- console.log(event.content.data);
73
- break;
74
- case 'runtime_done':
75
- // Task completed
76
- setIsComplete(true);
77
- break;
78
- case 'agent_message':
79
- // Legacy format support
80
- if (event.message_type === 'MESSAGE') {
81
- console.log(event.content);
82
- }
83
- break;
84
- }
85
- });
86
- ```
87
-
88
- ## Completion Detection
89
-
90
- The CLI uses different strategies for detecting when an agent task is complete:
91
-
92
- ### For Assistant Agent
93
-
94
- - Waits for `agent_notification_message` events (MESSAGE type)
95
- - Assistant agent identifier: `"assistant"`
96
- - More flexible completion detection for assistant workflows
97
-
98
- ### For Custom Agents
99
-
100
- - Waits for `runtime_done` events
101
- - Indicates the agent task has fully completed
102
-
103
- ### Legacy Support
104
-
105
- - Still supports `agent_message` with `message_type: 'DONE'`
106
- - Maintained during transition period
107
-
108
- ## Migration from Duplicated Types
109
-
110
- **Before PR #835:**
111
-
112
- ```typescript
113
- // Duplicated in chat.tsx, agent/test.ts, agent/chat.ts
114
- interface AgentMessageEvent extends BaseEvent {
115
- type: 'agent_message';
116
- message_type: 'MESSAGE' | 'PROGRESS_LOG' | 'DEBUG_LOG' | 'DONE';
117
- content: string;
118
- }
119
- ```
120
-
121
- **After PR #835:**
122
-
123
- ```typescript
124
- // Single definition in lib/session-events.ts
125
- import { AgentMessageEvent } from '../lib/session-events.js';
126
- ```
127
-
128
- ## Benefits
129
-
130
- - **Single Source of Truth**: All event types defined in one place
131
- - **Type Safety**: Compile-time checking for event handling
132
- - **Maintainability**: Changes to event structure only need to be made once
133
- - **Consistency**: All CLI commands use the same event definitions
134
- - **Future-Proof**: Easy to add new event types as the system evolves
135
-
136
- ## Files Using Shared Types
137
-
138
- - `src/commands/chat.tsx` - Interactive chat command
139
- - `src/commands/agent/test.ts` - Agent testing command
140
- - `src/commands/agent/chat.ts` - Agent-specific chat command
141
- - `src/lib/session-events.ts` - Type definitions (source of truth)
142
-
143
- This architecture supports the transition from heuristic-based session management to proper event-driven communication, enabling more reliable and faster CLI operations.