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/dotnet.md

.NET Modernization

Last Updated: 2026-05-13

Table of Contents

  • Capabilities

  • Agents & Transforms

  • Decision Points

    • Target Version

    • Transformation Mode

    • Source Code Upload

    • Confirm & Launch

    • Per-Project Review Toggles

  • Status Check

  • Workflow (11 Steps)

    • Verify Authentication

    • Create or Reuse Workspace

    • Collect User Choices

    • Create and Start Job

    • Upload Source Code

    • Monitor Assessment

    • Plan Approval

    • Checkpoint Config

    • Monitor Transformation

    • Local Build Verification (Auto-Skip)

    • Final Summary & Download

  • Apply Transformation Changes

  • Handle Missing Packages

  • Mode Behavior Reference

  • HITL Reference

  • Artifacts Reference

  • Error Recovery

  • Known Limitations


Capabilities

Modernize .NET applications to .NET 8, .NET 9, or .NET 10. Supports projects targeting .NET Framework (v2.0–v4.8), .NET Core (1.x–3.x), or .NET 5–7.

SourceTarget
.NET Framework 2.0–4.8.NET 8 or .NET 10
.NET Core 1.x–3.x.NET 8 or .NET 10
.NET 5–7.NET 8 or .NET 10
VB.NET (.vbproj)VB.NET on .NET 8 or .NET 10
WPF (.NET Framework)WPF on .NET 8 or .NET 10
Xamarin.NET MAUI
ASP.NET MVC 5ASP.NET Core
WCF ServicesgRPC or REST APIs
Web FormsBlazor or Razor Pages
Entity Framework 6EF Core
Web.configappsettings.json
IIS deploymentECS Fargate / App Runner
packages.configPackageReference (SDK-style .csproj)

Agents & Transforms

User-Facing NameorchestratorAgentPurpose
.NET Modernization Agentdotnet-chatty-agent.NET code assessment + transformation (primary)

The .NET Modernization Agent handles both assessment AND transformation in a single job. There is no separate assessment agent.

In user-facing messages, refer to this as ".NET modernization agent" or "Managed Agent". Use dotnet-chatty-agent only in create_job tool calls — never in chat prose.


Decision Points

All user-facing questions. Ask in this order: version → mode → source code → per-project toggles.

Target Version
TargetTFMSupportNotes
.NET 10net10.0LTS (Nov 2025 – Nov 2028)Latest LTS, newest APIs and performance
.NET 9net9.0STS (Nov 2024 – May 2026)Latest features, shorter support window
.NET 8net8.0LTS (Nov 2023 – Nov 2026)Stable, widely adopted

MUST present all versions as explicit options. Mark .NET 10 as "(Recommended)". Default to .NET 10 if user has no preference.

Present options to the user and wait for their selection:

OptionDescriptionValue Mapping
.NET 10 (Recommended)LTS until Nov 2028. Latest APIs and performance improvements.target_framework = "net10.0"
.NET 9STS until May 2026. Latest features, shorter support window.target_framework = "net9.0"
.NET 8LTS until Nov 2026. Stable, widely adopted.target_framework = "net8.0"
Transformation Mode

Exactly TWO modes exist. No other modes exist.

ModeValueBehaviorBest For
AutoautoRuns to completion without pausing. Failures logged and skipped. Transformations are applied to your code during status checks. Best for low-complexity projects resolvable mostly by package version upgrades.Simple projects, small solutions
InteractiveinteractivePauses after each project for review. Plan approval required. Approved changes are applied to your code. Users can optionally configure project checkpoints to review the transformation and iterate in chat for addressing feedback and any residual errors.Medium and complex applications

Present options to the user and wait for their selection:

OptionDescriptionValue Mapping
Auto (Recommended for simple projects)Runs to completion without pausing. Transformations are applied to your code during status checks. Failures logged and skipped. Fast.interactive_mode = "auto"
InteractivePauses after each project for your review. Approved changes are applied to your code. You can inspect diffs, request changes, or skip projects.interactive_mode = "interactive"

Default to auto if user has no preference.

After the user selects a mode, inform them: "You can switch between auto and interactive mode at any time during the transformation — just ask."

Source Code Upload

Present options to the user and wait for their selection:

