Skip to content

feat: compile-time feature flag for preview/GA consolidation#1341

Open
jesseturner21 wants to merge 18 commits into
mainfrom
feature/preview-feature-flag
Open

feat: compile-time feature flag for preview/GA consolidation#1341
jesseturner21 wants to merge 18 commits into
mainfrom
feature/preview-feature-flag

Conversation

@jesseturner21
Copy link
Copy Markdown
Contributor

@jesseturner21 jesseturner21 commented May 21, 2026

Summary

Consolidates the main and preview branches into a single branch using a compile-time feature flag. npm run bundle now produces two tarballs from the same source:

  • GA tarball — public customers, all harness features stripped via dead code elimination
  • Preview tarball — preview customers, full harness functionality enabled

This eliminates the merge-conflict-prone dual-branch workflow while ensuring GA customers never see unreleased features.

Also merges in main-branch work: datasets feature, feedback command, and version 0.15.0.

How it works

  1. src/cli/feature-flags.ts exports isPreviewEnabled() backed by a __PREVIEW__ constant
  2. esbuild's define block replaces __PREVIEW__ with true or false at bundle time
  3. When false, esbuild's minifier eliminates all dead code paths — GA bundles contain zero harness logic
  4. All harness command registrations, TUI screens, deploy paths, and invoke options are gated behind the flag

Changes

Feature flag infrastructure

  • src/cli/feature-flags.ts — wrapper function for compile-time constant
  • esbuild.config.mjsdefine: { __PREVIEW__: process.env.BUILD_PREVIEW === '1' ? 'true' : 'false' }
  • vitest.config.ts — matching define for test environments
  • scripts/bundle.mjs — produces dual tarballs (GA build, then BUILD_PREVIEW=1 rebuild)

Command gating

  • invoke/command.tsx — 13 harness options (--harness, --harness-arn, --model-id, etc.) conditionally registered
  • create/command.tsx — 8 harness options (--model-id, --api-key-arn, --truncation-strategy, etc.) conditionally registered
  • cli.tsadd tool / remove tool commands gated
  • primitives/registry.tsharnessPrimitive conditionally instantiated

TUI gating

  • useCreateFlow.ts — type selector (Harness/Agent/Skip) only shown in preview
  • useInvokeFlow.ts — harness targets only displayed in preview
  • dev/command.tsx — harness deploy + invoke flow gated

Imperative deployment (harnesses)

  • src/cli/operations/deploy/imperative/ — plugin-based deployment manager that runs deployers by phase, separate from CDK pipeline
  • harness-deployer.ts — creates/updates/deletes harness resources via API
  • harness-mapper.ts — maps local harness config to API request shape
  • change-detection.ts — hashes harness config to skip redundant deploys in dev mode

Structured deploy messages

  • handleDeploy now passes the full DeployMessage object (with code, level, timestamp) instead of plain strings
  • useDevDeploy hook receives structured messages directly — no more re-wrapping with hardcoded level: 'info'
  • Enables the TUI to render deploy output with proper severity coloring

Dev mode (harness support)

  • useDevDeploy hook auto-deploys harnesses before dev server start, with change-detection to skip redundant deploys
  • Browser UI /api/resources and /api/status endpoints include harness info
  • harness-invocation.ts routes dev-mode invocations to deployed harness endpoints

Invoke enhancements

  • resolve-agent-context.ts disambiguates between local agents, deployed agents, and harnesses
  • --harness / --harness-arn flags for direct harness invocation

Bug fixes (found during testing)

  • Orphaned memory on harness removalremove harness now also removes the associated <name>Memory entry
  • Deploy preflight rejected harness-only projects — added hasHarnesses to the resource check
  • TUI dev mode skipped deployment — auto-deploy before harness invoke
  • Deploy-to-harness transition didn't re-render — use queueMicrotask + setMode
  • Harness teardown on stack destroy — imperative deletion before CFN stack removal
  • Invoke hint renderingisHint check after isExec to preserve magenta exec styling
  • DeployMessage re-wrapping — removed unnecessary string→object→string round-trip in useDevDeploy

Tests

  • src/cli/__tests__/preview-flag.test.ts — verifies dead code elimination in both builds
  • integ-tests/add-remove-harness.test.ts — harness lifecycle + memory cleanup + re-add after removal
  • Unit tests for resolve-agent, change-detection, harness-mapper, harness invocation, status handlers
  • Harness integration/e2e tests properly skip in GA builds (BUILD_PREVIEW=1 guard)

Reviewer guidance

  1. Feature flag correctness — All harness code paths must be gated behind isPreviewEnabled(). The DCE test validates at the bundle level, but check no harness UI leaks through ungated paths.
  2. Imperative deploy manager — New deployment paradigm alongside CDK. Review the phase/plugin architecture for extensibility and error handling.
  3. Change detection — Dev mode skips deploy if config hash matches. Verify the hash covers all relevant inputs.
  4. Structured DeployMessage — Latest commit changes from string to DeployMessage flowing to the TUI. Check typing is consistent end-to-end.
  5. Schema additions — New harness schemas in src/schema/schemas/primitives/. Check alignment with agentcore.schema.v1.json.

Verification

