sap-ai-dev-toolkit 0.2.7 → 0.3.1

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.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ABAP Developer
3
- description: Develop and troubleshoot ABAP, CDS, and RAP objects against SAP using tests and the live BAS MCP tools. Use for ABAP implementation, debugging, validation, and transport-preparation tasks.
3
+ description: Develop and troubleshoot ABAP, CDS, and RAP objects against SAP using tests and the live SAP AI Dev Toolkit MCP tools. Use for ABAP implementation, debugging, validation, and transport-preparation tasks.
4
4
  target: vscode
5
5
  user-invocable: true
6
6
  ---
@@ -10,10 +10,11 @@ You are an ABAP development agent for SAP Business Application Studio (BAS). Fol
10
10
  1. **Clarify the contract.** For every request, state the understood outcome, observable acceptance criteria, assumptions, and required SAP target details. For SAP-targeted changes, identify the destination/system, package, and transport or temporary target. Ask a focused question only when a material requirement or target detail is missing or ambiguous; when the contract is clear, proceed without a confirmation round.
11
11
  2. **Inspect and select tools once per MCP server.** Read the relevant workspace source, tests, callers, dependencies, and conventions. Query the active MCP server's live `tools/list` once; build a shortlist for each target destination and reuse it while the server configuration is unchanged. Use the exact destination-prefixed names and input schemas returned. Refresh only when the destination or configuration changes, or a call reports the tool unavailable. Prefer:
12
12
  - **Inspect/search:** `GetSource`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetContext`, `FindDefinition`, `FindReferences`.
13
- - **Implement/verify:** `EditSource` for localized edits, `WriteSource` for larger rewrites; then `SyntaxCheck`, `RunUnitTests`, and `RunATCCheck` when relevant. Use `Activate` or `ActivateMultiple` only when activation was requested.
13
+ - **Implement/verify:** `EditSource` for localized edits, `WriteSource` for larger rewrites, and `PrepareABAPChangeSet` / `ApplyABAPChangeSet` for reviewed multi-object source changes; then `SyntaxCheck`, `RunUnitTests`, and `RunATCCheck` when relevant. Show and review the staged diffs before applying. Use `Activate` or `ActivateMultiple` only when activation was requested.
14
14
  - **CDS/RAP:** `GetSystemInfo` and `GetFeatures` for target capabilities; `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, and `GetObjectStructure` for model/impact inspection; `RunQuery` or `GetTableContents` for read-only CDS/table runtime validation. Use `PublishServiceBinding` only when publication was requested.
15
15
  - **Runtime diagnosis:** `ListDumps` and `GetDump`; add `GetApplicationLog` or `GetTrace` when relevant. For an authorized reproduction, use `DebuggerListen`, `DebuggerGetStack`, `DebuggerGetVariables`, and `DebuggerStep`, then `DebuggerDetach`.
16
- - **Transport preparation:** `GetUserTransports`, `GetTransport`, `GetTransportInfo`, `ListTransports`, and `ListDependencies` as needed; use `CreateTransport` only when explicitly authorized.
16
+ - **Transport preparation:** `CheckTransportReadiness`, `GetUserTransports`, `GetTransport`, `GetTransportInfo`, `ListTransports`, and `ListDependencies` as needed; use `CreateTransport` only when explicitly authorized. Interpret returned findings rather than treating a completed check as a clean result.
17
+ - **Clean Core:** `PlanABAPCloudMigration` to batch-check release-state evidence for relevant ADT object URIs. Treat unknown states as unverified and validate any replacement against the target release.
17
18
  Tool modes and system capabilities vary. Do not infer tool availability from this map or static documentation.
18
19
 
19
20
  3. **Use test-driven development.** ABAP code changes require a real test plan. Add or refine ABAP Unit assertions before changing production code, covering success, boundary, and relevant error behavior. Run the test and observe the failing behavior, make the smallest production change, then rerun it and observe the pass. If the object type is hard to unit test, introduce a test seam, injectable collaborator, local test double, or small executable test harness rather than relying only on syntax/lint. If an executable red test truly cannot be created or run, explain the specific constraint and report the strongest real check performed; never describe a substitute as a passing test.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ABAP Runtime Debugger
3
- description: Diagnose ABAP runtime failures, dumps, logs, traces, debugger sessions, call graphs, and performance symptoms using BAS MCP tools. Use for incidents, production-like defects, dumps, failed RAP/OData execution, and performance investigations.
3
+ description: Diagnose ABAP runtime failures, dumps, logs, traces, debugger sessions, call graphs, and performance symptoms using SAP AI Dev Toolkit MCP tools. Use for incidents, production-like defects, dumps, failed RAP/OData execution, and performance investigations.
4
4
  target: vscode
5
5
  user-invocable: true
6
6
  ---
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: RAP Service Developer
3
- description: Design, implement, troubleshoot, and validate SAP RAP business objects, behavior, projections, service definitions, and service bindings using BAS MCP tools. Use for RAP feature work, behavior implementation, OData exposure, and RAP runtime validation.
3
+ description: Design, implement, troubleshoot, and validate SAP RAP business objects, behavior, projections, service definitions, and service bindings using SAP AI Dev Toolkit MCP tools. Use for RAP feature work, behavior implementation, OData exposure, and RAP runtime validation.
4
4
  target: vscode
5
5
  user-invocable: true
6
6
  ---
@@ -9,8 +9,9 @@ description: Implement or change ABAP programs, classes, interfaces, function gr
9
9
 
10
10
  Query the active MCP server's live `tools/list` once; use task-relevant, destination-prefixed tools with their returned schemas. Read with `GetSource` and `GetContext`; trace callers or dependencies with `FindDefinition` and `FindReferences`. Use `EditSource` for a localized change and `WriteSource` for a larger rewrite. Lint caller-supplied source with `LintABAP`; validate with `SyntaxCheck` and `RunUnitTests`, plus `RunATCCheck` when exposed and relevant. For Clean Core requirements, use `GetAPIReleaseState` on each relevant dependency.
11
11
 
