@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,104 @@
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 { resolveVersionId } from '../../../lib/integration-helpers.js';
11
+ function parseJsonFlag(value, flagName) {
12
+ try {
13
+ return JSON.parse(value);
14
+ }
15
+ catch (e) {
16
+ const msg = e instanceof Error ? e.message : String(e);
17
+ throw new Error(`Invalid JSON for ${flagName}: ${msg}`);
18
+ }
19
+ }
20
+ export function createIntegrationVersionTestCommand() {
21
+ const cmd = new Command('test');
22
+ cmd
23
+ .description('Test an endpoint invocation')
24
+ .argument('<id_or_name>', 'Integration ID or name (owner~name)')
25
+ .option('--version <semver>', 'Specific version, e.g. 1.0.0')
26
+ .requiredOption('--operation <name>', 'Operation to test, e.g. list_users')
27
+ .option('--account <name>', 'Account name to resolve credential from')
28
+ .option('--input-path <json>', 'JSON object of path parameters')
29
+ .option('--input-query <json>', 'JSON object of query parameters')
30
+ .option('--input-body <json>', 'JSON object for request body')
31
+ .action(async (identifier, options) => {
32
+ const output = createOutputWriter();
33
+ try {
34
+ const token = await getAuthToken();
35
+ if (!token) {
36
+ output.error('Not authenticated. Please log in first.', 'Run: guild auth login');
37
+ process.exit(1);
38
+ }
39
+ // Validate JSON inputs before any API calls
40
+ const body = {
41
+ operation: options.operation,
42
+ };
43
+ if (options.inputPath) {
44
+ body.input_path = parseJsonFlag(options.inputPath, '--input-path');
45
+ }
46
+ if (options.inputQuery) {
47
+ body.input_query = parseJsonFlag(options.inputQuery, '--input-query');
48
+ }
49
+ if (options.inputBody) {
50
+ body.input_body = parseJsonFlag(options.inputBody, '--input-body');
51
+ }
52
+ const client = new GuildAPIClient();
53
+ const versionId = await resolveVersionId(client, identifier, options.version);
54
+ if (options.account) {
55
+ const creds = await client.get(`/accounts/${options.account}/credentials?integration=${encodeURIComponent(identifier)}`);
56
+ if (creds.items.length === 0) {
57
+ output.error(`Error: No credentials found for account '${options.account}' on integration '${identifier}'`);
58
+ process.exit(1);
59
+ }
60
+ body.credential_id = creds.items[0].id;
61
+ }
62
+ const response = await client.post(`/integration_versions/${versionId}/test`, body);
63
+ if (getOutputMode() === 'json') {
64
+ output.data(response);
65
+ }
66
+ else {
67
+ console.log(`Testing operation: ${options.operation}`);
68
+ console.log();
69
+ console.log(chalk.bold('Request'));
70
+ console.log(` ${'URL'.padEnd(9)}${response.request_url}`);
71
+ console.log();
72
+ console.log(chalk.bold('Response'));
73
+ console.log(` ${'Status'.padEnd(9)}${response.status_code}`);
74
+ console.log(` ${'Type'.padEnd(9)}${response.content_type || chalk.dim('—')}`);
75
+ console.log();
76
+ console.log(chalk.bold('Body'));
77
+ if (response.body !== null && response.body !== undefined) {
78
+ const bodyStr = typeof response.body === 'string'
79
+ ? response.body
80
+ : JSON.stringify(response.body, null, 2);
81
+ const indented = bodyStr
82
+ .split('\n')
83
+ .map((line) => ` ${line}`)
84
+ .join('\n');
85
+ console.log(indented);
86
+ }
87
+ else {
88
+ console.log(chalk.dim(' (empty)'));
89
+ }
90
+ }
91
+ }
92
+ catch (error) {
93
+ if (error instanceof Error && error.message.startsWith('Invalid JSON')) {
94
+ output.error(`Error: ${error.message}`);
95
+ process.exit(1);
96
+ }
97
+ const formattedError = handleAxiosError(error);
98
+ output.error(`Failed to test endpoint: ${formattedError.details}`);
99
+ process.exit(1);
100
+ }
101
+ });
102
+ return cmd;
103
+ }
104
+ //# sourceMappingURL=test.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 { WEBHOOK_SERVICES, TIME_TRIGGER_FREQUENCIES, } from '../../lib/api-types.js';
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('--service <service>', 'Webhook service: GITHUB, BITBUCKET, JIRA, SLACK')
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
- const token = await getAuthToken();
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
- // Validate webhook-specific options
67
- if (!options.service) {
68
- output.error(`--service is required for webhook triggers. Valid: ${WEBHOOK_SERVICES.join(', ')}`);
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
- const service = options.service.toUpperCase();
72
- if (!WEBHOOK_SERVICES.includes(service)) {
73
- output.error(`Invalid service "${options.service}". Valid: ${WEBHOOK_SERVICES.join(', ')}`);
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(', ')}`);
@@ -4,21 +4,27 @@ import { Command } from 'commander';
4
4
  import { GuildAPIClient } from '../../lib/api-client.js';
5
5
  import { handleAxiosError, ErrorCodes } from '../../lib/errors.js';
6
6
  import { createOutputWriter } from '../../lib/output.js';
7
+ import { resolveOwnerId } from '../../lib/owner-helpers.js';
8
+ import { isInteractive } from '../../lib/stdin.js';
7
9
  export function createWorkspaceCreateCommand() {
8
10
  const cmd = new Command('create');
9
11
  cmd
10
12
  .description('Create a new workspace')
11
13
  .argument('<name>', 'Workspace name')
12
- .action(async (name) => {
14
+ .option('--owner <owner>', 'Owner (name or ID)')
15
+ .action(async (name, options) => {
13
16
  const output = createOutputWriter();
14
17
  try {
15
18
  const client = new GuildAPIClient();
16
- // Get current user info to use as workspace owner
17
- const me = (await client.get('/me'));
19
+ const owner = await resolveOwnerId({
20
+ ownerFlag: options.owner,
21
+ client,
22
+ interactive: isInteractive(),
23
+ });
18
24
  // Create workspace
19
25
  const workspace = await client.post('/workspaces', {
20
26
  name,
21
- owner_id: me.id,
27
+ owner_id: owner.id,
22
28
  });
23
29
  output.data(workspace);
24
30
  }
@@ -86,7 +86,6 @@ export function createWorkspaceSelectCommand() {
86
86
  const selectedId = await search({
87
87
  message: 'Select a workspace (type to filter)',
88
88
  pageSize: 15,
89
- default: currentId,
90
89
  source: (input) => {
91
90
  const term = input?.toLowerCase() ?? '';
92
91
  const filtered = term
package/dist/index.js CHANGED
@@ -59,27 +59,37 @@ 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';
77
+ import { createIntegrationListCommand } from './commands/integration/list.js';
78
+ import { createIntegrationGetCommand } from './commands/integration/get.js';
79
+ import { createIntegrationCreateCommand } from './commands/integration/create.js';
80
+ import { createIntegrationUpdateCommand } from './commands/integration/update.js';
81
+ import { createIntegrationConnectCommand } from './commands/integration/connect.js';
82
+ import { createIntegrationVersionListCommand } from './commands/integration/version/list.js';
83
+ import { createIntegrationVersionCreateCommand } from './commands/integration/version/create.js';
84
+ import { createIntegrationVersionGetCommand } from './commands/integration/version/get.js';
85
+ import { createIntegrationVersionBuildCommand } from './commands/integration/version/build.js';
86
+ import { createIntegrationVersionPublishCommand } from './commands/integration/version/publish.js';
87
+ import { createIntegrationVersionTestCommand } from './commands/integration/version/test.js';
88
+ import { createIntegrationOperationListCommand } from './commands/integration/operation/list.js';
89
+ import { createIntegrationOperationCreateCommand } from './commands/integration/operation/create.js';
79
90
  import { showSplashScreen, shouldShowSplash } from './lib/splash.js';
80
91
  import { checkForUpdate } from './lib/update-check.js';
81
92
  import { setupUnknownCommandSuggestions } from './lib/did-you-mean.js';
82
- import { getEnabledGKs, isGKEnabled } from './lib/gk.js';
83
93
  import chalk from 'chalk';
84
94
  // ESM equivalent of __dirname
85
95
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
@@ -156,6 +166,31 @@ tagsCmd.addCommand(createAgentTagsListCommand());
156
166
  tagsCmd.addCommand(createAgentTagsAddCommand());
157
167
  tagsCmd.addCommand(createAgentTagsRemoveCommand());
158
168
  tagsCmd.addCommand(createAgentTagsSetCommand());
169
+ // Integration command group
170
+ const integrationCmd = program
171
+ .command('integration')
172
+ .description('Manage integrations');
173
+ integrationCmd.addCommand(createIntegrationListCommand());
174
+ integrationCmd.addCommand(createIntegrationGetCommand());
175
+ integrationCmd.addCommand(createIntegrationCreateCommand());
176
+ integrationCmd.addCommand(createIntegrationUpdateCommand());
177
+ integrationCmd.addCommand(createIntegrationConnectCommand());
178
+ // Integration version subcommand group
179
+ const integrationVersionCmd = integrationCmd
180
+ .command('version')
181
+ .description('Manage integration versions');
182
+ integrationVersionCmd.addCommand(createIntegrationVersionListCommand());
183
+ integrationVersionCmd.addCommand(createIntegrationVersionCreateCommand());
184
+ integrationVersionCmd.addCommand(createIntegrationVersionGetCommand());
185
+ integrationVersionCmd.addCommand(createIntegrationVersionBuildCommand());
186
+ integrationVersionCmd.addCommand(createIntegrationVersionPublishCommand());
187
+ integrationVersionCmd.addCommand(createIntegrationVersionTestCommand());
188
+ // Integration operation subcommand group
189
+ const integrationOperationCmd = integrationCmd
190
+ .command('operation')
191
+ .description('Manage version operations');
192
+ integrationOperationCmd.addCommand(createIntegrationOperationListCommand());
193
+ integrationOperationCmd.addCommand(createIntegrationOperationCreateCommand());
159
194
  // Workspace command group
160
195
  const workspaceCmd = program.command('workspace').description('Workspace management');
161
196
  workspaceCmd.addCommand(createWorkspaceListCommand());
@@ -217,24 +252,22 @@ triggerCmd.addCommand(createTriggerUpdateCommand());
217
252
  triggerCmd.addCommand(createTriggerActivateCommand());
218
253
  triggerCmd.addCommand(createTriggerDeactivateCommand());
219
254
  triggerCmd.addCommand(createTriggerSessionsCommand());
220
- // GK-gated commands: fetch enabled GKs and conditionally register command groups
221
- const enabledGKs = await getEnabledGKs();
222
- if (isGKEnabled('CONTAINERS', enabledGKs)) {
223
- // Container command group
224
- const containerCmd = program.command('container').description('Container management');
225
- containerCmd.addCommand(createContainerListCommand());
226
- containerCmd.addCommand(createContainerGetCommand());
227
- containerCmd.addCommand(createContainerEventsCommand());
228
- containerCmd.addCommand(createContainerExecCommand());
229
- containerCmd.addCommand(createContainerDestroyCommand());
230
- // Container image command group
231
- const containerImageCmd = program
232
- .command('container-image')
233
- .description('Container image management');
234
- containerImageCmd.addCommand(createContainerImageCreateCommand());
235
- containerImageCmd.addCommand(createContainerImageListCommand());
236
- containerImageCmd.addCommand(createContainerImageGetCommand());
237
- }
255
+ // Credentials command group
256
+ const credentialsCmd = program
257
+ .command('credentials')
258
+ .description('Credential management');
259
+ credentialsCmd.addCommand(createCredentialsListCommand());
260
+ const credentialsPolicyCmd = credentialsCmd
261
+ .command('policy')
262
+ .description('Manage credential policies');
263
+ credentialsPolicyCmd.addCommand(createCredentialsPolicyListCommand());
264
+ credentialsPolicyCmd.addCommand(createCredentialsPolicyCreateCommand());
265
+ credentialsPolicyCmd.addCommand(createCredentialsPolicyUpdateCommand());
266
+ credentialsPolicyCmd.addCommand(createCredentialsPolicyDeleteCommand());
267
+ const credentialsEndpointCmd = credentialsCmd
268
+ .command('endpoint')
269
+ .description('Manage credential endpoints');
270
+ credentialsEndpointCmd.addCommand(createCredentialsEndpointListCommand());
238
271
  // Session command group
239
272
  const sessionCmd = program.command('session').description('Session management');
240
273
  sessionCmd.addCommand(createSessionListCommand());
@@ -1,4 +1,12 @@
1
1
  import { LocalConfig } from './guild-config.js';
2
+ import { GuildAPIClient } from './api-client.js';
3
+ /**
4
+ * Resolve an agent identifier to a fully-qualified form.
5
+ *
6
+ * If the identifier already contains `/` or is a UUID, return it verbatim.
7
+ * Otherwise, resolve the default owner and prepend `owner.name/`.
8
+ */
9
+ export declare function resolveAgentRef(client: GuildAPIClient, identifier: string): Promise<string>;
2
10
  /**
3
11
  * Get agent ID from argument or guild.json in current directory
4
12
  * @param agentIdArg - Optional agent ID from command argument
@@ -4,6 +4,21 @@ import * as fs from 'fs/promises';
4
4
  import * as path from 'path';
5
5
  import { loadLocalConfig } from './guild-config.js';
6
6
  import { runGit } from './git.js';
7
+ import { resolveOwnerId } from './owner-helpers.js';
8
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
9
+ /**
10
+ * Resolve an agent identifier to a fully-qualified form.
11
+ *
12
+ * If the identifier already contains `/` or is a UUID, return it verbatim.
13
+ * Otherwise, resolve the default owner and prepend `owner.name/`.
14
+ */
15
+ export async function resolveAgentRef(client, identifier) {
16
+ if (identifier.includes('/') || UUID_RE.test(identifier)) {
17
+ return identifier;
18
+ }
19
+ const owner = await resolveOwnerId({ client, interactive: false });
20
+ return `${owner.name}/${identifier}`;
21
+ }
7
22
  /**
8
23
  * Get agent ID from argument or guild.json in current directory
9
24
  * @param agentIdArg - Optional agent ID from command argument
@@ -204,6 +204,18 @@ export interface AgentVersionDetail {
204
204
  description: string;
205
205
  };
206
206
  }
207
+ export interface TriggerIntegrationWebhookConfig {
208
+ id: string;
209
+ enabled: boolean;
210
+ events: Record<string, string[]>;
211
+ }
212
+ export interface TriggerIntegration {
213
+ id: string;
214
+ name: string;
215
+ full_name: string;
216
+ service?: string | null;
217
+ webhook_config: TriggerIntegrationWebhookConfig | null;
218
+ }
207
219
  export type TriggerType = 'webhook' | 'time';
208
220
  import { WEBHOOK_SERVICES, type WebhookService, TIME_TRIGGER_FREQUENCIES, type TimeTriggerFrequency } from './generated-types.js';
209
221
  export { WEBHOOK_SERVICES, type WebhookService, TIME_TRIGGER_FREQUENCIES, type TimeTriggerFrequency, };
@@ -239,7 +251,6 @@ export interface TriggerWorkspaceAgent {
239
251
  export interface TriggerWebhook {
240
252
  id: string;
241
253
  type: 'webhook';
242
- service: WebhookService;
243
254
  event_type: string | null;
244
255
  action: string | null;
245
256
  service_config?: {
@@ -248,6 +259,7 @@ export interface TriggerWebhook {
248
259
  project?: string;
249
260
  jql_filter?: string;
250
261
  } | Record<string, unknown>;
262
+ integration: TriggerIntegration;
251
263
  created_at: string;
252
264
  deactivated_at: string | null;
253
265
  disabled_reason: TriggerDisabledReason | null;
@@ -315,101 +327,55 @@ export interface Organization {
315
327
  viewer_role: 'ADMIN' | 'MEMBER' | null;
316
328
  }
317
329
  export type OrganizationListResponse = PaginatedResponse<Organization>;
318
- /**
319
- * Session entity from API responses.
320
- * Used by: session list, container list (as owner)
321
- */
322
- export interface Session {
330
+ export interface Credentials {
323
331
  id: string;
324
- session_type: 'chat' | 'agent_test' | 'time' | 'webhook';
325
- name?: string;
326
- workspace?: {
332
+ integration: {
333
+ id: string;
334
+ name: string;
335
+ full_name: string;
336
+ };
337
+ creator: {
327
338
  id: string;
328
339
  name: string;
329
340
  };
330
341
  created_at: string;
331
342
  updated_at: string;
332
343
  }
333
- export type ContainerStatus = 'STARTING' | 'RUNNING' | 'ERRORED' | 'DESTROYED';
334
- /**
335
- * Container image entity from the API.
336
- */
337
- export interface ContainerImage {
344
+ export type CredentialsListResponse = PaginatedResponse<Credentials>;
345
+ export interface CredentialsPolicy {
338
346
  id: string;
339
- name: string;
340
- image_name: string;
341
- tag: string;
342
- is_public: boolean;
347
+ decision: 'ALLOW' | 'DENY';
348
+ operations: string[] | null;
349
+ resources: Record<string, string[]> | null;
350
+ workspaces: {
351
+ id: string;
352
+ name: string;
353
+ full_name?: string;
354
+ }[];
355
+ agents: {
356
+ id: string;
357
+ name: string;
358
+ full_name?: string;
359
+ }[];
343
360
  created_at: string;
344
361
  updated_at: string;
345
362
  }
363
+ export type CredentialsPolicyListResponse = PaginatedResponse<CredentialsPolicy>;
346
364
  /**
347
- * The actor that created the container (user or task agent).
365
+ * Session entity from API responses.
366
+ * Used by: session list
348
367
  */
349
- export interface ContainerActor {
368
+ export interface Session {
350
369
  id: string;
351
- entity_type: string;
370
+ session_type: 'chat' | 'agent_test' | 'time' | 'webhook';
352
371
  name?: string;
353
- full_name?: string;
354
- }
355
- /**
356
- * Container entity from the API.
357
- * Used by: container list
358
- */
359
- export interface Container {
360
- id: string;
361
- status: ContainerStatus;
362
- owner: Session;
363
- created_by: ContainerActor;
364
- image: ContainerImage;
365
- created_at: string;
366
- updated_at: string;
367
- }
368
- export type ContainerListResponse = PaginatedResponse<Container>;
369
- /**
370
- * Container image as returned in list responses.
371
- */
372
- export interface ContainerImageListItem {
373
- id: string;
374
- name: string;
375
- image_name: string;
376
- tag: string;
377
- is_public: boolean;
378
- created_at: string;
379
- updated_at: string;
380
- }
381
- export type ContainerImageListResponse = PaginatedResponse<ContainerImageListItem>;
382
- export type ContainerEventStatus = 'PENDING' | 'ERROR' | 'SUCCESS';
383
- /**
384
- * Base fields shared by all container events.
385
- */
386
- export interface ContainerEventBase {
387
- id: string;
388
- entity_type: string;
389
- actor: ContainerActor;
390
- status: ContainerEventStatus;
391
- completed_at: string | null;
392
- error: string | null;
372
+ workspace?: {
373
+ id: string;
374
+ name: string;
375
+ };
393
376
  created_at: string;
394
377
  updated_at: string;
395
378
  }
396
- export interface ContainerEventCreate extends ContainerEventBase {
397
- entity_type: 'EntContainerEventCreate';
398
- is_local: boolean;
399
- }
400
- export interface ContainerEventDestroy extends ContainerEventBase {
401
- entity_type: 'EntContainerEventDestroy';
402
- found: boolean | null;
403
- }
404
- export interface ContainerEventCommand extends ContainerEventBase {
405
- entity_type: 'EntContainerEventCommand';
406
- command: string;
407
- return_code: number | null;
408
- stdout: string | null;
409
- stderr: string | null;
410
- }
411
- export type ContainerEvent = ContainerEventCreate | ContainerEventDestroy | ContainerEventCommand;
412
- export type ContainerEventListResponse = PaginatedResponse<ContainerEvent>;
413
379
  export type JobType = 'VALIDATION' | 'PUBLISH' | 'PUBLISH_PRE_CHECK';
414
380
  export type JobStatus = 'PENDING' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'ERRORED' | 'CANCELLED';
415
381
  export type JobStepStatus = 'PENDING' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'SKIPPED' | 'ERRORED';
@@ -450,6 +416,71 @@ export interface JobStepsResponse {
450
416
  job_id: string;
451
417
  steps: JobStep[];
452
418
  }
419
+ export interface IntegrationOwner {
420
+ id: string;
421
+ name: string;
422
+ }
423
+ export interface IntegrationAuthConfig {
424
+ id: string;
425
+ entity_type: string;
426
+ auth_scheme: 'API_KEY' | 'OAUTH';
427
+ token_header_template?: string;
428
+ install_url?: string;
429
+ token_url?: string;
430
+ client_id?: string;
431
+ scopes?: string[];
432
+ }
433
+ export interface IntegrationProtocolConfig {
434
+ protocol: 'REST';
435
+ base_url: string;
436
+ }
437
+ export interface IntegrationWebhookConfig {
438
+ enabled: boolean;
439
+ events?: string[];
440
+ }
441
+ export interface IntegrationPublishedVersion {
442
+ id: string;
443
+ version_number: string;
444
+ published_at: string;
445
+ }
446
+ export interface Integration {
447
+ id: string;
448
+ entity_type: string;
449
+ created_at: string;
450
+ updated_at: string;
451
+ name: string;
452
+ description: string | null;
453
+ is_public: boolean;
454
+ avatar_url: string | null;
455
+ owner: IntegrationOwner;
456
+ auth_config: IntegrationAuthConfig;
457
+ protocol_config: IntegrationProtocolConfig;
458
+ webhook_config: IntegrationWebhookConfig | null;
459
+ params: unknown[];
460
+ viewer_can_edit: boolean;
461
+ latest_published_version?: IntegrationPublishedVersion | null;
462
+ }
463
+ export type IntegrationListResponse = PaginatedResponse<Integration>;
464
+ export interface IntegrationVersion {
465
+ id: string;
466
+ entity_type: string;
467
+ created_at: string;
468
+ updated_at: string;
469
+ author: {
470
+ id: string;
471
+ name: string;
472
+ };
473
+ validation_status: string;
474
+ published_at: string | null;
475
+ publishing_started_at: string | null;
476
+ version_number: string | null;
477
+ integration?: {
478
+ id: string;
479
+ name: string;
480
+ description: string;
481
+ };
482
+ }
483
+ export type IntegrationVersionListResponse = PaginatedResponse<IntegrationVersion>;
453
484
  /**
454
485
  * Contents of guild.json file in agent directories.
455
486
  */
@@ -50,7 +50,7 @@ export declare function showBetaGuidance(): void;
50
50
  * @param returnLabel - Optional friendly label for return button (e.g., "VSCode")
51
51
  * @returns true if successful, false otherwise
52
52
  */
53
- export declare function login(returnUrl?: string, returnLabel?: string, noBrowser?: boolean): Promise<boolean>;
53
+ export declare function login(returnUrl?: string, returnLabel?: string, nonInteractive?: boolean): Promise<boolean>;
54
54
  /**
55
55
  * Perform logout
56
56
  */