npx skills add ...
npx skills add arc-mcp/arc-1 --skill sap-transport-review
Review what actually changed — in a transport, or in your unactivated drafts — by diffing each object's source and summarizing the change set with optional impact and quality signals. Produces a reviewable report (per-object unified diffs + risk flags), not a raw object dump. Use when asked to "review this transport", "what changed in TR X", "diff the objects in a transport", "show my pending changes before I activate/release", "prepare a transport/change review", or "what am I about to ship".
npx skills add arc-mcp/arc-1 --skill sap-transport-review
Answer "what actually changed?" for a transport or for your in-flight (unactivated) work, as a reviewable report: a per-object unified diff plus risk flags — not a wall of full source.
It leans on two token-cheap ARC-1 primitives so a review of a 30-object transport costs a handful of small diffs instead of 60 full-source reads:
SAPTransport(action="list", summary=true) — scan many open transports cheaply (objects omitted, objectCount kept), then drill into one.SAPRead(action="diff", from=…, to=…) — server-side unified diff per object; the response is just the hunks.Complements explain-abap-code (deep single-object understanding) and sap-object-documenter (written docs for a package). This skill is about delta — what moved between two points in time — for code review, hand-off, or a pre-release gate.
| You are… | Scope | What the skill does |
|---|---|---|
| Reviewing a transport (senior dev / approver) | one transport id | Diff every safely resolved source object, label the version coverage, and add impact/quality checks only when requested or risk-triggered. The chat / whole-transport twin of Eclipse ADT 3.6's "Object Changes" tab (same source-diff coverage boundary). |
| Checking your own recent work (dev) | your modifiable transports | "What have I changed since my last release?" — diff each object's last-released version → current. Light: skip impact/ATC unless asked. |
For a system-wide inventory of every open transport (basis: who has what open, how big, conflicts — no diffs) that's a different job → sap-transport-overview.
| Setting | Default | Rationale |
|---|---|---|
| Transport scope | current user, modifiable (status="D") | The work in progress, not released history |
| Overview first | summary=true when listing | Cheap scan before pulling any object list in full |
| Diff direction (in-flight) | from="active", to="inactive" | Exact for pending, unactivated source only; it does not reconstruct changes already activated in an open request |
| Diffable types | PROG, CLAS, INTF, FUNC, FUGR, INCL, DDLS, DCLS, BDEF, SRVD, DDLX, TABL | The plain-text source types action="diff" supports |
| Object-diff cap | ~40 | Above that, summarize counts and ask which to expand |
| Impact | On for changed CDS/RAP objects in a risk-focused review; otherwise opt-in | Focus the extra reads where dependency risk exists |
| ATC | Opt-in (+atc) or clearly risk-triggered; bounded to changed objects | ATC is workload-producing and must not fan out silently across a large request |
The user provides one of:
A4HK900123) — review everything in that request.Optional: +impact (who consumes the changed CDS/RAP), +atc (new quality findings), output path for a Markdown file.
Scope guard: if the selected set exceeds ~40 diffable objects, show the object table with +/-
counts only and ask which objects (or which task) to expand into full diffs. A review nobody reads is
worse than no review.
SAPTransport(action="get", id="<id>") → the tasks[].objects[] list.SAPTransport(action="list", summary=true) → a cheap table
(id, description, owner, status, objectCount). Present it, let the user pick, then get that one.SAPTransport get returns CTS identities, not guaranteed SAPRead inputs. Each entry has
pgmid, CTS type, name, and wbtype; real transports may also contain subobjects such as
LIMU/METH, LIMU/REPS, language entries, and package/metadata entries.
Before diffing:
tasks[].objects[], but keep the task id and original CTS key for the report.R3TR entries (R3TR/CLAS, R3TR/DDLS, …) as direct repository objects and
deduplicate exact repeats.pgmid (LIMU, LANG), a CTS subtype (METH, REPS), or wbtype (CLAS/OM,
PROG/I, …) to SAPRead(type=…).parent resolution unavailable rather than guessing a
class/include name. This is a coverage limitation, not evidence that nothing changed.Then split the resolved repository objects into:
action="diff" returns "not supported" (their read is parsed metadata/XML, not plain-text source).
This is exactly the boundary SAP's own Eclipse ADT 3.6 "Object Changes" has — it prints
"Feature not supported for object …" for these same types (e.g. SRVB). Don't try to diff them.
For a thorough review, still read the object's metadata (e.g. SAPRead(type="SRVB", name=…)) so the
report names what the object is and that it's in the change set — just without a source diff.from/to by intentRun these in parallel (each returns only hunks):
Choose the sides by what the user is reviewing:
| Intent | from → to | Notes |
|---|---|---|
| Pending draft ("what I'm about to activate") | active → inactive | Exact pending-source diff. No draft means "no pending source", not "the open transport made no changes". |
| Since the latest released snapshot | <latest released revision id> → active (or inactive if still draft) | Captures all changes since that release; it may combine multiple open requests and must be labelled that way. Confirm revision ordering/timestamps rather than assuming feed order. |
| Released transport ("what did this TR change") | <revision immediately before TR> → <revision tagged with TR> | Compare the transport's own released snapshot, not today's active source. If the matching snapshot/predecessor is ambiguous or absent, report the baseline gap. |
| Specific revisions | <id|uri> → <id|uri|active> | From a VERSIONS response. |
Snapshot-sparsity reality (important): ABAP cuts a version snapshot only when a transport is released. So for an open/unreleased transport, objects usually have just the active version (+ maybe an inactive draft) — there is no "before" revision to diff against. Handle it honestly:
SAPRead(type="VERSIONS", name=…, objectType=…) where supported.active source for an old transport.active → inactive only for the pending portion. A prior released
revision → active comparison is useful, but label it "since released snapshot" because it can
include other open requests.baseline unavailable.
Do not call it an add unless independent object metadata proves creation in this request.The report must state its coverage: pending draft, released snapshot, since released snapshot (may span requests), or baseline unavailable.
DDLS/BDEF/SRVD can break consumers): SAPContext(action="impact", type="DDLS", name="<view>") → projection views, BDEFs, service defs/bindings, ABAP consumers that depend on it.+atc, or risk justifies it, run SAPDiagnose(action="atc", ...)
only for the bounded changed set. Use SAPLint(action="lint", name=…) for a cheaper local pass.SAPDiagnose action="syntax" check for unactivated work.
SAPActivate mutates system state; run it only when the user explicitly asks to activate.…one block per diffable object…
<2–3 lines: what this change set does, what to review first, what's risky / not yet activated.>