arc-1 0.6.9 → 0.7.0

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 (157) hide show
  1. package/README.md +12 -9
  2. package/bin/arc1-cli.js +10 -0
  3. package/bin/arc1.js +1 -1
  4. package/dist/adt/abapgit.d.ts +39 -0
  5. package/dist/adt/abapgit.d.ts.map +1 -0
  6. package/dist/adt/abapgit.js +333 -0
  7. package/dist/adt/abapgit.js.map +1 -0
  8. package/dist/adt/cds-impact.d.ts +35 -0
  9. package/dist/adt/cds-impact.d.ts.map +1 -1
  10. package/dist/adt/cds-impact.js +71 -0
  11. package/dist/adt/cds-impact.js.map +1 -1
  12. package/dist/adt/client.d.ts +4 -1
  13. package/dist/adt/client.d.ts.map +1 -1
  14. package/dist/adt/client.js +18 -5
  15. package/dist/adt/client.js.map +1 -1
  16. package/dist/adt/config.d.ts +1 -0
  17. package/dist/adt/config.d.ts.map +1 -1
  18. package/dist/adt/config.js +1 -0
  19. package/dist/adt/config.js.map +1 -1
  20. package/dist/adt/crud.d.ts.map +1 -1
  21. package/dist/adt/crud.js +74 -8
  22. package/dist/adt/crud.js.map +1 -1
  23. package/dist/adt/devtools.d.ts +39 -3
  24. package/dist/adt/devtools.d.ts.map +1 -1
  25. package/dist/adt/devtools.js +237 -25
  26. package/dist/adt/devtools.js.map +1 -1
  27. package/dist/adt/diagnostics.d.ts +69 -7
  28. package/dist/adt/diagnostics.d.ts.map +1 -1
  29. package/dist/adt/diagnostics.js +694 -36
  30. package/dist/adt/diagnostics.js.map +1 -1
  31. package/dist/adt/errors.d.ts +36 -2
  32. package/dist/adt/errors.d.ts.map +1 -1
  33. package/dist/adt/errors.js +111 -11
  34. package/dist/adt/errors.js.map +1 -1
  35. package/dist/adt/features.d.ts.map +1 -1
  36. package/dist/adt/features.js +3 -0
  37. package/dist/adt/features.js.map +1 -1
  38. package/dist/adt/gcts.d.ts +68 -0
  39. package/dist/adt/gcts.d.ts.map +1 -0
  40. package/dist/adt/gcts.js +239 -0
  41. package/dist/adt/gcts.js.map +1 -0
  42. package/dist/adt/http.d.ts.map +1 -1
  43. package/dist/adt/http.js +86 -1
  44. package/dist/adt/http.js.map +1 -1
  45. package/dist/adt/rap-handlers.d.ts +165 -0
  46. package/dist/adt/rap-handlers.d.ts.map +1 -0
  47. package/dist/adt/rap-handlers.js +835 -0
  48. package/dist/adt/rap-handlers.js.map +1 -0
  49. package/dist/adt/rap-preflight.d.ts +43 -0
  50. package/dist/adt/rap-preflight.d.ts.map +1 -0
  51. package/dist/adt/rap-preflight.js +405 -0
  52. package/dist/adt/rap-preflight.js.map +1 -0
  53. package/dist/adt/safety.d.ts +60 -33
  54. package/dist/adt/safety.d.ts.map +1 -1
  55. package/dist/adt/safety.js +204 -113
  56. package/dist/adt/safety.js.map +1 -1
  57. package/dist/adt/transport.d.ts +1 -1
  58. package/dist/adt/transport.d.ts.map +1 -1
  59. package/dist/adt/transport.js +6 -3
  60. package/dist/adt/transport.js.map +1 -1
  61. package/dist/adt/types.d.ts +225 -0
  62. package/dist/adt/types.d.ts.map +1 -1
  63. package/dist/adt/xml-parser.d.ts +15 -1
  64. package/dist/adt/xml-parser.d.ts.map +1 -1
  65. package/dist/adt/xml-parser.js +28 -15
  66. package/dist/adt/xml-parser.js.map +1 -1
  67. package/dist/authz/policy.d.ts +53 -0
  68. package/dist/authz/policy.d.ts.map +1 -0
  69. package/dist/authz/policy.js +199 -0
  70. package/dist/authz/policy.js.map +1 -0
  71. package/dist/cli-args.d.ts +14 -0
  72. package/dist/cli-args.d.ts.map +1 -0
  73. package/dist/cli-args.js +62 -0
  74. package/dist/cli-args.js.map +1 -0
  75. package/dist/cli.d.ts +13 -7
  76. package/dist/cli.d.ts.map +1 -1
  77. package/dist/cli.js +252 -55
  78. package/dist/cli.js.map +1 -1
  79. package/dist/extract-sap-cookies.d.ts +24 -0
  80. package/dist/extract-sap-cookies.d.ts.map +1 -0
  81. package/dist/extract-sap-cookies.js +317 -0
  82. package/dist/extract-sap-cookies.js.map +1 -0
  83. package/dist/handlers/hyperfocused.d.ts +4 -3
  84. package/dist/handlers/hyperfocused.d.ts.map +1 -1
  85. package/dist/handlers/hyperfocused.js +25 -16
  86. package/dist/handlers/hyperfocused.js.map +1 -1
  87. package/dist/handlers/intent.d.ts +4 -12
  88. package/dist/handlers/intent.d.ts.map +1 -1
  89. package/dist/handlers/intent.js +1448 -89
  90. package/dist/handlers/intent.js.map +1 -1
  91. package/dist/handlers/schemas.d.ts +83 -11
  92. package/dist/handlers/schemas.d.ts.map +1 -1
  93. package/dist/handlers/schemas.js +115 -4
  94. package/dist/handlers/schemas.js.map +1 -1
  95. package/dist/handlers/tools.d.ts +4 -3
  96. package/dist/handlers/tools.d.ts.map +1 -1
  97. package/dist/handlers/tools.js +342 -143
  98. package/dist/handlers/tools.js.map +1 -1
  99. package/dist/index.d.ts +1 -1
  100. package/dist/index.js +7 -6
  101. package/dist/index.js.map +1 -1
  102. package/dist/probe/catalog.d.ts +30 -0
  103. package/dist/probe/catalog.d.ts.map +1 -0
  104. package/dist/probe/catalog.js +196 -0
  105. package/dist/probe/catalog.js.map +1 -0
  106. package/dist/probe/fixtures.d.ts +54 -0
  107. package/dist/probe/fixtures.d.ts.map +1 -0
  108. package/dist/probe/fixtures.js +94 -0
  109. package/dist/probe/fixtures.js.map +1 -0
  110. package/dist/probe/format.d.ts +10 -0
  111. package/dist/probe/format.d.ts.map +1 -0
  112. package/dist/probe/format.js +114 -0
  113. package/dist/probe/format.js.map +1 -0
  114. package/dist/probe/quality.d.ts +13 -0
  115. package/dist/probe/quality.d.ts.map +1 -0
  116. package/dist/probe/quality.js +50 -0
  117. package/dist/probe/quality.js.map +1 -0
  118. package/dist/probe/runner.d.ts +48 -0
  119. package/dist/probe/runner.d.ts.map +1 -0
  120. package/dist/probe/runner.js +211 -0
  121. package/dist/probe/runner.js.map +1 -0
  122. package/dist/probe/types.d.ts +159 -0
  123. package/dist/probe/types.d.ts.map +1 -0
  124. package/dist/probe/types.js +11 -0
  125. package/dist/probe/types.js.map +1 -0
  126. package/dist/server/audit.d.ts +26 -3
  127. package/dist/server/audit.d.ts.map +1 -1
  128. package/dist/server/audit.js +12 -1
  129. package/dist/server/audit.js.map +1 -1
  130. package/dist/server/config.d.ts +34 -19
  131. package/dist/server/config.d.ts.map +1 -1
  132. package/dist/server/config.js +327 -187
  133. package/dist/server/config.js.map +1 -1
  134. package/dist/server/deny-actions.d.ts +31 -0
  135. package/dist/server/deny-actions.d.ts.map +1 -0
  136. package/dist/server/deny-actions.js +156 -0
  137. package/dist/server/deny-actions.js.map +1 -0
  138. package/dist/server/effective-policy-log.d.ts +27 -0
  139. package/dist/server/effective-policy-log.d.ts.map +1 -0
  140. package/dist/server/effective-policy-log.js +103 -0
  141. package/dist/server/effective-policy-log.js.map +1 -0
  142. package/dist/server/http.d.ts.map +1 -1
  143. package/dist/server/http.js +15 -16
  144. package/dist/server/http.js.map +1 -1
  145. package/dist/server/server.d.ts +38 -4
  146. package/dist/server/server.d.ts.map +1 -1
  147. package/dist/server/server.js +234 -31
  148. package/dist/server/server.js.map +1 -1
  149. package/dist/server/types.d.ts +31 -13
  150. package/dist/server/types.d.ts.map +1 -1
  151. package/dist/server/types.js +11 -10
  152. package/dist/server/types.js.map +1 -1
  153. package/dist/server/xsuaa.d.ts +1 -2
  154. package/dist/server/xsuaa.d.ts.map +1 -1
  155. package/dist/server/xsuaa.js +13 -14
  156. package/dist/server/xsuaa.js.map +1 -1
  157. package/package.json +9 -3
