feat(project): vend a thin CDK app built on transformAgentCoreJson - #2249
feat(project): vend a thin CDK app built on transformAgentCoreJson#2249AlexanderRichey wants to merge 2 commits into
Conversation
The CDK app `project create` writes into agentcore/cdk/ shrinks to two files. bin/cdk.ts calls readAgentCoreProject, resolveTargetStacks and transformAgentCoreJson from @aws/agentcore-cdk and instantiates one AgentCoreStack per target; lib/cdk-stack.ts instantiates one AgentCoreApplication (construct id 'Application' unchanged) and is the file a customer edits to add resources and grant runtimes or harnesses access to them. Everything the old 181-line bin/cdk.ts did — reading the spec, every harness.json and system-prompt.md, connector files and deployed-state.json, stack naming and tagging — now lives in the library, so it changes with the library version rather than on customers' disks. No `as any`: the types come from the pinned library. The unused StackNameOutput output is dropped. test/cdk.test.ts, jest.config.js, .prettierrc and npmignore.template are removed, and jest, ts-jest, @types/jest and prettier leave the vended package.json with the test and format scripts: the library's vitest suite and this repository's tests cover synthesis, and a customer who wants tests in their CDK app adds them. The pin moves to 0.1.0-alpha.53, the first library release carrying transformAgentCoreJson; dependencies["@aws/agentcore-cdk"] stays a plain exact version string for scripts/sync-vended-cdk.ts. The manager snapshot drops the four removed files. The observability and CDK-backend comments that cited src/assets/cdk now point at the library helper and construct that own the rule. pathLimit: a fresh install puts its deepest file 155 characters below the project root (aws-cdk-lib's shipped fixtures, not jest), so the Windows limit is derived from that measurement (104-character project root) instead of the old "about 100" guess. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KEWrUu52DmcWE3sx4VEhKL
The project create entry in the command tree says what agentcore/cdk contains now, a new "Extending the CDK app" subsection walks through lib/cdk-stack.ts, the accessors, grants, environment variables and redeploying (noting that project status reports only the resources agentcore.json declares), and the Windows path note carries the measured depth. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KEWrUu52DmcWE3sx4VEhKL
|
Claude Security Review: no high-confidence findings. (run) |
There was a problem hiding this comment.
AgentCore Harness Review
Verdict: Looks good
Nice cleanup — the vended bin/cdk.ts collapsing to three library calls (readAgentCoreProject / resolveTargetStacks / transformAgentCoreJson) removes a lot of type-loosened field reading from the user-editable app, and moving HarnessConfig resolution and the AgentCore-<project>-<target> naming rule into @aws/agentcore-cdk is the right direction. The pathLimit rationale is now grounded in an actual measurement (aws-cdk-lib's own shipped fixtures), and the arithmetic in the new 104/105 test checks out with path.join on both separators.
A couple of things worth confirming before merge (not blockers, since I can't verify them against alpha.53 locally — agentcore-l3-cdk-constructs in this workspace is still at alpha.22):
- The old
bin/cdk.tsexplicitly treatedtargets.length === 0as "synthesize one environment-agnostic stack soproject buildcan typecheck before targets exist." That branch is gone; confirmresolveTargetStacksin alpha.53 does the same thing (returns a single env-agnostic entry), otherwiseagentcore project buildon a freshly created project — which runs unconditionally viaprojectManager.buildinhandlers/project/build/index.ts— will start failing. targetStackNameinsrc/core/observability.tsstill duplicates theAgentCore-<project>-<target>+_→-rule. The updated comment acknowledges the source of truth now lives in the library; consider exporting a helper from@aws/agentcore-cdkin a follow-up so the two can't drift.
Nothing that requires changes in this PR.
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## refactor #2249 +/- ##
=========================================
Coverage 97.04% 97.04%
=========================================
Files 566 566
Lines 39409 39410 +1
=========================================
+ Hits 38244 38245 +1
Misses 1165 1165 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
The CDK app
agentcore project createvends intoagentcore/cdk/shrinks from a 181-linebin/cdk.tsplus alib/cdk-stack.tsthat cast the spec toanyto two short files built on three library calls —readAgentCoreProject,resolveTargetStacksandtransformAgentCoreJson— so howagentcore.jsonis interpreted ships as@aws/agentcore-cdkversions instead of as code on customers' machines, andlib/cdk-stack.tsbecomes the place a customer adds their own resources and grants runtimes or harnesses access to them through the application's accessors.Blocked on
aws/agentcore-l3-cdk-constructs, branchfeat/application-transform-and-extension).@aws/agentcore-cdk@0.1.0-alpha.53: the vendedpackage.jsonpins that exact version, which does not exist on npm yet, soproject createwithout--skip-installfails until it is published.scripts/sync-vended-cdk.tsre-pinsdependencies["@aws/agentcore-cdk"]to thelatestdist-tag at release-prepare time; the key path is unchanged.Do not merge before both.
What changed
Vended tree, before → after
bin/cdk.tsreads the project once, makes oneAgentCoreStackper target with the env/tags/description the library returns, and passestransformAgentCoreJson(project.agentCoreJson, { projectRoot, credentials })as the stack'sapplicationprop. Failure stays one stderr line,AgentCore CDK synthesis failed: <message>, exit 1, so the CLI's progress tail stays readable.lib/cdk-stack.tsinstantiates oneAgentCoreApplication(construct id'Application'kept) with a commented DynamoDB example. Noas any, noSpecWithLatestFields; the unusedStackNameOutputis dropped (the observability test that uses that key as fixture data is untouched).test/cdk.test.ts,jest.config.js,.prettierrc,npmignore.template;jest,ts-jest,@types/jest,prettierand thetest/format*scripts). The library's vitest suite covers synthesis of everything the app can produce and this repository's tests cover the command lines; a customer who wants tests in their CDK app adds them. Fewer files to install on a customer's disk, and one fewer toolchain to keep current.src/core/project/__snapshots__/manager.test.ts.snap: regenerated; the diff removes exactly the four files above from each of the five manifests.src/core/observability.tsandsrc/core/project/backends/cdk.ts: the comments that citedsrc/assets/cdk/...now point atresolveTargetStacksandAgentCorePayments, which own those rules.src/handlers/project/create/pathLimit.ts: a freshnpm installputs its deepest file 155 characters below the project root (agentcore/cdk/node_modules/aws-cdk-lib/product-stack-snapshots/nested/...template.json, i.e. aws-cdk-lib's own shipped fixtures, not the removed jest), so the old "about 100" comment was an under-estimate. The Windows limit is now derived from the measurement: project root ≤ 260 − 1 − 155 = 104 characters (was a flat 150, which would have let a 306-character deepest path through). Reviewers may want to weigh this; the constant's derivation and the measurement are in the file and the README's Windows note.README.md: theproject createentry says whatagentcore/cdkcontains; a new Extending the CDK app subsection; the Windows path note carries the measurement.scripts/sync-vended-cdk.ts,scripts/build.ts, or the backend command lines (npm run cdk -- synth --quiet --output <cdk.out>withcwd = agentcore/cdkis asserted unchanged by the existing backend tests). No dependency changes;bun install --frozen-lockfilesucceeds.Verification
Static (this branch):
bun install --frozen-lockfile,bun run lint:check,bun run format:check,bun run typecheck,bun run secrets:checkall pass;bun test --coverage— 3179 pass, 0 fail across 224 files, 95.54% lines overall;bun run build,bun pm pack --ignore-scripts,bun run compile:linux-x64and./dist/bin/agentcore-linux-x64 --helppass, and the compiled binary embeds exactly the seven vended files (stringson the binary listsagentcore-assets/src/assets/cdk/{README.md,bin/cdk.ts,cdk.json,gitignore.template,lib/cdk-stack.ts,package.json,tsconfig.json}).Live (account 501930284170, us-east-1,
AGENTCORE_TELEMETRY_DISABLED=1, CLI run from this branch's source withbun run src/index.ts). Because0.1.0-alpha.53is unpublished, each scaffolded project was created with--skip-install --skip-gitand thennpm install <path>/aws-agentcore-cdk-0.1.0-alpha.53.tgzwas run inagentcore/cdk, which installs the library PR's tarball in place of the pin plus the rest ofpackage.json(node_modules/@aws/agentcore-cdk/package.jsonreports0.1.0-alpha.53anddist/index.jsexportstransformAgentCoreJson).Setup once:
cd agentcore-l3-cdk-constructs && npm run build && npm packwithpackage.jsontemporarily at0.1.0-alpha.53(reverted, not committed) →aws-agentcore-cdk-0.1.0-alpha.53.tgz(479 files).CLI=bun run <agentcore-cli>/src/index.ts.5.1 Harness project
L3E2Eknq5(defaultproject create)$CLI project create --name L3E2Eknq5 --skip-install --skip-git.gitignore,agentcore/{.env.local,agentcore.json,aws-targets.json},agentcore/cdk/{.gitignore,README.md,bin/cdk.ts,cdk.json,lib/cdk-stack.ts,package.json,tsconfig.json},app/L3E2Eknq5/{harness.json,system-prompt.md}— exactly the 3.1 tree.agentcore.json(withabTests: []),harness.json,system-prompt.mdand the post-deployaws-targets.json/.cli/deployed-state.jsonshapes are checked in undertest/fixtures/harness-project/(account id replaced by123456789012).cd L3E2Eknq5/agentcore/cdk && npm install <path>/aws-agentcore-cdk-0.1.0-alpha.53.tgznode_modules/@aws/agentcore-cdk/package.json→"version": "0.1.0-alpha.53";dist/index.jsexportstransformAgentCoreJson. Deepest installed path: 141 chars underagentcore/cdk(node_modules/aws-cdk-lib/product-stack-snapshots/nested/…v1.product.template.json).$CLI project buildBuilt project 'L3E2Eknq5'in 8.9 s.cdk.outholds one stackAgentCore-L3E2Eknq5, tags{agentcore:project-name: L3E2Eknq5}only, descriptionAgentCore stack for L3E2Eknq5 (no deployment target configured); resources:AWS::IAM::Role,AWS::IAM::Policy,AWS::BedrockAgentCore::Harness,AWS::CDK::Metadata; six outputs exported asAgentCore-L3E2Eknq5-Harness-L3E2Eknq5-{Id,Arn,Status,Version,AgentRuntimeArn,RoleArn}.$CLI project deploy --yesCreated default deployment target: account 501930284170, region us-east-1→Deployed project 'L3E2Eknq5' to target 'default'.aws cloudformation describe-stacks:CREATE_COMPLETE, descriptionAgentCore stack for L3E2Eknq5 deployed to default (us-east-1), tagsagentcore:project-name=L3E2Eknq5,agentcore:target-name=default, the sixAgentCore-L3E2Eknq5-default-Harness-L3E2Eknq5-*exports.aws bedrock-agentcore-control get-harness --harness-id L3E2Eknq5_L3E2Eknq5-DQNg7Re28f→status: READY,environmentVariables: null.$CLI project status --jsonresources: [{ resourceType: harness, name: L3E2Eknq5, deploymentState: deployed, id: arn:aws:bedrock-agentcore:us-east-1:…:harness/L3E2Eknq5_L3E2Eknq5-DQNg7Re28f }]— resolved through the export-name contract.$CLI project invoke harness --prompt "Reply with the single word: pong" --jsonstopReason: end_turn, transcript textpong, 898 ms.lib/cdk-stack.ts:new dynamodb.Table(this, 'Orders', { partitionKey: {pk, STRING}, removalPolicy: DESTROY });const h = this.application.harness('L3E2Eknq5'); h.grantReadWrite(orders); h.addEnvironmentVariable('ORDERS_TABLE', orders.tableName);$CLI project deploy --yesDeployed project 'L3E2Eknq5' to target 'default'.describe-stack-resources:OrdersA9B65338(AWS::DynamoDB::Table,CREATE_COMPLETE) in the same stack; harnessUPDATE_COMPLETE(in place, not replaced);…DefaultPolicy…UPDATE_COMPLETE.aws bedrock-agentcore-control get-harness --harness-id L3E2Eknq5_L3E2Eknq5-DQNg7Re28f --query harness.environmentVariables{ ORDERS_TABLE: AgentCore-L3E2Eknq5-default-OrdersA9B65338-1QN3PFN2CVU3U }, statusREADY.$CLI harness exec --id L3E2Eknq5_L3E2Eknq5-DQNg7Re28f --command 'echo $ORDERS_TABLE' --jsonexitCode: 0,output: "AgentCore-L3E2Eknq5-default-OrdersA9B65338-1QN3PFN2CVU3U\n"— the variable reached the runtime.aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::…:role/L3E2Eknq5_L3E2Eknq5 --action-names dynamodb:PutItem dynamodb:GetItem --resource-arns <table arn>dynamodb:PutItem allowed,dynamodb:GetItem allowed.$CLI project deploy --yeswith no changesDeployed project …; stackLastUpdatedTimeidentical before and after (2026-09-09T01:25:45.259Z), no new stack events — nothing updated or replaced.$CLI project remove all --yesthen$CLI project deploy --yesremove allemptied every collection. The firstdeployfailed at synth by design: the extension code still calledharness('L3E2Eknq5'), and the app printedAgentCore CDK synthesis failed: Unknown harness "L3E2Eknq5" in project "L3E2Eknq5". Available: none(exit 1) before touching AWS. Restored the vendedlib/cdk-stack.tsand re-ran:Removing stack AgentCore-L3E2Eknq5-default→Removed project 'L3E2Eknq5' from target 'default'(exit 0).describe-stacksafterwards: stack not found (DELETE_COMPLETEat 01:31:31Z); harness, role, policy and table gone.$CLI project status --jsonresources: [](nothing deployed);deployed-state.json→{ "targets": {} }.5.2 Runtime project
L3E2E1jh0(--template agent-python-strands, CodeZip, Python)$CLI project create --name L3E2E1jh0 --template agent-python-strands --skip-install --skip-git;npm install <tgz>inagentcore/cdk;uv syncinapp/agent_python_strandsagent_python_strands(PYTHON_3_14) and memoryagent_python_strandsMemory(four strategies). Tarball0.1.0-alpha.53installed.$CLI project buildAgentCore-L3E2E1jh0, target-less.$CLI project deploy --yesDeployed project 'L3E2E1jh0' to target 'default'.status --json: runtimeagent_python_strandsand memoryagent_python_strandsMemorybothdeployedwith ARNs.get-agent-runtime:READY, env{ MEMORY_AGENT_PYTHON_STRANDSMEMORY_ID: … }.$CLI runtime invoke --id L3E2E1jh0_agent_python_strands-PXdDrR4GTM --payload '{"prompt":"hello"}'→statusCode 200, streamedHello! How can I help you today?.lib/cdk-stack.tswith the same table,this.application.runtime('agent_python_strands').grantReadWrite(orders)+.addEnvironmentVariable('ORDERS_TABLE', orders.tableName);$CLI project deploy --yesDeployed.describe-stack-resources:OrdersA9B65338CREATE_COMPLETEin the same stack; runtimeUPDATE_COMPLETE(in place); roleCREATE_COMPLETE(kept);DefaultPolicyUPDATE_COMPLETE.aws bedrock-agentcore-control get-agent-runtime --agent-runtime-id L3E2E1jh0_agent_python_strands-PXdDrR4GTM --query environmentVariables{ MEMORY_AGENT_PYTHON_STRANDSMEMORY_ID: …, ORDERS_TABLE: AgentCore-L3E2E1jh0-default-OrdersA9B65338-1VSZAPZOEDBI }, statusREADY.aws iam simulate-principal-policy --policy-source-arn <runtime role> --action-names dynamodb:PutItem dynamodb:GetItem --resource-arns <table arn>allowed.$CLI runtime invoke --id … --payload '{"prompt":"hello"}' --jsonstatusCode 200, streamedHello! How can I help you today?— still answering.lib/cdk-stack.ts;$CLI project remove all --yes;$CLI project deploy --yes;$CLI project status --jsonRemoving stack AgentCore-L3E2E1jh0-default→Removed project 'L3E2E1jh0' from target 'default'(exit 0);status --json→resources: [];deployed-state.json→{ "targets": {} }; stackDELETE_COMPLETEat 01:34:23Z.Cleanup check (5.4):
aws cloudformation list-stacks --stack-status-filter CREATE_COMPLETE UPDATE_COMPLETE …lists noAgentCore-L3E2E*stack (both appear only underDELETE_COMPLETE);aws iam list-roles,list-agent-runtimes,list-harnesses,list-memoriesanddynamodb list-tablesreturn nothing with theL3E2E/AgentCore-L3E2Eprefix. Pre-existing resources in the account were not touched. The scratch projects remain on the verification host only.The optional container check (5.2,
agent-python-strands-container) was not run: the Docker daemon on the verification host was down (docker infofailed) and it is not required for the PRs.Reviewer guide
src/assets/cdk/bin/cdk.tsandsrc/assets/cdk/lib/cdk-stack.ts— the whole vended app.src/assets/cdk/package.json,tsconfig.json,README.md— the pin, the include list, the customer-facing docs.src/core/project/__snapshots__/manager.test.ts.snap— only removals.src/handlers/project/create/pathLimit.ts(+ test) — the measured Windows limit.src/core/observability.ts,src/core/project/backends/cdk.ts— comment-only.README.md—project createentry, "Extending the CDK app", Windows note.🤖 Generated with Claude Code
https://claude.ai/code/session_01KEWrUu52DmcWE3sx4VEhKL