@guildai/cli 0.5.10 → 0.5.12
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/init.js +24 -3
- package/dist/commands/auth/login.js +3 -1
- package/dist/commands/container/destroy.d.ts +3 -0
- package/dist/commands/container/destroy.js +48 -0
- package/dist/commands/container/events.d.ts +3 -0
- package/dist/commands/container/events.js +44 -0
- package/dist/commands/container/exec.d.ts +3 -0
- package/dist/commands/container/exec.js +64 -0
- package/dist/commands/container/get.d.ts +3 -0
- package/dist/commands/container/get.js +33 -0
- package/dist/commands/container/list.d.ts +3 -0
- package/dist/commands/container/list.js +48 -0
- package/dist/commands/container-image/create.d.ts +3 -0
- package/dist/commands/container-image/create.js +41 -0
- package/dist/commands/container-image/get.d.ts +3 -0
- package/dist/commands/container-image/get.js +33 -0
- package/dist/commands/container-image/list.d.ts +3 -0
- package/dist/commands/container-image/list.js +44 -0
- package/dist/commands/job/get.d.ts +3 -0
- package/dist/commands/job/get.js +44 -0
- package/dist/commands/job/step-get.d.ts +3 -0
- package/dist/commands/job/step-get.js +40 -0
- package/dist/commands/trigger/create.js +4 -0
- package/dist/commands/trigger/update.js +4 -0
- package/dist/index.js +33 -2
- package/dist/lib/api-types.d.ts +135 -0
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +29 -23
- package/dist/lib/config.js +0 -4
- package/dist/lib/generated-types.d.ts +2 -2
- package/dist/lib/generated-types.js +2 -0
- package/dist/lib/gk.d.ts +15 -0
- package/dist/lib/gk.js +91 -0
- package/dist/lib/output.d.ts +21 -16
- package/dist/lib/output.js +184 -1
- package/dist/lib/session-events.d.ts +1 -0
- package/dist/lib/table.d.ts +22 -0
- package/dist/lib/table.js +60 -0
- package/docs/CLI_WORKFLOW.md +9 -9
- package/docs/skills/agent-dev.md +11 -15
- package/package.json +2 -3
- package/dist/commands/agent/create.d.ts +0 -3
- package/dist/commands/agent/create.js +0 -132
package/dist/lib/output.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Copyright 2026 Guild.ai
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import chalk from 'chalk';
|
|
4
|
-
import { Table } from '
|
|
4
|
+
import { Table } from './table.js';
|
|
5
5
|
import { getOutputMode, isQuietMode } from './output-mode.js';
|
|
6
6
|
import { createSpinner } from './progress.js';
|
|
7
7
|
import { brand, hyperlink } from './colors.js';
|
|
@@ -313,6 +313,189 @@ export function formatTriggerTable(triggers, pagination) {
|
|
|
313
313
|
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} triggers`));
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Format a container list as a human-readable table.
|
|
318
|
+
* Used by container list command.
|
|
319
|
+
*/
|
|
320
|
+
export function formatContainerTable(containers, pagination) {
|
|
321
|
+
if (containers.length === 0) {
|
|
322
|
+
console.log(chalk.dim('No containers found'));
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
const table = new Table({
|
|
326
|
+
columns: [
|
|
327
|
+
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
328
|
+
{ name: 'status', title: 'STATUS', alignment: 'left' },
|
|
329
|
+
{ name: 'image', title: 'IMAGE', alignment: 'left' },
|
|
330
|
+
{ name: 'tag', title: 'TAG', alignment: 'left' },
|
|
331
|
+
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
332
|
+
],
|
|
333
|
+
});
|
|
334
|
+
containers.forEach((container) => {
|
|
335
|
+
const statusColor = container.status === 'RUNNING'
|
|
336
|
+
? chalk.green
|
|
337
|
+
: container.status === 'ERRORED'
|
|
338
|
+
? chalk.red
|
|
339
|
+
: container.status === 'DESTROYED'
|
|
340
|
+
? chalk.dim
|
|
341
|
+
: chalk.yellow;
|
|
342
|
+
table.addRow({
|
|
343
|
+
id: container.id,
|
|
344
|
+
status: statusColor(container.status),
|
|
345
|
+
image: container.image?.name || '-',
|
|
346
|
+
tag: container.image?.tag || '-',
|
|
347
|
+
created: container.created_at ? formatRelativeTime(container.created_at) : '',
|
|
348
|
+
});
|
|
349
|
+
});
|
|
350
|
+
table.printTable();
|
|
351
|
+
const showing = Math.min(pagination.limit, containers.length);
|
|
352
|
+
if (pagination.has_more) {
|
|
353
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
354
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} containers. ` +
|
|
355
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
356
|
+
}
|
|
357
|
+
else if (pagination.total_count > showing) {
|
|
358
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} containers`));
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Format a container image list as a human-readable table.
|
|
363
|
+
* Used by container-image list command.
|
|
364
|
+
*/
|
|
365
|
+
export function formatContainerImageTable(images, pagination) {
|
|
366
|
+
if (images.length === 0) {
|
|
367
|
+
console.log(chalk.dim('No container images found'));
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
const table = new Table({
|
|
371
|
+
columns: [
|
|
372
|
+
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
373
|
+
{ name: 'name', title: 'NAME', alignment: 'left' },
|
|
374
|
+
{ name: 'image', title: 'IMAGE', alignment: 'left' },
|
|
375
|
+
{ name: 'tag', title: 'TAG', alignment: 'left' },
|
|
376
|
+
{ name: 'public', title: 'PUBLIC', alignment: 'left' },
|
|
377
|
+
],
|
|
378
|
+
});
|
|
379
|
+
images.forEach((image) => {
|
|
380
|
+
table.addRow({
|
|
381
|
+
id: image.id,
|
|
382
|
+
name: image.name,
|
|
383
|
+
image: image.image_name,
|
|
384
|
+
tag: image.tag,
|
|
385
|
+
public: image.is_public ? chalk.green('yes') : chalk.dim('no'),
|
|
386
|
+
});
|
|
387
|
+
});
|
|
388
|
+
table.printTable();
|
|
389
|
+
const showing = Math.min(pagination.limit, images.length);
|
|
390
|
+
if (pagination.has_more) {
|
|
391
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
392
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} images. ` +
|
|
393
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
394
|
+
}
|
|
395
|
+
else if (pagination.total_count > showing) {
|
|
396
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} images`));
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Derive a human-readable event type label from entity_type.
|
|
401
|
+
*/
|
|
402
|
+
function formatEventType(entityType) {
|
|
403
|
+
if (entityType === 'EntContainerEventCreate')
|
|
404
|
+
return 'create';
|
|
405
|
+
if (entityType === 'EntContainerEventDestroy')
|
|
406
|
+
return 'destroy';
|
|
407
|
+
if (entityType === 'EntContainerEventCommand')
|
|
408
|
+
return 'command';
|
|
409
|
+
return entityType;
|
|
410
|
+
}
|
|
411
|
+
/**
|
|
412
|
+
* Format a container event list as a human-readable table.
|
|
413
|
+
* Used by container events command.
|
|
414
|
+
*/
|
|
415
|
+
export function formatContainerEventTable(events, pagination) {
|
|
416
|
+
if (events.length === 0) {
|
|
417
|
+
console.log(chalk.dim('No events found'));
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
const table = new Table({
|
|
421
|
+
columns: [
|
|
422
|
+
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
423
|
+
{ name: 'type', title: 'TYPE', alignment: 'left', color: 'cyan' },
|
|
424
|
+
{ name: 'status', title: 'STATUS', alignment: 'left' },
|
|
425
|
+
{ name: 'actor', title: 'ACTOR', alignment: 'left' },
|
|
426
|
+
{ name: 'detail', title: 'DETAIL', alignment: 'left' },
|
|
427
|
+
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
428
|
+
],
|
|
429
|
+
});
|
|
430
|
+
events.forEach((event) => {
|
|
431
|
+
const statusColor = event.status === 'SUCCESS'
|
|
432
|
+
? chalk.green
|
|
433
|
+
: event.status === 'ERROR'
|
|
434
|
+
? chalk.red
|
|
435
|
+
: chalk.yellow;
|
|
436
|
+
let detail = '';
|
|
437
|
+
if (event.entity_type === 'EntContainerEventCommand') {
|
|
438
|
+
detail = truncate(event.command, 30);
|
|
439
|
+
}
|
|
440
|
+
else if (event.status === 'ERROR' && event.error) {
|
|
441
|
+
detail = truncate(event.error, 30);
|
|
442
|
+
}
|
|
443
|
+
table.addRow({
|
|
444
|
+
id: event.id,
|
|
445
|
+
type: formatEventType(event.entity_type),
|
|
446
|
+
status: statusColor(event.status),
|
|
447
|
+
actor: event.actor?.name || event.actor?.full_name || '-',
|
|
448
|
+
detail,
|
|
449
|
+
created: event.created_at ? formatRelativeTime(event.created_at) : '',
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
table.printTable();
|
|
453
|
+
const showing = Math.min(pagination.limit, events.length);
|
|
454
|
+
if (pagination.has_more) {
|
|
455
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
456
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} events. ` +
|
|
457
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
458
|
+
}
|
|
459
|
+
else if (pagination.total_count > showing) {
|
|
460
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} events`));
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Format job steps as a human-readable table.
|
|
465
|
+
* Used by job get command.
|
|
466
|
+
*/
|
|
467
|
+
export function formatJobStepTable(steps) {
|
|
468
|
+
if (steps.length === 0) {
|
|
469
|
+
console.log(chalk.dim('No steps found'));
|
|
470
|
+
return;
|
|
471
|
+
}
|
|
472
|
+
const table = new Table({
|
|
473
|
+
columns: [
|
|
474
|
+
{ name: 'name', title: 'STEP', alignment: 'left' },
|
|
475
|
+
{ name: 'status', title: 'STATUS', alignment: 'left' },
|
|
476
|
+
{ name: 'started', title: 'STARTED', alignment: 'left' },
|
|
477
|
+
{ name: 'completed', title: 'COMPLETED', alignment: 'left' },
|
|
478
|
+
],
|
|
479
|
+
});
|
|
480
|
+
steps.forEach((step) => {
|
|
481
|
+
const statusColor = step.status === 'SUCCEEDED'
|
|
482
|
+
? chalk.green
|
|
483
|
+
: step.status === 'FAILED' || step.status === 'ERRORED'
|
|
484
|
+
? chalk.red
|
|
485
|
+
: step.status === 'RUNNING'
|
|
486
|
+
? chalk.yellow
|
|
487
|
+
: step.status === 'SKIPPED'
|
|
488
|
+
? chalk.dim
|
|
489
|
+
: chalk.white;
|
|
490
|
+
table.addRow({
|
|
491
|
+
name: step.name,
|
|
492
|
+
status: statusColor(step.status),
|
|
493
|
+
started: step.started_at ? formatRelativeTime(step.started_at) : '-',
|
|
494
|
+
completed: step.completed_at ? formatRelativeTime(step.completed_at) : '-',
|
|
495
|
+
});
|
|
496
|
+
});
|
|
497
|
+
table.printTable();
|
|
498
|
+
}
|
|
316
499
|
/**
|
|
317
500
|
* Human-friendly output writer
|
|
318
501
|
*
|
|
@@ -85,6 +85,7 @@ export interface RuntimeWaitingEvent extends BaseEvent {
|
|
|
85
85
|
export interface RuntimeErrorEvent extends BaseEvent {
|
|
86
86
|
type: 'runtime_error';
|
|
87
87
|
content: string;
|
|
88
|
+
stack: string | null;
|
|
88
89
|
}
|
|
89
90
|
export interface RuntimeDoneEvent extends BaseEvent {
|
|
90
91
|
type: 'runtime_done';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
interface ColumnConfig {
|
|
2
|
+
name: string;
|
|
3
|
+
title: string;
|
|
4
|
+
alignment?: 'left';
|
|
5
|
+
color?: string;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Minimal table renderer using string-width@7 for ANSI-aware column sizing.
|
|
9
|
+
* Handles OSC8 hyperlink sequences correctly (string-width uses strip-ansi@7).
|
|
10
|
+
*/
|
|
11
|
+
export declare class Table {
|
|
12
|
+
private columns;
|
|
13
|
+
private rows;
|
|
14
|
+
constructor(config: {
|
|
15
|
+
columns: ColumnConfig[];
|
|
16
|
+
});
|
|
17
|
+
addRow(row: Record<string, string>): void;
|
|
18
|
+
render(): string;
|
|
19
|
+
printTable(): void;
|
|
20
|
+
}
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=table.d.ts.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import stringWidth from 'string-width';
|
|
5
|
+
/**
|
|
6
|
+
* Minimal table renderer using string-width@7 for ANSI-aware column sizing.
|
|
7
|
+
* Handles OSC8 hyperlink sequences correctly (string-width uses strip-ansi@7).
|
|
8
|
+
*/
|
|
9
|
+
export class Table {
|
|
10
|
+
columns;
|
|
11
|
+
rows = [];
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.columns = config.columns;
|
|
14
|
+
}
|
|
15
|
+
addRow(row) {
|
|
16
|
+
const sanitized = {};
|
|
17
|
+
for (const [k, v] of Object.entries(row)) {
|
|
18
|
+
sanitized[k] = v.replace(/[\r\n]+/g, ' ').trim();
|
|
19
|
+
}
|
|
20
|
+
this.rows.push(sanitized);
|
|
21
|
+
}
|
|
22
|
+
render() {
|
|
23
|
+
const widths = this.columns.map((col) => {
|
|
24
|
+
const headerWidth = stringWidth(col.title);
|
|
25
|
+
const maxData = this.rows.reduce((max, row) => Math.max(max, stringWidth(row[col.name] ?? '')), 0);
|
|
26
|
+
return Math.max(headerWidth, maxData);
|
|
27
|
+
});
|
|
28
|
+
const pad = (text, width) => {
|
|
29
|
+
const visible = stringWidth(text);
|
|
30
|
+
return visible >= width ? text : text + ' '.repeat(width - visible);
|
|
31
|
+
};
|
|
32
|
+
const top = '┌' + widths.map((w) => '─'.repeat(w + 2)).join('┬') + '┐';
|
|
33
|
+
const mid = '├' + widths.map((w) => '─'.repeat(w + 2)).join('┼') + '┤';
|
|
34
|
+
const bot = '└' + widths.map((w) => '─'.repeat(w + 2)).join('┴') + '┘';
|
|
35
|
+
const header = '│' +
|
|
36
|
+
this.columns
|
|
37
|
+
.map((col, i) => ' ' + chalk.bold(pad(col.title, widths[i])) + ' ')
|
|
38
|
+
.join('│') +
|
|
39
|
+
'│';
|
|
40
|
+
const dataRows = this.rows.map((row) => '│' +
|
|
41
|
+
this.columns
|
|
42
|
+
.map((col, i) => {
|
|
43
|
+
const val = row[col.name] ?? '';
|
|
44
|
+
const padded = pad(val, widths[i]);
|
|
45
|
+
if (col.color && col.color in chalk) {
|
|
46
|
+
return (' ' +
|
|
47
|
+
chalk[col.color](padded) +
|
|
48
|
+
' ');
|
|
49
|
+
}
|
|
50
|
+
return ' ' + padded + ' ';
|
|
51
|
+
})
|
|
52
|
+
.join('│') +
|
|
53
|
+
'│');
|
|
54
|
+
return [top, header, mid, ...dataRows, bot].join('\n');
|
|
55
|
+
}
|
|
56
|
+
printTable() {
|
|
57
|
+
console.log(this.render());
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=table.js.map
|
package/docs/CLI_WORKFLOW.md
CHANGED
|
@@ -11,7 +11,7 @@ For local agent development using the Guild CLI. This workflow manages agent cod
|
|
|
11
11
|
|
|
12
12
|
If Guild MCP tools are available (check for tools prefixed with `guild_`), use them for **read operations**: searching agents, listing workspaces, reading contexts, checking sessions, viewing credentials. MCP tools are faster and don't require shell execution.
|
|
13
13
|
|
|
14
|
-
Use the **CLI** (via Bash) for **local development operations**: `guild agent
|
|
14
|
+
Use the **CLI** (via Bash) for **local development operations**: `guild agent init`, `guild agent save`, `guild agent test`, `guild agent pull`, `guild agent clone`. These involve the local filesystem and git, which MCP can't do.
|
|
15
15
|
|
|
16
16
|
## CRITICAL: Always Use the Guild CLI
|
|
17
17
|
|
|
@@ -19,7 +19,7 @@ Use the **CLI** (via Bash) for **local development operations**: `guild agent cr
|
|
|
19
19
|
|
|
20
20
|
```bash
|
|
21
21
|
# Create a new agent
|
|
22
|
-
guild agent
|
|
22
|
+
guild agent init --name my-agent --template LLM
|
|
23
23
|
|
|
24
24
|
# Clone an existing agent
|
|
25
25
|
guild agent clone guildai/dev-assistant
|
|
@@ -66,11 +66,11 @@ guild setup --claude-md
|
|
|
66
66
|
### Creating Agents
|
|
67
67
|
|
|
68
68
|
```bash
|
|
69
|
-
# Create
|
|
70
|
-
guild agent
|
|
71
|
-
guild agent
|
|
72
|
-
guild agent
|
|
73
|
-
guild agent
|
|
69
|
+
# Create and initialize a new agent (interactive — prompts for name and template)
|
|
70
|
+
guild agent init
|
|
71
|
+
guild agent init --name my-agent --template LLM
|
|
72
|
+
guild agent init --name my-agent --template AUTO_MANAGED_STATE
|
|
73
|
+
guild agent init --name my-agent --template BLANK
|
|
74
74
|
|
|
75
75
|
# Fork an existing agent
|
|
76
76
|
guild agent init --fork owner/agent-name
|
|
@@ -145,7 +145,7 @@ guild agent chat "Hello, can you help me?"
|
|
|
145
145
|
|
|
146
146
|
## File Structure
|
|
147
147
|
|
|
148
|
-
After `guild agent
|
|
148
|
+
After `guild agent init`, you get:
|
|
149
149
|
|
|
150
150
|
```
|
|
151
151
|
my-agent/
|
|
@@ -175,7 +175,7 @@ Working tree is clean and there are no unpushed commits. Make a code change, com
|
|
|
175
175
|
You're not in an agent directory. Either:
|
|
176
176
|
|
|
177
177
|
- `cd` into the agent directory
|
|
178
|
-
- Run `guild agent
|
|
178
|
+
- Run `guild agent init` to create one
|
|
179
179
|
|
|
180
180
|
### Validation Failed
|
|
181
181
|
|
package/docs/skills/agent-dev.md
CHANGED
|
@@ -11,7 +11,7 @@ Build agents for Guild using the CLI. **Always use the Guild CLI for agent opera
|
|
|
11
11
|
|
|
12
12
|
If Guild MCP tools are available (check for tools prefixed with `guild_`), use them for **read operations**: searching agents, listing workspaces, reading contexts, checking sessions, viewing credentials. MCP tools are faster and don't require shell execution.
|
|
13
13
|
|
|
14
|
-
Use the **CLI** (via Bash) for **local development operations**: `guild agent
|
|
14
|
+
Use the **CLI** (via Bash) for **local development operations**: `guild agent init`, `guild agent save`, `guild agent test`, `guild agent pull`, `guild agent clone`. These involve the local filesystem and git, which MCP can't do.
|
|
15
15
|
|
|
16
16
|
## When to Use This
|
|
17
17
|
|
|
@@ -39,17 +39,14 @@ guild setup --claude-md
|
|
|
39
39
|
### Creating Agents
|
|
40
40
|
|
|
41
41
|
```bash
|
|
42
|
-
# Create
|
|
43
|
-
guild agent create my-agent
|
|
44
|
-
|
|
45
|
-
# Create with specific template
|
|
46
|
-
guild agent create my-agent --template LLM
|
|
47
|
-
guild agent create my-agent --template AUTO_MANAGED_STATE
|
|
48
|
-
guild agent create my-agent --template BLANK
|
|
49
|
-
|
|
50
|
-
# Initialize local workspace for existing agent
|
|
42
|
+
# Create and initialize a new agent (interactive - prompts for name and template)
|
|
51
43
|
guild agent init
|
|
52
44
|
|
|
45
|
+
# Create with specific name and template
|
|
46
|
+
guild agent init --name my-agent --template LLM
|
|
47
|
+
guild agent init --name my-agent --template AUTO_MANAGED_STATE
|
|
48
|
+
guild agent init --name my-agent --template BLANK
|
|
49
|
+
|
|
53
50
|
# Initialize with fork of existing agent
|
|
54
51
|
guild agent init --fork owner/agent-name
|
|
55
52
|
|
|
@@ -98,7 +95,7 @@ guild agent chat "Hello, can you help me?"
|
|
|
98
95
|
|
|
99
96
|
### For Creating and Modifying
|
|
100
97
|
|
|
101
|
-
- ✅ `guild agent
|
|
98
|
+
- ✅ `guild agent init`, `guild agent clone`
|
|
102
99
|
- ✅ `git add`, `git commit` (manage your own working tree)
|
|
103
100
|
- ✅ `guild agent save` (push commits and create a version)
|
|
104
101
|
- ✅ `guild agent save -A --message "desc"` (stage+commit+push in one step)
|
|
@@ -1681,7 +1678,7 @@ export default agent({ run: async (input, task) => { ... } })
|
|
|
1681
1678
|
|
|
1682
1679
|
## File Structure
|
|
1683
1680
|
|
|
1684
|
-
After `guild agent
|
|
1681
|
+
After `guild agent init`:
|
|
1685
1682
|
|
|
1686
1683
|
```
|
|
1687
1684
|
my-agent/
|
|
@@ -1705,9 +1702,8 @@ my-agent/
|
|
|
1705
1702
|
```bash
|
|
1706
1703
|
guild setup # Install coding assistant skills
|
|
1707
1704
|
guild setup --claude-md # Also create CLAUDE.md template
|
|
1708
|
-
guild agent
|
|
1709
|
-
guild agent
|
|
1710
|
-
guild agent init # Initialize local workspace
|
|
1705
|
+
guild agent init # Create and initialize a new agent
|
|
1706
|
+
guild agent init --name <name> --template LLM # Create with specific name and template
|
|
1711
1707
|
guild agent init --fork <agent-id> # Fork existing agent
|
|
1712
1708
|
guild agent pull # Pull remote changes
|
|
1713
1709
|
guild agent save # Push commits and create a draft version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@guildai/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.12",
|
|
4
4
|
"description": "Guild.ai CLI - Build, test, and deploy AI agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -59,9 +59,7 @@
|
|
|
59
59
|
"@napi-rs/keyring": "^1.2.0",
|
|
60
60
|
"axios": "^1.13.2",
|
|
61
61
|
"chalk": "^5.3.0",
|
|
62
|
-
"cli-table3": "^0.6.5",
|
|
63
62
|
"commander": "^12.1.0",
|
|
64
|
-
"console-table-printer": "^2.15.0",
|
|
65
63
|
"dotenv": "^16.4.7",
|
|
66
64
|
"execa": "^9.6.1",
|
|
67
65
|
"ink": "^5.0.1",
|
|
@@ -76,6 +74,7 @@
|
|
|
76
74
|
"react": "^18.3.1",
|
|
77
75
|
"sharp": "^0.34.5",
|
|
78
76
|
"shell-quote": "^1.8.2",
|
|
77
|
+
"string-width": "^7.2.0",
|
|
79
78
|
"svg-pathdata": "^8.0.0",
|
|
80
79
|
"svgdom": "^0.1.22",
|
|
81
80
|
"ws": "^8.18.0",
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// Copyright 2026 Guild.ai
|
|
2
|
-
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import inquirer from 'inquirer';
|
|
5
|
-
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
6
|
-
import { getGuildcoreUrl } from '../../lib/config.js';
|
|
7
|
-
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
8
|
-
import { pollAgentStatus } from '../../lib/polling.js';
|
|
9
|
-
import { createOutputWriter } from '../../lib/output.js';
|
|
10
|
-
const TEMPLATE_CHOICES = [
|
|
11
|
-
{
|
|
12
|
-
name: 'LLM - Simple language model agent (recommended)',
|
|
13
|
-
value: 'LLM',
|
|
14
|
-
short: 'LLM',
|
|
15
|
-
},
|
|
16
|
-
{
|
|
17
|
-
name: 'Auto-managed state - Agent with automatic state management',
|
|
18
|
-
value: 'AUTO_MANAGED_STATE',
|
|
19
|
-
short: 'Auto-managed state',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
name: 'Blank - Start from scratch',
|
|
23
|
-
value: 'BLANK',
|
|
24
|
-
short: 'Blank',
|
|
25
|
-
},
|
|
26
|
-
];
|
|
27
|
-
function isInteractive() {
|
|
28
|
-
return process.stdin.isTTY === true;
|
|
29
|
-
}
|
|
30
|
-
async function promptForTemplate() {
|
|
31
|
-
const { template } = await inquirer.prompt([
|
|
32
|
-
{
|
|
33
|
-
type: 'list',
|
|
34
|
-
name: 'template',
|
|
35
|
-
message: 'Select agent template:',
|
|
36
|
-
choices: TEMPLATE_CHOICES,
|
|
37
|
-
default: 'LLM',
|
|
38
|
-
},
|
|
39
|
-
]);
|
|
40
|
-
return template;
|
|
41
|
-
}
|
|
42
|
-
export function createAgentCreateCommand() {
|
|
43
|
-
const cmd = new Command('create');
|
|
44
|
-
cmd
|
|
45
|
-
.description('Create a new agent')
|
|
46
|
-
.argument('<name>', 'Agent name')
|
|
47
|
-
.option('--description <text>', 'Agent description')
|
|
48
|
-
.option('--owner-id <id>', 'Owner ID (user or organization, defaults to current user)')
|
|
49
|
-
.option('--template <template>', 'Agent template (LLM, AUTO_MANAGED_STATE, BLANK)')
|
|
50
|
-
.option('--no-wait', 'Return immediately without waiting for initialization')
|
|
51
|
-
.action(async (name, options) => {
|
|
52
|
-
const output = createOutputWriter();
|
|
53
|
-
const baseUrl = getGuildcoreUrl();
|
|
54
|
-
const client = new GuildAPIClient({ baseUrl });
|
|
55
|
-
try {
|
|
56
|
-
// Get owner_id: use --owner-id option or default to current user
|
|
57
|
-
let ownerId = options.ownerId;
|
|
58
|
-
if (!ownerId) {
|
|
59
|
-
const me = (await client.get('/me'));
|
|
60
|
-
ownerId = me.id;
|
|
61
|
-
}
|
|
62
|
-
// Determine template: use --template option, prompt if interactive, or error
|
|
63
|
-
let template = options.template;
|
|
64
|
-
if (!template) {
|
|
65
|
-
if (isInteractive()) {
|
|
66
|
-
template = await promptForTemplate();
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
69
|
-
output.error('Error: --template is required in non-interactive mode', `Provide a template:\n guild agent create ${name} --template LLM\n\nAvailable templates:\n • LLM - Simple language model agent (recommended)\n • AUTO_MANAGED_STATE - Agent with automatic state management\n • BLANK - Start from scratch`);
|
|
70
|
-
process.exit(1);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
// Normalize template to uppercase for case-insensitive matching
|
|
74
|
-
template = template.toUpperCase();
|
|
75
|
-
// Validate template
|
|
76
|
-
const validTemplates = [
|
|
77
|
-
'LLM',
|
|
78
|
-
'AUTO_MANAGED_STATE',
|
|
79
|
-
'BLANK',
|
|
80
|
-
];
|
|
81
|
-
if (!validTemplates.includes(template)) {
|
|
82
|
-
output.error(`Error: Invalid template '${template}'`, 'Valid templates:\n • LLM\n • AUTO_MANAGED_STATE\n • BLANK');
|
|
83
|
-
process.exit(1);
|
|
84
|
-
}
|
|
85
|
-
const response = await client.post('/agents', {
|
|
86
|
-
name,
|
|
87
|
-
owner_id: ownerId,
|
|
88
|
-
description: options.description || 'No description provided',
|
|
89
|
-
template,
|
|
90
|
-
});
|
|
91
|
-
// By default, poll until agent is ready (unless --no-wait is passed)
|
|
92
|
-
if (options.wait !== false) {
|
|
93
|
-
const pollResult = await pollAgentStatus(response.id, 'READY');
|
|
94
|
-
if (pollResult.success && pollResult.response) {
|
|
95
|
-
// Display the updated response with READY status
|
|
96
|
-
output.data(pollResult.response);
|
|
97
|
-
}
|
|
98
|
-
else {
|
|
99
|
-
// Polling failed or timed out - this is an error
|
|
100
|
-
output.error('Agent initialization failed or timed out', `Check status: guild agent get ${response.id}`);
|
|
101
|
-
output.data(response);
|
|
102
|
-
process.exit(1);
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
else {
|
|
106
|
-
// --no-wait: return immediately without polling
|
|
107
|
-
output.data(response);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
catch (error) {
|
|
111
|
-
const formattedError = handleAxiosError(error);
|
|
112
|
-
// Provide specific error messages based on error code
|
|
113
|
-
if (formattedError.code === ErrorCodes.AUTH_REQUIRED) {
|
|
114
|
-
output.error('Not logged in.', 'Please authenticate first:\n guild auth login');
|
|
115
|
-
}
|
|
116
|
-
else if (formattedError.code === ErrorCodes.CONN_REFUSED) {
|
|
117
|
-
output.error('Cannot connect to Guild servers');
|
|
118
|
-
}
|
|
119
|
-
else if (formattedError.code === ErrorCodes.API_ERROR &&
|
|
120
|
-
formattedError.details.includes('already exists')) {
|
|
121
|
-
output.error(`Agent name '${name}' already exists.`, `Try a different name:\n guild agent create ${name}-v2`);
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
// Generic error with details from server
|
|
125
|
-
output.error(`Failed to create agent: ${formattedError.details}`);
|
|
126
|
-
}
|
|
127
|
-
process.exit(1);
|
|
128
|
-
}
|
|
129
|
-
});
|
|
130
|
-
return cmd;
|
|
131
|
-
}
|
|
132
|
-
//# sourceMappingURL=create.js.map
|