OptionDescription
Upload from workspaceZip and upload the solution from the current workspace
Specify a pathUser provides the path to the solution

MUST ask before uploading. MUST NOT auto-upload.

Confirm & Launch

After collecting target version and mode, present a summary of the user's selections and ask for confirmation before creating the job. No backend APIs have been called yet — this is the user's last chance to adjust.

Present options to the user and wait for their selection:

OptionDescription
Go aheadStart the migration
Wait, let me adjustChange something first

The plan presented above the question MUST include these steps:

  1. Create a new workspace (or reuse existing)

  2. Create a job with the .NET modernization agent (target: <version>, mode: <mode>)

  3. Upload your source code

  4. Agent assesses your solution, produces an assessment report, and generates a migration plan before starting the transformation

  5. Once transformation completes, you receive the migrated source code and a summary of changes

If user selects "Wait, let me adjust" — return to the relevant decision point (version or mode) and re-collect the choice. No backend APIs have been called yet, so this is a local loop with no side effects.

Per-Project Review Toggles (Interactive Mode Only)

Presented after plan approval. Projects default to "review enabled" — user deselects what they want to skip.

Present a multi-select list of projects from the plan. Each option shows the project name and complexity. All are selected by default — user deselects any they want to skip review for.

Option PatternDescription
<ProjectName><complexity> — <brief description>

Status Check

When the user asks for status, progress, or "what's happening" — use this procedure regardless of which workflow step is active:

  1. get_resource(resource="job", workspaceId=..., jobId=...) → get job status + _pollingGuidance + recentWorklogs

  2. list_resources(resource="tasks", workspaceId=..., jobId=...) → any pending HITL tasks?

  3. Check the latest agent message in the response — if it asks a question or presents options (continue/retry/skip/approve), the orchestrator is waiting for a send_message response. Present those options to the user.

Present the full picture:

  • Current phase and status

  • What the agent last did (from worklogs)

  • Any pending actions needed from user (HITL tasks OR agent message asking a question)

  • What's coming next

Rules:

  • AUTO mode: Call list_resources(resource="artifacts", pathPrefix="...Generated Outputs/") to check for new diff artifacts (fileType: "ZIP" with planStepId != "default"). If found, trigger the Apply Transformation Changes procedure for each completed project before reporting status.

  • If _pollingGuidance.hasPendingTasks=true → check tasks, present to user

  • If _pollingGuidance.isTerminal=true → job done, present final summary

  • If latest agent message asks a question → present it to user, orchestrator is waiting

  • If no pending tasks AND no questions AND job is EXECUTING → inform user the agent is working, no action needed


Workflow (11 Steps)

The full lifecycle of a .NET modernization job.

Verify Authentication
get_status()

If not authenticated, guide user through configure(). Do not proceed until auth is confirmed.

Create or Reuse Workspace
create_workspace(name="dotnet-modernization", description="Modernize .NET Framework solution to <target>")

Save workspaceId. If user has a workspace from a previous session (check .atx/context.json), offer to reuse it instead of creating a new one. Users can create multiple jobs within the same workspace.

Collect User Choices

MUST ask version FIRST, mode SECOND. MUST store exact values before calling create_job.

  1. Ask target version → store target_framework ("net10.0", "net9.0", or "net8.0")

  2. Ask transformation mode → store interactive_mode ("auto" or "interactive")

See Decision Points for the exact formats and value mappings.

Create and Start Job

Build objective as a JSON string from collected values:

# Examples:
objective_json = '{"target_framework": "net10.0", "interactive_mode": "interactive"}'
objective_json = '{"target_framework": "net8.0", "interactive_mode": "auto"}'

Call create_job:

create_job(
  workspaceId="<workspace-id>",
  jobName=".NET Assessment & Modernization",
  objective=objective_json,   # MUST be valid JSON, not prose
  intent="LANGUAGE_UPGRADE",
  orchestratorAgent="dotnet-chatty-agent"
)

Save jobId. The backend parses objective as JSON — if it receives prose, parsing fails silently and defaults to auto + net10.0.

Immediately after:

load_instructions(workspaceId="<workspace-id>", jobId="<job-id>")