@@ -1,12 +1,12 @@
1
1
  /**
2
- * Tool definitions for ARC-1's 11 intent-based MCP tools.
2
+ * Tool definitions for ARC-1's 12 intent-based MCP tools.
3
3
  *
4
4
  * Each tool has:
5
5
  * - name: The MCP tool name (SAPRead, SAPWrite, etc.)
6
6
  * - description: Rich LLM-friendly description
7
7
  * - inputSchema: JSON Schema for tool arguments
8
8
  *
9
- * The 11 intent-based design is ARC-1's key differentiator:
9
+ * The 12 intent-based design is ARC-1's key differentiator:
10
10
  * instead of 200+ individual tools (one per object type per operation),
11
11
  * we group by *intent* with a `type` parameter for routing.
12
12
  * This keeps the LLM's tool selection simple and the context window small.
@@ -133,7 +133,8 @@ const SAPWRITE_DESC_ONPREM = 'Create or update ABAP source code and DDIC metadat
133
133
  'SKTD (Knowledge Transfer Documents, Markdown docs attached to an ABAP object): create requires refObjectType (parent ADT type+subtype, e.g., "DDLS/DF"). 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="..."). ' +
134
134
  'For edit_method: surgically replace a single method body in a CLAS without sending the full class source. ' +
135
135
  'Provide just the new method implementation code in "source" — 95% fewer tokens than full-class updates. ' +
136
- '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.';
136
+ '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. ' +
137
+ 'For scaffold_rap_handlers: derive missing RAP behavior handler signatures from an interface BDEF and optionally inject declarations plus empty implementation stubs into an existing behavior pool class.';
137
138
  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, DDLX, BDEF, SRVD, SRVB, SKTD, TABL, DOMA, DTEL, MSAG. ' +
138
139
  'Type codes are auto-normalized and case-insensitive (e.g., "CLAS/OC" → "CLAS"). ' +
139
140
  'TABL supports custom table source writes via /source/main (define table syntax). ' +
@@ -144,7 +145,8 @@ const SAPWRITE_DESC_BTP = 'Create or update ABAP source code and DDIC metadata (
144
145
  'SKTD (Knowledge Transfer Documents, Markdown docs attached to an ABAP object): create requires refObjectType (parent ADT type+subtype, e.g., "DDLS/DF"). 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="..."). ' +
145
146
  'Must use ABAP Cloud language version (no classic statements). Only Z*/Y* namespace allowed on BTP. ' +
146
147
  'For edit_method: surgically replace a single method body in a CLAS without sending the full class source. ' +
147
- 'For batch_create: create and activate multiple objects in a single call — ideal for RAP stacks (TABL → DDLS → DCLS → BDEF → SRVD).';
148
+ 'For batch_create: create and activate multiple objects in a single call — ideal for RAP stacks (TABL → DDLS → DCLS → BDEF → SRVD). ' +
149
+ 'For scaffold_rap_handlers: derive missing RAP behavior handler signatures from an interface BDEF and optionally inject declarations plus empty implementation stubs into an existing behavior pool class.';
148
150
  // ─── SAPContext Types ───────────────────────────────────────────────
149
151
  const SAPCONTEXT_TYPES_ONPREM = ['CLAS', 'INTF', 'PROG', 'FUNC', 'DDLS'];
150
152
  const SAPCONTEXT_TYPES_BTP = ['CLAS', 'INTF', 'DDLS'];
@@ -153,7 +155,7 @@ const SAPCONTEXT_DESC_ONPREM = 'Get compressed dependency context or CDS blast-r
153
155
  '- "What breaks if I change <CDS view>?" / "Who consumes <I_*>?" / "Impact analysis on <DDLS>" / "Blast radius" → action="impact"\n' +
