@agentuity/cli 0.0.47 → 0.0.49
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/bin/cli.ts +26 -5
- package/dist/banner.d.ts +1 -1
- package/dist/banner.d.ts.map +1 -1
- package/dist/cli-logger.d.ts +27 -0
- package/dist/cli-logger.d.ts.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cmd/auth/index.d.ts.map +1 -1
- package/dist/cmd/auth/login.d.ts.map +1 -1
- package/dist/cmd/auth/logout.d.ts.map +1 -1
- package/dist/cmd/auth/signup.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/add.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/delete.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/index.d.ts +1 -2
- package/dist/cmd/auth/ssh/index.d.ts.map +1 -1
- package/dist/cmd/auth/ssh/list.d.ts.map +1 -1
- package/dist/cmd/auth/whoami.d.ts.map +1 -1
- package/dist/cmd/bundle/ast.d.ts.map +1 -1
- package/dist/cmd/bundle/index.d.ts.map +1 -1
- package/dist/cmd/bundle/plugin.d.ts.map +1 -1
- package/dist/cmd/capabilities/index.d.ts +4 -0
- package/dist/cmd/capabilities/index.d.ts.map +1 -0
- package/dist/cmd/capabilities/show.d.ts +20 -0
- package/dist/cmd/capabilities/show.d.ts.map +1 -0
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/index.d.ts +2 -0
- package/dist/cmd/cloud/deployment/index.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/list.d.ts +2 -0
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/remove.d.ts +2 -0
- package/dist/cmd/cloud/deployment/remove.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/rollback.d.ts +2 -0
- package/dist/cmd/cloud/deployment/rollback.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/show.d.ts +2 -0
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/undeploy.d.ts +2 -0
- package/dist/cmd/cloud/deployment/undeploy.d.ts.map +1 -0
- package/dist/cmd/cloud/deployment/utils.d.ts +7 -0
- package/dist/cmd/cloud/deployment/utils.d.ts.map +1 -0
- package/dist/cmd/cloud/domain.d.ts.map +1 -1
- package/dist/cmd/cloud/index.d.ts.map +1 -1
- package/dist/cmd/cloud/resource/add.d.ts.map +1 -1
- package/dist/cmd/cloud/resource/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/resource/index.d.ts +1 -2
- package/dist/cmd/cloud/resource/index.d.ts.map +1 -1
- package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
- package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
- package/dist/cmd/cloud/scp/index.d.ts +1 -2
- package/dist/cmd/cloud/scp/index.d.ts.map +1 -1
- package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/ssh.d.ts.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/env/delete.d.ts.map +1 -1
- package/dist/cmd/env/get.d.ts.map +1 -1
- package/dist/cmd/env/import.d.ts.map +1 -1
- package/dist/cmd/env/index.d.ts.map +1 -1
- package/dist/cmd/env/list.d.ts.map +1 -1
- package/dist/cmd/env/pull.d.ts.map +1 -1
- package/dist/cmd/env/push.d.ts.map +1 -1
- package/dist/cmd/env/set.d.ts.map +1 -1
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/kv/create-namespace.d.ts +3 -0
- package/dist/cmd/kv/create-namespace.d.ts.map +1 -0
- package/dist/cmd/kv/delete-namespace.d.ts +3 -0
- package/dist/cmd/kv/delete-namespace.d.ts.map +1 -0
- package/dist/cmd/kv/delete.d.ts +3 -0
- package/dist/cmd/kv/delete.d.ts.map +1 -0
- package/dist/cmd/kv/get.d.ts +3 -0
- package/dist/cmd/kv/get.d.ts.map +1 -0
- package/dist/cmd/kv/index.d.ts +2 -0
- package/dist/cmd/kv/index.d.ts.map +1 -0
- package/dist/cmd/kv/keys.d.ts +3 -0
- package/dist/cmd/kv/keys.d.ts.map +1 -0
- package/dist/cmd/kv/list-namespaces.d.ts +3 -0
- package/dist/cmd/kv/list-namespaces.d.ts.map +1 -0
- package/dist/cmd/kv/repl.d.ts +3 -0
- package/dist/cmd/kv/repl.d.ts.map +1 -0
- package/dist/cmd/kv/search.d.ts +3 -0
- package/dist/cmd/kv/search.d.ts.map +1 -0
- package/dist/cmd/kv/set.d.ts +3 -0
- package/dist/cmd/kv/set.d.ts.map +1 -0
- package/dist/cmd/kv/stats.d.ts +3 -0
- package/dist/cmd/kv/stats.d.ts.map +1 -0
- package/dist/cmd/kv/util.d.ts +8 -0
- package/dist/cmd/kv/util.d.ts.map +1 -0
- package/dist/cmd/objectstore/delete-bucket.d.ts +3 -0
- package/dist/cmd/objectstore/delete-bucket.d.ts.map +1 -0
- package/dist/cmd/objectstore/delete.d.ts +3 -0
- package/dist/cmd/objectstore/delete.d.ts.map +1 -0
- package/dist/cmd/objectstore/get.d.ts +3 -0
- package/dist/cmd/objectstore/get.d.ts.map +1 -0
- package/dist/cmd/objectstore/index.d.ts +2 -0
- package/dist/cmd/objectstore/index.d.ts.map +1 -0
- package/dist/cmd/objectstore/list-buckets.d.ts +3 -0
- package/dist/cmd/objectstore/list-buckets.d.ts.map +1 -0
- package/dist/cmd/objectstore/list-keys.d.ts +3 -0
- package/dist/cmd/objectstore/list-keys.d.ts.map +1 -0
- package/dist/cmd/objectstore/put.d.ts +3 -0
- package/dist/cmd/objectstore/put.d.ts.map +1 -0
- package/dist/cmd/objectstore/repl.d.ts +3 -0
- package/dist/cmd/objectstore/repl.d.ts.map +1 -0
- package/dist/cmd/objectstore/url.d.ts +3 -0
- package/dist/cmd/objectstore/url.d.ts.map +1 -0
- package/dist/cmd/objectstore/util.d.ts +8 -0
- package/dist/cmd/objectstore/util.d.ts.map +1 -0
- package/dist/cmd/profile/create.d.ts.map +1 -1
- package/dist/cmd/profile/delete.d.ts.map +1 -1
- package/dist/cmd/profile/index.d.ts.map +1 -1
- package/dist/cmd/profile/list.d.ts +1 -2
- package/dist/cmd/profile/list.d.ts.map +1 -1
- package/dist/cmd/profile/show.d.ts.map +1 -1
- package/dist/cmd/profile/use.d.ts.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/delete.d.ts.map +1 -1
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/list.d.ts.map +1 -1
- package/dist/cmd/project/show.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.d.ts +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/prompt/index.d.ts +4 -0
- package/dist/cmd/prompt/index.d.ts.map +1 -0
- package/dist/cmd/prompt/llm.d.ts +3 -0
- package/dist/cmd/prompt/llm.d.ts.map +1 -0
- package/dist/cmd/repl/index.d.ts +3 -0
- package/dist/cmd/repl/index.d.ts.map +1 -0
- package/dist/cmd/schema/index.d.ts +4 -0
- package/dist/cmd/schema/index.d.ts.map +1 -0
- package/dist/cmd/schema/show.d.ts +3 -0
- package/dist/cmd/schema/show.d.ts.map +1 -0
- package/dist/cmd/secret/delete.d.ts.map +1 -1
- package/dist/cmd/secret/get.d.ts.map +1 -1
- package/dist/cmd/secret/import.d.ts.map +1 -1
- package/dist/cmd/secret/index.d.ts.map +1 -1
- package/dist/cmd/secret/list.d.ts.map +1 -1
- package/dist/cmd/secret/pull.d.ts.map +1 -1
- package/dist/cmd/secret/push.d.ts.map +1 -1
- package/dist/cmd/secret/set.d.ts.map +1 -1
- package/dist/cmd/version/index.d.ts.map +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/errors.d.ts +83 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/explain.d.ts +47 -0
- package/dist/explain.d.ts.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/json.d.ts +3 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/output.d.ts +136 -0
- package/dist/output.d.ts.map +1 -0
- package/dist/repl.d.ts +124 -0
- package/dist/repl.d.ts.map +1 -0
- package/dist/schema-generator.d.ts +67 -0
- package/dist/schema-generator.d.ts.map +1 -0
- package/dist/tui.d.ts +20 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/types.d.ts +65 -6
- package/dist/types.d.ts.map +1 -1
- package/package.json +10 -4
- package/src/banner.ts +7 -7
- package/src/cli-logger.ts +80 -0
- package/src/cli.ts +186 -54
- package/src/cmd/auth/index.ts +1 -0
- package/src/cmd/auth/login.ts +7 -2
- package/src/cmd/auth/logout.ts +4 -0
- package/src/cmd/auth/signup.ts +7 -2
- package/src/cmd/auth/ssh/add.ts +20 -3
- package/src/cmd/auth/ssh/delete.ts +57 -4
- package/src/cmd/auth/ssh/index.ts +4 -3
- package/src/cmd/auth/ssh/list.ts +44 -32
- package/src/cmd/auth/whoami.ts +32 -21
- package/src/cmd/bundle/ast.ts +27 -5
- package/src/cmd/bundle/index.ts +20 -0
- package/src/cmd/bundle/plugin.ts +36 -12
- package/src/cmd/capabilities/index.ts +12 -0
- package/src/cmd/capabilities/show.ts +256 -0
- package/src/cmd/cloud/deploy.ts +60 -0
- package/src/cmd/cloud/deployment/index.ts +20 -0
- package/src/cmd/cloud/deployment/list.ts +105 -0
- package/src/cmd/cloud/deployment/remove.ts +65 -0
- package/src/cmd/cloud/deployment/rollback.ts +87 -0
- package/src/cmd/cloud/deployment/show.ts +107 -0
- package/src/cmd/cloud/deployment/undeploy.ts +48 -0
- package/src/cmd/cloud/deployment/utils.ts +14 -0
- package/src/cmd/cloud/domain.ts +3 -2
- package/src/cmd/cloud/index.ts +9 -1
- package/src/cmd/cloud/resource/add.ts +19 -0
- package/src/cmd/cloud/resource/delete.ts +24 -3
- package/src/cmd/cloud/resource/index.ts +4 -3
- package/src/cmd/cloud/resource/list.ts +36 -10
- package/src/cmd/cloud/scp/download.ts +27 -1
- package/src/cmd/cloud/scp/index.ts +4 -3
- package/src/cmd/cloud/scp/upload.ts +27 -1
- package/src/cmd/cloud/ssh.ts +12 -0
- package/src/cmd/dev/index.ts +11 -7
- package/src/cmd/dev/templates.ts +1 -1
- package/src/cmd/env/delete.ts +17 -0
- package/src/cmd/env/get.ts +17 -1
- package/src/cmd/env/import.ts +47 -3
- package/src/cmd/env/index.ts +1 -0
- package/src/cmd/env/list.ts +13 -1
- package/src/cmd/env/pull.ts +20 -0
- package/src/cmd/env/push.ts +33 -1
- package/src/cmd/env/set.ts +25 -1
- package/src/cmd/index.ts +9 -2
- package/src/cmd/kv/create-namespace.ts +45 -0
- package/src/cmd/kv/delete-namespace.ts +73 -0
- package/src/cmd/kv/delete.ts +51 -0
- package/src/cmd/kv/get.ts +65 -0
- package/src/cmd/kv/index.ts +31 -0
- package/src/cmd/kv/keys.ts +57 -0
- package/src/cmd/kv/list-namespaces.ts +43 -0
- package/src/cmd/kv/repl.ts +284 -0
- package/src/cmd/kv/search.ts +80 -0
- package/src/cmd/kv/set.ts +63 -0
- package/src/cmd/kv/stats.ts +96 -0
- package/src/cmd/kv/util.ts +32 -0
- package/src/cmd/objectstore/delete-bucket.ts +72 -0
- package/src/cmd/objectstore/delete.ts +59 -0
- package/src/cmd/objectstore/get.ts +64 -0
- package/src/cmd/objectstore/index.ts +27 -0
- package/src/cmd/objectstore/list-buckets.ts +45 -0
- package/src/cmd/objectstore/list-keys.ts +60 -0
- package/src/cmd/objectstore/put.ts +62 -0
- package/src/cmd/objectstore/repl.ts +235 -0
- package/src/cmd/objectstore/url.ts +59 -0
- package/src/cmd/objectstore/util.ts +28 -0
- package/src/cmd/profile/create.ts +61 -6
- package/src/cmd/profile/delete.ts +25 -5
- package/src/cmd/profile/index.ts +1 -0
- package/src/cmd/profile/list.ts +7 -3
- package/src/cmd/profile/show.ts +33 -19
- package/src/cmd/profile/use.ts +17 -4
- package/src/cmd/project/create.ts +31 -0
- package/src/cmd/project/delete.ts +24 -2
- package/src/cmd/project/index.ts +1 -0
- package/src/cmd/project/list.ts +23 -9
- package/src/cmd/project/show.ts +27 -8
- package/src/cmd/project/template-flow.ts +10 -6
- package/src/cmd/prompt/index.ts +12 -0
- package/src/cmd/prompt/llm.ts +368 -0
- package/src/cmd/repl/index.ts +477 -0
- package/src/cmd/schema/index.ts +12 -0
- package/src/cmd/schema/show.ts +27 -0
- package/src/cmd/secret/delete.ts +17 -0
- package/src/cmd/secret/get.ts +20 -1
- package/src/cmd/secret/import.ts +45 -2
- package/src/cmd/secret/index.ts +1 -0
- package/src/cmd/secret/list.ts +10 -1
- package/src/cmd/secret/pull.ts +20 -0
- package/src/cmd/secret/push.ts +33 -1
- package/src/cmd/secret/set.ts +20 -0
- package/src/cmd/version/index.ts +15 -2
- package/src/config.ts +18 -5
- package/src/errors.ts +222 -0
- package/src/explain.ts +126 -0
- package/src/index.ts +51 -0
- package/src/json.ts +28 -0
- package/src/output.ts +307 -0
- package/src/repl.ts +1517 -0
- package/src/schema-generator.ts +389 -0
- package/src/tui.ts +136 -13
- package/src/types.ts +62 -12
package/src/cmd/cloud/deploy.ts
CHANGED
|
@@ -27,12 +27,45 @@ import {
|
|
|
27
27
|
import { zipDir } from '../../utils/zip';
|
|
28
28
|
import { encryptFIPSKEMDEMStream } from '../../crypto/box';
|
|
29
29
|
import { checkCustomDomainForDNS } from './domain';
|
|
30
|
+
import { getCommand } from '../../command-prefix';
|
|
31
|
+
import { z } from 'zod';
|
|
32
|
+
|
|
33
|
+
const DeployResponseSchema = z.object({
|
|
34
|
+
success: z.boolean().describe('Whether deployment succeeded'),
|
|
35
|
+
deploymentId: z.string().describe('Deployment ID'),
|
|
36
|
+
projectId: z.string().describe('Project ID'),
|
|
37
|
+
urls: z
|
|
38
|
+
.object({
|
|
39
|
+
deployment: z.string().describe('Deployment-specific URL'),
|
|
40
|
+
latest: z.string().describe('Latest/active deployment URL'),
|
|
41
|
+
custom: z.array(z.string()).optional().describe('Custom domain URLs'),
|
|
42
|
+
})
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('Deployment URLs'),
|
|
45
|
+
});
|
|
30
46
|
|
|
31
47
|
export const deploySubcommand = createSubcommand({
|
|
32
48
|
name: 'deploy',
|
|
33
49
|
description: 'Deploy project to the Agentuity Cloud',
|
|
50
|
+
tags: [
|
|
51
|
+
'mutating',
|
|
52
|
+
'creates-resource',
|
|
53
|
+
'slow',
|
|
54
|
+
'api-intensive',
|
|
55
|
+
'requires-auth',
|
|
56
|
+
'requires-project',
|
|
57
|
+
],
|
|
58
|
+
examples: [
|
|
59
|
+
`${getCommand('cloud deploy')} # Deploy current project`,
|
|
60
|
+
`${getCommand('cloud deploy')} --log-level=debug # Deploy with verbose output`,
|
|
61
|
+
],
|
|
34
62
|
toplevel: true,
|
|
63
|
+
idempotent: false,
|
|
35
64
|
requires: { auth: true, project: true, apiClient: true },
|
|
65
|
+
prerequisites: ['auth login'],
|
|
66
|
+
schema: {
|
|
67
|
+
response: DeployResponseSchema,
|
|
68
|
+
},
|
|
36
69
|
|
|
37
70
|
async handler(ctx) {
|
|
38
71
|
const { project, apiClient, projectDir, config, options } = ctx;
|
|
@@ -183,6 +216,12 @@ export const deploySubcommand = createSubcommand({
|
|
|
183
216
|
if (relative.endsWith('.map')) {
|
|
184
217
|
return false;
|
|
185
218
|
}
|
|
219
|
+
// ignore common stuff we never want to include in the zip
|
|
220
|
+
if (relative.startsWith('.env')) return false;
|
|
221
|
+
if (relative.startsWith('.git/')) return false;
|
|
222
|
+
if (relative.startsWith('.ssh/')) return false;
|
|
223
|
+
if (relative.startsWith('node_modules/')) return false;
|
|
224
|
+
if (relative === '.DS_Store') return false;
|
|
186
225
|
return true;
|
|
187
226
|
},
|
|
188
227
|
});
|
|
@@ -329,6 +368,27 @@ export const deploySubcommand = createSubcommand({
|
|
|
329
368
|
);
|
|
330
369
|
}
|
|
331
370
|
}
|
|
371
|
+
|
|
372
|
+
// Return deployment result (if available)
|
|
373
|
+
if (deployment && complete?.publicUrls) {
|
|
374
|
+
return {
|
|
375
|
+
success: true,
|
|
376
|
+
deploymentId: deployment.id,
|
|
377
|
+
projectId: project.projectId,
|
|
378
|
+
urls: {
|
|
379
|
+
deployment: complete.publicUrls.deployment,
|
|
380
|
+
latest: complete.publicUrls.latest,
|
|
381
|
+
custom: complete.publicUrls.custom,
|
|
382
|
+
},
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
// Fallback response
|
|
387
|
+
return {
|
|
388
|
+
success: false,
|
|
389
|
+
deploymentId: '',
|
|
390
|
+
projectId: project.projectId,
|
|
391
|
+
};
|
|
332
392
|
} catch (ex) {
|
|
333
393
|
tui.fatal(`unexpected error trying to deploy project. ${ex}`);
|
|
334
394
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createCommand } from '../../../types';
|
|
2
|
+
import { listSubcommand } from './list';
|
|
3
|
+
import { showSubcommand } from './show';
|
|
4
|
+
import { removeSubcommand } from './remove';
|
|
5
|
+
import { rollbackSubcommand } from './rollback';
|
|
6
|
+
import { undeploySubcommand } from './undeploy';
|
|
7
|
+
|
|
8
|
+
export const deploymentCommand = createCommand({
|
|
9
|
+
name: 'deployment',
|
|
10
|
+
description: 'Manage deployments',
|
|
11
|
+
tags: ['read-only', 'fast', 'requires-auth'],
|
|
12
|
+
aliases: ['deployments', 'dep'],
|
|
13
|
+
subcommands: [
|
|
14
|
+
listSubcommand,
|
|
15
|
+
showSubcommand,
|
|
16
|
+
removeSubcommand,
|
|
17
|
+
rollbackSubcommand,
|
|
18
|
+
undeploySubcommand,
|
|
19
|
+
],
|
|
20
|
+
});
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createSubcommand } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { projectDeploymentList } from '@agentuity/server';
|
|
5
|
+
import { resolveProjectId } from './utils';
|
|
6
|
+
import { Table } from 'console-table-printer';
|
|
7
|
+
import { getCommand } from '../../../command-prefix';
|
|
8
|
+
import { ErrorCode } from '../../../errors';
|
|
9
|
+
|
|
10
|
+
const DeploymentListResponseSchema = z.array(
|
|
11
|
+
z.object({
|
|
12
|
+
id: z.string().describe('Deployment ID'),
|
|
13
|
+
state: z.string().optional().describe('Current state of the deployment'),
|
|
14
|
+
active: z.boolean().describe('Whether this is the active deployment'),
|
|
15
|
+
createdAt: z.string().describe('Creation timestamp'),
|
|
16
|
+
message: z.string().optional().describe('Deployment message or description'),
|
|
17
|
+
tags: z.array(z.string()).describe('Deployment tags'),
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
export const listSubcommand = createSubcommand({
|
|
22
|
+
name: 'list',
|
|
23
|
+
description: 'List deployments',
|
|
24
|
+
tags: ['read-only', 'slow', 'requires-auth'],
|
|
25
|
+
examples: [
|
|
26
|
+
`${getCommand('cloud deployment list')} # List 10 most recent deployments`,
|
|
27
|
+
`${getCommand('cloud deployment list')} --count=25 # List 25 most recent deployments`,
|
|
28
|
+
`${getCommand('cloud deployment list')} --project-id=proj_abc123xyz`,
|
|
29
|
+
],
|
|
30
|
+
aliases: ['ls'],
|
|
31
|
+
requires: { auth: true, apiClient: true },
|
|
32
|
+
optional: { project: true },
|
|
33
|
+
idempotent: true,
|
|
34
|
+
pagination: {
|
|
35
|
+
supported: true,
|
|
36
|
+
defaultLimit: 10,
|
|
37
|
+
maxLimit: 100,
|
|
38
|
+
parameters: {
|
|
39
|
+
limit: 'count',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
schema: {
|
|
43
|
+
options: z.object({
|
|
44
|
+
'project-id': z.string().optional().describe('Project ID'),
|
|
45
|
+
count: z.coerce
|
|
46
|
+
.number()
|
|
47
|
+
.int()
|
|
48
|
+
.min(1)
|
|
49
|
+
.max(100)
|
|
50
|
+
.default(10)
|
|
51
|
+
.describe('Number of deployments to list (1–100)'),
|
|
52
|
+
}),
|
|
53
|
+
response: DeploymentListResponseSchema,
|
|
54
|
+
},
|
|
55
|
+
async handler(ctx) {
|
|
56
|
+
const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
|
|
57
|
+
const { apiClient, opts } = ctx;
|
|
58
|
+
|
|
59
|
+
try {
|
|
60
|
+
const deployments = await projectDeploymentList(apiClient, projectId, opts.count);
|
|
61
|
+
|
|
62
|
+
if (deployments.length === 0) {
|
|
63
|
+
tui.info('No deployments found.');
|
|
64
|
+
return [];
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const table = new Table({
|
|
68
|
+
columns: [
|
|
69
|
+
{ name: 'ID', alignment: 'left' },
|
|
70
|
+
{ name: 'State', alignment: 'left' },
|
|
71
|
+
{ name: 'Active', alignment: 'center' },
|
|
72
|
+
{ name: 'Created', alignment: 'left' },
|
|
73
|
+
{ name: 'Message', alignment: 'left' },
|
|
74
|
+
{ name: 'Tags', alignment: 'left' },
|
|
75
|
+
],
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
for (const d of deployments) {
|
|
79
|
+
table.addRow({
|
|
80
|
+
ID: d.id,
|
|
81
|
+
State: d.state || 'unknown',
|
|
82
|
+
Active: d.active ? 'Yes' : '',
|
|
83
|
+
Created: new Date(d.createdAt).toLocaleString(),
|
|
84
|
+
Message: d.message || '',
|
|
85
|
+
Tags: d.tags.join(', '),
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
table.printTable();
|
|
89
|
+
|
|
90
|
+
return deployments.map((d) => ({
|
|
91
|
+
id: d.id,
|
|
92
|
+
state: d.state,
|
|
93
|
+
active: d.active,
|
|
94
|
+
createdAt: d.createdAt,
|
|
95
|
+
message: d.message,
|
|
96
|
+
tags: d.tags,
|
|
97
|
+
}));
|
|
98
|
+
} catch (ex) {
|
|
99
|
+
tui.fatal(
|
|
100
|
+
`Failed to list deployments: ${ex instanceof Error ? ex.message : String(ex)}`,
|
|
101
|
+
ErrorCode.API_ERROR
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createSubcommand } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { projectDeploymentDelete } from '@agentuity/server';
|
|
5
|
+
import { resolveProjectId } from './utils';
|
|
6
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
|
+
|
|
8
|
+
const DeploymentRemoveResponseSchema = z.object({
|
|
9
|
+
success: z.boolean().describe('Whether the removal succeeded'),
|
|
10
|
+
projectId: z.string().describe('Project ID'),
|
|
11
|
+
deploymentId: z.string().describe('Deployment ID that was removed'),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const removeSubcommand = createSubcommand({
|
|
15
|
+
name: 'remove',
|
|
16
|
+
description: 'Remove a specific deployment',
|
|
17
|
+
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
|
|
18
|
+
examples: [
|
|
19
|
+
`${getCommand('cloud deployment remove')} dep_abc123xyz # Remove with confirmation`,
|
|
20
|
+
`${getCommand('cloud deployment remove')} dep_abc123xyz --force # Remove without confirmation`,
|
|
21
|
+
`${getCommand('cloud deployment remove')} deployment-2024-11-20 --project-id=proj_abc123xyz`,
|
|
22
|
+
],
|
|
23
|
+
aliases: ['rm', 'delete'],
|
|
24
|
+
idempotent: false,
|
|
25
|
+
requires: { auth: true, apiClient: true },
|
|
26
|
+
optional: { project: true },
|
|
27
|
+
prerequisites: ['cloud deploy'],
|
|
28
|
+
schema: {
|
|
29
|
+
args: z.object({
|
|
30
|
+
deployment_id: z.string().describe('Deployment ID'),
|
|
31
|
+
}),
|
|
32
|
+
options: z.object({
|
|
33
|
+
'project-id': z.string().optional().describe('Project ID'),
|
|
34
|
+
force: z.boolean().default(false).describe('Force removal without confirmation'),
|
|
35
|
+
}),
|
|
36
|
+
response: DeploymentRemoveResponseSchema,
|
|
37
|
+
},
|
|
38
|
+
async handler(ctx) {
|
|
39
|
+
const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
|
|
40
|
+
const { apiClient, args, opts } = ctx;
|
|
41
|
+
|
|
42
|
+
if (!opts.force) {
|
|
43
|
+
const confirmed = await tui.confirm(
|
|
44
|
+
`Are you sure you want to remove deployment ${args.deployment_id}?`
|
|
45
|
+
);
|
|
46
|
+
if (!confirmed) {
|
|
47
|
+
tui.info('Operation cancelled');
|
|
48
|
+
return { success: false, projectId, deploymentId: args.deployment_id };
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
try {
|
|
53
|
+
await projectDeploymentDelete(apiClient, projectId, args.deployment_id);
|
|
54
|
+
tui.success(`Deployment ${args.deployment_id} removed successfully.`);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
success: true,
|
|
58
|
+
projectId,
|
|
59
|
+
deploymentId: args.deployment_id,
|
|
60
|
+
};
|
|
61
|
+
} catch (ex) {
|
|
62
|
+
tui.fatal(`Failed to remove deployment: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createSubcommand } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { projectDeploymentRollback, projectDeploymentList } from '@agentuity/server';
|
|
5
|
+
import { resolveProjectId } from './utils';
|
|
6
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
|
+
|
|
8
|
+
const DeploymentRollbackResponseSchema = z.object({
|
|
9
|
+
success: z.boolean().describe('Whether the rollback succeeded'),
|
|
10
|
+
projectId: z.string().describe('Project ID'),
|
|
11
|
+
targetDeploymentId: z.string().describe('Deployment ID that was rolled back to'),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const rollbackSubcommand = createSubcommand({
|
|
15
|
+
name: 'rollback',
|
|
16
|
+
description: 'Rollback the latest to the previous deployment',
|
|
17
|
+
tags: [
|
|
18
|
+
'destructive',
|
|
19
|
+
'deletes-resource',
|
|
20
|
+
'updates-resource',
|
|
21
|
+
'slow',
|
|
22
|
+
'api-intensive',
|
|
23
|
+
'requires-auth',
|
|
24
|
+
'requires-deployment',
|
|
25
|
+
],
|
|
26
|
+
examples: [
|
|
27
|
+
`${getCommand('cloud deployment rollback')} # Rollback to previous deployment`,
|
|
28
|
+
`${getCommand('cloud deployment rollback')} --project-id=proj_abc123xyz`,
|
|
29
|
+
],
|
|
30
|
+
idempotent: false,
|
|
31
|
+
requires: { auth: true, apiClient: true },
|
|
32
|
+
optional: { project: true },
|
|
33
|
+
prerequisites: ['cloud deploy'],
|
|
34
|
+
schema: {
|
|
35
|
+
options: z.object({
|
|
36
|
+
'project-id': z.string().optional().describe('Project ID'),
|
|
37
|
+
}),
|
|
38
|
+
response: DeploymentRollbackResponseSchema,
|
|
39
|
+
},
|
|
40
|
+
async handler(ctx) {
|
|
41
|
+
const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
|
|
42
|
+
const { apiClient } = ctx;
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
// Fetch deployments to find the previous one
|
|
46
|
+
const deployments = await projectDeploymentList(apiClient, projectId, 5);
|
|
47
|
+
|
|
48
|
+
// Find currently active
|
|
49
|
+
const activeIndex = deployments.findIndex((d) => d.active);
|
|
50
|
+
|
|
51
|
+
let targetDeploymentId: string | undefined;
|
|
52
|
+
|
|
53
|
+
if (activeIndex === -1) {
|
|
54
|
+
// No active deployment.
|
|
55
|
+
const candidate = deployments.find((d) => d.state === 'completed');
|
|
56
|
+
targetDeploymentId = candidate?.id;
|
|
57
|
+
} else {
|
|
58
|
+
// Has active deployment. Find the next completed one.
|
|
59
|
+
const candidate = deployments
|
|
60
|
+
.slice(activeIndex + 1)
|
|
61
|
+
.find((d) => d.state === 'completed');
|
|
62
|
+
targetDeploymentId = candidate?.id;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (!targetDeploymentId) {
|
|
66
|
+
tui.fatal('No previous completed deployment found to rollback to.');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const confirmed = await tui.confirm(`Rollback to deployment ${targetDeploymentId}?`);
|
|
70
|
+
if (!confirmed) {
|
|
71
|
+
tui.info('Operation cancelled');
|
|
72
|
+
return { success: false, projectId, targetDeploymentId };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
await projectDeploymentRollback(apiClient, projectId, targetDeploymentId!);
|
|
76
|
+
tui.success(`Rolled back to deployment ${targetDeploymentId}.`);
|
|
77
|
+
|
|
78
|
+
return {
|
|
79
|
+
success: true,
|
|
80
|
+
projectId,
|
|
81
|
+
targetDeploymentId,
|
|
82
|
+
};
|
|
83
|
+
} catch (ex) {
|
|
84
|
+
tui.fatal(`Failed to rollback: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
85
|
+
}
|
|
86
|
+
},
|
|
87
|
+
});
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createSubcommand } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { projectDeploymentGet } from '@agentuity/server';
|
|
5
|
+
import { resolveProjectId } from './utils';
|
|
6
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
|
+
|
|
8
|
+
const DeploymentShowResponseSchema = z.object({
|
|
9
|
+
id: z.string().describe('Deployment ID'),
|
|
10
|
+
state: z.string().optional().describe('Deployment state'),
|
|
11
|
+
active: z.boolean().describe('Whether deployment is active'),
|
|
12
|
+
createdAt: z.string().describe('Creation timestamp'),
|
|
13
|
+
updatedAt: z.string().optional().describe('Last update timestamp'),
|
|
14
|
+
message: z.string().optional().describe('Deployment message'),
|
|
15
|
+
tags: z.array(z.string()).describe('Deployment tags'),
|
|
16
|
+
customDomains: z.array(z.string()).optional().describe('Custom domains'),
|
|
17
|
+
cloudRegion: z.string().optional().describe('Cloud region'),
|
|
18
|
+
metadata: z.any().optional().describe('Deployment metadata'),
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
export const showSubcommand = createSubcommand({
|
|
22
|
+
name: 'show',
|
|
23
|
+
description: 'Show details about a specific deployment',
|
|
24
|
+
tags: ['read-only', 'fast', 'requires-auth', 'requires-deployment'],
|
|
25
|
+
examples: [
|
|
26
|
+
`${getCommand('cloud deployment show')} dep_abc123xyz`,
|
|
27
|
+
`${getCommand('cloud deployment show')} deployment-2024-11-20 --project-id=proj_abc123xyz`,
|
|
28
|
+
],
|
|
29
|
+
aliases: ['get'],
|
|
30
|
+
requires: { auth: true, apiClient: true },
|
|
31
|
+
optional: { project: true },
|
|
32
|
+
prerequisites: ['cloud deploy'],
|
|
33
|
+
schema: {
|
|
34
|
+
args: z.object({
|
|
35
|
+
deployment_id: z.string().describe('Deployment ID'),
|
|
36
|
+
}),
|
|
37
|
+
options: z.object({
|
|
38
|
+
'project-id': z.string().optional().describe('Project ID'),
|
|
39
|
+
}),
|
|
40
|
+
response: DeploymentShowResponseSchema,
|
|
41
|
+
},
|
|
42
|
+
idempotent: true,
|
|
43
|
+
async handler(ctx) {
|
|
44
|
+
const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
|
|
45
|
+
const { apiClient, args } = ctx;
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const deployment = await projectDeploymentGet(apiClient, projectId, args.deployment_id);
|
|
49
|
+
|
|
50
|
+
tui.banner(`Deployment ${deployment.id}`, `State: ${deployment.state || 'unknown'}`);
|
|
51
|
+
|
|
52
|
+
console.log(tui.bold('ID: ') + deployment.id);
|
|
53
|
+
console.log(tui.bold('Project: ') + projectId);
|
|
54
|
+
console.log(tui.bold('State: ') + (deployment.state || 'unknown'));
|
|
55
|
+
console.log(tui.bold('Active: ') + (deployment.active ? 'Yes' : 'No'));
|
|
56
|
+
console.log(tui.bold('Created: ') + new Date(deployment.createdAt).toLocaleString());
|
|
57
|
+
if (deployment.updatedAt) {
|
|
58
|
+
console.log(tui.bold('Updated: ') + new Date(deployment.updatedAt).toLocaleString());
|
|
59
|
+
}
|
|
60
|
+
if (deployment.message) {
|
|
61
|
+
console.log(tui.bold('Message: ') + deployment.message);
|
|
62
|
+
}
|
|
63
|
+
if (deployment.tags.length > 0) {
|
|
64
|
+
console.log(tui.bold('Tags: ') + deployment.tags.join(', '));
|
|
65
|
+
}
|
|
66
|
+
if (deployment.customDomains && deployment.customDomains.length > 0) {
|
|
67
|
+
console.log(tui.bold('Domains: ') + deployment.customDomains.join(', '));
|
|
68
|
+
}
|
|
69
|
+
if (deployment.cloudRegion) {
|
|
70
|
+
console.log(tui.bold('Region: ') + deployment.cloudRegion);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Metadata
|
|
74
|
+
const origin = deployment.metadata?.origin;
|
|
75
|
+
if (origin?.commit) {
|
|
76
|
+
tui.newline();
|
|
77
|
+
tui.info('Origin Information');
|
|
78
|
+
if (origin.trigger) console.log(` Trigger: ${origin.trigger}`);
|
|
79
|
+
if (origin.provider) console.log(` Provider: ${origin.provider}`);
|
|
80
|
+
if (origin.event) console.log(` Event: ${origin.event}`);
|
|
81
|
+
if (origin.branch) console.log(` Branch: ${origin.branch}`);
|
|
82
|
+
|
|
83
|
+
if (origin.commit) {
|
|
84
|
+
console.log(` Commit: ${origin.commit.hash}`);
|
|
85
|
+
if (origin.commit.message) console.log(` Message: ${origin.commit.message}`);
|
|
86
|
+
if (origin.commit.author?.name)
|
|
87
|
+
console.log(` Author: ${origin.commit.author.name}`);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return {
|
|
92
|
+
id: deployment.id,
|
|
93
|
+
state: deployment.state,
|
|
94
|
+
active: deployment.active,
|
|
95
|
+
createdAt: deployment.createdAt,
|
|
96
|
+
updatedAt: deployment.updatedAt,
|
|
97
|
+
message: deployment.message,
|
|
98
|
+
tags: deployment.tags,
|
|
99
|
+
customDomains: deployment.customDomains,
|
|
100
|
+
cloudRegion: deployment.cloudRegion,
|
|
101
|
+
metadata: deployment.metadata,
|
|
102
|
+
};
|
|
103
|
+
} catch (ex) {
|
|
104
|
+
tui.fatal(`Failed to show deployment: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
});
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { createSubcommand } from '../../../types';
|
|
3
|
+
import * as tui from '../../../tui';
|
|
4
|
+
import { projectDeploymentUndeploy } from '@agentuity/server';
|
|
5
|
+
import { resolveProjectId } from './utils';
|
|
6
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
|
+
|
|
8
|
+
export const undeploySubcommand = createSubcommand({
|
|
9
|
+
name: 'undeploy',
|
|
10
|
+
description: 'Undeploy the latest deployment',
|
|
11
|
+
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
|
|
12
|
+
examples: [
|
|
13
|
+
`${getCommand('cloud deployment undeploy')} # Undeploy with confirmation`,
|
|
14
|
+
`${getCommand('cloud deployment undeploy')} --force # Undeploy without confirmation`,
|
|
15
|
+
`${getCommand('cloud deployment undeploy')} --project-id=proj_abc123xyz`,
|
|
16
|
+
],
|
|
17
|
+
idempotent: false,
|
|
18
|
+
requires: { auth: true, apiClient: true },
|
|
19
|
+
optional: { project: true },
|
|
20
|
+
prerequisites: ['cloud deploy'],
|
|
21
|
+
schema: {
|
|
22
|
+
options: z.object({
|
|
23
|
+
'project-id': z.string().optional().describe('Project ID'),
|
|
24
|
+
force: z.boolean().default(false).describe('Force undeploy without confirmation'),
|
|
25
|
+
}),
|
|
26
|
+
},
|
|
27
|
+
async handler(ctx) {
|
|
28
|
+
const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
|
|
29
|
+
const { apiClient, opts } = ctx;
|
|
30
|
+
|
|
31
|
+
if (!opts.force) {
|
|
32
|
+
const confirmed = await tui.confirm(
|
|
33
|
+
'Are you sure you want to undeploy? This will stop the active deployment.'
|
|
34
|
+
);
|
|
35
|
+
if (!confirmed) {
|
|
36
|
+
tui.info('Operation cancelled');
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
await projectDeploymentUndeploy(apiClient, projectId);
|
|
43
|
+
tui.success('Undeployed successfully.');
|
|
44
|
+
} catch (ex) {
|
|
45
|
+
tui.fatal(`Failed to undeploy: ${ex instanceof Error ? ex.message : String(ex)}`);
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { ProjectConfig } from '../../../types';
|
|
2
|
+
|
|
3
|
+
export function resolveProjectId(
|
|
4
|
+
ctx: { project?: ProjectConfig },
|
|
5
|
+
options: { projectId?: string }
|
|
6
|
+
): string {
|
|
7
|
+
if (options.projectId) {
|
|
8
|
+
return options.projectId;
|
|
9
|
+
}
|
|
10
|
+
if (ctx.project?.projectId) {
|
|
11
|
+
return ctx.project.projectId;
|
|
12
|
+
}
|
|
13
|
+
throw new Error('Project ID is required. Use --project-id or run from a project directory.');
|
|
14
|
+
}
|
package/src/cmd/cloud/domain.ts
CHANGED
|
@@ -23,8 +23,9 @@ export async function checkCustomDomainForDNS(
|
|
|
23
23
|
): Promise<DNSResult[]> {
|
|
24
24
|
const suffix = config?.overrides?.api_url?.includes('agentuity.io')
|
|
25
25
|
? 'agentuity.io'
|
|
26
|
-
: 'agentuity.
|
|
27
|
-
|
|
26
|
+
: 'agentuity.cloud';
|
|
27
|
+
// FIXME: update to add the region into this
|
|
28
|
+
const id = Bun.hash.xxHash64(projectId).toString(16);
|
|
28
29
|
const proxy = `p${id}.${suffix}`;
|
|
29
30
|
|
|
30
31
|
return Promise.all(
|
package/src/cmd/cloud/index.ts
CHANGED
|
@@ -3,9 +3,17 @@ import { deploySubcommand } from './deploy';
|
|
|
3
3
|
import { resourceSubcommand } from './resource';
|
|
4
4
|
import { sshSubcommand } from './ssh';
|
|
5
5
|
import { scpSubcommand } from './scp';
|
|
6
|
+
import { deploymentCommand } from './deployment';
|
|
6
7
|
|
|
7
8
|
export const command = createCommand({
|
|
8
9
|
name: 'cloud',
|
|
9
10
|
description: 'Cloud related commands',
|
|
10
|
-
|
|
11
|
+
tags: ['slow', 'requires-auth'],
|
|
12
|
+
subcommands: [
|
|
13
|
+
deploySubcommand,
|
|
14
|
+
resourceSubcommand,
|
|
15
|
+
sshSubcommand,
|
|
16
|
+
scpSubcommand,
|
|
17
|
+
deploymentCommand,
|
|
18
|
+
],
|
|
11
19
|
});
|
|
@@ -4,16 +4,30 @@ import enquirer from 'enquirer';
|
|
|
4
4
|
import { createSubcommand } from '../../../types';
|
|
5
5
|
import * as tui from '../../../tui';
|
|
6
6
|
import { getCatalystAPIClient } from '../../../config';
|
|
7
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
8
|
|
|
8
9
|
export const addSubcommand = createSubcommand({
|
|
9
10
|
name: 'add',
|
|
10
11
|
aliases: ['create'],
|
|
11
12
|
description: 'Add a cloud resource for an organization',
|
|
13
|
+
tags: ['mutating', 'creates-resource', 'slow', 'requires-auth', 'requires-deployment'],
|
|
14
|
+
idempotent: false,
|
|
12
15
|
requires: { auth: true, org: true, region: true },
|
|
16
|
+
examples: [
|
|
17
|
+
getCommand('cloud resource add'),
|
|
18
|
+
getCommand('cloud resource add --type database'),
|
|
19
|
+
getCommand('cloud resource add --type storage'),
|
|
20
|
+
getCommand('cloud resource create --type database'),
|
|
21
|
+
],
|
|
13
22
|
schema: {
|
|
14
23
|
options: z.object({
|
|
15
24
|
type: z.enum(['database', 'storage']).optional().describe('Resource type'),
|
|
16
25
|
}),
|
|
26
|
+
response: z.object({
|
|
27
|
+
success: z.boolean().describe('Whether creation succeeded'),
|
|
28
|
+
type: z.string().describe('Resource type (database or storage)'),
|
|
29
|
+
name: z.string().describe('Created resource name'),
|
|
30
|
+
}),
|
|
17
31
|
},
|
|
18
32
|
|
|
19
33
|
async handler(ctx) {
|
|
@@ -49,6 +63,11 @@ export const addSubcommand = createSubcommand({
|
|
|
49
63
|
|
|
50
64
|
if (created.length > 0) {
|
|
51
65
|
tui.success(`Created ${resourceType}: ${tui.bold(created[0].name)}`);
|
|
66
|
+
return {
|
|
67
|
+
success: true,
|
|
68
|
+
type: resourceType,
|
|
69
|
+
name: created[0].name,
|
|
70
|
+
};
|
|
52
71
|
} else {
|
|
53
72
|
tui.fatal('Failed to create resource');
|
|
54
73
|
}
|
|
@@ -4,18 +4,33 @@ import enquirer from 'enquirer';
|
|
|
4
4
|
import { createSubcommand } from '../../../types';
|
|
5
5
|
import * as tui from '../../../tui';
|
|
6
6
|
import { getCatalystAPIClient } from '../../../config';
|
|
7
|
+
import { getCommand } from '../../../command-prefix';
|
|
7
8
|
|
|
8
9
|
export const deleteSubcommand = createSubcommand({
|
|
9
10
|
name: 'delete',
|
|
10
11
|
description: 'Delete cloud resource(s) for an organization',
|
|
12
|
+
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
|
|
11
13
|
aliases: ['rm', 'del', 'remove'],
|
|
14
|
+
idempotent: false,
|
|
12
15
|
requires: { auth: true, org: true, region: true },
|
|
16
|
+
examples: [
|
|
17
|
+
getCommand('cloud resource delete'),
|
|
18
|
+
getCommand('cloud resource delete --type db --name my-database'),
|
|
19
|
+
getCommand('cloud resource delete --type s3 --name uploads'),
|
|
20
|
+
getCommand('--explain cloud resource delete --type db --name old-db'),
|
|
21
|
+
getCommand('--dry-run cloud resource rm --type s3 --name temp-bucket'),
|
|
22
|
+
],
|
|
13
23
|
schema: {
|
|
14
24
|
options: z.object({
|
|
15
25
|
type: z.enum(['db', 's3']).optional().describe('Resource type (db or s3)'),
|
|
16
26
|
name: z.string().optional().describe('Resource name to delete'),
|
|
17
27
|
confirm: z.boolean().optional().describe('Skip confirmation prompts'),
|
|
18
28
|
}),
|
|
29
|
+
response: z.object({
|
|
30
|
+
success: z.boolean().describe('Whether deletion succeeded'),
|
|
31
|
+
count: z.number().describe('Number of resources deleted'),
|
|
32
|
+
resources: z.array(z.string()).describe('Deleted resource names'),
|
|
33
|
+
}),
|
|
19
34
|
},
|
|
20
35
|
|
|
21
36
|
async handler(ctx) {
|
|
@@ -41,7 +56,7 @@ export const deleteSubcommand = createSubcommand({
|
|
|
41
56
|
|
|
42
57
|
if (resources.db.length === 0 && resources.s3.length === 0) {
|
|
43
58
|
tui.info('No resources found to delete');
|
|
44
|
-
return;
|
|
59
|
+
return { success: false, count: 0, resources: [] };
|
|
45
60
|
}
|
|
46
61
|
|
|
47
62
|
// Build choices for multi-select and resource map
|
|
@@ -81,7 +96,7 @@ export const deleteSubcommand = createSubcommand({
|
|
|
81
96
|
|
|
82
97
|
if (resourcesToDelete.length === 0) {
|
|
83
98
|
tui.info('No resources selected for deletion');
|
|
84
|
-
return;
|
|
99
|
+
return { success: false, count: 0, resources: [] };
|
|
85
100
|
}
|
|
86
101
|
|
|
87
102
|
// Confirm deletion
|
|
@@ -98,7 +113,7 @@ export const deleteSubcommand = createSubcommand({
|
|
|
98
113
|
|
|
99
114
|
if (!confirm.confirm) {
|
|
100
115
|
tui.info('Deletion cancelled');
|
|
101
|
-
return;
|
|
116
|
+
return { success: false, count: 0, resources: [] };
|
|
102
117
|
}
|
|
103
118
|
}
|
|
104
119
|
|
|
@@ -116,5 +131,11 @@ export const deleteSubcommand = createSubcommand({
|
|
|
116
131
|
} else {
|
|
117
132
|
tui.error('Failed to delete resources');
|
|
118
133
|
}
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
success: deleted.length > 0,
|
|
137
|
+
count: deleted.length,
|
|
138
|
+
resources: deleted,
|
|
139
|
+
};
|
|
119
140
|
},
|
|
120
141
|
});
|