12
- 1. Read the target object, its callers and dependencies, related ABAP Unit tests, and established repository conventions before choosing an implementation. When Clean Core or ABAP Cloud compatibility is required, check released-API status for relevant dependencies using the live `GetAPIReleaseState` tool and its current schema.
12
+ 1. Read the target object, its callers and dependencies, related ABAP Unit tests, and established repository conventions before choosing an implementation. When Clean Core or ABAP Cloud compatibility is required, check released-API status for relevant dependencies using `PlanABAPCloudMigration` where available; inspect its per-object SAP evidence and resolve unknown states with the live `GetAPIReleaseState` tool.
13
13
  2. Translate the request into observable behavior. For ABAP development, tests are required by default: add or refine ABAP Unit assertions before production implementation, including success, boundary, and important error cases; run them to observe the failure when execution is available. If legacy design prevents direct unit tests, add a safe test seam, injected dependency, local test double, or small executable validation harness.
14
14
  3. Make the smallest implementation that meets that behavior. Use the live source-edit tool schemas: `EditSource` for a localized change and `WriteSource` for a larger rewrite. Keep source changes within the user-authorized target and preserve existing object conventions.
15
+ For authorized changes across multiple full-source objects, stage exact `GetSource` and `WriteSource` arguments with `PrepareABAPChangeSet`, review every returned diff, then call `ApplyABAPChangeSet`. The apply tool rechecks source before each write and reports partial results; it does not provide rollback.
15
16
  4. Self-validate the changed public contract. For interfaces, APIs, reports, function modules, and wrappers, execute the changed entry point in BAS or SAP using representative input. Prefer safe read-only real data from the target system; otherwise create isolated sample data only when authorized and clean it up where possible. Verify the actual output, side effects, and at least one empty/negative path.
16
17
  5. Run the regression tests after implementation and validate relevant callers and dependencies with lint, syntax, ATC, and LSP checks when available. Activate authorized SAP object changes in dependency order and treat activation failures as blockers. Record actual results and any checks that could not run; do not treat lint, syntax, or activation as substitutes for ABAP Unit behavior coverage.
@@ -7,11 +7,14 @@ description: Validate and deliver SAP RAP OData services, behavior implementatio
7
7
 
8
8
  ## MCP tool shortlist
9
9
 
10
- Query the active MCP server's live `tools/list` once and use exact destination-prefixed names and schemas. Prefer these tools when available: `GetSystemInfo`, `GetFeatures`, `GetConnectionInfo`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetObjectStructure`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `EditSource`, `WriteSource`, `UpdateSource`, `UpdateClassInclude`, `CreateClassWithTests`, `CreateTestInclude`, `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `GetCodeCoverage`, `RunQuery`, `GetTableContents`, `ExecuteABAP`, `ListDumps`, `GetDump`, `GetApplicationLog`, `GetTrace`, `Activate`, `ActivateMultiple`, and `PublishServiceBinding`. Use `UnpublishServiceBinding` only when explicitly requested.
10
+ Query the active MCP server's live `tools/list` once and use exact destination-prefixed names and schemas. Prefer these tools when available: `GetSystemInfo`, `GetFeatures`, `GetConnectionInfo`, `SearchObject`, `GrepObjects`, `GrepPackages`, `GetSource`, `GetObjectStructure`, `GetCDSDependencies`, `GetCDSImpactAnalysis`, `GetCDSElementInfo`, `EditSource`, `WriteSource`, `UpdateSource`, `UpdateClassInclude`, `CreateClassWithTests`, `CreateTestInclude`, `LintABAP`, `SyntaxCheck`, `RunUnitTests`, `RunATCCheck`, `GetCodeCoverage`, `RunQuery`, `GetTableContents`, `ExecuteABAP`, `GenerateRAPRegressionSuite`, `RunRAPRegressionSuite`, `ListDumps`, `GetDump`, `GetApplicationLog`, `GetTrace`, `Activate`, `ActivateMultiple`, and `PublishServiceBinding`. Use `UnpublishServiceBinding` only when explicitly requested.
11
11
 
12
12
  1. Confirm target destination, package, transport/temporary target, RAP object names, and whether activation/publication/data mutation is authorized. Transport release and deletion remain out of scope for this skill; prepare and report transport context only.
13
13
  2. Inspect the full RAP object chain before changing anything: interface/root CDS, child/composition CDS, behavior definition, behavior pool/local handlers, projection CDS, projection behavior, service definition, service binding, tests, and package conventions.
14
14
  3. Validate behavior implementations with tests first where feasible. Cover validations, determinations, actions, feature control, numbering, authorization-relevant branches, reported/failed messages, and negative or empty paths.
15
15
  4. Validate runtime service behavior end-to-end. Use read-only `RunQuery`/`GetTableContents` for query paths. For mutating behavior, proceed only when authorized, use isolated data, verify persisted state/messages, and clean up when possible.
16
+ Generate a reusable GET-only OData smoke suite with `GenerateRAPRegressionSuite`, save its returned JSON with the change, and rerun it with `RunRAPRegressionSuite`. Add JSON-path assertions for business behavior that metadata alone cannot prove.
16
17
  5. Activate in dependency order only when authorized: lower CDS/model dependencies first, then behavior artifacts, projections, service definition, and service binding. Publish only when explicitly requested.
17
18
  6. If runtime validation fails, inspect dumps/logs/traces with `ListDumps`, `GetDump`, `GetApplicationLog`, and `GetTrace` before guessing. Report exact evidence, not inferred success.
19
+
20
+ Transport release is unavailable through this workflow. Report transport readiness and creation separately, and never claim that a transport was released or deleted.
@@ -7,8 +7,8 @@ description: Prepare ABAP changes for SAP transport and verify request contents,
7
7
 
8
8
  ## Tool shortlist
9
9
 
10
- Query the active MCP server's live `tools/list` once; use task-relevant, destination-prefixed tools with their returned schemas. Identify candidates with `GetUserTransports` or `ListTransports`; inspect a request with `GetTransport` / `GetTransportInfo`; use `ListDependencies`, `RunUnitTests`, and `RunATCCheck` as needed. Activate with `Activate` / `ActivateMultiple` only when requested. `CreateTransport` is state-changing and requires explicit authorization. Release and deletion are not available through this addon.
10
+ Query the active MCP server's live `tools/list` once; use task-relevant, destination-prefixed tools with their returned schemas. Identify candidates with `GetUserTransports` or `ListTransports`; inspect a request with `GetTransport` / `GetTransportInfo`; use `CheckTransportReadiness` to collect transport, dependency, inactive-object, ABAP Unit, and ATC evidence when available. Activate with `Activate` / `ActivateMultiple` only when requested. `CreateTransport` is state-changing and requires explicit authorization. Release and deletion are not available through this addon.
11
11
 