154
156
  '- "Understand dependencies before editing <object>" / "What does X depend on?" → action="deps" (default)\n' +
155
157
  '- "Find all callers of <object>" (cache-warmup required) → action="usages"\n\n' +
156
- '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. 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.\n\n' +
158
+ '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' +
157
159
  'action="deps" (default): Returns 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 dependencies. Instead of N separate SAPRead calls returning full source (~200 lines each), returns ONE response with compressed contracts (~15-30 lines each). Typical compression: 7-30x fewer tokens.\n\n' +
158
160
  'What deps extracts per dependency:\n' +
159
161
  '- Classes: CLASS DEFINITION with PUBLIC SECTION only (methods, types, constants). PROTECTED, PRIVATE and IMPLEMENTATION stripped.\n' +
@@ -170,7 +172,7 @@ const SAPCONTEXT_DESC_BTP = 'Get compressed dependency context or CDS blast-radi
170
172
  "Decision rule — pick the action based on the user's question:\n" +
171
173
  '- "What breaks if I change <CDS view>?" / "Who consumes <I_*>?" / "Impact analysis on <DDLS>" / "Blast radius" → action="impact"\n' +
172
174
  '- "Understand dependencies before editing <object>" / "What does X depend on?" → action="deps" (default)\n\n' +
173
- '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. DO NOT replicate this with SAPQuery — the classifier already filters noise. Optional includeIndirect=true widens to transitive consumers.\n\n' +
175
+ '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' +
174
176
  'action="deps" (default): Returns 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' +
175
177
  'What deps extracts per dependency:\n' +
176
178
  '- Classes: CLASS DEFINITION with PUBLIC SECTION only (methods, types, constants).\n' +
@@ -185,7 +187,7 @@ const SAPQUERY_DESC_ONPREM = 'Execute ABAP SQL queries against SAP tables. Retur
185
187
  'Powerful for reverse-engineering: query metadata tables like DD02L (table catalog), DD03L (field catalog), ' +
186
188
  'SWOTLV (BOR method implementations), TADIR (object directory), TFDIR (function modules). ' +
187
189
  'If a table is not found, similar table names will be suggested automatically. ' +
188
- 'Note: Uses the ADT freestyle SQL endpoint (same as ADT SQL Console in Eclipse). Supports ABAP SQL syntax including JOINs, but the endpoint parser has known edge cases with complex queries on some system versions (SAP Note 3605050). If a complex query fails, try simplifying split JOINs into separate single-table SELECTs.\n\n' +
190
+ '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). If parsing fails, simplify to one SELECT and split multi-table logic into staged single-table queries (SAP Note 3605050).\n\n' +
189
191
  '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).';
190
192
  const SAPQUERY_DESC_BTP = 'Execute ABAP SQL queries (BTP ABAP Environment). Returns structured data with column names and rows. ' +
191
193
  'IMPORTANT: On BTP, only custom Z/Y tables and released CDS entities can be queried. ' +
@@ -207,14 +209,14 @@ const SAPTRANSPORT_DESC_ONPREM = 'Manage CTS transport requests (SE09/SE10 equiv
207
209
  'get (details with tasks and objects), create (K=Workbench, W=Customizing, T=Transport of Copies), ' +
208
210
  'release, delete, reassign (change owner), release_recursive (release tasks first, then parent), ' +
209
211
  'check (check if a package requires a transport — provide type, name, package), ' +
210
- 'history (find transports referencing an object — provide type, name; read-only, works without --enable-transports). ' +
212
+ 'history (find transports referencing an object — provide type, name; read-only, works without SAP_ALLOW_TRANSPORT_WRITES). ' +
211
213
  'Transport IDs look like A4HK900123. Status: D=modifiable, R=released.';
212
214
  const SAPTRANSPORT_DESC_BTP = 'Manage transport requests (BTP ABAP Environment, SE09/SE10 equivalent). ' +
213
215
  'Actions: list (defaults to current user, modifiable transports — both Workbench and Customizing), ' +
214
216
  'get (details with tasks and objects), create (K=Workbench, W=Customizing, T=Transport of Copies), ' +
215
217
  'release, delete, reassign (change owner), release_recursive (release tasks first, then parent), ' +
216
218
  'check (check if a package requires a transport — provide type, name, package), ' +
217
- 'history (find transports referencing an object — provide type, name; read-only, works without --enable-transports). ' +
219
+ 'history (find transports referencing an object — provide type, name; read-only, works without SAP_ALLOW_TRANSPORT_WRITES). ' +
218
220
  'On BTP, transport release triggers a gCTS push to the software component Git repository. ' +
219
221
  'Import into target systems is done via the Manage Software Components app or Cloud Transport Management Service (cTMS), not via this tool.';
220
222
  // ─── SAPManage ──────────────────────────────────────────────────────
@@ -223,14 +225,14 @@ const SAPMANAGE_DESC_ONPREM = 'Probe and report SAP system capabilities. Use thi
223
225
  'Actions:\n' +
224
226
  '- "features": Get cached feature status from last probe (fast, no SAP round-trip). ' +
225
227
  'Returns which features are available, their mode (auto/on/off), and when they were last probed.\n' +
226
- '- "probe": Re-probe the SAP system now (makes 8 parallel requests, ~1-2s). ' +
228
+ '- "probe": Re-probe the SAP system now (runs feature probes, auth checks, and ADT discovery refresh). ' +
227
229
  'Use this on first use or if you suspect feature availability has changed.\n' +
228
230
  '- "cache_stats": Show object cache health and warmup state.\n' +
229
- '- "create_package": Create a package (DEVC) via ADT packages API.\n' +
230
- '- "delete_package": Delete an existing package.\n' +
231
231
  '- "flp_list_catalogs": List FLP business catalogs.\n' +
232
232
  '- "flp_list_groups": List FLP groups.\n' +
233
233
  '- "flp_list_tiles": List tiles in a catalog (requires "catalogId").\n' +
234
+ '- "create_package": Create a package (DEVC) via ADT packages API.\n' +
235
+ '- "delete_package": Delete an existing package.\n' +
234
236
  '- "flp_create_catalog": Create a business catalog (requires "domainId", "title").\n' +
235
237
  '- "flp_create_group": Create a group (requires "groupId", "title").\n' +
236
238
  '- "flp_create_tile": Create a tile in a catalog (requires "catalogId", "tile").\n' +
@@ -243,13 +245,51 @@ const SAPMANAGE_DESC_BTP = 'Probe and report SAP system capabilities (BTP ABAP E
243
245
  'Returns feature status and system type. Also handles package (DEVC) lifecycle operations.\n\n' +