send_message(
  workspaceId="<workspace-id>",
  jobId="<job-id>",
  text="Target: <target> (<tfm>). Mode: <mode>. Source code will be uploaded shortly."
)

load_instructions gates all job-scoped tools — MUST be called once per job.

Upload Source Code

Ask user first (see Decision Points: Source Code Upload). Then:

# Zip (exclude .git, bin, obj, packages)
upload_artifact(
  workspaceId="<workspace-id>", jobId="<job-id>",
  content="/tmp/source.zip", fileType="ZIP",
  categoryType="CUSTOMER_INPUT", fileName="source.zip"
)

# Notify agent
send_message(workspaceId="<workspace-id>", jobId="<job-id>",
  text="Source code uploaded (artifact ID: <id>). Please proceed with assessment.")

Save the user's source path to .atx/context.json as source_root. This is needed later to apply transformation changes to the correct location.

Monitor Assessment

The agent assesses the solution automatically. On user check-in:

get_resource(resource="job", workspaceId="<workspace-id>", jobId="<job-id>")

Report status, any available artifacts (Assessment_Report.md, Modernization_Plan.md), and pending tasks.

Use _pollingGuidance from the response:

  • hasPendingTasks=true → check for BLOCKING tasks

  • isTerminal=true → job done

If list_resources(resource="tasks") returns a task with tag missing-packages, follow the Handle Missing Packages procedure. Transformation will not proceed until resolved.

Plan Approval

AUTO mode: Skipped. Agent proceeds directly to transformation.

INTERACTIVE mode:

The backend orchestrator WAITS for user approval before starting transformation. It will NOT proceed on its own. You MUST detect the plan and get user approval.

How to detect "plan ready": Job status is PLANNING AND Modernization_Plan.md artifact exists. The status stays PLANNING until the user approves — it only moves to PLANNED after approval.

Do NOT trust the chatter's response — it may say "I'm proceeding" or "preparing to begin" but the orchestrator is actually paused waiting for your send_message approval.