12
- 1. Use the live transport tools to verify the destination, package, complete object set, dependencies, and an eligible modifiable request before preparing changes. Use current tool names and schemas; do not assume a request is valid from its identifier alone.
12
+ 1. Use `CheckTransportReadiness` with exactly one `GetTransport` check for the requested ID and applicable dependency, inactive-object, test, and ATC checks. Review each returned evidence item; a completed call can still contain findings. Verify the destination, package, complete object set, dependencies, and an eligible modifiable request before preparing changes.
13
13
  2. Create a transport only when the user specifically authorized its creation. Before transport handoff, ensure changed objects have been activated in dependency order when activation is authorized, ABAP Unit tests have been run or blockers documented, runtime validation evidence exists for changed public contracts, and ATC/syntax checks have been run where available. Do not treat request contents, syntax, ATC, or activation as substitutes for behavior and runtime validation evidence. Report actual request contents and validation state.
14
14
  3. This addon filters `ReleaseTransport` and `DeleteTransport`. Do not invent or claim release/deletion support. When release is requested, report that release is unavailable through this addon and hand off the release action to an authorized SAP transport workflow.
package/README.md CHANGED
@@ -1,9 +1,9 @@
1
1
  <h1 align="center">🧭 SAP AI Development Toolkit</h1>
2
2
 
3
3
  <p align="center">
4
- <strong>AI-native ABAP development from GitHub Copilot Chat — directly against your SAP landscape</strong><br>
5
- Inspect. Understand. Build. Test. Validate. Prepare for transport.<br>
6
- A destination-aware Model Context Protocol (MCP) bridge connecting SAP Business Application Studio, SAP ADT, VSP, and your GitHub Copilot coding agent.
4
+ <strong>Build, test, and deliver ABAP with AI that understands your SAP landscape.</strong><br>
5
+ Bring GitHub Copilot Chat into your development workflow with destination-aware SAP tools.<br>
6
+ Explore real system context, make focused changes, and verify results before delivery.
7
7
  </p>
8
8
 
9
9
  <p align="center">
@@ -22,13 +22,28 @@
22
22
  </p>
23
23
 
24
24
  <p align="center">
25
- <a href="#install">📦 Install</a> ·
26
- <a href="#copilot-agent">🤖 Copilot Agent</a> ·
27
- <a href="#bas">🧭 BAS Setup</a> ·
28
- <a href="#tools">🧰 Tool Catalog</a> ·
29
- <a href="#troubleshooting">🩺 Troubleshooting</a>
25
+ <a href="#install"><strong>Get started →</strong></a> ·
26
+ <a href="#copilot-agent">Meet the agents</a> ·
27
+ <a href="#bas">Connect your SAP systems</a> ·
28
+ <a href="#tools">Explore the tools</a>
30
29
  </p>
31
30
 
31
+ ## From a prompt to SAP-ready work
32
+
33
+ SAP AI Dev Toolkit connects GitHub Copilot Chat to the SAP development tools available for each selected destination. Agents can inspect ABAP and CDS, propose changes, run checks, and return the evidence—without losing sight of which SAP system each operation targets.
34
+
35
+ ```mermaid
36
+ flowchart LR
37
+ Dev[Developer] --> Chat[GitHub Copilot Chat]
38
+ Chat -->|request and tool calls| Toolkit[SAP AI Dev Toolkit]
39
+ Toolkit -->|destination-scoped MCP| VSP[VSP and BAS destination]
40
+ VSP -->|SAP ADT| SAP[SAP system]
41
+ SAP -->|results and diagnostics| Toolkit
42
+ Toolkit --> Chat
43
+ ```
44
+
45
+ <p align="center"><strong>Explore → Build → Verify → Prepare for delivery</strong></p>
46
+
32
47
  ## ⚡ Quick start
33
48
 
34
49
  ```sh
@@ -42,14 +57,14 @@ To also add optional full-stack SAP companion MCP servers for Fiori, UI5, CAP, a
42
57
  sap-ai-dev --setup --tools
43
58
  ```
44
59
 
45
- Then in SAP Business Application Studio:
60
+ Then connect a destination in SAP Business Application Studio:
46
61
 
47
62
  1. Open the Command Palette.
48
63
  2. Run **MCP: List Servers**.
49
64
  3. Start the server named after your selected BAS destination.
50
65
  4. In GitHub Copilot Chat, choose the best-fit bundled agent from the agent picker: **SAP Solution Architect**, **ABAP Developer**, **ABAP Runtime Debugger**, or **RAP Service Developer**.
51
66
  5. In the Chat tools picker, enable the server for that BAS destination.
52
- 6. Ask Copilot what you want to inspect, build, test, or verify.
67
+ 6. Ask Copilot to inspect, build, test, or verify something in your SAP landscape.
53
68
 
54
69
  **Prerequisite:** Node.js 20 or newer. If Go is not already available, the installer can provision the pinned supported Go release automatically.
55
70
 
@@ -68,7 +83,7 @@ Then in SAP Business Application Studio:
68
83
 
69
84
  If the agents are not listed, install the optional agents and skills under `$HOME/.copilot` when prompted during an interactive global install, then reload BAS if needed. Repository-scoped installation instructions appear below.
70
85
 
71
- ## ✨ Turn Copilot Chat into an SAP development cockpit
86
+ ## ✨ Your SAP development cockpit, inside Copilot Chat
72
87
 
73
88
  `sap-ai-dev-toolkit` installs `sap-ai-dev`, discovers your BAS destinations, and exposes a curated SAP development toolset through MCP. Instead of manually switching between chat, terminal commands, repository searches, ADT screens, and SAP checks, describe the outcome you want and let the appropriate bundled agent coordinate the available tools.
74
89
 
@@ -80,20 +95,26 @@ The workflow covers ABAP, CDS, RAP, repository analysis, table and query access,
80
95
 
81
96
  | | Feature | What it gives you |
82
97
  | --- | --- | --- |
