Generated banner for AWS Transform
Generated logo for AWS Transform

AWS Transform

AWS LabsOfficialPublished by AWS Labs

  • Skill
  • Workflow
  • Software development
  • Apache-2.0
  • Medium risk
  • Has scripts

From the author

Migrate, modernize, and upgrade codebases to AWS. Run analysis on repos for tech debt, security vulnerabilities, and modernization opportunities. Transforms .NET Framework to .NET 8/10, mainframe COBOL to Java, VMware VMs to EC2, SQL Server to Aurora, and upgrades Java/Python/Node.js versions and AWS SDKs. Use when the user says "migrate .NET to AWS", "upgrade Java to 17/21", "modernize COBOL", "modernize mainframe", "move VMware to EC2", "convert SQL Server to Aurora", "upgrade Python version", "migrate AWS SDK", "transform this codebase", "analyze for issues", "find tech debt", "what tech debt", "security vulnerabilities", "CVEs", "what's wrong with my code", "assess my repos", "where do I start", "find what's outdated", "analyze my repos", "AWS Transform - continuous modernization", "continuous modernization" or "continuous-modernization". Don't use for infrastructure provisioning, CI/CD pipelines, or general coding tasks.
— the description by AWS Labs

AutoGineer summary

Written by AutoGineer from the skill’s own files, not by the author

AWS Transform provides a structured approach to modernizing legacy applications and migrating them to AWS. It supports complex transformations such as .NET Framework to .NET 8/10, mainframe COBOL to Java, and database migrations to Aurora. The skill orchestrates the entire lifecycle from discovery and assessment to planning and execution, utilizing both MCP-based agents and the AWS Transform CLI for continuous modernization analysis.

What it does

  • Analyzes repositories for tech debt, security vulnerabilities, and modernization opportunities.
  • Transforms legacy codebases including .NET Framework, COBOL, and various database engines.
  • Upgrades language versions and AWS SDKs to modern standards.
  • Orchestrates migration workflows through discovery, assessment, and execution phases.
  • Provides continuous modernization analysis via the AWS Transform CLI.
  • Supports remote execution modes including AWS-managed, EC2, and Batch.

When to use it

  • When migrating legacy applications like .NET or mainframe systems to AWS.
  • When you need to assess a codebase for security vulnerabilities or technical debt.
  • When upgrading outdated language versions or AWS SDKs.
  • When converting database platforms like SQL Server to Amazon Aurora.
  • When you require a continuous, automated approach to monitoring modernization readiness.

Advantages

  • Provides a standardized, repeatable workflow for complex migrations.
  • Reduces manual effort in identifying and remediating technical debt.
  • Supports diverse migration paths from legacy infrastructure to modern AWS services.
  • Offers flexible execution modes including fully managed options with no infrastructure overhead.
  • Integrates deep analysis capabilities directly into the development lifecycle.

Usage examples

“Migrate my .NET Framework application to .NET 8.”
The agent will initiate the discovery and assessment phase to scope the migration and generate a modernization plan.
“Analyze my repository for security vulnerabilities and tech debt.”
The agent will route to the continuous modernization analysis tool to scan the codebase and report findings.
“Convert my SQL Server database to Aurora.”
The agent will guide you through the database migration workflow, starting with an assessment of your current schema.
“Modernize my mainframe COBOL code to Java.”
The agent will begin the discovery process to evaluate the mainframe workload and prepare for transformation.

Install

  1. Download the skill as a ZIP:

    https://autogineer.com/agent-skills/awslabs/aws-transform/download
  2. Unzip it into the cross-client skills folder of your project:

    mkdir -p .agents/skills && unzip aws-transform.zip -d .agents/skills

Documentation by AWS Labs

AWS Transform

CRITICAL: Route Before Anything Else

STOP. Before reading files, analyzing code, or starting any workflow, identify the workload first, then route.

Step A: Identify the workload

Look for an explicit workload signal in the user's request — a named technology (.NET, VMware, SQL Server/Aurora/Oracle/MySQL, mainframe/COBOL), workload-specific terminology (Hyper-V, EC2 rehost, stored procs, CICS, JCL), or file/project signals already in the conversation. If no signal is present, treat the request as workload-unspecified.

Step B: Apply workload-specific routing

Workload-specific rules ALWAYS win over the keyword list in Step C. Do not let "analysis" or "tech debt" phrasing override these.

WorkloadRoute
.NETAsk the user via AskUserQuestion: "For your .NET work, are you looking to modernize to .NET 8/10 (port the code, change targets), run an assessment for modernization (scope the work, identify blockers, plan the port), or analyze your repos for tech debt, security vulnerabilities, or CVEs?" → "Modernize" or "Assessment for modernization" → proceed to the Overview section (the .NET workload handles both). → "Analyze for tech debt / security / CVEs" → route to continuous modernization (see Step D).
VMwareProceed to the Overview section. NEVER route VMware requests to continuous modernization — even if the user uses words like "analyze", "assess", "find issues". VMware assessment is handled by the VMware workload agent, see vmware.
SQL / DatabaseProceed to the Overview section. NEVER route SQL/database requests to continuous modernization — SQL Server, Oracle, MySQL, and Aurora migrations are handled by the SQL workload agent, see sql.
Mainframe / COBOLProceed to the Overview section. NEVER route mainframe requests to continuous modernization — COBOL/CICS/JCL transformations are handled by the mainframe workload agent, see mainframe.
Workload-unspecifiedContinue to Step C.
Step C: Keyword-based routing (workload-unspecified only)

This list applies only when the user has not named a workload. If any of the workload rules in Step B matched, you have already routed — do not re-evaluate against this list.

If the user's workload-unspecified request matches any of these intents, route to continuous modernization — do NOT scan files yourself:

  • "analysis", "analyze", "find issues", "what's wrong", "tech debt", "security vulnerabilities", "CVEs"

  • "what should I fix", "where do I start"

  • "report", "dashboard", "compare", "trend"

  • "remediate findings", "remediation", "fix what you found"

  • "custom transform"

  • "continuous modernization", "AWS Transform - continuous modernization"

