@agentuity/cli 0.1.9 → 0.1.10
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/README.md +2 -2
- package/bin/cli.ts +8 -0
- package/dist/cache/index.d.ts +2 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/index.js +2 -0
- package/dist/cache/index.js.map +1 -0
- package/dist/cache/resource-region.d.ts +46 -0
- package/dist/cache/resource-region.d.ts.map +1 -0
- package/dist/cache/resource-region.js +115 -0
- package/dist/cache/resource-region.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +44 -32
- package/dist/cli.js.map +1 -1
- package/dist/cmd/ai/capabilities/show.d.ts.map +1 -1
- package/dist/cmd/ai/capabilities/show.js +12 -15
- package/dist/cmd/ai/capabilities/show.js.map +1 -1
- package/dist/cmd/ai/prompt/llm.js +5 -5
- package/dist/cmd/ai/prompt/llm.js.map +1 -1
- package/dist/cmd/auth/logout.d.ts.map +1 -1
- package/dist/cmd/auth/logout.js +5 -2
- package/dist/cmd/auth/logout.js.map +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +87 -1
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +8 -3
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +5 -3
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/cloud/db/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/db/delete.js +69 -11
- package/dist/cmd/cloud/db/delete.js.map +1 -1
- package/dist/cmd/cloud/db/get.d.ts.map +1 -1
- package/dist/cmd/cloud/db/get.js +23 -7
- 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 +15 -7
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/db/logs.d.ts.map +1 -1
- package/dist/cmd/cloud/db/logs.js +24 -4
- package/dist/cmd/cloud/db/logs.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +38 -0
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/env/delete.js +30 -13
- package/dist/cmd/cloud/env/delete.js.map +1 -1
- package/dist/cmd/cloud/env/get.d.ts.map +1 -1
- package/dist/cmd/cloud/env/get.js +27 -30
- package/dist/cmd/cloud/env/get.js.map +1 -1
- package/dist/cmd/cloud/env/import.d.ts.map +1 -1
- package/dist/cmd/cloud/env/import.js +41 -48
- package/dist/cmd/cloud/env/import.js.map +1 -1
- package/dist/cmd/cloud/env/index.d.ts.map +1 -1
- package/dist/cmd/cloud/env/index.js +6 -2
- package/dist/cmd/cloud/env/index.js.map +1 -1
- package/dist/cmd/cloud/env/list.d.ts.map +1 -1
- package/dist/cmd/cloud/env/list.js +51 -28
- package/dist/cmd/cloud/env/list.js.map +1 -1
- package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
- package/dist/cmd/cloud/env/pull.js +3 -3
- package/dist/cmd/cloud/env/pull.js.map +1 -1
- package/dist/cmd/cloud/env/push.d.ts.map +1 -1
- package/dist/cmd/cloud/env/push.js +31 -11
- package/dist/cmd/cloud/env/push.js.map +1 -1
- package/dist/cmd/cloud/env/set.d.ts.map +1 -1
- package/dist/cmd/cloud/env/set.js +41 -26
- package/dist/cmd/cloud/env/set.js.map +1 -1
- package/dist/cmd/cloud/index.d.ts.map +1 -1
- package/dist/cmd/cloud/index.js +0 -2
- package/dist/cmd/cloud/index.js.map +1 -1
- package/dist/cmd/cloud/region-lookup.d.ts +18 -0
- package/dist/cmd/cloud/region-lookup.d.ts.map +1 -0
- package/dist/cmd/cloud/region-lookup.js +64 -0
- package/dist/cmd/cloud/region-lookup.js.map +1 -0
- package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/cp.js +5 -3
- package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +43 -6
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +5 -3
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/download.js +4 -3
- package/dist/cmd/cloud/sandbox/download.js.map +1 -1
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/env.js +4 -3
- package/dist/cmd/cloud/sandbox/env.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +4 -3
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/get.js +4 -4
- package/dist/cmd/cloud/sandbox/execution/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/index.js +1 -1
- package/dist/cmd/cloud/sandbox/execution/index.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.js +4 -3
- package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +9 -4
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/index.js +1 -1
- package/dist/cmd/cloud/sandbox/index.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +4 -4
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/ls.js +4 -3
- package/dist/cmd/cloud/sandbox/ls.js.map +1 -1
- package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/mkdir.js +4 -3
- package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/rm.js +4 -3
- package/dist/cmd/cloud/sandbox/rm.js.map +1 -1
- package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/rmdir.js +4 -3
- package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +44 -6
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/index.js +1 -1
- package/dist/cmd/cloud/sandbox/runtime/index.js.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.js +4 -4
- package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/create.js +5 -3
- package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/delete.js +4 -4
- package/dist/cmd/cloud/sandbox/snapshot/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.js +4 -4
- package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/index.js +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/index.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.js +4 -4
- package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/tag.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/tag.js +4 -4
- package/dist/cmd/cloud/sandbox/snapshot/tag.js.map +1 -1
- package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/upload.js +4 -3
- package/dist/cmd/cloud/sandbox/upload.js.map +1 -1
- package/dist/cmd/cloud/sandbox/util.d.ts +13 -0
- package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/util.js +40 -1
- package/dist/cmd/cloud/sandbox/util.js.map +1 -1
- package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
- package/dist/cmd/cloud/scp/download.js +6 -2
- package/dist/cmd/cloud/scp/download.js.map +1 -1
- package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/scp/upload.js +6 -2
- package/dist/cmd/cloud/scp/upload.js.map +1 -1
- package/dist/cmd/cloud/session/get.js +4 -4
- package/dist/cmd/cloud/session/get.js.map +1 -1
- package/dist/cmd/cloud/session/list.js +4 -4
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/ssh.d.ts.map +1 -1
- package/dist/cmd/cloud/ssh.js +7 -2
- package/dist/cmd/cloud/ssh.js.map +1 -1
- package/dist/cmd/cloud/storage/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/delete.js +46 -10
- package/dist/cmd/cloud/storage/delete.js.map +1 -1
- package/dist/cmd/cloud/storage/download.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/download.js +19 -6
- package/dist/cmd/cloud/storage/download.js.map +1 -1
- package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/get.js +19 -6
- package/dist/cmd/cloud/storage/get.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +17 -7
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/storage/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/upload.js +19 -6
- package/dist/cmd/cloud/storage/upload.js.map +1 -1
- package/dist/cmd/cloud/thread/delete.js +4 -4
- package/dist/cmd/cloud/thread/delete.js.map +1 -1
- package/dist/cmd/cloud/thread/get.js +4 -4
- package/dist/cmd/cloud/thread/get.js.map +1 -1
- package/dist/cmd/cloud/thread/list.js +4 -4
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/project/auth/init.d.ts.map +1 -1
- package/dist/cmd/project/auth/init.js +6 -3
- package/dist/cmd/project/auth/init.js.map +1 -1
- package/dist/cmd/project/auth/shared.d.ts +6 -2
- package/dist/cmd/project/auth/shared.d.ts.map +1 -1
- package/dist/cmd/project/auth/shared.js +40 -12
- package/dist/cmd/project/auth/shared.js.map +1 -1
- package/dist/config.d.ts +37 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +51 -8
- package/dist/config.js.map +1 -1
- package/dist/env-util.d.ts +25 -2
- package/dist/env-util.d.ts.map +1 -1
- package/dist/env-util.js +44 -4
- package/dist/env-util.js.map +1 -1
- package/dist/utils/apt-validator.d.ts +20 -0
- package/dist/utils/apt-validator.d.ts.map +1 -0
- package/dist/utils/apt-validator.js +157 -0
- package/dist/utils/apt-validator.js.map +1 -0
- package/package.json +6 -6
- package/src/cache/index.ts +11 -0
- package/src/cache/resource-region.ts +183 -0
- package/src/cli.ts +47 -38
- package/src/cmd/ai/capabilities/show.ts +12 -15
- package/src/cmd/ai/prompt/llm.ts +5 -5
- package/src/cmd/auth/logout.ts +5 -2
- package/src/cmd/build/ast.ts +160 -1
- package/src/cmd/build/vite/vite-asset-server-config.ts +7 -3
- package/src/cmd/build/vite/vite-asset-server.ts +6 -3
- package/src/cmd/cloud/db/delete.ts +83 -11
- package/src/cmd/cloud/db/get.ts +29 -7
- package/src/cmd/cloud/db/list.ts +16 -7
- package/src/cmd/cloud/db/logs.ts +33 -4
- package/src/cmd/cloud/deploy.ts +49 -0
- package/src/cmd/cloud/env/delete.ts +36 -12
- package/src/cmd/cloud/env/get.ts +28 -27
- package/src/cmd/cloud/env/import.ts +43 -56
- package/src/cmd/cloud/env/index.ts +6 -2
- package/src/cmd/cloud/env/list.ts +57 -30
- package/src/cmd/cloud/env/pull.ts +9 -3
- package/src/cmd/cloud/env/push.ts +44 -11
- package/src/cmd/cloud/env/set.ts +49 -30
- package/src/cmd/cloud/index.ts +0 -2
- package/src/cmd/cloud/region-lookup.ts +89 -0
- package/src/cmd/cloud/sandbox/cp.ts +5 -3
- package/src/cmd/cloud/sandbox/create.ts +50 -6
- package/src/cmd/cloud/sandbox/delete.ts +6 -3
- package/src/cmd/cloud/sandbox/download.ts +4 -3
- package/src/cmd/cloud/sandbox/env.ts +4 -3
- package/src/cmd/cloud/sandbox/exec.ts +4 -3
- package/src/cmd/cloud/sandbox/execution/get.ts +4 -4
- package/src/cmd/cloud/sandbox/execution/index.ts +1 -1
- package/src/cmd/cloud/sandbox/execution/list.ts +4 -3
- package/src/cmd/cloud/sandbox/get.ts +10 -4
- package/src/cmd/cloud/sandbox/index.ts +1 -1
- package/src/cmd/cloud/sandbox/list.ts +4 -4
- package/src/cmd/cloud/sandbox/ls.ts +4 -3
- package/src/cmd/cloud/sandbox/mkdir.ts +4 -3
- package/src/cmd/cloud/sandbox/rm.ts +4 -3
- package/src/cmd/cloud/sandbox/rmdir.ts +4 -3
- package/src/cmd/cloud/sandbox/run.ts +51 -6
- package/src/cmd/cloud/sandbox/runtime/index.ts +1 -1
- package/src/cmd/cloud/sandbox/runtime/list.ts +4 -4
- package/src/cmd/cloud/sandbox/snapshot/create.ts +11 -5
- package/src/cmd/cloud/sandbox/snapshot/delete.ts +4 -4
- package/src/cmd/cloud/sandbox/snapshot/get.ts +4 -4
- package/src/cmd/cloud/sandbox/snapshot/index.ts +1 -1
- package/src/cmd/cloud/sandbox/snapshot/list.ts +4 -4
- package/src/cmd/cloud/sandbox/snapshot/tag.ts +7 -5
- package/src/cmd/cloud/sandbox/upload.ts +4 -3
- package/src/cmd/cloud/sandbox/util.ts +60 -1
- package/src/cmd/cloud/scp/download.ts +14 -2
- package/src/cmd/cloud/scp/upload.ts +14 -2
- package/src/cmd/cloud/session/get.ts +4 -4
- package/src/cmd/cloud/session/list.ts +4 -4
- package/src/cmd/cloud/ssh.ts +15 -2
- package/src/cmd/cloud/storage/delete.ts +61 -10
- package/src/cmd/cloud/storage/download.ts +31 -6
- package/src/cmd/cloud/storage/get.ts +31 -6
- package/src/cmd/cloud/storage/list.ts +18 -7
- package/src/cmd/cloud/storage/upload.ts +31 -6
- package/src/cmd/cloud/thread/delete.ts +4 -4
- package/src/cmd/cloud/thread/get.ts +4 -4
- package/src/cmd/cloud/thread/list.ts +4 -4
- package/src/cmd/project/auth/init.ts +7 -3
- package/src/cmd/project/auth/shared.ts +52 -13
- package/src/config.ts +64 -8
- package/src/env-util.ts +50 -5
- package/src/utils/apt-validator.ts +215 -0
- package/dist/cmd/cloud/secret/delete.d.ts +0 -2
- package/dist/cmd/cloud/secret/delete.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/delete.js +0 -53
- package/dist/cmd/cloud/secret/delete.js.map +0 -1
- package/dist/cmd/cloud/secret/get.d.ts +0 -2
- package/dist/cmd/cloud/secret/get.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/get.js +0 -73
- package/dist/cmd/cloud/secret/get.js.map +0 -1
- package/dist/cmd/cloud/secret/import.d.ts +0 -2
- package/dist/cmd/cloud/secret/import.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/import.js +0 -91
- package/dist/cmd/cloud/secret/import.js.map +0 -1
- package/dist/cmd/cloud/secret/index.d.ts +0 -3
- package/dist/cmd/cloud/secret/index.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/index.js +0 -33
- package/dist/cmd/cloud/secret/index.js.map +0 -1
- package/dist/cmd/cloud/secret/list.d.ts +0 -2
- package/dist/cmd/cloud/secret/list.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/list.js +0 -65
- package/dist/cmd/cloud/secret/list.js.map +0 -1
- package/dist/cmd/cloud/secret/pull.d.ts +0 -2
- package/dist/cmd/cloud/secret/pull.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/pull.js +0 -82
- package/dist/cmd/cloud/secret/pull.js.map +0 -1
- package/dist/cmd/cloud/secret/push.d.ts +0 -2
- package/dist/cmd/cloud/secret/push.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/push.js +0 -61
- package/dist/cmd/cloud/secret/push.js.map +0 -1
- package/dist/cmd/cloud/secret/set.d.ts +0 -2
- package/dist/cmd/cloud/secret/set.d.ts.map +0 -1
- package/dist/cmd/cloud/secret/set.js +0 -63
- package/dist/cmd/cloud/secret/set.js.map +0 -1
- package/src/cmd/cloud/secret/delete.ts +0 -65
- package/src/cmd/cloud/secret/get.ts +0 -77
- package/src/cmd/cloud/secret/import.ts +0 -110
- package/src/cmd/cloud/secret/index.ts +0 -33
- package/src/cmd/cloud/secret/list.ts +0 -70
- package/src/cmd/cloud/secret/pull.ts +0 -92
- package/src/cmd/cloud/secret/push.ts +0 -69
- package/src/cmd/cloud/secret/set.ts +0 -76
package/src/cmd/cloud/deploy.ts
CHANGED
|
@@ -55,6 +55,7 @@ import { ErrorCode } from '../../errors';
|
|
|
55
55
|
import { typecheck } from '../build/typecheck';
|
|
56
56
|
import { BuildReportCollector, setGlobalCollector, clearGlobalCollector } from '../../build-report';
|
|
57
57
|
import { runForkedDeploy } from './deploy-fork';
|
|
58
|
+
import { validateAptDependencies } from '../../utils/apt-validator';
|
|
58
59
|
|
|
59
60
|
const DeploymentCancelledError = StructuredError(
|
|
60
61
|
'DeploymentCancelled',
|
|
@@ -171,6 +172,54 @@ export const deploySubcommand = createSubcommand({
|
|
|
171
172
|
}
|
|
172
173
|
}
|
|
173
174
|
|
|
175
|
+
// Validate apt dependencies before creating deployment
|
|
176
|
+
if (deploymentConfig.dependencies && deploymentConfig.dependencies.length > 0) {
|
|
177
|
+
const aptValidation = await tui.spinner({
|
|
178
|
+
message: 'Validating apt dependencies...',
|
|
179
|
+
type: 'simple',
|
|
180
|
+
callback: async () => {
|
|
181
|
+
return await validateAptDependencies(
|
|
182
|
+
deploymentConfig.dependencies!,
|
|
183
|
+
project.region,
|
|
184
|
+
config,
|
|
185
|
+
logger
|
|
186
|
+
);
|
|
187
|
+
},
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
if (aptValidation.invalid.length > 0) {
|
|
191
|
+
if (options.json) {
|
|
192
|
+
return {
|
|
193
|
+
success: false,
|
|
194
|
+
deploymentId: '',
|
|
195
|
+
projectId: project.projectId,
|
|
196
|
+
errors: aptValidation.invalid.map((pkg) => ({
|
|
197
|
+
type: 'invalid-apt-dependency',
|
|
198
|
+
package: pkg.package,
|
|
199
|
+
error: pkg.error,
|
|
200
|
+
searchUrl: pkg.searchUrl,
|
|
201
|
+
availableVersions: pkg.availableVersions,
|
|
202
|
+
})),
|
|
203
|
+
} as never;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
tui.error('Invalid apt dependencies in agentuity.json:');
|
|
207
|
+
tui.newline();
|
|
208
|
+
for (const pkg of aptValidation.invalid) {
|
|
209
|
+
tui.bullet(`${tui.bold(pkg.package)}: ${pkg.error}`);
|
|
210
|
+
if (pkg.availableVersions && pkg.availableVersions.length > 0) {
|
|
211
|
+
tui.muted(` Available versions: ${pkg.availableVersions.join(', ')}`);
|
|
212
|
+
}
|
|
213
|
+
tui.muted(` Search: ${tui.link(pkg.searchUrl)}`);
|
|
214
|
+
}
|
|
215
|
+
tui.newline();
|
|
216
|
+
tui.fatal(
|
|
217
|
+
'Fix the apt dependencies and try again. Search for valid packages at: https://packages.debian.org/stable/',
|
|
218
|
+
ErrorCode.CONFIG_INVALID
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
|
|
174
223
|
const initialDeployment = await projectDeploymentCreate(
|
|
175
224
|
apiClient,
|
|
176
225
|
project.projectId,
|
|
@@ -1,35 +1,38 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { createSubcommand } from '../../../types';
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
|
-
import { projectEnvDelete } from '@agentuity/server';
|
|
4
|
+
import { projectEnvDelete, projectGet } from '@agentuity/server';
|
|
5
5
|
import {
|
|
6
6
|
findExistingEnvFile,
|
|
7
7
|
readEnvFile,
|
|
8
8
|
writeEnvFile,
|
|
9
9
|
filterAgentuitySdkKeys,
|
|
10
|
+
isReservedAgentuityKey,
|
|
10
11
|
} from '../../../env-util';
|
|
11
12
|
import { getCommand } from '../../../command-prefix';
|
|
13
|
+
import { ErrorCode } from '../../../errors';
|
|
12
14
|
|
|
13
15
|
const EnvDeleteResponseSchema = z.object({
|
|
14
16
|
success: z.boolean().describe('Whether the operation succeeded'),
|
|
15
|
-
key: z.string().describe('
|
|
16
|
-
path: z.string().describe('Local file path where
|
|
17
|
+
key: z.string().describe('Variable key that was deleted'),
|
|
18
|
+
path: z.string().describe('Local file path where variable was removed'),
|
|
19
|
+
secret: z.boolean().describe('Whether a secret was deleted'),
|
|
17
20
|
});
|
|
18
21
|
|
|
19
22
|
export const deleteSubcommand = createSubcommand({
|
|
20
23
|
name: 'delete',
|
|
21
24
|
aliases: ['del', 'remove', 'rm'],
|
|
22
|
-
description: 'Delete an environment variable',
|
|
25
|
+
description: 'Delete an environment variable or secret',
|
|
23
26
|
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-project'],
|
|
24
27
|
idempotent: true,
|
|
25
28
|
examples: [
|
|
26
|
-
{ command: getCommand('env delete OLD_FEATURE_FLAG'), description: 'Delete
|
|
27
|
-
{ command: getCommand('env rm
|
|
29
|
+
{ command: getCommand('env delete OLD_FEATURE_FLAG'), description: 'Delete variable' },
|
|
30
|
+
{ command: getCommand('env rm API_KEY'), description: 'Delete a secret' },
|
|
28
31
|
],
|
|
29
32
|
requires: { auth: true, project: true, apiClient: true },
|
|
30
33
|
schema: {
|
|
31
34
|
args: z.object({
|
|
32
|
-
key: z.string().describe('the
|
|
35
|
+
key: z.string().describe('the variable or secret key to delete'),
|
|
33
36
|
}),
|
|
34
37
|
response: EnvDeleteResponseSchema,
|
|
35
38
|
},
|
|
@@ -37,15 +40,35 @@ export const deleteSubcommand = createSubcommand({
|
|
|
37
40
|
async handler(ctx) {
|
|
38
41
|
const { args, project, projectDir, apiClient } = ctx;
|
|
39
42
|
|
|
40
|
-
//
|
|
41
|
-
|
|
43
|
+
// Validate key doesn't start with reserved AGENTUITY_ prefix (except AGENTUITY_PUBLIC_)
|
|
44
|
+
if (isReservedAgentuityKey(args.key)) {
|
|
45
|
+
tui.fatal(
|
|
46
|
+
'Cannot delete AGENTUITY_ prefixed variables. These are reserved for system use.'
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// First, determine if this key exists in env or secrets
|
|
51
|
+
const projectData = await tui.spinner('Checking variable', () => {
|
|
52
|
+
return projectGet(apiClient, { id: project.projectId, mask: true });
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const isSecret = projectData.secrets?.[args.key] !== undefined;
|
|
56
|
+
const isEnv = projectData.env?.[args.key] !== undefined;
|
|
57
|
+
|
|
58
|
+
if (!isSecret && !isEnv) {
|
|
59
|
+
tui.fatal(`Variable '${args.key}' not found`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Delete from cloud using the correct field
|
|
63
|
+
const label = isSecret ? 'secret' : 'environment variable';
|
|
64
|
+
await tui.spinner(`Deleting ${label} from cloud`, () => {
|
|
42
65
|
return projectEnvDelete(apiClient, {
|
|
43
66
|
id: project.projectId,
|
|
44
|
-
env: [args.key],
|
|
67
|
+
...(isSecret ? { secrets: [args.key] } : { env: [args.key] }),
|
|
45
68
|
});
|
|
46
69
|
});
|
|
47
70
|
|
|
48
|
-
// Update local .env file
|
|
71
|
+
// Update local .env file
|
|
49
72
|
const envFilePath = await findExistingEnvFile(projectDir);
|
|
50
73
|
const currentEnv = await readEnvFile(envFilePath);
|
|
51
74
|
delete currentEnv[args.key];
|
|
@@ -55,13 +78,14 @@ export const deleteSubcommand = createSubcommand({
|
|
|
55
78
|
await writeEnvFile(envFilePath, filteredEnv);
|
|
56
79
|
|
|
57
80
|
tui.success(
|
|
58
|
-
|
|
81
|
+
`${isSecret ? 'Secret' : 'Environment variable'} '${args.key}' deleted successfully (cloud + ${envFilePath})`
|
|
59
82
|
);
|
|
60
83
|
|
|
61
84
|
return {
|
|
62
85
|
success: true,
|
|
63
86
|
key: args.key,
|
|
64
87
|
path: envFilePath,
|
|
88
|
+
secret: isSecret,
|
|
65
89
|
};
|
|
66
90
|
},
|
|
67
91
|
});
|
package/src/cmd/cloud/env/get.ts
CHANGED
|
@@ -8,26 +8,25 @@ import { ErrorCode } from '../../../errors';
|
|
|
8
8
|
const EnvGetResponseSchema = z.object({
|
|
9
9
|
key: z.string().describe('Environment variable key name'),
|
|
10
10
|
value: z.string().describe('Environment variable value'),
|
|
11
|
+
secret: z.boolean().describe('Whether the value is stored as a secret'),
|
|
11
12
|
});
|
|
12
13
|
|
|
13
14
|
export const getSubcommand = createSubcommand({
|
|
14
15
|
name: 'get',
|
|
15
|
-
description: 'Get an environment variable value',
|
|
16
|
+
description: 'Get an environment variable or secret value',
|
|
16
17
|
tags: ['read-only', 'fast', 'requires-auth', 'requires-project'],
|
|
17
18
|
examples: [
|
|
18
|
-
{ command: getCommand('env get NODE_ENV'), description: 'Get
|
|
19
|
-
{ command: getCommand('env get
|
|
19
|
+
{ command: getCommand('env get NODE_ENV'), description: 'Get environment variable' },
|
|
20
|
+
{ command: getCommand('env get API_KEY'), description: 'Get a secret value' },
|
|
21
|
+
{ command: getCommand('env get API_KEY --no-mask'), description: 'Show unmasked value' },
|
|
20
22
|
],
|
|
21
23
|
requires: { auth: true, project: true, apiClient: true },
|
|
22
24
|
schema: {
|
|
23
25
|
args: z.object({
|
|
24
|
-
key: z.string().describe('the environment variable key'),
|
|
26
|
+
key: z.string().describe('the environment variable or secret key'),
|
|
25
27
|
}),
|
|
26
28
|
options: z.object({
|
|
27
|
-
|
|
28
|
-
.boolean()
|
|
29
|
-
.default(false)
|
|
30
|
-
.describe('mask the value in output (default: true in TTY, false otherwise)'),
|
|
29
|
+
maskSecret: z.boolean().optional().describe('mask the secret value in output'),
|
|
31
30
|
}),
|
|
32
31
|
response: EnvGetResponseSchema,
|
|
33
32
|
},
|
|
@@ -36,38 +35,40 @@ export const getSubcommand = createSubcommand({
|
|
|
36
35
|
async handler(ctx) {
|
|
37
36
|
const { args, opts, apiClient, project, options } = ctx;
|
|
38
37
|
|
|
39
|
-
// Fetch project with unmasked
|
|
40
|
-
const projectData = await tui.spinner('Fetching
|
|
38
|
+
// Fetch project with unmasked values
|
|
39
|
+
const projectData = await tui.spinner('Fetching variable', () => {
|
|
41
40
|
return projectGet(apiClient, { id: project.projectId, mask: false });
|
|
42
41
|
});
|
|
43
42
|
|
|
44
|
-
// Look for the key in env
|
|
45
|
-
|
|
43
|
+
// Look for the key in both env and secrets
|
|
44
|
+
let value: string | undefined;
|
|
45
|
+
let isSecret = false;
|
|
46
|
+
|
|
47
|
+
if (projectData.secrets?.[args.key] !== undefined) {
|
|
48
|
+
value = projectData.secrets[args.key];
|
|
49
|
+
isSecret = true;
|
|
50
|
+
} else if (projectData.env?.[args.key] !== undefined) {
|
|
51
|
+
value = projectData.env[args.key];
|
|
52
|
+
isSecret = false;
|
|
53
|
+
}
|
|
46
54
|
|
|
47
55
|
if (value === undefined) {
|
|
48
|
-
tui.fatal(`
|
|
56
|
+
tui.fatal(`Variable '${args.key}' not found`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
49
57
|
}
|
|
50
58
|
|
|
59
|
+
// Mask secrets by default, env vars are never masked
|
|
60
|
+
const shouldMask = isSecret && (opts?.maskSecret ?? true);
|
|
61
|
+
|
|
51
62
|
if (!options.json) {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
tui.success(`${args.key}=${tui.maskSecret(value)}`);
|
|
56
|
-
} else {
|
|
57
|
-
tui.success(`${args.key}=${value}`);
|
|
58
|
-
}
|
|
59
|
-
} else {
|
|
60
|
-
if (opts?.mask) {
|
|
61
|
-
console.log(`${args.key}=${tui.maskSecret(value)}`);
|
|
62
|
-
} else {
|
|
63
|
-
console.log(`${args.key}=${value}`);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
63
|
+
const displayValue = shouldMask ? tui.maskSecret(value) : value;
|
|
64
|
+
const typeLabel = isSecret ? ' (secret)' : '';
|
|
65
|
+
tui.success(`${args.key}=${displayValue}${typeLabel}`);
|
|
66
66
|
}
|
|
67
67
|
|
|
68
68
|
return {
|
|
69
69
|
key: args.key,
|
|
70
70
|
value,
|
|
71
|
+
secret: isSecret,
|
|
71
72
|
};
|
|
72
73
|
},
|
|
73
74
|
});
|
|
@@ -9,13 +9,16 @@ import {
|
|
|
9
9
|
filterAgentuitySdkKeys,
|
|
10
10
|
mergeEnvVars,
|
|
11
11
|
splitEnvAndSecrets,
|
|
12
|
-
|
|
12
|
+
validateNoPublicSecrets,
|
|
13
|
+
isReservedAgentuityKey,
|
|
13
14
|
} from '../../../env-util';
|
|
14
15
|
import { getCommand } from '../../../command-prefix';
|
|
15
16
|
|
|
16
17
|
const EnvImportResponseSchema = z.object({
|
|
17
18
|
success: z.boolean().describe('Whether import succeeded'),
|
|
18
19
|
imported: z.number().describe('Number of items imported'),
|
|
20
|
+
envCount: z.number().describe('Number of env vars imported'),
|
|
21
|
+
secretCount: z.number().describe('Number of secrets imported'),
|
|
19
22
|
skipped: z.number().describe('Number of items skipped'),
|
|
20
23
|
path: z.string().describe('Local file path where variables were saved'),
|
|
21
24
|
file: z.string().describe('Source file path'),
|
|
@@ -23,7 +26,7 @@ const EnvImportResponseSchema = z.object({
|
|
|
23
26
|
|
|
24
27
|
export const importSubcommand = createSubcommand({
|
|
25
28
|
name: 'import',
|
|
26
|
-
description: 'Import environment variables from a file to cloud and local .env',
|
|
29
|
+
description: 'Import environment variables and secrets from a file to cloud and local .env',
|
|
27
30
|
tags: [
|
|
28
31
|
'mutating',
|
|
29
32
|
'creates-resource',
|
|
@@ -34,8 +37,8 @@ export const importSubcommand = createSubcommand({
|
|
|
34
37
|
],
|
|
35
38
|
examples: [
|
|
36
39
|
{
|
|
37
|
-
command: getCommand('cloud env import .env'),
|
|
38
|
-
description: 'Import
|
|
40
|
+
command: getCommand('cloud env import .env.backup'),
|
|
41
|
+
description: 'Import variables from backup file',
|
|
39
42
|
},
|
|
40
43
|
{
|
|
41
44
|
command: getCommand('cloud env import .env.local'),
|
|
@@ -55,100 +58,84 @@ export const importSubcommand = createSubcommand({
|
|
|
55
58
|
const { args, apiClient, project, projectDir } = ctx;
|
|
56
59
|
|
|
57
60
|
// Read the import file
|
|
58
|
-
const
|
|
61
|
+
const importedVars = await readEnvFile(args.file);
|
|
59
62
|
|
|
60
|
-
if (Object.keys(
|
|
61
|
-
tui.warning(`No
|
|
63
|
+
if (Object.keys(importedVars).length === 0) {
|
|
64
|
+
tui.warning(`No variables found in ${args.file}`);
|
|
62
65
|
return {
|
|
63
66
|
success: false,
|
|
64
67
|
imported: 0,
|
|
68
|
+
envCount: 0,
|
|
69
|
+
secretCount: 0,
|
|
65
70
|
skipped: 0,
|
|
66
71
|
path: '',
|
|
67
72
|
file: args.file,
|
|
68
73
|
};
|
|
69
74
|
}
|
|
70
75
|
|
|
71
|
-
// Filter out AGENTUITY_ prefixed keys
|
|
72
|
-
const
|
|
76
|
+
// Filter out reserved AGENTUITY_ prefixed keys
|
|
77
|
+
const filteredVars = filterAgentuitySdkKeys(importedVars);
|
|
73
78
|
|
|
74
|
-
if (Object.keys(
|
|
75
|
-
tui.warning('No valid
|
|
79
|
+
if (Object.keys(filteredVars).length === 0) {
|
|
80
|
+
tui.warning('No valid variables to import (all were reserved AGENTUITY_ prefixed)');
|
|
76
81
|
return {
|
|
77
82
|
success: false,
|
|
78
83
|
imported: 0,
|
|
79
|
-
|
|
84
|
+
envCount: 0,
|
|
85
|
+
secretCount: 0,
|
|
86
|
+
skipped: Object.keys(importedVars).length,
|
|
80
87
|
path: '',
|
|
81
88
|
file: args.file,
|
|
82
89
|
};
|
|
83
90
|
}
|
|
84
91
|
|
|
85
|
-
//
|
|
86
|
-
const
|
|
87
|
-
for (const [key, value] of Object.entries(filteredEnv)) {
|
|
88
|
-
if (looksLikeSecret(key, value)) {
|
|
89
|
-
potentialSecrets.push(key);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
+
// Split into env and secrets based on key naming conventions
|
|
93
|
+
const { env, secrets } = splitEnvAndSecrets(filteredVars);
|
|
92
94
|
|
|
93
|
-
|
|
95
|
+
// Check for any public vars that would have been treated as secrets
|
|
96
|
+
const publicSecretKeys = validateNoPublicSecrets(secrets);
|
|
97
|
+
if (publicSecretKeys.length > 0) {
|
|
94
98
|
tui.warning(
|
|
95
|
-
`
|
|
96
|
-
);
|
|
97
|
-
for (const key of potentialSecrets) {
|
|
98
|
-
tui.info(` • ${key}`);
|
|
99
|
-
}
|
|
100
|
-
tui.info(`\nSecrets should be stored using: ${getCommand('secret import <file>')}`);
|
|
101
|
-
tui.info('This keeps them more secure and properly masked in the cloud.');
|
|
102
|
-
|
|
103
|
-
const response = await tui.confirm(
|
|
104
|
-
'Do you still want to import these as regular environment variables?',
|
|
105
|
-
false
|
|
99
|
+
`Moving public variables to env: ${publicSecretKeys.join(', ')} (these are exposed to the frontend)`
|
|
106
100
|
);
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
`Cancelled. Use "${getCommand('secret import')}" to store these as secrets instead.`
|
|
111
|
-
);
|
|
112
|
-
return {
|
|
113
|
-
success: false,
|
|
114
|
-
imported: 0,
|
|
115
|
-
skipped: Object.keys(filteredEnv).length,
|
|
116
|
-
path: '',
|
|
117
|
-
file: args.file,
|
|
118
|
-
};
|
|
101
|
+
for (const key of publicSecretKeys) {
|
|
102
|
+
delete secrets[key];
|
|
103
|
+
env[key] = filteredVars[key];
|
|
119
104
|
}
|
|
120
105
|
}
|
|
121
106
|
|
|
122
|
-
// Split into env and secrets based on key naming conventions
|
|
123
|
-
const { env: normalEnv, secrets } = splitEnvAndSecrets(filteredEnv);
|
|
124
|
-
|
|
125
107
|
// Push to cloud
|
|
126
|
-
await tui.spinner('Importing
|
|
108
|
+
await tui.spinner('Importing variables to cloud', () => {
|
|
127
109
|
return projectEnvUpdate(apiClient, {
|
|
128
110
|
id: project.projectId,
|
|
129
|
-
env
|
|
130
|
-
secrets
|
|
111
|
+
env,
|
|
112
|
+
secrets,
|
|
131
113
|
});
|
|
132
114
|
});
|
|
133
115
|
|
|
134
|
-
// Merge
|
|
116
|
+
// Merge with local .env file
|
|
135
117
|
const localEnvPath = await findExistingEnvFile(projectDir);
|
|
136
118
|
const localEnv = await readEnvFile(localEnvPath);
|
|
137
|
-
const mergedEnv = mergeEnvVars(localEnv,
|
|
119
|
+
const mergedEnv = mergeEnvVars(localEnv, filteredVars);
|
|
138
120
|
|
|
139
121
|
await writeEnvFile(localEnvPath, mergedEnv, {
|
|
140
|
-
skipKeys: Object.keys(mergedEnv).filter(
|
|
122
|
+
skipKeys: Object.keys(mergedEnv).filter(isReservedAgentuityKey),
|
|
141
123
|
});
|
|
142
124
|
|
|
143
|
-
const
|
|
125
|
+
const envCount = Object.keys(env).length;
|
|
126
|
+
const secretCount = Object.keys(secrets).length;
|
|
127
|
+
const totalCount = envCount + secretCount;
|
|
128
|
+
|
|
144
129
|
tui.success(
|
|
145
|
-
`Imported ${
|
|
130
|
+
`Imported ${totalCount} variable${totalCount !== 1 ? 's' : ''} from ${args.file} (${envCount} env, ${secretCount} secret${secretCount !== 1 ? 's' : ''})`
|
|
146
131
|
);
|
|
147
132
|
|
|
148
133
|
return {
|
|
149
134
|
success: true,
|
|
150
|
-
imported:
|
|
151
|
-
|
|
135
|
+
imported: totalCount,
|
|
136
|
+
envCount,
|
|
137
|
+
secretCount,
|
|
138
|
+
skipped: Object.keys(importedVars).length - totalCount,
|
|
152
139
|
path: localEnvPath,
|
|
153
140
|
file: args.file,
|
|
154
141
|
};
|
|
@@ -10,14 +10,18 @@ import { getCommand } from '../../../command-prefix';
|
|
|
10
10
|
|
|
11
11
|
export const command = createCommand({
|
|
12
12
|
name: 'env',
|
|
13
|
-
description: 'Manage environment variables for your project',
|
|
13
|
+
description: 'Manage environment variables and secrets for your project',
|
|
14
14
|
tags: ['fast', 'requires-auth', 'requires-project'],
|
|
15
15
|
examples: [
|
|
16
|
-
{ command: getCommand('cloud env list'), description: 'List
|
|
16
|
+
{ command: getCommand('cloud env list'), description: 'List all variables and secrets' },
|
|
17
17
|
{
|
|
18
18
|
command: getCommand('cloud env set NODE_ENV production'),
|
|
19
19
|
description: 'Set environment variable',
|
|
20
20
|
},
|
|
21
|
+
{
|
|
22
|
+
command: getCommand('cloud env set API_KEY "sk_..." --secret'),
|
|
23
|
+
description: 'Set a secret',
|
|
24
|
+
},
|
|
21
25
|
],
|
|
22
26
|
subcommands: [
|
|
23
27
|
listSubcommand,
|
|
@@ -4,19 +4,23 @@ import * as tui from '../../../tui';
|
|
|
4
4
|
import { projectGet } from '@agentuity/server';
|
|
5
5
|
import { getCommand } from '../../../command-prefix';
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
z.string(),
|
|
9
|
-
z.
|
|
10
|
-
);
|
|
7
|
+
const EnvItemSchema = z.object({
|
|
8
|
+
value: z.string().describe('Variable value'),
|
|
9
|
+
secret: z.boolean().describe('Whether this is a secret'),
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
const EnvListResponseSchema = z.record(z.string(), EnvItemSchema);
|
|
11
13
|
|
|
12
14
|
export const listSubcommand = createSubcommand({
|
|
13
15
|
name: 'list',
|
|
14
16
|
aliases: ['ls'],
|
|
15
|
-
description: 'List all environment variables',
|
|
17
|
+
description: 'List all environment variables and secrets',
|
|
16
18
|
tags: ['read-only', 'fast', 'requires-auth', 'requires-project'],
|
|
17
19
|
examples: [
|
|
18
|
-
{ command: getCommand('env list'), description: 'List
|
|
19
|
-
{ command: getCommand('env list --mask'), description: '
|
|
20
|
+
{ command: getCommand('env list'), description: 'List all variables' },
|
|
21
|
+
{ command: getCommand('env list --no-mask'), description: 'Show unmasked values' },
|
|
22
|
+
{ command: getCommand('env list --secrets'), description: 'List only secrets' },
|
|
23
|
+
{ command: getCommand('env list --env-only'), description: 'List only env vars' },
|
|
20
24
|
],
|
|
21
25
|
requires: { auth: true, project: true, apiClient: true },
|
|
22
26
|
idempotent: true,
|
|
@@ -24,8 +28,10 @@ export const listSubcommand = createSubcommand({
|
|
|
24
28
|
options: z.object({
|
|
25
29
|
mask: z
|
|
26
30
|
.boolean()
|
|
27
|
-
.default(
|
|
28
|
-
.describe('mask
|
|
31
|
+
.default(true)
|
|
32
|
+
.describe('mask secret values in output (use --no-mask to show values)'),
|
|
33
|
+
secrets: z.boolean().default(false).describe('list only secrets'),
|
|
34
|
+
'env-only': z.boolean().default(false).describe('list only environment variables'),
|
|
29
35
|
}),
|
|
30
36
|
response: EnvListResponseSchema,
|
|
31
37
|
},
|
|
@@ -34,40 +40,61 @@ export const listSubcommand = createSubcommand({
|
|
|
34
40
|
async handler(ctx) {
|
|
35
41
|
const { opts, apiClient, project, options } = ctx;
|
|
36
42
|
|
|
37
|
-
// Fetch project with unmasked
|
|
38
|
-
const projectData = await tui.spinner('Fetching
|
|
43
|
+
// Fetch project with unmasked values
|
|
44
|
+
const projectData = await tui.spinner('Fetching variables', () => {
|
|
39
45
|
return projectGet(apiClient, { id: project.projectId, mask: false });
|
|
40
46
|
});
|
|
41
47
|
|
|
42
48
|
const env = projectData.env || {};
|
|
49
|
+
const secrets = projectData.secrets || {};
|
|
50
|
+
|
|
51
|
+
// Build combined result with type info
|
|
52
|
+
const result: Record<string, { value: string; secret: boolean }> = {};
|
|
53
|
+
|
|
54
|
+
// Filter based on options
|
|
55
|
+
const showEnv = !opts?.secrets;
|
|
56
|
+
const showSecrets = !opts?.['env-only'];
|
|
57
|
+
|
|
58
|
+
if (showEnv) {
|
|
59
|
+
for (const [key, value] of Object.entries(env)) {
|
|
60
|
+
result[key] = { value, secret: false };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (showSecrets) {
|
|
65
|
+
for (const [key, value] of Object.entries(secrets)) {
|
|
66
|
+
result[key] = { value, secret: true };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
43
69
|
|
|
44
70
|
// Skip TUI output in JSON mode
|
|
45
71
|
if (!options.json) {
|
|
46
|
-
if (Object.keys(
|
|
47
|
-
tui.info('No
|
|
72
|
+
if (Object.keys(result).length === 0) {
|
|
73
|
+
tui.info('No variables found');
|
|
48
74
|
} else {
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
75
|
+
tui.newline();
|
|
76
|
+
|
|
77
|
+
const envCount = showEnv ? Object.keys(env).length : 0;
|
|
78
|
+
const secretCount = showSecrets ? Object.keys(secrets).length : 0;
|
|
79
|
+
const parts: string[] = [];
|
|
80
|
+
if (envCount > 0) parts.push(`${envCount} env`);
|
|
81
|
+
if (secretCount > 0) parts.push(`${secretCount} secret${secretCount !== 1 ? 's' : ''}`);
|
|
82
|
+
|
|
83
|
+
tui.info(`Variables (${parts.join(', ')}):`);
|
|
84
|
+
tui.newline();
|
|
85
|
+
|
|
86
|
+
const sortedKeys = Object.keys(result).sort();
|
|
87
|
+
const shouldMask = opts?.mask !== false;
|
|
55
88
|
|
|
56
|
-
const sortedKeys = Object.keys(env).sort();
|
|
57
|
-
// For env vars, masking should be explicitly opted-in (default false)
|
|
58
|
-
const shouldMask = opts?.mask === true;
|
|
59
89
|
for (const key of sortedKeys) {
|
|
60
|
-
const value =
|
|
61
|
-
const displayValue = shouldMask ? tui.maskSecret(value) : value;
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
} else {
|
|
65
|
-
console.log(`${key}=${displayValue}`);
|
|
66
|
-
}
|
|
90
|
+
const { value, secret } = result[key];
|
|
91
|
+
const displayValue = shouldMask && secret ? tui.maskSecret(value) : value;
|
|
92
|
+
const typeIndicator = secret ? ' [secret]' : '';
|
|
93
|
+
console.log(`${tui.bold(key)}=${displayValue}${tui.muted(typeIndicator)}`);
|
|
67
94
|
}
|
|
68
95
|
}
|
|
69
96
|
}
|
|
70
97
|
|
|
71
|
-
return
|
|
98
|
+
return result;
|
|
72
99
|
},
|
|
73
100
|
});
|
|
@@ -3,7 +3,13 @@ import { join } from 'node:path';
|
|
|
3
3
|
import { createSubcommand } from '../../../types';
|
|
4
4
|
import * as tui from '../../../tui';
|
|
5
5
|
import { projectGet } from '@agentuity/server';
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
findExistingEnvFile,
|
|
8
|
+
readEnvFile,
|
|
9
|
+
writeEnvFile,
|
|
10
|
+
mergeEnvVars,
|
|
11
|
+
isReservedAgentuityKey,
|
|
12
|
+
} from '../../../env-util';
|
|
7
13
|
import { getCommand } from '../../../command-prefix';
|
|
8
14
|
|
|
9
15
|
const EnvPullResponseSchema = z.object({
|
|
@@ -55,9 +61,9 @@ export const pullSubcommand = createSubcommand({
|
|
|
55
61
|
mergedEnv = mergeEnvVars(cloudEnv, localEnv);
|
|
56
62
|
}
|
|
57
63
|
|
|
58
|
-
// Write to .env (skip AGENTUITY_ keys)
|
|
64
|
+
// Write to .env (skip reserved AGENTUITY_ keys, except AGENTUITY_PUBLIC_)
|
|
59
65
|
await writeEnvFile(targetEnvPath, mergedEnv, {
|
|
60
|
-
skipKeys: Object.keys(mergedEnv).filter(
|
|
66
|
+
skipKeys: Object.keys(mergedEnv).filter(isReservedAgentuityKey),
|
|
61
67
|
});
|
|
62
68
|
|
|
63
69
|
// Write AGENTUITY_SDK_KEY to .env if present and missing locally
|