@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.
Files changed (99) hide show
  1. package/README.md +17 -0
  2. package/dist/commands/agent/chat.js +31 -31
  3. package/dist/commands/agent/clone.js +3 -1
  4. package/dist/commands/agent/code.js +3 -2
  5. package/dist/commands/agent/fork.js +41 -15
  6. package/dist/commands/agent/get.js +3 -2
  7. package/dist/commands/agent/grep.js +61 -31
  8. package/dist/commands/agent/init.js +1 -1
  9. package/dist/commands/agent/publish.js +3 -2
  10. package/dist/commands/agent/pull.js +36 -21
  11. package/dist/commands/agent/revalidate.js +4 -3
  12. package/dist/commands/agent/save.js +2 -2
  13. package/dist/commands/agent/search.js +3 -3
  14. package/dist/commands/agent/tags/add.js +4 -3
  15. package/dist/commands/agent/tags/list.js +3 -2
  16. package/dist/commands/agent/tags/remove.js +4 -3
  17. package/dist/commands/agent/tags/set.js +3 -2
  18. package/dist/commands/agent/test.js +8 -12
  19. package/dist/commands/agent/unpublish.js +3 -2
  20. package/dist/commands/agent/update.js +9 -8
  21. package/dist/commands/agent/versions.js +3 -2
  22. package/dist/commands/agent/workspaces.js +3 -2
  23. package/dist/commands/auth/login.js +3 -3
  24. package/dist/commands/chat.js +64 -102
  25. package/dist/commands/credentials/endpoint-list.d.ts +3 -0
  26. package/dist/commands/credentials/endpoint-list.js +87 -0
  27. package/dist/commands/credentials/list.d.ts +3 -0
  28. package/dist/commands/{container → credentials}/list.js +11 -10
  29. package/dist/commands/credentials/policy-create.d.ts +3 -0
  30. package/dist/commands/credentials/policy-create.js +66 -0
  31. package/dist/commands/credentials/policy-delete.d.ts +3 -0
  32. package/dist/commands/{container/get.js → credentials/policy-delete.js} +9 -9
  33. package/dist/commands/credentials/policy-list.d.ts +3 -0
  34. package/dist/commands/{container-image/list.js → credentials/policy-list.js} +9 -9
  35. package/dist/commands/credentials/policy-update.d.ts +3 -0
  36. package/dist/commands/credentials/policy-update.js +66 -0
  37. package/dist/commands/integration/connect.d.ts +3 -0
  38. package/dist/commands/integration/connect.js +76 -0
  39. package/dist/commands/integration/create.d.ts +3 -0
  40. package/dist/commands/integration/create.js +298 -0
  41. package/dist/commands/integration/get.d.ts +3 -0
  42. package/dist/commands/integration/get.js +95 -0
  43. package/dist/commands/integration/list.d.ts +3 -0
  44. package/dist/commands/integration/list.js +61 -0
  45. package/dist/commands/integration/operation/create.d.ts +3 -0
  46. package/dist/commands/integration/operation/create.js +163 -0
  47. package/dist/commands/integration/operation/list.d.ts +3 -0
  48. package/dist/commands/integration/operation/list.js +83 -0
  49. package/dist/commands/integration/update.d.ts +3 -0
  50. package/dist/commands/integration/update.js +139 -0
  51. package/dist/commands/integration/version/build.d.ts +3 -0
  52. package/dist/commands/integration/version/build.js +86 -0
  53. package/dist/commands/integration/version/create.d.ts +3 -0
  54. package/dist/commands/integration/version/create.js +45 -0
  55. package/dist/commands/integration/version/get.d.ts +3 -0
  56. package/dist/commands/integration/version/get.js +72 -0
  57. package/dist/commands/integration/version/list.d.ts +3 -0
  58. package/dist/commands/integration/version/list.js +44 -0
  59. package/dist/commands/integration/version/publish.d.ts +3 -0
  60. package/dist/commands/integration/version/publish.js +79 -0
  61. package/dist/commands/integration/version/test.d.ts +3 -0
  62. package/dist/commands/integration/version/test.js +104 -0
  63. package/dist/commands/trigger/create.js +35 -19
  64. package/dist/commands/workspace/create.js +10 -4
  65. package/dist/commands/workspace/select.js +0 -1
  66. package/dist/index.js +60 -27
  67. package/dist/lib/agent-helpers.d.ts +8 -0
  68. package/dist/lib/agent-helpers.js +15 -0
  69. package/dist/lib/api-types.d.ts +109 -78
  70. package/dist/lib/auth.d.ts +1 -1
  71. package/dist/lib/auth.js +10 -6
  72. package/dist/lib/integration-helpers.d.ts +15 -0
  73. package/dist/lib/integration-helpers.js +38 -0
  74. package/dist/lib/output.d.ts +13 -16
  75. package/dist/lib/output.js +137 -109
  76. package/dist/lib/session-events-fetch.d.ts +27 -0
  77. package/dist/lib/session-events-fetch.js +25 -0
  78. package/dist/lib/session-polling.d.ts +7 -2
  79. package/dist/lib/session-polling.js +18 -11
  80. package/dist/lib/session-resume.js +2 -5
  81. package/dist/lib/table.d.ts +0 -1
  82. package/dist/lib/table.js +0 -1
  83. package/dist/mcp/tools.js +6 -12
  84. package/docs/CLI_WORKFLOW.md +19 -2
  85. package/docs/skills/agent-dev.md +17 -2
  86. package/package.json +6 -5
  87. package/dist/commands/container/destroy.d.ts +0 -3
  88. package/dist/commands/container/destroy.js +0 -48
  89. package/dist/commands/container/events.d.ts +0 -3
  90. package/dist/commands/container/events.js +0 -44
  91. package/dist/commands/container/exec.d.ts +0 -3
  92. package/dist/commands/container/exec.js +0 -64
  93. package/dist/commands/container/get.d.ts +0 -3
  94. package/dist/commands/container/list.d.ts +0 -3
  95. package/dist/commands/container-image/create.d.ts +0 -3
  96. package/dist/commands/container-image/create.js +0 -41
  97. package/dist/commands/container-image/get.d.ts +0 -3
  98. package/dist/commands/container-image/get.js +0 -33
  99. package/dist/commands/container-image/list.d.ts +0 -3
