Skip to content

feat(import): add runtime and memory import subcommands with TUI wizard#763

Merged
jesseturner21 merged 33 commits intoaws:mainfrom
jesseturner21:main
Apr 2, 2026
Merged

feat(import): add runtime and memory import subcommands with TUI wizard#763
jesseturner21 merged 33 commits intoaws:mainfrom
jesseturner21:main

Conversation

@jesseturner21
Copy link
Copy Markdown
Contributor

Description

Adds agentcore import runtime and agentcore import memory subcommands that import existing AWS BedrockAgentCore resources into a local CLI project via CloudFormation IMPORT change sets. Also adds an interactive TUI wizard for the import flow.

Key changes

New import subcommands:

  • agentcore import runtime --arn <arn> --code <path> — imports an existing AgentCore Runtime, copies agent source code, and brings the resource under CloudFormation management
  • agentcore import memory --arn <arn> — imports an existing AgentCore Memory with full strategy/namespace/tag preservation
  • Both commands support --name for local name override, --target for multi-target projects, and -y for auto-confirm

Interactive TUI wizard:

  • agentcore import with no args launches a guided wizard (resource type selection → ARN input → code path → progress → next steps)
  • Next-steps navigation works from both the full TUI and CLI-inline contexts (deploy, status)

Shared CDK import pipeline (import-pipeline.ts):

  • Extracted the duplicated CDK build → synth → bootstrap → publish → phase1 → phase2 → update-state pipeline from actions.ts, import-runtime.ts, and import-memory.ts into a single executeCdkImportPipeline() function
  • Each caller provides resource-specific logic via a buildResourcesToImport callback
  • ~200 lines of duplication removed

AWS control plane helpers (agentcore-control.ts):

  • getAgentRuntimeDetail / getMemoryDetail — fetch full resource details with field validation
  • listAllAgentRuntimes / listAllMemories — paginated listing with auto-select for single results
  • Required field validation with clear error messages

Import utilities (import-utils.ts):

  • resolveImportContext() — shared setup (logger, project context, target resolution)
  • parseAndValidateArn() — validates format, resource type, region, and account match
  • failResult() — standardized error return builder
  • copyAgentSource() — copies agent code with exclusion filters, pyproject.toml fixup, Dockerfile generation
  • findResourceInDeployedState() — duplicate detection against deployed-state.json

Validation and error handling:

  • Early name validation against AgentNameSchema regex before any file I/O (prevents path traversal via --name)
  • ARN format, region, and account validation before API calls
  • Duplicate detection by both local name and resource ID
  • Rollback on failure (config snapshot restore + copied directory cleanup)
  • Auto-create deployment target from ARN when no targets exist

