@agentuity/cli 0.0.48 → 0.0.50
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/agents/index.d.ts +2 -0
- package/dist/cmd/agents/index.d.ts.map +1 -0
- 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 +3 -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.map +1 -1
- package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/remove.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/rollback.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/undeploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/utils.d.ts +4 -2
- package/dist/cmd/cloud/deployment/utils.d.ts.map +1 -1
- 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/session/get.d.ts +2 -0
- package/dist/cmd/cloud/session/get.d.ts.map +1 -0
- package/dist/cmd/cloud/session/index.d.ts +2 -0
- package/dist/cmd/cloud/session/index.d.ts.map +1 -0
- package/dist/cmd/cloud/session/list.d.ts +2 -0
- package/dist/cmd/cloud/session/list.d.ts.map +1 -0
- package/dist/cmd/cloud/session/logs.d.ts +2 -0
- package/dist/cmd/cloud/session/logs.d.ts.map +1 -0
- package/dist/cmd/cloud/ssh.d.ts.map +1 -1
- package/dist/cmd/dev/agents.d.ts +2 -0
- package/dist/cmd/dev/agents.d.ts.map +1 -0
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/sync.d.ts +12 -0
- package/dist/cmd/dev/sync.d.ts.map +1 -0
- 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 +120 -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 +35 -1
- package/dist/tui.d.ts.map +1 -1
- package/dist/types.d.ts +77 -6
- package/dist/types.d.ts.map +1 -1
- package/dist/utils/format.d.ts +9 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/package.json +12 -4
- package/src/banner.ts +7 -7
- package/src/cli-logger.ts +80 -0
- package/src/cli.ts +192 -58
- package/src/cmd/agents/index.ts +147 -0
- 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 +38 -27
- package/src/cmd/auth/whoami.ts +32 -21
- package/src/cmd/bundle/ast.test.ts +2 -2
- package/src/cmd/bundle/ast.ts +112 -22
- package/src/cmd/bundle/index.ts +20 -0
- package/src/cmd/bundle/plugin.ts +60 -14
- package/src/cmd/capabilities/index.ts +12 -0
- package/src/cmd/capabilities/show.ts +256 -0
- package/src/cmd/cloud/deploy.ts +54 -0
- package/src/cmd/cloud/deployment/index.ts +1 -0
- package/src/cmd/cloud/deployment/list.ts +66 -25
- package/src/cmd/cloud/deployment/remove.ts +26 -2
- package/src/cmd/cloud/deployment/rollback.ts +35 -4
- package/src/cmd/cloud/deployment/show.ts +37 -2
- package/src/cmd/cloud/deployment/undeploy.ts +12 -1
- package/src/cmd/cloud/deployment/utils.ts +5 -2
- package/src/cmd/cloud/domain.ts +3 -2
- package/src/cmd/cloud/index.ts +10 -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/session/get.ts +164 -0
- package/src/cmd/cloud/session/index.ts +11 -0
- package/src/cmd/cloud/session/list.ts +145 -0
- package/src/cmd/cloud/session/logs.ts +68 -0
- package/src/cmd/cloud/ssh.ts +12 -0
- package/src/cmd/dev/agents.ts +122 -0
- package/src/cmd/dev/index.ts +106 -8
- package/src/cmd/dev/sync.ts +414 -0
- 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 +28 -2
- package/src/cmd/profile/delete.ts +17 -2
- package/src/cmd/profile/index.ts +1 -0
- package/src/cmd/profile/list.ts +7 -3
- package/src/cmd/profile/show.ts +20 -5
- package/src/cmd/profile/use.ts +8 -0
- 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 +24 -10
- package/src/cmd/project/show.ts +28 -9
- 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 +17 -4
- 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 +1507 -0
- package/src/schema-generator.ts +389 -0
- package/src/tui.ts +178 -13
- package/src/types.ts +75 -22
- package/src/utils/format.ts +17 -0
package/src/cmd/auth/signup.ts
CHANGED
|
@@ -3,12 +3,17 @@ import { getAppBaseURL, UpgradeRequiredError } from '@agentuity/server';
|
|
|
3
3
|
import { saveAuth } from '../../config';
|
|
4
4
|
import { generateSignupOTP, pollForSignupCompletion } from './api';
|
|
5
5
|
import * as tui from '../../tui';
|
|
6
|
+
import { getCommand } from '../../command-prefix';
|
|
7
|
+
import { ErrorCode } from '../../errors';
|
|
6
8
|
|
|
7
9
|
export const signupCommand = createSubcommand({
|
|
8
10
|
name: 'signup',
|
|
9
11
|
description: 'Create a new Agentuity Cloud Platform account',
|
|
12
|
+
tags: ['mutating', 'creates-resource', 'slow', 'api-intensive'],
|
|
10
13
|
toplevel: true,
|
|
14
|
+
idempotent: false,
|
|
11
15
|
requires: { apiClient: true },
|
|
16
|
+
examples: [getCommand('auth signup'), getCommand('signup')],
|
|
12
17
|
|
|
13
18
|
async handler(ctx) {
|
|
14
19
|
const { logger, config, apiClient } = ctx;
|
|
@@ -46,9 +51,9 @@ export const signupCommand = createSubcommand({
|
|
|
46
51
|
tui.banner('CLI Upgrade Required', bannerBody);
|
|
47
52
|
process.exit(1);
|
|
48
53
|
} else if (error instanceof Error) {
|
|
49
|
-
logger.fatal(`Signup failed: ${error.message}
|
|
54
|
+
logger.fatal(`Signup failed: ${error.message}`, ErrorCode.AUTH_FAILED);
|
|
50
55
|
} else {
|
|
51
|
-
logger.fatal('Signup failed');
|
|
56
|
+
logger.fatal('Signup failed', ErrorCode.AUTH_FAILED);
|
|
52
57
|
}
|
|
53
58
|
}
|
|
54
59
|
},
|
package/src/cmd/auth/ssh/add.ts
CHANGED
|
@@ -7,11 +7,19 @@ import { readFileSync, readdirSync, statSync } from 'fs';
|
|
|
7
7
|
import { join } from 'path';
|
|
8
8
|
import { homedir } from 'os';
|
|
9
9
|
import { z } from 'zod';
|
|
10
|
+
import { ErrorCode } from '../../../errors';
|
|
10
11
|
|
|
11
12
|
const optionsSchema = z.object({
|
|
12
13
|
file: z.string().optional().describe('File containing the public key'),
|
|
13
14
|
});
|
|
14
15
|
|
|
16
|
+
const SSHAddResponseSchema = z.object({
|
|
17
|
+
success: z.boolean().describe('Whether the operation succeeded'),
|
|
18
|
+
fingerprint: z.string().describe('SSH key fingerprint'),
|
|
19
|
+
keyType: z.string().describe('SSH key type (e.g., ssh-rsa, ssh-ed25519)'),
|
|
20
|
+
added: z.number().describe('Number of keys added'),
|
|
21
|
+
});
|
|
22
|
+
|
|
15
23
|
interface SSHKeyOption {
|
|
16
24
|
path: string;
|
|
17
25
|
filename: string;
|
|
@@ -107,15 +115,24 @@ export const addCommand = createSubcommand({
|
|
|
107
115
|
name: 'add',
|
|
108
116
|
aliases: ['create'],
|
|
109
117
|
description: 'Add an SSH public key to your account (reads from file or stdin)',
|
|
118
|
+
tags: ['mutating', 'creates-resource', 'slow', 'requires-auth'],
|
|
119
|
+
idempotent: false,
|
|
110
120
|
requires: { apiClient: true, auth: true },
|
|
121
|
+
examples: [
|
|
122
|
+
getCommand('auth ssh add'),
|
|
123
|
+
getCommand('auth ssh add --file ~/.ssh/id_ed25519.pub'),
|
|
124
|
+
getCommand('auth ssh add --file ./deploy_key.pub'),
|
|
125
|
+
'cat ~/.ssh/id_rsa.pub | ' + getCommand('auth ssh add'),
|
|
126
|
+
],
|
|
111
127
|
schema: {
|
|
112
128
|
options: optionsSchema,
|
|
129
|
+
response: SSHAddResponseSchema,
|
|
113
130
|
},
|
|
114
131
|
async handler(ctx) {
|
|
115
132
|
const { logger, apiClient, opts } = ctx;
|
|
116
133
|
|
|
117
134
|
if (!apiClient) {
|
|
118
|
-
logger.fatal('API client is not available');
|
|
135
|
+
logger.fatal('API client is not available', ErrorCode.INTERNAL_ERROR);
|
|
119
136
|
}
|
|
120
137
|
|
|
121
138
|
try {
|
|
@@ -254,9 +271,9 @@ export const addCommand = createSubcommand({
|
|
|
254
271
|
} catch (error) {
|
|
255
272
|
logger.trace(error);
|
|
256
273
|
if (error instanceof Error) {
|
|
257
|
-
logger.fatal(`Failed to add SSH key: ${error.message}
|
|
274
|
+
logger.fatal(`Failed to add SSH key: ${error.message}`, ErrorCode.API_ERROR);
|
|
258
275
|
} else {
|
|
259
|
-
logger.fatal('Failed to add SSH key');
|
|
276
|
+
logger.fatal('Failed to add SSH key', ErrorCode.API_ERROR);
|
|
260
277
|
}
|
|
261
278
|
}
|
|
262
279
|
},
|
|
@@ -3,12 +3,29 @@ import { removeSSHKey, listSSHKeys } from './api';
|
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
4
|
import enquirer from 'enquirer';
|
|
5
5
|
import { z } from 'zod';
|
|
6
|
+
import { isExplainMode, isDryRunMode, outputExplain, outputDryRun } from '../../../explain';
|
|
7
|
+
import { getCommand } from '../../../command-prefix';
|
|
8
|
+
import { ErrorCode } from '../../../errors';
|
|
9
|
+
|
|
10
|
+
const SSHDeleteResponseSchema = z.object({
|
|
11
|
+
success: z.boolean().describe('Whether the operation succeeded'),
|
|
12
|
+
removed: z.number().describe('Number of keys removed'),
|
|
13
|
+
fingerprints: z.array(z.string()).describe('Fingerprints of removed keys'),
|
|
14
|
+
});
|
|
6
15
|
|
|
7
16
|
export const deleteCommand = createSubcommand({
|
|
8
17
|
name: 'delete',
|
|
9
18
|
aliases: ['rm', 'del', 'remove'],
|
|
10
19
|
description: 'Delete an SSH key from your account',
|
|
20
|
+
tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth'],
|
|
11
21
|
requires: { apiClient: true, auth: true },
|
|
22
|
+
idempotent: false,
|
|
23
|
+
examples: [
|
|
24
|
+
getCommand('auth ssh delete'),
|
|
25
|
+
getCommand('auth ssh delete <fingerprint>'),
|
|
26
|
+
getCommand('--explain auth ssh delete abc123'),
|
|
27
|
+
getCommand('--dry-run auth ssh delete abc123'),
|
|
28
|
+
],
|
|
12
29
|
schema: {
|
|
13
30
|
args: z.object({
|
|
14
31
|
fingerprints: z.array(z.string()).optional().describe('SSH key fingerprint(s) to remove'),
|
|
@@ -16,12 +33,13 @@ export const deleteCommand = createSubcommand({
|
|
|
16
33
|
options: z.object({
|
|
17
34
|
confirm: z.boolean().default(true).describe('prompt for confirmation before deletion'),
|
|
18
35
|
}),
|
|
36
|
+
response: SSHDeleteResponseSchema,
|
|
19
37
|
},
|
|
20
38
|
async handler(ctx) {
|
|
21
|
-
const { logger, apiClient, args, opts } = ctx;
|
|
39
|
+
const { logger, apiClient, args, opts, options } = ctx;
|
|
22
40
|
|
|
23
41
|
if (!apiClient) {
|
|
24
|
-
logger.fatal('API client is not available');
|
|
42
|
+
logger.fatal('API client is not available', ErrorCode.INTERNAL_ERROR);
|
|
25
43
|
}
|
|
26
44
|
|
|
27
45
|
const shouldConfirm = process.stdin.isTTY ? opts.confirm : false;
|
|
@@ -67,6 +85,22 @@ export const deleteCommand = createSubcommand({
|
|
|
67
85
|
}
|
|
68
86
|
}
|
|
69
87
|
|
|
88
|
+
// If in explain mode, show what would happen
|
|
89
|
+
if (isExplainMode(options)) {
|
|
90
|
+
outputExplain(
|
|
91
|
+
{
|
|
92
|
+
command: 'auth ssh delete',
|
|
93
|
+
description: 'Delete SSH keys from your account',
|
|
94
|
+
steps: fingerprintsToRemove.map((fp) => ({
|
|
95
|
+
action: `Remove SSH key with fingerprint: ${fp}`,
|
|
96
|
+
})),
|
|
97
|
+
warnings: ['This action cannot be undone'],
|
|
98
|
+
},
|
|
99
|
+
options
|
|
100
|
+
);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
70
104
|
if (shouldConfirm) {
|
|
71
105
|
tui.newline();
|
|
72
106
|
const confirmed = await tui.confirm(
|
|
@@ -80,6 +114,19 @@ export const deleteCommand = createSubcommand({
|
|
|
80
114
|
}
|
|
81
115
|
}
|
|
82
116
|
|
|
117
|
+
// Handle dry-run mode
|
|
118
|
+
if (isDryRunMode(options)) {
|
|
119
|
+
for (const fingerprint of fingerprintsToRemove) {
|
|
120
|
+
outputDryRun(`Would remove SSH key: ${fingerprint}`, options);
|
|
121
|
+
}
|
|
122
|
+
tui.newline();
|
|
123
|
+
tui.info(
|
|
124
|
+
`[DRY RUN] Would remove ${fingerprintsToRemove.length} SSH key${fingerprintsToRemove.length > 1 ? 's' : ''}`
|
|
125
|
+
);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Actually execute the deletion
|
|
83
130
|
for (const fingerprint of fingerprintsToRemove) {
|
|
84
131
|
await tui.spinner(`Removing SSH key ${fingerprint}...`, () =>
|
|
85
132
|
removeSSHKey(apiClient, fingerprint)
|
|
@@ -90,12 +137,18 @@ export const deleteCommand = createSubcommand({
|
|
|
90
137
|
tui.success(
|
|
91
138
|
`Removed ${fingerprintsToRemove.length} SSH key${fingerprintsToRemove.length > 1 ? 's' : ''}`
|
|
92
139
|
);
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
success: true,
|
|
143
|
+
removed: fingerprintsToRemove.length,
|
|
144
|
+
fingerprints: fingerprintsToRemove,
|
|
145
|
+
};
|
|
93
146
|
} catch (error) {
|
|
94
147
|
logger.trace(error);
|
|
95
148
|
if (error instanceof Error) {
|
|
96
|
-
logger.fatal(`Failed to remove SSH key: ${error.message}
|
|
149
|
+
logger.fatal(`Failed to remove SSH key: ${error.message}`, ErrorCode.API_ERROR);
|
|
97
150
|
} else {
|
|
98
|
-
logger.fatal('Failed to remove SSH key');
|
|
151
|
+
logger.fatal('Failed to remove SSH key', ErrorCode.API_ERROR);
|
|
99
152
|
}
|
|
100
153
|
}
|
|
101
154
|
},
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { createCommand } from '../../../types';
|
|
2
2
|
import { listCommand } from './list';
|
|
3
3
|
import { addCommand } from './add';
|
|
4
4
|
import { deleteCommand } from './delete';
|
|
5
5
|
|
|
6
|
-
export const sshSubcommand
|
|
6
|
+
export const sshSubcommand = createCommand({
|
|
7
7
|
name: 'ssh',
|
|
8
8
|
description: 'Manage SSH keys',
|
|
9
|
+
tags: ['fast', 'requires-auth'],
|
|
9
10
|
subcommands: [listCommand, addCommand, deleteCommand],
|
|
10
|
-
};
|
|
11
|
+
});
|
package/src/cmd/auth/ssh/list.ts
CHANGED
|
@@ -1,68 +1,79 @@
|
|
|
1
1
|
import { createSubcommand } from '../../../types';
|
|
2
2
|
import { listSSHKeys } from './api';
|
|
3
3
|
import * as tui from '../../../tui';
|
|
4
|
+
import { getCommand } from '../../../command-prefix';
|
|
5
|
+
import { ErrorCode } from '../../../errors';
|
|
4
6
|
import { z } from 'zod';
|
|
5
|
-
|
|
7
|
+
|
|
8
|
+
const SSHListResponseSchema = z.array(
|
|
9
|
+
z.object({
|
|
10
|
+
id: z.string().describe('SSH key ID'),
|
|
11
|
+
fingerprint: z.string().describe('SSH key fingerprint'),
|
|
12
|
+
keyType: z.string().describe('SSH key type (e.g., ssh-rsa, ssh-ed25519)'),
|
|
13
|
+
comment: z.string().optional().describe('SSH key comment'),
|
|
14
|
+
createdAt: z.string().optional().describe('Creation timestamp'),
|
|
15
|
+
})
|
|
16
|
+
);
|
|
6
17
|
|
|
7
18
|
export const listCommand = createSubcommand({
|
|
8
19
|
name: 'list',
|
|
9
20
|
aliases: ['ls'],
|
|
10
21
|
description: 'List all SSH keys on your account',
|
|
22
|
+
tags: ['read-only', 'fast', 'requires-auth'],
|
|
11
23
|
requires: { apiClient: true, auth: true },
|
|
24
|
+
idempotent: true,
|
|
25
|
+
examples: [
|
|
26
|
+
getCommand('auth ssh list'),
|
|
27
|
+
getCommand('auth ssh ls'),
|
|
28
|
+
getCommand('--json auth ssh list'),
|
|
29
|
+
],
|
|
12
30
|
schema: {
|
|
13
|
-
|
|
14
|
-
format: z.enum(['text', 'json']).default('text').describe('output format'),
|
|
15
|
-
}),
|
|
31
|
+
response: SSHListResponseSchema,
|
|
16
32
|
},
|
|
17
33
|
async handler(ctx) {
|
|
18
|
-
const { logger, apiClient,
|
|
19
|
-
const format = opts.format;
|
|
34
|
+
const { logger, apiClient, options } = ctx;
|
|
20
35
|
|
|
21
36
|
if (!apiClient) {
|
|
22
|
-
logger.fatal('API client is not available');
|
|
37
|
+
logger.fatal('API client is not available', ErrorCode.INTERNAL_ERROR);
|
|
23
38
|
}
|
|
24
39
|
|
|
25
40
|
try {
|
|
26
41
|
const keys = await tui.spinner('Fetching SSH keys...', () => listSSHKeys(apiClient));
|
|
27
42
|
|
|
28
|
-
if (
|
|
43
|
+
if (options.json) {
|
|
29
44
|
console.log(JSON.stringify(keys, null, 2));
|
|
30
|
-
return;
|
|
45
|
+
return keys;
|
|
31
46
|
}
|
|
32
47
|
|
|
33
48
|
tui.newline();
|
|
34
49
|
|
|
35
50
|
if (keys.length === 0) {
|
|
36
51
|
console.log('No SSH keys found');
|
|
37
|
-
return;
|
|
52
|
+
return [];
|
|
38
53
|
}
|
|
39
54
|
|
|
40
55
|
console.log(tui.bold('SSH Keys:'));
|
|
41
56
|
tui.newline();
|
|
42
57
|
|
|
43
|
-
const
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
],
|
|
49
|
-
});
|
|
58
|
+
const tableData = keys.map((key) => ({
|
|
59
|
+
TYPE: key.keyType,
|
|
60
|
+
FINGERPRINT: key.fingerprint,
|
|
61
|
+
COMMENT: key.comment || tui.muted('(no comment)'),
|
|
62
|
+
}));
|
|
50
63
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
table.printTable();
|
|
64
|
+
tui.table(tableData, [
|
|
65
|
+
{ name: 'TYPE', alignment: 'left' },
|
|
66
|
+
{ name: 'FINGERPRINT', alignment: 'left' },
|
|
67
|
+
{ name: 'COMMENT', alignment: 'left' },
|
|
68
|
+
]);
|
|
59
69
|
|
|
70
|
+
return keys;
|
|
60
71
|
} catch (error) {
|
|
61
72
|
logger.trace(error);
|
|
62
73
|
if (error instanceof Error) {
|
|
63
|
-
logger.fatal(`Failed to list SSH keys: ${error.message}
|
|
74
|
+
logger.fatal(`Failed to list SSH keys: ${error.message}`, ErrorCode.API_ERROR);
|
|
64
75
|
} else {
|
|
65
|
-
logger.fatal('Failed to list SSH keys');
|
|
76
|
+
logger.fatal('Failed to list SSH keys', ErrorCode.API_ERROR);
|
|
66
77
|
}
|
|
67
78
|
}
|
|
68
79
|
},
|
package/src/cmd/auth/whoami.ts
CHANGED
|
@@ -1,23 +1,36 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { createSubcommand } from '../../types';
|
|
3
2
|
import * as tui from '../../tui';
|
|
4
3
|
import { whoami } from '@agentuity/server';
|
|
4
|
+
import { getCommand } from '../../command-prefix';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
|
|
7
|
+
const WhoamiResponseSchema = z.object({
|
|
8
|
+
userId: z.string().describe('Unique user identifier'),
|
|
9
|
+
firstName: z.string().describe('User first name'),
|
|
10
|
+
lastName: z.string().describe('User last name'),
|
|
11
|
+
organizations: z
|
|
12
|
+
.array(
|
|
13
|
+
z.object({
|
|
14
|
+
id: z.string().describe('Organization ID'),
|
|
15
|
+
name: z.string().describe('Organization name'),
|
|
16
|
+
})
|
|
17
|
+
)
|
|
18
|
+
.describe('Organizations the user belongs to'),
|
|
19
|
+
});
|
|
5
20
|
|
|
6
21
|
export const whoamiCommand = createSubcommand({
|
|
7
22
|
name: 'whoami',
|
|
8
23
|
description: 'Display information about the currently authenticated user',
|
|
24
|
+
tags: ['read-only', 'fast', 'requires-auth'],
|
|
9
25
|
requires: { auth: true, apiClient: true },
|
|
26
|
+
idempotent: true,
|
|
10
27
|
schema: {
|
|
11
|
-
|
|
12
|
-
format: z
|
|
13
|
-
.enum(['json', 'table'])
|
|
14
|
-
.optional()
|
|
15
|
-
.describe('the output format: json, table (default)'),
|
|
16
|
-
}),
|
|
28
|
+
response: WhoamiResponseSchema,
|
|
17
29
|
},
|
|
30
|
+
examples: [getCommand('auth whoami'), getCommand('--json auth whoami')],
|
|
18
31
|
|
|
19
32
|
async handler(ctx) {
|
|
20
|
-
const { apiClient,
|
|
33
|
+
const { apiClient, auth, options } = ctx;
|
|
21
34
|
|
|
22
35
|
if (!apiClient) {
|
|
23
36
|
throw new Error(
|
|
@@ -33,19 +46,15 @@ export const whoamiCommand = createSubcommand({
|
|
|
33
46
|
},
|
|
34
47
|
});
|
|
35
48
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
null,
|
|
46
|
-
2
|
|
47
|
-
)
|
|
48
|
-
);
|
|
49
|
+
const result = {
|
|
50
|
+
userId: auth?.userId || '',
|
|
51
|
+
firstName: user.firstName,
|
|
52
|
+
lastName: user.lastName,
|
|
53
|
+
organizations: user.organizations,
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
if (options.json) {
|
|
57
|
+
console.log(JSON.stringify(result, null, 2));
|
|
49
58
|
} else {
|
|
50
59
|
const fullName = `${user.firstName} ${user.lastName}`;
|
|
51
60
|
|
|
@@ -65,5 +74,7 @@ export const whoamiCommand = createSubcommand({
|
|
|
65
74
|
}
|
|
66
75
|
tui.newline();
|
|
67
76
|
}
|
|
77
|
+
|
|
78
|
+
return result;
|
|
68
79
|
},
|
|
69
80
|
});
|
|
@@ -278,8 +278,8 @@ describe('parseEvalMetadata', () => {
|
|
|
278
278
|
TEST_DEPLOYMENT_ID
|
|
279
279
|
);
|
|
280
280
|
|
|
281
|
-
|
|
282
|
-
expect(result
|
|
281
|
+
// Non-exported evals should not be included in metadata
|
|
282
|
+
expect(result).toHaveLength(0);
|
|
283
283
|
});
|
|
284
284
|
});
|
|
285
285
|
|
package/src/cmd/bundle/ast.ts
CHANGED
|
@@ -116,6 +116,10 @@ function hashSHA1(...val: string[]): string {
|
|
|
116
116
|
return hasher.digest().toHex();
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
export function getDevmodeDeploymentId(projectId: string, endpointId: string): string {
|
|
120
|
+
return `devmode_${hashSHA1(projectId, endpointId)}`;
|
|
121
|
+
}
|
|
122
|
+
|
|
119
123
|
function getAgentId(
|
|
120
124
|
projectId: string,
|
|
121
125
|
deploymentId: string,
|
|
@@ -147,31 +151,55 @@ function generateRouteId(
|
|
|
147
151
|
return `route_${hashSHA1(projectId, deploymentId, type, method, filename, path, version)}`;
|
|
148
152
|
}
|
|
149
153
|
|
|
154
|
+
function generateStableAgentId(projectId: string, name: string): string {
|
|
155
|
+
return `agentid_${hashSHA1(projectId, name)}`.substring(0, 64);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function generateStableEvalId(projectId: string, agentId: string, name: string): string {
|
|
159
|
+
return `evalid_${hashSHA1(projectId, agentId, name)}`.substring(0, 64);
|
|
160
|
+
}
|
|
161
|
+
|
|
150
162
|
type AcornParseResultType = ReturnType<typeof acornLoose.parse>;
|
|
151
163
|
|
|
152
164
|
function augmentAgentMetadataNode(
|
|
165
|
+
projectId: string,
|
|
153
166
|
id: string,
|
|
154
167
|
name: string,
|
|
155
168
|
rel: string,
|
|
156
169
|
version: string,
|
|
157
170
|
ast: AcornParseResultType,
|
|
158
171
|
propvalue: ASTObjectExpression,
|
|
159
|
-
|
|
172
|
+
filename: string
|
|
160
173
|
): [string, Map<string, string>] {
|
|
161
174
|
const metadata = parseObjectExpressionToMap(propvalue);
|
|
162
175
|
if (!metadata.has('name')) {
|
|
163
|
-
|
|
164
|
-
|
|
176
|
+
const location = ast.loc?.start ? ` on line ${ast.loc.start}` : '';
|
|
177
|
+
throw new Error(
|
|
178
|
+
`missing required metadata.name in ${filename}${location}. This Agent should have a unique and human readable name for this project.`
|
|
179
|
+
);
|
|
165
180
|
}
|
|
181
|
+
if (metadata.has('identifier') && name !== metadata.get('identifier')) {
|
|
182
|
+
const location = ast.loc?.start ? ` on line ${ast.loc.start}` : '';
|
|
183
|
+
throw new Error(
|
|
184
|
+
`metadata.identifier (${metadata.get('identifier')}) in ${filename}${location} is mismatched (${name}). This is an internal error.`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
const descriptionNode = propvalue.properties.find((x) => x.key.name === 'description')?.value;
|
|
188
|
+
const description = descriptionNode ? (descriptionNode as ASTLiteral).value : '';
|
|
189
|
+
const agentId = generateStableAgentId(projectId, name);
|
|
166
190
|
metadata.set('version', version);
|
|
167
191
|
metadata.set('identifier', name);
|
|
168
192
|
metadata.set('filename', rel);
|
|
169
193
|
metadata.set('id', id);
|
|
194
|
+
metadata.set('agentId', agentId);
|
|
195
|
+
metadata.set('description', description);
|
|
170
196
|
propvalue.properties.push(
|
|
171
197
|
createObjectPropertyNode('id', id),
|
|
198
|
+
createObjectPropertyNode('agentId', agentId),
|
|
172
199
|
createObjectPropertyNode('version', version),
|
|
173
200
|
createObjectPropertyNode('identifier', name),
|
|
174
|
-
createObjectPropertyNode('filename', rel)
|
|
201
|
+
createObjectPropertyNode('filename', rel),
|
|
202
|
+
createObjectPropertyNode('description', description)
|
|
175
203
|
);
|
|
176
204
|
|
|
177
205
|
const newsource = generate(ast);
|
|
@@ -222,14 +250,29 @@ function setLiteralValue(literal: ASTLiteral, value: string) {
|
|
|
222
250
|
}
|
|
223
251
|
|
|
224
252
|
function augmentEvalMetadataNode(
|
|
253
|
+
projectId: string,
|
|
254
|
+
agentId: string,
|
|
225
255
|
id: string,
|
|
226
256
|
name: string,
|
|
227
257
|
rel: string,
|
|
228
258
|
version: string,
|
|
229
|
-
|
|
230
|
-
metadataObj: ASTObjectExpression
|
|
259
|
+
_ast: AcornParseResultType,
|
|
260
|
+
metadataObj: ASTObjectExpression,
|
|
261
|
+
_filename: string
|
|
231
262
|
): void {
|
|
232
|
-
|
|
263
|
+
const metadata = parseObjectExpressionToMap(metadataObj);
|
|
264
|
+
// Name can come from metadata.name or variable name (already resolved in caller)
|
|
265
|
+
// If metadata doesn't have name, we'll add it from the resolved name
|
|
266
|
+
if (!metadata.has('name')) {
|
|
267
|
+
metadataObj.properties.push(createObjectPropertyNode('name', name));
|
|
268
|
+
}
|
|
269
|
+
const descriptionNode = metadataObj.properties.find((x) => x.key.name === 'description')?.value;
|
|
270
|
+
const description = descriptionNode ? (descriptionNode as ASTLiteral).value : '';
|
|
271
|
+
const effectiveAgentId = agentId || '';
|
|
272
|
+
const _evalId = getEvalId(projectId, effectiveAgentId, rel, name, version); // Deployment-specific ID (not used, kept for potential future use)
|
|
273
|
+
const stableEvalId = generateStableEvalId(projectId, effectiveAgentId, name);
|
|
274
|
+
|
|
275
|
+
// Check if id, version, identifier, filename, evalId already exist
|
|
233
276
|
const existingKeys = new Set<string>();
|
|
234
277
|
for (const prop of metadataObj.properties) {
|
|
235
278
|
if (prop.key.type === 'Identifier') {
|
|
@@ -266,12 +309,12 @@ function augmentEvalMetadataNode(
|
|
|
266
309
|
}
|
|
267
310
|
|
|
268
311
|
if (!existingKeys.has('identifier')) {
|
|
269
|
-
metadataObj.properties.push(createObjectPropertyNode('identifier',
|
|
312
|
+
metadataObj.properties.push(createObjectPropertyNode('identifier', name));
|
|
270
313
|
} else {
|
|
271
314
|
for (const prop of metadataObj.properties) {
|
|
272
315
|
if (prop.key.type === 'Identifier' && prop.key.name === 'identifier') {
|
|
273
316
|
if (prop.value.type === 'Literal') {
|
|
274
|
-
setLiteralValue(prop.value as ASTLiteral,
|
|
317
|
+
setLiteralValue(prop.value as ASTLiteral, name);
|
|
275
318
|
}
|
|
276
319
|
break;
|
|
277
320
|
}
|
|
@@ -290,6 +333,32 @@ function augmentEvalMetadataNode(
|
|
|
290
333
|
}
|
|
291
334
|
}
|
|
292
335
|
}
|
|
336
|
+
|
|
337
|
+
if (!existingKeys.has('evalId')) {
|
|
338
|
+
metadataObj.properties.push(createObjectPropertyNode('evalId', stableEvalId));
|
|
339
|
+
} else {
|
|
340
|
+
for (const prop of metadataObj.properties) {
|
|
341
|
+
if (prop.key.type === 'Identifier' && prop.key.name === 'evalId') {
|
|
342
|
+
if (prop.value.type === 'Literal') {
|
|
343
|
+
setLiteralValue(prop.value as ASTLiteral, stableEvalId);
|
|
344
|
+
}
|
|
345
|
+
break;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
if (!existingKeys.has('description')) {
|
|
351
|
+
metadataObj.properties.push(createObjectPropertyNode('description', description));
|
|
352
|
+
} else {
|
|
353
|
+
for (const prop of metadataObj.properties) {
|
|
354
|
+
if (prop.key.type === 'Identifier' && prop.key.name === 'description') {
|
|
355
|
+
if (prop.value.type === 'Literal') {
|
|
356
|
+
setLiteralValue(prop.value as ASTLiteral, description);
|
|
357
|
+
}
|
|
358
|
+
break;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
}
|
|
293
362
|
}
|
|
294
363
|
|
|
295
364
|
export function parseEvalMetadata(
|
|
@@ -297,7 +366,8 @@ export function parseEvalMetadata(
|
|
|
297
366
|
filename: string,
|
|
298
367
|
contents: string,
|
|
299
368
|
projectId: string,
|
|
300
|
-
deploymentId: string
|
|
369
|
+
deploymentId: string,
|
|
370
|
+
agentId?: string
|
|
301
371
|
): [
|
|
302
372
|
string,
|
|
303
373
|
Array<{
|
|
@@ -306,6 +376,7 @@ export function parseEvalMetadata(
|
|
|
306
376
|
version: string;
|
|
307
377
|
identifier: string;
|
|
308
378
|
name: string;
|
|
379
|
+
evalId: string;
|
|
309
380
|
description?: string;
|
|
310
381
|
}>,
|
|
311
382
|
] {
|
|
@@ -319,8 +390,6 @@ export function parseEvalMetadata(
|
|
|
319
390
|
logger.trace(`Parsing evals from ${filename}`);
|
|
320
391
|
const ast = acornLoose.parse(contents, { ecmaVersion: 'latest', sourceType: 'module' });
|
|
321
392
|
const rel = relative(rootDir, filename);
|
|
322
|
-
const dir = dirname(filename);
|
|
323
|
-
const identifier = basename(dir);
|
|
324
393
|
const version = hash(contents);
|
|
325
394
|
const evals: Array<{
|
|
326
395
|
filename: string;
|
|
@@ -328,17 +397,16 @@ export function parseEvalMetadata(
|
|
|
328
397
|
version: string;
|
|
329
398
|
identifier: string;
|
|
330
399
|
name: string;
|
|
400
|
+
evalId: string;
|
|
331
401
|
description?: string;
|
|
332
402
|
}> = [];
|
|
333
403
|
|
|
334
|
-
// Find all agent.createEval() calls
|
|
404
|
+
// Find all exported agent.createEval() calls
|
|
335
405
|
for (const body of ast.body) {
|
|
336
406
|
let variableDeclaration: { declarations: Array<ASTVariableDeclarator> } | undefined;
|
|
337
407
|
|
|
338
|
-
//
|
|
339
|
-
if (body.type === '
|
|
340
|
-
variableDeclaration = body as { declarations: Array<ASTVariableDeclarator> };
|
|
341
|
-
} else if (body.type === 'ExportNamedDeclaration') {
|
|
408
|
+
// Only process exported VariableDeclarations
|
|
409
|
+
if (body.type === 'ExportNamedDeclaration') {
|
|
342
410
|
const exportDecl = body as {
|
|
343
411
|
declaration?: { type: string; declarations?: Array<ASTVariableDeclarator> };
|
|
344
412
|
};
|
|
@@ -427,14 +495,31 @@ export function parseEvalMetadata(
|
|
|
427
495
|
);
|
|
428
496
|
|
|
429
497
|
// Inject metadata into AST if metadata object exists
|
|
498
|
+
let stableEvalId: string;
|
|
499
|
+
const effectiveAgentId = agentId || '';
|
|
430
500
|
if (metadataObj) {
|
|
431
501
|
augmentEvalMetadataNode(
|
|
502
|
+
projectId,
|
|
503
|
+
effectiveAgentId,
|
|
432
504
|
evalId,
|
|
433
505
|
finalName,
|
|
434
506
|
rel,
|
|
435
507
|
version,
|
|
436
|
-
|
|
437
|
-
metadataObj
|
|
508
|
+
ast,
|
|
509
|
+
metadataObj,
|
|
510
|
+
filename
|
|
511
|
+
);
|
|
512
|
+
// Extract evalId from metadata after augmentation
|
|
513
|
+
const metadata = parseObjectExpressionToMap(metadataObj);
|
|
514
|
+
stableEvalId =
|
|
515
|
+
metadata.get('evalId') ||
|
|
516
|
+
generateStableEvalId(projectId, effectiveAgentId, finalName);
|
|
517
|
+
} else {
|
|
518
|
+
// If no metadata object, generate stable evalId
|
|
519
|
+
stableEvalId = generateStableEvalId(
|
|
520
|
+
projectId,
|
|
521
|
+
effectiveAgentId,
|
|
522
|
+
finalName
|
|
438
523
|
);
|
|
439
524
|
}
|
|
440
525
|
|
|
@@ -442,8 +527,9 @@ export function parseEvalMetadata(
|
|
|
442
527
|
filename: rel,
|
|
443
528
|
id: evalId,
|
|
444
529
|
version,
|
|
445
|
-
identifier,
|
|
530
|
+
identifier: finalName,
|
|
446
531
|
name: finalName,
|
|
532
|
+
evalId: stableEvalId,
|
|
447
533
|
description: evalDescription,
|
|
448
534
|
});
|
|
449
535
|
}
|
|
@@ -508,6 +594,7 @@ export async function parseAgentMetadata(
|
|
|
508
594
|
for (const prop of callargexp.properties) {
|
|
509
595
|
if (prop.key.type === 'Identifier' && prop.key.name === 'metadata') {
|
|
510
596
|
result = augmentAgentMetadataNode(
|
|
597
|
+
projectId,
|
|
511
598
|
id,
|
|
512
599
|
name,
|
|
513
600
|
rel,
|
|
@@ -562,6 +649,7 @@ export async function parseAgentMetadata(
|
|
|
562
649
|
prop.key.name === 'metadata'
|
|
563
650
|
) {
|
|
564
651
|
result = augmentAgentMetadataNode(
|
|
652
|
+
projectId,
|
|
565
653
|
id,
|
|
566
654
|
name,
|
|
567
655
|
rel,
|
|
@@ -615,14 +703,16 @@ export async function parseAgentMetadata(
|
|
|
615
703
|
if (await evalsFile.exists()) {
|
|
616
704
|
logger.trace(`Found evals file at ${evalsPath}, parsing...`);
|
|
617
705
|
const evalsSource = await evalsFile.text();
|
|
618
|
-
const transpiler = new Bun.Transpiler({ loader: 'ts' });
|
|
706
|
+
const transpiler = new Bun.Transpiler({ loader: 'ts', target: 'bun' });
|
|
619
707
|
const evalsContents = transpiler.transformSync(evalsSource);
|
|
708
|
+
const agentId = result[1].get('agentId') || '';
|
|
620
709
|
const [, evals] = parseEvalMetadata(
|
|
621
710
|
rootDir,
|
|
622
711
|
evalsPath,
|
|
623
712
|
evalsContents,
|
|
624
713
|
projectId,
|
|
625
|
-
deploymentId
|
|
714
|
+
deploymentId,
|
|
715
|
+
agentId
|
|
626
716
|
);
|
|
627
717
|
if (evals.length > 0) {
|
|
628
718
|
logger.trace(`Adding ${evals.length} eval(s) to agent metadata for ${name}`);
|