@guildai/cli 0.5.13 → 0.6.1
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/README.md +17 -0
- package/dist/commands/agent/chat.js +31 -31
- package/dist/commands/agent/clone.js +3 -1
- package/dist/commands/agent/code.js +3 -2
- package/dist/commands/agent/fork.js +41 -15
- package/dist/commands/agent/get.js +3 -2
- package/dist/commands/agent/grep.js +61 -31
- package/dist/commands/agent/init.js +1 -1
- package/dist/commands/agent/publish.js +3 -2
- package/dist/commands/agent/pull.js +36 -21
- package/dist/commands/agent/revalidate.js +4 -3
- package/dist/commands/agent/save.js +2 -2
- package/dist/commands/agent/search.js +3 -3
- package/dist/commands/agent/tags/add.js +4 -3
- package/dist/commands/agent/tags/list.js +3 -2
- package/dist/commands/agent/tags/remove.js +4 -3
- package/dist/commands/agent/tags/set.js +3 -2
- package/dist/commands/agent/test.js +8 -12
- package/dist/commands/agent/unpublish.js +3 -2
- package/dist/commands/agent/update.js +9 -8
- package/dist/commands/agent/versions.js +3 -2
- package/dist/commands/agent/workspaces.js +3 -2
- package/dist/commands/auth/login.js +3 -3
- package/dist/commands/chat.js +64 -102
- package/dist/commands/credentials/endpoint-list.d.ts +3 -0
- package/dist/commands/credentials/endpoint-list.js +87 -0
- package/dist/commands/credentials/list.d.ts +3 -0
- package/dist/commands/{container → credentials}/list.js +11 -10
- package/dist/commands/credentials/policy-create.d.ts +3 -0
- package/dist/commands/credentials/policy-create.js +66 -0
- package/dist/commands/credentials/policy-delete.d.ts +3 -0
- package/dist/commands/{container/get.js → credentials/policy-delete.js} +9 -9
- package/dist/commands/credentials/policy-list.d.ts +3 -0
- package/dist/commands/{container-image/list.js → credentials/policy-list.js} +9 -9
- package/dist/commands/credentials/policy-update.d.ts +3 -0
- package/dist/commands/credentials/policy-update.js +66 -0
- package/dist/commands/integration/connect.d.ts +3 -0
- package/dist/commands/integration/connect.js +76 -0
- package/dist/commands/integration/create.d.ts +3 -0
- package/dist/commands/integration/create.js +298 -0
- package/dist/commands/integration/get.d.ts +3 -0
- package/dist/commands/integration/get.js +95 -0
- package/dist/commands/integration/list.d.ts +3 -0
- package/dist/commands/integration/list.js +61 -0
- package/dist/commands/integration/operation/create.d.ts +3 -0
- package/dist/commands/integration/operation/create.js +163 -0
- package/dist/commands/integration/operation/list.d.ts +3 -0
- package/dist/commands/integration/operation/list.js +83 -0
- package/dist/commands/integration/update.d.ts +3 -0
- package/dist/commands/integration/update.js +139 -0
- package/dist/commands/integration/version/build.d.ts +3 -0
- package/dist/commands/integration/version/build.js +86 -0
- package/dist/commands/integration/version/create.d.ts +3 -0
- package/dist/commands/integration/version/create.js +45 -0
- package/dist/commands/integration/version/get.d.ts +3 -0
- package/dist/commands/integration/version/get.js +72 -0
- package/dist/commands/integration/version/list.d.ts +3 -0
- package/dist/commands/integration/version/list.js +44 -0
- package/dist/commands/integration/version/publish.d.ts +3 -0
- package/dist/commands/integration/version/publish.js +79 -0
- package/dist/commands/integration/version/test.d.ts +3 -0
- package/dist/commands/integration/version/test.js +104 -0
- package/dist/commands/trigger/create.js +35 -19
- package/dist/commands/workspace/create.js +10 -4
- package/dist/commands/workspace/select.js +0 -1
- package/dist/index.js +60 -27
- package/dist/lib/agent-helpers.d.ts +8 -0
- package/dist/lib/agent-helpers.js +15 -0
- package/dist/lib/api-types.d.ts +109 -78
- package/dist/lib/auth.d.ts +1 -1
- package/dist/lib/auth.js +10 -6
- package/dist/lib/integration-helpers.d.ts +15 -0
- package/dist/lib/integration-helpers.js +38 -0
- package/dist/lib/output.d.ts +13 -16
- package/dist/lib/output.js +137 -109
- package/dist/lib/session-events-fetch.d.ts +27 -0
- package/dist/lib/session-events-fetch.js +25 -0
- package/dist/lib/session-polling.d.ts +7 -2
- package/dist/lib/session-polling.js +18 -11
- package/dist/lib/session-resume.js +2 -5
- package/dist/lib/table.d.ts +0 -1
- package/dist/lib/table.js +0 -1
- package/dist/mcp/tools.js +6 -12
- package/docs/CLI_WORKFLOW.md +19 -2
- package/docs/skills/agent-dev.md +17 -2
- package/package.json +6 -5
- package/dist/commands/container/destroy.d.ts +0 -3
- package/dist/commands/container/destroy.js +0 -48
- package/dist/commands/container/events.d.ts +0 -3
- package/dist/commands/container/events.js +0 -44
- package/dist/commands/container/exec.d.ts +0 -3
- package/dist/commands/container/exec.js +0 -64
- package/dist/commands/container/get.d.ts +0 -3
- package/dist/commands/container/list.d.ts +0 -3
- package/dist/commands/container-image/create.d.ts +0 -3
- package/dist/commands/container-image/create.js +0 -41
- package/dist/commands/container-image/get.d.ts +0 -3
- package/dist/commands/container-image/get.js +0 -33
- package/dist/commands/container-image/list.d.ts +0 -3
package/dist/lib/auth.js
CHANGED
|
@@ -10,6 +10,7 @@ import { createSpinner } from './progress.js';
|
|
|
10
10
|
import { getGuildcoreUrl } from './config.js';
|
|
11
11
|
import { getIapHeaders } from './iap.js';
|
|
12
12
|
import { brand, warn } from './colors.js';
|
|
13
|
+
import { isInteractive } from './stdin.js';
|
|
13
14
|
const SERVICE_NAME = 'guild-cli';
|
|
14
15
|
/**
|
|
15
16
|
* Get account name for keyring, keyed by host to support multiple backends
|
|
@@ -137,6 +138,7 @@ export async function startDeviceFlow(authUrl = getGuildcoreUrl(), returnUrl, re
|
|
|
137
138
|
* @returns Access token if successful, null if failed/expired
|
|
138
139
|
*/
|
|
139
140
|
export async function pollForToken(authUrl, code, interval) {
|
|
141
|
+
const isTTY = process.stderr.isTTY || false;
|
|
140
142
|
const spinner = createSpinner('Waiting for authorization...');
|
|
141
143
|
spinner.start();
|
|
142
144
|
const maxAttempts = 90; // 3 minutes (90 * 2 seconds)
|
|
@@ -167,7 +169,9 @@ export async function pollForToken(authUrl, code, interval) {
|
|
|
167
169
|
}
|
|
168
170
|
if (error.response?.data?.error === 'authorization_pending' ||
|
|
169
171
|
error.response?.data?.error === 'slow_down') {
|
|
170
|
-
|
|
172
|
+
if (isTTY) {
|
|
173
|
+
spinner.text = `Waiting for authorization... (${attempts}/${maxAttempts})`;
|
|
174
|
+
}
|
|
171
175
|
continue;
|
|
172
176
|
}
|
|
173
177
|
}
|
|
@@ -196,18 +200,18 @@ export function showBetaGuidance() {
|
|
|
196
200
|
* @param returnLabel - Optional friendly label for return button (e.g., "VSCode")
|
|
197
201
|
* @returns true if successful, false otherwise
|
|
198
202
|
*/
|
|
199
|
-
export async function login(returnUrl, returnLabel,
|
|
203
|
+
export async function login(returnUrl, returnLabel, nonInteractive) {
|
|
200
204
|
const authUrl = getGuildcoreUrl();
|
|
201
205
|
try {
|
|
202
206
|
console.log(chalk.bold('\nGuild.ai Authentication'));
|
|
203
207
|
const deviceCode = await startDeviceFlow(authUrl, returnUrl, returnLabel);
|
|
204
|
-
|
|
205
|
-
displayVerificationCode(deviceCode.user_code, deviceCode.verification_uri_complete);
|
|
206
|
-
const skipBrowser = noBrowser || process.stdin.isTTY !== true;
|
|
208
|
+
const skipBrowser = nonInteractive || !isInteractive();
|
|
207
209
|
if (skipBrowser) {
|
|
208
|
-
console.log(
|
|
210
|
+
console.log(`\nVerification code: ${deviceCode.user_code}`);
|
|
211
|
+
console.log(`Open to authenticate: ${deviceCode.verification_uri_complete}\n`);
|
|
209
212
|
}
|
|
210
213
|
else {
|
|
214
|
+
displayVerificationCode(deviceCode.user_code, deviceCode.verification_uri_complete);
|
|
211
215
|
// Wait for user to press Enter before opening browser
|
|
212
216
|
// This gives them time to see and copy the code before browser opens
|
|
213
217
|
// Critical for VSCode integration where browser may open full screen
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { GuildAPIClient } from './api-client.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve a version ID from an integration identifier and optional semver.
|
|
4
|
+
*
|
|
5
|
+
* 1. GET /integrations/<identifier> to resolve the integration
|
|
6
|
+
* 2. GET /integrations/<id>/versions to list versions
|
|
7
|
+
* 3. If semver provided, find matching version_number; otherwise use latest (first)
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveVersionId(client: GuildAPIClient, identifier: string, versionNumber?: string): Promise<string>;
|
|
10
|
+
/**
|
|
11
|
+
* Resolve the latest draft version ID for an integration.
|
|
12
|
+
* Used by the build command where --version is not applicable (drafts have no semver).
|
|
13
|
+
*/
|
|
14
|
+
export declare function resolveLatestDraftId(client: GuildAPIClient, identifier: string): Promise<string>;
|
|
15
|
+
//# sourceMappingURL=integration-helpers.d.ts.map
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a version ID from an integration identifier and optional semver.
|
|
5
|
+
*
|
|
6
|
+
* 1. GET /integrations/<identifier> to resolve the integration
|
|
7
|
+
* 2. GET /integrations/<id>/versions to list versions
|
|
8
|
+
* 3. If semver provided, find matching version_number; otherwise use latest (first)
|
|
9
|
+
*/
|
|
10
|
+
export async function resolveVersionId(client, identifier, versionNumber) {
|
|
11
|
+
const integration = await client.get(`/integrations/${identifier}`);
|
|
12
|
+
const versions = await client.get(`/integrations/${integration.id}/versions?limit=100`);
|
|
13
|
+
if (versions.items.length === 0) {
|
|
14
|
+
throw new Error('No versions found for this integration');
|
|
15
|
+
}
|
|
16
|
+
if (versionNumber) {
|
|
17
|
+
const match = versions.items.find((v) => v.version_number === versionNumber);
|
|
18
|
+
if (!match) {
|
|
19
|
+
throw new Error(`Version ${versionNumber} not found`);
|
|
20
|
+
}
|
|
21
|
+
return match.id;
|
|
22
|
+
}
|
|
23
|
+
return versions.items[0].id;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Resolve the latest draft version ID for an integration.
|
|
27
|
+
* Used by the build command where --version is not applicable (drafts have no semver).
|
|
28
|
+
*/
|
|
29
|
+
export async function resolveLatestDraftId(client, identifier) {
|
|
30
|
+
const integration = await client.get(`/integrations/${identifier}`);
|
|
31
|
+
const versions = await client.get(`/integrations/${integration.id}/versions?limit=100`);
|
|
32
|
+
const draft = versions.items.find((v) => v.version_number === null);
|
|
33
|
+
if (!draft) {
|
|
34
|
+
throw new Error('No draft version found for this integration');
|
|
35
|
+
}
|
|
36
|
+
return draft.id;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=integration-helpers.js.map
|
package/dist/lib/output.d.ts
CHANGED
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { type Spinner } from './progress.js';
|
|
2
|
-
import type { Agent, AgentVersion,
|
|
2
|
+
import type { Agent, AgentVersion, Credentials, CredentialsPolicy, Context, Integration, IntegrationVersion, JobStep, Pagination, Session, Workspace, WorkspaceAgent, Trigger } from './api-types.js';
|
|
3
3
|
/**
|
|
4
4
|
* Format an agent list as a human-readable table.
|
|
5
5
|
* Shared by agent list and agent search commands.
|
|
6
6
|
*/
|
|
7
7
|
export declare function formatAgentTable(agents: Agent[], pagination: Pagination): void;
|
|
8
|
+
/**
|
|
9
|
+
* Format an integration list as a human-readable table.
|
|
10
|
+
* Used by integration list command.
|
|
11
|
+
*/
|
|
12
|
+
export declare function formatIntegrationTable(integrations: Integration[], pagination: Pagination): void;
|
|
13
|
+
/**
|
|
14
|
+
* Format an integration version list as a human-readable table.
|
|
15
|
+
* Used by integration version list command.
|
|
16
|
+
*/
|
|
17
|
+
export declare function formatIntegrationVersionTable(versions: IntegrationVersion[], pagination: Pagination, integrationName: string): void;
|
|
8
18
|
/**
|
|
9
19
|
* Format an agent version list as a human-readable table.
|
|
10
20
|
* Used by agent versions command.
|
|
@@ -35,21 +45,8 @@ export declare function formatSessionTable(sessions: Session[], pagination: Pagi
|
|
|
35
45
|
* Used by trigger list command.
|
|
36
46
|
*/
|
|
37
47
|
export declare function formatTriggerTable(triggers: Trigger[], pagination: Pagination): void;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
* Used by container list command.
|
|
41
|
-
*/
|
|
42
|
-
export declare function formatContainerTable(containers: Container[], pagination: Pagination): void;
|
|
43
|
-
/**
|
|
44
|
-
* Format a container image list as a human-readable table.
|
|
45
|
-
* Used by container-image list command.
|
|
46
|
-
*/
|
|
47
|
-
export declare function formatContainerImageTable(images: ContainerImageListItem[], pagination: Pagination): void;
|
|
48
|
-
/**
|
|
49
|
-
* Format a container event list as a human-readable table.
|
|
50
|
-
* Used by container events command.
|
|
51
|
-
*/
|
|
52
|
-
export declare function formatContainerEventTable(events: ContainerEvent[], pagination: Pagination): void;
|
|
48
|
+
export declare function formatCredentialsTable(credentials: Credentials[], pagination: Pagination): void;
|
|
49
|
+
export declare function formatPoliciesTable(policies: CredentialsPolicy[], pagination: Pagination): void;
|
|
53
50
|
/**
|
|
54
51
|
* Format job steps as a human-readable table.
|
|
55
52
|
* Used by job get command.
|
package/dist/lib/output.js
CHANGED
|
@@ -81,6 +81,100 @@ export function formatAgentTable(agents, pagination) {
|
|
|
81
81
|
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} agents`));
|
|
82
82
|
}
|
|
83
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Format an integration list as a human-readable table.
|
|
86
|
+
* Used by integration list command.
|
|
87
|
+
*/
|
|
88
|
+
export function formatIntegrationTable(integrations, pagination) {
|
|
89
|
+
if (integrations.length === 0) {
|
|
90
|
+
console.log(chalk.dim('No integrations found'));
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const table = new Table({
|
|
94
|
+
columns: [
|
|
95
|
+
{ name: 'name', title: 'NAME', alignment: 'left' },
|
|
96
|
+
{ name: 'description', title: 'DESCRIPTION', alignment: 'left' },
|
|
97
|
+
{ name: 'visibility', title: 'VISIBILITY', alignment: 'left' },
|
|
98
|
+
{ name: 'owner', title: 'OWNER', alignment: 'left', color: 'cyan' },
|
|
99
|
+
{ name: 'updated', title: 'UPDATED', alignment: 'left' },
|
|
100
|
+
],
|
|
101
|
+
});
|
|
102
|
+
integrations.forEach((integration) => {
|
|
103
|
+
table.addRow({
|
|
104
|
+
name: integration.name,
|
|
105
|
+
description: truncate(integration.description || '', 40),
|
|
106
|
+
visibility: integration.is_public ? 'public' : 'internal',
|
|
107
|
+
owner: integration.owner?.name || '',
|
|
108
|
+
updated: integration.updated_at ? formatRelativeTime(integration.updated_at) : '',
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
table.printTable();
|
|
112
|
+
const showing = Math.min(pagination.limit, integrations.length);
|
|
113
|
+
if (pagination.has_more) {
|
|
114
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
115
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} integrations. ` +
|
|
116
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
117
|
+
}
|
|
118
|
+
else if (pagination.total_count > showing) {
|
|
119
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} integrations`));
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Format an integration version list as a human-readable table.
|
|
124
|
+
* Used by integration version list command.
|
|
125
|
+
*/
|
|
126
|
+
export function formatIntegrationVersionTable(versions, pagination, integrationName) {
|
|
127
|
+
if (versions.length === 0) {
|
|
128
|
+
console.log(chalk.dim('No versions found'));
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
console.log(chalk.bold(`Versions for ${integrationName}`));
|
|
132
|
+
console.log();
|
|
133
|
+
const table = new Table({
|
|
134
|
+
columns: [
|
|
135
|
+
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
136
|
+
{ name: 'version', title: 'VERSION', alignment: 'left' },
|
|
137
|
+
{ name: 'author', title: 'AUTHOR', alignment: 'left', color: 'cyan' },
|
|
138
|
+
{ name: 'status', title: 'STATUS', alignment: 'left' },
|
|
139
|
+
{ name: 'published', title: 'PUBLISHED', alignment: 'left' },
|
|
140
|
+
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
141
|
+
],
|
|
142
|
+
});
|
|
143
|
+
versions.forEach((v) => {
|
|
144
|
+
let statusLabel;
|
|
145
|
+
switch (v.validation_status) {
|
|
146
|
+
case 'PASSED':
|
|
147
|
+
statusLabel = chalk.green('Valid');
|
|
148
|
+
break;
|
|
149
|
+
case 'FAILED':
|
|
150
|
+
statusLabel = chalk.red('Failed');
|
|
151
|
+
break;
|
|
152
|
+
case 'RUNNING':
|
|
153
|
+
statusLabel = chalk.yellow('Building');
|
|
154
|
+
break;
|
|
155
|
+
default:
|
|
156
|
+
statusLabel = chalk.dim('—');
|
|
157
|
+
}
|
|
158
|
+
table.addRow({
|
|
159
|
+
id: v.id,
|
|
160
|
+
version: v.version_number || 'Draft',
|
|
161
|
+
author: v.author?.name || '',
|
|
162
|
+
status: statusLabel,
|
|
163
|
+
published: v.published_at ? formatRelativeTime(v.published_at) : chalk.dim('—'),
|
|
164
|
+
created: v.created_at ? formatRelativeTime(v.created_at) : '',
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
table.printTable();
|
|
168
|
+
const showing = Math.min(pagination.limit, versions.length);
|
|
169
|
+
if (pagination.has_more) {
|
|
170
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
171
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} versions. ` +
|
|
172
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
173
|
+
}
|
|
174
|
+
else if (pagination.total_count > showing) {
|
|
175
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} versions`));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
84
178
|
/**
|
|
85
179
|
* Format an agent version list as a human-readable table.
|
|
86
180
|
* Used by agent versions command.
|
|
@@ -313,151 +407,85 @@ export function formatTriggerTable(triggers, pagination) {
|
|
|
313
407
|
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} triggers`));
|
|
314
408
|
}
|
|
315
409
|
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
*/
|
|
320
|
-
export function formatContainerTable(containers, pagination) {
|
|
321
|
-
if (containers.length === 0) {
|
|
322
|
-
console.log(chalk.dim('No containers found'));
|
|
410
|
+
export function formatCredentialsTable(credentials, pagination) {
|
|
411
|
+
if (credentials.length === 0) {
|
|
412
|
+
console.log(chalk.dim('No credentials found'));
|
|
323
413
|
return;
|
|
324
414
|
}
|
|
325
415
|
const table = new Table({
|
|
326
416
|
columns: [
|
|
327
417
|
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
328
|
-
{ name: '
|
|
329
|
-
{ name: '
|
|
330
|
-
{ name: 'tag', title: 'TAG', alignment: 'left' },
|
|
418
|
+
{ name: 'integration', title: 'INTEGRATION', alignment: 'left' },
|
|
419
|
+
{ name: 'creator', title: 'CREATOR', alignment: 'left', color: 'cyan' },
|
|
331
420
|
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
332
421
|
],
|
|
333
422
|
});
|
|
334
|
-
|
|
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) => {
|
|
423
|
+
credentials.forEach((cred) => {
|
|
380
424
|
table.addRow({
|
|
381
|
-
id:
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
public: image.is_public ? chalk.green('yes') : chalk.dim('no'),
|
|
425
|
+
id: cred.id,
|
|
426
|
+
integration: cred.integration.full_name,
|
|
427
|
+
creator: cred.creator.name,
|
|
428
|
+
created: formatRelativeTime(cred.created_at),
|
|
386
429
|
});
|
|
387
430
|
});
|
|
388
431
|
table.printTable();
|
|
389
|
-
const showing = Math.min(pagination.limit,
|
|
432
|
+
const showing = Math.min(pagination.limit, credentials.length);
|
|
390
433
|
if (pagination.has_more) {
|
|
391
434
|
const nextOffset = pagination.offset + pagination.limit;
|
|
392
|
-
console.log(`\nShowing ${showing} of ${pagination.total_count}
|
|
435
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} credentials. ` +
|
|
393
436
|
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
394
437
|
}
|
|
395
438
|
else if (pagination.total_count > showing) {
|
|
396
|
-
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count}
|
|
439
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} credentials`));
|
|
397
440
|
}
|
|
398
441
|
}
|
|
399
|
-
|
|
400
|
-
|
|
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'));
|
|
442
|
+
export function formatPoliciesTable(policies, pagination) {
|
|
443
|
+
if (policies.length === 0) {
|
|
444
|
+
console.log(chalk.dim('No policies found'));
|
|
418
445
|
return;
|
|
419
446
|
}
|
|
420
447
|
const table = new Table({
|
|
421
448
|
columns: [
|
|
422
449
|
{ name: 'id', title: 'ID', alignment: 'left' },
|
|
423
|
-
{ name: '
|
|
424
|
-
{ name: '
|
|
425
|
-
{ name: '
|
|
426
|
-
{ name: '
|
|
450
|
+
{ name: 'decision', title: 'DECISION', alignment: 'left' },
|
|
451
|
+
{ name: 'operations', title: 'OPERATIONS', alignment: 'left' },
|
|
452
|
+
{ name: 'workspaces', title: 'WORKSPACES', alignment: 'left' },
|
|
453
|
+
{ name: 'agents', title: 'AGENTS', alignment: 'left' },
|
|
454
|
+
{ name: 'resources', title: 'RESOURCES', alignment: 'left' },
|
|
427
455
|
{ name: 'created', title: 'CREATED', alignment: 'left' },
|
|
428
456
|
],
|
|
429
457
|
});
|
|
430
|
-
|
|
431
|
-
const
|
|
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
|
-
}
|
|
458
|
+
policies.forEach((policy) => {
|
|
459
|
+
const decisionColor = policy.decision === 'ALLOW' ? chalk.green : chalk.red;
|
|
443
460
|
table.addRow({
|
|
444
|
-
id:
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
461
|
+
id: policy.id,
|
|
462
|
+
decision: decisionColor(policy.decision),
|
|
463
|
+
operations: policy.operations
|
|
464
|
+
? truncate(policy.operations.join(', '), 30)
|
|
465
|
+
: chalk.dim('all'),
|
|
466
|
+
workspaces: policy.workspaces.length > 0
|
|
467
|
+
? truncate(policy.workspaces.map((w) => w.full_name || w.name).join(', '), 20)
|
|
468
|
+
: chalk.dim('all'),
|
|
469
|
+
agents: policy.agents.length > 0
|
|
470
|
+
? truncate(policy.agents.map((a) => a.full_name || a.name).join(', '), 20)
|
|
471
|
+
: chalk.dim('all'),
|
|
472
|
+
resources: policy.resources
|
|
473
|
+
? truncate(Object.entries(policy.resources)
|
|
474
|
+
.map(([k, v]) => `${k}: ${v.join(', ')}`)
|
|
475
|
+
.join('; '), 30)
|
|
476
|
+
: chalk.dim('none'),
|
|
477
|
+
created: formatRelativeTime(policy.created_at),
|
|
450
478
|
});
|
|
451
479
|
});
|
|
452
480
|
table.printTable();
|
|
453
|
-
const showing = Math.min(pagination.limit,
|
|
481
|
+
const showing = Math.min(pagination.limit, policies.length);
|
|
454
482
|
if (pagination.has_more) {
|
|
455
483
|
const nextOffset = pagination.offset + pagination.limit;
|
|
456
|
-
console.log(`\nShowing ${showing} of ${pagination.total_count}
|
|
484
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} policies. ` +
|
|
457
485
|
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
458
486
|
}
|
|
459
487
|
else if (pagination.total_count > showing) {
|
|
460
|
-
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count}
|
|
488
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} policies`));
|
|
461
489
|
}
|
|
462
490
|
}
|
|
463
491
|
/**
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared event/task fetching for session polling.
|
|
3
|
+
*
|
|
4
|
+
* Consolidates the duplicate response parsing that was scattered across
|
|
5
|
+
* chat.tsx, session-polling.ts, and session-resume.ts.
|
|
6
|
+
*/
|
|
7
|
+
import { GuildAPIClient } from './api-client.js';
|
|
8
|
+
import { SessionEvent, SessionTask } from './session-events.js';
|
|
9
|
+
interface FetchOptions {
|
|
10
|
+
/** Only return events after this event ID (server-side cursor). */
|
|
11
|
+
fromId?: string;
|
|
12
|
+
/** Maximum number of events to return. Default 1000. */
|
|
13
|
+
limit?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Fetch session events from the API.
|
|
17
|
+
*
|
|
18
|
+
* Uses from_id cursor so callers only fetch new events
|
|
19
|
+
* instead of re-fetching everything on every poll cycle.
|
|
20
|
+
*/
|
|
21
|
+
export declare function fetchEvents(client: GuildAPIClient, sessionId: string, options?: FetchOptions): Promise<SessionEvent[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Fetch session tasks from the API.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fetchTasks(client: GuildAPIClient, sessionId: string): Promise<SessionTask[]>;
|
|
26
|
+
export {};
|
|
27
|
+
//# sourceMappingURL=session-events-fetch.d.ts.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
/**
|
|
4
|
+
* Fetch session events from the API.
|
|
5
|
+
*
|
|
6
|
+
* Uses from_id cursor so callers only fetch new events
|
|
7
|
+
* instead of re-fetching everything on every poll cycle.
|
|
8
|
+
*/
|
|
9
|
+
export async function fetchEvents(client, sessionId, options = {}) {
|
|
10
|
+
const { fromId, limit = 1000 } = options;
|
|
11
|
+
let url = `/sessions/${sessionId}/events?limit=${limit}`;
|
|
12
|
+
if (fromId) {
|
|
13
|
+
url += `&from_id=${fromId}`;
|
|
14
|
+
}
|
|
15
|
+
const response = await client.get(url);
|
|
16
|
+
return response?.items || [];
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Fetch session tasks from the API.
|
|
20
|
+
*/
|
|
21
|
+
export async function fetchTasks(client, sessionId) {
|
|
22
|
+
const response = await client.get(`/sessions/${sessionId}/tasks?limit=1000`);
|
|
23
|
+
return response?.items || [];
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=session-events-fetch.js.map
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { GuildAPIClient } from './api-client.js';
|
|
2
|
+
export interface PollResult {
|
|
3
|
+
response: string | null;
|
|
4
|
+
/** Last event ID seen — pass as `afterEventId` on next call. */
|
|
5
|
+
lastEventId: string | undefined;
|
|
6
|
+
}
|
|
2
7
|
/**
|
|
3
|
-
* Poll for agent response
|
|
8
|
+
* Poll for agent response using from_id cursor.
|
|
4
9
|
*
|
|
5
10
|
* Handles both multi-turn agents (which emit agent_notification_message)
|
|
6
11
|
* and one-shot agents (which may only emit runtime_done with output content).
|
|
@@ -10,5 +15,5 @@ import { GuildAPIClient } from './api-client.js';
|
|
|
10
15
|
* 2. runtime_done from agent tasks — fallback for one-shot agents
|
|
11
16
|
* 3. runtime_error from agent tasks — fail fast
|
|
12
17
|
*/
|
|
13
|
-
export declare function pollForResponse(client: GuildAPIClient, sessionId: string,
|
|
18
|
+
export declare function pollForResponse(client: GuildAPIClient, sessionId: string, afterEventId: string | undefined, maxWaitTime?: number): Promise<PollResult>;
|
|
14
19
|
//# sourceMappingURL=session-polling.d.ts.map
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Copyright 2026 Guild.ai
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import { isDebugMode } from './errors.js';
|
|
3
|
+
import { debug, isDebugMode } from './errors.js';
|
|
4
|
+
import { fetchEvents } from './session-events-fetch.js';
|
|
4
5
|
/**
|
|
5
|
-
* Poll for agent response
|
|
6
|
+
* Poll for agent response using from_id cursor.
|
|
6
7
|
*
|
|
7
8
|
* Handles both multi-turn agents (which emit agent_notification_message)
|
|
8
9
|
* and one-shot agents (which may only emit runtime_done with output content).
|
|
@@ -12,16 +13,16 @@ import { isDebugMode } from './errors.js';
|
|
|
12
13
|
* 2. runtime_done from agent tasks — fallback for one-shot agents
|
|
13
14
|
* 3. runtime_error from agent tasks — fail fast
|
|
14
15
|
*/
|
|
15
|
-
export async function pollForResponse(client, sessionId,
|
|
16
|
+
export async function pollForResponse(client, sessionId, afterEventId, maxWaitTime = 60000) {
|
|
16
17
|
const startTime = Date.now();
|
|
18
|
+
let fromId = afterEventId;
|
|
17
19
|
while (Date.now() - startTime < maxWaitTime) {
|
|
18
|
-
const
|
|
19
|
-
const events = response?.items || [];
|
|
20
|
+
const events = await fetchEvents(client, sessionId, { fromId });
|
|
20
21
|
let lastAgentRuntimeDone = null;
|
|
21
|
-
for (
|
|
22
|
-
|
|
22
|
+
for (const event of events) {
|
|
23
|
+
debug(`pollForResponse event: ${event.type}`);
|
|
23
24
|
if (event.type === 'agent_notification_message') {
|
|
24
|
-
return event.content.data;
|
|
25
|
+
return { response: event.content.data, lastEventId: event.id };
|
|
25
26
|
}
|
|
26
27
|
if (event.type === 'runtime_done' &&
|
|
27
28
|
event.content !== undefined &&
|
|
@@ -30,17 +31,23 @@ export async function pollForResponse(client, sessionId, afterEventCount, maxWai
|
|
|
30
31
|
lastAgentRuntimeDone = JSON.stringify(event.content);
|
|
31
32
|
}
|
|
32
33
|
if (event.type === 'runtime_error' && event.task && 'agent' in event.task) {
|
|
33
|
-
return
|
|
34
|
+
return {
|
|
35
|
+
response: JSON.stringify({ error: event.content }),
|
|
36
|
+
lastEventId: event.id,
|
|
37
|
+
};
|
|
34
38
|
}
|
|
35
39
|
if (event.type === 'agent_console' && isDebugMode()) {
|
|
36
40
|
process.stderr.write(`[console.${event.level}] ${event.content}\n`);
|
|
37
41
|
}
|
|
38
42
|
}
|
|
43
|
+
if (events.length > 0) {
|
|
44
|
+
fromId = events[events.length - 1].id;
|
|
45
|
+
}
|
|
39
46
|
if (lastAgentRuntimeDone !== null) {
|
|
40
|
-
return lastAgentRuntimeDone;
|
|
47
|
+
return { response: lastAgentRuntimeDone, lastEventId: fromId };
|
|
41
48
|
}
|
|
42
49
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
43
50
|
}
|
|
44
|
-
return null;
|
|
51
|
+
return { response: null, lastEventId: fromId };
|
|
45
52
|
}
|
|
46
53
|
//# sourceMappingURL=session-polling.js.map
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import chalk from 'chalk';
|
|
8
8
|
import { marked } from 'marked';
|
|
9
9
|
import { markedTerminal } from 'marked-terminal';
|
|
10
|
+
import { fetchEvents } from './session-events-fetch.js';
|
|
10
11
|
import { brand, code as codeColor } from './colors.js';
|
|
11
12
|
// Configure marked for terminal rendering (same config as chat.tsx)
|
|
12
13
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -37,11 +38,7 @@ export function printResumeHint(sessionId, command) {
|
|
|
37
38
|
* Fetch all events for a session from the API.
|
|
38
39
|
*/
|
|
39
40
|
export async function fetchSessionEvents(client, sessionId) {
|
|
40
|
-
|
|
41
|
-
const events = (Array.isArray(response)
|
|
42
|
-
? response
|
|
43
|
-
: response?.items || []);
|
|
44
|
-
return events;
|
|
41
|
+
return fetchEvents(client, sessionId);
|
|
45
42
|
}
|
|
46
43
|
/**
|
|
47
44
|
* Fetch an existing session by ID.
|
package/dist/lib/table.d.ts
CHANGED
package/dist/lib/table.js
CHANGED
|
@@ -4,7 +4,6 @@ import chalk from 'chalk';
|
|
|
4
4
|
import stringWidth from 'string-width';
|
|
5
5
|
/**
|
|
6
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
7
|
*/
|
|
9
8
|
export class Table {
|
|
10
9
|
columns;
|