Skip to content

feat: manage vended CDK project dependencies with minor-version pinning#1777

Open
jesseturner21 wants to merge 1 commit into
mainfrom
feat/managed-dependency-pinning
Open

feat: manage vended CDK project dependencies with minor-version pinning#1777
jesseturner21 wants to merge 1 commit into
mainfrom
feat/managed-dependency-pinning

Conversation

@jesseturner21

Copy link
Copy Markdown
Contributor

Description

Problem

The CLI vends projects with caret (^) dependency ranges in agentcore/cdk/package.json, so any upstream minor release (@aws/agentcore-cdk, aws-cdk-lib, …) can land in a customer's project without any CLI change — breaking template code or the CLI's ability to interact with the project. The CLI needs to own these versions on the customer's behalf while staying out of the way of dependencies the customer added themselves.

Solution

Pin to minor, let patches float. Managed dependencies are written as tilde ranges (~x.y.z); @aws/agentcore-cdk (L3 constructs, prerelease-versioned) is pinned exactly. A dependency is "managed" iff its name appears in the CLI's vended asset src/assets/cdk/package.json — that asset, baked into each CLI release, is the single source of truth for both the managed list and the known-good versions. Everything else in the customer's file is never touched.

On every agentcore deploy (headless and TUI), a preflight step:

  1. Skew check — if the project declares a managed dep with a higher minor/major than this CLI expects (e.g. a teammate on a newer CLI updated it), throw: "This project requires a newer version of the AgentCore CLI. Run npm install -g @aws/agentcore-cli@latest and retry." Higher patch is fine — that's the point of tilde.
  2. Migrate — projects created before pinning (caret ranges) are rewritten to the pinned form with a one-time explanation.
  3. Sync — managed deps are updated to the current CLI's values; user-added deps are left byte-for-byte untouched; non-semver specifiers (file: bundled-tarball overrides, git:, …) are skipped with a warning, never rewritten.
  4. Reinstall (only if something changed) — delete node_modules + lockfile in agentcore/cdk/ and fresh-install so the installed tree matches the new pins. No-op deploys stay fast.
  5. Report — print a summary of every change (old → new per dep, plus "Dependencies you added yourself were not changed.").

Opt-out: agentcore config disableDependencyManagement true skips migrate/sync/reinstall entirely; the skew check still runs but downgrades to a warning and deploy proceeds — an escape hatch if we ever ship a bad pin, and support for teams with their own dependency tooling.

High-level implementation

  • src/lib/dependency-management/ (new, self-contained) — one deep module behind a single function, syncManagedDependencies({vendedPackageJsonPath, projectDir, disabled}), designed to lift into the planned CLI refactor unchanged (zero imports from src/cli/). Internals: semver.ts (prerelease-aware parse/compare — the existing parseSemVer drops -alpha.N tags, which here would make an alpha downgrade look like a no-op), policy.ts (pure plan computation), messages.ts (single source of user-facing wording), and the rewrite/clean-reinstall logic. All notices/warnings are returned as data on the result; callers only display them, so the headless and TUI paths can't drift.
  • ErrorsCliVersionTooOldError (errorSource: 'user') and DependencySyncError ('client') in src/lib/errors/types.ts, registered in the telemetry ErrorName enum. All failure paths throw typed errors — never process.exit() — so telemetry classification keeps working.
  • Vended asset pinnedsrc/assets/cdk/package.json converted to the policy form, with tilde bases bumped to what today's caret ranges actually resolve to (e.g. constructs ^10.0.0~10.7.0, not ~10.0.0) so migration never silently downgrades an existing project. @aws/agentcore-cdk exact-pinned to 0.1.0-alpha.45.
  • Deploy integrationensureManagedDependencies() adapter (src/cli/operations/deploy/dependency-sync.ts) resolves the vended asset via getTemplatePath and reads the global-config opt-out; called as a "Sync CDK dependencies" step between validate and build in handleDeploy (actions.ts) and TUI preflight (useCdkPreflight.ts). The summary rides on DeployResult (so --json gets structured data; the human notice goes through onNotice, suppressed under --json), renders in the TUI DeployScreen, and feeds five new dep_sync_* deploy telemetry attributes.
  • ConfigdisableDependencyManagement added to GlobalConfigSchemaStrict; the generic agentcore config <key> <value> command handles it with no command changes.

Related Issue

Closes #1540

Documentation PR

N/A — behavior is self-describing via the deploy-time notices; can follow up in agent-docs if wanted.

Type of Change

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

Testing

33 new unit tests in src/lib/dependency-management/__tests__/:

  • sync.test.ts — end-to-end through the public function against a real temp project dir (only the npm subprocess mocked), one test per design-doc behavior: no-op deploy touches nothing and prints nothing; caret project migrates + reinstalls (node_modules/lockfile actually deleted, npm install invoked, migration notice includes the opt-out hint) while a user-added lodash survives untouched; higher-minor project throws CliVersionTooOldError with the upgrade wording; opted-out skew warns and leaves the file byte-identical; deleted managed dep is restored; file:bundled-agentcore-cdk.tgz override is skipped with a warning; npm failure / unreadable package.json wrap in DependencySyncError; rewrite preserves user key order and unknown fields.

  • policy.test.ts — plan computation: skew on higher minor and major but not higher patch; prerelease-aware skew on the exact pin (alpha.50 > alpha.45 detected, older alpha upgraded); devDependencies managed and the user's section respected; user deps never touched.

  • semver.test.ts — prerelease ordering (0.1.0-alpha.19 < 0.1.0-alpha.20 < 0.1.0), specifier classification (exact/tilde/caret), and unsupported forms (file:, git+https:, workspace:, *, latest, compound ranges).

  • I ran npm run test:unit and npm run test:integ (unit: 411 files / 5944 tests pass; integ not run — no integ coverage touched)

  • 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

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 July 16, 2026 19:46
@github-actions github-actions Bot added size/xl PR size: XL agentcore-harness-reviewing AgentCore Harness review in progress labels Jul 16, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Jul 16, 2026
@github-actions github-actions Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Jul 16, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Package Tarball

aws-agentcore-0.24.1.tgz

How to install

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

@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 Jul 16, 2026
@github-actions

github-actions Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 40.04% 14911 / 37235
🔵 Statements 39.32% 15906 / 40448
🔵 Functions 34.17% 2544 / 7445
🔵 Branches 33.54% 9935 / 29617
Generated in workflow #4121 for commit 360aca0 by the Vitest Coverage Report Action

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@github-actions github-actions Bot added size/xl PR size: XL and removed size/xl PR size: XL labels Jul 16, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Jul 16, 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 Jul 16, 2026
Pin managed dependencies in the vended agentcore/cdk/package.json to
tilde ranges (exact for @aws/agentcore-cdk), sync them to the CLI's
tested versions during deploy preflight, auto-migrate pre-pinning
projects, and error with an upgrade hint when the project was updated
by a newer CLI. Opt-out via 'agentcore config
disableDependencyManagement true'.
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.

feat: CLI should manage dependencies of created projects.

1 participant