@@ -0,0 +1,298 @@
1
+ // Copyright 2026 Guild.ai
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import inquirer from 'inquirer';
6
+ import { GuildAPIClient } from '../../lib/api-client.js';
7
+ import { getAuthToken } from '../../lib/auth.js';
8
+ import { handleAxiosError } from '../../lib/errors.js';
9
+ import { getOutputMode } from '../../lib/output-mode.js';
10
+ import { createOutputWriter } from '../../lib/output.js';
11
+ import { resolveOwnerId } from '../../lib/owner-helpers.js';
12
+ import { isInteractive } from '../../lib/stdin.js';
13
+ function formatCreatedIntegration(integration) {
14
+ console.log(chalk.green('Integration created successfully'));
15
+ console.log();
16
+ console.log(` ${'Name'.padEnd(15)}${integration.name}`);
17
+ console.log(` ${'Description'.padEnd(15)}${integration.description || chalk.dim('—')}`);
18
+ console.log(` ${'Visibility'.padEnd(15)}${integration.is_public ? 'public' : 'internal'}`);
19
+ console.log(` ${'Owner'.padEnd(15)}${integration.owner?.name || chalk.dim('—')}`);
20
+ console.log(` ${'Base URL'.padEnd(15)}${integration.protocol_config.base_url}`);
21
+ const scheme = integration.auth_config.auth_scheme === 'API_KEY' ? 'API Key' : 'OAuth 2.0';
22
+ console.log(` ${'Auth Scheme'.padEnd(15)}${scheme}`);
23
+ if (integration.auth_config.token_header_template) {
24
+ console.log(` ${'Header'.padEnd(15)}${integration.auth_config.token_header_template}`);
25
+ }
26
+ if (integration.webhook_config) {
27
+ console.log(` ${'Webhooks'.padEnd(15)}Enabled`);
28
+ }
29
+ else {
30
+ console.log(` ${'Webhooks'.padEnd(15)}${chalk.dim('Not configured')}`);
31
+ }
32
+ }
33
+ export function createIntegrationCreateCommand() {
34
+ const cmd = new Command('create');
35
+ cmd
36
+ .description('Create a new integration')
37
+ .argument('<name>', 'Integration name')
38
+ .option('--description <text>', 'What this integration does')
39
+ .option('--base-url <url>', 'Base URL for all API requests')
40
+ .option('--owner <account>', 'Owner account name or ID (default: current user)')
41
+ .option('--public', 'Make this integration visible to all users')
42
+ .option('--auth-scheme <scheme>', 'Authentication scheme: api-key or oauth')
43
+ .option('--header-template <template>', 'Header template for API Key auth (default: "X-API-Key: {token}")')
44
+ .option('--install-url <url>', 'OAuth authorization endpoint')
45
+ .option('--token-url <url>', 'OAuth token exchange endpoint')
46
+ .option('--client-id <id>', 'OAuth client ID')
47
+ .option('--client-secret <secret>', 'OAuth client secret')
48
+ .option('--scopes <scopes>', 'Comma-separated OAuth scopes')
49
+ .option('--token-content-type <type>', 'Content-Type for OAuth token request')
50
+ .option('--webhook-events <events>', 'Enable webhooks with events as JSON')
51
+ .action(async (name, options) => {
52
+ const output = createOutputWriter();
53
+ try {
54
+ const token = await getAuthToken();
55
+ if (!token) {
56
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
57
+ process.exit(1);
58
+ }
59
+ const client = new GuildAPIClient();
60
+ const interactive = isInteractive();
61
+ // Resolve owner
62
+ const owner = await resolveOwnerId({
63
+ ownerFlag: options.owner,
64
+ client,
65
+ interactive,
66
+ });
67
+ // Resolve description
68
+ let description = options.description;
69
+ if (!description) {
70
+ if (interactive) {
71
+ const answer = await inquirer.prompt([
72
+ { type: 'input', name: 'description', message: 'Description:' },
73
+ ]);
74
+ description = answer.description;
75
+ }
76
+ }
77
+ // Resolve base URL
78
+ let baseUrl = options.baseUrl;
79
+ if (!baseUrl) {
80
+ if (interactive) {
81
+ const answer = await inquirer.prompt([
82
+ { type: 'input', name: 'baseUrl', message: 'Base URL:' },
83
+ ]);
84
+ baseUrl = answer.baseUrl;
85
+ }
86
+ }
87
+ // Resolve auth scheme
88
+ let authScheme = options.authScheme;
89
+ if (!authScheme) {
90
+ if (interactive) {
91
+ const answer = await inquirer.prompt([
92
+ {
93
+ type: 'list',
94
+ name: 'authScheme',
95
+ message: 'Select authentication scheme:',
96
+ choices: [
97
+ {
98
+ name: 'API Key - Static token sent in request headers',
99
+ value: 'api-key',
100
+ },
101
+ {
102
+ name: 'OAuth 2.0 - User grants access via authorization flow',
103
+ value: 'oauth',
104
+ },
105
+ ],
106
+ },
107
+ ]);
108
+ authScheme = answer.authScheme;
109
+ }
110
+ }
111
+ // Validate required fields in non-interactive mode
112
+ const missing = [];
113
+ if (!description)
114
+ missing.push('--description <text>');
115
+ if (!baseUrl)
116
+ missing.push('--base-url <url>');
117
+ if (!authScheme)
118
+ missing.push('--auth-scheme <scheme>');
119
+ if (missing.length > 0) {
120
+ output.error(`Error: The following options are required in non-interactive mode:\n ${missing.join('\n ')}`, 'Provide all required options, or run interactively (in a TTY) to be prompted.');
121
+ process.exit(1);
122
+ }
123
+ // Build auth config
124
+ let authConfig;
125
+ const normalizedScheme = authScheme.toLowerCase();
126
+ if (normalizedScheme === 'api-key') {
127
+ let headerTemplate = options.headerTemplate || 'X-API-Key: {token}';
128
+ if (interactive && !options.headerTemplate) {
129
+ const answer = await inquirer.prompt([
130
+ {
131
+ type: 'input',
132
+ name: 'headerTemplate',
133
+ message: 'Header template:',
134
+ default: 'X-API-Key: {token}',
135
+ },
136
+ ]);
137
+ headerTemplate = answer.headerTemplate;
138
+ }
139
+ if (!headerTemplate.includes('{token}')) {
140
+ output.error('Error: --header-template must contain {token} placeholder');
141
+ process.exit(1);
142
+ }
143
+ authConfig = {
144
+ auth_scheme: 'API_KEY',
145
+ token_header_template: headerTemplate,
146
+ };
147
+ }
148
+ else if (normalizedScheme === 'oauth') {
149
+ let installUrl = options.installUrl;
150
+ let tokenUrl = options.tokenUrl;
151
+ let clientId = options.clientId;
152
+ let clientSecret = options.clientSecret;
153
+ if (interactive) {
154
+ if (!installUrl) {
155
+ const a = await inquirer.prompt([
156
+ { type: 'input', name: 'val', message: 'Install URL:' },
157
+ ]);
158
+ installUrl = a.val;
159
+ }
160
+ if (!tokenUrl) {
161
+ const a = await inquirer.prompt([
162
+ { type: 'input', name: 'val', message: 'Token URL:' },
163
+ ]);
164
+ tokenUrl = a.val;
165
+ }
166
+ if (!clientId) {
167
+ const a = await inquirer.prompt([
168
+ { type: 'input', name: 'val', message: 'Client ID:' },
169
+ ]);
170
+ clientId = a.val;
171
+ }
172
+ if (!clientSecret) {
173
+ const a = await inquirer.prompt([
174
+ {
175
+ type: 'password',
176
+ name: 'val',
177
+ message: 'Client Secret:',
178
+ },
179
+ ]);
180
+ clientSecret = a.val;
181
+ }
182
+ }
183
+ const oauthMissing = [];
184
+ if (!installUrl)
185
+ oauthMissing.push('--install-url');
186
+ if (!tokenUrl)
187
+ oauthMissing.push('--token-url');
188
+ if (!clientId)
189
+ oauthMissing.push('--client-id');
190
+ if (!clientSecret)
191
+ oauthMissing.push('--client-secret');
192
+ if (oauthMissing.length > 0) {
193
+ output.error(`Error: ${oauthMissing.join(', ')}, and --client-secret are required when --auth-scheme is oauth`);
194
+ process.exit(1);
195
+ }
196
+ authConfig = {
197
+ auth_scheme: 'OAUTH',
198
+ install_url: installUrl,
199
+ token_url: tokenUrl,
200
+ client_id: clientId,
201
+ client_secret: clientSecret,
202
+ token_url_content_type: options.tokenContentType || 'application/x-www-form-urlencoded',
203
+ };
204
+ if (options.scopes) {
205
+ authConfig.scopes = options.scopes.split(',').map((s) => s.trim());
206
+ }
207
+ else if (interactive) {
208
+ const answer = await inquirer.prompt([
209
+ {
210
+ type: 'input',
211
+ name: 'scopes',
212
+ message: 'Scopes (comma-separated, optional):',
213
+ },
214
+ ]);
215
+ if (answer.scopes) {
216
+ authConfig.scopes = answer.scopes
217
+ .split(',')
218
+ .map((s) => s.trim())
219
+ .filter(Boolean);
220
+ }
221
+ }
222
+ }
223
+ else {
224
+ output.error(`Error: Invalid auth scheme '${authScheme}'`, 'Valid schemes: api-key, oauth');
225
+ process.exit(1);
226
+ }
227
+ // Build webhook config
228
+ let webhookConfig;
229
+ if (options.webhookEvents) {
230
+ try {
231
+ const events = JSON.parse(options.webhookEvents);
232
+ webhookConfig = { events };
233
+ }
234
+ catch {
235
+ output.error(`Error: Invalid JSON for --webhook-events: ${options.webhookEvents}`);
236
+ process.exit(1);
237
+ }
238
+ }
239
+ else if (interactive) {
240
+ const answer = await inquirer.prompt([
241
+ {
242
+ type: 'confirm',
243
+ name: 'configureWebhooks',
244
+ message: 'Configure webhooks?',
245
+ default: false,
246
+ },
247
+ ]);
248
+ if (answer.configureWebhooks) {
249
+ const eventsAnswer = await inquirer.prompt([
250
+ {
251
+ type: 'input',
252
+ name: 'events',
253
+ message: 'Webhook events (JSON):',
254
+ },
255
+ ]);
256
+ if (eventsAnswer.events) {
257
+ try {
258
+ const events = JSON.parse(eventsAnswer.events);
259
+ webhookConfig = { events };
260
+ }
261
+ catch {
262
+ output.error('Error: Invalid JSON for webhook events');
263
+ process.exit(1);
264
+ }
265
+ }
266
+ }
267
+ }
268
+ // Build request body
269
+ const body = {
270
+ name,
271
+ description: description,
272
+ is_public: options.public || false,
273
+ protocol_config: {
274
+ protocol: 'REST',
275
+ base_url: baseUrl,
276
+ },
277
+ auth_config: authConfig,
278
+ };
279
+ if (webhookConfig) {
280
+ body.webhook_config = webhookConfig;
281
+ }
282
+ const response = await client.post(`/accounts/${owner.name}/integrations`, body);
283
+ if (getOutputMode() === 'json') {
284
+ output.data(response);
285
+ }
286
+ else {
287
+ formatCreatedIntegration(response);
288
+ }
289
+ }
290
+ catch (error) {
291
+ const formattedError = handleAxiosError(error);
292
+ output.error(`Failed to create integration: ${formattedError.details}`);
293
+ process.exit(1);
294
+ }
295
+ });
296
+ return cmd;
297
+ }
298
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createIntegrationGetCommand(): Command;
3
+ //# sourceMappingURL=get.d.ts.map
@@ -0,0 +1,95 @@
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
+ function formatDate(dateStr) {
11
+ return new Date(dateStr).toLocaleString('en-US', {
12
+ month: 'short',
13
+ day: 'numeric',
14
+ year: 'numeric',
15
+ hour: 'numeric',
16
+ minute: '2-digit',
17
+ });
18
+ }
19
+ function formatIntegrationDetails(integration) {
20
+ console.log(chalk.bold(integration.name));
21
+ console.log();
22
+ console.log(` ${'Description'.padEnd(15)}${integration.description || chalk.dim('—')}`);
23
+ console.log(` ${'Visibility'.padEnd(15)}${integration.is_public ? 'public' : 'internal'}`);
24
+ console.log(` ${'Owner'.padEnd(15)}${integration.owner?.name || chalk.dim('—')}`);
25
+ console.log(` ${'Created'.padEnd(15)}${formatDate(integration.created_at)}`);
26
+ console.log(` ${'Last Updated'.padEnd(15)}${formatDate(integration.updated_at)}`);
27
+ console.log();
28
+ console.log(chalk.bold('Protocol'));
29
+ console.log(` ${'Type'.padEnd(15)}${integration.protocol_config.protocol}`);
30
+ console.log(` ${'Base URL'.padEnd(15)}${integration.protocol_config.base_url}`);
31
+ console.log();
32
+ console.log(chalk.bold('Authentication'));
33
+ const scheme = integration.auth_config.auth_scheme === 'API_KEY' ? 'API Key' : 'OAuth 2.0';
34
+ console.log(` ${'Scheme'.padEnd(15)}${scheme}`);
35
+ if (integration.auth_config.token_header_template) {
36
+ console.log(` ${'Header'.padEnd(15)}${integration.auth_config.token_header_template}`);
37
+ }
38
+ if (integration.auth_config.install_url) {
39
+ console.log(` ${'Install URL'.padEnd(15)}${integration.auth_config.install_url}`);
40
+ }
41
+ if (integration.auth_config.token_url) {
42
+ console.log(` ${'Token URL'.padEnd(15)}${integration.auth_config.token_url}`);
43
+ }
44
+ console.log();
45
+ if (integration.webhook_config) {
46
+ console.log(`${'Webhooks'.padEnd(17)}${integration.webhook_config.enabled ? 'Enabled' : 'Disabled'}`);
47
+ if (integration.webhook_config.events?.length) {
48
+ console.log(` ${'Events'.padEnd(15)}${integration.webhook_config.events.join(', ')}`);
49
+ }
50
+ }
51
+ else {
52
+ console.log(`${'Webhooks'.padEnd(17)}${chalk.dim('Not configured')}`);
53
+ }
54
+ console.log();
55
+ console.log(chalk.bold('Latest Published Version'));
56
+ if (integration.latest_published_version) {
57
+ const v = integration.latest_published_version;
58
+ console.log(` ${'Version'.padEnd(15)}${v.version_number}`);
59
+ console.log(` ${'Published'.padEnd(15)}${formatDate(v.published_at)}`);
60
+ }
61
+ else {
62
+ console.log(` ${chalk.dim('None')}`);
63
+ }
64
+ }
65
+ export function createIntegrationGetCommand() {
66
+ const cmd = new Command('get');
67
+ cmd
68
+ .description('Get integration details')
69
+ .argument('<id_or_name>', 'Integration ID or name (e.g., owner~name)')
70
+ .action(async (identifier) => {
71
+ const output = createOutputWriter();
72
+ try {
73
+ const token = await getAuthToken();
74
+ if (!token) {
75
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
76
+ process.exit(1);
77
+ }
78
+ const client = new GuildAPIClient();
79
+ const response = await client.get(`/integrations/${identifier}`);
80
+ if (getOutputMode() === 'json') {
81
+ output.data(response);
82
+ }
83
+ else {
84
+ formatIntegrationDetails(response);
85
+ }
86
+ }
87
+ catch (error) {
88
+ const formattedError = handleAxiosError(error);
89
+ output.error(`Failed to get integration: ${formattedError.details}`);
90
+ process.exit(1);
91
+ }
92
+ });
93
+ return cmd;
94
+ }
95
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createIntegrationListCommand(): Command;
3
+ //# sourceMappingURL=list.d.ts.map
@@ -0,0 +1,61 @@
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 { getOutputMode } from '../../lib/output-mode.js';
8
+ import { createOutputWriter, formatIntegrationTable } from '../../lib/output.js';
9
+ const SORT_MAP = {
10
+ updated: 'updated_at',
11
+ newest: 'created_at',
12
+ name: 'name',
13
+ };
14
+ export function createIntegrationListCommand() {
15
+ const cmd = new Command('list');
16
+ cmd
17
+ .description('List integrations')
18
+ .option('--search <query>', 'Search integrations by name or description')
19
+ .option('--sort <field>', 'Sort by: updated, newest, name (default: updated)', 'updated')
20
+ .option('--published', 'Only show integrations with at least one published version')
21
+ .option('--limit <number>', 'Number of results to return', '20')
22
+ .option('--offset <number>', 'Offset for pagination', '0')
23
+ .action(async (options) => {
24
+ const output = createOutputWriter();
25
+ try {
26
+ const token = await getAuthToken();
27
+ if (!token) {
28
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
29
+ process.exit(1);
30
+ }
31
+ const client = new GuildAPIClient();
32
+ const params = new URLSearchParams();
33
+ params.append('limit', options.limit);
34
+ params.append('offset', options.offset);
35
+ if (options.search) {
36
+ params.append('search', options.search);
37
+ }
38
+ if (options.published) {
39
+ params.append('published_only', 'true');
40
+ }
41
+ const sortField = SORT_MAP[options.sort];
42
+ if (sortField) {
43
+ params.append('sort_by', sortField);
44
+ }
45
+ const response = await client.get(`/integrations?${params.toString()}`);
46
+ if (getOutputMode() === 'json') {
47
+ output.data(response);
48
+ }
49
+ else {
50
+ formatIntegrationTable(response.items, response.pagination);
51
+ }
52
+ }
53
+ catch (error) {
54
+ const formattedError = handleAxiosError(error);
55
+ output.error(`Failed to list integrations: ${formattedError.details}`);
56
+ process.exit(1);
57
+ }
58
+ });
59
+ return cmd;
60
+ }
61
+ //# sourceMappingURL=list.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createIntegrationOperationCreateCommand(): Command;
3
+ //# sourceMappingURL=create.d.ts.map
@@ -0,0 +1,163 @@
1
+ // Copyright 2026 Guild.ai
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import inquirer from 'inquirer';
6
+ import { readFileSync, existsSync } from 'fs';
7
+ import { GuildAPIClient } from '../../../lib/api-client.js';
8
+ import { getAuthToken } from '../../../lib/auth.js';
9
+ import { handleAxiosError } from '../../../lib/errors.js';
10
+ import { getOutputMode } from '../../../lib/output-mode.js';
11
+ import { createOutputWriter } from '../../../lib/output.js';
12
+ import { resolveVersionId } from '../../../lib/integration-helpers.js';
13
+ import { isInteractive } from '../../../lib/stdin.js';
14
+ const VALID_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'];
15
+ export function createIntegrationOperationCreateCommand() {
16
+ const cmd = new Command('create');
17
+ cmd
18
+ .description('Create operation(s) for an integration version')
19
+ .argument('<id_or_name>', 'Integration ID or name (owner~name)')
20
+ .option('--version <semver>', 'Specific version, e.g. 1.0.0')
21
+ .option('--operation <name>', 'Operation identifier, e.g. list_users')
22
+ .option('--method <method>', 'HTTP method: GET, POST, PUT, PATCH, DELETE')
23
+ .option('--path <path>', 'REST path, e.g. /{owner}/{repo}/issues')
24
+ .option('--summary <text>', 'Short description of the operation')
25
+ .option('--tags <tags>', 'Comma-separated tags, e.g. users,admin')
26
+ .option('--input-body-schema <file>', 'Path to JSON file for request body schema')
27
+ .option('--output-body-schema <file>', 'Path to JSON file for response body schema')
28
+ .option('--openapi <file>', 'Path to OpenAPI spec file (YAML or JSON)')
29
+ .action(async (identifier, options) => {
30
+ const output = createOutputWriter();
31
+ try {
32
+ const token = await getAuthToken();
33
+ if (!token) {
34
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
35
+ process.exit(1);
36
+ }
37
+ const client = new GuildAPIClient();
38
+ const versionId = await resolveVersionId(client, identifier, options.version);
39
+ if (options.openapi) {
40
+ // OpenAPI mode
41
+ if (!existsSync(options.openapi)) {
42
+ output.error(`Error: File not found: ${options.openapi}`);
43
+ process.exit(1);
44
+ }
45
+ const content = readFileSync(options.openapi, 'utf-8');
46
+ const response = await client.post(`/integration_versions/${versionId}/endpoint_generators`, { type: 'openapi', content });
47
+ if (getOutputMode() === 'json') {
48
+ output.data(response);
49
+ }
50
+ else {
51
+ console.log(chalk.green('OpenAPI operation generation triggered'));
52
+ console.log();
53
+ console.log("Operations will be generated asynchronously. Use 'guild integration operation list' to check results.");
54
+ }
55
+ }
56
+ else {
57
+ // Individual operation mode — prompt for missing fields in TTY
58
+ let operation = options.operation;
59
+ let method = options.method;
60
+ let operationPath = options.path;
61
+ if (isInteractive()) {
62
+ if (!operation) {
63
+ const a = await inquirer.prompt([
64
+ {
65
+ type: 'input',
66
+ name: 'val',
67
+ message: 'Operation name (e.g. list_users):',
68
+ },
69
+ ]);
70
+ operation = a.val;
71
+ }
72
+ if (!method) {
73
+ const a = await inquirer.prompt([
74
+ {
75
+ type: 'list',
76
+ name: 'val',
77
+ message: 'HTTP method:',
78
+ choices: VALID_METHODS,
79
+ },
80
+ ]);
81
+ method = a.val;
82
+ }
83
+ if (!operationPath) {
84
+ const a = await inquirer.prompt([
85
+ { type: 'input', name: 'val', message: 'REST path (e.g. /users):' },
86
+ ]);
87
+ operationPath = a.val;
88
+ }
89
+ }
90
+ const missing = [];
91
+ if (!operation)
92
+ missing.push('--operation');
93
+ if (!method)
94
+ missing.push('--method');
95
+ if (!operationPath)
96
+ missing.push('--path');
97
+ if (missing.length > 0) {
98
+ output.error(`Error: ${missing.join(', ')} are required when not using --openapi`);
99
+ process.exit(1);
100
+ }
101
+ method = method.toUpperCase();
102
+ if (!VALID_METHODS.includes(method)) {
103
+ output.error(`Error: Invalid HTTP method '${method}'`, `Valid methods: ${VALID_METHODS.join(', ')}`);
104
+ process.exit(1);
105
+ }
106
+ const body = {
107
+ operation,
108
+ method,
109
+ path: operationPath,
110
+ };
111
+ let summary = options.summary;
112
+ if (!summary && isInteractive()) {
113
+ const a = await inquirer.prompt([
114
+ { type: 'input', name: 'val', message: 'Summary (optional):' },
115
+ ]);
116
+ if (a.val)
117
+ summary = a.val;
118
+ }
119
+ if (summary) {
120
+ body.summary = summary;
121
+ }
122
+ if (options.tags) {
123
+ body.tags = options.tags.split(',').map((t) => t.trim());
124
+ }
125
+ if (options.inputBodySchema) {
126
+ if (!existsSync(options.inputBodySchema)) {
127
+ output.error(`Error: File not found: ${options.inputBodySchema}`);
128
+ process.exit(1);
129
+ }
130
+ body.input_body_type = JSON.parse(readFileSync(options.inputBodySchema, 'utf-8'));
131
+ }
132
+ if (options.outputBodySchema) {
133
+ if (!existsSync(options.outputBodySchema)) {
134
+ output.error(`Error: File not found: ${options.outputBodySchema}`);
135
+ process.exit(1);
136
+ }
137
+ body.output_body_type = JSON.parse(readFileSync(options.outputBodySchema, 'utf-8'));
138
+ }
139
+ const response = await client.post(`/integration_versions/${versionId}/endpoints`, body);
140
+ if (getOutputMode() === 'json') {
141
+ output.data(response);
142
+ }
143
+ else {
144
+ console.log(chalk.green('Operation created successfully'));
145
+ console.log();
146
+ console.log(` ${'Operation'.padEnd(12)}${response.operation}`);
147
+ console.log(` ${'Method'.padEnd(12)}${response.method}`);
148
+ console.log(` ${'Path'.padEnd(12)}${response.path}`);
149
+ if (response.summary) {
150
+ console.log(` ${'Summary'.padEnd(12)}${response.summary}`);
151
+ }
152
+ }
153
+ }
154
+ }
155
+ catch (error) {
156
+ const formattedError = handleAxiosError(error);
157
+ output.error(`Failed to create operation: ${formattedError.details}`);
158
+ process.exit(1);
159
+ }
160
+ });
161
+ return cmd;
162
+ }
163
+ //# sourceMappingURL=create.js.map
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createIntegrationOperationListCommand(): Command;
3
+ //# sourceMappingURL=list.d.ts.map