Schema changes:

  • runtimeVersion made optional (Container builds don't need it)
  • Added description and encryptionKeyArn to Memory schema
  • Added executionRoleArn to Memory schema

Related Issue

Closes #

Documentation PR

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

Unit tests added:

  • import-runtime-handler.test.ts — 200+ tests covering entrypoint detection, field mapping, validation, duplicate detection, rollback, error paths
  • import-runtime-entrypoint.test.ts — extractEntrypoint edge cases (OTel wrappers, missing extensions, path prefixes)
  • agentcore-control.test.ts — AWS API helper tests (pagination, field extraction, auto-select, env var mapping)
  • 260/260 import tests pass, full suite passes

End-to-end bugbash testing:

  • Tested import memory with real AWS memory (3 strategies, tags, executionRoleArn) — all fields preserved
  • Tested import runtime with real AWS CodeZip runtime — build, entrypoint, protocol all correct
  • Tested error paths: invalid ARN, account mismatch, duplicate detection, missing --code
  • Tested runtime + memory coexistence in same project

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

@jesseturner21 jesseturner21 requested a review from a team April 2, 2026 16:00
@github-actions github-actions bot added the size/xl PR size: XL label Apr 2, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Package Tarball

aws-agentcore-0.5.1.tgz

How to install

npm install https://github.com/aws/agentcore-cli/releases/download/pr-763-tarball/aws-agentcore-0.5.1.tgz

@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Apr 2, 2026
@github-actions github-actions bot removed the size/xl PR size: XL label Apr 2, 2026
@github-actions github-actions bot added the size/xl PR size: XL label Apr 2, 2026
Copy link
Copy Markdown
Contributor

@Hweinstock Hweinstock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly nits and some questions about existing patterns. Only comments worth addressing today:

  • could we build more reusable utilities to make future import work easier? Feels like memory/runtime are pretty duplicated. This could also be picked up when adding new resources, if we're trying to get this out today.
  • Should we log when non-critical parts of import fail, or when we attempt to rollback?

@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Apr 2, 2026
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Apr 2, 2026
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Apr 2, 2026
@github-actions github-actions bot added size/xl PR size: XL and removed size/xl PR size: XL labels Apr 2, 2026
jesseturner21 and others added 23 commits April 2, 2026 21:12
Fetch tags via ListTagsForResource API and include them in the imported
memory config. Tags already flow through the CLI schema and CDK construct,
they just weren't being read from the API during import.
Add encryptionKeyArn to CLI schema, MemoryDetail, and toMemorySpec so
imported memories preserve their KMS encryption key configuration.
Also update CDK L3 construct to pass encryptionKeyArn through to CfnMemory.
Map the API field memoryExecutionRoleArn to executionRoleArn in CLI
schema to match the runtime convention. Also update CDK L3 construct
to use an imported role via Role.fromRoleArn when executionRoleArn
is provided instead of always creating a new one.
…ities

actions.ts reimplemented 5 utilities that already exist in import-utils.ts.
Replace local definitions with imports and use updateDeployedState() instead
of inline state manipulation.

Removed: sanitize(), toStackName(), fixPyprojectForSetuptools(),
COPY_EXCLUDE_DIRS, copyDirRecursive() — all duplicates of import-utils.ts.
…ve runtime config

Three import bugs fixed:

1. listAgentRuntimes/listMemories only fetched one page (max 100).
   Added listAllAgentRuntimes/listAllMemories that paginate via nextToken.

2. Single-result listing incorrectly showed "Multiple found" error.
   Now auto-selects when exactly one runtime/memory exists.

3. toAgentEnvSpec dropped env vars, tags, lifecycle config, and request
   header allowlist. Extended AgentRuntimeDetail and getAgentRuntimeDetail
   to extract these fields (including ListTagsForResource call for tags),
   and mapped them in toAgentEnvSpec.

Confidence: high
Scope-risk: moderate
Not-tested: pagination with >100 real resources (no integration test account available)
…, and env var mapping

Tests cover:
- listAllAgentRuntimes/listAllMemories pagination across multiple pages
- getAgentRuntimeDetail extraction of environmentVariables, tags (via
  ListTagsForResource), lifecycleConfiguration, requestHeaderAllowlist
- toAgentEnvSpec mapping of env vars Record to envVars array, plus
  direct mapping of tags, lifecycle config, and header allowlist
- Single-result auto-select when listing returns exactly 1 runtime
- Error cases: empty listings, multiple results, absent fields
When no deployment targets are configured, import runtime/memory now
parses the --arn to extract region and account, then creates a default
target automatically instead of requiring `agentcore deploy` first.
Container runtimes have no runtimeVersion from the API, but
toAgentEnvSpec was hardcoding PYTHON_3_12 as a fallback. Now
runtimeVersion is optional in the schema and only set for
non-Container builds.
Memory strategies like SUMMARIZATION and USER_PREFERENCE include
auto-generated namespace patterns (e.g. /strategies/{memoryStrategyId}/...)
that are API-internal and should not be written to local agentcore.json.

Constraint: Only filters namespaces containing {memoryStrategyId} template var
Rejected: Strip all namespaces for non-SEMANTIC strategies | would lose user-defined namespaces
Confidence: high
Scope-risk: narrow
Commander's requiredOption() for --code runs before the action handler,
so users outside a project see "required option not specified" instead
of "no agentcore project found". Change to option() so the handler's
project context check (step 1) runs first. The --code validation at
step 5 still catches missing values after project context is confirmed.

Constraint: Commander validates requiredOption before action handlers execute
Rejected: Moving project check into a Commander hook | adds complexity for one flag
Confidence: high
Scope-risk: narrow
- Invalid ARN now returns "Not a valid ARN" before target resolution
- Failed imports roll back agentcore.json and clean up copied app/ dirs
- Discovery listings show ARNs (not just IDs) so users can copy them
- Remove --target flag from import runtime/memory subcommands
- Add description field to AgentEnvSpec schema and wire through import

Constraint: Commander validates requiredOption before action handlers
Constraint: Rollback is best-effort to avoid masking the original error
Rejected: Keep --target on subcommands | silently falls back to default, confusing UX
Confidence: high
Scope-risk: moderate
Adds a multi-screen TUI flow for importing runtimes, memories,
and starter toolkit configs, replacing the silent fall-through
that previously occurred when selecting "import" in the TUI.

Constraint: onProgress must be injectable so TUI can display step progress
Rejected: Single text-input screen for all flows | each import type has different required fields
Confidence: high
Scope-risk: narrow
Bug 5: Validate --name against the AgentNameSchema regex before any
file I/O operations. Previously, a malicious --name like
'../../../etc/pwned' would copy files outside the project directory
and set up a Python venv there before schema validation rejected it.
Now invalid names are caught immediately with a clear error message.
Applied to both import-runtime and import-memory.

Bug 6: Allow re-importing the same cloud resource under a different
local name when --name is provided. Previously, the deployed-state
duplicate check blocked all re-imports by resource ID regardless of
--name. Now it only blocks when --name is not provided, and suggests
using --name in the error message. When --name is provided, it warns
and proceeds. Applied to both import-runtime and import-memory.
Bug 6 is not a bug — blocking re-imports of the same cloud resource
ARN is correct because allowing it would create duplicate CFN logical
resources referencing the same physical resource, causing deploy
failures. Reverts the --name re-import allowance while keeping the
Bug 5 early name validation fix.
…le picker

Two TUI fixes for the import flow:
1. ImportFlow now accepts onNavigate prop so selecting "Deploy" from
   next steps navigates to the deploy screen instead of going back.
2. PathInput gains a showHidden prop; YamlPathScreen uses it so
   .bedrock_agentcore.yaml is visible in the file picker.
…lication

The three import handlers (import-runtime, import-memory, actions) all
repeated the same CDK build/synth/bootstrap/publish/phase1/phase2/state-update
pipeline (~120 lines each). Extract this into executeCdkImportPipeline() in
a new import-pipeline.ts module. Also add resolveImportContext() and
failResult() helpers to import-utils.ts for shared setup and error handling.

Net effect: -335 lines, zero behavior change, all 260 tests pass.

Constraint: Must not change any observable behavior — pure structural refactor
Rejected: Full strategy-pattern abstraction | over-engineering for 2 concrete cases
Confidence: high
Scope-risk: moderate
Not-tested: actions.ts YAML import path with real AWS (infra limitation)
…args

Previously `agentcore import` with no --source flag showed help text.
Now it launches the interactive ImportFlow TUI, matching the pattern
used by `agentcore add` and other commands.
When running `agentcore import` from CLI (not full TUI), selecting
"deploy" or "status" from the next-steps menu now renders the
corresponding screen instead of silently exiting.
…ulnerabilities

npm audit fix resolves CVE for code injection via _.template and
prototype pollution via _.unset/_.omit in lodash <=4.17.23.
…nstantiation

Each function in agentcore-control.ts was creating a new
BedrockAgentCoreControlClient on every call, wasting HTTP connections
and credential resolution. Extracted a shared createControlClient()
factory and reuse a single client across paginated listAll* calls.
…ing errors

Tag fetch failures in agentcore-control.ts and rollback failures in
import-runtime.ts and import-memory.ts were silently swallowed. Users
had no indication when config could be left in a broken state. Added
console.warn calls matching the existing pattern in bedrock-import.ts.
Copy link
Copy Markdown
Contributor

@Hweinstock Hweinstock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4k lines, send it (once build passes)!

@jesseturner21 jesseturner21 merged commit cb79649 into aws:main Apr 2, 2026
12 of 13 checks passed
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.

3 participants