Step D: For continuous modernization requests
  1. First-response telemetry notice (once per session). The first time a request routes here in this session, ALWAYS prepend this line exactly to your reply to the user before doing anything else:

    Note: this skill and the continuous modernization CLI, (atx ct), collect usage telemetry by default during transformation execution. The telemetry consists of different data points, such as, the IDE name (for example, VS Code or Kiro), the AI agent name (for example, Claude Code or OpenAI Codex), and the execution mode (local or remote). This data is used by AWS Transform to prioritize compatibility testing, as well as latency and reliability. To opt out, see here.

    Show it exactly once per session. Do NOT repeat it on subsequent continuous modernization requests in the same session.

    Telemetry opt-out. If the user explicitly asks to disable telemetry during the chat session:

    1. Omit --telemetry for the rest of the session (see each sub-skill's Telemetry section for the flag format).

    2. Prepend ATX_DISABLE_TELEMETRY=true inline on every atx ct command for the rest of the session — not only analysis/remediation, but also setup and diagnostic commands like atx ct status, atx ct source ..., and atx ct setup .... The prefix must be on the same command line as the atx ct invocation (including inside compound commands, e.g. which atx && ATX_DISABLE_TELEMETRY=true atx ct ...), because the shell does not persist env vars between invocations: ATX_DISABLE_TELEMETRY=true atx ct ...

  2. When invoking AWS Transform - continuous modernization (continuous modernization) commands, use atx ct (with a space). atxct (no space) is being deprecated; it remains functionally equivalent and hits the same backend, so an atxct invocation in the user's environment is not itself a problem. Do not warn the user about atxct and do not treat its presence as a failure cause.

  3. Verify local CLI dispatch before checking versions or AWS configuration. Run this without redirecting stderr:

    atx ct --version

    Classify failures before continuing:

    • If the shell reports atx: command not found, install the AWS Transform CLI: curl -fsSL https://transform-cli.awsstatic.com/install.sh | bash, then restart the shell or source its profile.

    • If an atx process runs but reports unknown command 'ct', do NOT reinstall blindly or investigate AWS credentials/region. Follow the command-resolution troubleshooting first.

    • If the command succeeds, continue with the version comparison.

  4. Check whether the working CLI is up to date:

    INSTALLED=$(atx ct --version | head -1); LATEST=$(curl -fsSL "https://transform-cli.awsstatic.com/index.json" 2>/dev/null | grep -o '"latest"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/.*"latest"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/'); echo "Installed: ${INSTALLED:-not found}, Latest: ${LATEST:-unknown}"

    If LATEST is known and newer than INSTALLED, update with curl -fsSL https://transform-cli.awsstatic.com/install.sh | bash, then restart the shell or source its profile.

  5. Credential preflight. Validate AWS credentials before starting any analysis or remediation — at minimum on the first continuous modernization request of the session (new or returning users), and again before any later run in a long session, since credentials can lapse mid-session:

    aws sts get-caller-identity

    If it fails or the credentials are expired, refresh them before continuing. Do NOT start any long-running work on expired or soon-to-expire credentials — an analysis started on credentials about to expire can strand the run mid-flight. Run the preflight silently; surface it to the user only if the credentials need refreshing.

  6. If local atx ct dispatch succeeded but a later command fails, then check runtime configuration:

    • AWS_PROFILE points at a valid account with refreshed credentials

    • AWS_REGION is set to a supported region

    • ATX_CUSTOM_ENDPOINT is set in the environment (only if you use a custom endpoint)

    An unknown command 'ct' failure is a local command-resolution problem, not an AWS configuration problem; return to Step 3 instead.

  7. Ensure a supported region has been selected (see continuous-modernization-setup.md "Choose your region") and prefixed inline (AWS_REGION=$ATX_REGION) on every atx ct command.

  8. Then use the appropriate continuous modernization skill — see continuous-modernization. Recurring/scheduled intent ("weekly scan", "every Monday", "on a schedule", "cron") routes to continuous-modernization-schedule: scheduling is a real, shipped capability (atx ct schedule create/list/get/enable/disable/delete) that runs remotely ONLY — either an EventBridge schedule on the customer's EC2/Batch stack, or an AWS-managed server-side schedule (--mode aws-managed, no customer infrastructure). For recurring intent with no infrastructure ("no infra", "don't want to manage/provision anything"), the answer is atx ct schedule create --mode aws-managed --execution-role <arn> (server-side, nothing to provision) — offer this; do NOT tell the user that recurring analyses require deploying infrastructure. Never claim it doesn't exist, and never offer a local cron/systemd/launchd entry as a substitute or fallback.

    Remote analysis has THREE compute modes (atx ct remote analysis --mode <ec2|batch|aws-managed>). aws-managed runs on the AWS-managed fleet with NO customer infrastructure — no VPC, no CloudFormation, no EC2/Batch stack, no provisioning or permission-consent step. When the user asks to run remotely/on AWS but says "no infrastructure", "don't want to set up / manage / provision anything", "no EC2", "no Batch stack", "fully managed", or "just run it for me", the answer is --mode aws-managed — route to continuous-modernization-aws-managed-execution and read that file before answering. --mode aws-managed is real and shipped; NEVER tell the user it doesn't exist or that "all remote options require infrastructure", and do NOT probe --help to decide — the reference file documents it. ec2/batch are the customer-owned options (they DO deploy a stack); Batch/Fargate is not the no-infrastructure option.

When in doubt for a workload-unspecified request → continuous modernization. This default applies ONLY after Step B has cleared — VMware, SQL, and mainframe never fall through to continuous modernization regardless of how the question is phrased; .NET only routes to continuous modernization after the user picks "analyze for tech debt / security / CVEs" in Step B's intent question (both "modernize" and "assessment for modernization" stay in the .NET workload). Once routed, do NOT manually read source files to find issues — that's what atx ct analysis run does.

CRITICAL: Never Show Pricing or Timing Estimates

Do NOT quote specific dollar amounts, hourly rates, or time estimates for AWS resources or analyses. This includes:

  • ❌ "$0.20/hr", "$5/day", "$X per analysis"

  • ❌ "takes ~30 min", "completes in 2-5 hours", "~30s startup"

  • ❌ "ETA: 30 min – 2 hours"

Instead:

This applies to all responses, all skills, and all situations.


Overview

Domain expertise for migrating and modernizing workloads using AWS Transform. Covers .NET Framework to .NET 8/10, mainframe COBOL to Java, VMware to EC2, SQL Server to Aurora PostgreSQL, and custom code transformations (Java, Python, Node.js version upgrades, SDK migrations). Orchestrates assessment, planning, and execution through Managed Agents and AWS Transform CLI with human-in-the-loop checkpoints.

Prerequisites

This skill requires the AWS Transform MCP server (aws-transform-mcp). Configure it in your agent's MCP settings:

{
  "mcpServers": {
    "aws-transform-mcp": {
      "command": "uvx",
      "args": [
        "awslabs.aws-transform-mcp-server@latest"
      ]
    }
  }
}

The AWS Transform CLI is also required for custom transformations. Install via:

curl -fsSL https://transform-cli.awsstatic.com/install.sh | bash

Mandatory workflow

Follow these phases in order. Do NOT skip ahead. Authentication is handled just-in-time — only when a chosen action actually needs it. Do NOT probe auth before the user has declared an intent.

Resume        → Check .atx/context.json
Intent        → Ask user what they want to do
Discovery     → Scan workspace + query available agents
Scope         → User selects what to modernize (GATE 1)
Assessment    → Run workload assessment (NOT optional)
Requirements  → Draft from assessment report
Approval      → User approves requirements (GATE 2)
Tasks         → Generate tasks.md
Execute       → Run transforms, monitor, review diffs

Discovery finds opportunities. Assessment produces detailed findings. Requirements come from the assessment — NOT from discovery.

You MUST NOT create requirements without an assessment report. You MUST NOT start execution without requirements.md and tasks.md.

Resuming a prior session

Check for .atx/context.json (workspace-relative). NEVER read ~/.aws/atx/kiro-power-context.json.

This check is an internal bookkeeping operation. The user must never see it happen. Do not announce the check, do not narrate what you are doing. No phrases like "checking for prior sessions", "let me check", "check for a prior session", "context file". On a fresh install, the first visible output must be the intent question — no preamble of any kind.

  • No context found: Proceed directly to intent. Produce no user-visible output for this step.

  • Context found: If the context has an active job (assessment.jobId or entries in execution.activeJobIds), try to refresh live state from the service, but do so invisibly:

    • Check auth first (no-auth-required). If sign-in is NOT configured, skip the refresh entirely — do not attempt service calls. Use local context only.

    • If sign-in is configured, fetch each resource your resume message depends on — at minimum the job itself and all pending user tasks. Surface every pending task to the user; do not cherry-pick one and omit the others. BLOCKING HITL tasks hold up progress even when the job status is active; NON_BLOCKING tasks still need attention but don't stall the job. Name every pending task; flag blocking ones. Don't infer one resource from another.

    • If any call fails for any reason, silently fall back to local context. Do NOT reveal your reasoning about the refresh to the user — no "sign-in isn't configured so I'll skip", no "the service isn't reachable". The user should see only the resume message. Do NOT demand auth or block the flow.

    Then tell the user about their prior session. Frame the offer explicitly as a continuation of that same session — not a new one. The message should make clear:

    • This is the specific session they previously worked on. Mention the phase reached, workspace/job identifiers if relevant.

    • Refresh succeeded → speak in present tense about live state ("your assessment job is running", "I need your input on X to continue"). If there is a pending HITL task, surface it — don't bury it under "your job is running."

    • Refresh failed or was skipped → use prior-session framing: "last time", "when you paused", "previously", "your last session had finished assessment." Do NOT present-tense claims about job state — local context may be stale. Offer sign-in as the path to current status ("sign in to see the latest status"), not as a gate.

    • Resume = continue where you left off, reusing the existing assessment report, workspace, and prior progress.

    • Start fresh = discard the prior session (local artifacts deleted) and begin a brand-new migration.

    Use language like "continue where you left off" or "pick up from where you stopped" — not ambiguous phrasing like "start a similar session." If user chooses start fresh, delete .atx/context.json, .atx/discovery.json, .atx/assessment-report/, and .atx/specs/, then proceed to intent. Otherwise follow the resume logic in workflow reference.

Determining user intent

If Step A/B routed the request to continuous modernization, skip this entire section. continuous modernization has its own self-contained onboarding flow — hand off directly to continuous-modernization-guide. Its own first prompt (Mode selection: Local vs. AWS Infrastructure) is the user's first visible question. Do NOT show the generic intent menu first, and do NOT mix in non-continuous modernization options like "Browse My Jobs" or "Start a Specific Transform" — those are AWS Transform top-level capabilities, not continuous modernization features.

For every other route — VMware, SQL, Mainframe, and .NET (modernize or assessment-for-modernization) — use the generic intent menu below. The menu's options (Discover Workspace, Browse Jobs, Start Specific Transform, Analyze for findings) are how those workloads enter the standard MANDATORY workflow's Discovery → Scope → Assessment phases.

Generic intent menu

Ask the user: "What would you like to focus on?" The first user-visible action in this phase is the question — no auth-probing tool calls precede it, no auth lecture precedes it.

With projects: [Discover This Workspace] [Browse My Jobs] [Start a Specific Transform] [Analyze for findings] No projects: [Browse My Jobs] [Open a Project Folder] [Start from Scratch] [Analyze for findings]

Custom vs continuous modernization routing. When the user's intent is clear, route to the correct skill set using the decision table in continuous-modernization reference. Key rule: named transformation AND no prior continuous modernization findings → Custom. Analysis/reporting/remediation of existing findings → continuous modernization. When in doubt → continuous modernization.

Just-in-time auth. Once the user picks an intent, the next tool that action needs may require auth. If so, prompt for auth then, framed around the action the user just chose ("to browse your jobs, sign in to AWS Transform"). Which auth each MCP tool needs is reported by the MCP server — read it from the tool's description, get_status, or the error the tool returns. CLI transforms use AWS credentials only — do NOT prompt for sign-in for CLI-only intents, even when sign-in is unconfigured. If the user picks something that needs no service call (e.g., "Open a Project Folder"), do not probe auth.

See auth reference for the MCP-vs-CLI auth split and how to present sign-in options.

Discovery

Fast scan (~10 sec). Three things happen in parallel:

  1. Scan the workspace — detect languages, frameworks, file types, and dependencies present in the project.

  2. Query available agents — call list_resources with resource: "agents" (MCP). Skip if sign-in is not configured or the user's intent is CLI-only. This is a paginated API — fetch all pages to get the complete set. The results contain two levels:

    • Orchestrator agents — top-level agents you create jobs with. Each orchestrator may have sub-agents that provide deeper workload-specific capabilities.

    • Sub-agents — invoked through their orchestrator, not directly. They represent specialized skills within a workload type.

    • Some agents may not belong to a known orchestrator — treat these as standalone capabilities.

  3. List available transformation definitions — call atx custom def list (CLI) to get the current set and what they transform. Skip if CLI is not available or the user's intent is MCP-only.

For the "Discover This Workspace" intent, Discovery is where sign-in is first required (other intents like "Browse My Jobs" need sign-in even earlier, per the just-in-time rule — handle those there). If list_resources returns NOT_CONFIGURED, prompt the user to sign in for the auth system needed — do not demand both.

Then match workspace signals against orchestrator capabilities and available transformation definitions. Before selecting an orchestratorAgent for any workload, read the matched workload's reference file — it may specify the exact agent to use. Save the matched results to .atx/discovery.json — include the orchestrator → sub-agent hierarchy so later steps know what deeper capabilities are available.

See workflow reference for the workspace scanning framework.

Discovery is NOT assessment. Discovery identifies opportunities and matches them to available agents. Assessment produces the detailed findings.

Scoping (GATE 1)

For each matched workload type, read ALL reference files with its prefix (e.g., dotnet). These contain the workload's capabilities, workflow, agent details, example requirements, and known limitations. The file prefix comes from the agent match in Discovery — not from a hardcoded list.

Show migration table, then let the user select with multiSelect:

| Risk | Why | Component | Current | Target | AWS Target | Recommended Approach |

Always explain risk in plain language in the "Why" column — use the user-facing phrases from the Risk Classification table in workflow reference. Never show a bare HIGH/MED/LOW label without explanation.

User selects what to modernize.

Assessment

This is NOT optional. Run the workload's assessment BEFORE creating requirements.

Tell the user: "I'll assess your workload. The assessment report drives the migration plan."

How assessment runs depends on the workload's reference files. Each workload type defines its own assessment approach — the agent to use, the objective format, and how to collect results. Consult the matched workload's reference files for specifics.

General pattern for agent-based assessment:

  1. Confirm the plan — tell the user what you will do (create workspace, create job with which agent, what the objective is). WAIT for approval before calling any tools.

  2. Create/select workspace

  3. Create job with a clear objective — the workload's reference files define what a good objective looks like

  4. Start the job (already started by create_job; use control_job to restart if stopped)

  5. Send a detailed follow-up message with project specifics

  6. Ask before uploading — ask how the user wants to share source code. WAIT. Then upload with categoryType: "CUSTOMER_INPUT".

  7. Handle agent requests (checkpoints, decisions) — always present to user, WAIT for user response

  8. When assessment completes, download the report: get_resource resource="artifact"

  9. Save report to .atx/assessment-report/

Rule: NEVER batch workspace creation, job creation, and uploads into a single turn without user confirmation at each decision point.

Use the orchestrator agent or transformation definition identified during Discovery. The match comes from list_resources (with resource: "agents") and atx custom def list, not a hardcoded mapping. When creating a job, specify the orchestrator — sub-agents are invoked by the orchestrator as needed.

Update .atx/context.json with phase: "assessed", workspace ID, job ID.

Requirements (from assessment report)

Now create .atx/specs/requirements.md using the assessment report — NOT discovery findings.

  • Read .atx/assessment-report/ for detailed findings

  • Load workload reference files for context

  • Draft requirements grounded in the assessment (specific blockers, LOC, complexity, migration paths)

  • Each requirement says WHO handles it: AWS Transform CLI / Managed Agents / IDE

  • Multi-module: group by module with Module Overview table

  • See workflow reference for format

Do NOT create tasks.md yet.

Show requirements summary and let the user choose: [Looks Good] [Edit] [Add Component]

Approval (GATE 2)

Ask the user: "Requirements finalized. Ready to create the execution plan?" [Create Plan] [Edit More]

Task generation

Generate tasks.md from approved requirements:

  • Module Status table + per-module sections

  • Sized: max 100 files/task

  • Parallel groups verified

  • Review-diffs after every code change

  • See workflow reference for format

Present options: [Start Execution] [Review Tasks] [Modify]

Execution

See workflow reference for full details.

How execution runs depends on the workload's reference files. Each workload type defines its own execution tooling — which agent or CLI command to use, how to parallelize, and how to collect results. Consult the matched workload's reference files.

General pattern for agent-based execution:

When creating new jobs, always:

  1. Clear objective in create_job — what to transform, from what, to what

  2. Detailed follow-up message via send_message — project specifics, discovery findings, blockers

  3. Upload artifacts if agent needs code — ask user first, categoryType: "CUSTOMER_INPUT"

Every agent request → user decides (NEVER auto-handle)

When the AWS Transform agent asks for input, needs files, or hits a checkpoint:

  1. Read the task/message

  2. Present to user

  3. WAIT for user response

  4. Relay user's decision back to agent

Uploading artifacts to agents

Always use categoryType: "CUSTOMER_INPUT" when uploading files to an agent:

upload_artifact(
  workspaceId="...", jobId="...",
  content="/path/to/source.zip",
  fileType="ZIP",
  categoryType="CUSTOMER_INPUT"
)
categoryTypeWhen to Use
CUSTOMER_INPUTUploading files TO the agent (source code, configs, data)
CUSTOMER_OUTPUTDownloading files FROM the agent (reports, migrated code)
HITL_FROM_USERUser responses to agent HITL tasks

See workflow reference for agent request handling patterns.

Progress

Review diffs after every code change. User must approve. Update tasks.md checkboxes + .atx/context.json after every step.


Context persistence (.atx/context.json)

Save .atx/context.json IMMEDIATELY after completing each phase — before presenting results to the user. Every phase transition must have a context save between them. Top-level keys: phase, discovery, assessment, spec, workStyle, execution, updatedAt. See workflow reference for the full schema.

Resume: read phase, pick up from that phase.


Constraints

  • MUST use product, capability, and step names exactly as defined in this document. Never paraphrase or invent terminology. When describing this skill's capabilities, use: "Migrate, modernize, and upgrade codebases — .NET, mainframe COBOL, VMware, databases, and language/SDK upgrades — using AWS Transform CLI and Managed Agents, directly from your IDE."

  • MUST present user choices as an explicit selectable list — never bury options in prose or proceed on an inferred answer

  • MUST run CLI commands in background — never block the conversation

  • MUST discover agents dynamically via list_resources with resource: "agents" (paginated) — do not hardcode agent names

  • MUST create jobs with orchestrator agents — sub-agents are invoked by the orchestrator, not directly

  • MUST refer to resources by name, not ID. When referencing a workspace, job, agent, or artifact in user-facing messages, use its human-readable name. Never surface raw UUIDs in prose. If a resource has no name, use a descriptive phrase ("your .NET modernization job") rather than the ID.

  • MUST NOT expose internal mechanics to the user — do not name tools (get_status, list_resources), do not cite step numbers, do not reference files you are reading, and do not narrate what you are about to do. Just do it silently and present the outcome in user terms.

  • MUST NOT mix workflow descriptions with actual questions in the same numbered list, and never use count language like "two questions" when some items are informational steps rather than questions. Keep what-I-will-do separate from what-I-need-from-you.

  • MUST NOT frame HITL checkpoints, agent questions, or pending decisions as coming from "the web app", "the webapp", "the web UI", or a third-party "the agent is asking / the agent needs / the agent wants". The user is working with you in the IDE — you own the interaction. Present every checkpoint as your own first-person request, not a relayed message from elsewhere. Wrong: "The web app is asking how you want to deploy the landing zone." / "The agent is now asking about the replication subnet configuration." Right: "The next step is to choose how to deploy the landing zone." / "I need the replication subnet configuration to continue."

  • MUST NOT explain what this skill does

  • MUST NOT create requirements from discovery — wait for assessment

  • MUST NOT skip from discovery to execution

  • MUST NOT modify code, upgrade dependencies, or run analysis manually — always use AWS Transform tooling

  • MUST NOT probe --help to figure out a CLI invocation that the reference files already document. The capability-specific reference files in references/ (e.g. continuous-modernization-source.md, continuous-modernization-analysis.md, continuous-modernization-remediation.md, custom-cli-reference.md) contain the canonical atx ct … and atx custom … commands with every required flag and example invocations — read the matching file and lift the command verbatim. The orchestrating files (continuous-modernization-guide.md, continuous-modernization-setup.md) explicitly point at them ("Use the /source skill for the exact commands"). --help is a fallback used ONLY when (a) no reference file covers the capability, or (b) a documented command demonstrably fails because the installed CLI version diverges from the reference. Treat --help probes the user can see as a signal that the agent didn't read its own skill — that is the failure mode this rule prevents.

  • MUST NOT make decisions on behalf of the user

  • MUST NOT editorialize or use subjective language — no "interesting", "fascinating", "notably", "impressive", "remarkable". State findings as facts.

  • MUST NOT prompt for authentication before the user has declared an intent. Auth prompts come from the tool a chosen action needs, framed around that action.

  • MUST NOT overclaim freshness. If you did NOT fetch a resource this turn, lead with "last I checked" (past tense throughout) and offer to refresh. Never promise proactive surfacing ("I'll let you know when…") unless actively polling — make the reactive model explicit.

  • MUST NOT infer one resource's state from another — each MCP resource (job, tasks, artifacts) is its own source of truth. A job in an active state does NOT imply no pending user tasks. Fetch each resource directly when relevant. See workflow reference.

  • MUST NOT mix unrelated transformation goals in the same chat without warning. On every shift to a different goal, suggest the user start a new chat session (they start it themselves). Keep re-offers terse. If the user declines, proceed to answer their question about the other job — do not refuse or redirect back to the original goal. Just avoid mixing cached state (e.g., don't apply VMware findings to the .NET question).

  • MUST store state in .atx/context.json


Reference

Core
TopicFile
Authentication (sign-in, AWS credentials, CLI credentials, errors)references/auth.md
Tools (MCP tools, CLI commands, connectors, HITL, troubleshooting)references/tools.md
Workflow (discovery, transforms, execution, planning, context, display)references/workflow.md
Workload Types
WorkloadFiles
.NETreferences/dotnet*.md
SQL/Databasereferences/sql*.md
Mainframereferences/mainframe*.md
VMwarereferences/vmware*.md
continuous modernizationreferences/continuous-modernization*.md

Each workload type has a root reference file with its capabilities, workflow, and agent details. Additional files with the same prefix provide deeper guidance (e.g., continuous-modernization-setup.md, continuous-modernization-discovery.md).

Files

references/custom.md

AWS Transform custom

Table of Contents

  • Overview

  • Greeting

  • Usage

  • Core Concepts

  • Philosophy

  • Prerequisites

  • Workflow

  • Execution Modes

  • Critical Rules

  • Guardrails

  • Telemetry

  • Output Structure

  • References

  • License

  • Issues

  • Changelog

Overview

Perform code upgrades, migrations, and transformations using AWS Transform custom. Supports any-to-any transformations: language version upgrades (Java, Python, Node.js, etc.), framework migrations, AWS SDK migrations, library upgrades, code refactoring, architecture changes, and custom organization-specific transformations.

Two execution modes:

  • Local mode: Runs the AWS Transform CLI directly on the user's machine. Best for 1-9 repos.

  • Remote mode: Runs transformations at scale via AWS Batch/Fargate containers. Best for 10+ repos or when the user prefers cloud execution. Infrastructure is auto-deployed with user consent.

You handle the full workflow: inspecting repos, matching them to available transformation definitions, collecting configuration, and executing transformations in either mode — the user just provides repos and confirms the plan.

Greeting

"AWS Transform custom can help you:

  • Upgrade Java, Python, and Node.js to modern versions

  • Migrate AWS SDKs (Java SDK v1->v2, boto2->boto3, JS SDK v2->v3)

  • Handle framework migrations, library upgrades, and code refactoring

  • Analyze codebases and generate documentation

  • Define and run your own custom transformations using natural language, docs, and code samples

Run locally on a few repos for fast iteration, or at scale on hundreds of repos (up to 128 in-parallel). Note: this skill collects usage telemetry by default during transformation execution. The telemetry consists of different data points, such as, the IDE name (for example, VS Code or Kiro), the AI agent name (for example, Claude Code or OpenAI Codex), and the execution mode (local or remote). This data is used by AWS Transform to prioritize compatibility testing, as well as latency and reliability. To opt out, see here.

What would you like to transform today?"

Do NOT inspect any files, run any commands, or check prerequisites until the user responds.

Usage

Use when the user wants to:

  • Transform, upgrade, or migrate code (Java, Python, Node.js, etc.)

  • Migrate AWS SDKs (Java SDK v1->v2, boto2->boto3, JS SDK v2->v3, etc.)

  • Run bulk code transformations at scale via AWS Batch/Fargate

  • Analyze which AWS Transform transformations apply to their repositories

  • Perform comprehensive codebase analysis

  • Create a new custom Transformation definition

Core Concepts

  • Transformation definition: A reusable transformation recipe discovered via atx custom def list --json

  • Match Report: Auto-generated mapping of repos to applicable transformation definitions based on code inspection

  • Local Mode: Runs AWS Transform CLI on the user's machine (1-9 repos, max 3 concurrent)

  • Remote Mode: Runs transformations in AWS Batch/Fargate (10+ repos, or by preference)

Philosophy

Wait for the user. On activation, present what this skill can do and ask the user what they'd like to accomplish. Do NOT automatically inspect the working directory, open files, or any repository until the user explicitly provides repos to work with.

Once the user provides repositories, match — don't ask. Inspect those repositories and present which transformations apply automatically. Never show a raw transformation definition list and ask the user to pick.

Prerequisites

Prerequisite checks run ONCE at the start of a session. Do not repeat per repo. Do NOT run prerequisite checks until the user has stated what they want to do.

Platform Check (Required — All Modes)

Detect the user's operating system. If on Windows (not WSL), stop immediately and inform the user:

AWS Transform custom does not support native Windows. You need to install Windows Subsystem for Linux (WSL) and run this from within WSL.

Install WSL: wsl --install in PowerShell (as Administrator), then restart. After that, open a WSL terminal and re-run this skill from there.

Check by running:

uname -s
  • Linux or Darwin -> proceed normally

  • MINGW*, MSYS*, CYGWIN*, or any Windows-like output -> block and show the WSL message above

  • Command fails, errors, or is not found -> treat as native Windows, block and show the WSL message above

Do NOT proceed with any other steps on native Windows.

AWS CLI (Required — All Modes)
aws --version

If not installed, guide the user:

  • macOS: brew install awscli or curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" && sudo installer -pkg AWSCLIV2.pkg -target /

  • Linux: curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" && unzip awscliv2.zip && sudo ./aws/install

Do NOT proceed until aws --version succeeds.

AWS Credentials (Required — All Modes)
aws sts get-caller-identity

If credentials are NOT configured, walk the user through setup:

AWS Transform custom requires AWS credentials to authenticate with the service. Configure authentication using one of the following methods.

1. AWS CLI Configure (~/.aws/credentials):
   aws configure

2. AWS Credentials File (manual). Configure credentials in ~/.aws/credentials:

[default]
aws_access_key_id = your_access_key
aws_secret_access_key = your_secret_key

3. Environment Variables. Set the following environment variables:

export AWS_ACCESS_KEY_ID=your_access_key
export AWS_SECRET_ACCESS_KEY=your_secret_key
export AWS_SESSION_TOKEN=your_session_token

You can also specify a profile using the AWS_PROFILE environment variable:

export AWS_PROFILE=your_profile_name

Do NOT proceed until credentials are verified. Re-run aws sts get-caller-identity after setup.

Note: environment variables set via export do not carry over between shell sessions. If you spawn a new shell, credentials set as env vars may be lost. Prefer aws configure or ~/.aws/credentials for persistence.

AWS Transform CLI (Required — All Modes)

Required in all modes for transformation definition discovery (atx custom def list --json). Local mode also uses it for transformation execution.

atx --version
# Install: curl -fsSL https://transform-cli.awsstatic.com/install.sh | bash

Mandatory: always run atx update once at the start of every session, even if you just ran it recently. This catches new AWS Transform CLI versions and new transformation definitions. Run it before any other ATX command (including atx custom def list --json):

atx update

Do NOT skip this step. Do NOT ask the user whether to update. Do NOT condition it on whether the CLI "needs" an update. Run it unconditionally.

IAM Permissions (Required — All Modes)

Local mode requires transform-custom:* minimum. Verify by running a transformation definition list:

atx custom def list --json

If this succeeds, permissions are sufficient — skip the rest of this section.

If it fails with a permissions error, the caller needs the transform-custom:* IAM permission. Explain to the user what's needed and get confirmation before proceeding:

Your identity needs the transform-custom:* permission to use the AWS Transform CLI. I can attach the AWS-managed policy AWSTransformCustomFullAccess to your identity. Shall I proceed?

Only after the user confirms, attach the managed policy:

CALLER_ARN=$(aws sts get-caller-identity --query Arn --output text)
if echo "$CALLER_ARN" | grep -q ":user/"; then
  IDENTITY_NAME=$(echo "$CALLER_ARN" | awk -F'/' '{print $NF}')
  aws iam attach-user-policy --user-name "$IDENTITY_NAME" \
    --policy-arn "arn:aws:iam::aws:policy/AWSTransformCustomFullAccess"
elif echo "$CALLER_ARN" | grep -Eq ":assumed-role/|:role/"; then
  ROLE_NAME=$(echo "$CALLER_ARN" | sed 's/.*:\(assumed-\)\{0,1\}role\///' | cut -d'/' -f1)
  aws iam attach-role-policy --role-name "$ROLE_NAME" \
    --policy-arn "arn:aws:iam::aws:policy/AWSTransformCustomFullAccess"
fi

If the attachment command itself fails (e.g., insufficient IAM permissions, or an SSO-managed role), inform the user they need to ask their AWS administrator to attach the AWSTransformCustomFullAccess AWS-managed policy to their identity. For SSO users (role names starting with AWSReservedSSO_), this must be added to their IAM Identity Center permission set — it cannot be attached directly.

Do NOT proceed until atx custom def list --json succeeds.

Remote mode requires additional permissions (Lambda invoke, S3, KMS, Secrets Manager, CloudWatch). These are generated and attached as part of the deployment flow — see custom-remote-execution.

See custom-cli-reference for the full permission list.

AWS CDK (Remote Mode Only)

Required for deploying remote infrastructure. Check if installed:

cdk --version

If not installed, install it globally:

npm install -g aws-cdk

Do NOT proceed with remote deployment until cdk --version succeeds.

Remote Infrastructure (Remote Mode Only — Deferred)

Only verify if user chooses remote mode. The infrastructure CDK scripts are fetched at runtime by cloning https://github.com/aws-samples/aws-transform-custom-samples.git (branch atx-remote-infra) — they are not bundled with this skill. See custom-remote-execution.

Workflow

Generate a session timestamp once and reuse it for all paths in this session:

SESSION_TS=$(date +%Y%m%d-%H%M%S)
Collect Repositories

Ask the user for local paths or git URLs. Accept one or many. Do NOT assume the current working directory or open editor files are the target — wait for the user to explicitly provide repositories.

Accepted source formats:

  • Local paths — directories on the user's machine (e.g., /home/user/my-project)

  • HTTPS git URLs — public or private (e.g., https://github.com/org/repo.git)

  • SSH git URLs — e.g., [email protected]:org/repo.git

  • S3 bucket path with zips — e.g., s3://my-bucket/repos/ containing zip files of repositories. Each zip becomes one transformation job.

S3 Bucket Input

If the user provides an S3 path containing zip files, ask which execution mode they prefer (if not already specified). S3 input works in both modes:

Remote mode: Copy the zips from the user's bucket to the managed source bucket, then submit jobs pointing to the managed copies:

ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)
SOURCE_BUCKET="atx-source-code-${ACCOUNT_ID}"

# List all zips in the user's bucket path
aws s3 ls s3://user-bucket/repos/ --recursive | grep '\.zip$'

# Copy each zip to the managed source bucket
aws s3 sync s3://user-bucket/repos/ s3://${SOURCE_BUCKET}/repos/ --exclude "*" --include "*.zip"

Then submit a batch job with one job per zip, each pointing to s3://${SOURCE_BUCKET}/repos/<filename>.zip. The container handles zip extraction automatically. See custom-multi-transformation for batch submission. The managed source bucket has a 7-day lifecycle — copied zips auto-delete.

Local mode: Download and extract each zip locally:

mkdir -p ~/.aws/atx/custom/atx-agent-session/repos
aws s3 sync s3://user-bucket/repos/ ~/.aws/atx/custom/atx-agent-session/repos/ --exclude "*" --include "*.zip"
for zip in ~/.aws/atx/custom/atx-agent-session/repos/*.zip; do
  name=$(basename "$zip" .zip)
  unzip -qo "$zip" -d "$HOME/.aws/atx/custom/atx-agent-session/repos/${name}-$SESSION_TS/"
done

Use the extracted directories as <repo-path> for local execution. Standard local mode limits apply (max 3 concurrent repos).

Private Repository Detection (Remote Mode)

Always ask the user — do NOT try to determine repo visibility yourself. Never attempt to clone, curl, or probe a URL to check if it's public or private. Simply ask the user. As soon as the user provides git URLs and remote mode is selected (or likely), ask:

"Are any of these repositories private? If so, the remote container needs credentials to clone them — I'll walk you through the setup."

Do NOT skip this question. Do NOT try to infer visibility by attempting a clone, curl, or any other network request. Just ask.

If the user confirms repos are private, determine the credential type based on URL format:

First, resolve the region (use for all Secrets Manager commands below):

REGION=${AWS_REGION:-${AWS_DEFAULT_REGION:-$(aws configure get region 2>/dev/null)}}
REGION=${REGION:-us-east-1}

For HTTPS URLs — check whether a GitHub PAT is already configured:

aws secretsmanager describe-secret --secret-id "atx/github-token" --region "$REGION" 2>/dev/null \
  && echo "CONFIGURED" || echo "NOT_CONFIGURED"

If CONFIGURED, ask the user: "A GitHub PAT is already stored. Would you like to keep using it, or replace it with a new one?" If they want to replace it, tell them to run:

aws secretsmanager put-secret-value --secret-id "atx/github-token" --region "$REGION" --secret-string "YOUR_TOKEN_HERE"

If NOT_CONFIGURED, explain what's needed and tell the user to run the create command:

"Private HTTPS repos need a GitHub Personal Access Token (PAT) stored in AWS Secrets Manager. The remote container fetches it at startup to clone your repos. The token stays in your AWS account — you can delete it anytime.

The PAT needs the repo scope for private repositories. Create one at https://github.com/settings/tokens and then run:

aws secretsmanager create-secret --name "atx/github-token" --region "$REGION" --secret-string "YOUR_TOKEN_HERE"

Delete anytime: aws secretsmanager delete-secret --secret-id atx/github-token --region "$REGION" --force-delete-without-recovery"

Do NOT ask the user to paste their token in chat, or ask them to confirm or repeat the token value in any way. They run the command themselves. Wait for the user to confirm it's done, then verify:

aws secretsmanager describe-secret --secret-id "atx/github-token" --region "$REGION" 2>/dev/null \
  && echo "CONFIGURED" || echo "NOT_CONFIGURED"

For SSH URLs (git@... or ssh://...) — check whether an SSH key is configured:

aws secretsmanager describe-secret --secret-id "atx/ssh-key" --region "$REGION" 2>/dev/null \
  && echo "CONFIGURED" || echo "NOT_CONFIGURED"

If CONFIGURED, ask the user: "An SSH key is already stored. Would you like to keep using it, or replace it with a new one?" If they want to replace it, tell them to run:

aws secretsmanager put-secret-value --secret-id "atx/ssh-key" --region "$REGION" --secret-string "$(cat <path-to-your-private-key>)"

If NOT_CONFIGURED, explain what's needed and tell the user to run the create command:

"SSH repos need an SSH private key stored in AWS Secrets Manager. The remote container fetches it at startup to clone your repos.

Run:

aws secretsmanager create-secret --name "atx/ssh-key" --region "$REGION" --secret-string "$(cat <path-to-your-private-key>)"

Delete anytime: aws secretsmanager delete-secret --secret-id atx/ssh-key --region "$REGION" --force-delete-without-recovery"

Do NOT ask the user to paste their SSH key in chat. They run the command themselves.

For local mode, private repo credentials are not needed — the user's local git config handles authentication. Skip this check entirely for local mode.

Discover Transformation Definitions (Silent)

Run silently — do NOT show output to user:

atx custom def list --json

Inspect the JSON output directly to build an internal lookup of available transformation definitions. Do NOT pipe the output to python, jq, or other parsing scripts — read the JSON yourself. Never hardcode transformation definition names.

Creating a New Transformation Definition

User explicitly asks to create a transformation definition, or no existing transformation definition matches the user's goal:

If no match, confirm with the user first:

"I didn't find an existing transformation definition that covers [describe the user's goal]. Would you like to create a new one?"

If the user confirms (or explicitly asked), open a terminal and launch atx -t for them:

atx -t

Run this in a new terminal so the user can interact with it directly. Then tell the user:

"I've opened a terminal with atx -t — describe the transformation you want to build (e.g., 'migrate log4j to SLF4J') and AWS Transform will walk you through it. Come back here once it's published and I'll pick it up automatically."

After the user returns, re-run atx custom def list --json to pick up the newly published transformation definition and continue with the normal workflow.

Inspect Each Repository

Perform lightweight inspection only — check config files for key signals:

SignalFiles to CheckLikely Transformation Type
Python version.python-version, pyproject.toml, setup.cfg, requirements.txtPython version upgrade
Java versionpom.xml (<java.version>), build.gradle (sourceCompatibility), .java-versionJava version upgrade
Node.js versionpackage.json (engines.node), .nvmrc, .node-versionNode.js version upgrade
Python boto2import boto (NOT boto3)boto2->boto3 migration
Java SDK v1com.amazonaws imports, aws-java-sdk in pom.xmlJava SDK v1->v2
Node.js SDK v2"aws-sdk" in package.json (NOT @aws-sdk)JS SDK v2->v3
x86 Javax86_64/amd64 in Dockerfiles, build configsGraviton migration

Cross-reference detected signals against transformation definitions from the discovery step. Only match transformation definitions that actually exist in the user's account.

See custom-repo-analysis for full detection commands.

Present Match Report

Format:

Transformation Match Report
=============================
Repository: <name> (<path>)
  Language: <lang> <version>
  Matching transformation definitions:
    - <td-name> — <description>

Summary: N repos analyzed, M have applicable transformations (T total jobs)

Present the match report and wait for user confirmation before proceeding. Do NOT start any transformation without explicit user consent.

Collect Configuration

Ask the user for any additional plan context (e.g., target version for upgrade transformation definitions). This is mandatory — always ask, even if the transformation definition doesn't strictly require config. The user may have preferences or constraints you don't know about. Skip only if the user explicitly says no additional context is needed.

Verify Runtime Compatibility (Remote and Local)
Remote Mode

Infrastructure check: To verify whether remote infrastructure is deployed, use CloudFormation — do NOT check individual Lambda functions by name:

aws cloudformation describe-stacks --stack-name AtxInfrastructureStack \
  --query 'Stacks[0].StackStatus' --output text || echo "NOT_DEPLOYED"

Before submitting remote jobs, determine whether the pre-built image covers the target runtime or if a custom Docker build is needed.

Pre-built image includes:

  • Java: 8, 11, 17, 21, 25 (Amazon Corretto) with Maven and Gradle 9.4

  • Python: 3.8, 3.9, 3.10, 3.11, 3.12, 3.13, 3.14 (dnf + pyenv)

  • Node.js: 16, 18, 20, 22, 24 (nvm) with yarn, pnpm, TypeScript, ts-node

  • Build tools: gcc, g++, make, patch

  • CLI tools: AWS CLI v2, AWS Transform CLI, git, jq, curl, unzip, tar

  • OS: Amazon Linux 2023 (x86_64)

Decision logic:

  1. Based on the transformation requirements (source runtime, target runtime, build tools, and any other dependencies), determine whether everything needed is available in the pre-built image listed above

  2. If yes -> use the pre-built image path (no Docker required). Proceed to deployment using the pre-built image instructions in custom-remote-execution.

  3. If no -> use the custom image path (Docker required). Inform the user:

The remote container doesn't include [language/tool version]. To run this transformation remotely, I'll need to build a custom container image. This requires Docker installed and running on your machine. It's a one-time change — about 5-10 minutes. Want me to proceed?

If the user confirms, follow the custom image path in custom-remote-execution: clear prebuiltImageUri, customize the Dockerfile, and deploy.

If the user declines, suggest local mode as an alternative (if the tools are available on their machine).

Dockerfile customization (custom image path only):

First, read the Dockerfile to see what's installed:

ATX_INFRA_DIR="$HOME/.aws/atx/custom/remote-infra"
cat "$ATX_INFRA_DIR/container/Dockerfile" 2>/dev/null
  1. Ensure the infrastructure repo is cloned and up to date:

    ATX_INFRA_DIR="$HOME/.aws/atx/custom/remote-infra"
    if [ -d "$ATX_INFRA_DIR" ]; then
      git -C "$ATX_INFRA_DIR" add -A
      git -C "$ATX_INFRA_DIR" commit -m "Local customizations" -q 2>/dev/null || true
      git -C "$ATX_INFRA_DIR" pull -q
    else
      git clone -b atx-remote-infra --single-branch https://github.com/aws-samples/aws-transform-custom-samples.git "$ATX_INFRA_DIR"
    fi

    If git pull reports a merge conflict, resolve it by keeping both upstream changes and the user's customizations in the CUSTOM LANGUAGES AND TOOLS section of the Dockerfile, then commit the merge.

  2. Edit $ATX_INFRA_DIR/container/Dockerfile. Find the section marked # CUSTOM LANGUAGES AND TOOLS and insert RUN commands after the comment block, before the USER root line.

    For missing versions of already-installed languages, add the version in the custom section. Examples:

    # Java 23 (Amazon Corretto — direct install, must run as root)
    # Do NOT use dnf in the custom section — pyenv overrides the system python3
    # that dnf depends on, causing "No module named 'dnf'" errors.
    USER root
    RUN curl -fsSL "https://corretto.aws/downloads/latest/amazon-corretto-23-x64-linux-jdk.tar.gz" -o /tmp/corretto23.tar.gz && \
        mkdir -p /usr/lib/jvm && \
        tar -xzf /tmp/corretto23.tar.gz -C /usr/lib/jvm && \
        rm /tmp/corretto23.tar.gz && \
        ln -sfn /usr/lib/jvm/amazon-corretto-23.* /usr/lib/jvm/corretto-23
    
    # Node.js 23 (via nvm — must run as atxuser)
    USER atxuser
    RUN . /home/atxuser/.nvm/nvm.sh && nvm install 23
    USER root
    
    # Python 3.15 (via pyenv — must run as atxuser)
    USER atxuser
    RUN eval "$(/home/atxuser/.pyenv/bin/pyenv init -)" && \
        MAKE_OPTS="-j$(nproc)" /home/atxuser/.pyenv/bin/pyenv install 3.15.0
    USER root

    For entirely new languages, avoid dnf in the custom section — pyenv overrides the system python3 that dnf depends on. Use language-specific installers instead:

    # Go
    RUN curl -fsSL https://go.dev/dl/go1.22.0.linux-amd64.tar.gz | tar -C /usr/local -xz
    ENV PATH="/usr/local/go/bin:$PATH"
    
    # Ruby (via rbenv — must run as atxuser)
    USER atxuser
    RUN git clone --depth 1 https://github.com/rbenv/rbenv.git /home/atxuser/.rbenv && \
        git clone --depth 1 https://github.com/rbenv/ruby-build.git /home/atxuser/.rbenv/plugins/ruby-build && \
        /home/atxuser/.rbenv/bin/rbenv install 3.3.0 && \
        /home/atxuser/.rbenv/bin/rbenv global 3.3.0
    ENV PATH="/home/atxuser/.rbenv/shims:/home/atxuser/.rbenv/bin:$PATH"
    USER root
    
    # Rust
    USER atxuser
    RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
    ENV PATH="/home/atxuser/.cargo/bin:$PATH"
    USER root
  3. Update the version switcher in $ATX_INFRA_DIR/container/entrypoint.sh. Find the relevant switch_*_version function and add a case for the new version. For Java versions installed via direct download, find the extracted directory name under /usr/lib/jvm/. For example, to add Java 23:

    # In switch_java_version(), add to the case statement:
    23) java_home="/usr/lib/jvm/corretto-23" ;;

    Check the actual directory name: ls /usr/lib/jvm/ — use the directory that matches the version you installed.

    For Node.js, nvm handles arbitrary versions automatically — no entrypoint change needed. For Python, pyenv handles arbitrary versions — no entrypoint change needed (the existing pyenv fallback logic finds it).

  4. Deploy (or redeploy): cd "$ATX_INFRA_DIR" && ./setup.sh CDK hashes the container/ directory — any file change triggers a rebuild and push to ECR automatically.

After redeployment, set the environment field on the job to the exact target version (e.g., "JAVA_VERSION":"23", not "21"). The version switcher in the entrypoint reads this and activates the correct runtime.

If the user declines, suggest local mode as an alternative (if the tools are available on their machine).

Local Mode

Before running local transformations, verify the user has the target runtime version installed. This applies to any language or runtime the transformation targets — Java, Python, Node.js, Ruby, Go, Rust, .NET, etc. Check the current version of whatever runtime the transformation definition requires. For example:

java -version    # Java transformations
python3 --version # Python transformations
node --version   # Node.js transformations
ruby --version   # Ruby transformations
go version       # Go transformations

If the target version is not active, check whether it's already installed:

# Java: check common install locations
/usr/libexec/java_home -V 2>&1          # macOS
ls /usr/lib/jvm/ 2>/dev/null            # Linux
# Python: check if the specific version binary exists
which python3.12 2>/dev/null            # adjust version as needed
# Node.js: check if nvm is available, or look for the binary
command -v nvm &>/dev/null && nvm ls 2>/dev/null
which node 2>/dev/null && node --version

If the target version is found, switch to it:

  • Java: export JAVA_HOME=<path to JDK> && export PATH="$JAVA_HOME/bin:$PATH"

  • Python: pyenv shell 3.15.0

  • Node.js: nvm use 23

Only if the target version is not installed at all, ask the user for permission before installing. Do NOT install runtimes without explicit user confirmation. Suggest the appropriate version manager:

  • Java: brew install --cask corretto23 (macOS), sudo yum install java-23-amazon-corretto-devel (RHEL/AL2), or sudo apt install java-23-amazon-corretto-jdk (Debian/Ubuntu)

  • Python: pyenv install 3.15.0 && pyenv shell 3.15.0, or brew install [email protected]

  • Node.js: nvm install 23 && nvm use 23

The active runtime must match the transformation's target version so that builds and tests run correctly. Do NOT proceed with the transformation until the correct version is active.

Confirm Transformation Plan

Present final plan with repo, transformation definition, config, and execution mode. Do NOT proceed until user confirms.

Execute

Execution Modes

ModeBest ForPrerequisites
Local (default for 1-9 repos)Quick transforms, dev machines with ATXAWS Transform CLI installed
Remote (recommended for 10+ repos)Bulk transforms, up to 512 repos (128 concurrent per batch)AWS account, auto-deployed infra

Mode inference:

  • User says "local"/"here"/"on my machine" -> Local (honor the request regardless of repo count)

  • User says "remote"/"cloud"/"AWS"/"batch"/"at scale" -> Remote

  • 10+ repos without preference -> Recommend remote, explain local cap recommendation of 3 concurrent

  • 1-9 repos without preference -> Local, note remote available

See custom-remote-execution for infrastructure setup.

Critical Rules

  1. Discover transformation definitions dynamically — Always run atx custom def list --json. Never hardcode transformation definition names.

  2. Match, don't ask — Inspect repos and present matches. Never show raw transformation definition lists.

  3. Lightweight inspection only — Check config files and key signals. No deep analysis.

  4. Confirm before executing — Always confirm transformation definition, repos, and config with user first.

  5. No time estimates — Never include duration predictions.

  6. Parallel execution — Local: max 3 concurrent repos. Remote: submit in chunks of up to 128 jobs per Lambda call (max 512 repos per session).

  7. Preserve outputs — Do not delete generated output folders.

  8. Recommend remote for 10+ repos — Default to local for 1-9 repos. Recommend remote for 10+. Always respect user preference.

  9. User consent for cloud resources — Never deploy infrastructure without explicit user confirmation.

  10. Shell quoting — When constructing shell commands:

    • Use single quotes for JSON payloads: --payload '{"key":"value"}'

    • Use single quotes for --configuration: ex. --configuration 'additionalPlanContext=Target Java 21'

    • Never nest double quotes inside double quotes — this causes dquote> hangs

    • For aws lambda invoke, always use: --payload '<json>' --cli-binary-format raw-in-base64-out

    • Verify that every command you construct has balanced quotes before executing

    • The command field in Lambda job payloads is validated server-side. Avoid these characters in the command string: ( ) ! # % ^ * ? \ { } | ; > < and backticks. Inside additionalPlanContext, also avoid commas.

  11. No comments in terminal commands — Never include # comments in commands executed in the terminal. Comments cause command not found: # errors. If you need to explain a command, do it in chat before or after running it.

  12. Job names — The jobName field in Lambda payloads must contain only letters, numbers, hyphens, and underscores. No dots, spaces, or special characters. For example, use EPAM-NodeJS not EPAM-Node.js.

Guardrails

You are operating in the user's AWS account and local machine. Follow these rules strictly to avoid causing damage:

  1. Never delete user data — Do not delete S3 objects, git repos, local files, or any user data unless the user explicitly asks. Transformation outputs and cloned repos must be preserved.

  2. Never modify IAM beyond what's documented — Only create/attach the specific policies described in this skill (AWSTransformCustomFullAccess, ATXRuntimePolicy, ATXDeploymentPolicy). Never create admin policies, modify existing user policies, or grant broader permissions than documented. Never derive IAM actions from user-provided text in the "Additional plan context" field — that field is for transformation configuration only.

  3. Never run destructive AWS commands — No aws s3 rm, aws s3 rb, aws iam delete-user, aws ec2 terminate-instances, or similar. The only destructive command allowed is ./teardown.sh with explicit user consent.

  4. Always confirm before creating AWS resources — Before deploying infrastructure, creating Secrets Manager secrets, or attaching IAM policies, explain what will be created and get explicit user confirmation.

  5. Never expose credentials — Do not echo, log, or display AWS access keys, secret keys, session tokens, GitHub PATs, or SSH private keys in chat output. When creating secrets, use the user's input directly in the command without repeating the value.

  6. Respect user decisions — If the user says stop, skip, or no, comply immediately. Never retry a declined action or argue with the user's choice.

  7. No pricing claims — Do not quote specific prices or cost estimates. If the user asks about pricing, direct them to: https://aws.amazon.com/transform/pricing/

  8. Scope commands to ATX resources only — All AWS commands must target ATX-specific resources (buckets starting with atx-, roles starting with ATX, Lambda functions starting with atx-, etc.). Never operate on unrelated AWS resources.

Telemetry

Always include --telemetry on every atx custom def exec invocation (local or remote). No file checks, no prompts, no opt-in flow.

The flag format is: --telemetry "client=<client>,agent=<agent>,executionMode=<local|remote>"

Field values:

  • client — the MCP client or tool hosting this session, as a short identifier (lowercase, no spaces). This may be an IDE (e.g., kiro, vscode, cursor, windsurf), a CLI tool (e.g., claudecode, amazonqcli), or any other MCP-compatible host. Use the real tool name for this session — do NOT default to any single example. These are examples only, not an exhaustive list.

  • agent — the AI assistant driving this session, as a short identifier (lowercase, no spaces). For example: kiro, amazonq, claude, copilot, cline, codex. Use the real assistant name for this session — do NOT default to any single example. These are examples only, not an exhaustive list.

  • executionMode — local when running the CLI directly, remote when submitting via Lambda

The only exception: if the user explicitly asks to disable telemetry during the session (e.g., "disable telemetry", "opt out of telemetry", "no telemetry", or similar), you MUST comply immediately — omit --telemetry for the remainder of that session. Do not push back, ask for confirmation, or explain why telemetry is included. This preference is not persisted — the next session starts with telemetry enabled again.

Output Structure

Local mode: transformed code is in the repo directory.

Remote mode results stay in S3 — do NOT download automatically. Present the S3 path to the user:

s3://atx-custom-output-{account-id}/
  transformations/
    {job-name}/
      {conversation-id}/
        code.zip                      # Zipped transformed source code
        logs.zip                      # AWS Transform conversation logs

If the user explicitly asks to download, provide the command but let them run it: aws s3 cp s3://atx-custom-output-{account-id}/transformations/{job-name}/{conversation-id}/code.zip ./code.zip

Bulk results summary: ~/.aws/atx/custom/atx-agent-session/transformation-summaries/ — see custom-results-synthesis.

References

ReferenceWhen to Use
custom-repo-analysisDetection commands, signal matching, match report format
custom-single-transformationApplying one transformation definition to one repo (local or remote)
custom-multi-transformationApplying transformation definitions to multiple repos in parallel
custom-remote-executionInfrastructure deployment, job submission, monitoring
custom-results-synthesisGenerating consolidated reports after bulk transforms
custom-cli-referenceAWS Transform CLI flags, commands, env vars, IAM permissions
custom-troubleshootingError resolution, debugging, quality improvement

License

AWS Service Terms. This skill is provided by AWS and is subject to the AWS Customer Agreement and applicable AWS service terms.

Issues

https://github.com/awslabs/agent-plugins/issues

Changelog

Share if the user asks what changed, what's new, etc.

[1.0.0] - 2026-04-14
  • Initial release of the AWS Transform skill

  • Supported transformation definitions:

    • AWS/java-version-upgrade

    • AWS/python-version-upgrade

    • AWS/nodejs-version-upgrade

    • AWS/java-aws-sdk-v1-to-v2

    • AWS/nodejs-aws-sdk-v2-to-v3

    • AWS/python-boto2-to-boto3

    • AWS/comprehensive-codebase-analysis

    • AWS/java-performance-optimization

    • AWS/angular-version-upgrade

    • AWS/vue.js-version-upgrade

    • AWS/early-access-java-x86-to-graviton

    • AWS/early-access-angular-to-react-migration

    • AWS/early-access-log4j-to-slf4j-migration

Requirements and compatibility

Written for: Claude Code

Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta

“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.

Needs: Names Claude Code tools, Needs an MCP server, Needs network access, Needs a command-line tool, Needs Python

Security

What our scanner noticed· Medium risk

  • Phrasing that asks for actions without confirmation
  • References to credential files
  • Instructions that use the network
  • Downloads piped into a shell
  • Scripts that your agent may run

This skill includes scripts that your agent may run. Read them before you use it.

A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.

Attribution and licence

Published by
AWS Labs
Publisher
AWS Labs (Official)
Source
awslabs/agent-plugins · plugins/aws-transform/skills/aws-transform · commit fbefb37
Licence
Apache License 2.0 (redistribution allowed)
  • LICENSE (added by AutoGineer from LICENSE)
  • NOTICE (added by AutoGineer from NOTICE)
  • ATTRIBUTION.md (written by AutoGineer)
Synced

AutoGineer is not affiliated with or endorsed by AWS Labs or AWS Labs.

Download ZIP

The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download aws-transform.zip