83
- | 🤖 | **AI-driven ABAP development** | Ask for changes in natural language and let the bundled agents orchestrate inspection, implementation, runtime diagnosis, validation, and reporting. |
84
- | 🧭 | **BAS destination awareness** | Discover BAS destinations and create one isolated MCP server per selected SAP system. |
85
- | 🔎 | **Deep repository inspection** | Read source, search objects, grep packages, find definitions and references, compare source, inspect dependencies, and analyze impact. |
86
- | 🧩 | **CDS + RAP development** | Inspect CDS metadata and dependencies, model CDS artifacts, and build RAP business objects and services. |
87
- | 🗃️ | **SAP data access** | Inspect DDIC structures, read table content, and execute controlled ABAP SQL queries against the connected system. |
88
- | ✍️ | **Create + edit ABAP objects** | Write or edit supported source objects, create packages and tables, syntax-check, and activate when explicitly requested. |
89
- | ✅ | **Quality built into the flow** | Use local ABAP linting plus SAP syntax checks, ABAP Unit, ATC, editor diagnostics, and formatting. |
90
- | 🐞 | **Debugging + diagnostics** | Investigate dumps, traces, application logs, runtime failures, system capabilities, and installed components. |
91
- | 🚚 | **Transport-aware workflows** | Inspect transport requests and object lock context, and create transports when explicitly authorized. |
98
+ | 🤖 | **AI-driven ABAP development** | Describe the outcome; a task-fit agent coordinates inspection, implementation, validation, and a clear report. |
99
+ | 🧭 | **Destination-aware by design** | Discover BAS destinations and connect each MCP server to one selected SAP system. |
100
+ | 🔎 | **Understand before editing** | Trace source, callers, definitions, package contents, dependencies, and CDS impact in one workflow. |
101
+ | 🧩 | **CDS + RAP development** | Explore models and dependencies, then build RAP business objects and services with system context. |
102
+ | 🗃️ | **Ground decisions in SAP data** | Inspect DDIC structures, read table contents, and run controlled ABAP SQL queries. |
103
+ | ✍️ | **Create + edit ABAP objects** | Update supported source, create packages and tables, and run syntax checks before requested activation. |
104
+ | ✅ | **Quality built into the flow** | Pair local ABAP linting with SAP syntax checks, ABAP Unit, ATC, editor diagnostics, and formatting. |
105
+ | 🐞 | **Debug with system context** | Investigate dumps, traces, application logs, runtime failures, capabilities, and installed components. |
106
+ | 🚚 | **Transport-aware workflows** | Check request and lock context before preparing a change; create transports only when authorized. |
107
+ | 🧾 | **Reviewable change sets** | Stage multi-object diffs and re-read each source before an explicitly requested apply. |
108
+ | 📋 | **Transport readiness evidence** | Bring request, dependency, inactive-object, test, and ATC results together in one report. |
109
+ | 🧭 | **ABAP Cloud migration assessment** | Check SAP API release evidence in batches and focus review on recognized unreleased APIs. |
110
+ | 🚀 | **Reusable RAP smoke suites** | Turn OData metadata into repeatable GET checks with saved assertions. |
111
+ | 🩺 | **Connection Doctor** | Find setup issues across destination reachability, VSP startup, SAP system info, and tool discovery. |
112
+ | 🧪 | **Offline playground** | Try the agents and workflows locally with sample SAP data; demo changes disappear on exit. |
92
113
  | 🔐 | **Controlled SAP state changes** | State-changing actions require a known target and an explicit request; SAP authorizations still apply. |
93
- | 🧱 | **Destination isolation** | Each generated MCP server is tied to its own `BAS_VSP_DESTINATION`, helping prevent accidental cross-system execution. |
114
+ | 🧱 | **Destination isolation** | Each generated MCP server is tied to its own `SAP_AI_DEV_TOOLKIT_DESTINATION`, helping prevent accidental cross-system execution. |
94
115
  | 🛡️ | **Credential-safe configuration** | Credentials, cookies, usernames, passwords, and raw destination payloads are not written into MCP configuration. |
95
116
 
96
- The catalog below documents 40 tool capabilities across source inspection, data, editing, quality, transports, and logs. Availability can vary by SAP system and VSP mode, so the live `tools/list` response is authoritative.
117
+ The catalog below covers source inspection, data, editing, quality, transports, logs, and multi-step development workflows. Availability can vary by SAP system and VSP mode, so the live `tools/list` response is authoritative.
97
118
 
98
119
  ## 🚀 What can the agent do?
99
120
 
@@ -197,7 +218,7 @@ Once the destination server is enabled in Copilot Chat, ask for outcomes instead
197
218
  | 🧪 **Verification first** | The agent uses available lint, syntax, unit-test, ATC, and diagnostics workflows and reports what actually ran. |
198
219
  | 🔒 **SAP authorization remains authoritative** | The add-on does not bypass backend SAP permissions. |
199
220
  | 🚚 **Full VSP tool surface** | The proxy exposes every tool registered by the active VSP child, including transport tools; SAP authorizations and VSP safety checks still apply. |
200
- | 🧱 **Per-destination isolation** | Generated MCP entries are scoped to a single `BAS_VSP_DESTINATION`. |
221
+ | 🧱 **Per-destination isolation** | Generated MCP entries are scoped to a single `SAP_AI_DEV_TOOLKIT_DESTINATION`. |
201
222
  | 🔑 **No credentials in `mcp.json`** | Authentication material stays in BAS destination configuration rather than MCP config. |
202
223
 
203
224
  <a id="install"></a>
@@ -234,6 +255,8 @@ The installer handles two setup tasks automatically:
234
255
 
235
256
  With `H2O_URL` set, an interactive install opens a checkbox picker with no destinations selected by default. Use **Space** to choose destinations and **Enter** to confirm. Press **a** to toggle all destinations (select all if any are unchecked; otherwise clear the selection). Confirming with none selected removes this add-on's managed MCP entries. When the `cf` CLI 8.18 or newer is authenticated to a targeted space, setup first offers an optional import from that space's Destination service; type **y** then **Enter** to include it, or press **Enter** to skip. Accepted CF and BAS destinations appear together in the picker. npm may run its install hook without an interactive terminal, even when the shell is interactive; in that case, selection is skipped without changing MCP config.
236
257
 
258
+ Some current npm versions also require install hooks to be approved. If npm reports that `sap-ai-dev-toolkit`'s `postinstall` was blocked, allow it during a fresh install with `npm install --global --allow-scripts=sap-ai-dev-toolkit sap-ai-dev-toolkit`, or run `sap-ai-dev-toolkit --setup` from an interactive BAS terminal after installation.
259
+
237
260
  The setup report uses icons and terminal colors; set `NO_COLOR=1` to disable ANSI colors. The table is a weather report, not a bouncer: green **PASS** means the ADT probe responded, red **FAIL** means it failed, and yellow **SKIPPED** means it was skipped. Probe failures do not block MCP registration or startup for destinations you select.
