sap-ai-dev-toolkit 0.6.0 → 0.6.2

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/README.md CHANGED
@@ -84,7 +84,7 @@ Use the attached destination-prefixed tools directly in chat. Do not launch `sap
84
84
 
85
85
  **Included skills:** `abap-development` · `abap-testing-quality` · `cds-development` · `rap-development` · `abap-debugging` · `abap-runtime-analysis` · `rap-service-delivery` · `sap-standard-api-analysis` · `clean-core-extensibility` · `sap-sdlc-orchestration` · `sap-transport-release` · `hana-cloud-inspection` · `hana-cloud-native-development` · `hana-cloud-validation`
86
86
 
87
- 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.
87
+ Agents and skills install into `$HOME/.copilot` by default during global installation; press Enter to accept or type `n` to skip. In non-interactive installs they are installed automatically. Repository-scoped installation instructions appear below.
88
88
 
89
89
  ## ✨ Your SAP development cockpit, inside Copilot Chat
90
90
 
@@ -237,10 +237,9 @@ Once the destination server is enabled in Copilot Chat, ask for outcomes instead
237
237
  | --- | --- |
238
238
  | 🎯 **Explicit target** | SAP changes only proceed when the destination and required target details are known. |
239
239
  | 🚦 **Explicit state change** | Activation, service publication, and transport creation happen only when requested and authorized. |
240
- | 👁️ **Optional read-only mode** | `SAP_AI_DEV_TOOLKIT_READ_ONLY=true` removes every write/activate/transport-create tool from the surface and starts VSP with `--transport-read-only`. Recommended for exploration destinations. |
241
240
  | 🧪 **Verification first** | The agent uses available lint, syntax, unit-test, ATC, and diagnostics workflows and reports what actually ran. |
242
241
  | 🔒 **SAP authorization remains authoritative** | The add-on does not bypass backend SAP permissions. |
243
- | 🚚 **Curated VSP tool surface** | The proxy exposes a cherry-picked developer-lifecycle set from VSP plus local workflow tools, keeping one destination below 60 tools; SAP authorizations and VSP safety checks still apply. |
242
+ | 🚚 **Curated VSP tool surface** | The proxy exposes the same curated developer-lifecycle set for every destination, plus local workflow tools; SAP authorizations and VSP safety checks still apply. |
244
243
  | 🧱 **Per-destination isolation** | Generated MCP entries are scoped to a single `SAP_AI_DEV_TOOLKIT_DESTINATION`. |
245
244
  | 🔑 **No credentials in `mcp.json`** | Authentication material stays in BAS destination configuration rather than MCP config. |
246
245
 
@@ -278,6 +277,9 @@ The installer handles VSP provisioning automatically:
278
277
 
279
278
  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.
280
279
 
280
+
281
+ The same postinstall installs bundled Copilot agents and skills under `$HOME/.copilot` by default. Press Enter at `[Y/n]` to install or update them; type `n` to leave them unchanged. With no interactive terminal, installation proceeds automatically.
282
+
281
283
  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 --setup` from an interactive BAS terminal after installation.
282
284
 
283
285
  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.
@@ -617,8 +619,11 @@ The write and activation tools change SAP state. Confirm the target, package, an
617
619
  | `GetUserTransports` | Read and group a user's transport requests and tasks; supports organizer filters and source selection. |
618
620
  | `GetTransport` | Read a transport request's details, objects, and tasks. |
619
621
  | `GetTransportInfo` | Find eligible transports and lock status for an ABAP object or package. |
622
+ | `LockObject` | Lock an ABAP repository object in SAP. |
623
+ | `UnlockObject` | Unlock an ABAP repository object in SAP. |
620
624
  | `CreateTransport` | Create a transport request. |
621
625
  | `CheckTransportReadiness` | Collect a whitelisted bundle of transport, dependency, inactive-object, ABAP Unit, and ATC evidence. |
626
+ `LockObject` and `UnlockObject` are state-changing VSP tools; the proxy does not retry them after a child crash to avoid duplicate side effects.
622
627
 
623
628
  Transport release and deletion are not exposed by the curated proxy surface; release or delete transports outside this add-on after review.
624
629
 
@@ -736,7 +741,6 @@ The response contains a `tools` array. A `RunQuery` entry resembles this excerpt
736
741
  | `SAP_AI_DEV_TOOLKIT_DISABLE_BAS_RELAY=true` | Disable the built-in BAS destination relay. By default the add-on self-heals `.dest` destinations through a local relay that keeps all access destination-based while handling ADT CSRF fetch/retry behavior before VSP calls SAP. |
737
742
  | `SAP_AI_DEV_TOOLKIT_HTTP_PROXY` | Egress proxy for relay and discovery traffic. Takes precedence over `HTTP_PROXY`/`http_proxy`; unset means the default BAS proxy for `.dest` hosts, empty means direct. |
