feat: compile-time feature flag for preview/GA consolidation#1341
Conversation
…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
Package TarballHow to installgh 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 |
|
Claude Security Review: the review run failed before completing. See the run for details. |
Prettier requires unquoted object keys when valid identifiers.
|
Claude Security Review: the review run failed before completing. See the run for details. |
Coverage Report
|
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.
|
Claude Security Review: the review run failed before completing. See the run for details. |
…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
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
|
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.
|
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.
|
Claude Security Review: no high-confidence findings. (run) |
|
Claude Security Review: no high-confidence findings. (run) |
…actor The merge conflict resolution left duplicated code blocks and mismatched braces. Rebuilt from main's withCommandRunTelemetry+recorder pattern and re-applied preview feature flag gates (harness support, skip-deploy, TUI picker).
|
Claude Security Review: no high-confidence findings. (run) |
jariy17
left a comment
There was a problem hiding this comment.
Looks good overall. only blocker is workflow bugs.
- Remove unnecessary `as unknown as` cast in agentcore-control.ts (SDK already has IndexedKey type) - Optimize preview build to only re-run esbuild (not full tsc + assets) - Delete dead code: poll.ts and its test (nothing imports it) - Error when harness enters FAILED state after create/update instead of silently returning success - Add unit tests for harness-deployer (create, update, skip, teardown, FAILED status, role resolution, retry, polling)
|
Claude Security Review: no high-confidence findings. (run) |
- release.yml: set BUILD_PREVIEW=1 for preview builds - release-main-and-preview.yml: rewrite as single-PR flow using preview-version.json for the preview version track (no separate preview branch needed) - Remove sync-preview.yml (no preview branch to sync) - Update preview-version.json to match current npm state (1.0.0-preview.9) Constraint: preview and GA are both built from main, differentiated by BUILD_PREVIEW env var at esbuild time Confidence: high Scope-risk: narrow
|
Claude Security Review: no high-confidence findings. (run) |
Allows running the release workflow for just main-only, preview-only, or both together. Jobs are conditionally skipped based on the selection. Confidence: high Scope-risk: narrow
|
Claude Security Review: no high-confidence findings. (run) |
Allows triggering the release workflow from any branch via the GitHub UI branch selector, instead of hardcoding main. Confidence: high Scope-risk: narrow
|
Claude Security Review: no high-confidence findings. (run) |
Preview releases are handled by release-main-and-preview.yml. Confidence: high Scope-risk: narrow
|
Claude Security Review: no high-confidence findings. (run) |
Summary
Consolidates the main and preview branches into a single branch using a compile-time feature flag.
npm run bundlenow produces two tarballs from the same source: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
src/cli/feature-flags.tsexportsisPreviewEnabled()backed by a__PREVIEW__constantdefineblock replaces__PREVIEW__withtrueorfalseat bundle timefalse, esbuild's minifier eliminates all dead code paths — GA bundles contain zero harness logicChanges
Feature flag infrastructure
src/cli/feature-flags.ts— wrapper function for compile-time constantesbuild.config.mjs—define: { __PREVIEW__: process.env.BUILD_PREVIEW === '1' ? 'true' : 'false' }vitest.config.ts— matching define for test environmentsscripts/bundle.mjs— produces dual tarballs (GA build, thenBUILD_PREVIEW=1rebuild)Command gating
invoke/command.tsx— 13 harness options (--harness,--harness-arn,--model-id, etc.) conditionally registeredcreate/command.tsx— 8 harness options (--model-id,--api-key-arn,--truncation-strategy, etc.) conditionally registeredcli.ts—add tool/remove toolcommands gatedprimitives/registry.ts—harnessPrimitiveconditionally instantiatedTUI gating
useCreateFlow.ts— type selector (Harness/Agent/Skip) only shown in previewuseInvokeFlow.ts— harness targets only displayed in previewdev/command.tsx— harness deploy + invoke flow gatedImperative deployment (harnesses)
src/cli/operations/deploy/imperative/— plugin-based deployment manager that runs deployers by phase, separate from CDK pipelineharness-deployer.ts— creates/updates/deletes harness resources via APIharness-mapper.ts— maps local harness config to API request shapechange-detection.ts— hashes harness config to skip redundant deploys in dev modeStructured deploy messages
handleDeploynow passes the fullDeployMessageobject (with code, level, timestamp) instead of plain stringsuseDevDeployhook receives structured messages directly — no more re-wrapping with hardcodedlevel: 'info'Dev mode (harness support)
useDevDeployhook auto-deploys harnesses before dev server start, with change-detection to skip redundant deploys/api/resourcesand/api/statusendpoints include harness infoharness-invocation.tsroutes dev-mode invocations to deployed harness endpointsInvoke enhancements
resolve-agent-context.tsdisambiguates between local agents, deployed agents, and harnesses--harness/--harness-arnflags for direct harness invocationBug fixes (found during testing)
remove harnessnow also removes the associated<name>MemoryentryhasHarnessesto the resource checkqueueMicrotask+setModeisHintcheck afterisExecto preserve magenta exec stylingTests
src/cli/__tests__/preview-flag.test.ts— verifies dead code elimination in both buildsinteg-tests/add-remove-harness.test.ts— harness lifecycle + memory cleanup + re-add after removalBUILD_PREVIEW=1guard)Reviewer guidance
isPreviewEnabled(). The DCE test validates at the bundle level, but check no harness UI leaks through ungated paths.stringtoDeployMessageflowing to the TUI. Check typing is consistent end-to-end.src/schema/schemas/primitives/. Check alignment withagentcore.schema.v1.json.Verification
invoke --helpshows no harness optionscreate --helpshows no harness optionsadd --helpshows no harness/tool subcommandsBUILD_PREVIEW=1env var cannot bypass flagagentcore createprojectagentcore devstarts serveragentcore dev -bTUI deploy + devagentcore deployto AWSagentcore invokeharnessagentcore statusshows harness state