--- name: sap-cli description: "SAP ABAP ADT CLI for AI agents. Trigger when: operating ABAP objects, syncing code to/from SAP, managing transports, querying DDIC, running ABAP programs, reading SAP tables, or any SAP development task via terminal." version: "2.2.1" author: WuRangyu license: MIT triggers: - "ABAP development" - "sync to SAP" - "download from SAP" - "SAP transport request" - "DDIC/SE11/SE16N/SE38/SE80" - "SAP ADT REST API" --- # sap-cli — SAP ABAP Development Object Management Python CLI wrapping the SAP ADT REST API. Manages the full lifecycle of ABAP development objects from the terminal. Core loop: **download → local edit → sync back to SAP**. ## Quick Start ```bash # 1. Single object: download → edit → sync python main.py download --name ZMY_CLASS --type class --path ./src # edit ./src/zmy_class.abap python main.py sync --name ZMY_CLASS --type class --path ./src/zmy_class.abap --corr_nr DEVK901XXX # 2. Batch project sync (auto dependency-ordered) python main.py init --path ./my_project # add objects under src/ python main.py sync --all --path ./my_project --corr_nr DEVK901XXX # 3. Table query: structure (SE11) + data (SE16N) python main.py show-table --name ZMY_TABLE python main.py read-table --name ZMY_TABLE --fields "F1,F2" --where "F1 = 'X'" --max-rows 50 ``` ## Command Reference Global params (before command): `--profile `, `--verify-ssl`. Optional params in `[ ]`. | Category | Command | Key Parameters | |----------|---------|----------------| | CRUD | `create` | `--name --type [--description --source <.abap> --definition <.json> --package <$TMP> --corr_nr]` | | CRUD | `info` | `--name --type` | | CRUD | `download` | `--name --type --path` | | CRUD | `sync` | `--name --type --path --corr_nr` **(REQUIRED)** | | CRUD | `delete` | `--name --type` | | CRUD | `activate` | `--name --type --corr_nr` (built-in NW 7.40 double-activate) | | CRUD | `upload` | `--name --type --path --corr_nr` (lock→write→unlock only; no check/activate) | | CRUD | `syntax-check` | `--name --type` (remote object; no upload/activate) | | Batch | `init` | `--path` | | Batch | `refresh` | `--path` | | Batch | `sync --all` | `--path --corr_nr [--dry-run]` | | Batch | `analyze` | `--path` (dependency analysis) | | Query | `show-table` | `--name` (SE11 structure) | | Query | `read-table` | `--name [--fields --where --max-rows]` (SE16N data) | | Query | `list` | `--type [--package --prefix]` | | Query | `whereused` | `--name --type` | | Query | `search` | `--query` | | Query | `diff` | `--name --type --path` (local vs SAP) | | Transport | `transport list` | — | | Transport | `transport info` | `--corr_nr` | | Transport | `transport release` | `--corr_nr` | | Transport | `transport objects` | `--corr_nr` | | Config | `config show` | — | | Config | `config list-profiles` | — | | Config | `config set` | ` ` | | Config | `auth login` / `auth status` | password stored in keyring | | Other | `run-program` | `--name` (SA38) | | Other | `check` | `--name --type` (ATC) | | Other | `format` | `--name --type` (Pretty Printer) | | Other | `package create` | `--name` | | Other | `cds download` | `--name --path` | | Other | `scaffold` | `--name --template ` — alv-report, bapi-wrapper, interface-class, data-model | Batch sync dependency order: `domain(10) → dataelement(20) → table(30) → tabletype(40) → interface(50) → class(60) → function(70) → report(80)`. Step-wise sync for lock-heavy automation — split the atomic `sync` when lock conflicts are frequent; upload now, verify, activate later: ```bash python main.py upload --name ZMY_CLASS --type class --path ./src/zmy_class.abap --corr_nr DEVK901XXX # lock→write→unlock only python main.py syntax-check --name ZDEPENDENT_REPORT --type report # verify dependents (no upload) python main.py activate --name ZMY_CLASS --type class --corr_nr DEVK901XXX # activate once clean ``` ### Supported Object Types (16) | Category | Types | Has source | |----------|-------|------------| | Programs | `report`, `include` | ✅ | | OOP | `class`, `interface` | ✅ | | Functions | `function` | ✅ | | DDIC base | `domain`, `dataelement`, `table`, `structure` | ✅ | | DDIC ext | `cdsview`, `view` | ✅ | | DDIC no-source | `tabletype`, `messageclass`, `searchhelp`, `lockobject` | ❌ | | Groups | `functiongroup` | ❌ | **Function naming**: must use `group/module`, e.g. `ZMY_FGROUP/Z_MY_FUNC`. ## ⚠️ Constraints (HARD RULES — DO NOT VIOLATE) Full rules: `references/sap-tool-constraints.md`. Violations are intercepted by hooks. 1. **Only `python main.py ` touches SAP** — no `requests`/`urllib`, no curl to ADT/SOAP/RFC, no `python -c` inline, no importing `ADTClient` internals, no hand-built ADT XML. Exceptions: `run-program` custom reports, explicit user request, or developing sap-cli itself. 2. **Never modify SAP standard objects** (`CL_*`, `CX_*`, `IF_*`, `SAPL*`, or any non-user original system) — read-only only: download/info/list/search/whereused/show-table/read-table/diff. When unsure, ask the user. 3. **Never write system tables** (TADIR, E071, SEOCLASS, REPOSRC, D010SINF, T000, TDEVC, TSTC) — read-only SELECT is fine; any write needs explicit authorization. 4. **`sync` must carry `--corr_nr`** — otherwise it triggers an interactive transport-request prompt. 5. **Non-interactive `delete` needs piped confirm** — `echo "yes" | python main.py delete ...` (else EOFError). 6. **DDIC `sync` failure on NW 7.40 (HTTP 406) is a system limit** — do not retry; report to the user for SE09. ## Error Handling (Quick Reference) Full flow: `references/error-handling.md`. | Error Pattern | Action | |---|---| | HTTP 406 (DDIC Lock) | System limit — report to user → SE09 manual DDIC sync | | HTTP 403 (Locked) | Residual enqueue lock — try `run-program` clear-locks report, then SM12 | | HTTP 400 (SaveFailure) | Class DEFINITION mismatch — diff local vs SAP source | | HTTP 404 (DDIC download/sync) | NW 7.40 has no `/source/main` endpoint (7.50+) — DDIC objects only create/info/delete | | HTTP 423 (Transport lock) | Object bound to transport — report to user → SE09 | | Activate fails, still inactive | double-activate built-in; still fails → report → SE09 | | `WITH EMPTY KEY` dump | NW 7.40 unsupported — use `WITH NON-UNIQUE KEY` / `WITH DEFAULT KEY` | | Function name error | Missing `/` separator — use `ZGROUP/Z_FUNC` | | EOFError on delete | Non-interactive — prepend `echo "yes" \|` | General flow: **diagnose** (params / file / transport / network / object existence) → **usage error**: fix & retry → **sap-cli limit**: report, never bypass → **SAP limit**: exhaust automation below → **confirmed un-automatable**: request SAP GUI op. Automation fallbacks — exhaust in order before requesting any SAP GUI action: 1. **Adjust params** — different `--corr_nr`, or `--dry-run` to preview a batch before committing. 2. **`run-program` workaround** — sync + run a helper report (e.g. `ZSAPILOT_CLEAR_LOCKS`) to clear residual enqueue locks. 3. **`delete` + recreate** — only if the object needs a full rewrite; `delete` may fail with HTTP 423 (transport-bound) → then it is SE09. 4. **`activate` retry** — double-activate is built in; if it still fails, stop retrying and report — do not chase other activation strategies. - **Never bypass sap-cli** (no requests / curl / ADTClient) — report the failure and its cause. - **Give the complete change checklist at once** — do the full comparison first (`show-table` vs code field refs); never surface issues incrementally. - **System-table writes** — 4-step authorization: explain reason → list exact statements → state risks & alternatives → await explicit approval. ## NW 7.40 Compatibility (E2E verified — v2.2.1) Full matrix: `docs/NW740-COMPATIBILITY.md`. | Availability | Types | |---|---| | Full (download → edit → sync closed loop) | `report`, `class`, `interface`, `function`, `functiongroup`, `include` | | CRUD only (create/info/delete, no source edit) | `domain`, `dataelement` — DDIC stored as XML at object URI, no `/source/main` endpoint (7.50+ feature) | | Endpoint missing (404/415) | `table`, `structure`, `tabletype`, `view`, `messageclass`, `searchhelp`, `lockobject`, `cdsview` | NW 7.40 specifics: - **DDIC Lock** — `delete` fixed (dedicated Accept header); `sync` still 406. - **Activation false-negative** — first activate may report failure but actually succeed; double-activate is built in. - **ABAP syntax limits** — no string templates `\|...\|`, no inline `DATA(...)`, no `WITH EMPTY KEY`. - **CSRF token** — all writes require it; sap-cli handles automatically.