Flow:

  1. Detect plan is ready (artifact or worklog signal)

  2. Present plan summary to user (from the agent's messages or assessment data)

  3. Ask user to approve

  4. Send approval:

send_message(workspaceId="<workspace-id>", jobId="<job-id>",
  text="User approves the migration plan. Please proceed with transformation.")

Only after this send_message will the backend start transforming projects.

After confirming approval to the user, also inform them: "You can switch between auto and interactive mode, or select/deselect which projects to review, at any time during the transformation — just ask."

AUTO mode: Plan approval is skipped, but still inform the user when first reporting transformation progress that they can switch modes or enable per-project review at any time.

Checkpoint Config (Interactive Mode Only)

Skip this step entirely in AUTO mode.

After plan approval, extract project step_ids from the plan and present per-project toggles:

8a. Get plan and find project steps:

get_resource(resource="plan", workspaceId="<id>", jobId="<id>")
# Find steps where parentStepId matches "Transform Projects" step
# These are per-project steps with stepId and stepName

8b. Find checkpoint config task ID:

list_resources(resource="tasks", workspaceId="<id>", jobId="<id>")
# Find task where tag ends with "-checkpoint"

8c. Present per-project toggles to user (see Decision Points: Per-Project Review Toggles)

8d. Submit user's choices:

complete_task(
  workspaceId="<workspace-id>", jobId="<job-id>",
  taskId="<checkpoint-task-id>",
  content='{"interactive_mode": "interactive", "<step_id_1>": true, "<step_id_2>": false, ...}',
  action="SAVE_DRAFT"
)

Use SAVE_DRAFT (not APPROVE) for checkpoint config — this keeps the task open so it can be updated again later. The backend reads the humanArtifact regardless of task status.

Rules:

  • Step IDs come from plan (steps[].stepId where parent is "Transform Projects")

  • true = pause for review; false = skip review

  • MUST include ALL project step_ids — omitted ones default to false

  • MUST include interactive_mode in every submission

  • The HITL does not close — can be updated anytime

8e. Save to .atx/checkpoint-config.json:

{
  "checkpointTaskId": "<task-id>",
  "mode": "interactive",
  "projects": {
    "<step_id>": { "label": "<ProjectName>", "review": true }
  },
  "lastUpdated": "<ISO timestamp>"
}

On conversation resume, check this file first — reuse stored mapping instead of re-asking.

Mid-run updates: When user asks to switch mode or change toggles:

  1. Read .atx/checkpoint-config.json

  2. Update values per user's request

  3. Save updated file

  4. Call complete_task with values from saved file, using action="SAVE_DRAFT"

A send_message alone does NOT change the mode — only complete_task (with SAVE_DRAFT) on the checkpoint HITL changes backend behavior.

Monitor Transformation

The agent transforms each project in dependency order (convert → upgrade packages → fix errors → checkpoint).

Status progression: PLANNING → PLANNED → EXECUTING → COMPLETED

Terminal states: STOPPED, FAILED

INTERACTIVE mode — when Project Review HITL appears:

  1. Inform user which project completed + summary

  2. Present options to the user:

    OptionDescription
    ApproveApply transformation to the project and continue to the next project.
    Download the diffInspect the exact file changes before deciding.
    RejectSkip this project's transformation. Local code is not modified.
  3. If user approves, state which project you are approving before calling complete_task

  4. Submit decision:

    complete_task(workspaceId="<id>", jobId="<id>", taskId="<review-task-id>",
      content='{}', action="APPROVE")
  5. Immediately send follow-up:

    send_message(workspaceId="<id>", jobId="<id>",
      text="Review approved for <project>. Please continue with transformation.")
  6. Apply transformation changes (see Apply Transformation Changes section).

AUTO mode: No review tasks appear. Transformation changes are applied when the user checks status (see Status Check and Apply Transformation Changes sections).

Local Build Verification (Auto-Skip)

After all projects transform, a build verification HITL appears (BLOCKING, tag: local-build-verification). This applies to both auto and interactive modes.

Auto-complete this HITL immediately with a skip response. The user does not need to approve — this workflow handles it silently. After auto-completing, inform the user: "Local build verification is optional and has been skipped. You can always run dotnet build on the migrated code yourself after downloading. If you encounter build errors, you can ask me to help fix them."

complete_task(workspaceId="<id>", jobId="<id>", taskId="<build-task-id>",
  content='{"status": "SUCCESS", "errorCount": 0, "errors": [], "rawOutput": "Build verification skipped."}',
  action="APPROVE")

send_message(workspaceId="<id>", jobId="<id>",
  text="Build verification skipped. Please proceed with next steps.")

Detection: When list_resources(resource="tasks") returns a task with tag local-build-verification, auto-complete it using the pattern above. This includes detection during status checks — if the user asks for status and a local-build-verification HITL is pending, auto-complete it first, then report progress.

If the backend creates additional build verification rounds (after agent-side fixes), auto-complete each round the same way.

Final Summary & Download

After build verification, the agent generates final artifacts (report, next steps, migrated source ZIP) and sends a message asking whether to mark the job as complete. The job remains in EXECUTING until a confirmation is sent via send_message.

When the agent's message indicates transformation is complete and artifacts are ready:

  1. List output artifacts: list_resources(resource="artifacts")

  2. Announce what is ready — present a summary so the user chooses with full knowledge of the available artifacts:

    • Projects transformed (count, names, status)

    • Per-project diff ZIPs — list each with project name and artifact ID. These contain metadata.json, diffs/*.diff, before/*, and after/* so the user can review exactly what changed per project. Identify them by label checkpoint-diff-{project-name}.

    • Transformation report available (Transformation_Report.html — detailed HTML report)

    • Next steps available (NextSteps.md — remaining post-migration items to fix)

    • Final migrated source available (*_Transformed_*.zip — complete migrated solution)

  3. Ask the user how to proceed, presenting these options and waiting for their selection:

    OptionDescription
    Download code & fix next steps (Recommended)Download the migrated source and all artifacts, then hand NextSteps.md back to the agent to work through the remaining items
    Download all to reviewSave all artifacts locally for review, without handing next steps back to the agent
    Complete the transformation nowMark the job as done without downloading or ingesting next steps
  4. Based on the user's choice:

    "Download code & fix next steps" — download, then ingest NextSteps.md back to the agent:

    a. Download every output artifact to .atx/ (migrated source ZIP, Transformation_Report.html, NextSteps.md, and each per-project diff ZIP):

    get_resource(resource="artifact", workspaceId="<id>", jobId="<id>",
      artifactId="<id>", savePath=".atx/<filename>")

    b. Locate the downloaded NextSteps.md (if multiple exist, use the most recent) and upload it back to the same job as customer input:

    upload_artifact(workspaceId="<id>", jobId="<id>",
      content=".atx/NextSteps.md", fileType="MARKDOWN", categoryType="CUSTOMER_INPUT")

    c. Tell the agent to act on it:

    send_message(workspaceId="<id>", jobId="<id>",
      text="I've uploaded NextSteps.md — please follow it and complete it.")

    The agent reads NextSteps.md and works the items, completing what it can and asking the user directly for anything it cannot do alone (for example, connection string updates). Your role is to relay, not to act on the items yourself:

    • Do NOT claim the items are done. Report only what a live status check confirms.

    • Do NOT create, edit, or generate any files. Your only writes are the artifact downloads (a) and the NextSteps.md upload (b).

    Then continue to the final gate below.

    "Download all to review" — download every output artifact to .atx/ as in (a). Do not upload anything back. Then continue to the final gate below.

    "Complete the transformation now" — skip download and ingest; go directly to the final gate below.

  5. Present the final gate, presenting these options and waiting for the user's selection:

    OptionDescription
    Complete the transformationMark the job as done
    Make adjustmentsRequest additional changes before completing
    # User completes:
    send_message(workspaceId="<id>", jobId="<id>",
      text="Looks good, mark the job as complete.")
    
    # User wants adjustments — relay their request:
    send_message(workspaceId="<id>", jobId="<id>",
      text="<user's adjustment request>")
    # Agent handles the request, then asks again — repeat this step.
  6. Once the job reaches COMPLETED, update .atx/context.json with phase: "complete".

Ingesting NextSteps.md on request

The user may download artifacts themselves (from the AWS Transform website or a prior .atx/ download), review the NextSteps.md, and then ask you to hand it back to the agent. When the user asks to ingest, feed, or send NextSteps.md to the agent:

  1. Locate the file: check .atx/ first; if it is not there, ask the user for its local path (they may have downloaded it from the website).

  2. Confirm the job can still accept input. If the job is in a terminal state (COMPLETED, STOPPED, FAILED), the agent cannot act on an upload — tell the user plainly that ingestion is not possible on a closed job rather than reporting success. Otherwise:

upload_artifact(workspaceId="<id>", jobId="<id>",
  content="<path to NextSteps.md>", fileType="MARKDOWN", categoryType="CUSTOMER_INPUT")
send_message(workspaceId="<id>", jobId="<id>",
  text="I've uploaded NextSteps.md — please follow it and complete it.")

Do NOT create any files yourself — only upload the existing NextSteps.md and notify the agent.


Apply Transformation Changes

Apply transformed code from per-project diff artifacts to the user's local filesystem. Triggered when a project's transformation completes and the user interacts.

Trigger conditions:

  • AUTO mode: When the user checks status and projects have completed transformation, trigger the Apply Transformation Changes procedure for each completed project

  • INTERACTIVE mode: After the user approves the project review HITL

  • MUST NOT apply if the user rejected the project in interactive mode

First-time consent (both modes): Before applying changes for the first time, inform the user:

"I'll apply the transformed code to your local codebase as each project completes. Any modifications you made since uploading will be overwritten for the affected projects. If you have git initialized, the changes will appear as unstaged modifications you can review or discard."

In AUTO mode, ask for confirmation before proceeding. In INTERACTIVE mode, the user's approval of the project review HITL serves as consent.

Procedure

1. Find the latest diff artifact for the project:

# First call returns folder paths
list_resources(resource="artifacts", workspaceId="<id>", jobId="<id>")
# Response contains folders[] — use the "Generated Outputs/" path as pathPrefix

# Second call with pathPrefix returns actual artifacts
list_resources(resource="artifacts", workspaceId="<id>", jobId="<id>",
  pathPrefix="AWSTransform/Workspaces/<workspaceId>/Jobs/<jobId>/Generated Outputs/")
# Per-project diff artifacts are identified by:
#   - fileType == "ZIP"
#   - planStepId != "default"
# Match artifact.planStepId to plan step.stepId to determine which project it belongs to.
# If multiple artifacts share the same planStepId (retries), pick the one with the latest artifactCreatedTimestamp.

2. Download the diff ZIP:

get_resource(resource="artifact", workspaceId="<id>", jobId="<id>",
  artifactId="<latest-diff-artifact-id>",
  savePath=".atx/diffs/<jobId>/checkpoint-diff-<project-name>.zip")

3. Extract the ZIP and read metadata.json:

{
  "filesAdded": ["path/to/NewFile.cs"],
  "filesUpdated": ["path/to/Modified.csproj"],
  "filesRemoved": ["path/to/Deleted.cs"]
}

4. Write files to the user's local codebase:

The source_root is the path the user provided during Source Code Upload, stored in .atx/context.json.

ActionSourceDestination
Update/Addafter/{path} from extracted ZIP{source_root}/{path}
Remove—Delete {source_root}/{path}

MUST use the agent's native file-write capability. Do NOT use git apply, patch, or any OS-specific command. This ensures cross-platform compatibility (Windows, macOS, Linux).

MUST create parent directories if they do not exist when writing new files.

MUST preserve file encoding from the after/ content (write bytes as-is).

5. Confirm to user:

✅ Applied transformation for <project-name>:
   • <N> files updated
   • <N> files added
   • <N> files removed
Rules
  • MUST apply project-by-project as each completes — do NOT wait until all projects finish

  • MUST use the latest diff artifact when multiple exist (highest createdAt)

  • MUST preserve file encoding from the after/ content (write bytes as-is)

  • If a file in filesUpdated does not exist locally, treat it as an add

  • If a file in filesRemoved does not exist locally, skip silently

  • If download or extraction fails, inform the user and offer to retry


Handle Missing Packages

When the agent detects private or unavailable NuGet packages during assessment, a BLOCKING HITL task appears. Transformation will not proceed until resolved.

Detection: list_resources(resource="tasks") returns a task with tag missing-packages and uxComponentId: "DotnetMissingPackages".

Procedure:

  1. Get task details to see which packages are missing:

    get_resource(resource="task", workspaceId="<id>", jobId="<id>", taskId="<task-id>")
  2. Present to user: "The following NuGet packages could not be found on public feeds: [list]. Please provide the .nupkg files, or let me know if any can be removed."

  3. For each .nupkg file the user provides, upload it:

    complete_task(workspaceId="<id>", jobId="<id>", taskId="<task-id>",
      filePath="/path/to/Package.1.0.0.nupkg",
      action="SAVE_DRAFT")
    # Returns uploadedArtifactId — save this for the final submission
  4. After all packages are uploaded, submit the final response with all artifact IDs:

    complete_task(workspaceId="<id>", jobId="<id>", taskId="<task-id>",
      content='{"uploadedArtifactIds": [{"artifactId": "<id1>", "name": "Package1.nupkg", "lastModified": 0, "size": 0}, {"artifactId": "<id2>", "name": "Package2.nupkg", "lastModified": 0, "size": 0}]}',
      action="APPROVE")
  5. If user wants to remove a package from the missing list instead of uploading:

    complete_task(workspaceId="<id>", jobId="<id>", taskId="<task-id>",
      content='{"removedPackages": [{"name": "PackageName", "version": "1.0.0"}]}',
      action="APPROVE")

Rules:

  • MUST collect all uploadedArtifactId values from each SAVE_DRAFT call for the final APPROVE submission

  • User uploads are stored under CUSTOMER_INPUT category

  • If only one package is missing, a single complete_task with filePath + action="APPROVE" is sufficient

  • Transformation remains blocked until this HITL is resolved

Upload packages anytime (outside the HITL):

If the user wants to upload private packages at any point during the job (e.g., after the HITL closes, or when a build fails due to a missing package):

upload_artifact(workspaceId="<id>", jobId="<id>",
  content="/path/to/Package.nupkg", fileType="ZIP",
  categoryType="CUSTOMER_INPUT", fileName="Package.1.0.0.nupkg")

send_message(workspaceId="<id>", jobId="<id>",
  text="I uploaded the private package Package.1.0.0.nupkg. Please add it to the local feed and retry.")

The agent checks CUSTOMER_INPUT artifacts, adds the package to the local feed, and resumes.


Mode Behavior Reference

PhaseAUTOINTERACTIVE
Plan approvalSkippedRequired (via send_message)
Checkpoint configIgnorePresent per-project toggles — optional
Per-project reviewNo HITLs createdHITL per toggled-on project — optional
Apply transformation changesOn status check, for each completed projectAfter user approves project review
On project failureLog + skip + continuePresent to user, wait for decision
Build verificationAuto-skipAuto-skip
Missing PackagesPresent to user (BLOCKING)Present to user (BLOCKING)
Final diffsAll at endPer-project during + all at end

HITL Reference

HITL TypeComponent IDTagBlockingBehavior
Checkpoint ConfigFileUploadV2*-checkpointNON_BLOCKINGAUTO: ignore. INTERACTIVE: Checkpoint Config step.
Project ReviewDotnetReviewAndConfirm*-reviewNON_BLOCKINGINTERACTIVE only. Present diffs, wait for decision.
Missing PackagesDotnetMissingPackagesmissing-packagesBLOCKINGBoth modes. Always present to user. Severity: CRITICAL.
Local Build VerificationFileUploadV2local-build-verificationBLOCKINGBoth modes. Auto-skip with dummy SUCCESS.

Processing pattern for any HITL:

  1. list_resources(resource="tasks") → discover pending tasks

  2. get_resource(resource="task", taskId=...) → get full details (read _outputSchema, _responseHint)

  3. Present to user

  4. Show payload before submitting

  5. complete_task(content=..., action="APPROVE") → submit

There is NO Assessment Review HITL. Plan approval uses send_message.


Artifacts Reference

TypeCategoryContains
Source code ZIPCUSTOMER_INPUTUser's original .NET solution
Assessment report (Assessment_Report.md)CUSTOMER_OUTPUTComplexity scores, dependency analysis
Modernization plan (Modernization_Plan.md)CUSTOMER_OUTPUTMigration plan with project ordering
Per-project diff ZIPCUSTOMER_OUTPUTmetadata.json + diffs/*.diff + before/* + after/*
Final migrated source ZIP (*_Transformed_*.zip)CUSTOMER_OUTPUTComplete migrated solution after all projects transform
Transformation report (Transformation_Report.html)CUSTOMER_OUTPUTHTML summary of all transformations performed
Next steps (NextSteps.md)CUSTOMER_OUTPUTRecommended post-migration actions

Per-project diff ZIPs have label: "checkpoint-diff-{project-name}".

The final migrated source ZIP, Transformation_Report.html, and NextSteps.md appear after build verification completes (job near completion).

Upload rules:

  • Use categoryType: "CUSTOMER_INPUT" for source code

  • Exclude .git/, bin/, obj/, packages/ from ZIP

  • Notify agent via send_message after upload with artifact ID

When multiple artifacts of the same type exist (e.g., multiple diff ZIPs from retries or re-runs), always use the most recent one. Sort by creation timestamp and pick the latest.


Error Recovery

Job not progressing?
├─ Check tasks → pending HITL? → present to user
├─ Check messages → agent asked something? → respond via send_message
├─ Check job status → FAILED? → offer restart or new job
├─ Send status query → agent responds? → continue
└─ None of above → offer restart

Key actions:

  • Job creation fails: Retry. If repeated, check auth and workspace.

  • Upload fails: Check file size, verify ZIP, retry.

  • Job stuck: Send status query via send_message. Check for hidden HITL tasks.

  • Task or project fails: Ask the agent to retry the failed task in chat via send_message. The agent can re-attempt the transformation for that project.

  • Restart: control_job(action="stop") then control_job(action="start"). Previously uploaded artifacts remain available.

  • Delete and start over: delete_job() then new create_job().


Known Limitations

  • COM interop references require manual replacement

  • P/Invoke (native Windows DLL calls) need manual porting

  • Web Forms → Blazor conversion is partial — complex controls may need redesign

  • Windows Services → need manual conversion to BackgroundService

  • GAC dependencies must be replaced with NuGet packages manually

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