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.
- package/.github/agents/abap-developer.agent.md +4 -3
- package/.github/agents/abap-runtime-debugger.agent.md +1 -1
- package/.github/agents/rap-service-developer.agent.md +1 -1
- package/.github/skills/abap-development/SKILL.md +2 -1
- package/.github/skills/rap-service-delivery/SKILL.md +4 -1
- package/.github/skills/sap-transport-release/SKILL.md +2 -2
- package/README.md +82 -34
- package/package.json +1 -1
- package/scripts/ensure-go.mjs +5 -4
- package/scripts/install-user-copilot-assets.mjs +6 -1
- package/scripts/postinstall.mjs +11 -11
- package/src/bas-discovery.mjs +3 -2
- package/src/binary.mjs +27 -17
- package/src/branding.mjs +21 -0
- package/src/cf-destination.mjs +1 -1
- package/src/demo-vsp.mjs +113 -0
- package/src/engineering-tools.mjs +641 -0
- package/src/launcher.mjs +118 -11
- package/src/mcp-config.mjs +19 -10
- package/src/mcp-proxy.mjs +18 -4
- package/src/setup.mjs +5 -6
- package/test/cf-destination.test.mjs +2 -2
- package/test/cf-runtime.test.mjs +12 -12
- package/test/copilot-assets.test.mjs +26 -0
- package/test/discovery.test.mjs +10 -1
- package/test/launcher.test.mjs +46 -9
- package/test/mcp-config-cf.test.mjs +49 -5
- package/test/mcp-proxy.test.mjs +1 -1
- package/test/pty.mjs +8 -0
- package/test/setup-cf.test.mjs +4 -4
- package/test/setup.test.mjs +51 -14
- package/tools.md +12 -1
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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 `
|
|
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
|
|
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>
|
|
5
|
-
|
|
6
|
-
|
|
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"
|
|
26
|
-
<a href="#copilot-agent"
|
|
27
|
-
<a href="#bas"
|
|
28
|
-
<a href="#tools"
|
|
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
|
|
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
|
-
## ✨
|
|
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** |
|
|
84
|
-
| 🧭 | **
|
|
85
|
-
| 🔎 | **
|
|
86
|
-
| 🧩 | **CDS + RAP development** |
|
|
87
|
-
| 🗃️ | **SAP data
|
|
88
|
-
| ✍️ | **Create + edit ABAP objects** |
|
|
89
|
-
| ✅ | **Quality built into the flow** |
|
|
90
|
-
| 🐞 | **
|
|
91
|
-
| 🚚 | **Transport-aware workflows** |
|
|
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 `
|
|
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
|
|
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 `
|
|
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
|
-
## 🧭
|
|
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 `
|
|
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
|
-
"
|
|
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 `
|
|
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
|
|
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`
|
|
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
|
|
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
|
-
| `
|
|
652
|
-
| `
|
|
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
|
-
| `
|
|
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 `
|
|
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
package/scripts/ensure-go.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
}
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -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 ||
|
|
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
|
|
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
|
|
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 (
|
|
221
|
-
await announce('Using the
|
|
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
|
|
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
|
-
|
package/src/bas-discovery.mjs
CHANGED
|
@@ -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
|
|
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
|
|
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 });
|