@guildai/cli 0.5.12 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/agent/clone.js +3 -1
- package/dist/commands/agent/code.js +3 -2
- package/dist/commands/agent/fork.js +41 -17
- package/dist/commands/agent/get.js +3 -2
- package/dist/commands/agent/grep.js +61 -31
- package/dist/commands/agent/init.js +1 -3
- package/dist/commands/agent/publish.js +3 -2
- package/dist/commands/agent/revalidate.js +4 -3
- 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/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/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/trigger/create.js +35 -19
- package/dist/commands/workspace/select.js +28 -33
- package/dist/index.js +22 -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 +52 -78
- package/dist/lib/auth.js +7 -4
- package/dist/lib/output.d.ts +3 -16
- package/dist/lib/output.js +43 -109
- package/dist/lib/stdin.d.ts +4 -0
- package/dist/lib/stdin.js +6 -0
- package/dist/mcp/tools.js +1 -1
- package/docs/CLI_WORKFLOW.md +4 -2
- package/docs/skills/agent-dev.md +61 -34
- package/package.json +4 -3
- 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
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import chalk from 'chalk';
|
|
5
|
+
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
6
|
+
import { getAuthToken } from '../../lib/auth.js';
|
|
7
|
+
import { handleAxiosError } from '../../lib/errors.js';
|
|
8
|
+
import { getOutputMode } from '../../lib/output-mode.js';
|
|
9
|
+
import { createOutputWriter } from '../../lib/output.js';
|
|
10
|
+
import { Table } from '../../lib/table.js';
|
|
11
|
+
export function createCredentialsEndpointListCommand() {
|
|
12
|
+
const cmd = new Command('list');
|
|
13
|
+
cmd
|
|
14
|
+
.description('List endpoints for a credential')
|
|
15
|
+
.argument('<credential-id>', 'Credential ID')
|
|
16
|
+
.option('--include-previous-versions', 'Include endpoints from previous versions')
|
|
17
|
+
.option('--search <query>', 'Search by operation name')
|
|
18
|
+
.option('--limit <number>', 'Number of results to return', '20')
|
|
19
|
+
.option('--offset <number>', 'Offset for pagination', '0')
|
|
20
|
+
.action(async (credentialId, options) => {
|
|
21
|
+
const output = createOutputWriter();
|
|
22
|
+
try {
|
|
23
|
+
const token = await getAuthToken();
|
|
24
|
+
if (!token) {
|
|
25
|
+
output.error('Not authenticated. Run: guild auth login');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const client = new GuildAPIClient();
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
params.append('limit', options.limit);
|
|
31
|
+
params.append('offset', options.offset);
|
|
32
|
+
if (options.includePreviousVersions) {
|
|
33
|
+
params.append('include_previous_versions', 'true');
|
|
34
|
+
}
|
|
35
|
+
if (options.search) {
|
|
36
|
+
params.append('search', options.search);
|
|
37
|
+
}
|
|
38
|
+
const response = await client.get(`/credentials/${credentialId}/endpoints/new?${params.toString()}`);
|
|
39
|
+
if (getOutputMode() === 'json') {
|
|
40
|
+
console.log(JSON.stringify(response, null, 2));
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
formatEndpointsTable(response.items, response.pagination);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
const formattedError = handleAxiosError(error);
|
|
48
|
+
output.error(formattedError.details);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
return cmd;
|
|
53
|
+
}
|
|
54
|
+
function formatEndpointsTable(endpoints, pagination) {
|
|
55
|
+
if (endpoints.length === 0) {
|
|
56
|
+
console.log(chalk.dim('No endpoints found'));
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const table = new Table({
|
|
60
|
+
columns: [
|
|
61
|
+
{ name: 'operation', title: 'OPERATION', alignment: 'left' },
|
|
62
|
+
{ name: 'method', title: 'METHOD', alignment: 'left' },
|
|
63
|
+
{ name: 'path', title: 'PATH', alignment: 'left' },
|
|
64
|
+
{ name: 'tags', title: 'TAGS', alignment: 'left' },
|
|
65
|
+
],
|
|
66
|
+
});
|
|
67
|
+
endpoints.forEach((ep) => {
|
|
68
|
+
const methodColor = ep.method === 'DELETE' ? chalk.red : chalk.green;
|
|
69
|
+
table.addRow({
|
|
70
|
+
operation: ep.operation,
|
|
71
|
+
method: methodColor(ep.method),
|
|
72
|
+
path: ep.path,
|
|
73
|
+
tags: ep.tags?.join(', ') || '',
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
table.printTable();
|
|
77
|
+
const showing = Math.min(pagination.limit, endpoints.length);
|
|
78
|
+
if (pagination.has_more) {
|
|
79
|
+
const nextOffset = pagination.offset + pagination.limit;
|
|
80
|
+
console.log(`\nShowing ${showing} of ${pagination.total_count} endpoints. ` +
|
|
81
|
+
chalk.dim(`Use --offset ${nextOffset} to see more.`));
|
|
82
|
+
}
|
|
83
|
+
else if (pagination.total_count > showing) {
|
|
84
|
+
console.log(chalk.dim(`\nShowing ${showing} of ${pagination.total_count} endpoints`));
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=endpoint-list.js.map
|
|
@@ -5,13 +5,13 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
7
|
import { getOutputMode } from '../../lib/output-mode.js';
|
|
8
|
-
import { createOutputWriter,
|
|
9
|
-
export function
|
|
8
|
+
import { createOutputWriter, formatCredentialsTable } from '../../lib/output.js';
|
|
9
|
+
export function createCredentialsListCommand() {
|
|
10
10
|
const cmd = new Command('list');
|
|
11
11
|
cmd
|
|
12
|
-
.description('List
|
|
13
|
-
.requiredOption('--
|
|
14
|
-
.option('--
|
|
12
|
+
.description('List credentials for an account')
|
|
13
|
+
.requiredOption('--owner <account>', 'Account name or ID')
|
|
14
|
+
.option('--search <query>', 'Filter by integration name')
|
|
15
15
|
.option('--limit <number>', 'Number of results to return', '20')
|
|
16
16
|
.option('--offset <number>', 'Offset for pagination', '0')
|
|
17
17
|
.action(async (options) => {
|
|
@@ -23,23 +23,24 @@ export function createContainerListCommand() {
|
|
|
23
23
|
process.exit(1);
|
|
24
24
|
}
|
|
25
25
|
const client = new GuildAPIClient();
|
|
26
|
+
const accountId = options.owner;
|
|
26
27
|
const params = new URLSearchParams();
|
|
27
28
|
params.append('limit', options.limit);
|
|
28
29
|
params.append('offset', options.offset);
|
|
29
|
-
if (options.
|
|
30
|
-
params.append('
|
|
30
|
+
if (options.search) {
|
|
31
|
+
params.append('search', options.search);
|
|
31
32
|
}
|
|
32
|
-
const response = await client.get(`/accounts/${
|
|
33
|
+
const response = await client.get(`/accounts/${accountId}/credentials?${params.toString()}`);
|
|
33
34
|
if (getOutputMode() === 'json') {
|
|
34
35
|
console.log(JSON.stringify(response, null, 2));
|
|
35
36
|
}
|
|
36
37
|
else {
|
|
37
|
-
|
|
38
|
+
formatCredentialsTable(response.items, response.pagination);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
catch (error) {
|
|
41
42
|
const formattedError = handleAxiosError(error);
|
|
42
|
-
output.error(
|
|
43
|
+
output.error(formattedError.details);
|
|
43
44
|
process.exit(1);
|
|
44
45
|
}
|
|
45
46
|
});
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
|
+
import { getAuthToken } from '../../lib/auth.js';
|
|
6
|
+
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
|
+
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
+
export function createCredentialsPolicyCreateCommand() {
|
|
9
|
+
const cmd = new Command('create');
|
|
10
|
+
cmd
|
|
11
|
+
.description('Create a policy for a credential')
|
|
12
|
+
.argument('<credential-id>', 'Credential ID')
|
|
13
|
+
.requiredOption('--decision <decision>', 'ALLOW or DENY')
|
|
14
|
+
.option('--operations <ops>', 'Comma-separated operation names')
|
|
15
|
+
.option('--workspaces <ids-or-names>', 'Comma-separated workspace IDs or names')
|
|
16
|
+
.option('--agents <ids-or-names>', 'Comma-separated agent IDs or names')
|
|
17
|
+
.option('--resources <json>', 'Resource restrictions as JSON')
|
|
18
|
+
.action(async (credentialId, options) => {
|
|
19
|
+
const output = createOutputWriter();
|
|
20
|
+
try {
|
|
21
|
+
const token = await getAuthToken();
|
|
22
|
+
if (!token) {
|
|
23
|
+
output.error('Not authenticated. Run: guild auth login');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const decision = options.decision.toUpperCase();
|
|
27
|
+
if (decision !== 'ALLOW' && decision !== 'DENY') {
|
|
28
|
+
output.error('--decision must be ALLOW or DENY');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const body = {
|
|
32
|
+
decision,
|
|
33
|
+
};
|
|
34
|
+
if (options.operations) {
|
|
35
|
+
body.operations = options.operations.split(',').map((s) => s.trim());
|
|
36
|
+
}
|
|
37
|
+
if (options.workspaces) {
|
|
38
|
+
body.workspace_ids_or_names = options.workspaces
|
|
39
|
+
.split(',')
|
|
40
|
+
.map((s) => s.trim());
|
|
41
|
+
}
|
|
42
|
+
if (options.agents) {
|
|
43
|
+
body.agent_ids_or_names = options.agents.split(',').map((s) => s.trim());
|
|
44
|
+
}
|
|
45
|
+
if (options.resources) {
|
|
46
|
+
try {
|
|
47
|
+
body.resources = JSON.parse(options.resources);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
output.error('--resources must be valid JSON');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const client = new GuildAPIClient();
|
|
55
|
+
const response = await client.post(`/credentials/${credentialId}/policies`, body);
|
|
56
|
+
output.data(response);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const formattedError = handleAxiosError(error);
|
|
60
|
+
output.error(formattedError.details);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return cmd;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=policy-create.js.map
|
|
@@ -5,12 +5,12 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
7
|
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
-
export function
|
|
9
|
-
const cmd = new Command('
|
|
8
|
+
export function createCredentialsPolicyDeleteCommand() {
|
|
9
|
+
const cmd = new Command('delete');
|
|
10
10
|
cmd
|
|
11
|
-
.description('
|
|
12
|
-
.argument('<
|
|
13
|
-
.action(async (
|
|
11
|
+
.description('Delete a credential policy')
|
|
12
|
+
.argument('<policy-id>', 'Policy ID')
|
|
13
|
+
.action(async (policyId) => {
|
|
14
14
|
const output = createOutputWriter();
|
|
15
15
|
try {
|
|
16
16
|
const token = await getAuthToken();
|
|
@@ -19,15 +19,15 @@ export function createContainerGetCommand() {
|
|
|
19
19
|
process.exit(1);
|
|
20
20
|
}
|
|
21
21
|
const client = new GuildAPIClient();
|
|
22
|
-
|
|
23
|
-
output.
|
|
22
|
+
await client.delete(`/credentials/policies/${policyId}`);
|
|
23
|
+
output.success(`Policy ${policyId} deleted`);
|
|
24
24
|
}
|
|
25
25
|
catch (error) {
|
|
26
26
|
const formattedError = handleAxiosError(error);
|
|
27
|
-
output.error(
|
|
27
|
+
output.error(formattedError.details);
|
|
28
28
|
process.exit(1);
|
|
29
29
|
}
|
|
30
30
|
});
|
|
31
31
|
return cmd;
|
|
32
32
|
}
|
|
33
|
-
//# sourceMappingURL=
|
|
33
|
+
//# sourceMappingURL=policy-delete.js.map
|
|
@@ -5,15 +5,15 @@ import { GuildAPIClient } from '../../lib/api-client.js';
|
|
|
5
5
|
import { getAuthToken } from '../../lib/auth.js';
|
|
6
6
|
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
7
|
import { getOutputMode } from '../../lib/output-mode.js';
|
|
8
|
-
import { createOutputWriter,
|
|
9
|
-
export function
|
|
8
|
+
import { createOutputWriter, formatPoliciesTable } from '../../lib/output.js';
|
|
9
|
+
export function createCredentialsPolicyListCommand() {
|
|
10
10
|
const cmd = new Command('list');
|
|
11
11
|
cmd
|
|
12
|
-
.description('List
|
|
13
|
-
.
|
|
12
|
+
.description('List policies for a credential')
|
|
13
|
+
.argument('<credential-id>', 'Credential ID')
|
|
14
14
|
.option('--limit <number>', 'Number of results to return', '20')
|
|
15
15
|
.option('--offset <number>', 'Offset for pagination', '0')
|
|
16
|
-
.action(async (options) => {
|
|
16
|
+
.action(async (credentialId, options) => {
|
|
17
17
|
const output = createOutputWriter();
|
|
18
18
|
try {
|
|
19
19
|
const token = await getAuthToken();
|
|
@@ -25,20 +25,20 @@ export function createContainerImageListCommand() {
|
|
|
25
25
|
const params = new URLSearchParams();
|
|
26
26
|
params.append('limit', options.limit);
|
|
27
27
|
params.append('offset', options.offset);
|
|
28
|
-
const response = await client.get(`/
|
|
28
|
+
const response = await client.get(`/credentials/${credentialId}/policies?${params.toString()}`);
|
|
29
29
|
if (getOutputMode() === 'json') {
|
|
30
30
|
console.log(JSON.stringify(response, null, 2));
|
|
31
31
|
}
|
|
32
32
|
else {
|
|
33
|
-
|
|
33
|
+
formatPoliciesTable(response.items, response.pagination);
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
catch (error) {
|
|
37
37
|
const formattedError = handleAxiosError(error);
|
|
38
|
-
output.error(
|
|
38
|
+
output.error(formattedError.details);
|
|
39
39
|
process.exit(1);
|
|
40
40
|
}
|
|
41
41
|
});
|
|
42
42
|
return cmd;
|
|
43
43
|
}
|
|
44
|
-
//# sourceMappingURL=list.js.map
|
|
44
|
+
//# sourceMappingURL=policy-list.js.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Copyright 2026 Guild.ai
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
5
|
+
import { getAuthToken } from '../../lib/auth.js';
|
|
6
|
+
import { handleAxiosError } from '../../lib/errors.js';
|
|
7
|
+
import { createOutputWriter } from '../../lib/output.js';
|
|
8
|
+
export function createCredentialsPolicyUpdateCommand() {
|
|
9
|
+
const cmd = new Command('update');
|
|
10
|
+
cmd
|
|
11
|
+
.description('Update a credential policy')
|
|
12
|
+
.argument('<policy-id>', 'Policy ID')
|
|
13
|
+
.requiredOption('--decision <decision>', 'ALLOW or DENY')
|
|
14
|
+
.option('--operations <ops>', 'Comma-separated operation names')
|
|
15
|
+
.option('--workspaces <ids-or-names>', 'Comma-separated workspace IDs or names')
|
|
16
|
+
.option('--agents <ids-or-names>', 'Comma-separated agent IDs or names')
|
|
17
|
+
.option('--resources <json>', 'Resource restrictions as JSON')
|
|
18
|
+
.action(async (policyId, options) => {
|
|
19
|
+
const output = createOutputWriter();
|
|
20
|
+
try {
|
|
21
|
+
const token = await getAuthToken();
|
|
22
|
+
if (!token) {
|
|
23
|
+
output.error('Not authenticated. Run: guild auth login');
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|
|
26
|
+
const decision = options.decision.toUpperCase();
|
|
27
|
+
if (decision !== 'ALLOW' && decision !== 'DENY') {
|
|
28
|
+
output.error('--decision must be ALLOW or DENY');
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
const body = {
|
|
32
|
+
decision,
|
|
33
|
+
};
|
|
34
|
+
if (options.operations) {
|
|
35
|
+
body.operations = options.operations.split(',').map((s) => s.trim());
|
|
36
|
+
}
|
|
37
|
+
if (options.workspaces) {
|
|
38
|
+
body.workspace_ids_or_names = options.workspaces
|
|
39
|
+
.split(',')
|
|
40
|
+
.map((s) => s.trim());
|
|
41
|
+
}
|
|
42
|
+
if (options.agents) {
|
|
43
|
+
body.agent_ids_or_names = options.agents.split(',').map((s) => s.trim());
|
|
44
|
+
}
|
|
45
|
+
if (options.resources) {
|
|
46
|
+
try {
|
|
47
|
+
body.resources = JSON.parse(options.resources);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
output.error('--resources must be valid JSON');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
const client = new GuildAPIClient();
|
|
55
|
+
const response = await client.put(`/credentials/policies/${policyId}`, body);
|
|
56
|
+
output.data(response);
|
|
57
|
+
}
|
|
58
|
+
catch (error) {
|
|
59
|
+
const formattedError = handleAxiosError(error);
|
|
60
|
+
output.error(formattedError.details);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
return cmd;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=policy-update.js.map
|
|
@@ -6,7 +6,7 @@ import { getAuthToken } from '../../lib/auth.js';
|
|
|
6
6
|
import { getWorkspaceId } from '../../lib/guild-config.js';
|
|
7
7
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
8
8
|
import { createOutputWriter } from '../../lib/output.js';
|
|
9
|
-
import {
|
|
9
|
+
import { TIME_TRIGGER_FREQUENCIES, } from '../../lib/api-types.js';
|
|
10
10
|
export function createTriggerCreateCommand() {
|
|
11
11
|
const cmd = new Command('create');
|
|
12
12
|
cmd
|
|
@@ -15,7 +15,7 @@ export function createTriggerCreateCommand() {
|
|
|
15
15
|
.requiredOption('--type <type>', 'Trigger type: webhook or time')
|
|
16
16
|
.requiredOption('--agent <identifier>', 'Agent identifier (e.g., owner/agent-name)')
|
|
17
17
|
// Webhook options
|
|
18
|
-
.option('--
|
|
18
|
+
.option('--integration <name>', 'Integration name for webhook triggers (e.g., github, slack, jira)')
|
|
19
19
|
.option('--event <event>', 'Event type (e.g., app_mention, issues)')
|
|
20
20
|
.option('--action <action>', 'Event action (e.g., opened, created)')
|
|
21
21
|
.option('--service-config <json>', 'Service-specific config as JSON')
|
|
@@ -29,17 +29,26 @@ export function createTriggerCreateCommand() {
|
|
|
29
29
|
.action(async (options) => {
|
|
30
30
|
const output = createOutputWriter();
|
|
31
31
|
try {
|
|
32
|
-
|
|
33
|
-
if (!token) {
|
|
34
|
-
output.error('Not authenticated. Run: guild auth login');
|
|
35
|
-
process.exit(1);
|
|
36
|
-
}
|
|
37
|
-
// Validate trigger type
|
|
32
|
+
// Validate trigger type before auth (fail fast on bad input)
|
|
38
33
|
const triggerType = options.type.toLowerCase();
|
|
39
34
|
if (triggerType !== 'webhook' && triggerType !== 'time') {
|
|
40
35
|
output.error('--type must be "webhook" or "time"');
|
|
41
36
|
process.exit(1);
|
|
42
37
|
}
|
|
38
|
+
// Validate type-specific required options before auth
|
|
39
|
+
if (triggerType === 'webhook' && !options.integration) {
|
|
40
|
+
output.error('--integration is required for webhook triggers (e.g., --integration github)');
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
if (triggerType === 'time' && !options.frequency) {
|
|
44
|
+
output.error(`--frequency is required for time triggers. Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const token = await getAuthToken();
|
|
48
|
+
if (!token) {
|
|
49
|
+
output.error('Not authenticated. Run: guild auth login');
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
43
52
|
// Resolve workspace
|
|
44
53
|
let workspaceId = options.workspace;
|
|
45
54
|
if (!workspaceId) {
|
|
@@ -63,20 +72,31 @@ export function createTriggerCreateCommand() {
|
|
|
63
72
|
// Build request body based on trigger type
|
|
64
73
|
let body;
|
|
65
74
|
if (triggerType === 'webhook') {
|
|
66
|
-
//
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
// Fetch workspace details to get the owner account ID
|
|
76
|
+
const workspace = await client.get(`/workspaces/${workspaceId}`);
|
|
77
|
+
if (!workspace.owner) {
|
|
78
|
+
output.error('Could not resolve workspace owner');
|
|
69
79
|
process.exit(1);
|
|
70
80
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
81
|
+
// Fetch integrations with webhook configs for this account
|
|
82
|
+
const integrations = await client.fetchAll(`/accounts/${workspace.owner.id}/integrations?has_webhooks_only=true`);
|
|
83
|
+
// Match by integration name (case-insensitive)
|
|
84
|
+
const integrationName = options.integration.toLowerCase();
|
|
85
|
+
const integration = integrations.find((i) => i.name.toLowerCase() === integrationName ||
|
|
86
|
+
i.full_name.toLowerCase() === integrationName);
|
|
87
|
+
if (!integration) {
|
|
88
|
+
const available = integrations.map((i) => i.name).join(', ');
|
|
89
|
+
output.error(`Integration "${options.integration}" not found.${available ? ` Available: ${available}` : ' No webhook integrations configured.'}`);
|
|
90
|
+
process.exit(1);
|
|
91
|
+
}
|
|
92
|
+
if (!integration.webhook_config) {
|
|
93
|
+
output.error(`Integration "${integration.name}" does not have webhooks configured`);
|
|
74
94
|
process.exit(1);
|
|
75
95
|
}
|
|
76
96
|
body = {
|
|
77
97
|
type: 'webhook',
|
|
78
|
-
service: service,
|
|
79
98
|
workspace_agent_id: workspaceAgent.id,
|
|
99
|
+
webhook_config_id: integration.webhook_config.id,
|
|
80
100
|
};
|
|
81
101
|
if (options.event) {
|
|
82
102
|
body.event_type = options.event;
|
|
@@ -96,10 +116,6 @@ export function createTriggerCreateCommand() {
|
|
|
96
116
|
}
|
|
97
117
|
else {
|
|
98
118
|
// Time trigger
|
|
99
|
-
if (!options.frequency) {
|
|
100
|
-
output.error(`--frequency is required for time triggers. Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
|
|
101
|
-
process.exit(1);
|
|
102
|
-
}
|
|
103
119
|
const frequency = options.frequency.toUpperCase();
|
|
104
120
|
if (!TIME_TRIGGER_FREQUENCIES.includes(frequency)) {
|
|
105
121
|
output.error(`Invalid frequency "${options.frequency}". Valid: ${TIME_TRIGGER_FREQUENCIES.join(', ')}`);
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
import { Command } from 'commander';
|
|
4
4
|
import * as fs from 'fs/promises';
|
|
5
|
-
import
|
|
5
|
+
import search from '@inquirer/search';
|
|
6
6
|
import { GuildAPIClient } from '../../lib/api-client.js';
|
|
7
7
|
import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
|
|
8
8
|
import { createOutputWriter } from '../../lib/output.js';
|
|
9
|
+
import { isInteractive } from '../../lib/stdin.js';
|
|
9
10
|
import { isAgentDirectory, loadLocalConfig, getLocalConfigPath, getWorkspaceId, saveGlobalConfig, } from '../../lib/guild-config.js';
|
|
10
11
|
/**
|
|
11
12
|
* Format workspace for display with owner name.
|
|
@@ -68,44 +69,38 @@ export function createWorkspaceSelectCommand() {
|
|
|
68
69
|
}
|
|
69
70
|
return;
|
|
70
71
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
72
|
+
if (!isInteractive()) {
|
|
73
|
+
output.error('Interactive mode requires a terminal.', 'Provide a workspace argument:\n guild workspace select <name|id>');
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
// Interactive mode: fetch all workspaces across all pages
|
|
77
|
+
const workspaces = await client.fetchAll('/me/workspaces?filter=all');
|
|
78
|
+
if (workspaces.length === 0) {
|
|
74
79
|
output.error('No workspaces found.', 'Create a workspace first:\n guild workspace create <name>');
|
|
75
80
|
process.exit(1);
|
|
76
81
|
}
|
|
77
82
|
// Resolve the currently selected workspace (if any)
|
|
78
83
|
const current = await getWorkspaceId();
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
84
|
+
const currentId = current?.workspaceId;
|
|
85
|
+
// Interactive searchable selection
|
|
86
|
+
const selectedId = await search({
|
|
87
|
+
message: 'Select a workspace (type to filter)',
|
|
88
|
+
pageSize: 15,
|
|
89
|
+
source: (input) => {
|
|
90
|
+
const term = input?.toLowerCase() ?? '';
|
|
91
|
+
const filtered = term
|
|
92
|
+
? workspaces.filter((w) => w.name.toLowerCase().includes(term) ||
|
|
93
|
+
w.full_name?.toLowerCase().includes(term) ||
|
|
94
|
+
w.owner?.name.toLowerCase().includes(term))
|
|
95
|
+
: workspaces;
|
|
96
|
+
return filtered.map((w) => ({
|
|
97
|
+
name: formatWorkspaceDisplay(w) + (w.id === currentId ? ' (current)' : ''),
|
|
98
|
+
value: w.id,
|
|
99
|
+
short: w.name,
|
|
100
|
+
}));
|
|
101
|
+
},
|
|
96
102
|
});
|
|
97
|
-
|
|
98
|
-
// Empty input keeps current selection
|
|
99
|
-
if (answer.trim() === '' && currentIndex >= 0) {
|
|
100
|
-
console.log('Workspace unchanged.');
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const selection = parseInt(answer.trim(), 10);
|
|
104
|
-
if (isNaN(selection) || selection < 1 || selection > workspaces.items.length) {
|
|
105
|
-
output.error('Invalid selection');
|
|
106
|
-
process.exit(1);
|
|
107
|
-
}
|
|
108
|
-
const selectedWorkspace = workspaces.items[selection - 1];
|
|
103
|
+
const selectedWorkspace = workspaces.find((w) => w.id === selectedId);
|
|
109
104
|
const target = await saveWorkspaceConfig(selectedWorkspace.id, selectedWorkspace.name);
|
|
110
105
|
if (target === 'local') {
|
|
111
106
|
output.success(`Workspace set for this agent: ${formatWorkspaceDisplay(selectedWorkspace)}`);
|
package/dist/index.js
CHANGED
|
@@ -59,27 +59,24 @@ import { createSessionEventsCommand } from './commands/session/events.js';
|
|
|
59
59
|
import { createSessionTasksCommand } from './commands/session/tasks.js';
|
|
60
60
|
import { createSessionCreateCommand } from './commands/session/create.js';
|
|
61
61
|
import { createSessionSendCommand } from './commands/session/send.js';
|
|
62
|
-
import { createContainerGetCommand } from './commands/container/get.js';
|
|
63
|
-
import { createContainerListCommand } from './commands/container/list.js';
|
|
64
|
-
import { createContainerEventsCommand } from './commands/container/events.js';
|
|
65
|
-
import { createContainerExecCommand } from './commands/container/exec.js';
|
|
66
|
-
import { createContainerDestroyCommand } from './commands/container/destroy.js';
|
|
67
|
-
import { createContainerImageListCommand } from './commands/container-image/list.js';
|
|
68
|
-
import { createContainerImageGetCommand } from './commands/container-image/get.js';
|
|
69
|
-
import { createContainerImageCreateCommand } from './commands/container-image/create.js';
|
|
70
62
|
import { createJobGetCommand } from './commands/job/get.js';
|
|
71
63
|
import { createJobStepGetCommand } from './commands/job/step-get.js';
|
|
72
64
|
import { createConfigListCommand } from './commands/config/list.js';
|
|
73
65
|
import { createConfigGetCommand } from './commands/config/get.js';
|
|
74
66
|
import { createConfigSetCommand } from './commands/config/set.js';
|
|
75
67
|
import { createConfigPathCommand } from './commands/config/path.js';
|
|
68
|
+
import { createCredentialsEndpointListCommand } from './commands/credentials/endpoint-list.js';
|
|
69
|
+
import { createCredentialsListCommand } from './commands/credentials/list.js';
|
|
70
|
+
import { createCredentialsPolicyCreateCommand } from './commands/credentials/policy-create.js';
|
|
71
|
+
import { createCredentialsPolicyDeleteCommand } from './commands/credentials/policy-delete.js';
|
|
72
|
+
import { createCredentialsPolicyListCommand } from './commands/credentials/policy-list.js';
|
|
73
|
+
import { createCredentialsPolicyUpdateCommand } from './commands/credentials/policy-update.js';
|
|
76
74
|
import { createDoctorCommand } from './commands/doctor.js';
|
|
77
75
|
import { createSetupCommand } from './commands/setup.js';
|
|
78
76
|
import { createMcpCommand } from './commands/mcp.js';
|
|
79
77
|
import { showSplashScreen, shouldShowSplash } from './lib/splash.js';
|
|
80
78
|
import { checkForUpdate } from './lib/update-check.js';
|
|
81
79
|
import { setupUnknownCommandSuggestions } from './lib/did-you-mean.js';
|
|
82
|
-
import { getEnabledGKs, isGKEnabled } from './lib/gk.js';
|
|
83
80
|
import chalk from 'chalk';
|
|
84
81
|
// ESM equivalent of __dirname
|
|
85
82
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
@@ -217,24 +214,22 @@ triggerCmd.addCommand(createTriggerUpdateCommand());
|
|
|
217
214
|
triggerCmd.addCommand(createTriggerActivateCommand());
|
|
218
215
|
triggerCmd.addCommand(createTriggerDeactivateCommand());
|
|
219
216
|
triggerCmd.addCommand(createTriggerSessionsCommand());
|
|
220
|
-
//
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
containerImageCmd.addCommand(createContainerImageGetCommand());
|
|
237
|
-
}
|
|
217
|
+
// Credentials command group
|
|
218
|
+
const credentialsCmd = program
|
|
219
|
+
.command('credentials')
|
|
220
|
+
.description('Credential management');
|
|
221
|
+
credentialsCmd.addCommand(createCredentialsListCommand());
|
|
222
|
+
const credentialsPolicyCmd = credentialsCmd
|
|
223
|
+
.command('policy')
|
|
224
|
+
.description('Manage credential policies');
|
|
225
|
+
credentialsPolicyCmd.addCommand(createCredentialsPolicyListCommand());
|
|
226
|
+
credentialsPolicyCmd.addCommand(createCredentialsPolicyCreateCommand());
|
|
227
|
+
credentialsPolicyCmd.addCommand(createCredentialsPolicyUpdateCommand());
|
|
228
|
+
credentialsPolicyCmd.addCommand(createCredentialsPolicyDeleteCommand());
|
|
229
|
+
const credentialsEndpointCmd = credentialsCmd
|
|
230
|
+
.command('endpoint')
|
|
231
|
+
.description('Manage credential endpoints');
|
|
232
|
+
credentialsEndpointCmd.addCommand(createCredentialsEndpointListCommand());
|
|
238
233
|
// Session command group
|
|
239
234
|
const sessionCmd = program.command('session').description('Session management');
|
|
240
235
|
sessionCmd.addCommand(createSessionListCommand());
|