@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.
@@ -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];
@@ -13,6 +13,8 @@ export const WEBHOOK_SERVICES = [
13
13
  'CYPRESS',
14
14
  'GITHUB',
15
15
  'GOOGLE_DOCS',
16
+ 'GOOGLE_COMPUTE',
17
+ 'GOOGLE_LOGGING',
16
18
  'JIRA',
17
19
  'LINEAR',
18
20
  'NEWRELIC',
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', ['config', 'delete', '--location', 'user', key]);
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
@@ -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
- * - HumanOutputWriter: Colors, tables, spinners for interactive use
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 HumanOutputWriter implements OutputWriter {
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;
@@ -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 HumanOutputWriter {
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 HumanOutputWriter();
369
+ return mode === 'json' ? new JSONOutputWriter() : new InteractiveOutputWriter();
277
370
  }
278
371
  /**
279
372
  * Create a no-op spinner (for quiet/JSON modes)
@@ -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
  */
@@ -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 init --name my-agent --template LLM
16
+ guild agent create my-agent --template LLM
12
17
 
13
18
  # Clone an existing agent
14
- guild agent clone guildai/slack-assistant
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
- # Install skills and create a CLAUDE.md template
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
- # Interactive creation
56
- guild agent init --name my-agent
57
-
58
- # With specific template
59
- guild agent init --name my-agent --template LLM
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 guildai/slack-assistant
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/slack-assistant
72
- cd slack-assistant
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 init`, you get:
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
- You already committed. Just push:
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 init` to create one
162
+ - Run `guild agent create` to create one
158
163
 
159
164
  ### Validation Failed
160
165
 
161
- Check the error in `guild agent versions --limit 1`. Common issues:
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`
@@ -316,7 +316,7 @@ guild agent code # View source of latest version
316
316
 
317
317
  ## Key Rules
318
318
 
319
- - Agent code lives at `agent.ts` in the project root.
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.
@@ -46,7 +46,7 @@ interface OutputWriter {
46
46
 
47
47
  Two implementations:
48
48
 
49
- - `HumanOutputWriter` - Colors, symbols, formatted output
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.
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  name: Guild Agent Development
3
- description: 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.
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 never use raw git commands.**
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 prompts for template)
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
- ## Use the Guild CLI for All Agent Operations
83
+ ## Guild CLI Is the ONLY Tool for Agent Operations
84
84
 
85
- **All agent work — creating, saving, testing, debugging — goes through Guild CLI.**
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
- - `guild agent get`, `guild agent versions`, `guild agent code`, `guild agent grep`
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 NOT from SDK)
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({ type: 'text', text: 'What repo?' });
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
- import slackifyMarkdown from 'slackify-markdown';
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
- **Important:**
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`) to `dependencies`.
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 (at project root, NOT in src/)
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** After `guild agent save` (no `--publish`)
661
- 2. **Validating** After `--publish`, running validation
662
- 3. **Published** Validation passed, available for use
663
- 4. **Failed** Validation failed, check errors
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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@guildai/cli",
3
- "version": "0.3.17",
3
+ "version": "0.4.0",
4
4
  "description": "Guild.ai CLI - Build, test, and deploy AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",