From 654d36fdbd3b3cb3e7f1a4570496c587a54891c4 Mon Sep 17 00:00:00 2001 From: gitikavj Date: Tue, 13 Oct 2026 22:24:42 +0000 Subject: [PATCH] fix(compat): address v0 project follow-ups --- .../project/backends/cdk/credentials.test.ts | 3 +- src/core/project/legacy/deploy.test.ts | 10 ++++-- src/core/project/legacy/deploy.ts | 6 ++-- src/core/project/legacy/load.ts | 4 +-- src/core/project/legacy/translate.test.ts | 24 ++++++++----- src/core/project/legacy/translate.ts | 35 +++++++++---------- src/core/project/legacy/types.ts | 7 ---- .../project/buildDeploy.screen.test.tsx | 6 ---- src/handlers/project/deploy/index.test.ts | 7 ++-- src/handlers/project/deploy/index.ts | 10 +++--- src/handlers/project/dev/index.test.ts | 10 ++---- 11 files changed, 58 insertions(+), 64 deletions(-) diff --git a/src/core/project/backends/cdk/credentials.test.ts b/src/core/project/backends/cdk/credentials.test.ts index 63903c7e2..423f23fca 100644 --- a/src/core/project/backends/cdk/credentials.test.ts +++ b/src/core/project/backends/cdk/credentials.test.ts @@ -13,7 +13,6 @@ import { ProjectSpecSchema } from "../../../../projectSchemas/project"; import type { CoreOptions } from "../../../types"; import { EnvLocalFile } from "../../envLocal"; import { v0Fixture } from "../../legacy/fixtures-test-support"; -import { translateV0Spec } from "../../legacy/translate"; import { createCredentialProvisioner, createCredentialRemover, @@ -87,7 +86,7 @@ async function legacyProject(credentials: unknown[], envLocal?: string): Promise const v0Spec = v0Fixture("baseline.json"); return { ...(await project(credentials, envLocal)), - legacy: { format: "v0", v0Spec, extras: translateV0Spec(v0Spec).extras }, + legacy: { format: "v0", v0Spec }, }; } diff --git a/src/core/project/legacy/deploy.test.ts b/src/core/project/legacy/deploy.test.ts index 2fd271ddc..3df05e90f 100644 --- a/src/core/project/legacy/deploy.test.ts +++ b/src/core/project/legacy/deploy.test.ts @@ -3,7 +3,7 @@ import type { InheritedProcessOptions, InheritedProcessRunner } from "../../../i import { executeV0Deploy, V0_CLI_PACKAGE } from "./deploy"; describe("executeV0Deploy", () => { - test("pins the final v0 CLI and forwards deploy flags from the project root", async () => { + test("uses the latest v0 CLI and forwards deploy flags from the project root", async () => { const calls: Array<{ command: string[]; options: InheritedProcessOptions }> = []; const runner: InheritedProcessRunner = async (command, options) => { calls.push({ command, options }); @@ -14,6 +14,7 @@ describe("executeV0Deploy", () => { { projectRoot: "/workspace/project", target: "staging", + region: "eu-west-1", yes: true, json: true, }, @@ -30,6 +31,8 @@ describe("executeV0Deploy", () => { "deploy", "--target", "staging", + "--region", + "eu-west-1", "--yes", "--json", ], @@ -50,6 +53,7 @@ describe("executeV0Deploy", () => { { projectRoot: "/workspace/project", target: "default", + region: "us-east-1", yes: false, json: false, }, @@ -59,6 +63,8 @@ describe("executeV0Deploy", () => { }, ); - expect(commands).toEqual([["npx", "--yes", V0_CLI_PACKAGE, "deploy", "--target", "default"]]); + expect(commands).toEqual([ + ["npx", "--yes", V0_CLI_PACKAGE, "deploy", "--target", "default", "--region", "us-east-1"], + ]); }); }); diff --git a/src/core/project/legacy/deploy.ts b/src/core/project/legacy/deploy.ts index 7e1f61965..36ef88b11 100644 --- a/src/core/project/legacy/deploy.ts +++ b/src/core/project/legacy/deploy.ts @@ -1,11 +1,11 @@ import { runInheritedProcess, type InheritedProcessRunner } from "../../../io"; -export const V0_CLI_VERSION = "0.31.1"; -export const V0_CLI_PACKAGE = `@aws/agentcore@${V0_CLI_VERSION}`; +export const V0_CLI_PACKAGE = "@aws/agentcore@0"; export type V0DeployInput = { projectRoot: string; target: string; + region: string; yes: boolean; json: boolean; }; @@ -25,6 +25,8 @@ export async function executeV0Deploy( "deploy", "--target", input.target, + "--region", + input.region, ...(input.yes ? ["--yes"] : []), ...(input.json ? ["--json"] : []), ]; diff --git a/src/core/project/legacy/load.ts b/src/core/project/legacy/load.ts index 511ad7475..53b5522b3 100644 --- a/src/core/project/legacy/load.ts +++ b/src/core/project/legacy/load.ts @@ -7,11 +7,11 @@ import { translateV0Spec } from "./translate"; /** Parse a v0 project with v0's schema and expose a translated, read-only in-memory view. */ export async function loadLegacyProject(rootPath: string, json: ReadWriteJson): Promise { const v0Spec = await json.read(projectSpecPath(rootPath), V0AgentCoreProjectSpecSchema); - const { spec, extras } = translateV0Spec(v0Spec); + const { spec } = translateV0Spec(v0Spec); return { name: v0Spec.name, rootPath, spec, - legacy: { format: "v0", v0Spec, extras }, + legacy: { format: "v0", v0Spec }, }; } diff --git a/src/core/project/legacy/translate.test.ts b/src/core/project/legacy/translate.test.ts index 812e15643..50a2ebd0e 100644 --- a/src/core/project/legacy/translate.test.ts +++ b/src/core/project/legacy/translate.test.ts @@ -11,16 +11,17 @@ describe("translateV0Spec", () => { expect("$schema" in spec).toBe(false); }); - test("moves v0-only collections into extras and drops httpGateways", () => { - const { spec, extras } = translateV0Spec(v0Fixture("top-abTests-nonempty.json")); - for (const key of ["abTests", "datasets", "capacityProviders", "httpGateways"]) { + test("drops collections that have no v1 equivalent from the translated view", () => { + const { spec } = translateV0Spec(v0Fixture("top-abTests-nonempty.json")); + for (const key of [ + "abTests", + "datasets", + "capacityProviders", + "unassignedTargets", + "httpGateways", + ]) { expect(key in spec).toBe(false); } - expect(extras.abTests?.length).toBeGreaterThan(0); - - const unassigned = translateV0Spec(v0Fixture("top-unassignedTargets.json")); - expect("unassignedTargets" in unassigned.spec).toBe(false); - expect(unassigned.extras.unassignedTargets?.length).toBeGreaterThan(0); }); test("renames mcpRuntimeTools to toolRuntimes and artifact to build", () => { @@ -36,6 +37,13 @@ describe("translateV0Spec", () => { expect("toolRuntimes" in spec).toBe(false); }); + test("omits toolRuntimes when v0 had an empty mcpRuntimeTools array", () => { + const v0 = v0Fixture("baseline.json"); + v0.mcpRuntimeTools = []; + const { spec } = translateV0Spec(v0); + expect("toolRuntimes" in spec).toBe(false); + }); + test("renames artifact to build on gateway target compute", () => { const { spec } = translateV0Spec( v0Fixture("gateway-target-mcpServer-agentcoreRuntime-compute.json"), diff --git a/src/core/project/legacy/translate.ts b/src/core/project/legacy/translate.ts index f82d988b6..2f54c5601 100644 --- a/src/core/project/legacy/translate.ts +++ b/src/core/project/legacy/translate.ts @@ -1,6 +1,5 @@ import type { ProjectSpec } from "../../../projectSchemas/project"; import type { V0ProjectSpec } from "../../../projectSchemas/v0"; -import type { LegacyExtras } from "./types"; type Json = Record; @@ -21,20 +20,21 @@ function renameArtifact(compute: unknown): unknown { * another name. Callers that need a valid v1 spec (migrate) validate the result. * * - `version` becomes 2 and `$schema` is dropped. - * - `abTests`, `datasets`, `capacityProviders`, and `unassignedTargets` move into - * the returned extras; `httpGateways` (always empty in v0) is dropped. + * - `abTests`, `datasets`, `capacityProviders`, `unassignedTargets`, and + * `httpGateways` have no v1 equivalent and are dropped from the translated + * view. They remain available on `legacy.v0Spec`. * - `mcpRuntimeTools` becomes `toolRuntimes`, and every tool runtime's and gateway * target's `compute.runtime.artifact` becomes `build`. * - Runtime `capacityProviderVolume` mounts are dropped: v1 has no capacity * providers, and its code switches over the mount kinds it knows. */ -export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec; extras: LegacyExtras } { +export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec } { const { $schema: _schema, - abTests, - datasets, - capacityProviders, - unassignedTargets, + abTests: _abTests, + datasets: _datasets, + capacityProviders: _capacityProviders, + unassignedTargets: _unassignedTargets, httpGateways: _httpGateways, mcpRuntimeTools, ...rest @@ -60,16 +60,15 @@ export function translateV0Spec(v0: V0ProjectSpec): { spec: ProjectSpec; extras: version: 2, runtimes, agentCoreGateways, - ...(mcpRuntimeTools && { - toolRuntimes: (mcpRuntimeTools as Json[]).map((tool) => ({ - ...tool, - compute: renameArtifact(tool.compute), - })), - }), + ...(mcpRuntimeTools?.length + ? { + toolRuntimes: (mcpRuntimeTools as Json[]).map((tool) => ({ + ...tool, + compute: renameArtifact(tool.compute), + })), + } + : {}), } as unknown as ProjectSpec; - return { - spec, - extras: { abTests, datasets, capacityProviders, unassignedTargets } as LegacyExtras, - }; + return { spec }; } diff --git a/src/core/project/legacy/types.ts b/src/core/project/legacy/types.ts index 188fa23f3..d77521a78 100644 --- a/src/core/project/legacy/types.ts +++ b/src/core/project/legacy/types.ts @@ -1,14 +1,7 @@ import type { V0ProjectSpec } from "../../../projectSchemas/v0"; -/** The v0 collections that have no place in v1's spec, kept aside by the translator. */ -export type LegacyExtras = Pick< - V0ProjectSpec, - "abTests" | "datasets" | "capacityProviders" | "unassignedTargets" ->; - export type LegacyProjectInfo = { format: "v0"; /** The v0 spec as parsed by the v0 schema; the source of truth for v0-only reads. */ v0Spec: V0ProjectSpec; - extras: LegacyExtras; }; diff --git a/src/handlers/project/buildDeploy.screen.test.tsx b/src/handlers/project/buildDeploy.screen.test.tsx index 5bcfa8ef0..91ade62e3 100644 --- a/src/handlers/project/buildDeploy.screen.test.tsx +++ b/src/handlers/project/buildDeploy.screen.test.tsx @@ -216,12 +216,6 @@ describe("project deploy screen", () => { legacy: { format: "v0", v0Spec: {} as never, - extras: { - abTests: [], - datasets: [], - capacityProviders: [], - unassignedTargets: [], - }, }, } as Project; core.projectManager.listTargets = async () => [ diff --git a/src/handlers/project/deploy/index.test.ts b/src/handlers/project/deploy/index.test.ts index ca05068a9..785613948 100644 --- a/src/handlers/project/deploy/index.test.ts +++ b/src/handlers/project/deploy/index.test.ts @@ -164,7 +164,7 @@ describe("project deploy handler", () => { test.each(["--yes", "--json"])( "delegates a legacy deploy with %s before resolving an account or using v1 CDK", async (flag) => { - const projectRoot = await inProjectWithTargets(); + const projectRoot = await inProjectWithTargets("[]"); const specPath = join(projectRoot, "agentcore", "agentcore.json"); const manifestPath = join(projectRoot, "agentcore", "cdk", "package.json"); await writeFile(specPath, JSON.stringify({ name: "orders", version: 1 })); @@ -189,7 +189,7 @@ describe("project deploy handler", () => { }, }); - await subject.run([flag]); + await subject.run(["--region", "eu-west-2", flag]); expect(subject.calls).toEqual([]); expect(accountCalls).toEqual([]); @@ -197,6 +197,7 @@ describe("project deploy handler", () => { { projectRoot, target: "default", + region: "eu-west-2", yes: flag === "--yes", json: flag === "--json", }, @@ -205,7 +206,7 @@ describe("project deploy handler", () => { expect(subject.io.stderr()).toBe( flag === "--json" ? "" - : "This is a v0 project; running AgentCore CLI 0.31.1 deploy in compatibility mode.", + : "This is a v0 project; running the latest v0 AgentCore CLI deploy in compatibility mode.", ); expect( await Promise.all([readFile(specPath, "utf8"), readFile(manifestPath, "utf8")]), diff --git a/src/handlers/project/deploy/index.ts b/src/handlers/project/deploy/index.ts index bd74dcf30..26aea01db 100644 --- a/src/handlers/project/deploy/index.ts +++ b/src/handlers/project/deploy/index.ts @@ -1,11 +1,7 @@ import { createInterface } from "node:readline/promises"; import z from "zod"; import { enclosingProjectRoot, isV0Project } from "../../../core/project/fsUtils"; -import { - runV0Deploy, - V0_CLI_VERSION, - type V0DeployRunner, -} from "../../../core/project/legacy/deploy"; +import { runV0Deploy, type V0DeployRunner } from "../../../core/project/legacy/deploy"; import { SilentCLIError, UserCancellationError } from "../../../errors"; import type { AppIO } from "../../../io"; import { DEFAULT_TARGET_NAME } from "../../../projectSchemas/aws-targets"; @@ -87,6 +83,7 @@ export const createDeployProjectHandler = (config: DeployProjectHandlerConfig) = await delegateV0Deploy(config, { projectRoot: project.rootPath, target: flags.target, + region: ctx.require(RegionKey), yes: flags.yes, json: jsonOutput, }); @@ -198,6 +195,7 @@ function withV0Deploy(config: DeployProjectHandlerConfig): Middleware { await delegateV0Deploy(config, { projectRoot, target: flags.target as string, + region: ctx.require(RegionKey), yes: flags.yes as boolean, json: ctx.require(JsonKey), }); @@ -214,7 +212,7 @@ async function delegateV0Deploy( ): Promise { if (!input.json) { config.io.stderr.write( - `This is a v0 project; running AgentCore CLI ${V0_CLI_VERSION} deploy in compatibility mode.\n`, + "This is a v0 project; running the latest v0 AgentCore CLI deploy in compatibility mode.\n", ); } const exitCode = await (config.runV0Deploy ?? runV0Deploy)(input); diff --git a/src/handlers/project/dev/index.test.ts b/src/handlers/project/dev/index.test.ts index ccca68cb3..dfd1550d1 100644 --- a/src/handlers/project/dev/index.test.ts +++ b/src/handlers/project/dev/index.test.ts @@ -256,7 +256,6 @@ describe("project dev selection and dispatch", () => { configuredProject.legacy = { format: "v0", v0Spec: {} as never, - extras: {} as never, }; const subject = harness({ project: configuredProject }); @@ -695,12 +694,6 @@ describe("project dev harnesses", () => { configuredProject.legacy = { format: "v0", v0Spec: {} as never, - extras: { - abTests: [], - datasets: [], - capacityProviders: [], - unassignedTargets: [], - }, }; const subject = harness({ project: configuredProject }); @@ -710,12 +703,13 @@ describe("project dev harnesses", () => { { projectRoot: configuredProject.rootPath, target: "staging", + region: "us-west-2", yes: true, json: false, }, ]); expect(subject.deployments).toEqual([]); - expect(subject.io.stderr()).toContain("running AgentCore CLI 0.31.1 deploy"); + expect(subject.io.stderr()).toContain("running the latest v0 AgentCore CLI deploy"); }); test.each([