diff --git a/src/cli/commands/add/__tests__/validate.test.ts b/src/cli/commands/add/__tests__/validate.test.ts index f28997edc..a42182e87 100644 --- a/src/cli/commands/add/__tests__/validate.test.ts +++ b/src/cli/commands/add/__tests__/validate.test.ts @@ -469,8 +469,7 @@ describe('validate', () => { expect(result.valid).toBe(true); }); - // Passthrough is gated behind ENABLE_GATED_FEATURES - describe('passthrough feature flag', () => { + describe('passthrough target type', () => { const passthroughOpts: AddGatewayTargetOptions = { name: 'pt-target', type: 'passthrough', @@ -478,31 +477,18 @@ describe('validate', () => { passthroughEndpoint: 'https://api.example.com', } as AddGatewayTargetOptions; - afterEach(() => { - delete process.env.ENABLE_GATED_FEATURES; - }); - - it('rejects passthrough when the flag is off', async () => { - delete process.env.ENABLE_GATED_FEATURES; + it('accepts a valid passthrough target', async () => { const result = await validateAddGatewayTargetOptions({ ...passthroughOpts }); - expect(result.valid).toBe(false); - expect(result.error).toBe('Passthrough targets are not yet available.'); + expect(result.valid).toBe(true); }); - it('omits passthrough from the invalid-type error when the flag is off', async () => { - delete process.env.ENABLE_GATED_FEATURES; + it('lists passthrough in the invalid-type error', async () => { const result = await validateAddGatewayTargetOptions({ ...validGatewayTargetOptions, type: 'bogus-type', } as AddGatewayTargetOptions); expect(result.valid).toBe(false); - expect(result.error).not.toContain('passthrough'); - }); - - it('allows passthrough when the flag is on', async () => { - process.env.ENABLE_GATED_FEATURES = '1'; - const result = await validateAddGatewayTargetOptions({ ...passthroughOpts }); - expect(result.valid).toBe(true); + expect(result.error).toContain('passthrough'); }); }); // AC20: type validation diff --git a/src/cli/commands/add/validate.ts b/src/cli/commands/add/validate.ts index 59c0d324b..9c8c5d38c 100644 --- a/src/cli/commands/add/validate.ts +++ b/src/cli/commands/add/validate.ts @@ -399,7 +399,6 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO return { valid: false, error: '--name is required' }; } - // passthrough is gated; omit it from advertised type lists when the flag is off. const validTypeList = [ 'mcp-server', 'api-gateway', @@ -408,7 +407,7 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO 'lambda-function-arn', 'http-runtime', 'connector', - ...(isGatedFeaturesEnabled() ? ['passthrough'] : []), + 'passthrough', 'web-search', ].join(', '); @@ -727,9 +726,6 @@ export async function validateAddGatewayTargetOptions(options: AddGatewayTargetO // Passthrough targets: validate early and return if (mappedType === 'passthrough') { - if (!isGatedFeaturesEnabled()) { - return { valid: false, error: 'Passthrough targets are not yet available.' }; - } const passthroughEndpoint = (options as Record).passthroughEndpoint; if (!passthroughEndpoint) { return { valid: false, error: '--passthrough-endpoint is required for passthrough type' }; diff --git a/src/cli/primitives/GatewayTargetPrimitive.ts b/src/cli/primitives/GatewayTargetPrimitive.ts index f96d5d0f4..71313ea62 100644 --- a/src/cli/primitives/GatewayTargetPrimitive.ts +++ b/src/cli/primitives/GatewayTargetPrimitive.ts @@ -29,7 +29,6 @@ import { import type { AddGatewayTargetOptions as CLIAddGatewayTargetOptions } from '../commands/add/types'; import { validateAddGatewayTargetOptions } from '../commands/add/validate'; import { getErrorMessage } from '../errors'; -import { isGatedFeaturesEnabled } from '../feature-flags'; import { upsertAgenticRetrieveTarget } from '../operations/knowledge-base/agentic-retrieve-upsert'; import type { RemovableGatewayTarget } from '../operations/remove/remove-gateway-target'; import type { RemovalPreview, SchemaChange } from '../operations/remove/types'; @@ -63,14 +62,6 @@ import { dirname, join } from 'path'; const MCP_DEFS_FILE = 'mcp-defs.json'; -/** - * Hide a passthrough-only CLI option from --help unless gated features are enabled. - * The option is still parsed if passed; the runtime guard in validate.ts rejects it. - */ -function gatePassthroughOption(option: Option): Option { - return isGatedFeaturesEnabled() ? option : option.hideHelp(); -} - /** * Options for adding a gateway target (CLI-level). */ @@ -283,9 +274,8 @@ export class GatewayTargetPrimitive extends BasePrimitive', 'Runtime from your project (for http-runtime type) [non-interactive]') .option('--runtime-endpoint ', 'Runtime endpoint / version alias (for http-runtime type) [non-interactive]') - // Passthrough-only flags are gated behind ENABLE_GATED_FEATURES — hidden from help when off. + // Passthrough-only flags. .addOption( - gatePassthroughOption( - new Option('--passthrough-endpoint ', 'HTTPS endpoint URL for passthrough targets [non-interactive]') - ) + new Option('--passthrough-endpoint ', 'HTTPS endpoint URL for passthrough targets [non-interactive]') ) .addOption( - gatePassthroughOption( - new Option( - '--passthrough-protocol ', - 'Passthrough protocol: MCP | A2A | INFERENCE | CUSTOM (default: CUSTOM) [non-interactive]' - ) + new Option( + '--passthrough-protocol ', + 'Passthrough protocol: MCP | A2A | INFERENCE | CUSTOM (default: CUSTOM) [non-interactive]' ) ) .addOption( - gatePassthroughOption( - new Option( - '--stickiness-identifier ', - 'Session routing expression for passthrough targets [non-interactive]' - ) + new Option( + '--stickiness-identifier ', + 'Session routing expression for passthrough targets [non-interactive]' ) ) .addOption( - gatePassthroughOption( - new Option('--stickiness-timeout ', 'Sticky session timeout in seconds (1-86400) [non-interactive]') - ) + new Option('--stickiness-timeout ', 'Sticky session timeout in seconds (1-86400) [non-interactive]') ) .addOption( - gatePassthroughOption( - new Option( - '--signing-service ', - 'SigV4 signing service name for passthrough GATEWAY_IAM_ROLE auth [non-interactive]' - ) + new Option( + '--signing-service ', + 'SigV4 signing service name for passthrough GATEWAY_IAM_ROLE auth [non-interactive]' ) ) .addOption( - gatePassthroughOption( - new Option( - '--signing-region ', - 'SigV4 signing region for passthrough (defaults to project region) [non-interactive]' - ) + new Option( + '--signing-region ', + 'SigV4 signing region for passthrough (defaults to project region) [non-interactive]' ) ) .option('--json', 'Output as JSON [non-interactive]') @@ -430,17 +408,13 @@ Target types and their options: connector — Wire a managed AWS connector (Bedrock KB, agentic-retrieve) --connector bedrock-knowledge-bases or bedrock-agentic-retrieve --knowledge-base-id Project KB name or 10-char external KB id (repeatable for agentic-retrieve) -${ - isGatedFeaturesEnabled() - ? ` + passthrough — Route to an external HTTPS endpoint --passthrough-endpoint HTTPS endpoint URL --stickiness-identifier Session routing expression (optional) --stickiness-timeout Sticky session timeout in seconds (optional) -` - : '' -} - Auth (mcp-server, open-api-schema, smithy-model, lambda-function-arn${isGatedFeaturesEnabled() ? ', passthrough' : ''}): + + Auth (mcp-server, open-api-schema, smithy-model, lambda-function-arn, passthrough): --outbound-auth oauth, api-key, or none --credential-name Existing credential name ` diff --git a/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx b/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx index b3e2aa835..62ae71dfe 100644 --- a/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx +++ b/src/cli/tui/screens/mcp/AddGatewayTargetScreen.tsx @@ -1,6 +1,5 @@ import type { ApiGatewayHttpMethod, GatewayTargetType, PassthroughProtocolType } from '../../../../schema'; import { REAL_KB_ID_PATTERN, ToolNameSchema } from '../../../../schema'; -import { isGatedFeaturesEnabled } from '../../../feature-flags'; import { ConfirmReview, Panel, Screen, StepIndicator, TextInput, WizardSelect } from '../../components'; import type { SelectableItem } from '../../components'; import { HELP_TEXT } from '../../constants'; @@ -154,15 +153,11 @@ export function AddGatewayTargetScreen({ ); const targetTypeItems: SelectableItem[] = useMemo( () => - TARGET_TYPE_OPTIONS.map(o => { - const gated = o.id === 'passthrough' && !isGatedFeaturesEnabled(); - return { - id: o.id, - title: o.title, - description: gated ? 'Coming soon' : o.description, - disabled: gated, - }; - }), + TARGET_TYPE_OPTIONS.map(o => ({ + id: o.id, + title: o.title, + description: o.description, + })), [] ); const outboundAuthItems: SelectableItem[] = useMemo(