arc-1 0.9.20 → 0.9.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dist/adt/client.d.ts +31 -3
  2. package/dist/adt/client.d.ts.map +1 -1
  3. package/dist/adt/client.js +76 -6
  4. package/dist/adt/client.js.map +1 -1
  5. package/dist/adt/config.d.ts +7 -0
  6. package/dist/adt/config.d.ts.map +1 -1
  7. package/dist/adt/config.js.map +1 -1
  8. package/dist/adt/ddic-xml.d.ts +30 -1
  9. package/dist/adt/ddic-xml.d.ts.map +1 -1
  10. package/dist/adt/ddic-xml.js +113 -2
  11. package/dist/adt/ddic-xml.js.map +1 -1
  12. package/dist/adt/devtools.d.ts +9 -2
  13. package/dist/adt/devtools.d.ts.map +1 -1
  14. package/dist/adt/devtools.js +126 -5
  15. package/dist/adt/devtools.js.map +1 -1
  16. package/dist/adt/diagnostics.d.ts +110 -4
  17. package/dist/adt/diagnostics.d.ts.map +1 -1
  18. package/dist/adt/diagnostics.js +466 -10
  19. package/dist/adt/diagnostics.js.map +1 -1
  20. package/dist/adt/errors.d.ts +13 -1
  21. package/dist/adt/errors.d.ts.map +1 -1
  22. package/dist/adt/errors.js +58 -0
  23. package/dist/adt/errors.js.map +1 -1
  24. package/dist/adt/features.d.ts.map +1 -1
  25. package/dist/adt/features.js +2 -1
  26. package/dist/adt/features.js.map +1 -1
  27. package/dist/adt/fm-signature.d.ts +1 -1
  28. package/dist/adt/fm-signature.js +1 -1
  29. package/dist/adt/gcts.d.ts +3 -3
  30. package/dist/adt/gcts.d.ts.map +1 -1
  31. package/dist/adt/gcts.js +24 -3
  32. package/dist/adt/gcts.js.map +1 -1
  33. package/dist/adt/http.d.ts +6 -0
  34. package/dist/adt/http.d.ts.map +1 -1
  35. package/dist/adt/http.js +14 -3
  36. package/dist/adt/http.js.map +1 -1
  37. package/dist/adt/structure-hierarchy.d.ts +41 -0
  38. package/dist/adt/structure-hierarchy.d.ts.map +1 -0
  39. package/dist/adt/structure-hierarchy.js +194 -0
  40. package/dist/adt/structure-hierarchy.js.map +1 -0
  41. package/dist/adt/transport.d.ts +43 -4
  42. package/dist/adt/transport.d.ts.map +1 -1
  43. package/dist/adt/transport.js +84 -10
  44. package/dist/adt/transport.js.map +1 -1
  45. package/dist/adt/types.d.ts +104 -0
  46. package/dist/adt/types.d.ts.map +1 -1
  47. package/dist/adt/xml-parser.d.ts +37 -0
  48. package/dist/adt/xml-parser.d.ts.map +1 -1
  49. package/dist/adt/xml-parser.js +102 -0
  50. package/dist/adt/xml-parser.js.map +1 -1
  51. package/dist/authz/policy.d.ts.map +1 -1
  52. package/dist/authz/policy.js +12 -1
  53. package/dist/authz/policy.js.map +1 -1
  54. package/dist/cache/sqlite.d.ts.map +1 -1
  55. package/dist/cache/sqlite.js +10 -0
  56. package/dist/cache/sqlite.js.map +1 -1
  57. package/dist/cli.js +7 -6
  58. package/dist/cli.js.map +1 -1
  59. package/dist/handlers/context.d.ts.map +1 -1
  60. package/dist/handlers/context.js +11 -1
  61. package/dist/handlers/context.js.map +1 -1
  62. package/dist/handlers/diagnose.d.ts.map +1 -1
  63. package/dist/handlers/diagnose.js +88 -4
  64. package/dist/handlers/diagnose.js.map +1 -1
  65. package/dist/handlers/dispatch.d.ts.map +1 -1
  66. package/dist/handlers/dispatch.js +10 -1
  67. package/dist/handlers/dispatch.js.map +1 -1
  68. package/dist/handlers/feature-cache.d.ts +5 -0
  69. package/dist/handlers/feature-cache.d.ts.map +1 -1
  70. package/dist/handlers/feature-cache.js +10 -0
  71. package/dist/handlers/feature-cache.js.map +1 -1
  72. package/dist/handlers/git.d.ts.map +1 -1
  73. package/dist/handlers/git.js +3 -3
  74. package/dist/handlers/git.js.map +1 -1
  75. package/dist/handlers/manage.d.ts.map +1 -1
  76. package/dist/handlers/manage.js +44 -0
  77. package/dist/handlers/manage.js.map +1 -1
  78. package/dist/handlers/object-types.d.ts +1 -1
  79. package/dist/handlers/object-types.d.ts.map +1 -1
  80. package/dist/handlers/object-types.js +58 -51
  81. package/dist/handlers/object-types.js.map +1 -1
  82. package/dist/handlers/query.d.ts.map +1 -1
  83. package/dist/handlers/query.js +35 -3
  84. package/dist/handlers/query.js.map +1 -1
  85. package/dist/handlers/read.d.ts.map +1 -1
  86. package/dist/handlers/read.js +32 -10
  87. package/dist/handlers/read.js.map +1 -1
  88. package/dist/handlers/schemas.d.ts +74 -4
  89. package/dist/handlers/schemas.d.ts.map +1 -1
  90. package/dist/handlers/schemas.js +34 -3
  91. package/dist/handlers/schemas.js.map +1 -1
  92. package/dist/handlers/tool-registry.d.ts +4 -4
  93. package/dist/handlers/tool-registry.d.ts.map +1 -1
  94. package/dist/handlers/tool-registry.js +6 -3
  95. package/dist/handlers/tool-registry.js.map +1 -1
  96. package/dist/handlers/tools.d.ts +4 -1
  97. package/dist/handlers/tools.d.ts.map +1 -1
  98. package/dist/handlers/tools.js +260 -261
  99. package/dist/handlers/tools.js.map +1 -1
  100. package/dist/handlers/transport.d.ts.map +1 -1
  101. package/dist/handlers/transport.js +82 -5
  102. package/dist/handlers/transport.js.map +1 -1
  103. package/dist/handlers/write/create.d.ts.map +1 -1
  104. package/dist/handlers/write/create.js +135 -3
  105. package/dist/handlers/write/create.js.map +1 -1
  106. package/dist/handlers/write/rap.js +2 -2
  107. package/dist/handlers/write/rap.js.map +1 -1
  108. package/dist/handlers/write-helpers.d.ts +1 -0
  109. package/dist/handlers/write-helpers.d.ts.map +1 -1
  110. package/dist/handlers/write-helpers.js +50 -6
  111. package/dist/handlers/write-helpers.js.map +1 -1
  112. package/dist/handlers/write.d.ts.map +1 -1
  113. package/dist/handlers/write.js +18 -2
  114. package/dist/handlers/write.js.map +1 -1
  115. package/dist/plugins/manifest-interpreter.js +1 -1
  116. package/dist/plugins/manifest-interpreter.js.map +1 -1
  117. package/dist/probe/catalog.js +2 -2
  118. package/dist/probe/catalog.js.map +1 -1
  119. package/dist/public/index.js +1 -1
  120. package/dist/public/index.js.map +1 -1
  121. package/dist/public/testing.js +1 -1
  122. package/dist/public/testing.js.map +1 -1
  123. package/dist/public/types.js +1 -1
  124. package/dist/public/types.js.map +1 -1
  125. package/dist/registry/tool-registry.js +1 -1
  126. package/dist/registry/tool-registry.js.map +1 -1
  127. package/dist/server/audit.d.ts +4 -2
  128. package/dist/server/audit.d.ts.map +1 -1
  129. package/dist/server/audit.js +42 -13
  130. package/dist/server/audit.js.map +1 -1
  131. package/dist/server/config.d.ts.map +1 -1
  132. package/dist/server/config.js +42 -1
  133. package/dist/server/config.js.map +1 -1
  134. package/dist/server/logger.d.ts +1 -1
  135. package/dist/server/logger.d.ts.map +1 -1
  136. package/dist/server/logger.js +9 -4
  137. package/dist/server/logger.js.map +1 -1
  138. package/dist/server/plugin-loader.js +1 -1
  139. package/dist/server/plugin-loader.js.map +1 -1
  140. package/dist/server/safe-http-client.js +1 -1
  141. package/dist/server/safe-http-client.js.map +1 -1
  142. package/dist/server/server.d.ts +22 -3
  143. package/dist/server/server.d.ts.map +1 -1
  144. package/dist/server/server.js +80 -12
  145. package/dist/server/server.js.map +1 -1
  146. package/dist/server/sinks/file.d.ts +3 -0
  147. package/dist/server/sinks/file.d.ts.map +1 -1
  148. package/dist/server/sinks/file.js +15 -3
  149. package/dist/server/sinks/file.js.map +1 -1
  150. package/dist/server/sinks/stderr.d.ts.map +1 -1
  151. package/dist/server/sinks/stderr.js +2 -30
  152. package/dist/server/sinks/stderr.js.map +1 -1
  153. package/dist/server/types.d.ts +10 -0
  154. package/dist/server/types.d.ts.map +1 -1
  155. package/dist/server/types.js +4 -0
  156. package/dist/server/types.js.map +1 -1
  157. package/dist/server/ui.js +1 -1
  158. package/dist/server/ui.js.map +1 -1
  159. package/package.json +4 -4