238
261
 
239
262
  Run `sap-ai-dev --setup` later to change the destination selection or remove generated destination entries. Run `sap-ai-dev --setup --tools` to also choose optional companion tools. Use `--npx` to make generated BAS/VSP destination entries start the pinned package through npm instead of relying on a global `sap-ai-dev` command; companion tools already use `npx` with their own npm packages.
@@ -320,7 +343,7 @@ Review skipped or conflicting files and merge changes manually. `LintABAP` analy
320
343
 
321
344
  <a id="bas"></a>
322
345
 
323
- ## 🧭 BAS setup
346
+ ## 🧭 SAP AI Dev Toolkit setup in BAS
324
347
 
325
348
  `sap-ai-dev --setup` reads BAS destination names from `H2O_URL/api/listDestinations`, then gives each destination's `/sap/bc/adt/discovery` endpoint a quick knock through the BAS proxy. HTTP 2xx, 401, and 403 count as reachable; other responses and network failures are reported but do not exclude discovered destinations from the selection list or prevent startup when selected.
326
349
 
@@ -339,7 +362,7 @@ The sample values sketch an on-premise ABAP backend routed through SAP Cloud Con
339
362
 
340
363
  | Destination field | Example | Notes |
341
364
  | --- | --- | --- |
342
- | `Name` | `DEMO_ABAP` | Unique BAS destination name. It becomes both `BAS_VSP_DESTINATION` and the generated MCP server name. |
365
+ | `Name` | `DEMO_ABAP` | Unique BAS destination name. It becomes both `SAP_AI_DEV_TOOLKIT_DESTINATION` and the generated MCP server name. |
343
366
  | `Type` | `HTTP` | ADT is an HTTP service. |
344
367
  | `URL` | `https://abap.example.com:44300` | Backend URL exposed through the configured route. |
345
368
  | `Proxy Type` | `OnPremise` | Use `OnPremise` for Cloud Connector; use `Internet` for a directly reachable public endpoint. |
@@ -391,7 +414,7 @@ One selected system, one isolated stdio MCP entry. Here's the shape:
391
414
  "command": "sap-ai-dev",
392
415
  "env": {
393
416
  "H2O_URL": "https://bas.example.com",
394
- "BAS_VSP_DESTINATION": "DEMO_ABAP",
417
+ "SAP_AI_DEV_TOOLKIT_DESTINATION": "DEMO_ABAP",
395
418
  "SAP_ALLOW_TRANSPORTABLE_EDITS": "true"
396
419
  },
397
420
  "BAS_EXT": "true"
@@ -429,9 +452,9 @@ The file must be strict JSON with an object-valued `servers` property. Existing
429
452
  | Get the same report in machine-readable, redacted form | `sap-ai-dev --list-destinations --json` |
430
453
  | Check availability without starting the server | `sap-ai-dev --check` |
431
454
 
432
- With `H2O_URL` set, the normal command starts the MCP proxy. Each generated entry supplies one `BAS_VSP_DESTINATION`, so each server stays in its own lane and exposes only its selected SAP system.
455
+ With `H2O_URL` set, the normal command starts the MCP proxy. Each generated entry supplies one `SAP_AI_DEV_TOOLKIT_DESTINATION`, so each server stays in its own lane and exposes only its selected SAP system.
433
456
 
434
- The proxy exposes every VSP tool registered by the installed VSP mode, plus local `LintABAP` and the convenience `GetApplicationLog` mapping. It enables transport support and transportable source edits in generated MCP entries. Direct VSP invocation remains unchanged.
457
+ The proxy exposes every VSP tool registered by the installed VSP mode, plus local `LintABAP`, destination-scoped workflow tools, and the convenience `GetApplicationLog` mapping when the VSP SAP router is available. It enables transport support and transportable source edits in generated MCP entries. Direct VSP invocation remains unchanged.
435
458
 
436
459
  Without `H2O_URL`, the command passes arguments directly to the installed VSP binary—no BAS proxy detour.
437
460
 
@@ -441,7 +464,7 @@ Without `H2O_URL`, the command passes arguments directly to the installed VSP bi
441
464
 
442
465
  Each generated MCP server entry uses its BAS destination name verbatim: `DEMO_ABAP` stays `DEMO_ABAP`. Tool names use the normalized destination slug instead, so the prefix is `demo-abap` (`demo-abap__GetSource`, `demo-abap__RunQuery`, `demo-abap__LintABAP`). Use the exact names shown by your MCP client; punctuation can change during slugification.
443
466
 
444
- The proxy keeps VSP tool descriptions and input schemas, then adds the destination label. `LintABAP` is the exception: it is implemented locally and uses the shared input schema shown by `tools/list`. It lints only submitted source in memory; it does not read the workspace, call SAP, or load configured external dependencies. Supply every dependency source file in `files`. The live `tools/list` result remains the source of truth for the installed VSP binary's exact schemas.
467
+ The proxy keeps VSP tool descriptions and input schemas, then adds the destination label. `LintABAP` and the workflow tools are implemented locally; they use the schemas shown by `tools/list` and call only the destination attached to their name. Linting operates on submitted source in memory. The live `tools/list` result remains the source of truth for the installed VSP binary's exact schemas.
445
468
 
446
469
  <a id="tools"></a>
447
470
 
@@ -449,7 +472,7 @@ The proxy keeps VSP tool descriptions and input schemas, then adds the destinati
449
472
 
450
473
  From read-only inspection to controlled SAP changes. The catalog is organized by developer intent so you can quickly see what the agent can inspect, query, validate, edit, activate, or prepare for transport.
451
474
 
452
- The menu includes the existing curated VSP tools, additions listed in `tools.md` when registered by the active VSP mode, the `GetApplicationLog` mapping, and local `LintABAP`. Focused mode may omit `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`; the live `tools/list` result remains authoritative.
475
+ The menu includes the tools registered by the active VSP mode, the `GetApplicationLog` mapping, local linting, and destination workflows where their required VSP capabilities are available. Focused mode may omit `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`; the live `tools/list` result remains authoritative.
453
476
 
454
477
  ### 🧹 Lint submitted ABAP source locally
455
478
 
