Commit cb79649
feat(import): add runtime and memory import subcommands with TUI wizard (#763)
* feat(import): add runtime and memory import subcommands
Add `agentcore import runtime` and `agentcore import memory` subcommands
to import existing AWS resources into a CLI project. Includes 2-phase
CFN import, source code copying, and shared utilities.
Also adds TODO.md tracking entrypoint detection improvement and CFN
Phase 2 handler investigation, and IMPORT_TESTING_SUMMARY.md with
full E2E test results.
Constraint: AWS API returns modified entryPoint array (with otel wrapper), not original
Constraint: Commander.js parent options shadow same-named child options
Rejected: --source flag on runtime subcommand | conflicts with parent import --source
Confidence: high
Scope-risk: moderate
Not-tested: CFN Phase 2 import for runtimes (service-side HandlerInternalFailure)
* fix(import): fail on undetectable entrypoint instead of silent fallback
extractEntrypoint() now returns undefined when it cannot find a file
with a known extension (.py/.ts/.js) in the API's entryPoint array,
instead of silently falling back to main.py. Adds --entrypoint flag
so users can specify the entrypoint manually when auto-detection fails.
Constraint: AWS API returns modified entryPoint array with otel wrappers, not original
Rejected: Silent fallback to main.py | wrong entrypoint causes silent deploy failures
Confidence: high
Scope-risk: narrow
* chore: remove TODO.md and testing summary from branch
* test(import): add unit tests for entrypoint detection and runtime import handler
11 tests for extractEntrypoint covering otel wrappers, missing/empty
arrays, multiple extensions, and extensionless entries. 8 tests for
handleImportRuntime covering entrypoint failure, --entrypoint override,
missing --code, nonexistent source path, and duplicate runtime names.
* fix(import): address PR review feedback
- Validate entrypoint file exists inside --code directory
- Improve --code help text to clarify it points to the entrypoint folder
- Validate AWS credentials match target account via STS GetCallerIdentity
- Fix project name prefix stripping to only strip known prefix, not any underscore
- Rename sanitize() to replaceUnderscoresWithDashes() for clarity
- Use existing Dockerfile template from assets instead of hardcoded duplicate
* refactor: change --id to --arn on import runtime and memory subcommands
Users now provide the full resource ARN instead of just the ID.
The runtime/memory ID is extracted from the ARN's last path segment.
* fix(import): extract reflectionNamespaces for EPISODIC memory strategies
toMemorySpec was not mapping reflectionNamespaces from the API response,
causing EPISODIC strategy imports to fail Zod schema validation which
requires reflectionNamespaces for EPISODIC type strategies.
* fix(import): validate ARN format, region, and account before extracting resource ID
Previously, --arn was parsed with a blind split('/').pop() with no
validation. Now parseAndValidateArn checks the ARN matches the expected
format, resource type, and that region/account match the deployment target.
* fix(import): throw on missing required fields in getMemoryDetail instead of silent defaults
Previously, missing id/arn/name/eventExpiryDuration/strategy.type were
silently replaced with empty strings or default values, hiding API
response issues that would cause broken imports downstream.
* fix(import): detect already-imported resources early and improve CFN error messages
Check deployed-state.json before making any config changes to catch
resources already imported in the current project. Also detect the
"already exists in stack" CFN error and provide a friendlier message
explaining the resource must be removed from the other stack first.
* feat(import): capture tags during memory import
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.
* feat(import): capture encryptionKeyArn during memory 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.
* feat(import): capture executionRoleArn during memory import
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.
* refactor(import): deduplicate actions.ts by reusing import-utils utilities
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.
* fix(import): paginate listings, auto-select single result, and preserve 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)
* test(import): add tests for pagination, field extraction, auto-select, 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
* feat(import): auto-create deployment target from ARN when none exist
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.
* fix(import): omit runtimeVersion for Container builds
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.
* fix(import): filter API-internal namespace patterns from memory import
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
* fix(import): show project context error before --code flag validation
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
* fix(import): address bugbash issues for import commands
- 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
* feat(import): add interactive TUI wizard for import command
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
* fix(import): add early name validation and allow re-import with --name
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.
* revert(import): restore original duplicate-by-ARN blocking behavior
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.
* feat(import): mark import command as experimental
* fix(import): wire deploy next-step navigation and show dotfiles in file 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.
* refactor(import): extract shared CDK import pipeline to eliminate duplication
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)
* fix(import): launch TUI wizard when running agentcore import with no 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.
* fix(import): wire deploy and status navigation from CLI-inline TUI
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.
* style(import): fix prettier formatting in TUI screens
* fix(security): update lodash and lodash-es to resolve high-severity vulnerabilities
npm audit fix resolves CVE for code injection via _.template and
prototype pollution via _.unset/_.omit in lodash <=4.17.23.
* refactor(aws): extract createControlClient to avoid per-call client instantiation
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.
* fix(import): log warnings on silent catch failures instead of swallowing 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.
---------
Co-authored-by: Aidan Daly <aidandal@amazon.com>1 parent 11ca658 commit cb79649
File tree
32 files changed
+4207
-2411
lines changed- src
- cli
- aws
- __tests__
- commands/import
- __tests__
- tui
- components
- __tests__
- screens/import
- utils
- lib/packaging
- schema
- llm-compacted
- schemas
32 files changed
+4207
-2411
lines changedSome generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
| 2 | + | |
2 | 3 | | |
3 | 4 | | |
4 | 5 | | |
| 6 | + | |
| 7 | + | |
5 | 8 | | |
6 | 9 | | |
7 | 10 | | |
| |||
24 | 27 | | |
25 | 28 | | |
26 | 29 | | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
27 | 36 | | |
28 | 37 | | |
29 | 38 | | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
30 | 42 | | |
31 | 43 | | |
32 | 44 | | |
| |||
305 | 317 | | |
306 | 318 | | |
307 | 319 | | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
| 325 | + | |
| 326 | + | |
| 327 | + | |
| 328 | + | |
| 329 | + | |
| 330 | + | |
| 331 | + | |
| 332 | + | |
| 333 | + | |
| 334 | + | |
| 335 | + | |
| 336 | + | |
| 337 | + | |
| 338 | + | |
| 339 | + | |
| 340 | + | |
| 341 | + | |
| 342 | + | |
| 343 | + | |
| 344 | + | |
| 345 | + | |
| 346 | + | |
| 347 | + | |
| 348 | + | |
| 349 | + | |
| 350 | + | |
| 351 | + | |
| 352 | + | |
| 353 | + | |
| 354 | + | |
| 355 | + | |
| 356 | + | |
| 357 | + | |
| 358 | + | |
| 359 | + | |
| 360 | + | |
| 361 | + | |
| 362 | + | |
| 363 | + | |
| 364 | + | |
| 365 | + | |
| 366 | + | |
| 367 | + | |
| 368 | + | |
| 369 | + | |
| 370 | + | |
| 371 | + | |
| 372 | + | |
| 373 | + | |
| 374 | + | |
| 375 | + | |
| 376 | + | |
| 377 | + | |
| 378 | + | |
| 379 | + | |
| 380 | + | |
| 381 | + | |
| 382 | + | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
| 388 | + | |
| 389 | + | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
| 393 | + | |
| 394 | + | |
| 395 | + | |
| 396 | + | |
| 397 | + | |
| 398 | + | |
| 399 | + | |
| 400 | + | |
| 401 | + | |
| 402 | + | |
| 403 | + | |
| 404 | + | |
| 405 | + | |
| 406 | + | |
| 407 | + | |
| 408 | + | |
| 409 | + | |
| 410 | + | |
| 411 | + | |
| 412 | + | |
| 413 | + | |
| 414 | + | |
| 415 | + | |
| 416 | + | |
| 417 | + | |
| 418 | + | |
| 419 | + | |
| 420 | + | |
| 421 | + | |
| 422 | + | |
| 423 | + | |
| 424 | + | |
| 425 | + | |
| 426 | + | |
| 427 | + | |
| 428 | + | |
| 429 | + | |
| 430 | + | |
| 431 | + | |
| 432 | + | |
| 433 | + | |
| 434 | + | |
| 435 | + | |
| 436 | + | |
| 437 | + | |
| 438 | + | |
| 439 | + | |
| 440 | + | |
| 441 | + | |
| 442 | + | |
| 443 | + | |
| 444 | + | |
| 445 | + | |
| 446 | + | |
| 447 | + | |
| 448 | + | |
| 449 | + | |
| 450 | + | |
| 451 | + | |
| 452 | + | |
| 453 | + | |
| 454 | + | |
| 455 | + | |
| 456 | + | |
| 457 | + | |
| 458 | + | |
| 459 | + | |
| 460 | + | |
| 461 | + | |
| 462 | + | |
| 463 | + | |
| 464 | + | |
| 465 | + | |
| 466 | + | |
| 467 | + | |
| 468 | + | |
| 469 | + | |
| 470 | + | |
| 471 | + | |
| 472 | + | |
| 473 | + | |
| 474 | + | |
| 475 | + | |
| 476 | + | |
| 477 | + | |
| 478 | + | |
| 479 | + | |
| 480 | + | |
| 481 | + | |
| 482 | + | |
| 483 | + | |
| 484 | + | |
| 485 | + | |
| 486 | + | |
| 487 | + | |
| 488 | + | |
| 489 | + | |
| 490 | + | |
| 491 | + | |
| 492 | + | |
| 493 | + | |
| 494 | + | |
| 495 | + | |
| 496 | + | |
| 497 | + | |
| 498 | + | |
| 499 | + | |
| 500 | + | |
| 501 | + | |
| 502 | + | |
| 503 | + | |
| 504 | + | |
308 | 505 | | |
309 | 506 | | |
310 | 507 | | |
| |||
0 commit comments