@@ -39,8 +39,9 @@ const TOOL_ANNOTATIONS = {
39
39
  SAPNavigate: { readOnlyHint: true },
40
40
  SAPQuery: { readOnlyHint: true },
41
41
  SAPContext: { readOnlyHint: true },
42
- SAPDiagnose: { readOnlyHint: true },
43
42
  // Mutating, non-destructive (no delete action).
43
+ // SAPDiagnose.apply_quickfix is a write/Update action, so the tool is not read-only.
44
+ SAPDiagnose: { readOnlyHint: false, destructiveHint: false },
44
45
  SAPLint: { readOnlyHint: false, destructiveHint: false },
45
46
  SAPActivate: { readOnlyHint: false, destructiveHint: false },
46
47
  // Mutating AND destructive (delete / unlink / overwriting actions).
@@ -56,55 +57,37 @@ function isBtpMode(config) {
56
57
  // ─── SAPRead Types ──────────────────────────────────────────────────
57
58
  /** All SAPRead types available on on-premise */
58
59
  /** SAPRead types available on BTP ABAP Environment (no PROG, INCL, VIEW, TEXT_ELEMENTS, VARIANTS) */
59
- const SAPREAD_DESC_ONPREM = 'Read SAP ABAP objects. Use SAPRead when you need exact raw source, a specific method body, grep output, inactive drafts, revision history, or metadata. For "what does this object do?", object explanation, spec work, reviews, or pre-change orientation, prefer SAPContext first because it returns intent-level context before raw source. Types: PROG, CLAS, INTF, FUNC, FUGR (use expand_includes=true to get all include sources), INCL, DDLS, DCLS (CDS access controls), DDLX (CDS metadata extensions — UI annotations), BDEF, SRVD, SRVB (service bindings — returns structured binding info: OData version, publish status, service definition ref), SKTD/KTD (Knowledge Transfer Documents — Markdown documentation attached to KTD-capable ABAP objects like DDLS, BDEF, SRVD, SRVB, and packages; KTD is a friendly alias for SKTD), TABL (DDIC TABL — covers transparent tables like T000 AND DDIC structures like BAPIRET2; returns CDS-like source. ARC-1 auto-resolves the URL: tries /sap/bc/adt/ddic/tables/ first, falls back to /sap/bc/adt/ddic/structures/. Note: there is no separate STRU type — TABL is the canonical short type for both, mirroring TADIR R3TR TABL and abapGit conventions), VIEW, DOMA (DDIC domains — returns type info, value table, fixed values), DTEL (data elements — returns domain, labels, search help), TRAN (transaction codes — returns description, program, package), TABLE_CONTENTS (simple row preview — no filter or single-column filter; use TABLE_QUERY for multi-column WHERE), TABLE_QUERY (structured multi-column query on DDIC tables and CDS views via the freestyle endpoint — supports AND conditions, column selection; gated by allowDataPreview; use instead of TABLE_CONTENTS when filtering on multiple fields. Note: CDS views require SAP_BASIS 752+ — NW 7.50/7.51 rejects them with "TABLE is invalid here"), DEVC, SOBJ (BOR business objects — returns method catalog or full implementation), SYSTEM, COMPONENTS, MSAG (message classes — returns class metadata + messages array), TEXT_ELEMENTS, VARIANTS. For CLAS: omit include to get the full class source (definition + implementation combined). The include param is optional — use it only to read class-local sections: definitions (local types), implementations (local helper classes), macros, testclasses (ABAP Unit). For CLAS with method param: use method="*" to list all methods with signatures and visibility, or method="method_name" to read a single method implementation (95% fewer tokens than full source). For SOBJ: returns BOR method catalog; use method param to read a specific method implementation. BSP (deployed UI5/Fiori apps — list apps, browse files, read content; use name to browse app structure, include for subfolder or file), BSP_DEPLOY (query deployed UI5 apps via ABAP Repository OData Service — returns name, package, description). API_STATE (API release state — checks if an object is released for ABAP Cloud / S/4HANA Clean Core; returns contract states C0-C4, successor info; use objectType param for non-class objects). INACTIVE_OBJECTS (list all objects pending activation — no name param needed; use before SAPActivate batch_activate to see what needs activating). AUTH (Authorization Fields — returns check table, domain, conversion exit, org-level flags; on-prem only). FEATURE_TOGGLE (Feature Toggles — returns current toggle state per system from SAP switch framework; on-prem only). ENHO (Enhancement Implementations / BAdI — returns technology type, referenced enhancement object, and BAdI implementations with implementing classes; on-prem only). VERSIONS (list revision history of an object — returns JSON with object metadata and revisions [{id, author, timestamp, versionTitle?, transport?, uri}]; pass optional include for CLAS or group for FUNC; on-prem only and may return 404 for some DDIC types on non-S/4 backends). VERSION_SOURCE (fetch source at a specific revision URI from VERSIONS response; returns raw source text; on-prem only). ' +
60
- 'Optional grep parameter: pass a case-insensitive regex to return only matching source lines (+context, with line numbers) instead of the full objecttoken-efficient search across source-bearing types; for CLAS, matches are annotated with the owning class/method. ' +
61
- 'Optional version parameter (default "active"): set to "inactive" to read the user\'s unactivated draft, or "auto" for the developer view. Active reads include a note when an inactive draft exists.';
62
- const SAPREAD_DESC_BTP = 'Read SAP ABAP objects (BTP ABAP Environment). Use SAPRead when you need exact raw source, a specific method body, grep output, inactive drafts, or metadata. For "what does this object do?", object explanation, spec work, reviews, or pre-change orientation, prefer SAPContext first because it returns intent-level context before raw source. Types: CLAS, INTF, FUNC (released/custom only), FUGR (released/custom only), DDLS (CDS views — primary data model on BTP), DCLS (CDS access controls), DDLX (CDS metadata extensions — UI annotations for Fiori Elements), BDEF (RAP behavior definitions), SRVD (service definitions), SRVB (service bindings — returns structured binding info: OData version, publish status, service definition ref), SKTD/KTD (Knowledge Transfer Documents — Markdown documentation attached to KTD-capable ABAP objects like DDLS, BDEF, SRVD, SRVB, and packages; KTD is a friendly alias for SKTD), TABL (DDIC TABL — covers both custom transparent tables AND DDIC structures; returns CDS-like source. ARC-1 auto-resolves /tables/ vs /structures/ via fallback. Note: there is no separate STRU type — TABL is the canonical short type for both), DOMA (DDIC domains — type info, value table, fixed values), DTEL (data elements — domain, labels, search help), TABLE_CONTENTS (custom tables and released CDS only — SAP standard tables are blocked; no filter or single-column filter only), TABLE_QUERY (structured multi-column query on custom DDIC tables and released CDS views; use when filtering on multiple fields. Requires SAP_BASIS 752+ for CDS view support), DEVC, SYSTEM, COMPONENTS, MSAG (custom message classes only). For CLAS: omit include to get the full class source. The include param reads class-local sections: definitions, implementations, macros, testclasses. For CLAS with method param: use method="*" to list all methods with signatures and visibility, or method="method_name" to read a single method (95% fewer tokens). Note: PROG, INCL, VIEW, TRAN, TEXT_ELEMENTS, VARIANTS are not available on BTP — use CLAS with IF_OO_ADT_CLASSRUN for console applications, and DDLS for data models instead of classic views. VERSIONS and VERSION_SOURCE are currently on-prem only in ARC-1 and are intentionally not exposed on BTP yet. BSP (deployed UI5/Fiori apps — list apps, browse files, read content; use name to browse app structure, include for subfolder or file), BSP_DEPLOY (query deployed UI5 apps via ABAP Repository OData Service — returns name, package, description). API_STATE (API release state — checks if an object is released for ABAP Cloud / Clean Core; returns contract states C0-C4, successor info; essential for cloud development; use objectType param for non-class objects). INACTIVE_OBJECTS (list all objects pending activation — no name param needed; use before SAPActivate batch_activate to see what needs activating). ' +
63
- 'Optional grep parameter: pass a case-insensitive regex to return only matching source lines (+context, with line numbers) instead of the full object token-efficient search across source-bearing types; for CLAS, matches are annotated with the owning class/method. ' +
64
- 'Optional version parameter (default "active"): set to "inactive" to read the user\'s unactivated draft, or "auto" for the developer view. Active reads include a note when an inactive draft exists.';
60
+ const SAPREAD_DESC_ONPREM = 'Read SAP ABAP objects exact raw source, a method body, grep output, inactive drafts, revision history, or metadata. For "what does this object do?", explanations, spec work, reviews, or pre-change orientation, prefer SAPContext first (intent-level context before raw source). ' +
61
+ 'Types: PROG, CLAS, INTF, FUNC, FUGR (expand_includes=true for all include sources), INCL, DDLS, DCLS, DDLX, BDEF, SRVD, SRVB, SKTD/KTD (KTD aliases SKTD), TABL (covers both transparent tables AND DDIC structures — no separate STRU type), VIEW, DOMA, DTEL, TRAN, TABLE_CONTENTS (single-column filter), TABLE_QUERY (multi-column WHERE via the freestyle endpoint; gated by allowDataPreview; CDS views need SAP_BASIS 752+), DEVC, SOBJ (BOR method param reads one method), SYSTEM, COMPONENTS, MSAG, TEXT_ELEMENTS, VARIANTS, BSP, BSP_DEPLOY, API_STATE (contract states C0-C4; objectType for non-class), INACTIVE_OBJECTS (no name; pending-activation list), AUTH, FEATURE_TOGGLE, ENHO, VERSIONS, VERSION_SOURCE. AUTH/FEATURE_TOGGLE/ENHO/VERSIONS/VERSION_SOURCE are on-prem only. ' +
62
+ 'CLAS: to save tokens, prefer method="*" (all signatures), method="NAME" (one body, ~95% fewer tokens than the full class), or grep over reading the full source. Omit include for the full source, or include=definitions|implementations|macros|testclasses for a local section. Full per-type detail: docs_page SAPRead. ' +
63
+ 'Optional grep: case-insensitive regex returning only matching source lines (+context, line numbers); for CLAS, matches are annotated with the owning class/method. ' +
64
+ 'Optional version parameter (default "active"): "inactive" reads the user\'s draft, "auto" the developer view. Active reads note when an inactive draft exists.';
65
+ const SAPREAD_DESC_BTP = 'Read SAP ABAP objects (BTP ABAP Environment) exact raw source, a method body, grep output, inactive drafts, or metadata. For "what does this object do?", explanations, spec work, reviews, or pre-change orientation, prefer SAPContext first (intent-level context before raw source). ' +
66
+ 'Types: CLAS, INTF, FUNC (released/custom only), FUGR (released/custom only), DDLS (primary data model on BTP), DCLS, DDLX, BDEF, SRVD, SRVB, SKTD/KTD (KTD aliases SKTD), TABL (custom tables AND structures — no separate STRU type), DOMA, DTEL, TABLE_CONTENTS (custom tables + released CDS only; standard tables blocked), TABLE_QUERY (multi-column WHERE on custom tables + released CDS; needs SAP_BASIS 752+), DEVC, SYSTEM, COMPONENTS, MSAG (custom only), BSP, BSP_DEPLOY, API_STATE (contract states C0-C4; objectType for non-class), INACTIVE_OBJECTS (no name; pending-activation list). PROG/INCL/VIEW/TRAN/TEXT_ELEMENTS/VARIANTS and VERSIONS/VERSION_SOURCE are not available on BTP (use CLAS with IF_OO_ADT_CLASSRUN for console apps, DDLS for data models). ' +
67
+ 'CLAS: to save tokens, prefer method="*" (all signatures), method="NAME" (one body, ~95% fewer tokens than the full class), or grep over reading the full source. Omit include for the full source, or include=definitions|implementations|macros|testclasses for a local section. Full per-type detail: docs_page SAPRead. ' +
68
+ 'Optional grep: case-insensitive regex returning only matching source lines (+context, line numbers); for CLAS, matches are annotated with the owning class/method. ' +
69
+ 'Optional version parameter (default "active"): "inactive" reads the user\'s draft, "auto" the developer view.';
65
70
  // ─── SAPWrite Types ─────────────────────────────────────────────────
66
71
  const SAPWRITE_DESC_ONPREM = 'Create or update ABAP source code and DDIC metadata. Handles lock/modify/unlock automatically. Supports PROG, CLAS, INTF, FUNC, FUGR, INCL, DDLS, DCLS, DDLX, BDEF, SRVD, SRVB, SKTD/KTD, TABL, TABL/DT, TABL/DS, DOMA, DTEL, MSAG. ' +
67
- 'Type codes are auto-normalized and case-insensitive (e.g., "CLAS/OC" → "CLAS"). ' +
68
- 'For delete, only type and name are required (plus optional transport); other fields are ignored. ' +
69
- 'Optional fields may be omitted entirely do not send empty strings or null to "skip" a field; irrelevant ones are ignored. ' +
70
- 'For CLAS update, pass include="definitions"|"implementations"|"macros"|"testclasses" to update that local include natively; omit include to update source/main. ' +
71
- 'TABL uses source-based writes via /source/main (define table syntax), similar to DDLS/BDEF/SRVD. ' +
72
- 'TABL create: bare "TABL" or "TABL/DT" transparent table (16-char name limit); "TABL/DS" DDIC structure (30-char limit, accepts namespaces like /LEOWM/X). Update/delete/activate discover subtype via SAP search, so the slash form is optional there. ' +
73
- 'DOMA/DTEL use metadata XML writes (not /source/main): provide DDIC fields like dataType, length, fixedValues, typeKind, labels, searchHelp. ' +
74
- 'MSAG (message classes) use metadata XML writes: provide "messages" array with {number, shortText} entries. Create empty then update, or provide messages at creation. ' +
75
- 'SRVB (service bindings) use metadata XML writes: provide serviceDefinition (SRVD name), odataVersion ("V2"/"V4"), optional category (0=UI, 1=Web API). ' +
76
- 'bindingType accepts human-readable values like "ODataV4-UI" which are auto-normalized. ' +
77
- 'SKTD/KTD (Knowledge Transfer Documents, Markdown docs attached to a KTD-capable ABAP object; KTD is a friendly alias for SKTD): create requires refObjectType (parent ADT type+subtype, e.g., "DDLS/DF", "BDEF/BDO", "SRVD/SRV", "SRVB/SVB", "DEVC/K"). Do not use CLAS/OC, INTF/OI, or PROG/P; use ABAP Doc for code objects. A KTD inherits the name of the object it documents — so "name" MUST equal the parent object name (one KTD per object; refObjectName defaults to name and cannot differ). Update takes Markdown in "source"; delete uses the ADT deletion framework (two-step check/delete). Follow creates/updates with SAPActivate(type="SKTD", name="..."). ' +
78
- 'FUGR (function groups): create with package; serves as the parent container for FUNC. Delete the FUGR after deleting all its FMs. ' +
79
- 'FUNC (function modules): require "group" parameter — the parent FUGR must exist (create it first via SAPWrite type=FUGR). Pass structured `parameters` array to manage FM signatures (IMPORTING/EXPORTING/CHANGING/TABLES/EXCEPTIONS/RAISING). Example: parameters=[{kind:"importing",name:"IV_X",type:"STRING",byValue:true},{kind:"exporting",name:"EV_Y",type:"STRING",byValue:true},{kind:"raising",name:"CX_ROOT"}]. Use SAPRead(type=FUNC, includeSignature=true) to read parameters back as structured JSON. SAPGUI-style *"...IMPORTING..."* parameter comment blocks in source are stripped before PUT as defense-in-depth (SAP rejects them with FUNC_ADT028); a warning is appended in that case. ' +
80
- 'For edit_method: surgically replace a single method body in a CLAS without sending the full class source. ' +
81
- 'Provide just the new method implementation code in "source" — 95% fewer tokens than full-class updates. ' +
82
- 'For local handler classes inside a class include (RAP behavior pools, local helpers, test classes), pass the qualified specifier "lhc_project~approve_project" — ARC-1 routes the read+write to /includes/implementations automatically. ' +
83
- 'Auto-detection prefixes: lhc_*/lcl_* → implementations, ltc_* → testclasses. Override with include="definitions"|"implementations"|"macros"|"testclasses" for explicit control. ' +
84
- 'Global-interface methods like "zif_order~create" continue to use /source/main. ' +
85
- 'For batch_create: create and activate multiple objects in a single call — ideal for RAP stacks (TABL → DDLS → DCLS → BDEF → SRVD). Pass "objects" array with dependency order. ' +
86
- 'For scaffold_rap_handlers: derive missing RAP behavior handler signatures from an interface BDEF and optionally create missing lhc_* skeletons plus inject declarations and empty implementation stubs into an existing behavior pool class. ' +
87
- 'For generate_behavior_implementation: one-shot RAP behavior pool — auto-discover the bound BDEF via class metadata (rootEntityRef), scaffold every required handler (creating lhc_<alias> skeletons when missing), write under one lock, and (by default) activate. Reliable equivalent of Eclipse ADT\'s "Generate Behavior Implementation" Cmd+1 quickfix without the broken /sap/bc/adt/quickfixes/proposals/.../create_class_implementation server endpoint. ' +
88
- 'Server-driven objects (ABAP Platform 2025 / SAP_BASIS 8.16+, discovery-gated): DESD (CDS Logical External Schema), DTSC (CDS Static Cache), CSNM (CSN Model), EVTB (RAP Event Binding), EVTO (RAP Event Object), COTA (Communication Target). For these, create/update/delete operate on the generic AFF blue:blueSource object — pass the AFF JSON in "source" (e.g. {"formatVersion":"1","header":{...}}); create leaves the object inactive, so follow with SAPActivate. On pre-8.16 systems these types return a clean "requires SAP_BASIS 8.16+" error.';
72
+ 'Type codes are auto-normalized and case-insensitive (e.g., "CLAS/OC" → "CLAS"). For delete, only type and name are required (plus optional transport). ' +
73
+ 'Source objects (PROG/CLAS/INTF/DDLS/DCLS/DDLX/BDEF/SRVD/TABL/INCL) write via /source/main. CLAS update: pass include=definitions|implementations|macros|testclasses to write a local include; omit for source/main. ' +
74
+ 'TABL create: "TABL"/"TABL/DT" transparent table (16-char name); "TABL/DS" structure (30-char, namespaces OK); update/delete/activate auto-discover the subtype. ' +
75
+ 'Metadata-XML writes (not /source/main): DOMA/DTEL (dataType, length, fixedValues, typeKind, labels, searchHelp); MSAG (messages array of {number, shortText}); SRVB (serviceDefinition, odataVersion V2/V4, optional category 0=UI/1=Web API; bindingType like "ODataV4-UI" auto-normalized). ' +
76
+ 'SKTD/KTD (Markdown docs on a KTD-capable object; KTD aliases SKTD): create needs refObjectType (parent type+subtype, e.g. "DDLS/DF"); "name" MUST equal the parent name; update takes Markdown in source; then SAPActivate(type="SKTD"). ' +
77
+ 'FUNC: require "group" (parent FUGR must exist create it first); pass structured `parameters` for the signature (read back via SAPRead includeSignature=true). ' +
78
+ 'edit_method: replace one CLAS method body via source (95% fewer tokens than full-class). Local-class methods use the qualified specifier (e.g. "lhc_project~approve_project"); auto-routing: lhc_*/lcl_* implementations, ltc_* testclasses (override with include=); zif_*~* stays on /source/main. ' +
79
+ 'batch_create: create+activate multiple objects in dependency order via the "objects" array (RAP stacks TABL→DDLS→DCLS→BDEF→SRVD). scaffold_rap_handlers / generate_behavior_implementation: derive RAP behavior-pool handlers from the BDEF (the latter auto-discovers the BDEF via rootEntityRef and activates by default). ' +
80
+ 'Server-driven objects (SAP_BASIS 8.16+, discovery-gated): DESD, DTSC, CSNM, EVTB, EVTO, COTA create/update/delete with AFF JSON in "source", then SAPActivate; pre-8.16 returns a clean "requires 8.16+" error. ' +
81
+ 'Full per-type field reference: docs_page SAPWrite. ';
89
82
  const SAPWRITE_DESC_BTP = 'Create or update ABAP source code and DDIC metadata (BTP ABAP Environment). Handles lock/modify/unlock automatically. Supports CLAS, INTF, DDLS, DCLS, DDLX, BDEF, SRVD, SRVB, SKTD/KTD, TABL, TABL/DT, TABL/DS, DOMA, DTEL, MSAG. ' +
90
- 'Type codes are auto-normalized and case-insensitive (e.g., "CLAS/OC" → "CLAS"). ' +
91
- 'For delete, only type and name are required (plus optional transport); other fields are ignored. ' +
92
- 'Optional fields may be omitted entirely do not send empty strings or null to "skip" a field; irrelevant ones are ignored. ' +
93
- 'For CLAS update, pass include="definitions"|"implementations"|"macros"|"testclasses" to update that local include natively; omit include to update source/main. ' +
94
- 'TABL supports custom table source writes via /source/main (define table syntax). ' +
95
- 'DOMA/DTEL use metadata XML writes (not /source/main): provide DDIC fields like dataType, length, fixedValues, typeKind, labels, searchHelp. ' +
96
- 'MSAG (message classes) use metadata XML writes: provide "messages" array with {number, shortText} entries. ' +
97
- 'SRVB (service bindings) use metadata XML writes: provide serviceDefinition (SRVD name), odataVersion ("V2"/"V4"), optional category (0=UI, 1=Web API). ' +
98
- 'bindingType accepts human-readable values like "ODataV4-UI" which are auto-normalized. ' +
99
- 'SKTD/KTD (Knowledge Transfer Documents, Markdown docs attached to a KTD-capable ABAP object; KTD is a friendly alias for SKTD): create requires refObjectType (parent ADT type+subtype, e.g., "DDLS/DF", "BDEF/BDO", "SRVD/SRV", "SRVB/SVB", "DEVC/K"). Do not use CLAS/OC, INTF/OI, or PROG/P; use ABAP Doc for code objects. A KTD inherits the name of the object it documents — so "name" MUST equal the parent object name (one KTD per object; refObjectName defaults to name and cannot differ). Update takes Markdown in "source"; delete uses the ADT deletion framework (two-step check/delete). Follow creates/updates with SAPActivate(type="SKTD", name="..."). ' +
100
- 'Must use ABAP Cloud language version (no classic statements). Only Z*/Y* namespace allowed on BTP. ' +
101
- 'For edit_method: surgically replace a single method body in a CLAS without sending the full class source. ' +
102
- 'For local handler classes inside a class include (RAP behavior pools, local helpers, test classes), pass the qualified specifier "lhc_project~approve_project" — ARC-1 routes the read+write to /includes/implementations automatically. ' +
103
- 'Auto-detection prefixes: lhc_*/lcl_* → implementations, ltc_* → testclasses. Override with include= for explicit control. ' +
104
- 'For batch_create: create and activate multiple objects in a single call — ideal for RAP stacks (TABL → DDLS → DCLS → BDEF → SRVD). ' +
105
- 'For scaffold_rap_handlers: derive missing RAP behavior handler signatures from an interface BDEF and optionally create missing lhc_* skeletons plus inject declarations and empty implementation stubs into an existing behavior pool class. ' +
106
- 'For generate_behavior_implementation: one-shot RAP behavior pool — auto-discover the bound BDEF via class metadata (rootEntityRef), scaffold every required handler (creating lhc_<alias> skeletons when missing), write under one lock, and (by default) activate. ' +
107
- 'Server-driven objects (8.16+ / ABAP Cloud, discovery-gated): DESD, DTSC, CSNM, EVTB, EVTO, COTA — create/update/delete operate on the generic AFF blue:blueSource object (pass AFF JSON in "source"); create leaves the object inactive, so follow with SAPActivate. Pre-8.16 systems return a clean "requires SAP_BASIS 8.16+" error.';
83
+ 'Must use ABAP Cloud language version (no classic statements); only Z*/Y* namespace. Type codes are auto-normalized (e.g. "CLAS/OC" → "CLAS"). For delete, only type and name are required (plus optional transport). ' +
84
+ 'Source objects (CLAS/INTF/DDLS/DCLS/DDLX/BDEF/SRVD/TABL) write via /source/main. CLAS update: pass include=definitions|implementations|macros|testclasses for a local include; omit for source/main. ' +
85
+ 'Metadata-XML writes (not /source/main): DOMA/DTEL (dataType, length, fixedValues, typeKind, labels, searchHelp); MSAG (messages array of {number, shortText}); SRVB (serviceDefinition, odataVersion V2/V4, optional category 0=UI/1=Web API). ' +
86
+ 'SKTD/KTD (Markdown docs on a KTD-capable object; KTD aliases SKTD): create needs refObjectType (e.g. "DDLS/DF"); "name" MUST equal the parent name; update takes Markdown in source; then SAPActivate(type="SKTD"). ' +
87
+ 'edit_method: replace one CLAS method body via source. Local-class methods use the qualified specifier (e.g. "lhc_project~approve_project"); auto-routing lhc_*/lcl_* → implementations, ltc_* → testclasses (override with include=). ' +
88
+ 'batch_create: create+activate multiple objects in dependency order (RAP stacks TABL→DDLS→DCLS→BDEF→SRVD). scaffold_rap_handlers / generate_behavior_implementation: derive RAP behavior-pool handlers from the BDEF (the latter auto-discovers via rootEntityRef and activates by default). ' +
89
+ 'Server-driven objects (8.16+, discovery-gated): DESD, DTSC, CSNM, EVTB, EVTO, COTA create/update/delete with AFF JSON in "source", then SAPActivate; pre-8.16 returns a clean "requires 8.16+" error. ' +
90
+ 'Full per-type field reference: docs_page SAPWrite. ';
108
91
  // Prepended to both SAPWrite descriptions. The schema lists every optional field for every
109
92
  // object type/action, but each call uses only a small subset — GPT/OpenAI callers tend to
110
93
  // fill the rest with empty/null/placeholder values. This steers the model to a minimal first
@@ -116,101 +99,65 @@ const SAPWRITE_MINIMAL_PAYLOAD_GUIDE = 'MINIMAL PAYLOAD — send ONLY the fields
116
99
  "delete needs only {action, type, name}; DOMA/DTEL/MSAG/SRVB need {action, type, name} plus that type's own DDIC fields; FUNC also needs group. " +
117
100
  'Do NOT send `include` unless type=CLAS, and do NOT send DDIC/metadata fields (dataType, length, decimals, signExists, lowercase, typeKind, domainName, odataVersion, category, version, labels, …) on a source-object or delete call. ';
118
101
  // ─── SAPContext Types ───────────────────────────────────────────────
119
- const SAPCONTEXT_DESC_ONPREM = 'Primary tool for understanding ABAP objects before specs, reviews, explanations, or changes. Use SAPContext instead of SAPRead when the user asks what a class, interface, program, function module, or CDS view does. For action="deps" it returns intent/context first: the object KTD when available, then compressed dependency contracts. Use SAPRead later only for exact source, method bodies, grep, drafts, revisions, or metadata.\n\n' +
120
- 'Get compressed dependency context or CDS blast-radius impact for an ABAP / CDS object.\n\n' +
121
- "Decision rule pick the action based on the user's question:\n" +
122
- '- "What breaks if I change <CDS view>?" / "Who consumes <I_*>?" / "Impact analysis on <DDLS>" / "Blast radius" → action="impact"\n' +
123
- '- "What does <object> do?" / "Explain <object>" / "Prepare a spec/change/review for <object>" / "Understand dependencies before editing <object>" / "What does X depend on?" → action="deps" (default)\n' +
124
- '- "Find all callers of <object>" (cache-warmup required) → action="usages"\n\n' +
125
- 'action="impact" (CDS blast-radius, DDLS only): ALWAYS use this for CDS change-impact questions. Returns upstream AST dependencies plus downstream where-used results classified into RAP-aware buckets: projectionViews, bdefs, serviceDefinitions, serviceBindings, accessControls (DCLS), metadataExtensions (DDLX), abapConsumers, documentation (SKTD), tables, other. Also emits additive sibling-consistency diagnostics (consistencyHints + siblingExtensionAnalysis) when sibling DDLS variants in the same package show asymmetric metadata-extension coverage. DO NOT replicate this with SAPQuery against DDDDLSRC/ACMDCLSRC/DDLXSRC_SRC/SRVDSRC_SRC those text scans produce noise (non-dependency matches, package group nodes) that this classifier already filters out. Optional includeIndirect=true widens to transitive consumers. Optional siblingCheck=false disables sibling analysis; siblingMaxCandidates controls fan-out (default 4, hard cap 10).\n\n' +
126
- 'action="deps" (default): Returns the target object KTD first when one exists, then only the public API contracts (method signatures, interface definitions, type declarations) of all objects that the target depends on — NOT the full source code. The most token-efficient way to understand an object before editing. Instead of N separate SAPRead calls returning full source (~200 lines each), returns ONE response with KTD context plus compressed contracts (~15-30 lines each). Typical compression: 7-30x fewer tokens.\n\n' +
127
- 'What deps extracts per dependency:\n' +
128
- '- Classes: CLASS DEFINITION with PUBLIC SECTION only (methods, types, constants). PROTECTED, PRIVATE and IMPLEMENTATION stripped.\n' +
129
- '- Interfaces: Full interface definition (interfaces are already public contracts).\n' +
130
- '- Function modules: FUNCTION signature block only (IMPORTING/EXPORTING parameters).\n' +
131
- '- CDS views (DDLS): All data sources (tables, other CDS views), association targets, and compositions. ' +
132
- "Each dependency's full source is included (table definitions, CDS DDL). Essential for CDS unit test generation — " +
133
- 'provides the dependency graph and field catalogs needed for cl_cds_test_environment doubles.\n\n' +
134
- 'Filtering (deps): SAP standard objects (CL_ABAP_*, IF_ABAP_*, CX_SY_*) are excluded. Custom objects (Z*, Y*) are prioritized.\n\n' +
135
- 'Use SAPContext BEFORE writing code that modifies or extends existing objects. ' +
136
- 'Use SAPRead after SAPContext when you need exact source or method-level detail.\n\n' +
137
- 'For non-CDS reverse-lookup, use SAPNavigate(action="references"). For CDS reverse-lookup, ALWAYS prefer action="impact" over SAPNavigate it returns the same where-used data pre-classified into RAP buckets.';
138
- const SAPCONTEXT_DESC_BTP = 'Primary tool for understanding ABAP objects before specs, reviews, explanations, or changes (BTP ABAP Environment). Use SAPContext instead of SAPRead when the user asks what a class, interface, or CDS view does. For action="deps" it returns intent/context first: the object KTD when available, then compressed dependency contracts. Use SAPRead later only for exact source, method bodies, grep, drafts, or metadata.\n\n' +
139
- 'Get compressed dependency context or CDS blast-radius impact for an ABAP / CDS object (BTP ABAP Environment).\n\n' +
140
- "Decision rule — pick the action based on the user's question:\n" +
141
- '- "What breaks if I change <CDS view>?" / "Who consumes <I_*>?" / "Impact analysis on <DDLS>" / "Blast radius" → action="impact"\n' +
142
- '- "What does <object> do?" / "Explain <object>" / "Prepare a spec/change/review for <object>" / "Understand dependencies before editing <object>" / "What does X depend on?" → action="deps" (default)\n\n' +
143
- 'action="impact" (CDS blast-radius, DDLS only): ALWAYS use this for CDS change-impact questions. Returns upstream AST dependencies plus downstream where-used results classified into RAP-aware buckets: projectionViews, bdefs, serviceDefinitions, serviceBindings, accessControls (DCLS), metadataExtensions (DDLX), abapConsumers, documentation (SKTD), tables, other. Also emits additive sibling-consistency diagnostics (consistencyHints + siblingExtensionAnalysis) when sibling DDLS variants in the same package show asymmetric metadata-extension coverage. DO NOT replicate this with SAPQuery — the classifier already filters noise. Optional includeIndirect=true widens to transitive consumers. Optional siblingCheck=false disables sibling analysis; siblingMaxCandidates controls fan-out (default 4, hard cap 10).\n\n' +
144
- 'action="deps" (default): Returns the target object KTD first when one exists, then only the public API contracts (method signatures, interface definitions, type declarations) of all objects that the target depends on — NOT the full source code.\n\n' +
145
- 'What deps extracts per dependency:\n' +
146
- '- Classes: CLASS DEFINITION with PUBLIC SECTION only (methods, types, constants).\n' +
147
- '- Interfaces: Full interface definition (interfaces are already public contracts).\n' +
148
- '- CDS views (DDLS): All data sources (tables, other CDS views), association targets, and compositions. ' +
149
- "Each dependency's full source is included. Essential for CDS unit test generation.\n\n" +
150
- 'On BTP: released SAP objects (CL_ABAP_*, IF_ABAP_*) are included since they form the primary development API surface. ' +
151
- 'Custom objects (Z*, Y*) are also included.\n\n' +
152
- 'Use SAPContext BEFORE writing code that modifies or extends existing objects. Use SAPRead after SAPContext when you need exact source or method-level detail.';
102
+ const SAPCONTEXT_DESC_ONPREM = 'Primary tool for understanding ABAP/CDS objects before specs, reviews, explanations, or changes use instead of SAPRead when the user asks what an object does. Returns intent first (the object KTD when available) then compressed dependency contracts. Use SAPRead after SAPContext for exact source/method bodies/grep/drafts.\n\n' +
103
+ "Decision rule pick the action from the user's question:\n" +
104
+ '- "What breaks if I change <CDS>?" / "Who consumes <I_*>?" / "Blast radius" → action="impact" (DDLS only).\n' +
105
+ '- "Which includes/appends extend <TABL>?" action="structure", type="TABL".\n' +
106
+ '- "What does <object> do?" / "Explain" / "deps before editing" → action="deps" (default).\n' +
107
+ '- "Find all callers of <object>" (needs cache warmup) → action="usages".\n\n' +
108
+ 'impact (CDS blast-radius): upstream AST deps + downstream where-used, classified into RAP buckets (projectionViews, bdefs, serviceDefinitions, serviceBindings, accessControls, metadataExtensions, abapConsumers, documentation, tables, other) + sibling-consistency hints. Use this instead of text-scanning DDDDLSRC/ACMDCLSRC with SAPQuery (it filters the noise). Optional includeIndirect, siblingCheck, siblingMaxCandidates.\n' +
109
+ 'deps (default): target KTD + the public API contracts of its dependencies (not full source) one compact response vs N SAPRead calls (7-30x fewer tokens); SAP standard objects filtered out. For CDS, includes dependency DDL/field catalogs for cl_cds_test_environment.\n' +
110
+ 'structure (TABL only): the DDIC include/append tree.\n\n' +
111
+ 'Use SAPContext BEFORE editing existing objects. For non-CDS reverse-lookup use SAPNavigate(references); for CDS prefer impact. Full detail: docs_page SAPContext.';
112
+ const SAPCONTEXT_DESC_BTP = 'Primary tool for understanding ABAP/CDS objects before specs, reviews, explanations, or changes (BTP ABAP Environment) use instead of SAPRead when the user asks what an object does. Returns intent first (object KTD when available) then compressed dependency contracts.\n\n' +
113
+ "Decision rule pick the action from the user's question:\n" +
114
+ '- "What breaks if I change <CDS>?" / "Who consumes <I_*>?" / "Blast radius" action="impact" (DDLS only).\n' +
115
+ '- "Which includes/appends extend <TABL>?" action="structure", type="TABL".\n' +
116
+ '- "What does <object> do?" / "Explain" / "deps before editing" → action="deps" (default).\n\n' +
117
+ 'impact (CDS blast-radius): upstream AST deps + downstream where-used classified into RAP buckets (projectionViews, bdefs, serviceDefinitions, serviceBindings, accessControls, metadataExtensions, abapConsumers, documentation, tables, other) + sibling-consistency hints; filters the noise that text-scanning with SAPQuery produces. Optional includeIndirect, siblingCheck, siblingMaxCandidates.\n' +
118
+ 'deps (default): target KTD + the public API contracts of its dependencies (not full source). On BTP, released SAP objects (CL_ABAP_*/IF_ABAP_*) and custom Z/Y are included.\n' +
119
+ 'structure (TABL only): the DDIC include/append tree.\n\n' +
120
+ 'Use SAPContext BEFORE editing existing objects; SAPRead afterwards for exact source. Full detail: docs_page SAPContext.';
153
121
  // ─── SAPQuery ───────────────────────────────────────────────────────
154
- const SAPQUERY_DESC_ONPREM = 'Execute ABAP SQL queries against SAP tables. Returns structured data with column names and rows. ' +
155
- 'Powerful for reverse-engineering: query metadata tables like DD02L (table catalog), DD03L (field catalog), ' +
156
- 'SWOTLV (BOR method implementations), TADIR (object directory), TFDIR (function modules). ' +
157
- 'If a table is not found, similar table names will be suggested automatically. ' +
158
- 'Note: Uses the ADT freestyle SQL endpoint (same family as ADT SQL Console in Eclipse). ABAP SQL language supports JOINs and subqueries, but this endpoint parser can reject valid-looking statements on some backend versions (for example grammar errors, single-SELECT enforcement). ARC-1 automatically chunks simple long literal IN lists; if parsing still fails, simplify to one SELECT and split multi-table logic into staged single-table queries (SAP Note 3605050).\n\n' +
159
- 'CDS impact analysis: DO NOT query DDDDLSRC, ACMDCLSRC, DDLXSRC_SRC, or SRVDSRC_SRC to find CDS consumers — those text scans produce noise (substring matches, package group nodes, generated patterns). Use SAPContext(action="impact", type="DDLS", name="...") instead — it uses SAP\'s where-used index and returns bucketed, filtered results (projection views, BDEFs, SRVDs, access controls, documentation, ABAP consumers).';
122
+ const SAPQUERY_DESC_ONPREM = 'Execute ABAP SQL queries against SAP tables. Returns columns + rows. Good for reverse-engineering metadata tables (DD02L, DD03L, TADIR, TFDIR, SWOTLV). Unknown tables get name suggestions. ' +
123
+ 'Uses the ADT freestyle SQL endpoint; its parser can reject valid-looking statements on some releases ARC-1 automatically chunks simple long literal IN lists; if parsing still fails, use one SELECT and stage multi-table logic (SAP Note 3605050). ' +
124
+ 'To find CDS consumers do NOT text-scan DDDDLSRC/ACMDCLSRC/DDLXSRC_SRC — use SAPContext(action="impact", type="DDLS") (where-used index, filtered buckets).';
160
125
  const SAPQUERY_DESC_BTP = 'Execute ABAP SQL queries (BTP ABAP Environment). Returns structured data with column names and rows. ' +
161
126
  'IMPORTANT: On BTP, only custom Z/Y tables and released CDS entities can be queried. ' +
162
127
  'SAP standard tables (MARA, VBAK, DD02L, DD03L, TADIR, etc.) are blocked. ' +
163
128
  'Use released CDS views instead: I_LANGUAGE, I_COUNTRY, I_CURRENCY, I_UnitOfMeasure, etc. ' +
164
129
  'If a table is not found, similar table names will be suggested automatically.';
165
130
  // ─── SAPSearch ──────────────────────────────────────────────────────
166
- const SAPSEARCH_DESC_ONPREM = 'Search for ABAP objects, exact object-directory entries, or source code. Three modes:\n' +
167
- '1. Object search (default): Search by name pattern with wildcards (* for any characters). Returns object type, name, package, description, and ADT URI. Use this to find classes, programs, function modules, tables, etc.\n' +
168
- '2. TADIR lookup (searchType="tadir_lookup"): Exact cross-package object lookup for one or more names via ADT repository quick search. Use this before create/reset workflows instead of long SAPQuery TADIR IN-lists.\n' +
169
- '3. Source code search (searchType="source_code"): Full-text search within ABAP source code across the system. Use this to find all objects containing a specific string (e.g., a method call, variable name, or class reference). Requires SAP_BASIS >= 7.51.\n\n' +
170
- "Tips: BOR business objects appear as SOBJ type in results. The uri field from results can be used directly with SAPNavigate for references. The objectType field from results can be passed directly to SAPRead/SAPWrite/SAPActivate (ARC-1 auto-normalizes slash suffixes like DDLS/DF, CLAS/OC, PROG/P).\n\nNote: Searches object names only (classes, tables, CDS views, etc.) — field/column names are not searchable here. To find fields by name, use SAPRead(type='DDLS', include='elements') for CDS views or SAPQuery against DD03L.";
131
+ const SAPSEARCH_DESC_ONPREM = 'Search for ABAP objects, exact object-directory entries, or source code. Modes:\n' +
132
+ '1. Object search (default): name pattern with wildcards (*); returns type, name, package, description, ADT URI.\n' +
133
+ '2. TADIR lookup (searchType="tadir_lookup"): exact cross-package lookup of one or more names (prefer over long SAPQuery TADIR IN-lists).\n' +
134
+ '3. Source code search (searchType="source_code"): full-text search across source (SAP_BASIS 7.51).\n' +
135
+ "Tips: BOR objects appear as SOBJ; the uri field feeds SAPNavigate, objectType feeds SAPRead/SAPWrite/SAPActivate. Searches object NAMES only for field names use SAPRead(type='DDLS', include='elements') or SAPQuery on DD03L.";
171
136
  const SAPSEARCH_DESC_BTP = 'Search for ABAP objects, exact object-directory entries, or source code (BTP ABAP Environment). Three modes:\n' +
172
137
  '1. Object search (default): Search by name pattern with wildcards. Returns released SAP objects and custom Z/Y objects. Classic programs, includes, and DDIC views are not searchable on BTP.\n' +
173
138
  '2. TADIR lookup (searchType="tadir_lookup"): Exact object lookup for one or more names via ADT repository quick search.\n' +
174
139
  '3. Source code search (searchType="source_code"): Full-text search within ABAP source code.\n\n' +
175
140
  "Tips: On BTP, focus on classes (CL_*), interfaces (IF_*), CDS views (I_*), and custom Z/Y objects.\n\nNote: Searches object names only (classes, CDS views, etc.) — field/column names are not searchable here. To find fields by name, use SAPRead(type='DDLS', include='elements') for CDS views.";
176
141
  // ─── SAPTransport ───────────────────────────────────────────────────
177
- const SAPTRANSPORT_DESC_ONPREM = 'Manage CTS transport requests (SE09/SE10 equivalent). ' +
178
- 'Actions: list (defaults to current user, modifiable transports both Workbench and Customizing), ' +
179
- 'get (details with tasks and objects), create (K=Workbench, W=Customizing, T=Transport of Copies), ' +
180
- 'release, delete, remove_object (remove an object, keep the request), reassign (change owner), release_recursive (release tasks first, then parent), ' +
181
- 'check (check if a package requires a transport — provide type, name, package), ' +
182
- 'history (find transports referencing an object provide type, name; read-only, works without SAP_ALLOW_TRANSPORT_WRITES). ' +
183
- 'Transport IDs look like A4HK900123. Status: D=modifiable, R=released.';
184
- const SAPTRANSPORT_DESC_BTP = 'Manage transport requests (BTP ABAP Environment, SE09/SE10 equivalent). ' +
185
- 'Actions: list (defaults to current user, modifiable transports both Workbench and Customizing), ' +
186
- 'get (details with tasks and objects), create (K=Workbench, W=Customizing, T=Transport of Copies), ' +
187
- 'release, delete, remove_object (remove an object, keep the request), reassign (change owner), release_recursive (release tasks first, then parent), ' +
188
- 'check (check if a package requires a transport — provide type, name, package), ' +
189
- 'history (find transports referencing an object — provide type, name; read-only, works without SAP_ALLOW_TRANSPORT_WRITES). ' +
190
- 'On BTP, transport release triggers a gCTS push to the software component Git repository. ' +
191
- 'Import into target systems is done via the Manage Software Components app or Cloud Transport Management Service (cTMS), not via this tool.';
142
+ const SAPTRANSPORT_DESC_ONPREM = 'Manage CTS transport requests (SE09/SE10). Actions: list (current user, modifiable), get (tasks + objects), ' +
143
+ 'create (always a Workbench (K) request the package/target sets target & layer, not the request category; optional explicit target), ' +
144
+ 'release, delete, remove_object (keep the request), reassign (change owner), release_recursive (tasks then parent), ' +
145
+ 'check (does a package need a transport type, name, package), history (transports referencing an object — type, name; read-only, no write scope needed). ' +
146
+ 'IDs look like A4HK900123. Status: D=modifiable, R=released.';
147
+ const SAPTRANSPORT_DESC_BTP = 'Manage transport requests (BTP ABAP Environment, SE09/SE10). Actions: list (current user, modifiable), get (tasks + objects), ' +
148
+ 'create (always a Workbench (K) request — the package/target sets target & layer; optional explicit target), ' +
149
+ 'release, delete, remove_object (keep the request), reassign (change owner), release_recursive (tasks then parent), ' +
150
+ 'check (does a package need a transport — type, name, package), history (transports referencing an object type, name; read-only). ' +
151
+ 'On BTP, release triggers a gCTS push to the software-component Git repo; import is via Manage Software Components / cTMS, not this tool.';
192
152
  // ─── SAPManage ──────────────────────────────────────────────────────
193
- const SAPMANAGE_DESC_ONPREM = 'Probe and report SAP system capabilities. Use this BEFORE attempting operations that depend on optional ' +
194
- 'features (abapGit, RAP/CDS, AMDP, HANA, UI5/Fiori, CTS transports, FLP customization). Also handles package (DEVC) lifecycle operations.\n\n' +
153
+ const SAPMANAGE_DESC_ONPREM = 'Probe and report SAP system capabilities. Use BEFORE operations that depend on optional features ' +
154
+ '(abapGit, RAP/CDS, AMDP, HANA, UI5/Fiori, CTS transports, FLP). Also handles package (DEVC) lifecycle.\n\n' +
195
155
  'Actions:\n' +
196
- '- "features": Get cached feature status from last probe (fast, no SAP round-trip). ' +
197
- 'Returns which features are available, their mode (auto/on/off), and when they were last probed.\n' +
198
- '- "probe": Re-probe the SAP system now (runs feature probes, auth checks, and ADT discovery refresh). ' +
199
- 'Use this on first use or if you suspect feature availability has changed.\n' +
200
- '- "cache_stats": Show object cache health and warmup state.\n' +
201
- '- "flp_list_catalogs": List FLP business catalogs.\n' +
202
- '- "flp_list_groups": List FLP groups.\n' +
203
- '- "flp_list_tiles": List tiles in a catalog (requires "catalogId").\n' +
204
- '- "create_package": Create a package (DEVC) via ADT packages API.\n' +
205
- '- "delete_package": Delete an existing package.\n' +
206
- '- "flp_create_catalog": Create a business catalog (requires "domainId", "title").\n' +
207
- '- "flp_create_group": Create a group (requires "groupId", "title").\n' +
208
- '- "flp_create_tile": Create a tile in a catalog (requires "catalogId", "tile").\n' +
209
- '- "flp_add_tile_to_group": Add a catalog tile to a group (requires "groupId", "catalogId", "tileInstanceId").\n' +
210
- '- "flp_delete_catalog": Delete a business catalog (requires "catalogId").\n\n' +
211
- 'Returns JSON with features, each having: id, available (bool), mode, message, and probedAt timestamp. ' +
212
- 'Also returns systemType ("btp" or "onprem") for understanding available capabilities. ' +
213
- '"available: false" means do NOT attempt operations that depend on it.';
156
+ '- "features": cached feature status (fast, no round-trip; id, available, mode, probedAt). "probe": re-probe now (feature probes + auth + discovery refresh). "cache_stats": object cache health.\n' +
157
+ '- "create_package" / "delete_package" / "change_package": DEVC lifecycle via ADT packages API.\n' +
158
+ '- FLP read: flp_list_catalogs, flp_list_groups, flp_list_tiles (catalogId). FLP write: flp_create_catalog, flp_create_group, flp_create_tile, flp_add_tile_to_group, flp_delete_catalog.\n' +
159
+ '- "set_api_state": release/revoke an object\'s API release contract (objectUri, or name+objectType; apiState defaults RELEASED, contract defaults C1 — C0 for SRVD, C3 for classic views). Write counterpart of SAPRead(type="API_STATE").\n\n' +
160
+ 'Returns features + systemType ("onprem"/"btp"); "available: false" means do NOT attempt dependent operations.';
214
161
  const SAPMANAGE_DESC_BTP = 'Probe and report SAP system capabilities (BTP ABAP Environment). ' +
215
162
  'Returns feature status and system type. Also handles package (DEVC) lifecycle operations.\n\n' +
216
163
  'Actions:\n' +
@@ -219,7 +166,9 @@ const SAPMANAGE_DESC_BTP = 'Probe and report SAP system capabilities (BTP ABAP E
219
166
  '- "cache_stats": Show object cache health and warmup state.\n' +
220
167
  '- "create_package": Create a package (DEVC) via ADT packages API.\n' +
221
168
  '- "delete_package": Delete an existing package.\n' +
222
- '- FLP actions: flp_list_catalogs, flp_list_groups, flp_list_tiles, flp_create_catalog, flp_create_group, flp_create_tile, flp_add_tile_to_group, flp_delete_catalog.\n\n' +
169
+ '- FLP actions: flp_list_catalogs, flp_list_groups, flp_list_tiles, flp_create_catalog, flp_create_group, flp_create_tile, flp_add_tile_to_group, flp_delete_catalog.\n' +
170
+ '- "set_api_state": Release (or revoke) an object\'s API release contract for ABAP Cloud / Clean Core ' +
171
+ '(requires "objectUri", or "name" + "objectType"; "apiState" defaults to RELEASED, "contract" defaults to C1 — pass C0 for SRVD, C3 for classic views). The write counterpart of SAPRead(type="API_STATE").\n\n' +
223
172
  'Returns JSON with features and systemType="btp". On BTP, RAP/CDS and transports are always available. ' +
224
173
  'abapGit, AMDP, UI5/BSP, and FLP customization may not be available depending on the BTP ABAP configuration.';
225
174
  const SAPMANAGE_ACTIONS_READ = [
@@ -239,6 +188,7 @@ const SAPMANAGE_ACTIONS_WRITE = [
239
188
  'flp_create_tile',
240
189
  'flp_add_tile_to_group',
241
190
  'flp_delete_catalog',
191
+ 'set_api_state',
242
192
  ];
243
193
  const SAPTRANSPORT_ACTIONS_READ = ['list', 'get', 'check', 'history', 'layers', 'targets'];
244
194
  const SAPTRANSPORT_ACTIONS_WRITE = ['create', 'release', 'delete', 'remove_object', 'reassign', 'release_recursive'];
@@ -336,8 +286,8 @@ function buildSAPSearchTool(btp, textSearchAvailable) {
336
286
  };
337
287
  }
338
288
  // ─── GPT/OpenAI strict-mode nullable helper (issue #360) ────────────
339
- /** Add `null` to a property's `type` (string ["string","null"]). Per OpenAI's Structured
340
- * Outputs guide, null goes in `type` ONLY never added to `enum`. */
289
+ /** Add `null` to a property's `type` (string -> ["string","null"]). Per OpenAI's Structured
290
+ * Outputs guide, null goes in `type` only, never into `enum`. */
341
291
  function makeNullableType(def) {
342
292
  const d = { ...def };
343
293
  const t = d.type;
@@ -351,17 +301,15 @@ function makeNullableType(def) {
351
301
  return d;
352
302
  }
353
303
  /**
354
- * Recursively make every NON-required property of a JSON-schema object nullable.
304
+ * Recursively make every non-required property of a JSON-schema object nullable.
355
305
  *
356
- * GPT/OpenAI strict mode (the default for the Responses API) marks every property required;
357
- * a non-nullable optional field then leaves the model no way to signal "unused" for an enum
358
- * it is FORCED to emit one of the values (the hallucinated typeKind=domain / odataVersion=V4
359
- * seen on unrelated writes, issue #360). The OpenAI-documented fix is a union with null
360
- * (`"type": ["string","null"]`) so the model can emit null = "not used"; ARC-1's runtime
361
- * `stripLlmEmptyValues` then drops the nulls before Zod. Each object node's OWN `required`
362
- * array decides what stays non-nullable, so it is correct at every nesting level (top level
363
- * keeps `action`; batch `objects[]` items keep `type`/`name`; leaf arrays keep their keys).
364
- * Pure — returns a copy, does not mutate the input.
306
+ * This exists only for explicit OpenAI/Azure strict-mode compatibility (#360), where a strict
307
+ * function schema can force every optional field to be present and enum optionals then get
308
+ * fabricated values. Several MCP clients reject `type: ["x","null"]` unions, so the default
309
+ * visible schema stays plain for broad client compatibility (#520).
310
+ *
311
+ * Pure returns a copy and does not mutate the input. Each object node's own `required` array
312
+ * decides what stays non-nullable, so top-level `action` and batch-item `type`/`name` remain plain.
365
313
  */
366
314
  function makeOptionalPropertiesNullable(node) {
367
315
  if (Array.isArray(node))
@@ -387,7 +335,7 @@ function makeOptionalPropertiesNullable(node) {
387
335
  return result;
388
336
  }
389
337
  // ─── Main Tool Definitions ──────────────────────────────────────────
390
- export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures) {
338
+ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures, options = {}) {
391
339
  // Hyperfocused mode: single universal SAP tool (~200 tokens)
392
340
  if (config.toolMode === 'hyperfocused') {
393
341
  return [getHyperfocusedToolDefinition(config, resolvedFeatures)];
@@ -528,12 +476,12 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
528
476
  const pkgList = config.allowedPackages.join(', ');
529
477
  sapWriteDesc += ` Write access is restricted to packages: ${pkgList}.`;
530
478
  }
531
- tools.push({
479
+ const sapWriteTool = {
532
480
  name: 'SAPWrite',
533
481
  description: sapWriteDesc,
534
- // Make optional fields nullable so GPT/OpenAI strict-mode callers can emit null for
535
- // unused fields instead of fabricating values; the runtime strip removes the nulls (#360).
536
- inputSchema: makeOptionalPropertiesNullable({
482
+ // Keep visible schemas on widely supported JSON Schema primitives. Runtime argument
483
+ // normalization still strips null-valued optionals from strict clients before Zod (#360).
484
+ inputSchema: {
537
485
  type: 'object',
538
486
  properties: {
539
487
  action: {
@@ -552,7 +500,7 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
552
500
  'scaffold_rap_handlers',
553
501
  'generate_behavior_implementation',
554
502
  ],
555
- description: "Write action. edit_method: surgically replace a single method body (requires type=CLAS, method, and source params). Class-section surgery actions (issue #303, type=CLAS only) target a global class without re-sending /source/main: edit_class_definition without include= replaces the global DEFINITION block (caller passes the new block via source; ARC-1 refuses if the diff would leave the class non-activatable e.g. added concrete method without IMPL stub — and suggests add_method/delete_method instead); edit_class_definition with include= whole-replaces that class-local include (CCDEF/CCIMP/macros/testclasses) and auto-creates the include first if missing; add_method atomically inserts a METHODS clause AND empty METHOD/ENDMETHOD stub (caller passes the METHODS clause via method, optional visibility=public|protected|private, optional abstract=true to skip the stub); edit_method_signature replaces one method's METHODS clause via the source param (no IMPL changes); delete_method removes both the DEFINITION clause and METHOD/ENDMETHOD body atomically — WARNING: this is destructive (it discards the method body). To change a method's visibility/section, use change_method_visibility (NOT delete_method + add_method, which would discard the body). change_method_visibility moves a method between PUBLIC/PROTECTED/PRIVATE sections (requires method=NAME and visibility=target); it touches only the DEFINITION, so the IMPLEMENTATION body is preserved. add_method/edit_method_signature/delete_method/change_method_visibility operate on the global class /source/main only. batch_create: create and activate multiple objects in sequence (requires objects array). scaffold_rap_handlers: derive missing behavior-pool handler signatures from interface BDEF declarations and optionally inject declarations plus empty implementation stubs. generate_behavior_implementation: one-shot RAP behavior pool auto-discover the bound BDEF via class rootEntityRef, scaffold every required handler (creating lhc_<alias> skeletons when missing), write under one lock, and optionally activate. The reliable equivalent of Eclipse ADT's \"Generate Behavior Implementation\" Cmd+1 quickfix.",
503
+ description: 'Write action. create/update/delete: standard object writes. edit_method: replace one method body (type=CLAS, method, source). Class-section surgery (type=CLAS only): edit_class_definition without include= replaces the global DEFINITION block (refuses a diff that would leave the class non-activatable, e.g. a concrete method with no IMPL stub); with include= it whole-replaces a class-local include (CCDEF/CCIMP/macros/testclasses), auto-creating it. add_method inserts a METHODS clause + empty stub (visibility, abstract=true skips the stub); edit_method_signature replaces one METHODS clause (no IMPL change); delete_method removes the clause AND body — WARNING: destructive, discards the method body (to re-section a method use change_method_visibility, NOT delete+add); change_method_visibility moves a method between PUBLIC/PROTECTED/PRIVATE, preserves the body. add_method/edit_method_signature/delete_method/change_method_visibility act on /source/main only. batch_create: create+activate multiple objects (objects array). scaffold_rap_handlers / generate_behavior_implementation: derive RAP behavior-pool handlers from the BDEF (the latter the equivalent of Eclipse\'s "Generate Behavior Implementation").',
556
504
  },
557
505
  type: {
558
506
  type: 'string',
@@ -567,16 +515,16 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
567
515
  },
568
516
  source: {
569
517
  type: 'string',
570
- description: 'ABAP source code. For create/update: the full source body. For edit_method: the new method body. For edit_class_definition without include=: ONLY the new global CLASS DEFINITION ENDCLASS. block (~10–80 lines for a typical class — no IMPLEMENTATION block needed). For edit_class_definition with include=: the FULL replacement body of that local include; for include="testclasses" this usually means local CLASS ltc_* DEFINITION plus CLASS ltc_* IMPLEMENTATION. For edit_method_signature: ONLY the new METHODS clause for one method (~1–5 lines). For add_method/delete_method/change_method_visibility: not used — pass the new method clause, method name, or target section via `method`/`visibility` instead.',
518
+ description: 'ABAP source code. create/update: full source body. edit_method: the new method body. edit_class_definition without include=: only the new global CLASS…DEFINITION…ENDCLASS block (no IMPLEMENTATION); with include=: the full replacement body of that include. edit_method_signature: only the new METHODS clause. Not used by add_method/delete_method/change_method_visibility (use `method`/`visibility`).',
571
519
  },
572
520
  include: {
573
521
  type: 'string',
574
522
  enum: CLASS_WRITE_INCLUDES,
575
- description: 'CLAS-ONLY. Do NOT send this field unless type=CLAS AND action is one of update / edit_method / edit_class_definition. OMIT it entirely for every other object type (PROG, INTF, INCL, FUNC, FUGR, DDLS, DCLS, DDLX, BDEF, SRVD, SRVB, TABL, DOMA, DTEL, MSAG) and for delete / batch_create / add_method / edit_method_signature / delete_method / change_method_visibility (those operate on the global class /source/main). When it does apply: target a class-local include instead of /source/main — definitions (CCDEF), implementations (CCIMP), macros, testclasses. For edit_method, ARC-1 auto-detects the include from the method specifier (lhc_*/lcl_* → implementations, ltc_* → testclasses), so you usually need not pass it; use update or edit_class_definition with include=testclasses to create a new local test class. Whole-include writes (update and edit_class_definition with include=) auto-create a missing include first, including fresh testclasses/CCAU. Include writes create an inactive draft; read with SAPRead version="inactive" before activation. NOTE: edit_class_definition with include= skips the symmetry refuse-policy — cross-include validation is not performed; rely on SAPActivate to catch breaks.',
523
+ description: 'CLAS-ONLY. Do NOT send unless type=CLAS AND action is update / edit_method / edit_class_definition. OMIT it entirely for every other type and for delete / batch_create / add_method / edit_method_signature / delete_method / change_method_visibility (those use /source/main). Targets a class-local include: definitions (CCDEF), implementations (CCIMP), macros, testclasses. edit_method auto-detects it from the method specifier (lhc_*/lcl_* → implementations, ltc_* → testclasses), so you rarely pass it; use include=testclasses to create a new local test class. Whole-include writes auto-create a missing include and produce an inactive draft (read with SAPRead version="inactive" before activation).',
576
524
  },
577
525
  method: {
578
526
  type: 'string',
579
- description: 'For edit_method/edit_method_signature: method NAME (e.g., "get_name", "zif_order~process", "lhc_project~approve_project"). For delete_method and change_method_visibility: the method NAME. For add_method: the full METHODS clause as ABAP source (e.g. "METHODS greet IMPORTING who TYPE string RETURNING VALUE(r) TYPE string."). edit_method auto-detects CCIMP from local-class prefix (lhc_*/lcl_* → implementations, ltc_* → testclasses); same auto-detection applies to the class-section surgery actions. When two local classes in the same CCIMP share a bare method name, the qualified <localclass>~<method> form is required to disambiguate.',
527
+ description: 'edit_method/edit_method_signature/delete_method/change_method_visibility: the method NAME (e.g. "get_name", "zif_order~process", "lhc_project~approve_project"). add_method: the full METHODS clause as ABAP source. Local-class methods auto-route by prefix (lhc_*/lcl_* → implementations, ltc_* → testclasses); use the qualified <localclass>~<method> form when a bare name is ambiguous.',
580
528
  },
581
529
  visibility: {
582
530
  type: 'string',
@@ -589,11 +537,11 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
589
537
  },
590
538
  bdefName: {
591
539
  type: 'string',
592
- description: "For scaffold_rap_handlers action: interface BDEF name used to derive required handler signatures (e.g., ZI_TRAVELREQ). The BDEF is parsed to find every action/determination/validation/authorization that must exist in the behavior pool. For generate_behavior_implementation: optional override; default discovery reads the class metadata's rootEntityRef to locate the BDEF automatically.",
540
+ description: 'For scaffold_rap_handlers: interface BDEF name whose actions/determinations/validations/authorizations define the required handlers (e.g. ZI_TRAVELREQ). For generate_behavior_implementation: optional override (default discovery reads the class rootEntityRef).',
593
541
  },
594
542
  autoApply: {
595
543
  type: 'boolean',
596
- description: 'For scaffold_rap_handlers: when true, missing METHODS signatures are inserted into matching lhc_* class definitions, empty METHOD stubs are inserted into matching implementation blocks where possible, and the class source is written back under a single lock. When false (default), returns a JSON report of required vs. missing signatures without modifying the class — use this first to preview, then re-run with autoApply=true to commit. (Not used by generate_behavior_implementation, which always applies; use dryRun=true there to preview.)',
544
+ description: 'For scaffold_rap_handlers: true inserts missing METHODS signatures + empty stubs and writes the class under one lock; false (default) returns a required-vs-missing report without modifying (preview, then re-run with autoApply=true). Not used by generate_behavior_implementation (use dryRun to preview there).',
597
545
  },
598
546
  targetAlias: {
599
547
  type: 'string',
@@ -601,11 +549,11 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
601
549
  },
602
550
  activate: {
603
551
  type: 'boolean',
604
- description: 'For generate_behavior_implementation: when true (default), runs SAPActivate on the class after writing. When false, only the source is written. Activation failures matching the well-known "Local classes of CL_ABAP_BEHAVIOR_HANDLER…" stale-active coupling do not throw — they return activation.success=false with a guided recovery hint so the source remains usable.',
552
+ description: 'For generate_behavior_implementation: true (default) activates the class after writing; false writes source only. The known "Local classes of CL_ABAP_BEHAVIOR_HANDLER…" stale-active activation failure does not throw — it returns activation.success=false with a recovery hint.',
605
553
  },
606
554
  activateAtEnd: {
607
555
  type: 'boolean',
608
- description: 'For action="batch_create" only. Default false: per-object inline activation (each object is created → source written → activated, in order). When true: ARC-1 writes inactive drafts for every object then issues a single terminal activateBatch SAP\'s activator sees the whole graph and resolves cross-references between siblings (e.g. composition-linked DDLS where the parent references a not-yet-active child). Use this for interdependent RAP stacks (TABL DDLS DCLS BDEF SRVD). Has no effect on other actions. Partial-failure semantics: a write-phase failure still breaks the loop; the terminal activateBatch only runs over the already-written subset.',
556
+ description: 'For batch_create only. false (default): per-object inline activation in order. true: write all inactive drafts then one terminal activateBatch so SAP resolves cross-references between siblings use for interdependent RAP stacks (TABL→DDLS→DCLS→BDEF→SRVD). A write-phase failure still breaks the loop; the terminal activate runs over the already-written subset.',
609
557
  },
610
558
  dryRun: {
611
559
  type: 'boolean',
@@ -628,6 +576,15 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
628
576
  description: 'For FUNC: parent function-group name. Required for FUNC create (the FUGR must already exist — create it first via SAPWrite type=FUGR). Auto-resolved via search for FUNC update/delete if omitted.',
629
577
  },
630
578
  dataType: { type: 'string', description: 'DOMA/DTEL: ABAP data type (e.g., CHAR, NUMC, DEC)' },
579
+ rowType: {
580
+ type: 'string',
581
+ description: 'TTYP create: the row type — a built-in ABAP type (STRING, I, …) or a DDIC structure/type name. Required for TTYP create.',
582
+ },
583
+ rowTypeKind: {
584
+ type: 'string',
585
+ enum: ['builtin', 'structure'],
586
+ description: 'TTYP create: row-type mode (auto-detected from rowType if omitted).',
587
+ },
631
588
  length: { type: 'number', description: 'DOMA/DTEL: data type length' },
632
589
  decimals: { type: 'number', description: 'DOMA/DTEL: decimal places' },
633
590
  outputLength: { type: 'number', description: 'DOMA: output length' },
@@ -678,7 +635,7 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
678
635
  },
679
636
  parameters: {
680
637
  type: 'array',
681
- description: 'FUNC: structured signature parameters. ARC-1 builds the IMPORTING/EXPORTING/CHANGING/TABLES/EXCEPTIONS/RAISING clause from this array and splices it into the FM source body. Example: [{kind: "importing", name: "IV_INPUT", type: "STRING", byValue: true, optional: true, default: "\'X\'"}, {kind: "exporting", name: "EV_OUTPUT", type: "STRING", byValue: true}, {kind: "raising", name: "CX_ROOT"}]. When omitted, the user-supplied source is PUT verbatim (backward compatible).',
638
+ description: 'FUNC: structured signature parameters. ARC-1 builds the IMPORTING/EXPORTING/CHANGING/TABLES/EXCEPTIONS/RAISING clause and splices it into the FM body. When omitted, the supplied source is PUT verbatim.',
682
639
  items: {
683
640
  type: 'object',
684
641
  properties: {
@@ -708,7 +665,7 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
708
665
  serviceDefinition: { type: 'string', description: 'SRVB: service definition name (SRVD) to bind to' },
709
666
  bindingType: {
710
667
  type: 'string',
711
- description: 'SRVB: binding type — accepts human-readable values like "ODataV4-UI", "OData V2 - Web API", "ODATA_V4" which are auto-normalized to SAP ADT values (type=ODATA, correct odataVersion + category)',
668
+ description: 'SRVB: binding type — human-readable values like "ODataV4-UI", "OData V2 - Web API" are auto-normalized (sets odataVersion + category).',
712
669
  },
713
670
  odataVersion: {
714
671
  type: 'string',
@@ -723,19 +680,19 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
723
680
  version: { type: 'string', description: 'SRVB: service version number (default: 0001)' },
724
681
  lintBeforeWrite: {
725
682
  type: 'boolean',
726
- description: 'Override server lint-before-write setting for this call. Set false to skip pre-write lint validation. Lint applies to ABAP types (PROG, CLAS, INTF, FUNC) and CDS views (DDLS). BDEF/SRVD/SRVB/DDLX/TABL are skipped by offline linter; RAP preflight may still catch deterministic issues for those types.',
683
+ description: 'Override server lint-before-write for this call (false skips it). Lint covers PROG/CLAS/INTF/FUNC and DDLS; other types rely on RAP preflight.',
727
684
  },
728
685
  preflightBeforeWrite: {
729
686
  type: 'boolean',
730
- description: 'Enable/disable deterministic RAP preflight checks for this call (default: true). Useful for TABL/BDEF/DDLX static rules (e.g., curr/quan semantics, invalid BDEF enums, unsupported DDLX annotation scope on on-prem 7.5x).',
687
+ description: 'Enable/disable deterministic RAP preflight checks (default true) TABL/BDEF/DDLX static rules (curr/quan semantics, invalid BDEF enums, DDLX scope on 7.5x).',
731
688
  },
732
689
  checkBeforeWrite: {
733
690
  type: 'boolean',
734
- description: 'Override server check-before-write setting (default off). When true, SAPWrite sends the proposed source to /sap/bc/adt/checkruns with inline <chkrun:content> and appends any error/warning messages to the success response — the write is NOT blocked. Useful for single-file edits to see compile diagnostics without a separate SAPDiagnose call. Off by default because (a) it adds a round-trip per write and (b) intermediate writes during multi-file refactors will legitimately trip dependency errors that resolve once the whole sequence lands. Activation remains the definitive compile check.',
691
+ description: 'Override server check-before-write (default off). When true, runs a SAP syntax check and appends diagnostics to the response — the write is NOT blocked. Off by default (adds a round-trip; intermediate refactor writes legitimately trip transient dependency errors). Activation remains the definitive check.',
735
692
  },
736
693
  refObjectType: {
737
694
  type: 'string',
738
- description: 'SKTD/KTD create: ADT type+subtype of the parent object the KTD documents (e.g., "DDLS/DF", "BDEF/BDO", "SRVD/SRV", "SRVB/SVB", "DEVC/K"). Do not use CLAS/OC, INTF/OI, or PROG/P; use ABAP Doc for code objects. Required for SKTD/KTD create.',
695
+ description: 'SKTD/KTD create (required): ADT type+subtype of the documented parent (e.g. "DDLS/DF", "BDEF/BDO", "SRVD/SRV", "DEVC/K"). Not CLAS/INTF/PROG (use ABAP Doc for code).',
739
696
  },
740
697
  refObjectName: {
741
698
  type: 'string',
@@ -766,87 +723,69 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
766
723
  type: 'string',
767
724
  description: 'Object-specific transport request. Overrides top-level transport for this item.',
768
725
  },
769
- dataType: { type: 'string', description: 'DOMA/DTEL: ABAP data type' },
770
- length: { type: 'number', description: 'DOMA/DTEL: data type length' },
771
- decimals: { type: 'number', description: 'DOMA/DTEL: decimal places' },
772
- outputLength: { type: 'number', description: 'DOMA: output length' },
773
- conversionExit: { type: 'string', description: 'DOMA: conversion exit' },
774
- signExists: { type: 'boolean', description: 'DOMA: signed values allowed' },
775
- lowercase: { type: 'boolean', description: 'DOMA: lowercase allowed' },
726
+ // DDIC metadata fields (DOMA/DTEL/TTYP/MSAG/SRVB) mirror the top-level SAPWrite
727
+ // params 1:1 descriptions omitted here to keep the tools/list payload small (#520).
728
+ dataType: { type: 'string' },
729
+ rowType: { type: 'string' },
730
+ rowTypeKind: { type: 'string', enum: ['builtin', 'structure'] },
731
+ length: { type: 'number' },
732
+ decimals: { type: 'number' },
733
+ outputLength: { type: 'number' },
734
+ conversionExit: { type: 'string' },
735
+ signExists: { type: 'boolean' },
736
+ lowercase: { type: 'boolean' },
776
737
  fixedValues: {
777
738
  type: 'array',
778
- description: 'DOMA: fixed value ranges',
779
739
  items: {
780
740
  type: 'object',
781
- properties: {
782
- low: { type: 'string' },
783
- high: { type: 'string' },
784
- description: { type: 'string' },
785
- },
741
+ properties: { low: { type: 'string' }, high: { type: 'string' }, description: { type: 'string' } },
786
742
  required: ['low'],
787
743
  },
788
744
  },
789
- valueTable: { type: 'string', description: 'DOMA: value table' },
790
- typeKind: { type: 'string', enum: ['domain', 'predefinedAbapType'], description: 'DTEL: type mode' },
791
- typeName: { type: 'string', description: 'DTEL: domain/type name reference' },
792
- domainName: { type: 'string', description: 'DTEL: alias for typeName' },
793
- shortLabel: { type: 'string', description: 'DTEL: short field label' },
794
- mediumLabel: { type: 'string', description: 'DTEL: medium field label' },
795
- longLabel: { type: 'string', description: 'DTEL: long field label' },
796
- headingLabel: { type: 'string', description: 'DTEL: heading field label' },
797
- searchHelp: { type: 'string', description: 'DTEL: search help' },
798
- searchHelpParameter: { type: 'string', description: 'DTEL: search help parameter' },
799
- setGetParameter: { type: 'string', description: 'DTEL: SET/GET parameter ID' },
800
- defaultComponentName: { type: 'string', description: 'DTEL: default component name' },
801
- changeDocument: { type: 'boolean', description: 'DTEL: change document flag' },
745
+ valueTable: { type: 'string' },
746
+ typeKind: { type: 'string', enum: ['domain', 'predefinedAbapType'] },
747
+ typeName: { type: 'string' },
748
+ domainName: { type: 'string' },
749
+ shortLabel: { type: 'string' },
750
+ mediumLabel: { type: 'string' },
751
+ longLabel: { type: 'string' },
752
+ headingLabel: { type: 'string' },
753
+ searchHelp: { type: 'string' },
754
+ searchHelpParameter: { type: 'string' },
755
+ setGetParameter: { type: 'string' },
756
+ defaultComponentName: { type: 'string' },
757
+ changeDocument: { type: 'boolean' },
802
758
  messages: {
803
759
  type: 'array',
804
- description: 'MSAG: message entries',
805
760
  items: {
806
761
  type: 'object',
807
- properties: {
808
- number: { type: 'string', description: 'Message number (e.g., "001")' },
809
- shortText: { type: 'string', description: 'Message short text' },
810
- },
762
+ properties: { number: { type: 'string' }, shortText: { type: 'string' } },
811
763
  required: ['number', 'shortText'],
812
764
  },
813
765
  },
814
- serviceDefinition: { type: 'string', description: 'SRVB: service definition (SRVD)' },
815
- bindingType: {
816
- type: 'string',
817
- description: 'SRVB: binding type accepts human-readable values like "ODataV4-UI" (auto-normalized)',
818
- },
819
- odataVersion: {
820
- type: 'string',
821
- enum: ['V2', 'V4'],
822
- description: 'SRVB: OData protocol version (default: V2)',
823
- },
824
- category: {
825
- type: 'string',
826
- enum: ['0', '1'],
827
- description: 'SRVB: binding category (0=UI, 1=Web API)',
828
- },
829
- version: { type: 'string', description: 'SRVB: service version number (default 0001)' },
766
+ serviceDefinition: { type: 'string' },
767
+ bindingType: { type: 'string' },
768
+ odataVersion: { type: 'string', enum: ['V2', 'V4'] },
769
+ category: { type: 'string', enum: ['0', '1'] },
770
+ version: { type: 'string' },
830
771
  },
831
772
  required: ['type', 'name'],
832
773
  },
833
- description: 'For batch_create: ordered list of objects to create and activate. Each object needs type, name, and source (if applicable). ' +
834
- 'Objects are created and activated in array order — put dependencies first (e.g., TABL before DDLS, BDEF after DDLS). ' +
835
- 'Each item may include package and transport; item-level values override top-level package/transport. ' +
836
- 'Example: [{type:"TABL",name:"ZTRAVEL",source:"..."},{type:"DDLS",name:"ZI_TRAVEL",source:"..."},{type:"BDEF",name:"ZI_TRAVEL",source:"..."},{type:"SRVD",name:"ZSD_TRAVEL",source:"..."}]',
774
+ description: 'For batch_create: ordered list of objects to create+activate (each needs type, name, and source if applicable). Created in array order — dependencies first (TABL before DDLS, BDEF after DDLS). Item-level package/transport override the top-level. Use activateAtEnd=true for interdependent stacks.',
837
775
  },
838
776
  },
839
777
  required: ['action'],
840
- }),
841
- });
778
+ },
779
+ };
780
+ if (options.nullableOptionals) {
781
+ sapWriteTool.inputSchema = makeOptionalPropertiesNullable(sapWriteTool.inputSchema);
782
+ }
783
+ tools.push(sapWriteTool);
842
784
  tools.push({
843
785
  name: 'SAPActivate',
844
- description: 'Activate (publish) ABAP objects. Supports single object or batch activation.\n' +
845
- 'Type codes are auto-normalized and case-insensitive (e.g., "CLAS/OC" or "clas" map to CLAS).\n' +
846
- 'ALWAYS prefer batch activation when activating 2+ objects — pass "objects" array with {type, name} entries. ' +
847
- 'Batch activation is more efficient (one SAP round-trip) and works for ANY combination of objects, not just dependent ones. ' +
848
- 'It is required for RAP stacks where DDLS, BDEF, SRVD depend on each other, but equally useful for unrelated objects like multiple DTELs or DOMAs.\n' +
849
- 'For publish_srvb/unpublish_srvb: publish or unpublish an OData service binding (SRVB) — makes the OData service available for consumption.',
786
+ description: 'Activate (publish) ABAP objects, single or batch. Type codes auto-normalized (e.g. "CLAS/OC" → CLAS). ' +
787
+ 'ALWAYS prefer batch activation for 2+ objects pass an "objects" array of {type, name}: one round-trip, works for any mix (required for interdependent RAP stacks, useful for unrelated objects too). ' +
788
+ 'publish_srvb/unpublish_srvb: publish or unpublish an OData service binding (SRVB).',
850
789
  inputSchema: {
851
790
  type: 'object',
852
791
  properties: {
@@ -863,14 +802,11 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
863
802
  service_type: {
864
803
  type: 'string',
865
804
  enum: ['odatav2', 'odatav4'],
866
- description: 'OData service type for publish/unpublish endpoint routing. ' +
867
- 'Auto-detected from SRVB metadata when omitted. Only needed if auto-detection fails.',
805
+ description: 'OData service type for publish/unpublish routing. Auto-detected from SRVB metadata when omitted.',
868
806
  },
869
807
  preaudit: {
870
808
  type: 'boolean',
871
- description: 'Request pre-activation audit from SAP (default: true). ' +
872
- 'When true, SAP checks for issues before activating and returns warnings/errors. ' +
873
- 'Set to false to skip pre-audit for faster activation when confident the code is correct.',
809
+ description: 'Request pre-activation audit (default true) — SAP returns warnings/errors before activating. false skips it for speed.',
874
810
  },
875
811
  objects: {
876
812
  type: 'array',
@@ -882,8 +818,7 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
882
818
  },
883
819
  required: ['type', 'name'],
884
820
  },
885
- description: 'Batch activation: array of objects to activate in one call. Use whenever activating 2+ objects. ' +
886
- 'Works for any mix of types — e.g., [{type:"DOMA",name:"Z_DOM"},{type:"DTEL",name:"Z_DEL"}] or RAP stacks like [{type:"DDLS",name:"ZI_TRAVEL"},{type:"BDEF",name:"ZI_TRAVEL"},{type:"SRVD",name:"ZSD_TRAVEL"}].',
821
+ description: 'Batch activation: array of {type, name} to activate in one call. Use whenever activating 2+ objects (any mix of types).',
887
822
  },
888
823
  },
889
824
  },
@@ -892,8 +827,8 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
892
827
  tools.push({
893
828
  name: 'SAPNavigate',
894
829
  description: btp
895
- ? 'Navigate code (BTP ABAP Environment): find definitions, references (where-used), code completion, and class hierarchy. Use for "go to definition", "where is this used?", "what does this class inherit?", and auto-complete. For references: uses the full scope-based Where-Used API returning detailed results with line numbers, snippets, and package info. Optional objectType filter narrows results to a specific ADT type in slash format (e.g., CLAS/OC, PROG/P). Type+name params are auto-normalized (e.g., type="clas" works). On BTP, navigation scope is limited to released SAP objects and custom Z/Y objects.\n\nFor CDS entities (DDLS), prefer SAPContext(action="impact") — it returns the same where-used data pre-classified into RAP buckets (projection views, BDEFs, SRVDs, access controls, etc.), which is more useful than the flat reference list returned here.'
896
- : 'Navigate code: find definitions, references (where-used), code completion, and class hierarchy. Use for "go to definition", "where is this used?", "what does this class inherit?", and auto-complete. For references: uses the full scope-based Where-Used API returning detailed results with line numbers, snippets, and package info. Optional objectType filter narrows results to a specific ADT type in slash format (e.g., CLAS/OC, PROG/P). Type+name params are auto-normalized (e.g., type="clas" works). For hierarchy: returns superclass, implemented interfaces, and direct subclasses via SEOMETAREL. You can use type+name instead of uri (e.g., type="CLAS", name="ZCL_ORDER") for a where-used list without needing the full ADT URI.\n\nFor CDS entities (DDLS), prefer SAPContext(action="impact") — it returns the same where-used data pre-classified into RAP buckets (projection views, BDEFs, SRVDs, access controls, metadata extensions, documentation, ABAP consumers), which answers "what breaks if I change this view" directly without manual bucketing.',
830
+ ? 'Navigate code (BTP ABAP Environment): definitions, references (where-used), completion, class hierarchy. references uses the scope-based Where-Used API (line numbers, snippets, package); optional objectType filters by ADT slash type (e.g. CLAS/OC). type+name auto-normalized. Scope = released SAP + custom Z/Y. For CDS (DDLS), prefer SAPContext(action="impact") — the same where-used pre-classified into RAP buckets.'
831
+ : 'Navigate code: definitions, references (where-used), completion, class hierarchy. references uses the scope-based Where-Used API (line numbers, snippets, package); optional objectType filters by ADT slash type (e.g. CLAS/OC, PROG/P); pass type+name instead of uri. hierarchy returns superclass + interfaces + direct subclasses. For CDS (DDLS), prefer SAPContext(action="impact") — the same where-used pre-classified into RAP buckets, answering "what breaks if I change this view".',
897
832
  inputSchema: {
898
833
  type: 'object',
899
834
  properties: {
@@ -939,16 +874,13 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
939
874
  }
940
875
  tools.push({
941
876
  name: 'SAPLint',
942
- description: 'Run local abaplint rules on ABAP and CDS source code. System-aware: auto-selects cloud or on-prem rules based on detected system type.\n\n' +
943
- 'Actions:\n' +
944
- '- "lint": Check source for issues. Returns errors and warnings. Works for ABAP (PROG, CLAS, INTF, FUNC) and CDS views (DDLS) — catches syntax errors, naming conventions, field order, legacy view patterns.\n' +
945
- '- "lint_and_fix": Lint + auto-fix all fixable issues (keyword case, obsolete statements, etc.). Returns fixed source.\n' +
946
- '- "list_rules": List all available rules with current config. No source needed.\n' +
947
- '- "format": Pretty-print ABAP source via SAP\'s ADT formatter (uses the SAP system\'s global formatter settings). Requires source. Returns the formatted source.\n' +
948
- '- "get_formatter_settings": Read the SAP system\'s global PrettyPrinter settings (indentation, keyword style). No params.\n' +
949
- '- "set_formatter_settings": Update the SAP system\'s global PrettyPrinter settings. Requires indentation (bool) and/or style (keywordUpper|keywordLower|keywordAuto|none). Blocked in read-only mode.\n\n' +
950
- 'For server-side checks (ATC, syntax check, unit tests), use SAPDiagnose instead.\n' +
951
- 'Note: lint/lint_and_fix/list_rules run locally; format/*_formatter_settings call the SAP system.',
877
+ description: 'Run local abaplint rules on ABAP/CDS source (auto-selects cloud or on-prem rules by system type). Actions:\n' +
878
+ '- "lint": check source (errors+warnings) for ABAP (PROG/CLAS/INTF/FUNC) and CDS (DDLS).\n' +
879
+ '- "lint_and_fix": lint + auto-fix fixable issues (keyword case, obsolete statements); returns fixed source.\n' +
880
+ '- "list_rules": list rules + current config (no source).\n' +
881
+ '- "format": pretty-print via SAP\'s ADT formatter (needs source).\n' +
882
+ '- "get_formatter_settings" / "set_formatter_settings": read/update the system\'s global PrettyPrinter (indentation bool, style keywordUpper|keywordLower|keywordAuto|none; set is blocked read-only).\n' +
883
+ 'lint/lint_and_fix/list_rules run locally; format/*_formatter_settings call SAP. For ATC/syntax/unit tests use SAPDiagnose.',
952
884
  inputSchema: {
953
885
  type: 'object',
954
886
  properties: {
@@ -980,20 +912,23 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
980
912
  },
981
913
  }, {
982
914
  name: 'SAPDiagnose',
983
- description: 'Run diagnostics on ABAP objects and analyze runtime errors.\n\n' +
984
- 'Actions:\n' +
985
- '- "syntax": Syntax check an ABAP object. Requires name + type. Optional: version ("active" or "inactive", defaults to active). Optional: source — when supplied, SAP compiles the given content as if it lived at the object\'s URI (pre-write dry-run, nothing is written). Omit source to check what is stored.\n' +
986
- '- "unittest": Run ABAP unit tests. Requires name + type.\n' +
987
- '- "atc": Run ATC code quality checks. Requires name + type. Optional: variant.\n' +
988
- '- "cds_testcases": Get SAP-suggested ABAP Unit test cases for a CDS entity (CDS Test Double Framework). Requires name (the CDS entity / DDLS source name; no type needed). Returns one test-method suggestion per testable semantic (whole view, calculated fields, CAST/JOIN/CASE) to scaffold a cl_cds_test_environment unit test. Read-only; SAP_BASIS 8.16+ (ABAP Platform 2025 / S/4HANA 2025) only.\n' +
989
- '- "object_state": Compare active and inactive source versions. Requires name + type. For CLAS, also compares main, definitions, implementations, macros, and testclasses includes (up to 10 parallel reads per class; sequence calls when sweeping many classes). Returns ETags, byte lengths, hashes, and divergence flags.\n' +
990
- '- "quickfix": Get SAP quick fix proposals for a specific source position. Requires name + type + source + line. Optional: column, sourceUri for exact ADT include/source targets.\n' +
991
- '- "apply_quickfix": Apply one quick fix proposal and return text deltas (does not write source). Requires name + type + source + line + proposalUri + proposalUserContent. Optional: column, sourceUri, proposalAffectedObjects. proposalUserContent may be an empty string; pass it through exactly from quickfix.\n' +
992
- '- "dumps": List or read ABAP short dumps (ST22). Without id: lists recent dumps (filter by user, maxResults). With id: returns focused chapter sections by default; set includeFullText=true to include the full formatted dump blob. Optional sections=[kap0,kap3,...] to request specific chapter IDs.\n' +
993
- '- "traces": List or analyze ABAP profiler traces. Without id: lists trace files. With id + analysis: returns trace analysis (hitlist = hot spots, statements = call tree, dbAccesses = database access statistics).\n\n' +
994
- '- "system_messages": List SM02 system messages via ADT feed (filter by user, maxResults, from, to).\n' +
995
- '- "gateway_errors": List SAP Gateway error log entries (/IWFND/ERROR_LOG, on-prem). For detail mode provide detailUrl (preferred) or id+errorType.\n\n' +
996
- 'Quickfix workflow: run syntax/ATC first to identify issues and line positions, then call quickfix to retrieve SAP-verified proposals, then apply_quickfix to get exact text deltas, and finally write the updated source via SAPWrite.',
915
+ description: 'Run diagnostics on ABAP objects and analyze runtime errors. Actions:\n' +
916
+ '- "syntax": syntax-check (name+type; optional version; optional source = pre-write dry-run, nothing written).\n' +
917
+ '- "unittest": run ABAP Unit tests (name+type).\n' +
918
+ '- "atc": run ATC checks (name+type; optional variant).\n' +
919
+ '- "cds_testcases": SAP-suggested ABAP Unit test cases for a CDS entity (name; read-only; SAP_BASIS 8.16+).\n' +
920
+ '- "object_state": compare active and inactive source versions without fetching both (name+type; CLAS compares all includes). Returns ETags, hashes, divergence flags.\n' +
921
+ '- "quickfix": get quick-fix proposals at a position (name+type+source+line; optional column, sourceUri).\n' +
922
+ '- "apply_quickfix": apply one proposal, return text deltas, no write (name+type+source+line+proposalUri+proposalUserContent; pass proposalUserContent through exactly, may be empty).\n' +
923
+ '- "dumps": list/read ST22 short dumps (no id = list; id = read; includeFullText, sections).\n' +
924
+ '- "traces": list/analyze profiler traces (id+analysis: hitlist=hot spots, statements=call tree, dbAccesses=DB stats).\n' +
925
+ '- "trace_start": arm a profiler trace for the NEXT matching execution, then reproduce and read via "traces" (write scope; defaults: next HTTP request, SQL on; optional traceUser/processType/maxExecutions/expiresHours/sqlTrace/…).\n' +
926
+ '- "trace_requests": list armed trace requests. "trace_cancel": cancel one by id (write scope).\n' +
927
+ '- "system_messages": list SM02 messages. "gateway_errors": list /IWFND/ERROR_LOG (on-prem; detailUrl or id+errorType for detail).\n' +
928
+ '- "odata_perf": diagnose why an OData call is slow (url = host-relative path from the Network tab); returns the sap-statistics timing split (DB/ABAP/framework/auth) + a verdict. Read-only; needs allowDataPreview.\n' +
929
+ '- "cds_sql": show the native SQL a CDS view compiles to (name; read-only; may be absent on old releases).\n' +
930
+ '- "sql_trace_state" / "set_sql_trace_state" (sqlOn; needs SAP_ALLOW_WRITES) / "sql_trace_directory": ST05 SQL-trace control.\n' +
931
+ 'Quickfix workflow: syntax/ATC → quickfix → apply_quickfix → write via SAPWrite. Full action reference: docs_page SAPDiagnose.',
997
932
  inputSchema: {
998
933
  type: 'object',
999
934
  properties: {
@@ -1006,17 +941,29 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1006
941
  'cds_testcases',
1007
942
  'dumps',
1008
943
  'traces',
944
+ 'trace_start',
945
+ 'trace_requests',
946
+ 'trace_cancel',
1009
947
  'system_messages',
1010
948
  'gateway_errors',
1011
949
  'object_state',
1012
950
  'quickfix',
1013
951
  'apply_quickfix',
952
+ 'odata_perf',
953
+ 'cds_sql',
954
+ 'sql_trace_state',
955
+ 'set_sql_trace_state',
956
+ 'sql_trace_directory',
1014
957
  ],
1015
958
  description: 'Diagnostic action',
1016
959
  },
1017
960
  name: {
1018
961
  type: 'string',
1019
- description: 'Object name (for syntax/unittest/atc/object_state); the CDS entity / DDLS source name for cds_testcases',
962
+ description: 'Object name (for syntax/unittest/atc/object_state); the CDS entity / DDLS source name for cds_testcases and cds_sql',
963
+ },
964
+ url: {
965
+ type: 'string',
966
+ description: 'For odata_perf: the host-relative OData path to probe, from the Fiori app\'s Network tab (e.g. "/sap/opu/odata4/sap/.../Entity?$filter=…"). Must be a path on the connected system — absolute URLs are rejected.',
1020
967
  },
1021
968
  type: {
1022
969
  type: 'string',
@@ -1069,7 +1016,7 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1069
1016
  variant: { type: 'string', description: 'ATC check variant (for atc action)' },
1070
1017
  id: {
1071
1018
  type: 'string',
1072
- description: 'Dump or trace ID (for dumps/traces actions). Omit to list, provide to get details.',
1019
+ description: 'Dump or trace ID (for dumps/traces actions); also the trace-request id to cancel (for trace_cancel). Omit to list, provide to get details.',
1073
1020
  },
1074
1021
  detailUrl: {
1075
1022
  type: 'string',
@@ -1101,11 +1048,53 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1101
1048
  type: 'boolean',
1102
1049
  description: 'For dumps detail mode only: include full formattedText blob. Default false to reduce token usage.',
1103
1050
  },
1051
+ coverage: {
1052
+ type: 'boolean',
1053
+ description: 'For action="unittest": also return statement/branch/procedure coverage for the object, plus methodsBelowFull — the methods below 100% statement coverage, worst first (what to test next) — in one extra round-trip. If the coverage endpoint or measurement is unavailable, returns the tests without coverage. Default false.',
1054
+ },
1055
+ sqlOn: {
1056
+ type: 'boolean',
1057
+ description: 'For action="set_sql_trace_state": true to arm the ST05 SQL trace, false to disarm. Combine with user to filter the trace to one SAP user.',
1058
+ },
1104
1059
  analysis: {
1105
1060
  type: 'string',
1106
1061
  enum: ['hitlist', 'statements', 'dbAccesses'],
1107
1062
  description: 'Trace analysis type (for traces action with id). hitlist = execution hot spots, statements = call tree, dbAccesses = database access stats.',
1108
1063
  },
1064
+ traceUser: {
1065
+ type: 'string',
1066
+ description: 'For trace_start/trace_requests: the SAP user whose matching execution is traced/listed. Defaults to the connected user.',
1067
+ },
1068
+ processType: {
1069
+ type: 'string',
1070
+ enum: ['any', 'http', 'dialog', 'batch', 'rfc'],
1071
+ description: 'For trace_start: the kind of work process to capture. Default "http" (OData/Gateway). dialog = SAP GUI transaction, batch = background job, rfc = RFC call.',
1072
+ },
1073
+ objectType: {
1074
+ type: 'string',
1075
+ enum: ['any', 'url', 'transaction', 'report', 'functionModule'],
1076
+ description: 'For trace_start: what to match within the process. Defaults to the valid type for the process type (http→url, dialog→transaction, batch→report, rfc→functionModule).',
1077
+ },
1078
+ maxExecutions: {
1079
+ type: 'number',
1080
+ description: 'For trace_start: how many matching executions to capture before the request is consumed (default 1).',
1081
+ },
1082
+ expiresHours: {
1083
+ type: 'number',
1084
+ description: 'For trace_start: hours until the armed request auto-expires (default 24).',
1085
+ },
1086
+ sqlTrace: {
1087
+ type: 'boolean',
1088
+ description: 'For trace_start: capture SQL/DB accesses (default true — required for analysis="dbAccesses").',
1089
+ },
1090
+ aggregate: {
1091
+ type: 'boolean',
1092
+ description: 'For trace_start: aggregate the trace (default true).',
1093
+ },
1094
+ description: {
1095
+ type: 'string',
1096
+ description: 'For trace_start: optional label for the trace request.',
1097
+ },
1109
1098
  },
1110
1099
  required: ['action'],
1111
1100
  },
@@ -1119,17 +1108,17 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1119
1108
  properties: {
1120
1109
  action: {
1121
1110
  type: 'string',
1122
- enum: ['impact', 'deps', 'usages'],
1111
+ enum: ['impact', 'deps', 'usages', 'structure'],
1123
1112
  description: 'Action:\n' +
1124
1113
  '"impact" = CDS blast-radius analysis (DDLS only). USE THIS for any question like "what breaks if I change <view>", "who consumes <I_*>", "impact analysis on <CDS>", "downstream of <view>". Returns upstream AST dependencies + downstream where-used classified into RAP buckets (projectionViews, bdefs, serviceDefinitions, serviceBindings, accessControls, metadataExtensions, abapConsumers, documentation, tables, other), plus additive sibling-consistency diagnostics (consistencyHints + siblingExtensionAnalysis) when related DDLS siblings show asymmetric DDLX coverage. ALWAYS prefer over SAPQuery against DDDDLSRC/ACMDCLSRC/DDLXSRC_SRC/SRVDSRC_SRC (those text-scans produce noise this classifier filters out). Non-DDLS input returns a guardrail error.\n' +
1125
1114
  '"deps" (default, can be omitted) = object understanding / forward dependency context — "what does <object> do?" or "what does <object> depend on?". Returns the object KTD when available plus public API contracts of dependencies.\n' +
1126
- '"usages" = reverse dependency lookup — "who calls <object>?". Requires cache warmup (--cache-warmup). Only "name" is needed. For CDS entities prefer action="impact" instead.',
1115
+ '"usages" = reverse dependency lookup — "who calls <object>?". Requires cache warmup (--cache-warmup). Only "name" is needed. For CDS entities prefer action="impact" instead.\n' +
1116
+ '"structure" = TABL includes/appends.',
1127
1117
  },
1128
1118
  type: {
1129
1119
  type: 'string',
1130
1120
  enum: btp ? SAPCONTEXT_TYPES_BTP : SAPCONTEXT_TYPES_ONPREM,
1131
- description: 'Object type. Required for action="deps" and action="usages". ' +
1132
- 'Optional for action="impact" — defaults to DDLS (the only supported type for impact).',
1121
+ description: 'Object type. Optional for action="impact" (defaults to DDLS); required otherwise.',
1133
1122
  },
1134
1123
  name: {
1135
1124
  type: 'string',
@@ -1228,11 +1217,21 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1228
1217
  },
1229
1218
  objectUri: {
1230
1219
  type: 'string',
1231
- description: 'ADT URI of the object to move (e.g., /sap/bc/adt/oo/classes/zcl_my_class). If not provided, resolved automatically from objectName + objectType via search.',
1220
+ description: 'ADT URI of the object to move (e.g., /sap/bc/adt/oo/classes/zcl_my_class). If not provided, resolved automatically from objectName + objectType via search. For set_api_state: the object whose API release contract to set (or pass name + objectType instead).',
1232
1221
  },
1233
1222
  objectType: {
1234
1223
  type: 'string',
1235
- description: 'ADT object type (e.g., CLAS/OC, DDLS/DF, PROG/P). Required for change_package.',
1224
+ description: 'ADT object type (e.g., CLAS/OC, DDLS/DF, PROG/P). Required for change_package. For set_api_state: object type of "name" when objectUri is omitted (e.g. CLAS, INTF, DDLS, TABL).',
1225
+ },
1226
+ apiState: {
1227
+ type: 'string',
1228
+ enum: ['RELEASED', 'NOT_RELEASED'],
1229
+ description: 'For set_api_state: target state of the object\'s API release contract — RELEASED (mark released for ABAP Cloud / Clean Core) or NOT_RELEASED (revoke). Default RELEASED. Visibility (ABAP Cloud / Key User Apps) follows the contract\'s defaults. Read the current state first with SAPRead(type="API_STATE").',
1230
+ },
1231
+ contract: {
1232
+ type: 'string',
1233
+ enum: ['C0', 'C1', 'C2', 'C3', 'C4'],
1234
+ description: 'For set_api_state: which release contract to set. Default C1 (Key-User/Cloud — the common clean-core contract). Object types support different contracts: e.g. service definitions (SRVD) only support C0, classic DDIC views only C3, behavior definitions and tables support C0+C1. If the object does not support the chosen contract, the error lists the ones it does.',
1236
1235
  },
1237
1236
  objectName: {
1238
1237
  type: 'string',
@@ -1256,11 +1255,11 @@ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures
1256
1255
  },
1257
1256
  title: {
1258
1257
  type: 'string',
1259
- description: 'Title for FLP catalog/group creation.',
1258
+ description: 'Title — required for flp_create_catalog and flp_create_group.',
1260
1259
  },
1261
1260
  domainId: {
1262
1261
  type: 'string',
1263
- description: 'Domain ID for FLP catalog creation (e.g., ZARC1_SALES).',
1262
+ description: 'Domain ID required for flp_create_catalog (e.g., ZARC1_SALES).',
1264
1263
  },
1265
1264
  tileInstanceId: {
1266
1265
  type: 'string',