738
743
  | `SAP_AI_DEV_TOOLKIT_MAX_CSRF_RETRIES` | Bounded retries after explicit CSRF-session rejection per unsafe request (default 3, maximum 10). Invalid values use the default. |
739
- | `SAP_AI_DEV_TOOLKIT_READ_ONLY=true` | Read-only mode: hides `WriteSource`, `EditSource`, `Activate`, `ActivateMultiple`, `CreateTransport`, `SetBreakpoint`, and the change-set workflow tools, and starts VSP with `--transport-read-only`. |
740
744
  | `SAP_AI_DEV_TOOLKIT_REQUEST_TIMEOUT_MS` | Per-request timeout for calls forwarded to a VSP child (default 600000 = 10 minutes; `0` disables). A stalled request fails with a timeout error; the child is left running. |
741
745
  | `SAP_AI_DEV_MCP_CONFIG` | Explicit MCP configuration path; highest precedence. |
742
746
  | `SAP_AI_DEV_TOOLKIT_MCP_CONFIG` | Branded compatibility alias for the MCP configuration path. |
package/inventory.md CHANGED
@@ -163,7 +163,7 @@ These logical names are exposed through MCP in lowercase snake_case (`lint_abap`
163
163
 
164
164
  - Runtime tool names are unprefixed lowercase snake_case (`run_query`) on the normal single-destination server; a `<destination-slug>_` prefix appears only on multi-destination servers. `tools/call` accepts the exact name returned by `tools/list`.
165
165
  - The proxy starts VSP with `--enable-transports`; generated MCP entries set `SAP_ALLOW_TRANSPORTABLE_EDITS=true`.
166
- - `SAP_AI_DEV_TOOLKIT_READ_ONLY=true` switches a server to read-only: the write/activate/transport-create/breakpoint tools above are removed from the surface, change-set workflows are not registered, and VSP starts with `--transport-read-only` instead.
166
+ - The curated VSP tool surface and enabled transport mode are the same for every destination; SAP authorization remains authoritative.
167
167
  - `SAP_AI_DEV_TOOLKIT_REQUEST_TIMEOUT_MS` (default 600000) bounds each forwarded call; stalled requests fail without killing the child.
168
168
  - Transport release/deletion and the general-purpose `SAP` router are intentionally hidden from direct proxy calls. `GetApplicationLog` is the bounded convenience mapping for the SAP application-log route.
169
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sap-ai-dev-toolkit",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "SAP AI development toolkit for BAS, ABAP, RAP, CAP, HANA Cloud, Fiori, UI5, and MCP",
5
5
  "author": "Gurkan Yilmaz",
6
6
  "type": "module",
@@ -14,7 +14,7 @@ function usage() {
14
14
  '',
15
15
  ' (default) Packs the workspace and installs the tarball globally, then',
16
16
  ' runs the normal postinstall wizard (binary provisioning,',
17
- ' BAS destination setup, optional Copilot assets).',
17
+ ' BAS destination setup, and default Copilot asset installation).',
18
18
  ' --link Installs with npm link instead of a tarball; edits to src/',
19
19
  ' and scripts/ take effect immediately without reinstalling.',
20
20
  ' --verify Verifies the global sap-ai-dev command resolves to this',
@@ -68,19 +68,29 @@ async function runInstallSetup() {
68
68
  }
69
69
 
70
70
  async function runCopilotAssetInstall() {
71
+ const copilotRoot = join(process.env.HOME || homedir(), '.copilot');
72
+ const installAssets = async () => {
73
+ const assets = await installUserCopilotAssets({ root });
74
+ const installed = assets.installed + assets.updated;
75
+ await announce(`Installed ${installed} Copilot files in ${assets.root}; ${assets.unchanged} already current.`, 'success');
76
+ if (assets.conflicts.length > 0) {
77
+ const paths = assets.conflicts.map(path => join(assets.root, path)).join(', ');
78
+ await announce(`Existing Copilot customizations were preserved; review these paths: ${paths}`, 'warning');
79
+ }
80
+ };
71
81
  await withInstallTerminal(async terminal => {
72
82
  if (!terminal) {
73
- await announce('Optional Copilot installation skipped because no interactive terminal is available.', 'warning');
83
+ await announce('Installing bundled agents and skills by default because no interactive terminal is available.', 'progress');
84
+ await installAssets();
74
85
  return;
75
86
  }
76
- const copilotRoot = join(process.env.HOME || homedir(), '.copilot');
77
87
  await announce([
78
- 'Optional Copilot setup is waiting for your choice.',
88
+ 'Bundled Copilot agents and skills are installed by default.',
79
89
  '',
80
- 'Type y then press Enter to install the bundled agents and all skills in the path shown below; press Enter alone to skip.',
90
+ 'Type n then press Enter to skip installing or updating the bundled files.',
81
91
  '',
82
- `${colorText('✅ Type y then Enter', 'green', true)} to install the bundled agents and all skills.`,
83
- `${colorText('⏭️ Press Enter', 'yellow', true)} to skip this optional step (default).`,
92
+ `${colorText('✅ Press Enter', 'green', true)} to install or update the bundled agents and all skills.`,
93
+ `${colorText('⏭️ Type n then Enter', 'yellow', true)} to skip this step.`,
84
94
  '',
85
95
  `${colorText('📁 Target folder:', 'cyan', true)}`,
86
96
  ` ${copilotRoot}`,
@@ -89,23 +99,15 @@ async function runCopilotAssetInstall() {
89
99
  const prompt = createInterface({ input: terminal.input, output: terminal.output });
90
100
  let answer;
91
101
  try {
92
- answer = await prompt.question(`${colorText('🤖 Install the bundled agents and all skills?', 'magenta', terminal.output)} ${colorText('[y/N]', 'yellow', terminal.output)} `);
102
+ answer = await prompt.question(`${colorText('🤖 Install the bundled agents and all skills?', 'magenta', terminal.output)} ${colorText('[Y/n]', 'yellow', terminal.output)} `);
93
103
  } finally {
94
104
  prompt.close();
95
105
  }
96
- // Default is skip: writing instruction files into ~/.copilot affects
97
- // every Copilot session on the machine, so it needs an explicit yes.
98
- if (!/^y(?:es)?$/i.test(answer.trim())) {
106
+ if (/^n(?:o)?$/i.test(answer.trim())) {
99
107
  await announce('Copilot agent and skills were skipped. Your files were not changed.', 'info');
100
108
  return;
101
109
  }
102
- const assets = await installUserCopilotAssets({ root });
103
- const installed = assets.installed + assets.updated;
104
- await announce(`Installed ${installed} Copilot files in ${assets.root}; ${assets.unchanged} already current.`, 'success');
105
- if (assets.conflicts.length > 0) {
106
- const paths = assets.conflicts.map(path => join(assets.root, path)).join(', ');
107
- await announce(`Existing Copilot customizations were preserved; review these paths: ${paths}`, 'warning');
108
- }
110
+ await installAssets();
109
111
  });
110
112
  }
111
113
 
package/src/mcp-proxy.mjs CHANGED
@@ -38,18 +38,6 @@ const APPLICATION_LOG_SCHEMA = {
38
38
  };
39
39
  const APPLICATION_LOG_DESCRIPTION = 'Read SAP application log (SLG1) entries. Results are newest first and limited to 100 by default; set messages=true to include log message details.';
40
40
 
41
- // Read-only mode (SAP_AI_DEV_TOOLKIT_READ_ONLY=true) removes every tool that
42
- // changes SAP state from the public surface and starts VSP with
43
- // --transport-read-only, so an exploration destination cannot be written to
44
- // through this proxy even if a chat prompt asks for it.
45
- const READ_ONLY_HIDDEN_VSP_TOOLS = new Set([
46
- 'Activate',
47
- 'ActivateMultiple',
48
- 'CreateTransport',
49
- 'EditSource',
50
- 'SetBreakpoint',
51
- 'WriteSource'
52
- ]);
53
41
 
54
42
  // Self-healing restarts retry the interrupted tools/call once. Retrying a
55
43
  // state-changing tool after a crash can apply the same write twice (the child
@@ -60,6 +48,8 @@ const NON_RETRIABLE_VSP_TOOLS = new Set([
60
48
  'ActivateMultiple',
61
49
  'CreateTransport',
62
50
  'EditSource',
51
+ 'LockObject',
52
+ 'UnlockObject',
63
53
  'WriteSource'
64
54
  ]);
65
55
 
@@ -78,10 +68,6 @@ function requestTimeoutMs(env) {
78
68
  return parsed > 0 ? Math.floor(parsed) : 0;
79
69
  }
80
70
 
81
- export function readOnlyMode(env = process.env) {
82
- const raw = brandedEnvValue(env, 'READ_ONLY');
83
- return raw !== undefined && ['1', 'true', 'yes'].includes(String(raw).trim().toLowerCase());
84
- }
85
71
 
86
72
  // Keep the default public VSP surface small enough for developer-lifecycle use.
87
73
  // Hidden upstream tools can still be used by local workflow tools when needed.
@@ -129,6 +115,7 @@ export const PUBLIC_VSP_TOOLS = new Set([
129
115
  'GrepPackages',
130
116
  'ListDependencies',
131
117
  'ListTransports',
118
+ 'LockObject',
132
119
  'PrettyPrint',
133
120
  'RunATCCheck',
134
121
  'RunQuery',
@@ -136,15 +123,10 @@ export const PUBLIC_VSP_TOOLS = new Set([
136
123
  'SearchObject',
137
124
  'SetBreakpoint',
138
125
  'SyntaxCheck',
126
+ 'UnlockObject',
139
127
  'WriteSource'
140
128
  ]);
141
129
 
142
- function exposeVspTool(tool, readOnly = false) {
143
- if (!PUBLIC_VSP_TOOLS.has(tool?.name)) return false;
144
- // Read-only destinations never expose the write/activate/transport-create
145
- // surface, even when VSP registers it.
146
- return !(readOnly && READ_ONLY_HIDDEN_VSP_TOOLS.has(tool.name));
147
- }
148
130
 
149
131
  // Public tool names are lowercase snake_case. BAS/VS Code chat tool references
150
132
  // are lowercase-only, so mixed-case names never bind in the tools picker even
@@ -210,13 +192,12 @@ function childEnvironment(destination, env) {
210
192
 
211
193
 
212
194
  export function childArguments(destination, env = process.env) {
213
- // The proxy allowlist keeps transport mutations to CreateTransport.
214
- // Transportable source edits are controlled by SAP_ALLOW_TRANSPORTABLE_EDITS.
195
+ // The proxy allowlist controls transport operations; source edits are
196
+ // controlled by SAP_ALLOW_TRANSPORTABLE_EDITS and SAP authorizations.
215
197
  const mode = brandedEnvValue(env, 'MODE') || 'expert';
216
198
  const args = ['--url', destination.url, '--client', destination.client || '001', '--mode', mode];
217
199
  if (destination.source !== 'cloud-foundry' || destination.authentication === 'PrincipalPropagation') args.push('--proxy-auth');
218
- if (readOnlyMode(env)) args.push('--transport-read-only');
219
- else args.push('--enable-transports');
200
+ args.push('--enable-transports');
220
201
  return args;
221
202
  }
222
203
 
@@ -394,7 +375,6 @@ export class MCPProxy {
394
375
  this.log = log;
395
376
  this.output = output;
396
377
  this.version = version;
397
- this.readOnly = readOnlyMode(env);
398
378
  this.requestTimeoutMs = requestTimeoutMs(env);
399
379
  this.children = [];
400
380
  this.started = false;
@@ -663,17 +643,11 @@ export class MCPProxy {
663
643
  });
664
644
  }
665
645
 
666
- if (!exposeVspTool(tool, this.readOnly)) continue;
646
+ if (!PUBLIC_VSP_TOOLS.has(tool?.name)) continue;
667
647
  const name = publicName(tool.name);
668
648
  publish(name, { entry, upstream: tool.name }, { ...tool, name, description: `${tool.description || tool.name} [destination: ${entry.destination.name}]` });
669
649
  }
670
- // Local workflow tools gate on the upstream surface they can use; in
671
- // read-only mode the hidden write tools must not enable change-set
672
- // staging either.
673
- const effectiveUpstream = this.readOnly
674
- ? upstreamTools.filter(tool => !READ_ONLY_HIDDEN_VSP_TOOLS.has(tool.name))
675
- : upstreamTools;
676
- for (const localTool of createEngineeringTools(entry, effectiveUpstream, { env: this.env, log: this.log })) {
650
+ for (const localTool of createEngineeringTools(entry, upstreamTools, { env: this.env, log: this.log })) {
677
651
  const name = publicName(localTool.definition.name);
678
652
  publish(name, { handler: localTool.handler }, {
679
653
  ...localTool.definition,
package/tools.md CHANGED
@@ -77,9 +77,6 @@ The proxy adds local multi-step tools to each destination when their required VS
77
77
 
78
78
  `sap-ai-dev --doctor` checks destination probing, VSP startup, the `get_system_info` probe, and MCP tool listing. `sap-ai-dev --demo` runs the sample tools and OData fixtures without contacting SAP; demo writes and transport creation remain in memory until that process exits.
79
79
 
80
- ### Read-only mode
81
-
82
- Set `SAP_AI_DEV_TOOLKIT_READ_ONLY=true` (or legacy `BAS_VSP_READ_ONLY`) on a destination server to run it strictly read-only: `WriteSource`, `EditSource`, `Activate`, `ActivateMultiple`, `CreateTransport`, `SetBreakpoint`, and the change-set workflow tools are removed from the surface, and the VSP child starts with `--transport-read-only` so transport writes are rejected upstream as well. Inspection, queries, linting, and checks remain available.
83
80
 
84
81
  ### Request timeouts
85
82