@agentuity/cli 0.1.11 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +6 -10
- package/dist/auth.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +89 -41
- package/dist/cli.js.map +1 -1
- package/dist/cmd/auth/login.d.ts.map +1 -1
- package/dist/cmd/auth/login.js +49 -5
- package/dist/cmd/auth/login.js.map +1 -1
- package/dist/cmd/build/patch/_util.d.ts.map +1 -1
- package/dist/cmd/build/patch/_util.js +6 -2
- package/dist/cmd/build/patch/_util.js.map +1 -1
- package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
- package/dist/cmd/cloud/agent/get.js +10 -6
- package/dist/cmd/cloud/agent/get.js.map +1 -1
- package/dist/cmd/cloud/db/create.d.ts.map +1 -1
- package/dist/cmd/cloud/db/create.js +14 -3
- package/dist/cmd/cloud/db/create.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +13 -3
- package/dist/cmd/cloud/db/get.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +17 -25
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +50 -37
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +19 -2
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/get.js +14 -11
- package/dist/cmd/cloud/sandbox/execution/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +48 -39
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +6 -1
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +5 -1
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/build.js +39 -23
- package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/generate.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/generate.js +2 -0
- package/dist/cmd/cloud/sandbox/snapshot/generate.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.js +10 -7
- package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
- package/dist/cmd/cloud/session/get.d.ts.map +1 -1
- package/dist/cmd/cloud/session/get.js +24 -23
- package/dist/cmd/cloud/session/get.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +7 -2
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/thread/get.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/get.js +11 -8
- package/dist/cmd/cloud/thread/get.js.map +1 -1
- package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/list.js +6 -1
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
- package/dist/cmd/dev/file-watcher.js +2 -0
- package/dist/cmd/dev/file-watcher.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +62 -4
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +15 -1
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/cmd/setup/index.d.ts.map +1 -1
- package/dist/cmd/setup/index.js +40 -3
- package/dist/cmd/setup/index.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +3 -2
- package/dist/config.js.map +1 -1
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +4 -2
- package/dist/steps.js.map +1 -1
- package/dist/tui.d.ts +11 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +47 -12
- package/dist/tui.js.map +1 -1
- package/package.json +6 -6
- package/src/auth.ts +12 -11
- package/src/cli.ts +121 -43
- package/src/cmd/auth/login.ts +57 -5
- package/src/cmd/build/patch/_util.ts +6 -2
- package/src/cmd/cloud/agent/get.ts +14 -6
- package/src/cmd/cloud/db/create.ts +15 -3
- package/src/cmd/cloud/db/get.ts +14 -3
- package/src/cmd/cloud/db/list.ts +16 -26
- package/src/cmd/cloud/deployment/show.ts +53 -47
- package/src/cmd/cloud/sandbox/create.ts +20 -2
- package/src/cmd/cloud/sandbox/execution/get.ts +16 -13
- package/src/cmd/cloud/sandbox/get.ts +48 -38
- package/src/cmd/cloud/sandbox/list.ts +6 -1
- package/src/cmd/cloud/sandbox/run.ts +5 -1
- package/src/cmd/cloud/sandbox/snapshot/build.ts +51 -24
- package/src/cmd/cloud/sandbox/snapshot/generate.ts +2 -0
- package/src/cmd/cloud/sandbox/snapshot/get.ts +11 -7
- package/src/cmd/cloud/session/get.ts +25 -29
- package/src/cmd/cloud/session/list.ts +7 -2
- package/src/cmd/cloud/thread/get.ts +12 -8
- package/src/cmd/cloud/thread/list.ts +6 -1
- package/src/cmd/dev/file-watcher.ts +2 -0
- package/src/cmd/dev/index.ts +76 -4
- package/src/cmd/project/template-flow.ts +15 -1
- package/src/cmd/setup/index.ts +41 -3
- package/src/config.ts +3 -2
- package/src/steps.ts +4 -2
- package/src/tui.ts +61 -12
package/src/cmd/auth/login.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
1
2
|
import { createSubcommand } from '../../types';
|
|
2
|
-
import { getAppBaseURL } from '../../api';
|
|
3
|
+
import { getAPIBaseURL, getAppBaseURL } from '../../api';
|
|
3
4
|
import { saveAuth } from '../../config';
|
|
4
5
|
import { generateLoginCode, pollForLoginCompletion } from './api';
|
|
5
6
|
import * as tui from '../../tui';
|
|
@@ -17,8 +18,53 @@ export const loginCommand = createSubcommand({
|
|
|
17
18
|
{ command: getCommand('auth login'), description: 'Login to account' },
|
|
18
19
|
{ command: getCommand('login'), description: 'Login to account' },
|
|
19
20
|
],
|
|
21
|
+
schema: {
|
|
22
|
+
options: z.object({
|
|
23
|
+
setupToken: z.string().optional().describe('Use a one-time use setup token'),
|
|
24
|
+
}),
|
|
25
|
+
response: z.object({ success: z.boolean() }),
|
|
26
|
+
},
|
|
20
27
|
async handler(ctx) {
|
|
21
|
-
const { logger, config, apiClient } = ctx;
|
|
28
|
+
const { logger, config, apiClient, opts, options } = ctx;
|
|
29
|
+
|
|
30
|
+
if (opts.setupToken) {
|
|
31
|
+
const url = getAPIBaseURL(config);
|
|
32
|
+
try {
|
|
33
|
+
const res = await fetch(
|
|
34
|
+
`${url}/cli/auth/setup-token/${encodeURIComponent(opts.setupToken)}`,
|
|
35
|
+
{
|
|
36
|
+
signal: AbortSignal.timeout(5000),
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
if (res.ok) {
|
|
40
|
+
const result = (await res.json()) as {
|
|
41
|
+
success: boolean;
|
|
42
|
+
message: string;
|
|
43
|
+
data?: { apiKey: string; expiresAt: number; userId: string };
|
|
44
|
+
};
|
|
45
|
+
if (result.success && result.data) {
|
|
46
|
+
await saveAuth({
|
|
47
|
+
apiKey: result.data.apiKey,
|
|
48
|
+
userId: result.data.userId,
|
|
49
|
+
expires: new Date(result.data.expiresAt),
|
|
50
|
+
});
|
|
51
|
+
if (!options.json) {
|
|
52
|
+
tui.success('Welcome to Agentuity! You are now logged in');
|
|
53
|
+
}
|
|
54
|
+
return { success: true };
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
throw new Error(await res.text());
|
|
58
|
+
}
|
|
59
|
+
} catch (ex) {
|
|
60
|
+
if (options.json) {
|
|
61
|
+
return {
|
|
62
|
+
success: false,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
tui.error(`error validating the setup token: ${ex}`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
22
68
|
|
|
23
69
|
const appUrl = getAppBaseURL(config);
|
|
24
70
|
|
|
@@ -32,7 +78,7 @@ export const loginCommand = createSubcommand({
|
|
|
32
78
|
});
|
|
33
79
|
|
|
34
80
|
if (!code) {
|
|
35
|
-
return;
|
|
81
|
+
return { success: false };
|
|
36
82
|
}
|
|
37
83
|
|
|
38
84
|
const authURL = `${appUrl}/auth/cli?code=${code}`;
|
|
@@ -84,11 +130,17 @@ export const loginCommand = createSubcommand({
|
|
|
84
130
|
expires: result.expires,
|
|
85
131
|
});
|
|
86
132
|
|
|
87
|
-
|
|
88
|
-
|
|
133
|
+
if (!options.json) {
|
|
134
|
+
tui.newline();
|
|
135
|
+
tui.success('Welcome to Agentuity! You are now logged in');
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
return { success: true };
|
|
89
139
|
} catch (error) {
|
|
90
140
|
logger.trace(error);
|
|
91
141
|
logger.fatal('Login failed: %s', error, ErrorCode.AUTH_FAILED);
|
|
92
142
|
}
|
|
143
|
+
|
|
144
|
+
return { success: false };
|
|
93
145
|
},
|
|
94
146
|
});
|
|
@@ -17,9 +17,13 @@ export interface PatchModule {
|
|
|
17
17
|
|
|
18
18
|
export function generateEnvWarning(envkey: string): string {
|
|
19
19
|
return `if (process.env.AGENTUITY_ENVIRONMENT === 'development' || process.env.NODE_ENV !== 'production') {
|
|
20
|
-
console.error('
|
|
20
|
+
console.error('[ERROR] No credentials found for this AI provider. To fix this, either:');
|
|
21
|
+
console.error(' 1. Login to Agentuity Cloud (agentuity auth login) to use the AI Gateway (recommended)');
|
|
22
|
+
console.error(' 2. Set ${envkey} in your .env file to use the provider directly');
|
|
21
23
|
} else {
|
|
22
|
-
console.error('The
|
|
24
|
+
console.error('[ERROR] The environment variable ${envkey} is required. Either:');
|
|
25
|
+
console.error(' 1. Use Agentuity Cloud AI Gateway by ensuring AGENTUITY_SDK_KEY is configured');
|
|
26
|
+
console.error(' 2. Set ${envkey} using "agentuity env set ${envkey}" and redeploy');
|
|
23
27
|
}
|
|
24
28
|
`;
|
|
25
29
|
}
|
|
@@ -43,12 +43,20 @@ export const getSubcommand = createSubcommand({
|
|
|
43
43
|
}
|
|
44
44
|
|
|
45
45
|
// Display agent details
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
46
|
+
tui.table(
|
|
47
|
+
[
|
|
48
|
+
{
|
|
49
|
+
ID: agent.identifier,
|
|
50
|
+
Name: agent.name,
|
|
51
|
+
Description: agent.description || 'N/A',
|
|
52
|
+
'Dev Mode': agent.devmode ? 'Yes' : 'No',
|
|
53
|
+
Created: new Date(agent.createdAt).toLocaleString(),
|
|
54
|
+
Updated: new Date(agent.updatedAt).toLocaleString(),
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
['ID', 'Name', 'Description', 'Dev Mode', 'Created', 'Updated'],
|
|
58
|
+
{ layout: 'vertical', padStart: ' ' }
|
|
59
|
+
);
|
|
52
60
|
|
|
53
61
|
// Display metadata if present
|
|
54
62
|
if (agent.metadata && Object.keys(agent.metadata).length > 0) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
|
-
import { createResources, APIError } from '@agentuity/server';
|
|
2
|
+
import { createResources, APIError, validateDatabaseName } from '@agentuity/server';
|
|
3
3
|
import { createSubcommand as defineSubcommand } from '../../../types';
|
|
4
4
|
import * as tui from '../../../tui';
|
|
5
5
|
import { getCatalystAPIClient } from '../../../config';
|
|
@@ -24,6 +24,7 @@ export const createSubcommand = defineSubcommand({
|
|
|
24
24
|
schema: {
|
|
25
25
|
options: z.object({
|
|
26
26
|
name: z.string().optional().describe('Custom database name'),
|
|
27
|
+
description: z.string().optional().describe('Optional database description'),
|
|
27
28
|
}),
|
|
28
29
|
response: z.object({
|
|
29
30
|
success: z.boolean().describe('Whether creation succeeded'),
|
|
@@ -34,11 +35,22 @@ export const createSubcommand = defineSubcommand({
|
|
|
34
35
|
async handler(ctx) {
|
|
35
36
|
const { logger, opts, orgId, region, auth, options } = ctx;
|
|
36
37
|
|
|
38
|
+
// Validate database name if provided
|
|
39
|
+
if (opts.name) {
|
|
40
|
+
const validation = validateDatabaseName(opts.name);
|
|
41
|
+
if (!validation.valid) {
|
|
42
|
+
tui.fatal(validation.error!, ErrorCode.INVALID_ARGUMENT);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
// Handle dry-run mode
|
|
38
47
|
if (isDryRunMode(options)) {
|
|
39
|
-
|
|
48
|
+
let message = opts.name
|
|
40
49
|
? `Would create database with name: ${opts.name} in region: ${region}`
|
|
41
50
|
: `Would create database in region: ${region}`;
|
|
51
|
+
if (opts.description) {
|
|
52
|
+
message += ` with description: "${opts.description}"`;
|
|
53
|
+
}
|
|
42
54
|
outputDryRun(message, options);
|
|
43
55
|
if (!options.json) {
|
|
44
56
|
tui.newline();
|
|
@@ -58,7 +70,7 @@ export const createSubcommand = defineSubcommand({
|
|
|
58
70
|
clearOnSuccess: true,
|
|
59
71
|
callback: async () => {
|
|
60
72
|
return await createResources(catalystClient, orgId, region!, [
|
|
61
|
-
{ type: 'db', name: opts.name },
|
|
73
|
+
{ type: 'db', name: opts.name, description: opts.description },
|
|
62
74
|
]);
|
|
63
75
|
},
|
|
64
76
|
});
|
package/src/cmd/cloud/db/get.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { getResourceInfo, setResourceInfo } from '../../../cache';
|
|
|
10
10
|
const DBGetResponseSchema = z
|
|
11
11
|
.object({
|
|
12
12
|
name: z.string().describe('Database name'),
|
|
13
|
+
description: z.string().optional().describe('Database description'),
|
|
13
14
|
url: z.string().optional().describe('Database connection URL'),
|
|
14
15
|
})
|
|
15
16
|
.or(
|
|
@@ -171,15 +172,25 @@ export const getSubcommand = createSubcommand({
|
|
|
171
172
|
const shouldMask = !options.json && !shouldShowCredentials;
|
|
172
173
|
|
|
173
174
|
if (!options.json) {
|
|
174
|
-
|
|
175
|
+
const tableData: Record<string, string> = {
|
|
176
|
+
Name: tui.bold(db.name),
|
|
177
|
+
};
|
|
178
|
+
if (db.description) {
|
|
179
|
+
tableData['Description'] = db.description;
|
|
180
|
+
}
|
|
181
|
+
if (db.cloud_region) {
|
|
182
|
+
tableData['Region'] = db.cloud_region;
|
|
183
|
+
}
|
|
175
184
|
if (db.url) {
|
|
176
|
-
|
|
177
|
-
console.log(tui.bold('URL: ') + displayUrl);
|
|
185
|
+
tableData['URL'] = shouldMask ? tui.maskSecret(db.url) : db.url;
|
|
178
186
|
}
|
|
187
|
+
|
|
188
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
179
189
|
}
|
|
180
190
|
|
|
181
191
|
return {
|
|
182
192
|
name: db.name,
|
|
193
|
+
description: db.description ?? undefined,
|
|
183
194
|
url: db.url ?? undefined,
|
|
184
195
|
};
|
|
185
196
|
},
|
package/src/cmd/cloud/db/list.ts
CHANGED
|
@@ -4,13 +4,13 @@ import { createSubcommand } from '../../../types';
|
|
|
4
4
|
import * as tui from '../../../tui';
|
|
5
5
|
import { getGlobalCatalystAPIClient } from '../../../config';
|
|
6
6
|
import { getCommand } from '../../../command-prefix';
|
|
7
|
-
import { setResourceInfo } from '../../../cache';
|
|
8
7
|
|
|
9
8
|
const DBListResponseSchema = z.object({
|
|
10
9
|
databases: z
|
|
11
10
|
.array(
|
|
12
11
|
z.object({
|
|
13
12
|
name: z.string().describe('Database name'),
|
|
13
|
+
description: z.string().optional().describe('Database description'),
|
|
14
14
|
url: z.string().optional().describe('Database connection URL'),
|
|
15
15
|
cloud_region: z.string().optional().describe('Cloud region where database is hosted'),
|
|
16
16
|
})
|
|
@@ -23,7 +23,7 @@ export const listSubcommand = createSubcommand({
|
|
|
23
23
|
aliases: ['ls'],
|
|
24
24
|
description: 'List database resources',
|
|
25
25
|
tags: ['read-only', 'fast', 'requires-auth'],
|
|
26
|
-
requires: { auth: true
|
|
26
|
+
requires: { auth: true },
|
|
27
27
|
idempotent: true,
|
|
28
28
|
examples: [
|
|
29
29
|
{ command: getCommand('cloud db list'), description: 'List items' },
|
|
@@ -49,24 +49,18 @@ export const listSubcommand = createSubcommand({
|
|
|
49
49
|
webUrl: '/services/database',
|
|
50
50
|
|
|
51
51
|
async handler(ctx) {
|
|
52
|
-
const { logger, opts, options,
|
|
52
|
+
const { logger, opts, options, auth, config } = ctx;
|
|
53
53
|
|
|
54
54
|
const catalystClient = await getGlobalCatalystAPIClient(logger, auth, config?.name);
|
|
55
55
|
|
|
56
|
-
const profileName = config?.name ?? 'production';
|
|
57
56
|
const resources = await tui.spinner({
|
|
58
|
-
message:
|
|
57
|
+
message: 'Fetching databases',
|
|
59
58
|
clearOnSuccess: true,
|
|
60
59
|
callback: async () => {
|
|
61
|
-
return listOrgResources(catalystClient, { type: 'db'
|
|
60
|
+
return listOrgResources(catalystClient, { type: 'db' });
|
|
62
61
|
},
|
|
63
62
|
});
|
|
64
63
|
|
|
65
|
-
// Cache each database with its region and orgId for future lookups
|
|
66
|
-
for (const db of resources.db) {
|
|
67
|
-
await setResourceInfo('db', profileName, db.name, db.cloud_region, orgId);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
64
|
// Mask credentials in terminal output by default, unless --show-credentials is passed
|
|
71
65
|
const shouldShowCredentials = opts.showCredentials === true;
|
|
72
66
|
const shouldMask = !options.json && !shouldShowCredentials;
|
|
@@ -74,29 +68,25 @@ export const listSubcommand = createSubcommand({
|
|
|
74
68
|
if (!options.json) {
|
|
75
69
|
if (resources.db.length === 0) {
|
|
76
70
|
tui.info('No databases found');
|
|
77
|
-
} else {
|
|
78
|
-
if (!opts.nameOnly) {
|
|
79
|
-
tui.info(tui.bold('Databases'));
|
|
80
|
-
tui.newline();
|
|
81
|
-
}
|
|
71
|
+
} else if (opts.nameOnly) {
|
|
82
72
|
for (const db of resources.db) {
|
|
83
|
-
|
|
84
|
-
console.log(db.name);
|
|
85
|
-
continue;
|
|
86
|
-
}
|
|
87
|
-
console.log(tui.bold(db.name));
|
|
88
|
-
if (db.url) {
|
|
89
|
-
const displayUrl = shouldMask ? tui.maskSecret(db.url) : db.url;
|
|
90
|
-
console.log(` URL: ${tui.muted(displayUrl)}`);
|
|
91
|
-
}
|
|
92
|
-
tui.newline();
|
|
73
|
+
console.log(db.name);
|
|
93
74
|
}
|
|
75
|
+
} else {
|
|
76
|
+
const tableData = resources.db.map((db) => ({
|
|
77
|
+
Name: db.name,
|
|
78
|
+
Description: db.description ?? '',
|
|
79
|
+
Region: db.cloud_region,
|
|
80
|
+
URL: db.url ? (shouldMask ? tui.maskSecret(db.url) : db.url) : '',
|
|
81
|
+
}));
|
|
82
|
+
tui.table(tableData);
|
|
94
83
|
}
|
|
95
84
|
}
|
|
96
85
|
|
|
97
86
|
return {
|
|
98
87
|
databases: resources.db.map((db) => ({
|
|
99
88
|
name: db.name,
|
|
89
|
+
description: db.description ?? undefined,
|
|
100
90
|
url: db.url ?? undefined,
|
|
101
91
|
cloud_region: db.cloud_region,
|
|
102
92
|
})),
|
|
@@ -90,82 +90,88 @@ export const showSubcommand = createSubcommand({
|
|
|
90
90
|
|
|
91
91
|
// Skip TUI output in JSON mode
|
|
92
92
|
if (!options.json) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
new Date(deployment.createdAt).toLocaleString()
|
|
101
|
-
);
|
|
93
|
+
const tableData: Record<string, string> = {
|
|
94
|
+
ID: deployment.id,
|
|
95
|
+
Project: projectId,
|
|
96
|
+
State: deployment.state || 'unknown',
|
|
97
|
+
Active: deployment.active ? 'Yes' : 'No',
|
|
98
|
+
Created: new Date(deployment.createdAt).toLocaleString(),
|
|
99
|
+
};
|
|
102
100
|
if (deployment.updatedAt) {
|
|
103
|
-
|
|
104
|
-
tui.bold('Updated:'.padEnd(maxWidth)) +
|
|
105
|
-
new Date(deployment.updatedAt).toLocaleString()
|
|
106
|
-
);
|
|
101
|
+
tableData['Updated'] = new Date(deployment.updatedAt).toLocaleString();
|
|
107
102
|
}
|
|
108
103
|
if (deployment.message) {
|
|
109
|
-
|
|
104
|
+
tableData['Message'] = deployment.message;
|
|
110
105
|
}
|
|
111
106
|
if (deployment.tags.length > 0) {
|
|
112
|
-
|
|
107
|
+
tableData['Tags'] = deployment.tags.join(', ');
|
|
113
108
|
}
|
|
114
109
|
if (deployment.customDomains && deployment.customDomains.length > 0) {
|
|
115
|
-
|
|
116
|
-
tui.bold('Domains:'.padEnd(maxWidth)) + deployment.customDomains.join(', ')
|
|
117
|
-
);
|
|
110
|
+
tableData['Domains'] = deployment.customDomains.join(', ');
|
|
118
111
|
}
|
|
119
112
|
if (deployment.cloudRegion) {
|
|
120
|
-
|
|
113
|
+
tableData['Region'] = deployment.cloudRegion;
|
|
121
114
|
}
|
|
122
115
|
if (deployment.resourceDb) {
|
|
123
|
-
|
|
116
|
+
tableData['Database'] = deployment.resourceDb;
|
|
124
117
|
}
|
|
125
118
|
if (deployment.resourceStorage) {
|
|
126
|
-
|
|
119
|
+
tableData['Storage'] = deployment.resourceStorage;
|
|
127
120
|
}
|
|
128
121
|
if (deployment.deploymentLogsURL) {
|
|
129
|
-
|
|
130
|
-
tui.bold('Deployment Logs:'.padEnd(maxWidth)) +
|
|
131
|
-
tui.link(deployment.deploymentLogsURL)
|
|
132
|
-
);
|
|
122
|
+
tableData['Deployment Logs'] = tui.link(deployment.deploymentLogsURL);
|
|
133
123
|
}
|
|
134
124
|
if (deployment.buildLogsURL) {
|
|
135
|
-
|
|
136
|
-
tui.bold('Build Logs:'.padEnd(maxWidth)) + tui.link(deployment.buildLogsURL)
|
|
137
|
-
);
|
|
125
|
+
tableData['Build Logs'] = tui.link(deployment.buildLogsURL);
|
|
138
126
|
}
|
|
139
127
|
|
|
128
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
129
|
+
|
|
140
130
|
// Git metadata
|
|
141
131
|
const git = deployment.metadata?.git;
|
|
142
132
|
if (git) {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
if (git.
|
|
146
|
-
if (git.
|
|
147
|
-
if (git.
|
|
148
|
-
if (git.
|
|
149
|
-
if (git.
|
|
150
|
-
if (git.
|
|
151
|
-
if (git.
|
|
152
|
-
if (git.event) console.log(` Event: ${git.event}`);
|
|
133
|
+
const gitData: Record<string, string> = {};
|
|
134
|
+
if (git.repo) gitData['Repo'] = git.repo;
|
|
135
|
+
if (git.branch) gitData['Branch'] = git.branch;
|
|
136
|
+
if (git.commit) gitData['Commit'] = git.commit;
|
|
137
|
+
if (git.message) gitData['Message'] = git.message;
|
|
138
|
+
if (git.url) gitData['URL'] = git.url;
|
|
139
|
+
if (git.trigger) gitData['Trigger'] = git.trigger;
|
|
140
|
+
if (git.provider) gitData['Provider'] = git.provider;
|
|
141
|
+
if (git.event) gitData['Event'] = git.event;
|
|
153
142
|
if (git.pull_request) {
|
|
154
|
-
|
|
155
|
-
if (git.pull_request.url)
|
|
143
|
+
gitData['PR'] = `#${git.pull_request.number}`;
|
|
144
|
+
if (git.pull_request.url) gitData['PR URL'] = git.pull_request.url;
|
|
145
|
+
}
|
|
146
|
+
if (git.buildUrl) gitData['Build'] = git.buildUrl;
|
|
147
|
+
|
|
148
|
+
if (Object.keys(gitData).length > 0) {
|
|
149
|
+
tui.newline();
|
|
150
|
+
tui.info('Git Information');
|
|
151
|
+
tui.table([gitData], Object.keys(gitData), {
|
|
152
|
+
layout: 'vertical',
|
|
153
|
+
padStart: ' ',
|
|
154
|
+
});
|
|
156
155
|
}
|
|
157
|
-
if (git.buildUrl) console.log(` Build: ${git.buildUrl}`);
|
|
158
156
|
}
|
|
159
157
|
|
|
160
158
|
// Build metadata
|
|
161
159
|
const build = deployment.metadata?.build;
|
|
162
160
|
if (build) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (build.
|
|
166
|
-
if (build.
|
|
167
|
-
if (build.
|
|
168
|
-
|
|
161
|
+
const buildData: Record<string, string> = {};
|
|
162
|
+
if (build.agentuity) buildData['Agentuity'] = build.agentuity;
|
|
163
|
+
if (build.bun) buildData['Bun'] = build.bun;
|
|
164
|
+
if (build.platform) buildData['Platform'] = build.platform;
|
|
165
|
+
if (build.arch) buildData['Arch'] = build.arch;
|
|
166
|
+
|
|
167
|
+
if (Object.keys(buildData).length > 0) {
|
|
168
|
+
tui.newline();
|
|
169
|
+
tui.info('Build Information');
|
|
170
|
+
tui.table([buildData], Object.keys(buildData), {
|
|
171
|
+
layout: 'vertical',
|
|
172
|
+
padStart: ' ',
|
|
173
|
+
});
|
|
174
|
+
}
|
|
169
175
|
}
|
|
170
176
|
}
|
|
171
177
|
|
|
@@ -25,6 +25,7 @@ export const createSubcommand = createCommand({
|
|
|
25
25
|
description: 'Create an interactive sandbox for multiple executions',
|
|
26
26
|
tags: ['slow', 'requires-auth'],
|
|
27
27
|
requires: { auth: true, region: true, org: true },
|
|
28
|
+
optional: { project: true },
|
|
28
29
|
examples: [
|
|
29
30
|
{
|
|
30
31
|
command: getCommand('cloud sandbox create'),
|
|
@@ -46,6 +47,10 @@ export const createSubcommand = createCommand({
|
|
|
46
47
|
command: getCommand('cloud sandbox create --env KEY=VAL'),
|
|
47
48
|
description: 'Create a sandbox with a specific environment variable',
|
|
48
49
|
},
|
|
50
|
+
{
|
|
51
|
+
command: getCommand('cloud sandbox create --project-id proj_123'),
|
|
52
|
+
description: 'Create a sandbox associated with a specific project',
|
|
53
|
+
},
|
|
49
54
|
],
|
|
50
55
|
schema: {
|
|
51
56
|
options: z.object({
|
|
@@ -72,12 +77,21 @@ export const createSubcommand = createCommand({
|
|
|
72
77
|
.optional()
|
|
73
78
|
.describe('Apt packages to install (can be specified multiple times)'),
|
|
74
79
|
metadata: z.string().optional().describe('JSON object of user-defined metadata'),
|
|
80
|
+
port: z
|
|
81
|
+
.number()
|
|
82
|
+
.int()
|
|
83
|
+
.min(1024)
|
|
84
|
+
.max(65535)
|
|
85
|
+
.optional()
|
|
86
|
+
.describe('Port to expose from the sandbox to the outside Internet (1024-65535)'),
|
|
87
|
+
projectId: z.string().optional().describe('Project ID to associate this sandbox with'),
|
|
75
88
|
}),
|
|
76
89
|
response: SandboxCreateResponseSchema,
|
|
77
90
|
},
|
|
78
91
|
|
|
79
92
|
async handler(ctx) {
|
|
80
|
-
const { opts, options, auth, region, config, logger, orgId } = ctx;
|
|
93
|
+
const { opts, options, auth, region, config, logger, orgId, project } = ctx;
|
|
94
|
+
const projectId = opts.projectId || project?.projectId;
|
|
81
95
|
const client = createSandboxClient(logger, auth, region);
|
|
82
96
|
const started = Date.now();
|
|
83
97
|
|
|
@@ -152,6 +166,7 @@ export const createSubcommand = createCommand({
|
|
|
152
166
|
|
|
153
167
|
const result = await sandboxCreate(client, {
|
|
154
168
|
options: {
|
|
169
|
+
projectId,
|
|
155
170
|
runtime: opts.runtime,
|
|
156
171
|
runtimeId: opts.runtimeId,
|
|
157
172
|
name: opts.name,
|
|
@@ -164,7 +179,10 @@ export const createSubcommand = createCommand({
|
|
|
164
179
|
disk: opts.disk,
|
|
165
180
|
}
|
|
166
181
|
: undefined,
|
|
167
|
-
network:
|
|
182
|
+
network:
|
|
183
|
+
opts.network || opts.port
|
|
184
|
+
? { enabled: opts.network || opts.port !== undefined, port: opts.port }
|
|
185
|
+
: undefined,
|
|
168
186
|
timeout: opts.idleTimeout ? { idle: opts.idleTimeout } : undefined,
|
|
169
187
|
env: Object.keys(envMap).length > 0 ? envMap : undefined,
|
|
170
188
|
command: hasFiles ? { exec: [], files } : undefined,
|
|
@@ -55,36 +55,39 @@ export const getSubcommand = createCommand({
|
|
|
55
55
|
? tui.colorError
|
|
56
56
|
: tui.colorMuted;
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
58
|
+
const tableData: Record<string, string | number> = {
|
|
59
|
+
Execution: tui.bold(result.executionId),
|
|
60
|
+
Sandbox: result.sandboxId,
|
|
61
|
+
Status: statusColor(result.status),
|
|
62
|
+
};
|
|
63
|
+
|
|
61
64
|
if (result.exitCode !== undefined) {
|
|
62
65
|
const exitCodeColor = result.exitCode === 0 ? tui.colorSuccess : tui.colorError;
|
|
63
|
-
|
|
64
|
-
`${tui.muted('Exit Code:')} ${exitCodeColor(String(result.exitCode))}`
|
|
65
|
-
);
|
|
66
|
+
tableData['Exit Code'] = exitCodeColor(String(result.exitCode));
|
|
66
67
|
}
|
|
67
68
|
if (result.durationMs !== undefined) {
|
|
68
|
-
|
|
69
|
+
tableData['Duration'] = `${result.durationMs}ms`;
|
|
69
70
|
}
|
|
70
71
|
if (result.startedAt) {
|
|
71
|
-
|
|
72
|
+
tableData['Started'] = result.startedAt;
|
|
72
73
|
}
|
|
73
74
|
if (result.completedAt) {
|
|
74
|
-
|
|
75
|
+
tableData['Completed'] = result.completedAt;
|
|
75
76
|
}
|
|
76
77
|
if (result.error) {
|
|
77
|
-
|
|
78
|
+
tableData['Error'] = tui.colorError(result.error);
|
|
78
79
|
}
|
|
79
80
|
if (result.stdoutStreamUrl) {
|
|
80
|
-
|
|
81
|
+
tableData['Stdout'] = result.stdoutStreamUrl;
|
|
81
82
|
}
|
|
82
83
|
if (result.stderrStreamUrl) {
|
|
83
|
-
|
|
84
|
+
tableData['Stderr'] = result.stderrStreamUrl;
|
|
84
85
|
}
|
|
85
86
|
if (result.command && result.command.length > 0) {
|
|
86
|
-
|
|
87
|
+
tableData['Command'] = result.command.join(' ');
|
|
87
88
|
}
|
|
89
|
+
|
|
90
|
+
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
88
91
|
}
|
|
89
92
|
|
|
90
93
|
return {
|