Skip to content

Commit ee402d7

Browse files
committed
fix(cli): correct inaccurate --help text across all commands
Audit and fix help text for all CLI commands and primitives: - Fix agent name constraints: "max 64 chars" → "max 48 chars", add "underscores" to allowed characters - Fix project name constraint: "max 36 chars" → "max 23 chars" - Remove CrewAI from framework lists (not user-accessible) - Fix "Remove a agent" → "Remove an agent" grammar - Add missing resource types (evaluator, online-eval) to status --type - Remove phantom 'edit' command from COMMAND_DESCRIPTIONS - Remove false --agent-arn claim from evals description - Add [non-interactive] markers to all options missing them in EvaluatorPrimitive, GatewayPrimitive, GatewayTargetPrimitive, and PolicyEnginePrimitive - Improve gateway and gateway-target help descriptions for clarity - Update AGENTS.md to match current CLI reality Constraint: Help text and Zod schemas are defined in separate files with no shared constant Confidence: high Scope-risk: narrow Not-tested: Interactive TUI mode (only CLI --help verified)
1 parent acd300d commit ee402d7

9 files changed

Lines changed: 108 additions & 76 deletions

File tree

AGENTS.md

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,17 @@ Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.
2424
## CLI Commands
2525

2626
- `create` - Create new AgentCore project
27-
- `add` - Add resources (agent, memory, identity, evaluator, online-eval, target)
28-
- `remove` - Remove resources (agent, memory, identity, evaluator, online-eval, target, all)
27+
- `add` - Add resources (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine,
28+
policy)
29+
- `remove` - Remove resources (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine,
30+
policy, all)
2931
- `deploy` - Deploy infrastructure to AWS
3032
- `status` - Check deployment status
3133
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
3234
- `invoke` - Invoke agents (local or deployed)
3335
- `run eval` - Run on-demand evaluation against agent sessions
3436
- `evals history` - View past eval run results
37+
- `fetch access` - Fetch access info for a deployed gateway
3538
- `pause online-eval` - Pause (disable) a deployed online eval config
3639
- `resume online-eval` - Resume (enable) a paused online eval config
3740
- `logs` - Stream or search agent runtime logs
@@ -45,8 +48,7 @@ Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.
4548

4649
### Agent Types
4750

48-
- **Template agents**: Created from framework templates (Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents,
49-
AutoGen)
51+
- **Template agents**: Created from framework templates (Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents)
5052
- **BYO agents**: Bring your own code with `agentcore add agent --type byo`
5153
- **Imported agents**: Import from Bedrock Agents with `agentcore add agent --type import`
5254

@@ -58,10 +60,10 @@ Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.
5860

5961
## Primitives Architecture
6062

61-
All resource types (agent, memory, identity, evaluator, online-eval, gateway, mcp-tool) are modeled as **primitives** --
62-
self-contained classes in `src/cli/primitives/` that own the full add/remove lifecycle for their resource type.
63-
Resources support config-driven tagging via `agentcore.json` and `mcp.json`, with tags flowing through to deployed
64-
CloudFormation resources.
63+
All resource types (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine, policy) are
64+
modeled as **primitives** -- self-contained classes in `src/cli/primitives/` that own the full add/remove lifecycle for
65+
their resource type. Resources support config-driven tagging via `agentcore.json` and `mcp.json`, with tags flowing
66+
through to deployed CloudFormation resources.
6567

6668
Each primitive extends `BasePrimitive` and implements: `add()`, `remove()`, `previewRemove()`, `getRemovable()`,
6769
`registerCommands()`, and `addScreen()`.
@@ -73,8 +75,10 @@ Current primitives:
7375
- `CredentialPrimitive` — credential/identity creation, .env management, removal
7476
- `EvaluatorPrimitive` — custom evaluator creation/removal with cross-reference validation
7577
- `OnlineEvalConfigPrimitive` — online eval config creation/removal
76-
- `GatewayPrimitive` — MCP gateway creation/removal
77-
- `GatewayTargetPrimitive` — MCP tool creation/removal with code generation
78+
- `GatewayPrimitive` — gateway creation/removal
79+
- `GatewayTargetPrimitive` — gateway target creation/removal with code generation
80+
- `PolicyEnginePrimitive` — Cedar policy engine creation/removal
81+
- `PolicyPrimitive` — Cedar policy creation/removal within policy engines
7882

7983
Singletons are created in `registry.ts` and wired into CLI commands via `cli.ts`. See `src/cli/AGENTS.md` for details on
8084
adding new primitives.

