Skip to content

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

Open
jesseturner21 wants to merge 8 commits into
mainfrom
feat/managed-dependency-pinning
Open

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

Conversation

@jesseturner21

@jesseturner21 jesseturner21 commented Jul 16, 2026

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@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. Install (only if something changed) — run an incremental npm install in agentcore/cdk/ that reconciles the edited package.json against the existing lockfile; node_modules and the lockfile are never deleted, so user-added deps keep their resolved versions and installs stay warm. The install also runs as a self-heal when node_modules is missing even with a matching manifest. If the install fails, the pre-rewrite package.json is restored so a retry recomputes the same plan and re-attempts the install. 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.").

Preview modes: --dry-run and --diff run the sync in check-only mode — the notice reports what a real deploy would change (future tense), but nothing is written and no install runs.

Teardown: teardown deploys are never blocked by the sync — both skew and write/install failures downgrade to warnings, so dependency pinning can never prevent destroying a cost-incurring stack.

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/). All notices/warnings are returned as data on the result; callers only display them, so the headless and TUI paths can't drift.
  • 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.
  • 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).
  • 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

40 new unit tests in src/lib/dependency-management/__tests__/ (16 sync + 12 policy + 12 semver), plus new useDevDeploy cases for the dev-flow notice/warnings:

  • I ran npm run test:unit and npm run test:integ (unit: 411 files / 5956 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.16% 15008 / 37362
🔵 Statements 39.44% 16006 / 40579
🔵 Functions 34.27% 2556 / 7457
🔵 Branches 33.66% 10014 / 29746
Generated in workflow #4149 for commit dc1aef3 by the Vitest Coverage Report Action

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@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 17, 2026
…mational warnings don't exit 2

The bundled-tarball override (file:bundled-agentcore-cdk.tgz) always yields a
'left unmanaged' dep-sync warning in e2e/dev builds. Merging depSync.warnings
into postDeployWarnings made every such deploy exit 2, failing e2e deploy
assertions. Dep-sync warnings are informational: print them from
printDeployResult (headless CLI) instead — the TUI and dev paths already
render result.dependencySync.warnings separately.
@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 17, 2026
…ilure, persist dev notice, print warnings on failed deploys, never block teardown

Round-2 review fixes for managed dependency pinning (#1540):

- handleDeploy: every explicit failure return after the sync step now
  carries dependencySync, so dep_sync_* telemetry and the rewrite notice
  survive deploys that fail at a later step (not just the catch path).
- syncManagedDependencies: on npm install failure, restore the pre-rewrite
  package.json before throwing DependencySyncError — otherwise a retry sees
  a matching manifest plus a stale node_modules, skips the install, and
  deploys against the old installed tree (the exact skew the feature
  prevents). Tests pin restore + successful retry.
- Dev TUI: the dep-sync notice/warnings arrived in the same render batch
  that transitioned out of 'deploying', so they were visible for at most
  one frame. They now persist into the post-deploy modes (harness chooser /
  InvokeScreen) and print to the normal buffer on the browser-launch path.
- Headless CLI: the non-JSON failure branch now prints
  dependencySync.notice/warnings to stderr, so a failed deploy still
  explains the package.json rewrite and any downgraded skew.
- Teardown: DependencySyncError (write/install failure) at both sync call
  sites is downgraded to a warning via teardownSyncFailureResult and the
  teardown proceeds — extending the treatSkewAsWarning invariant that
  nothing about pinning may block destroying a cost-incurring stack.
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

… suite

- policy.ts -> plan.ts, index.ts -> sync.ts with thin re-export barrel
- DependencySyncResult.migrated -> migratedFromCaret (consistent with SyncPlan)
- SKIPPED_SYNC_RESULT -> NO_OP_SYNC_RESULT via noOpSyncResult factory
- DeployResult.dependencySync -> dependencySyncResult; depSync local -> shorthand
- move toDepSyncAttrs into operations/deploy/dependency-sync.ts
- readManifest 'what' param -> fileDescription; install -> installResult
- drop #1540 issue references from comments
- add e2e-tests/dependency-sync.test.ts (migration+real deploy, upgrade,
  skew failure, opt-out warning)
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

- add outcome discriminant to DependencySyncResult (synced/check-only/
  opted-out/skipped/failure-suppressed/failed) + dep_sync_outcome telemetry
- attach failedSyncResult on sync-step failures so telemetry records them
- reset dep-sync state in startPreflight retries
- accept v-prefixed semver versions (v1.2.3, ~v1.2.3)
- replace NO_OP_SYNC_RESULT singleton with per-call factory
- warn (not success) on suppressed teardown sync failure in headless progress
- PreflightResult.dependencySync -> dependencySyncResult
- export PackageManifest from barrel; drop redundant type re-exports
- delete dead formatVersion; fix orphaned doc comment
- retitle e2e opt-out test to what it actually proves; drop stale #1540 ref
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

- TUI logs warn (not success) for suppressed teardown sync failure
- dedupe suppressed-failure warning line in deploy log
- e2e: add 'failed' outcome to DepSyncJson union + assert it in skew test
- add unit tests for CLI-layer sync factories, skip branch, toDepSyncAttrs,
  and disabled-wins-over-check outcome precedence
- fix outcome doc overclaim; rename endStep error param to message
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

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

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