From ARC-1 — SAP ABAP for Claude
Runs ATC readiness checks on S/4HANA custom code, groups findings, and generates clean-core replacement ABAP code.
How this skill is triggered — by the user, by Claude, or both
Slash command
/arc-1:migrate-custom-codeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
ATC-driven S/4HANA custom code migration assistant with automated fix proposals.
ATC-driven S/4HANA custom code migration assistant with automated fix proposals.
This skill replicates SAP Joule's "Custom Code Migration" capability by combining ARC-1 (SAP system access) with mcp-sap-docs (documentation & best practices). It runs ATC readiness checks, groups and explains findings, and generates replacement code following modern ABAP patterns.
| Setting | Default | Rationale |
|---|---|---|
| Object type | Auto-detect via SAPSearch | Don't make user look up the type |
| ATC variant | System default | Use what's configured on the system |
| Scope | fix (explain + fix proposals) | Most actionable output |
| Priority filter | All priorities (start with Priority 1 errors) | Don't miss anything, but fix most critical first |
The user provides an object or package to check (e.g., ZCL_SALES_HANDLER, Z_REPORT_POSTING, ZSALES_PKG).
Only the object name is required. If the user provides just an object name, auto-detect the type and proceed with the default variant and fix scope.
Optionally, the user may specify:
S4HANA_2023, S4HANA_READINESS; default: system default)explain (findings only) or fix (explain + fix proposals; default: fix)ATC gotchas (verified live on S/4HANA 2023):
- ATC skips
$TMP/ local objects. A check run against a$TMPobject resolves to an empty object set and returns zero findings — this is not "clean code", it's "not checked". Run ATC against objects in a transportable package. If the user points you at$TMPcode, say so and ask them to assign it to a transportable package first.- The check variant must exist on the system.
ABAP_CLOUD_READINESSis the standard name on SAP BTP ABAP / S/4HANA Cloud, but on-premise systems often shipS4HANA_READINESS_<release>(e.g.S4HANA_READINESS_2023) orSAP_CLOUD_PLATFORM_DEFAULTinstead. If the named variant is absent, fall back to the system default (omitvariant).
SAPDiagnose(action="atc", type="<type>", name="<object_name>", variant="<variant>")
If no variant was specified, run with the system default first (omitting variant uses the system's configured default check variant):
SAPDiagnose(action="atc", type="<type>", name="<object_name>")
Then suggest a readiness variant if available (e.g., S4HANA_READINESS_2023, ABAP_CLOUD_READINESS). If a run returns zero findings on code you expect to be flagged, first confirm the object is not in $TMP (see the gotcha above).
SAPRead(type="DEVC", name="<package_name>")
This returns all objects in the package. Then run ATC on each object individually. For large packages, prioritize PROG, CLAS, FUGR, FUNC types first as they typically contain the most migration-relevant findings.
Organize findings into a structured summary. Deduplicate findings with the same checkTitle across multiple locations.
Present findings grouped by priority and category:
Migration Readiness Report for <object_name>
=============================================
Total findings: <N>
Priority 1 (Errors): <n>
Priority 2 (Warnings): <n>
Priority 3 (Info): <n>
| # | Priority | Check | Category | Count | Affected Objects |
|---|----------|-------|----------|-------|------------------|
| 1 | 1 | Use of obsolete statement MOVE | Syntax Change | 3 | Z_REPORT_POSTING |
| 2 | 1 | Call to released API CL_GUI_ALV_GRID | Deprecated API | 1 | Z_REPORT_POSTING |
| 3 | 2 | SELECT...ENDSELECT pattern | Performance | 5 | Z_REPORT_POSTING |
| ...
Group findings into these categories:
Ask the user: "Which findings should I explain and fix? (all / specific numbers / errors only)"
For each selected finding, provide a detailed explanation.
SAPRead(type="<type>", name="<object_name>")
Show the code context around each finding (the line with the issue and a few lines before/after).
search("<checkTitle> S/4HANA migration")
search("<deprecated_api> replacement ABAP")
For specific simplification items:
search("<simplification_item_id> simplification list")
sap_notes_search(q="<checkTitle>")
sap_notes_search(q="<deprecated_api> replacement")
For each finding, present:
For each fixable finding, generate replacement code based on documentation and modern ABAP patterns.
For each finding location, first check whether SAP provides a native quickfix:
SAPDiagnose(action="quickfix", type="<type>", name="<object_name>", source="<current_source>", line=<finding_line>, column=0)
If proposals are returned:
SAPDiagnose(action="apply_quickfix", type="<type>", name="<object_name>", source="<current_source>", line=<finding_line>, column=0, proposalUri="<proposal_uri>", proposalUserContent="<proposal_user_content>")
apply_quickfix returns ranged text deltas — it does not persist. Apply the returned deltas to the source yourself, then write the result via SAPWrite(action="update"). When applying multiple fixes to the same object, re-resolve each finding's line after each write (earlier edits shift later line numbers), or fix top-to-bottom.Quickfix availability is system-dependent. SAP only offers quickfix proposals where the system has the corresponding check/cloudification content installed. On a bare ABAP trial or a system without the Clean-Core remediation content,
getFixProposalsreturns[]and ATC findings carryhasQuickfix=false— that's expected, not a bug. In that case skip straight to LLM-generated fixes (the options below). Prefer SAP quickfixes only when they actually come back.
Match the proposal to the finding — don't blindly apply
proposals[0].quickfixreturns every proposal applicable at that source position, which often includes generic refactorings unrelated to the finding (verified live on S/4HANA 2023: a position returned "Rename", "Convert to attribute", "Convert to importing parameter", "Extract local variable", …). Pick the proposal whosename/descriptionactually addresses the finding; ignore the rest.
Refactoring-style proposals can't be auto-applied here. Proposals whose
uricontains/providers/refactoring/(rename / convert-to-X / extract / introduce) are interactive refactorings that ride the separate/sap/bc/adt/refactoringsmulti-step flow —apply_quickfixreturns HTTP 500 for them (verified live). They are not finding fixes; skip them for automated apply and fall back to an LLM-generated fix. Only proposals from non-refactoring providers apply cleanly throughapply_quickfix.
Present 4 options per finding:
Group related fixes that can be applied together (e.g., multiple deprecated statements in the same method).
Use these replacement patterns when generating fixes:
| Old Pattern | New Pattern | Notes |
|---|---|---|
CALL FUNCTION '<fm>' | Class method call | Find replacement class in documentation |
SELECT...ENDSELECT | SELECT INTO TABLE + loop | Avoid row-by-row processing |
MOVE-CORRESPONDING src TO dst | dst = CORRESPONDING #( src ) | New ABAP syntax |
READ TABLE itab WITH KEY k = v | line_exists( itab[ k = v ] ) or VALUE #( itab[ k = v ] OPTIONAL ) | Use table expressions |
FORM/PERFORM | Method call | Extract to class method |
DESCRIBE TABLE itab LINES lv_cnt | lv_cnt = lines( itab ) | Built-in function |
CALL METHOD obj->method | obj->method( ) | Functional call syntax |
CREATE OBJECT obj TYPE cls | obj = NEW cls( ) | NEW operator |
TRANSLATE str TO UPPER CASE | str = to_upper( str ) | Built-in function |
| Classic DB view | CDS view entity | Redesign required |
WRITE: / ALV list | Fiori / RAP service | Major redesign |
For method-level fixes in classes:
SAPWrite(action="edit_method", type="CLAS", name="<class>", method="<method>", source="<fixed_source>", transport="<transport>")
For full-source updates (programs, functions):
SAPWrite(action="update", type="<type>", name="<object_name>", source="<fixed_source>", transport="<transport>")
SAPDiagnose(action="syntax", type="<type>", name="<object_name>")
If syntax errors are introduced: revert by writing back the original source and report the issue.
SAPActivate(type="<type>", name="<object_name>")
Run ATC again to confirm findings are resolved:
SAPDiagnose(action="atc", type="<type>", name="<object_name>", variant="<variant>")
Present a final summary:
Migration Fix Summary for <object_name>
========================================
Findings fixed: <n>
Findings remaining: <n>
Findings needing manual fix: <n>
Fixed:
- [FIXED] Use of obsolete statement MOVE (3 occurrences)
- [FIXED] SELECT...ENDSELECT replaced with SELECT INTO TABLE
Remaining:
- [MANUAL] CL_GUI_ALV_GRID replacement requires UI redesign
- [SKIPPED] User skipped FORM/PERFORM migration
Next steps:
- Address remaining manual findings
- Run full regression tests
- Consider running ATC on dependent objects
| Error | Cause | Fix |
|---|---|---|
| ATC variant not found | Variant doesn't exist on this system | Run default ATC, list available variants with SAPDiagnose(action="atc") |
| Object locked by another user | Object is being edited elsewhere | Inform user, suggest trying later or contacting the lock holder |
| Fix causes new syntax error | Generated replacement code is incorrect | Revert to original source, show the diff, suggest manual correction |
| No mcp-sap-docs available | Documentation MCP not configured | Explain findings using ATC finding text only, recommend user check SAP Help Portal |
| Package has too many objects | Large package with 100+ objects | Suggest breaking into smaller batches by sub-package or object type |
| ATC returns no findings | Object is already S/4HANA ready | Inform user — no findings is good news, suggest checking with a stricter variant |
| Transport required but not provided | Object is in a transportable package | Ask user for transport request number before applying fixes |
npx claudepluginhub arc-mcp/arc-1 --plugin arc-1Explains ABAP objects with full dependency context via SAPContext and optional ATC code quality analysis. Supports classes, CDS views, behavior definitions (BDEF), reports, and more.
Migrates classic ABAP custom code to ABAP Cloud with ATC readiness checks, API replacements, and wrapper generation for unreleased objects.
Assists with ABAP code for SAP systems: internal tables, structures, ABAP SQL, OOP, RAP, CDS views, EML statements, ABAP Cloud, strings, dynamic programming, RTTI/RTTC, field symbols, data references, exceptions, unit testing.