244
246
  'Actions:\n' +
245
247
  '- "features": Get cached feature status from last probe.\n' +
246
- '- "probe": Re-probe the SAP system now.\n' +
248
+ '- "probe": Re-probe the SAP system now (feature probes + discovery refresh).\n' +
247
249
  '- "cache_stats": Show object cache health and warmup state.\n' +
248
250
  '- "create_package": Create a package (DEVC) via ADT packages API.\n' +
249
251
  '- "delete_package": Delete an existing package.\n' +
250
252
  '- 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' +
251
253
  'Returns JSON with features and systemType="btp". On BTP, RAP/CDS and transports are always available. ' +
252
254
  'abapGit, AMDP, UI5/BSP, and FLP customization may not be available depending on the BTP ABAP configuration.';
255
+ const SAPMANAGE_ACTIONS_READ = [
256
+ 'features',
257
+ 'probe',
258
+ 'cache_stats',
259
+ 'flp_list_catalogs',
260
+ 'flp_list_groups',
261
+ 'flp_list_tiles',
262
+ ];
263
+ const SAPMANAGE_ACTIONS_WRITE = [
264
+ 'create_package',
265
+ 'delete_package',
266
+ 'change_package',
267
+ 'flp_create_catalog',
268
+ 'flp_create_group',
269
+ 'flp_create_tile',
270
+ 'flp_add_tile_to_group',
271
+ 'flp_delete_catalog',
272
+ ];
273
+ const SAPTRANSPORT_ACTIONS_READ = ['list', 'get', 'check', 'history'];
274
+ const SAPTRANSPORT_ACTIONS_WRITE = ['create', 'release', 'delete', 'reassign', 'release_recursive'];
275
+ const SAPGIT_ACTIONS_READ = [
276
+ 'list_repos',
277
+ 'whoami',
278
+ 'config',
279
+ 'branches',
280
+ 'external_info',
281
+ 'history',
282
+ 'objects',
283
+ 'check',
284
+ ];
285
+ const SAPGIT_ACTIONS_WRITE = ['stage', 'clone', 'pull', 'push', 'commit', 'switch_branch', 'create_branch', 'unlink'];
286
+ // ─── SAPGit ─────────────────────────────────────────────────────────
287
+ const SAPGIT_DESC_ONPREM = 'Git-based ABAP repository workflows with backend auto-selection: gCTS is preferred when available, otherwise abapGit bridge is used. ' +
288
+ 'Actions: list_repos (both), whoami/config/branches/history/objects (gCTS only), external_info/check/stage/push (abapGit only), clone/pull/commit/switch_branch/create_branch/unlink (backend-specific implementation). ' +
289
+ 'Use backend="gcts" or backend="abapgit" to force a backend. Write actions require SAP_ALLOW_WRITES=true, SAP_ALLOW_GIT_WRITES=true, git scope, and package allowlist compliance.';
290
+ const SAPGIT_DESC_BTP = 'Git-based ABAP repository workflows for BTP ABAP and S/4 systems. Backend auto-selection prefers gCTS and falls back to abapGit bridge when gCTS is unavailable. ' +
291
+ 'Actions: list_repos (both), whoami/config/branches/history/objects (gCTS only), external_info/check/stage/push (abapGit only), clone/pull/commit/switch_branch/create_branch/unlink (backend-specific implementation). ' +
292
+ 'Use backend="gcts" or backend="abapgit" to force a backend. Write actions require SAP_ALLOW_WRITES=true, SAP_ALLOW_GIT_WRITES=true, git scope, and package allowlist compliance.';
253
293
  // ─── SAPSearch Builder ─────────────────────────────────────────────
254
294
  /** Strip source_code-specific lines from a SAPSearch description when textSearch is unavailable */
255
295
  function stripSourceCodeLines(desc) {
@@ -306,10 +346,10 @@ function buildSAPSearchTool(btp, textSearchAvailable) {
306
346
  };
307
347
  }
308
348
  // ─── Main Tool Definitions ──────────────────────────────────────────