Scenario Result
GA: invoke --help shows no harness options
GA: create --help shows no harness options
GA: add --help shows no harness/tool subcommands
GA: BUILD_PREVIEW=1 env var cannot bypass flag
GA: TUI create goes straight to project name (no type selector)
Preview: full harness TUI wizard
Preview: agentcore create project
Preview: agentcore dev starts server
Preview: agentcore dev -b TUI deploy + dev
Preview: agentcore deploy to AWS
Preview: agentcore invoke harness
Preview: agentcore status shows harness state
Preview: remove harness cleans up memory
Preview: re-add harness after removal
All unit tests pass
All harness integration tests pass (BUILD_PREVIEW=1)
CI: build, lint, format, typecheck, e2e, CodeQL all green

…lidation

Replace the dual-branch (main/preview) workflow with a single branch using
a compile-time __PREVIEW__ constant. esbuild's define block replaces the
constant at build time, enabling dead code elimination for GA builds while
keeping all harness/preview code in the same source tree.

Key changes:
- Add src/cli/feature-flags.ts with isPreviewEnabled() wrapper
- Configure esbuild define block and vitest define for __PREVIEW__
- Gate harness commands (add tool, remove tool/harness) behind isPreviewEnabled()
- Gate harness UI screens and create flow behind the flag
- Add globalThis shim in index.ts for tsx dev mode
- Update bundle.mjs to produce dual tarballs (GA + preview)
- Support ESBUILD_OUTFILE env var for isolated test builds
- Port all harness-related source files from preview branch
- Add preview-flag.test.ts verifying dead code elimination
@jesseturner21 jesseturner21 requested a review from a team May 21, 2026 13:24
@github-actions github-actions Bot added the size/xl PR size: XL label May 21, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
@github-actions github-actions Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label May 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Package Tarball

aws-agentcore-0.15.0.tgz

How to install

gh release download pr-1341-tarball --repo aws/agentcore-cli --pattern "*.tgz" --dir /tmp/pr-tarball
npm install -g /tmp/pr-tarball/aws-agentcore-0.15.0.tgz

@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: the review run failed before completing. See the run for details.

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
Prettier requires unquoted object keys when valid identifiers.
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels May 21, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
@github-actions github-actions Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 21, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: the review run failed before completing. See the run for details.

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 21, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 43.2% 10418 / 24111
🔵 Statements 42.45% 11076 / 26087
🔵 Functions 40.29% 1796 / 4457
🔵 Branches 39.54% 6685 / 16904
Generated in workflow #3276 for commit d04a2d6 by the Vitest Coverage Report Action

Harness features are gated behind BUILD_PREVIEW=1 and eliminated from
GA bundles. Integration and e2e tests that exercise harness commands
must skip when running against the default (GA) build.
@github-actions github-actions Bot removed the size/xl PR size: XL label May 21, 2026
@github-actions github-actions Bot added the size/xl PR size: XL label May 21, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: the review run failed before completing. See the run for details.

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
…mory cleanup

- Wrap harness-related CLI options in invoke command behind isPreviewEnabled()
  so they don't leak into GA build's --help output
- Wrap harness-related CLI options in create command behind isPreviewEnabled()
- Fix remove harness leaving orphaned memory entries in agentcore.json
- Fix deploy preflight rejecting harness-only projects
- Add integration test for harness re-add after removal
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels May 21, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 21, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 22, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 22, 2026
The frontend Agent Inspector crashes with "Cannot read properties of
undefined (reading 'find')" when switching to a harness because the
/api/resources endpoint was missing the harnesses array entirely.

Constraint: Frontend expects harnesses array with deploymentStatus and deployed fields
Confidence: high
Scope-risk: narrow
@github-actions github-actions Bot removed the size/xl PR size: XL label May 22, 2026
@github-actions github-actions Bot added the size/xl PR size: XL label May 22, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 22, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 22, 2026
Covers validation, routing, SSE streaming, error handling, and
the harness fields added to /api/status response.

Confidence: high
Scope-risk: narrow
@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels May 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 25, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 25, 2026
…-mapper

Cover the untested middle-layer logic that routes invocations, decides
whether deploys can be skipped, and maps harness specs to API payloads.

Confidence: high
Scope-risk: narrow
@github-actions github-actions Bot removed the size/xl PR size: XL label May 25, 2026
@github-actions github-actions Bot added the size/xl PR size: XL label May 25, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

Integrates dataset feature, feedback command, SDK bump, and CI changes
from main alongside the harness/preview feature flag work.

Confidence: high
Scope-risk: moderate
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

The keepNames:true esbuild option (added for better error stacks)
preserves class/function name strings even in dead code paths.
Adjust assertions to check for harness-only module markers that
are fully tree-shaken, rather than name strings that survive.

Confidence: high
Scope-risk: narrow
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

…rings

The dev deploy hook was re-wrapping string messages into DeployMessage
objects with hardcoded values. Now the real message (with actual level,
code, timestamp) flows through directly from CDK.
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

Includes EPISODIC reflectionNamespaces in the retrieval config so the
harness runtime searches all relevant memory namespaces at inference time.
Also incorporates memorySpec into the deploy hash so namespace changes
trigger a harness update.

Cherry-picked from #1374.
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/xl PR size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant