From 7095912769df8e5e4eeb016278f7a43d2c4e772e Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Tue, 4 Aug 2026 07:05:12 -0700 Subject: [PATCH 1/2] Fix: align dev's express and @types/express ranges with core core declares express ^4.22.1 / @types/express ^4.17.25 while dev declared ^4.21.2 / ^4.17.21. Both workspaces already resolve the single hoisted express@4.22.2 and @types/express@4.17.25, so dev's ranges were a stale, untrue floor that ships in the published @google/adk-devtools manifest. Align up to core: core's floor is the newer one, and lowering it would weaken the published floor of @google/adk for no benefit. The lockfile delta is the two mirrored range strings under packages/dev; no resolved version changes. --- dev/package.json | 4 ++-- package-lock.json | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dev/package.json b/dev/package.json index 6117df13a..a734b6271 100644 --- a/dev/package.json +++ b/dev/package.json @@ -41,7 +41,7 @@ }, "devDependencies": { "@types/cors": "^2.8.19", - "@types/express": "^4.17.21", + "@types/express": "^4.17.25", "@types/node": "^20.12.7", "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", @@ -67,7 +67,7 @@ "dotenv": "^17.2.3", "esbuild": "^0.25.9", "esbuild-shim-plugin": "^1.0.3", - "express": "^4.21.2", + "express": "^4.22.1", "fast-glob": "^3.3.3", "js-yaml": "^4.1.1", "ts-graphviz": "^1.0.1", diff --git a/package-lock.json b/package-lock.json index e29a4a190..782823035 100644 --- a/package-lock.json +++ b/package-lock.json @@ -107,7 +107,7 @@ "dotenv": "^17.2.3", "esbuild": "^0.25.9", "esbuild-shim-plugin": "^1.0.3", - "express": "^4.21.2", + "express": "^4.22.1", "fast-glob": "^3.3.3", "js-yaml": "^4.1.1", "ts-graphviz": "^1.0.1", @@ -119,7 +119,7 @@ }, "devDependencies": { "@types/cors": "^2.8.19", - "@types/express": "^4.17.21", + "@types/express": "^4.17.25", "@types/node": "^20.12.7", "@typescript-eslint/eslint-plugin": "^7.7.1", "@typescript-eslint/parser": "^7.7.1", From 53a333e4c8553d8d604d0e2b180d00c6b4c48f1e Mon Sep 17 00:00:00 2001 From: Amaad Martin Date: Tue, 4 Aug 2026 07:15:12 -0700 Subject: [PATCH 2/2] Test: guard against workspace dependency-range drift Nothing in the repo prevented the express range drift from reappearing, which is the actual root cause. Index every dependencies/devDependencies entry of the workspaces named by the root manifest and fail when one package name is declared with more than one range string, naming every site. peerDependencies are excluded (a peer range is deliberately wider), as is the root manifest (tooling root, and it carries separately-tracked eslint/prettier drift). --- .../dependency_alignment_test.ts | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 tests/integration/workspace_manifests/dependency_alignment_test.ts diff --git a/tests/integration/workspace_manifests/dependency_alignment_test.ts b/tests/integration/workspace_manifests/dependency_alignment_test.ts new file mode 100644 index 000000000..8e7a59f32 --- /dev/null +++ b/tests/integration/workspace_manifests/dependency_alignment_test.ts @@ -0,0 +1,65 @@ +/** + * @license + * Copyright 2026 Google LLC + * SPDX-License-Identifier: Apache-2.0 + */ + +import {readFileSync} from 'node:fs'; +import path from 'node:path'; +import {describe, expect, it} from 'vitest'; + +/** + * `peerDependencies` are excluded because a peer range is deliberately allowed + * to be wider than the dependency range that satisfies it. The root manifest is + * excluded too: it is the tooling root rather than a shipped workspace. + */ +const CHECKED_FIELDS = ['dependencies', 'devDependencies'] as const; + +interface Manifest { + workspaces?: string[]; + dependencies?: Record; + devDependencies?: Record; +} + +interface Declaration { + site: string; + range: string; +} + +/** Reads a manifest relative to the repo root, which vitest sets as the cwd. */ +function readManifest(workspaceDir: string): Manifest { + return JSON.parse( + readFileSync( + path.join(process.cwd(), workspaceDir, 'package.json'), + 'utf8', + ), + ); +} + +describe('workspace dependency ranges', () => { + it('declares one range per package across all workspaces', () => { + const workspaces = readManifest('.').workspaces ?? []; + const declarations = new Map(); + + for (const workspace of workspaces) { + const manifest = readManifest(workspace); + for (const field of CHECKED_FIELDS) { + for (const [name, range] of Object.entries(manifest[field] ?? {})) { + const sites = declarations.get(name) ?? []; + sites.push({site: `${workspace} (${field})`, range}); + declarations.set(name, sites); + } + } + } + + const violations = [...declarations] + .filter(([, sites]) => new Set(sites.map((s) => s.range)).size > 1) + .map( + ([name, sites]) => + `${name}: ${sites.map((s) => `${s.site} -> ${s.range}`).join(', ')}`, + ); + + expect(workspaces.length).toBeGreaterThan(1); + expect(violations).toEqual([]); + }); +});