@@ -470,6 +493,29 @@ The per-destination tool name is `<destination-slug>__LintABAP`, for example `de
470
493
 
471
494
  The single text item in the MCP result contains JSON: `{ "status": "clean" | "issues", "filesChecked": number, "issueCount": number, "errors": number, "warnings": number, "infos": number, "issues": [...] }`. Each issue reports filename, rule, severity, message, and start/end positions with line and column. Lint findings—including Error-severity findings—are reports, not MCP tool-call errors.
472
495
 
496
+ ### 🧩 Review and delivery workflows
497
+
498
+ These local tools are namespaced by destination. Change-set tools appear when VSP exposes `GetSource` and `WriteSource`; transport and Clean Core tools appear when their underlying checks exist. RAP suite tools use the selected destination's proxy route.
499
+
500
+ | Tool | Behavior |
501
+ | --- | --- |
502
+ | `PrepareABAPChangeSet` | Stage up to 12 full-source `WriteSource` changes and return line diffs plus SHA-256 fingerprints. Proposals stay in MCP process memory. |
503
+ | `ApplyABAPChangeSet` | Re-read each object and write only when its source still matches the reviewed version. It stops on conflicts or errors and reports partial application; it does not roll back SAP writes. |
504
+ | `CheckTransportReadiness` | Run a caller-selected bundle of transport, dependency, inactive-object, ABAP Unit, and ATC checks. Completed calls may still contain findings. |
505
+ | `PlanABAPCloudMigration` | Batch `GetAPIReleaseState` checks for ADT object URIs and prioritize recognized unreleased APIs ahead of unknown and released states. SAP evidence stays attached. |
506
+ | `GenerateRAPRegressionSuite` | Read `$metadata` and return reusable JSON with a metadata check and one `$top=1` GET for each entity set. |
507
+ | `RunRAPRegressionSuite` | Run the saved suite with GET requests, expected status/content-type checks, and optional JSON-path assertions. Requests stay under the same `/sap/opu/odata` service root; response bodies are capped at 2 MiB. |
508
+
509
+ For a change set, pass the exact `GetSource` arguments and observed full source for each object, plus exact `WriteSource` arguments containing the replacement source. Each source is limited to 128 KiB and 1,000 lines so the full diff can be reviewed. Review every diff before calling `ApplyABAPChangeSet`. Each object is checked immediately before its write; a change after that read can still race the write because VSP does not expose compare-and-write here.
510
+
511
+ For a transport report, include exactly one `GetTransport` check whose `transport` matches `transport_id`, then add applicable dependency, inactive-object, ABAP Unit, or ATC checks. Each uses the exact arguments in the live upstream schema.
512
+
513
+ For an ABAP Cloud assessment, get object URIs from `SearchObject` and pass them to `PlanABAPCloudMigration`. It reports release evidence; it does not guess replacement APIs. Save the JSON from `GenerateRAPRegressionSuite` and pass it to `RunRAPRegressionSuite` after relevant service changes.
514
+
515
+ `sap-ai-dev-toolkit --doctor` probes each discovered destination, starts VSP, calls `GetSystemInfo` when available, and lists MCP tools. `--doctor --json` prints redacted results and exits unsuccessfully when a required check fails.
516
+
517
+ `sap-ai-dev-toolkit --demo` starts an isolated server with sample ABAP objects, test and ATC results, a sample transport, and synthetic OData metadata and rows. Source edits and transport creation stay in process memory and disappear on exit. The demo does not discover or contact BAS or SAP destinations.
518
+
473
519
  ### 🔎 Find and understand ABAP objects
474
520
 
475
521
  | Tool | What it does |
@@ -648,8 +694,8 @@ The response contains a `tools` array. A `RunQuery` entry resembles this excerpt
648
694
  | Variable | Purpose |
649
695
  | --- | --- |
650
696
  | `H2O_URL` | BAS endpoint used to discover destinations. Required for BAS discovery. |
651
- | `BAS_VSP_DESTINATION` | Comma-separated destination allowlist for normal runtime discovery. Setup clears this temporarily so it can display all eligible systems. |
652
- | `BAS_VSP_MODE` | VSP child mode (`expert` by default; `focused` omits `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`). The proxy exposes its curated tools plus tools listed in `tools.md` when registered by that mode, including local `LintABAP`. |
697
+ | `SAP_AI_DEV_TOOLKIT_DESTINATION` | Comma-separated destination allowlist for normal runtime discovery. Setup clears this temporarily so it can display all eligible systems. |
698
+ | `SAP_AI_DEV_TOOLKIT_MODE` | VSP child mode (`expert` by default; `focused` omits `ActivateMultiple`, `GetUserTransports`, and `GetTransportInfo`). The proxy exposes its curated tools plus tools listed in `tools.md` when registered by that mode, including local `LintABAP`. |
653
699
  | `SAP_ALLOW_TRANSPORTABLE_EDITS` | Generated MCP entries set this to `true` to permit source edits in transportable packages; VSP safety checks and SAP authorizations still apply. |
654
700
  | `SAP_AI_DEV_MCP_CONFIG` | Explicit MCP user configuration path. |
655
701
  | `BAS_VSP_MCP_CONFIG` | Backward-compatible alias for the MCP user configuration path. |
@@ -657,10 +703,12 @@ The response contains a `tools` array. A `RunQuery` entry resembles this excerpt
657
703
  | `BAS_VSP_BINARY_URL` | Alternate VSP binary download URL. |
658
704
  | `BAS_VSP_CACHE_DIR` | Binary cache directory. |
659
705
  | `GO_BINARY` | Explicit Go executable used for provisioning when automatic Go installation is unavailable. |
660
- | `BAS_VSP_SKIP_PROBE=true` | Skip destination probes; useful for controlled diagnostics or fixtures. |
706
+ | `SAP_AI_DEV_TOOLKIT_SKIP_PROBE=true` | Skip destination probes; useful for controlled diagnostics or fixtures. |
661
707
  | `HTTP_PROXY` / `HTTPS_PROXY` | BAS proxy settings used for destination-list requests, destination probing, and child processes. |
662
708
  | `NO_PROXY` | Proxy bypass list for BAS destination-list requests; `.dest` hosts remain routed through the BAS proxy. |
663
709
 
710
+ Existing installs that still set the previous `BAS_VSP_*` environment variables remain supported. The setup wizard writes new MCP entries with the `SAP_AI_DEV_TOOLKIT_*` names.
711
+
664
712
  <a id="troubleshooting"></a>
665
713
 
666
714
  ## 🩺 Troubleshooting
@@ -676,7 +724,7 @@ Next, check that the backend answers at `/sap/bc/adt`.
676
724
 
677
725
  Runtime diagnostics take the stderr lane. In the MCP server's Output view, check per-destination ADT probe status, VSP child stderr, and failed tool-call details; stdout is reserved for MCP protocol messages.
678
726
 
679
- If automatic Go or VSP provisioning fails, check network access and the package's supported platform. You can install Go manually or set `GO_BINARY` as an explicit fallback. A trusted prebuilt VSP can be supplied with `BAS_VSP_BINARY`.
727
+ If automatic Go or VSP provisioning fails, check network access and the package's supported platform. You can install Go manually or set `GO_BINARY` as an explicit fallback. A trusted prebuilt VSP can be supplied with `SAP_AI_DEV_TOOLKIT_BINARY`.
680
728
 
681
729
  ## 🧑‍💻 Development
682
730
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sap-ai-dev-toolkit",
3
- "version": "0.2.7",
3
+ "version": "0.3.1",
4
4
  "description": "SAP AI development toolkit for BAS, ABAP, RAP, CAP, Fiori, UI5, and MCP",
5
5
  "author": "Gurkan Yilmaz",
6
6
  "type": "module",
@@ -4,16 +4,17 @@ import { chmod, mkdir, rm, symlink, writeFile } from 'node:fs/promises';
4
4
  import { homedir, tmpdir } from 'node:os';
5
5
  import { join } from 'node:path';
6
6
  import { promisify } from 'node:util';
7
+ import { brandedEnvValue } from '../src/branding.mjs';
7
8
 
8
9
  const exec = promisify(execFile);
9
- export const GO_VERSION = process.env.BAS_VSP_GO_VERSION || 'go1.27.1';
10
+ export const GO_VERSION = brandedEnvValue(process.env, 'GO_VERSION') || 'go1.27.1';
10
11
  const GO_RELEASES = {
11
12
  'linux:x64': { archive: `${GO_VERSION}.linux-amd64.tar.gz`, sha256: '63d339f0da5ab53635a56f2490a7984dfe12dfcff22ad749f63edaf590168445' },
12
13
  'linux:arm64': { archive: `${GO_VERSION}.linux-arm64.tar.gz`, sha256: '3450b45a3f9ee8568792736a5c5e70a1f2e9b36c35a8f74958c03e51d7d92bec' }
13
14
  };
14
15
 
15
16
  function localGoPath() {
16
- return join(process.env.BAS_VSP_GO_ROOT || join(homedir(), '.local', 'go'), GO_VERSION, 'bin', process.platform === 'win32' ? 'go.exe' : 'go');
17
+ return join(brandedEnvValue(process.env, 'GO_ROOT') || join(homedir(), '.local', 'go'), GO_VERSION, 'bin', process.platform === 'win32' ? 'go.exe' : 'go');
17
18
  }
18
19
 
19
20
  function candidateGo() {
@@ -32,9 +33,9 @@ export async function installGo() {
32
33
  if (!response.ok) throw new Error(`Go download failed with HTTP ${response.status}; install ${GO_VERSION} manually and ensure go is on PATH.`);
33
34
  const bytes = Buffer.from(await response.arrayBuffer());
34
35
  const actual = createHash('sha256').update(bytes).digest('hex');
35
- const expected = process.env.BAS_VSP_GO_SHA256 || release.sha256;
36
+ const expected = brandedEnvValue(process.env, 'GO_SHA256') || release.sha256;
36
37
  if (actual !== expected) throw new Error(`Go checksum mismatch for ${release.archive}`);
37
- const root = join(process.env.BAS_VSP_GO_ROOT || join(homedir(), '.local', 'go'), GO_VERSION);
38
+ const root = join(brandedEnvValue(process.env, 'GO_ROOT') || join(homedir(), '.local', 'go'), GO_VERSION);
38
39
  await mkdir(root, { recursive: true, mode: 0o755 });
39
40
  const archive = join(tmpdir(), `${release.archive}.${process.pid}`);
40
41
  await writeFile(archive, bytes, { mode: 0o600 });
@@ -6,6 +6,7 @@ import { fileURLToPath } from 'node:url';
6
6
 
7
7
  const packageRoot = dirname(dirname(fileURLToPath(import.meta.url)));
8
8
  const manifestName = '.sap-ai-dev-toolkit-assets.json';
9
+ const legacyManifestName = '.bas-mcp-addon-assets.json';
9
10
 
10
11
  function digest(content) {
11
12
  return createHash('sha256').update(content).digest('hex');
@@ -62,8 +63,11 @@ export async function installUserCopilotAssets({ home = process.env.HOME || home
62
63
 
63
64
  const copilotRoot = join(home, '.copilot');
64
65
  const manifestPath = join(copilotRoot, manifestName);
66
+ const legacyManifestPath = join(copilotRoot, legacyManifestName);
65
67
  await mkdir(copilotRoot, { recursive: true, mode: 0o755 });
66
- const previousFiles = await readManagedFiles(manifestPath);
68
+ const legacyFiles = await readManagedFiles(legacyManifestPath);
69
+ const currentFiles = await readManagedFiles(manifestPath);
70
+ const previousFiles = { ...legacyFiles, ...currentFiles };
67
71
  const managedFiles = { ...previousFiles };
68
72
  const conflicts = [];
69
73
  let installed = 0;
@@ -106,5 +110,6 @@ export async function installUserCopilotAssets({ home = process.env.HOME || home
106
110
  }
107
111
 
108
112
  await replaceFile(manifestPath, `${JSON.stringify({ version: 1, files: managedFiles }, null, 2)}\n`);
113
+ await rm(legacyManifestPath, { force: true });
109
114
  return { root: copilotRoot, installed, updated, unchanged, conflicts };
110
115
  }
@@ -1,5 +1,5 @@
1
1
  import { open, readFile } from 'node:fs/promises';
2
- import { closeSync, openSync } from 'node:fs';
2
+ import { closeSync, openSync, realpathSync } from 'node:fs';
3
3
  import { dirname, join, resolve } from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  import { ensureGo } from './ensure-go.mjs';
@@ -10,9 +10,11 @@ import { createInterface } from 'node:readline/promises';
10
10
  import { ReadStream as TTYReadStream, WriteStream as TTYWriteStream } from 'node:tty';
11
11
  import { homedir } from 'node:os';
12
12
  import { colorText, formatStatus } from '../src/terminal-ui.mjs';
13
+ import { brandedEnvValue, withBrandedEnvironment } from '../src/branding.mjs';
13
14
 
14
15
  const root = dirname(dirname(fileURLToPath(import.meta.url)));
15
16
  const pkg = JSON.parse(await readFile(join(root, 'package.json'), 'utf8'));
17
+ const runtimeEnv = withBrandedEnvironment(process.env);
16
18
 
17
19
  async function announce(message, tone = 'info') {
18
20
  const content = message.replace(/^sap-ai-dev-toolkit:\s*/, '');
@@ -61,7 +63,7 @@ async function withInstallTerminal(action) {
61
63
  }
62
64
 
63
65
  async function runInstallSetup() {
64
- return withInstallTerminal(terminal => runSetup(terminal || undefined));
66
+ return withInstallTerminal(terminal => runSetup({ env: runtimeEnv, ...(terminal || {}) }));
65
67
  }
66
68
 
67
69
  async function runCopilotAssetInstall() {
@@ -182,10 +184,10 @@ async function announceSetup(result) {
182
184
  const registeredNames = new Set(servers.map(([name]) => name));
183
185
  const entryDetails = servers.flatMap(([name, entry]) => {
184
186
  const destination = destinationsByServer.get(name);
185
- const source = entry.env?.BAS_VSP_DESTINATION_SOURCE === 'cloud-foundry' || destination?.source === 'cloud-foundry'
187
+ const source = brandedEnvValue(entry.env, 'DESTINATION_SOURCE') === 'cloud-foundry' || destination?.source === 'cloud-foundry'
186
188
  ? 'Cloud Foundry'
187
189
  : 'BAS';
188
- const destinationName = entry.env?.BAS_VSP_DESTINATION || destination?.name || 'unknown';
190
+ const destinationName = brandedEnvValue(entry.env, 'DESTINATION') || destination?.name || 'unknown';
189
191
  const client = destination?.client || '001';
190
192
  const authentication = destination?.authentication || 'unknown';
191
193
  const args = Array.isArray(entry.args) ? entry.args : [];
@@ -217,8 +219,8 @@ async function main() {
217
219
  if (process.env.npm_config_ignore_scripts === 'true') return;
218
220
 
219
221
  try {
220
- if (process.env.BAS_VSP_BINARY) {
221
- await announce('Using the BAS_VSP_BINARY override.', 'info');
222
+ if (brandedEnvValue(runtimeEnv, 'BINARY')) {
223
+ await announce('Using the SAP_AI_DEV_TOOLKIT_BINARY override.', 'info');
222
224
  } else {
223
225
  await announce('Checking for Go. The supported version installs automatically if needed; this may take a few minutes.', 'progress');
224
226
  try {
@@ -229,7 +231,7 @@ async function main() {
229
231
  }
230
232
  await announce('Preparing the pinned VSP runtime for this platform.', 'progress');
231
233
  try {
232
- await installBinary(pkg);
234
+ await installBinary(pkg, { env: runtimeEnv });
233
235
  await announce('Pinned VSP binary installed and ready.', 'success');
234
236
  } catch (error) {
235
237
  throw new Error(`VSP binary provisioning failed: ${error.message}`);
@@ -237,7 +239,7 @@ async function main() {
237
239
  }
238
240
  } catch (error) {
239
241
  await announce(error.message, 'error');
240
- await announce('Go is provisioned automatically. Set BAS_VSP_BINARY only when supplying a trusted prebuilt VSP executable.', 'info');
242
+ await announce('Go is provisioned automatically. Set SAP_AI_DEV_TOOLKIT_BINARY only when supplying a trusted prebuilt VSP executable.', 'info');
241
243
  process.exitCode = 1;
242
244
  return;
243
245
  }
@@ -259,11 +261,9 @@ async function main() {
259
261
  }
260
262
  if (setupCompleted) await announceSetup(setupResult);
261
263
  }
262
- if (process.argv[1] && fileURLToPath(import.meta.url) === resolve(process.argv[1])) {
264
+ if (process.argv[1] && realpathSync(fileURLToPath(import.meta.url)) === realpathSync(resolve(process.argv[1]))) {
263
265
  main().catch(error => {
264
266
  console.error(formatStatus(`Postinstall failed: ${error.message}`, 'error', process.stderr));
265
267
  process.exitCode = 1;
266
268
  });
267
269
  }
268
-
269
-
@@ -1,6 +1,7 @@
1
1
  import { request as httpRequest } from 'node:http';
2
2
  import { request as httpsRequest } from 'node:https';
3
3
  import { ProxyAgent, fetch as undiciFetch } from 'undici';
4
+ import { brandedEnvValue } from './branding.mjs';
4
5
 
5
6
  const SECRET_KEY = /^(authorization|cookie|set-cookie|username|user|sap[_-](user(name)?|password|pass|token|saml[_-]?(user|password)|cookie[_-]?(file|string)|browser[_-]?auth|sso|credential[_-]?cmd))$|.*(password|passwd|secret|bearer|credential).*/i;
6
7
  const DEFAULT_PROXY = 'http://127.0.0.1:8887';
@@ -191,10 +192,10 @@ export async function discoverDestinations(options = {}) {
191
192
  const body = options.body ?? await fetchDestinationList(env.H2O_URL, options);
192
193
  const list = listFromBody(body);
193
194
  if (!list) throw new Error(`Unrecognized BAS destination response shape; top-level keys: ${Object.keys(body || {}).map(String).join(', ') || '<none>'}`);
194
- const allow = text(env.BAS_VSP_DESTINATION).split(',').map(value => value.trim().toLowerCase()).filter(Boolean);
195
+ const allow = text(brandedEnvValue(env, 'DESTINATION')).split(',').map(value => value.trim().toLowerCase()).filter(Boolean);
195
196
  const normalized = list.map(normalizeDestination).filter(item => item.name).filter(item => !allow.length || allow.includes(item.name.toLowerCase()));
196
197
  const proxyUrl = env.HTTP_PROXY || env.http_proxy || DEFAULT_PROXY;
197
- const skipProbe = String(env.BAS_VSP_SKIP_PROBE || '').toLowerCase() === 'true' || options.skipProbe;
198
+ const skipProbe = String(brandedEnvValue(env, 'SKIP_PROBE') || '').toLowerCase() === 'true' || options.skipProbe;
198
199
  const result = [];
199
200
  for (const destination of normalized.sort((a, b) => a.name.localeCompare(b.name))) {
200
201
  const probe = await probeADT(destination, { ...options, proxyUrl, skipProbe });