309
- export function getToolDefinitions(config, textSearchAvailable) {
349
+ export function getToolDefinitions(config, textSearchAvailable, resolvedFeatures) {
310
350
  // Hyperfocused mode: single universal SAP tool (~200 tokens)
311
351
  if (config.toolMode === 'hyperfocused') {
312
- return [getHyperfocusedToolDefinition(config)];
352
+ return [getHyperfocusedToolDefinition(config, resolvedFeatures)];
313
353
  }
314
354
  const btp = isBtpMode(config);
315
355
  const tools = [
@@ -358,7 +398,10 @@ export function getToolDefinitions(config, textSearchAvailable) {
358
398
  description: 'Output format. "text" (default): raw source code. "structured" (CLAS only): JSON with metadata (description, language, category) + decomposed source (main, testclasses, definitions, implementations, macros). Useful when you need to understand class structure or separate test code from production code.',
359
399
  },
360
400
  maxRows: { type: 'number', description: 'For TABLE_CONTENTS: max rows to return (default 100)' },
361
- sqlFilter: { type: 'string', description: 'For TABLE_CONTENTS: SQL WHERE clause filter' },
401
+ sqlFilter: {
402
+ type: 'string',
403
+ description: 'For TABLE_CONTENTS: condition expression only (no WHERE, no SELECT), e.g. "MANDT = \'100\'" or "MATNR LIKE \'Z%\'".',
404
+ },
362
405
  objectType: {
363
406
  type: 'string',
364
407
  description: 'For API_STATE and VERSIONS: SAP object type (CLAS, INTF, PROG, FUNC, INCL, DDLS, DCLS, BDEF, SRVD, etc.). For API_STATE: auto-detected from name if omitted. For VERSIONS: required to pick the correct revisions endpoint (e.g., "FUNC" + group for function modules); inferred from CL_/IF_/CX_ name prefixes when possible, defaults to PROG.',
@@ -373,8 +416,8 @@ export function getToolDefinitions(config, textSearchAvailable) {
373
416
  },
374
417
  buildSAPSearchTool(btp, textSearchAvailable),
375
418
  ];
376
- // Write tools — only registered when not in read-only mode
377
- if (!config.readOnly) {
419
+ // Write tools — only registered when writes are enabled
420
+ if (config.allowWrites) {
378
421
  let sapWriteDesc = btp ? SAPWRITE_DESC_BTP : SAPWRITE_DESC_ONPREM;
379
422
  // Append package restriction info so the LLM knows its boundaries
380
423
  if (config.allowedPackages.length > 0) {
@@ -389,8 +432,8 @@ export function getToolDefinitions(config, textSearchAvailable) {
389
432
  properties: {
390
433
  action: {
391
434
  type: 'string',
392
- enum: ['create', 'update', 'delete', 'edit_method', 'batch_create'],
393
- description: 'Write action. edit_method: surgically replace a single method body (requires type=CLAS, method, and source params). batch_create: create and activate multiple objects in sequence (requires objects array)',
435
+ enum: ['create', 'update', 'delete', 'edit_method', 'batch_create', 'scaffold_rap_handlers'],
436
+ description: 'Write action. edit_method: surgically replace a single method body (requires type=CLAS, method, and source params). 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.',
394
437
  },
395
438
  type: {
396
439
  type: 'string',
@@ -405,6 +448,18 @@ export function getToolDefinitions(config, textSearchAvailable) {
405
448
  type: 'string',
406
449
  description: 'For edit_method action: method name to replace (e.g., "get_name", "zif_order~process")',
407
450
  },
451
+ bdefName: {
452
+ type: 'string',
453
+ 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.',
454
+ },
455
+ autoApply: {
456
+ type: 'boolean',
457
+ 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.',
458
+ },
459
+ targetAlias: {
460
+ type: 'string',
461
+ description: 'For scaffold_rap_handlers: optional RAP entity alias filter (e.g., Travel, Segment) to scaffold only one handler class. When omitted, all entities declared in the BDEF are scaffolded. Case-insensitive.',
462
+ },
408
463
  description: {
409
464
  type: 'string',
410
465
  description: 'Object description for create action (defaults to name if omitted). Max 60 chars for most types.',
@@ -472,7 +527,15 @@ export function getToolDefinitions(config, textSearchAvailable) {
472
527
  version: { type: 'string', description: 'SRVB: service version number (default: 0001)' },
473
528
  lintBeforeWrite: {
474
529
  type: 'boolean',
475
- 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 (not supported by offline linter).',
530
+ 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.',
531
+ },
532
+ preflightBeforeWrite: {
533
+ type: 'boolean',
534
+ 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).',
535
+ },
536
+ checkBeforeWrite: {
537
+ type: 'boolean',
538
+ 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.',
476
539
  },
477
540
  refObjectType: {
478
541
  type: 'string',
@@ -643,7 +706,7 @@ export function getToolDefinitions(config, textSearchAvailable) {
643
706
  },
644
707
  });
645
708
  // SAPQuery — only registered when free SQL is allowed
646
- if (!config.blockFreeSQL) {
709
+ if (config.allowFreeSQL) {
647
710
  tools.push({
648
711
  name: 'SAPQuery',
649
712
  description: btp ? SAPQUERY_DESC_BTP : SAPQUERY_DESC_ONPREM,
@@ -702,20 +765,32 @@ export function getToolDefinitions(config, textSearchAvailable) {
702
765
  name: 'SAPDiagnose',
703
766
  description: 'Run diagnostics on ABAP objects and analyze runtime errors.\n\n' +
704
767
  'Actions:\n' +
705
- '- "syntax": Syntax check an ABAP object. Requires name + type.\n' +
768
+ '- "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' +
706
769
  '- "unittest": Run ABAP unit tests. Requires name + type.\n' +
707
770
  '- "atc": Run ATC code quality checks. Requires name + type. Optional: variant.\n' +
708
771
  '- "quickfix": Get SAP quick fix proposals for a specific source position. Requires name + type + source + line. Optional: column.\n' +
709
772
  '- "apply_quickfix": Apply one quick fix proposal and return text deltas (does not write source). Requires name + type + source + line + proposalUri + proposalUserContent. Optional: column.\n' +
710
- '- "dumps": List or read ABAP short dumps (ST22). Without id: lists recent dumps (filter by user, maxResults). With id: returns full dump detail including formatted text, error analysis, source code extract, and call stack.\n' +
773
+ '- "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' +
711
774
  '- "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' +
775
+ '- "system_messages": List SM02 system messages via ADT feed (filter by user, maxResults, from, to).\n' +
776
+ '- "gateway_errors": List SAP Gateway error log entries (/IWFND/ERROR_LOG, on-prem). For detail mode provide detailUrl (preferred) or id+errorType.\n\n' +
712
777
  '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.',
713
778
  inputSchema: {
714
779
  type: 'object',
715
780
  properties: {
716
781
  action: {
717
782
  type: 'string',
718
- enum: ['syntax', 'unittest', 'atc', 'dumps', 'traces', 'quickfix', 'apply_quickfix'],
783
+ enum: [
784
+ 'syntax',
785
+ 'unittest',
786
+ 'atc',
787
+ 'dumps',
788
+ 'traces',
789
+ 'system_messages',
790
+ 'gateway_errors',
791
+ 'quickfix',
792
+ 'apply_quickfix',
793
+ ],
719
794
  description: 'Diagnostic action',
720
795
  },
721
796
  name: { type: 'string', description: 'Object name (for syntax/unittest/atc)' },
@@ -732,6 +807,11 @@ export function getToolDefinitions(config, textSearchAvailable) {
732
807
  type: 'number',
733
808
  description: 'Source column number for quickfix evaluation (default 0 for quickfix actions).',
734
809
  },
810
+ version: {
811
+ type: 'string',
812
+ enum: ['active', 'inactive'],
813
+ description: 'Source version for syntax check (default "active"). Use "inactive" to validate pending changes.',
814
+ },
735
815
  proposalUri: {
736
816
  type: 'string',
737
817
  description: 'Quickfix proposal URI from quickfix action (required for apply_quickfix).',
@@ -745,8 +825,36 @@ export function getToolDefinitions(config, textSearchAvailable) {
745
825
  type: 'string',
746
826
  description: 'Dump or trace ID (for dumps/traces actions). Omit to list, provide to get details.',
747
827
  },
828
+ detailUrl: {
829
+ type: 'string',
830
+ description: 'ADT detail URL for gateway_errors detail mode (preferred over id+errorType). Accepts absolute or /sap/bc/adt/... path.',
831
+ },
832
+ errorType: {
833
+ type: 'string',
834
+ description: 'Gateway error type for gateway_errors detail by id (for example "Frontend Error"). Required when using id without detailUrl.',
835
+ },
748
836
  user: { type: 'string', description: 'Filter dumps by SAP user (for dumps action)' },
749
- maxResults: { type: 'number', description: 'Maximum results to return (for dumps action, default 50)' },
837
+ from: {
838
+ type: 'string',
839
+ description: 'Optional lower time boundary for feed-based diagnostics actions (system_messages/gateway_errors).',
840
+ },
841
+ to: {
842
+ type: 'string',
843
+ description: 'Optional upper time boundary for feed-based diagnostics actions (system_messages/gateway_errors).',
844
+ },
845
+ maxResults: {
846
+ type: 'number',
847
+ description: 'Maximum results to return for dumps/system_messages/gateway_errors (default 50, bounded to a safe cap).',
848
+ },
849
+ sections: {
850
+ type: 'array',
851
+ items: { type: 'string' },
852
+ description: 'Dump chapter IDs to include for dumps detail mode (for example ["kap0","kap3","kap8"]). Omit to use focused defaults.',
853
+ },
854
+ includeFullText: {
855
+ type: 'boolean',
856
+ description: 'For dumps detail mode only: include full formattedText blob. Default false to reduce token usage.',
857
+ },
750
858
  analysis: {
751
859
  type: 'string',
752
860
  enum: ['hitlist', 'statements', 'dbAccesses'],
@@ -767,7 +875,7 @@ export function getToolDefinitions(config, textSearchAvailable) {
767
875
  type: 'string',
768
876
  enum: ['impact', 'deps', 'usages'],
769
877
  description: 'Action:\n' +
770
- '"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). 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' +
878
+ '"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' +
771
879
  '"deps" (default, can be omitted) = forward dependency context — "what does <object> depend on?". Returns public API contracts of dependencies.\n' +
772
880
  '"usages" = reverse dependency lookup — "who calls <object>?". Requires cache warmup (--cache-warmup). Only "name" is needed. For CDS entities prefer action="impact" instead.',
773
881
  },
@@ -807,171 +915,262 @@ export function getToolDefinitions(config, textSearchAvailable) {
807
915
  type: 'boolean',
808
916
  description: 'Only for action="impact". Include indirect (transitive) downstream where-used entries. Default false.',
809
917
  },
918
+ siblingCheck: {
919
+ type: 'boolean',
920
+ description: 'Only for action="impact". Enable sibling metadata-extension consistency analysis. Default true.',
921
+ },
922
+ siblingMaxCandidates: {
923
+ type: 'number',
924
+ description: 'Only for action="impact". Maximum sibling DDLS candidates to compare. Default 4; hard cap 10.',
925
+ },
810
926
  },
811
927
  required: ['name'],
812
928
  },
813
929
  });
814
- // SAPManage — registered when not in read-only mode
815
- if (!config.readOnly) {
930
+ // SAPManage — always registered; mutating actions remain safety/scope-protected.
931
+ const sapManageActions = config.allowWrites
932
+ ? [...SAPMANAGE_ACTIONS_READ, ...SAPMANAGE_ACTIONS_WRITE]
933
+ : SAPMANAGE_ACTIONS_READ;
934
+ tools.push({
935
+ name: 'SAPManage',
936
+ description: btp ? SAPMANAGE_DESC_BTP : SAPMANAGE_DESC_ONPREM,
937
+ inputSchema: {
938
+ type: 'object',
939
+ properties: {
940
+ action: {
941
+ type: 'string',
942
+ enum: sapManageActions,
943
+ description: 'Action to execute. Read actions: features, probe, cache_stats, flp_list_catalogs, flp_list_groups, flp_list_tiles. ' +
944
+ 'Mutating package/FLP actions require writable safety config and write scope in authenticated mode.',
945
+ },
946
+ name: {
947
+ type: 'string',
948
+ description: 'Package name (required for create_package and delete_package).',
949
+ },
950
+ description: {
951
+ type: 'string',
952
+ description: 'Package description (required for create_package).',
953
+ },
954
+ superPackage: {
955
+ type: 'string',
956
+ description: 'Parent package for create_package (defaults to empty root package).',
957
+ },
958
+ softwareComponent: {
959
+ type: 'string',
960
+ description: 'Software component for create_package (default: LOCAL).',
961
+ },
962
+ transportLayer: {
963
+ type: 'string',
964
+ description: 'Transport layer for create_package (optional; required by some transportable landscapes).',
965
+ },
966
+ packageType: {
967
+ type: 'string',
968
+ enum: ['development', 'structure', 'main'],
969
+ description: 'Package type for create_package (default: development).',
970
+ },
971
+ transport: {
972
+ type: 'string',
973
+ description: 'Optional transport request (corrNr) for create_package, delete_package, or change_package.',
974
+ },
975
+ objectUri: {
976
+ type: 'string',
977
+ 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.',
978
+ },
979
+ objectType: {
980
+ type: 'string',
981
+ description: 'ADT object type (e.g., CLAS/OC, DDLS/DF, PROG/P). Required for change_package.',
982
+ },
983
+ objectName: {
984
+ type: 'string',
985
+ description: 'Object name to move (e.g., ZCL_MY_CLASS). Required for change_package.',
986
+ },
987
+ oldPackage: {
988
+ type: 'string',
989
+ description: 'Current package of the object. Required for change_package.',
990
+ },
991
+ newPackage: {
992
+ type: 'string',
993
+ description: 'Target package to move the object to. Required for change_package.',
994
+ },
995
+ catalogId: {
996
+ type: 'string',
997
+ description: 'FLP catalog identifier — accepts either full ID (X-SAP-UI2-CATALOGPAGE:MY_CAT) or domain ID (MY_CAT). Required for flp_list_tiles, flp_create_tile, flp_add_tile_to_group, flp_delete_catalog.',
998
+ },
999
+ groupId: {
1000
+ type: 'string',
1001
+ description: 'FLP group/page identifier (required for flp_create_group, flp_add_tile_to_group).',
1002
+ },
1003
+ title: {
1004
+ type: 'string',
1005
+ description: 'Title for FLP catalog/group creation.',
1006
+ },
1007
+ domainId: {
1008
+ type: 'string',
1009
+ description: 'Domain ID for FLP catalog creation (e.g., ZARC1_SALES).',
1010
+ },
1011
+ tileInstanceId: {
1012
+ type: 'string',
1013
+ description: 'Tile instance ID in the source catalog (required for flp_add_tile_to_group).',
1014
+ },
1015
+ tile: {
1016
+ type: 'object',
1017
+ description: 'Tile definition for flp_create_tile.',
1018
+ properties: {
1019
+ id: { type: 'string', description: 'Tile ID (client-side logical id).' },
1020
+ title: { type: 'string', description: 'Display title.' },
1021
+ icon: { type: 'string', description: 'Optional icon URI.' },
1022
+ semanticObject: { type: 'string', description: 'Semantic object for intent navigation.' },
1023
+ semanticAction: { type: 'string', description: 'Semantic action for intent navigation.' },
1024
+ url: { type: 'string', description: 'Optional target URL.' },
1025
+ subtitle: { type: 'string', description: 'Optional subtitle text.' },
1026
+ info: { type: 'string', description: 'Optional info text.' },
1027
+ },
1028
+ required: ['id', 'title', 'semanticObject', 'semanticAction'],
1029
+ },
1030
+ },
1031
+ required: ['action'],
1032
+ },
1033
+ });
1034
+ // Transport tools — always registered when the feature is available.
1035
+ // Read actions (list/get/check/history) work with read scope.
1036
+ // Write actions (create/release/delete/...) require 'transports' scope + allowTransportWrites=true.
1037
+ if (config.featureTransport !== 'off') {
1038
+ const sapTransportActions = config.allowWrites && config.allowTransportWrites
1039
+ ? [...SAPTRANSPORT_ACTIONS_READ, ...SAPTRANSPORT_ACTIONS_WRITE]
1040
+ : SAPTRANSPORT_ACTIONS_READ;
816
1041
  tools.push({
817
- name: 'SAPManage',
818
- description: btp ? SAPMANAGE_DESC_BTP : SAPMANAGE_DESC_ONPREM,
1042
+ name: 'SAPTransport',
1043
+ description: btp ? SAPTRANSPORT_DESC_BTP : SAPTRANSPORT_DESC_ONPREM,
819
1044
  inputSchema: {
820
1045
  type: 'object',
821
1046
  properties: {
822
1047
  action: {
823
1048
  type: 'string',
824
- enum: [
825
- 'features',
826
- 'probe',
827
- 'cache_stats',
828
- 'create_package',
829
- 'delete_package',
830
- 'change_package',
831
- 'flp_list_catalogs',
832
- 'flp_list_groups',
833
- 'flp_list_tiles',
834
- 'flp_create_catalog',
835
- 'flp_create_group',
836
- 'flp_create_tile',
837
- 'flp_add_tile_to_group',
838
- 'flp_delete_catalog',
839
- ],
840
- description: 'Action to execute. Includes package lifecycle (create/delete/move) and FLP actions for catalogs/groups/tiles via PAGE_BUILDER_CUST OData service.',
841
- },
842
- name: {
843
- type: 'string',
844
- description: 'Package name (required for create_package and delete_package).',
845
- },
846
- description: {
847
- type: 'string',
848
- description: 'Package description (required for create_package).',
1049
+ enum: sapTransportActions,
1050
+ description: 'list: show transports (defaults to current user, modifiable only). ' +
1051
+ 'get: fetch transport details including tasks and objects. ' +
1052
+ 'create: create a new transport request. ' +
1053
+ 'release: release a single transport or task. ' +
1054
+ 'delete: delete a transport (use recursive=true to delete tasks first). ' +
1055
+ 'reassign: change transport owner (use recursive=true for tasks too). ' +
1056
+ 'release_recursive: release all unreleased tasks first, then the transport itself. ' +
1057
+ 'check: check if a transport is needed for a package/object (requires type, name, package). ' +
1058
+ 'history: list transports referencing an object (reverse lookup; requires type, name; works without SAP_ALLOW_TRANSPORT_WRITES).',
849
1059
  },
850
- superPackage: {
1060
+ id: {
851
1061
  type: 'string',
852
- description: 'Parent package for create_package (defaults to empty root package).',
1062
+ description: 'Transport request ID, e.g. A4HK900123 (required for get/release/delete/reassign/release_recursive)',
853
1063
  },
854
- softwareComponent: {
1064
+ description: { type: 'string', description: 'Transport description text (required for create)' },
1065
+ name: { type: 'string', description: 'Object name (for check or history actions)' },
1066
+ package: { type: 'string', description: 'Package name (for check action)' },
1067
+ user: {
855
1068
  type: 'string',
856
- description: 'Software component for create_package (default: LOCAL).',
1069
+ description: 'SAP username to filter by (for list). Defaults to the current SAP user. Use "*" to list all users.',
857
1070
  },
858
- transportLayer: {
1071
+ status: {
859
1072
  type: 'string',
860
- description: 'Transport layer for create_package (optional; required by some transportable landscapes).',
1073
+ description: 'Transport status filter (for list). D=modifiable (default), R=released, "*"=all statuses.',
861
1074
  },
862
- packageType: {
1075
+ type: {
863
1076
  type: 'string',
864
- enum: ['development', 'structure', 'main'],
865
- description: 'Package type for create_package (default: development).',
1077
+ description: 'For create: transport type K=Workbench (default), W=Customizing, T=Transport of Copies. For check/history: object type (PROG, CLAS, DDLS, etc.)',
866
1078
  },
867
- transport: {
868
- type: 'string',
869
- description: 'Optional transport request (corrNr) for create_package, delete_package, or change_package.',
1079
+ owner: { type: 'string', description: 'New owner SAP username (required for reassign)' },
1080
+ recursive: {
1081
+ type: 'boolean',
1082
+ description: 'Apply recursively to child tasks (for delete/reassign). release_recursive always recurses.',
870
1083
  },
871
- objectUri: {
1084
+ },
1085
+ required: ['action'],
1086
+ },
1087
+ });
1088
+ }
1089
+ // SAPGit — registered only when gCTS or abapGit backend is available
1090
+ if (resolvedFeatures?.gcts?.available || resolvedFeatures?.abapGit?.available) {
1091
+ const sapGitActions = config.allowWrites && config.allowGitWrites
1092
+ ? [...SAPGIT_ACTIONS_READ, ...SAPGIT_ACTIONS_WRITE]
1093
+ : SAPGIT_ACTIONS_READ;
1094
+ tools.push({
1095
+ name: 'SAPGit',
1096
+ description: btp ? SAPGIT_DESC_BTP : SAPGIT_DESC_ONPREM,
1097
+ inputSchema: {
1098
+ type: 'object',
1099
+ properties: {
1100
+ action: {
872
1101
  type: 'string',
873
- 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.',
1102
+ enum: sapGitActions,
1103
+ description: 'Git action. Read: list_repos, whoami, config, branches, external_info, history, objects, check. ' +
1104
+ 'Write (requires SAP_ALLOW_WRITES=true and SAP_ALLOW_GIT_WRITES=true): clone, pull, push, commit, stage, switch_branch, create_branch, unlink.',
874
1105
  },
875
- objectType: {
1106
+ backend: {
876
1107
  type: 'string',
877
- description: 'ADT object type (e.g., CLAS/OC, DDLS/DF, PROG/P). Required for change_package.',
1108
+ enum: ['gcts', 'abapgit'],
1109
+ description: 'Optional backend override. Omit to auto-select (gCTS preferred over abapGit).',
878
1110
  },
879
- objectName: {
1111
+ repoId: {
880
1112
  type: 'string',
881
- description: 'Object name to move (e.g., ZCL_MY_CLASS). Required for change_package.',
1113
+ description: 'Repository ID/key for repo-specific actions.',
882
1114
  },
883
- oldPackage: {
1115
+ url: {
884
1116
  type: 'string',
885
- description: 'Current package of the object. Required for change_package.',
1117
+ description: 'Remote Git URL (required for clone and abapGit external_info).',
886
1118
  },
887
- newPackage: {
1119
+ branch: {
888
1120
  type: 'string',
889
- description: 'Target package to move the object to. Required for change_package.',
1121
+ description: 'Branch name for switch_branch/create_branch.',
890
1122
  },
891
- catalogId: {
1123
+ package: {
892
1124
  type: 'string',
893
- description: 'FLP catalog identifier accepts either full ID (X-SAP-UI2-CATALOGPAGE:MY_CAT) or domain ID (MY_CAT). Required for flp_list_tiles, flp_create_tile, flp_add_tile_to_group, flp_delete_catalog.',
1125
+ description: 'ABAP package for clone/create operations (checked against allowedPackages).',
894
1126
  },
895
- groupId: {
1127
+ transport: {
896
1128
  type: 'string',
897
- description: 'FLP group/page identifier (required for flp_create_group, flp_add_tile_to_group).',
1129
+ description: 'Optional transport request where supported by the backend.',
898
1130
  },
899
- title: {
1131
+ commit: {
900
1132
  type: 'string',
901
- description: 'Title for FLP catalog/group creation.',
1133
+ description: 'Commit SHA for history/pull-by-commit actions.',
902
1134
  },
903
- domainId: {
1135
+ message: {
904
1136
  type: 'string',
905
- description: 'Domain ID for FLP catalog creation (e.g., ZARC1_SALES).',
1137
+ description: 'Commit message for gCTS commit.',
906
1138
  },
907
- tileInstanceId: {
1139
+ description: {
908
1140
  type: 'string',
909
- description: 'Tile instance ID in the source catalog (required for flp_add_tile_to_group).',
1141
+ description: 'Optional commit description for gCTS commit.',
910
1142
  },
911
- tile: {
912
- type: 'object',
913
- description: 'Tile definition for flp_create_tile.',
914
- properties: {
915
- id: { type: 'string', description: 'Tile ID (client-side logical id).' },
916
- title: { type: 'string', description: 'Display title.' },
917
- icon: { type: 'string', description: 'Optional icon URI.' },
918
- semanticObject: { type: 'string', description: 'Semantic object for intent navigation.' },
919
- semanticAction: { type: 'string', description: 'Semantic action for intent navigation.' },
920
- url: { type: 'string', description: 'Optional target URL.' },
921
- subtitle: { type: 'string', description: 'Optional subtitle text.' },
922
- info: { type: 'string', description: 'Optional info text.' },
1143
+ objects: {
1144
+ type: 'array',
1145
+ description: 'Optional object list for commit/push payloads.',
1146
+ items: {
1147
+ type: 'object',
1148
+ properties: {
1149
+ type: { type: 'string' },
1150
+ name: { type: 'string' },
1151
+ package: { type: 'string' },
1152
+ path: { type: 'string' },
1153
+ state: { type: 'string' },
1154
+ operation: { type: 'string' },
1155
+ },
1156
+ required: ['type', 'name'],
923
1157
  },
924
- required: ['id', 'title', 'semanticObject', 'semanticAction'],
925
- },
926
- },
927
- required: ['action'],
928
- },
929
- });
930
- }
931
- // Transport tools — registered when transports are explicitly enabled
932
- if (config.enableTransports) {
933
- tools.push({
934
- name: 'SAPTransport',
935
- description: btp ? SAPTRANSPORT_DESC_BTP : SAPTRANSPORT_DESC_ONPREM,
936
- inputSchema: {
937
- type: 'object',
938
- properties: {
939
- action: {
940
- type: 'string',
941
- enum: ['list', 'get', 'create', 'release', 'delete', 'reassign', 'release_recursive', 'check', 'history'],
942
- description: 'list: show transports (defaults to current user, modifiable only). ' +
943
- 'get: fetch transport details including tasks and objects. ' +
944
- 'create: create a new transport request. ' +
945
- 'release: release a single transport or task. ' +
946
- 'delete: delete a transport (use recursive=true to delete tasks first). ' +
947
- 'reassign: change transport owner (use recursive=true for tasks too). ' +
948
- 'release_recursive: release all unreleased tasks first, then the transport itself. ' +
949
- 'check: check if a transport is needed for a package/object (requires type, name, package). ' +
950
- 'history: list transports referencing an object (reverse lookup; requires type, name; works without --enable-transports).',
951
1158
  },
952
- id: {
953
- type: 'string',
954
- description: 'Transport request ID, e.g. A4HK900123 (required for get/release/delete/reassign/release_recursive)',
955
- },
956
- description: { type: 'string', description: 'Transport description text (required for create)' },
957
- name: { type: 'string', description: 'Object name (for check or history actions)' },
958
- package: { type: 'string', description: 'Package name (for check action)' },
959
1159
  user: {
960
1160
  type: 'string',
961
- description: 'SAP username to filter by (for list). Defaults to the current SAP user. Use "*" to list all users.',
1161
+ description: 'Optional remote repository username.',
962
1162
  },
963
- status: {
1163
+ password: {
964
1164
  type: 'string',
965
- description: 'Transport status filter (for list). D=modifiable (default), R=released, "*"=all statuses.',
1165
+ description: 'Optional remote repository password/token secret.',
966
1166
  },
967
- type: {
1167
+ token: {
968
1168
  type: 'string',
969
- description: 'For create: transport type K=Workbench (default), W=Customizing, T=Transport of Copies. For check/history: object type (PROG, CLAS, DDLS, etc.)',
1169
+ description: 'Optional remote repository access token.',
970
1170
  },
971
- owner: { type: 'string', description: 'New owner SAP username (required for reassign)' },
972
- recursive: {
973
- type: 'boolean',
974
- description: 'Apply recursively to child tasks (for delete/reassign). release_recursive always recurses.',
1171
+ limit: {
1172
+ type: 'number',
1173
+ description: 'Optional limit for history queries.',
975
1174
  },
976
1175
  },
977
1176
  required: ['action'],