From b731986a3b661ebdae0984c10a5d6cb68c13adf9 Mon Sep 17 00:00:00 2001 From: jariy17 Date: Tue, 23 Jun 2026 16:56:54 +0000 Subject: [PATCH 1/3] Ungate passthrough gateway targets Make passthrough gateway targets generally available by removing the isGatedFeaturesEnabled() checks that previously hid them behind ENABLE_GATED_FEATURES. - add/validate.ts: always include `passthrough` in the valid target-type list; drop the "not yet available" early return. - GatewayTargetPrimitive.ts: always advertise passthrough options in --help and the type description; gatePassthroughOption() is now a pass-through so the six call sites stay consistent. - TUI AddGatewayTargetScreen: passthrough is always selectable (no more "Coming soon"). - Update unit tests to assert passthrough is accepted without the flag. Other gated features (knowledge-base, managed memory, aws-skills, previews) are untouched. --- .../commands/add/__tests__/validate.test.ts | 23 +++++-------------- src/cli/commands/add/validate.ts | 6 +---- src/cli/primitives/GatewayTargetPrimitive.ts | 22 +++++++----------- .../screens/mcp/AddGatewayTargetScreen.tsx | 15 ++++-------- 4 files changed, 20 insertions(+), 46 deletions(-) diff --git a/src/cli/commands/add/__tests__/validate.test.ts b/src/cli/commands/add/__tests__/validate.test.ts index f28997edc..263850c50 100644 --- a/src/cli/commands/add/__tests__/validate.test.ts +++ b/src/cli/commands/add/__tests__/validate.test.ts @@ -469,8 +469,8 @@ describe('validate', () => { expect(result.valid).toBe(true); }); - // Passthrough is gated behind ENABLE_GATED_FEATURES - describe('passthrough feature flag', () => { + // Passthrough is generally available (no longer gated) + describe('passthrough target type', () => { const passthroughOpts: AddGatewayTargetOptions = { name: 'pt-target', type: 'passthrough', @@ -478,31 +478,20 @@ 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 () => { + it('allows passthrough without any feature flag', async () => { delete process.env.ENABLE_GATED_FEATURES; 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 () => { + it('lists passthrough in the invalid-type error', async () => { delete process.env.ENABLE_GATED_FEATURES; 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..48ea6f234 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'; @@ -64,11 +63,11 @@ 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. + * Passthrough-only CLI option. Kept as a pass-through wrapper so the six call sites + * read consistently; passthrough targets are no longer gated. */ function gatePassthroughOption(option: Option): Option { - return isGatedFeaturesEnabled() ? option : option.hideHelp(); + return option; } /** @@ -283,9 +282,8 @@ export class GatewayTargetPrimitive extends BasePrimitive 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( From 8e3c6bf7aed2565f9750698641a51678531b3550 Mon Sep 17 00:00:00 2001 From: jariy17 Date: Tue, 23 Jun 2026 17:26:52 +0000 Subject: [PATCH 2/3] Remove no-op gatePassthroughOption wrapper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Inline the six call sites and delete the function — it returned its argument unchanged after ungating, so it was pure indirection. --- src/cli/primitives/GatewayTargetPrimitive.ts | 50 ++++++-------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/src/cli/primitives/GatewayTargetPrimitive.ts b/src/cli/primitives/GatewayTargetPrimitive.ts index 48ea6f234..71313ea62 100644 --- a/src/cli/primitives/GatewayTargetPrimitive.ts +++ b/src/cli/primitives/GatewayTargetPrimitive.ts @@ -62,14 +62,6 @@ import { dirname, join } from 'path'; const MCP_DEFS_FILE = 'mcp-defs.json'; -/** - * Passthrough-only CLI option. Kept as a pass-through wrapper so the six call sites - * read consistently; passthrough targets are no longer gated. - */ -function gatePassthroughOption(option: Option): Option { - return option; -} - /** * Options for adding a gateway target (CLI-level). */ @@ -355,47 +347,35 @@ 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]') From f935cbd6de938ac1c9f5b8ea9d2ce65894237aef Mon Sep 17 00:00:00 2001 From: jariy17 Date: Tue, 23 Jun 2026 18:39:44 +0000 Subject: [PATCH 3/3] Address review: drop gating-specific bits from passthrough tests Remove the ungate-specific comment and the now-irrelevant delete process.env.ENABLE_GATED_FEATURES lines; passthrough is a normal target type, so the tests read like any other type's. --- src/cli/commands/add/__tests__/validate.test.ts | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/cli/commands/add/__tests__/validate.test.ts b/src/cli/commands/add/__tests__/validate.test.ts index 263850c50..a42182e87 100644 --- a/src/cli/commands/add/__tests__/validate.test.ts +++ b/src/cli/commands/add/__tests__/validate.test.ts @@ -469,7 +469,6 @@ describe('validate', () => { expect(result.valid).toBe(true); }); - // Passthrough is generally available (no longer gated) describe('passthrough target type', () => { const passthroughOpts: AddGatewayTargetOptions = { name: 'pt-target', @@ -478,14 +477,12 @@ describe('validate', () => { passthroughEndpoint: 'https://api.example.com', } as AddGatewayTargetOptions; - it('allows passthrough without any feature flag', async () => { - delete process.env.ENABLE_GATED_FEATURES; + it('accepts a valid passthrough target', async () => { const result = await validateAddGatewayTargetOptions({ ...passthroughOpts }); expect(result.valid).toBe(true); }); it('lists passthrough in the invalid-type error', async () => { - delete process.env.ENABLE_GATED_FEATURES; const result = await validateAddGatewayTargetOptions({ ...validGatewayTargetOptions, type: 'bogus-type',