src/cli/commands/create/command.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,14 +156,14 @@ export const registerCreate = (program: Command) => {
156156
program
157157
.command('create')
158158
.description(COMMAND_DESCRIPTIONS.create)
159-
.option('--name <name>', 'Project name (start with letter, alphanumeric only, max 36 chars) [non-interactive]')
159+
.option('--name <name>', 'Project name (start with letter, alphanumeric only, max 23 chars) [non-interactive]')
160160
.option('--no-agent', 'Skip agent creation [non-interactive]')
161161
.option('--defaults', 'Use defaults (Python, Strands, Bedrock, no memory) [non-interactive]')
162162
.option('--build <type>', 'Build type: CodeZip or Container (default: CodeZip) [non-interactive]')
163163
.option('--language <language>', 'Target language (default: Python) [non-interactive]')
164164
.option(
165165
'--framework <framework>',
166-
'Agent framework (Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents) [non-interactive]'
166+
'Agent framework (Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents) [non-interactive]'
167167
)
168168
.option('--model-provider <provider>', 'Model provider (Bedrock, Anthropic, OpenAI, Gemini) [non-interactive]')
169169
.option('--api-key <key>', 'API key for non-Bedrock providers [non-interactive]')

src/cli/commands/status/command.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,10 @@ export const registerStatus = (program: Command) => {
5656
.description(COMMAND_DESCRIPTIONS.status)
5757
.option('--agent-runtime-id <id>', 'Look up a specific agent runtime by ID')
5858
.option('--target <name>', 'Select deployment target')
59-
.option('--type <type>', 'Filter by resource type (agent, memory, credential, gateway, policy-engine, policy)')
59+
.option(
60+
'--type <type>',
61+
'Filter by resource type (agent, memory, credential, gateway, evaluator, online-eval, policy-engine, policy)'
62+
)
6063
.option('--state <state>', 'Filter by deployment state (deployed, local-only, pending-removal)')
6164
.option('--agent <name>', 'Filter to a specific agent')
6265
.option('--json', 'Output as JSON')

src/cli/primitives/AgentPrimitive.tsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export interface AddAgentOptions extends VpcOptions {
6262
export class AgentPrimitive extends BasePrimitive<AddAgentOptions, RemovableResource> {
6363
readonly kind = 'agent';
6464
readonly label = 'Agent';
65+
protected override readonly article = 'an';
6566
readonly primitiveSchema = AgentEnvSpecSchema;
6667

6768
/** Local instance to avoid circular dependency with registry. */
@@ -173,14 +174,14 @@ export class AgentPrimitive extends BasePrimitive<AddAgentOptions, RemovableReso
173174
addCmd
174175
.command('agent')
175176
.description('Add an agent to the project')
176-
.option('--name <name>', 'Agent name (start with letter, alphanumeric only, max 64 chars) [non-interactive]')
177+
.option(
178+
'--name <name>',
179+
'Agent name (start with letter, alphanumeric and underscores only, max 48 chars) [non-interactive]'
180+
)
177181
.option('--type <type>', 'Agent type: create, byo, or import [non-interactive]', 'create')
178182
.option('--build <type>', 'Build type: CodeZip or Container (default: CodeZip) [non-interactive]')
179183
.option('--language <lang>', 'Language: Python (create), or Python/TypeScript/Other (BYO) [non-interactive]')
180-
.option(
181-
'--framework <fw>',
182-
'Framework: Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents [non-interactive]'
183-
)
184+
.option('--framework <fw>', 'Framework: Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents [non-interactive]')
184185
.option('--model-provider <provider>', 'Model provider: Bedrock, Anthropic, OpenAI, Gemini [non-interactive]')
185186
.option('--api-key <key>', 'API key for non-Bedrock providers [non-interactive]')
186187
.option('--memory <mem>', 'Memory: none, shortTerm, longAndShortTerm (create path only) [non-interactive]')

src/cli/primitives/EvaluatorPrimitive.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -124,19 +124,22 @@ export class EvaluatorPrimitive extends BasePrimitive<AddEvaluatorOptions, Remov
124124
addCmd
125125
.command(this.kind)
126126
.description('Add a custom evaluator to the project')
127-
.option('--name <name>', 'Evaluator name')
128-
.option('--level <level>', 'Evaluation level: SESSION, TRACE, TOOL_CALL')
129-
.option('--model <model>', 'Bedrock model ID for LLM-as-a-Judge')
127+
.option('--name <name>', 'Evaluator name [non-interactive]')
128+
.option('--level <level>', 'Evaluation level: SESSION, TRACE, TOOL_CALL [non-interactive]')
129+
.option('--model <model>', 'Bedrock model ID for LLM-as-a-Judge [non-interactive]')
130130
.option(
131131
'--instructions <text>',
132-
'Evaluation prompt instructions (must include level-appropriate placeholders, e.g. {context})'
132+
'Evaluation prompt instructions (must include level-appropriate placeholders, e.g. {context}) [non-interactive]'
133+
)
134+
.option(
135+
'--rating-scale <preset>',
136+
`Rating scale preset: ${presetIds.join(', ')} (default: 1-5-quality) [non-interactive]`
133137
)
134-
.option('--rating-scale <preset>', `Rating scale preset: ${presetIds.join(', ')} (default: 1-5-quality)`)
135138
.option(
136139
'--config <path>',
137-
'Path to evaluator config JSON file (overrides --model, --instructions, --rating-scale)'
140+
'Path to evaluator config JSON file (overrides --model, --instructions, --rating-scale) [non-interactive]'
138141
)
139-
.option('--json', 'Output as JSON')
142+
.option('--json', 'Output as JSON [non-interactive]')
140143
.action(
141144
async (cliOptions: {
142145
name?: string;

src/cli/primitives/GatewayPrimitive.ts

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -158,23 +158,27 @@ export class GatewayPrimitive extends BasePrimitive<AddGatewayOptions, Removable
158158
registerCommands(addCmd: Command, removeCmd: Command): void {
159159
addCmd
160160
.command('gateway')
161-
.description('Add a gateway to the project')
162-
.option('--name <name>', 'Gateway name')
163-
.option('--description <desc>', 'Gateway description')
164-
.option('--authorizer-type <type>', 'Authorizer type: NONE or CUSTOM_JWT')
165-
.option('--discovery-url <url>', 'OIDC discovery URL (for CUSTOM_JWT)')
166-
.option('--allowed-audience <audience>', 'Comma-separated allowed audiences (for CUSTOM_JWT)')
167-
.option('--allowed-clients <clients>', 'Comma-separated allowed client IDs (for CUSTOM_JWT)')
168-
.option('--allowed-scopes <scopes>', 'Comma-separated allowed scopes (for CUSTOM_JWT)')
169-
.option('--custom-claims <json>', 'Custom claim validations as JSON array (for CUSTOM_JWT)')
170-
.option('--client-id <id>', 'OAuth client ID for gateway bearer token')
171-
.option('--client-secret <secret>', 'OAuth client secret')
172-
.option('--agents <agents>', 'Comma-separated agent names')
173-
.option('--no-semantic-search', 'Disable semantic search for tool discovery')
174-
.option('--exception-level <level>', 'Exception verbosity level', 'NONE')
175-
.option('--policy-engine <name>', 'Policy engine name for Cedar-based authorization')
176-
.option('--policy-engine-mode <mode>', 'Policy engine mode: LOG_ONLY or ENFORCE')
177-
.option('--json', 'Output as JSON')
161+
.description('Add an API gateway that routes requests to agent targets')
162+
.option('--name <name>', 'Gateway name [non-interactive]')
163+
.option('--description <desc>', 'Gateway description [non-interactive]')
164+
.option('--agents <agents>', 'Comma-separated agent names to expose through this gateway [non-interactive]')
165+
.option('--authorizer-type <type>', 'Authorizer type: NONE or CUSTOM_JWT [non-interactive]')
166+
.option('--discovery-url <url>', 'OIDC discovery URL (for CUSTOM_JWT) [non-interactive]')
167+
.option('--allowed-audience <audience>', 'Comma-separated allowed audiences (for CUSTOM_JWT) [non-interactive]')
168+
.option('--allowed-clients <clients>', 'Comma-separated allowed client IDs (for CUSTOM_JWT) [non-interactive]')
169+
.option('--allowed-scopes <scopes>', 'Comma-separated allowed scopes (for CUSTOM_JWT) [non-interactive]')
170+
.option('--custom-claims <json>', 'Custom claim validations as JSON array (for CUSTOM_JWT) [non-interactive]')
171+
.option('--client-id <id>', 'OAuth client ID for fetching gateway bearer tokens [non-interactive]')
172+
.option('--client-secret <secret>', 'OAuth client secret for fetching gateway bearer tokens [non-interactive]')
173+
.option('--no-semantic-search', 'Disable semantic search for gateway target tool discovery [non-interactive]')
174+
.option(
175+
'--exception-level <level>',
176+
'Exception detail level in error responses: NONE, ALL [non-interactive]',
177+
'NONE'
178+
)
179+
.option('--policy-engine <name>', 'Policy engine name for Cedar-based authorization [non-interactive]')
180+
.option('--policy-engine-mode <mode>', 'Policy engine mode: LOG_ONLY or ENFORCE [non-interactive]')
181+
.option('--json', 'Output as JSON [non-interactive]')
178182
.action(async (rawOptions: Record<string, string | boolean | undefined>) => {
179183
const cliOptions = rawOptions as unknown as CLIAddGatewayOptions;
180184
try {
@@ -238,9 +242,9 @@ export class GatewayPrimitive extends BasePrimitive<AddGatewayOptions, Removable
238242
removeCmd
239243
.command('gateway')
240244
.description('Remove a gateway from the project')
241-
.option('--name <name>', 'Name of resource to remove')
242-
.option('--force', 'Skip confirmation prompt')
243-
.option('--json', 'Output as JSON')
245+
.option('--name <name>', 'Name of resource to remove [non-interactive]')
246+
.option('--force', 'Skip confirmation prompt [non-interactive]')
247+
.option('--json', 'Output as JSON [non-interactive]')
244248
.action(async (cliOptions: { name?: string; force?: boolean; json?: boolean }) => {
245249
try {
246250
if (!findConfigRoot()) {

src/cli/primitives/GatewayTargetPrimitive.ts

Lines changed: 41 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -245,35 +245,50 @@ export class GatewayTargetPrimitive extends BasePrimitive<AddGatewayTargetOption
245245
registerCommands(addCmd: Command, removeCmd: Command): void {
246246
addCmd
247247
.command('gateway-target')
248-
.description('Add a gateway target to the project')
249-
.option('--name <name>', 'Target name')
250-
.option('--description <desc>', 'Target description')
248+
.description('Add a target (API, MCP server, Lambda) to a gateway for tool routing')
249+
.option('--name <name>', 'Target name [non-interactive]')
250+
.option('--description <desc>', 'Target description [non-interactive]')
251+
.option('--gateway <name>', 'Gateway to attach this target to [non-interactive]')
251252
.option(
252253
'--type <type>',
253-
'Target type (required): mcp-server, api-gateway, open-api-schema, smithy-model, lambda-function-arn'
254+
'Target type (required): mcp-server, api-gateway, open-api-schema, smithy-model, lambda-function-arn [non-interactive]'
254255
)
255-
.option('--endpoint <url>', 'MCP server endpoint URL')
256-
.option('--language <lang>', 'Language: Python, TypeScript, Other')
257-
.option('--gateway <name>', 'Gateway name')
258-
.option('--host <host>', 'Compute host: Lambda or AgentCoreRuntime')
259-
.option('--outbound-auth <type>', 'Outbound auth type: oauth, api-key, or none')
260-
.option('--credential-name <name>', 'Existing credential name for outbound auth')
261-
.option('--oauth-client-id <id>', 'OAuth client ID (creates credential inline)')
262-
.option('--oauth-client-secret <secret>', 'OAuth client secret (creates credential inline)')
263-
.option('--oauth-discovery-url <url>', 'OAuth discovery URL (creates credential inline)')
264-
.option('--oauth-scopes <scopes>', 'OAuth scopes, comma-separated')
265-
.option('--rest-api-id <id>', 'API Gateway REST API ID (required for api-gateway type)')
266-
.option('--stage <stage>', 'API Gateway deployment stage (required for api-gateway type)')
267-
.option('--tool-filter-path <path>', 'Tool filter path pattern, e.g. /pets/*')
268-
.option('--tool-filter-methods <methods>', 'Comma-separated HTTP methods, e.g. GET,POST')
256+
.option('--endpoint <url>', 'Server endpoint URL (for mcp-server type) [non-interactive]')
257+
.option('--language <lang>', 'Language of target code: Python, TypeScript, Other [non-interactive]')
258+
.option('--host <host>', 'Where to run the target: Lambda or AgentCoreRuntime [non-interactive]')
259+
.option('--outbound-auth <type>', 'Outbound auth type: oauth, api-key, or none [non-interactive]')
260+
.option('--credential-name <name>', 'Existing credential name for outbound auth [non-interactive]')
261+
.option(
262+
'--oauth-client-id <id>',
263+
'OAuth client ID — creates credential inline (for oauth auth) [non-interactive]'
264+
)
265+
.option(
266+
'--oauth-client-secret <secret>',
267+
'OAuth client secret — creates credential inline (for oauth auth) [non-interactive]'
268+
)
269+
.option(
270+
'--oauth-discovery-url <url>',
271+
'OAuth discovery URL — creates credential inline (for oauth auth) [non-interactive]'
272+
)
273+
.option('--oauth-scopes <scopes>', 'OAuth scopes, comma-separated (for oauth auth) [non-interactive]')
274+
.option('--rest-api-id <id>', 'REST API ID (for api-gateway type) [non-interactive]')
275+
.option('--stage <stage>', 'Deployment stage (for api-gateway type) [non-interactive]')
276+
.option('--tool-filter-path <path>', 'Tool filter path pattern, e.g. /pets/* [non-interactive]')
277+
.option('--tool-filter-methods <methods>', 'Comma-separated HTTP methods, e.g. GET,POST [non-interactive]')
269278
.option(
270279
'--schema <path>',
271-
'Path to schema file (relative to project root) or S3 URI (for open-api-schema / smithy-model)'
280+
'Schema file path or S3 URI (for open-api-schema / smithy-model type) [non-interactive]'
281+
)
282+
.option(
283+
'--schema-s3-account <id>',
284+
'S3 bucket owner account ID for cross-account access (for schema on S3) [non-interactive]'
285+
)
286+
.option('--lambda-arn <arn>', 'Lambda function ARN (for lambda-function-arn type) [non-interactive]')
287+
.option(
288+
'--tool-schema-file <path>',
289+
'Tool schema JSON file path (for lambda-function-arn type) [non-interactive]'
272290
)
273-
.option('--schema-s3-account <id>', 'S3 bucket owner account ID (for cross-account access)')
274-
.option('--lambda-arn <arn>', 'Lambda function ARN (required for lambda-function-arn type)')
275-
.option('--tool-schema-file <path>', 'Path to tool schema JSON file (required for lambda-function-arn type)')
276-
.option('--json', 'Output as JSON')
291+
.option('--json', 'Output as JSON [non-interactive]')
277292
.action(async (rawOptions: Record<string, string | boolean | undefined>) => {
278293
// Commander camelCases --outbound-auth to outboundAuth, but our types use outboundAuthType
279294
if (rawOptions.outboundAuth && !rawOptions.outboundAuthType) {
@@ -464,9 +479,9 @@ export class GatewayTargetPrimitive extends BasePrimitive<AddGatewayTargetOption
464479
removeCmd
465480
.command('gateway-target')
466481
.description('Remove a gateway target from the project')
467-
.option('--name <name>', 'Name of resource to remove')
468-
.option('--force', 'Skip confirmation prompt')
469-
.option('--json', 'Output as JSON')
482+
.option('--name <name>', 'Name of resource to remove [non-interactive]')
483+
.option('--force', 'Skip confirmation prompt [non-interactive]')
484+
.option('--json', 'Output as JSON [non-interactive]')
470485
.action(async (cliOptions: { name?: string; force?: boolean; json?: boolean }) => {
471486
try {
472487
if (!findConfigRoot()) {

src/cli/primitives/PolicyEnginePrimitive.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,11 @@ export class PolicyEnginePrimitive extends BasePrimitive<AddPolicyEngineOptions,
205205
.option('--name <name>', 'Policy engine name [non-interactive]')
206206
.option('--description <desc>', 'Policy engine description [non-interactive]')
207207
.option('--encryption-key-arn <arn>', 'KMS encryption key ARN [non-interactive]')
208-
.option('--attach-to-gateways <gateways>', 'Comma-separated gateway names to attach this engine to')
209-
.option('--attach-mode <mode>', 'Enforcement mode for attached gateways: LOG_ONLY or ENFORCE')
208+
.option(
209+
'--attach-to-gateways <gateways>',
210+
'Comma-separated gateway names to attach this engine to [non-interactive]'
211+
)
212+
.option('--attach-mode <mode>', 'Enforcement mode for attached gateways: LOG_ONLY or ENFORCE [non-interactive]')
210213
.option('--json', 'Output as JSON [non-interactive]')
211214
.action(
212215
async (cliOptions: {

0 commit comments

Comments
 (0)