dlw-machine-setup 0.3.0 → 0.3.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 +0 -4
- package/bin/installer.js +61 -161
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -99,10 +99,6 @@ The installer provides:
|
|
|
99
99
|
- **MCP server configuration** for AI assistants (Claude, Copilot, Cursor)
|
|
100
100
|
- **Setup instructions** for your development environment
|
|
101
101
|
|
|
102
|
-
## Repository
|
|
103
|
-
|
|
104
|
-
GitHub: [DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client](https://github.com/DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client)
|
|
105
|
-
|
|
106
102
|
## License
|
|
107
103
|
|
|
108
104
|
Internal use only - DLW-INT-SAP-DEV organization
|
package/bin/installer.js
CHANGED
|
@@ -3244,135 +3244,15 @@ var import_fs5 = require("fs");
|
|
|
3244
3244
|
var import_readline = require("readline");
|
|
3245
3245
|
var import_path5 = require("path");
|
|
3246
3246
|
|
|
3247
|
-
// data/wizard-options/agents.json
|
|
3248
|
-
var agents_default = {
|
|
3249
|
-
agents: [
|
|
3250
|
-
{ name: "Claude Code", value: "claude-code", active: true },
|
|
3251
|
-
{ name: "GitHub Copilot", value: "github-copilot", active: true },
|
|
3252
|
-
{ name: "Cursor", value: "cursor", active: false }
|
|
3253
|
-
]
|
|
3254
|
-
};
|
|
3255
|
-
|
|
3256
|
-
// data/wizard-options/personas.json
|
|
3257
|
-
var personas_default = {
|
|
3258
|
-
baseMcpServers: ["azure-devops", "context7"],
|
|
3259
|
-
personas: [
|
|
3260
|
-
{
|
|
3261
|
-
id: "sapui5-developer",
|
|
3262
|
-
name: "SAPUI5 Developer",
|
|
3263
|
-
description: "Frontend development with SAP UI5 and Fiori",
|
|
3264
|
-
domains: ["SAPUI5"],
|
|
3265
|
-
mcpServers: ["azure-devops", "context7", "playwright", "@ui5/mcp-server"],
|
|
3266
|
-
active: true
|
|
3267
|
-
},
|
|
3268
|
-
{
|
|
3269
|
-
id: "cap-developer",
|
|
3270
|
-
name: "CAP Developer",
|
|
3271
|
-
description: "Backend development with SAP Cloud Application Programming model",
|
|
3272
|
-
domains: ["CAP"],
|
|
3273
|
-
mcpServers: ["azure-devops", "context7", "cds-mcp"],
|
|
3274
|
-
active: true
|
|
3275
|
-
},
|
|
3276
|
-
{
|
|
3277
|
-
id: "abap-developer",
|
|
3278
|
-
name: "ABAP Developer",
|
|
3279
|
-
description: "ABAP and SAP backend development",
|
|
3280
|
-
domains: ["ABAP"],
|
|
3281
|
-
mcpServers: ["azure-devops", "context7", "abap", "sap-researcher"],
|
|
3282
|
-
active: true
|
|
3283
|
-
},
|
|
3284
|
-
{
|
|
3285
|
-
id: "btp-developer",
|
|
3286
|
-
name: "BTP Developer",
|
|
3287
|
-
description: "SAP Business Technology Platform development",
|
|
3288
|
-
domains: ["BTP"],
|
|
3289
|
-
mcpServers: ["azure-devops", "context7"],
|
|
3290
|
-
active: true
|
|
3291
|
-
},
|
|
3292
|
-
{
|
|
3293
|
-
id: "sap-dm-developer",
|
|
3294
|
-
name: "SAP Digital Manufacturing Developer",
|
|
3295
|
-
description: "SAP Digital Manufacturing development",
|
|
3296
|
-
domains: ["SAP_DM"],
|
|
3297
|
-
mcpServers: ["azure-devops", "context7"],
|
|
3298
|
-
active: true
|
|
3299
|
-
},
|
|
3300
|
-
{
|
|
3301
|
-
id: "forms-developer",
|
|
3302
|
-
name: "Forms Developer",
|
|
3303
|
-
description: "SAP Forms development",
|
|
3304
|
-
domains: ["FORMS"],
|
|
3305
|
-
mcpServers: ["azure-devops", "context7"],
|
|
3306
|
-
active: true
|
|
3307
|
-
}
|
|
3308
|
-
]
|
|
3309
|
-
};
|
|
3310
|
-
|
|
3311
|
-
// data/wizard-options/mcp-servers.json
|
|
3312
|
-
var mcp_servers_default = {
|
|
3313
|
-
"azure-devops": {
|
|
3314
|
-
command: "npx",
|
|
3315
|
-
args: ["-y", "@azure-devops/mcp", "__AZURE_ORG__"],
|
|
3316
|
-
description: "Access Azure DevOps work items, boards, pipelines and repositories",
|
|
3317
|
-
useWhen: "User asks about work items, sprints, pipelines, pull requests or Azure DevOps tasks",
|
|
3318
|
-
active: true
|
|
3319
|
-
},
|
|
3320
|
-
context7: {
|
|
3321
|
-
type: "stdio",
|
|
3322
|
-
command: "npx",
|
|
3323
|
-
args: ["-y", "@upstash/context7-mcp"],
|
|
3324
|
-
description: "Fetch up-to-date library and framework documentation",
|
|
3325
|
-
useWhen: "User asks how something works in a specific library or framework (e.g. 'how does X work in SAPUI5?')",
|
|
3326
|
-
active: true
|
|
3327
|
-
},
|
|
3328
|
-
"@ui5/mcp-server": {
|
|
3329
|
-
type: "stdio",
|
|
3330
|
-
command: "npx",
|
|
3331
|
-
args: ["@ui5/mcp-server"],
|
|
3332
|
-
description: "SAPUI5-specific tooling for views, controllers, manifest and OData",
|
|
3333
|
-
useWhen: "User asks to create or modify SAPUI5 views, controllers, fragments or manifest.json",
|
|
3334
|
-
active: true
|
|
3335
|
-
},
|
|
3336
|
-
playwright: {
|
|
3337
|
-
command: "npx",
|
|
3338
|
-
args: ["@playwright/mcp@latest"],
|
|
3339
|
-
description: "Browser automation and end-to-end testing",
|
|
3340
|
-
useWhen: "User asks to write or run browser tests, or automate browser interactions",
|
|
3341
|
-
active: true
|
|
3342
|
-
},
|
|
3343
|
-
"cds-mcp": {
|
|
3344
|
-
command: "npx",
|
|
3345
|
-
args: ["-y", "@cap-js/mcp-server"],
|
|
3346
|
-
description: "SAP CAP/CDS tooling for service definitions, handlers and CQL",
|
|
3347
|
-
useWhen: "User asks about CAP services, CDS models, handlers or CQL queries",
|
|
3348
|
-
active: true
|
|
3349
|
-
},
|
|
3350
|
-
abap: {
|
|
3351
|
-
type: "http",
|
|
3352
|
-
url: "http://localhost:5001/mcp",
|
|
3353
|
-
description: "ABAP development assistant for SAP backend development",
|
|
3354
|
-
useWhen: "User asks about ABAP code, RAP objects, CDS views or SAP backend logic",
|
|
3355
|
-
active: true
|
|
3356
|
-
},
|
|
3357
|
-
"sap-researcher": {
|
|
3358
|
-
command: "npx",
|
|
3359
|
-
args: ["mcp-remote", "http://gsi-em-az1-0057/successormcp/mcp", "--allow-http"],
|
|
3360
|
-
description: "Internal SAP knowledge base and documentation search",
|
|
3361
|
-
useWhen: "User asks about SAP-specific topics, best practices or internal documentation",
|
|
3362
|
-
active: true
|
|
3363
|
-
}
|
|
3364
|
-
};
|
|
3365
|
-
|
|
3366
3247
|
// src/utils/data/fetch-wizard-options.ts
|
|
3367
|
-
|
|
3368
|
-
async function fetchWizardOptions(token) {
|
|
3248
|
+
async function fetchWizardOptions(token, repo) {
|
|
3369
3249
|
try {
|
|
3370
3250
|
const headers = {
|
|
3371
3251
|
"Accept": "application/vnd.github+json",
|
|
3372
3252
|
"Authorization": `Bearer ${token}`
|
|
3373
3253
|
};
|
|
3374
3254
|
const releaseRes = await fetch(
|
|
3375
|
-
`https://api.github.com/repos/${
|
|
3255
|
+
`https://api.github.com/repos/${repo}/releases/latest`,
|
|
3376
3256
|
{ headers }
|
|
3377
3257
|
);
|
|
3378
3258
|
if (!releaseRes.ok) return null;
|
|
@@ -3393,6 +3273,38 @@ async function fetchWizardOptions(token) {
|
|
|
3393
3273
|
}
|
|
3394
3274
|
}
|
|
3395
3275
|
|
|
3276
|
+
// src/utils/data/discover-repo.ts
|
|
3277
|
+
var GITHUB_ORG = "DLW-INT-SAP-DEV";
|
|
3278
|
+
var REPO_TOPIC = "one-shot-data";
|
|
3279
|
+
async function discoverRepo(token) {
|
|
3280
|
+
const response = await fetch(
|
|
3281
|
+
`https://api.github.com/search/repositories?q=topic:${REPO_TOPIC}+org:${GITHUB_ORG}`,
|
|
3282
|
+
{
|
|
3283
|
+
headers: {
|
|
3284
|
+
"Accept": "application/vnd.github+json",
|
|
3285
|
+
"Authorization": `Bearer ${token}`
|
|
3286
|
+
}
|
|
3287
|
+
}
|
|
3288
|
+
);
|
|
3289
|
+
if (!response.ok) {
|
|
3290
|
+
throw new Error(
|
|
3291
|
+
`Failed to discover data repository (HTTP ${response.status}). Check your GitHub token and network.`
|
|
3292
|
+
);
|
|
3293
|
+
}
|
|
3294
|
+
const data = await response.json();
|
|
3295
|
+
if (data.total_count === 0) {
|
|
3296
|
+
throw new Error(
|
|
3297
|
+
"No data repository found. Verify your GitHub account has access to the organization."
|
|
3298
|
+
);
|
|
3299
|
+
}
|
|
3300
|
+
if (data.total_count > 1) {
|
|
3301
|
+
throw new Error(
|
|
3302
|
+
"Multiple data repositories found. Contact your administrator."
|
|
3303
|
+
);
|
|
3304
|
+
}
|
|
3305
|
+
return data.items[0].full_name;
|
|
3306
|
+
}
|
|
3307
|
+
|
|
3396
3308
|
// src/utils/data/fetch-contexts.ts
|
|
3397
3309
|
var import_fs2 = require("fs");
|
|
3398
3310
|
var import_path2 = require("path");
|
|
@@ -3554,12 +3466,14 @@ async function getGitHubToken() {
|
|
|
3554
3466
|
}
|
|
3555
3467
|
|
|
3556
3468
|
// src/utils/data/fetch-contexts.ts
|
|
3557
|
-
var GITHUB_REPO2 = "DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client";
|
|
3558
3469
|
var MAX_RETRIES = 3;
|
|
3559
3470
|
var RETRY_DELAY_MS = 2e3;
|
|
3560
3471
|
var MIN_FILE_SIZE = 1024;
|
|
3561
3472
|
async function fetchContexts(options = {}) {
|
|
3562
|
-
const { domains = [], targetDir = process.cwd(), force = false, token } = options;
|
|
3473
|
+
const { domains = [], targetDir = process.cwd(), force = false, token, repo } = options;
|
|
3474
|
+
if (!repo) {
|
|
3475
|
+
throw new Error("Repository not specified. Discovery may have failed.");
|
|
3476
|
+
}
|
|
3563
3477
|
const result = {
|
|
3564
3478
|
successful: [],
|
|
3565
3479
|
failed: [],
|
|
@@ -3572,7 +3486,7 @@ async function fetchContexts(options = {}) {
|
|
|
3572
3486
|
await checkPrerequisites();
|
|
3573
3487
|
const githubToken = token ?? await getGitHubToken();
|
|
3574
3488
|
try {
|
|
3575
|
-
const releaseUrl = `https://api.github.com/repos/${
|
|
3489
|
+
const releaseUrl = `https://api.github.com/repos/${repo}/releases/latest`;
|
|
3576
3490
|
const headers = {
|
|
3577
3491
|
"Accept": "application/vnd.github+json",
|
|
3578
3492
|
"Authorization": `Bearer ${githubToken}`
|
|
@@ -3758,9 +3672,6 @@ function getAgentMCPTarget(agent) {
|
|
|
3758
3672
|
return { filePath: ".vscode/mcp.json", rootKey: "servers", dir: ".vscode" };
|
|
3759
3673
|
}
|
|
3760
3674
|
}
|
|
3761
|
-
var ALL_MCP_SERVERS = Object.fromEntries(
|
|
3762
|
-
Object.entries(mcp_servers_default).filter(([, config]) => config.active !== false)
|
|
3763
|
-
);
|
|
3764
3675
|
async function setupMCPConfiguration(projectPath, mcpConfig, agent) {
|
|
3765
3676
|
const target = getAgentMCPTarget(agent);
|
|
3766
3677
|
const mcpJsonPath = (0, import_path3.join)(projectPath, target.filePath);
|
|
@@ -3795,18 +3706,17 @@ async function setupMCPConfiguration(projectPath, mcpConfig, agent) {
|
|
|
3795
3706
|
(0, import_fs3.writeFileSync)(mcpJsonPath, JSON.stringify(outputFile, null, 2), "utf-8");
|
|
3796
3707
|
return { addedServers, skippedServers };
|
|
3797
3708
|
}
|
|
3798
|
-
function buildMCPConfiguration(selectedItems,
|
|
3799
|
-
const servers = allMcpServers ?? ALL_MCP_SERVERS;
|
|
3709
|
+
function buildMCPConfiguration(selectedItems, baseMcpServers, allMcpServers) {
|
|
3800
3710
|
const config = {};
|
|
3801
|
-
for (const serverName of
|
|
3802
|
-
if (
|
|
3803
|
-
config[serverName] =
|
|
3711
|
+
for (const serverName of baseMcpServers) {
|
|
3712
|
+
if (allMcpServers[serverName]) {
|
|
3713
|
+
config[serverName] = allMcpServers[serverName];
|
|
3804
3714
|
}
|
|
3805
3715
|
}
|
|
3806
3716
|
for (const item of selectedItems) {
|
|
3807
3717
|
for (const serverName of item.mcpServers) {
|
|
3808
|
-
if (
|
|
3809
|
-
config[serverName] =
|
|
3718
|
+
if (allMcpServers[serverName] && !config[serverName]) {
|
|
3719
|
+
config[serverName] = allMcpServers[serverName];
|
|
3810
3720
|
}
|
|
3811
3721
|
}
|
|
3812
3722
|
}
|
|
@@ -3936,31 +3846,19 @@ ${body}`;
|
|
|
3936
3846
|
}
|
|
3937
3847
|
|
|
3938
3848
|
// src/utils/mod.ts
|
|
3939
|
-
|
|
3940
|
-
|
|
3941
|
-
|
|
3942
|
-
|
|
3943
|
-
const remote = await fetchWizardOptions(token);
|
|
3944
|
-
if (remote) {
|
|
3945
|
-
const filteredMcpServers = Object.fromEntries(
|
|
3946
|
-
Object.entries(remote.mcpServers).filter(([, config]) => config.active !== false)
|
|
3947
|
-
);
|
|
3948
|
-
return {
|
|
3949
|
-
personas: remote.personas.personas.filter((p) => p.active !== false),
|
|
3950
|
-
agents: remote.agents.filter((a) => a.active !== false),
|
|
3951
|
-
baseMcpServers: remote.personas.baseMcpServers,
|
|
3952
|
-
mcpServers: filteredMcpServers
|
|
3953
|
-
};
|
|
3849
|
+
async function loadWizardOptions(token, repo) {
|
|
3850
|
+
const remote = await fetchWizardOptions(token, repo);
|
|
3851
|
+
if (!remote) {
|
|
3852
|
+
throw new Error("Failed to load configuration from GitHub release. Check your network and token.");
|
|
3954
3853
|
}
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
Object.entries(mcp_servers_default).filter(([, c]) => c.active !== false)
|
|
3854
|
+
const filteredMcpServers = Object.fromEntries(
|
|
3855
|
+
Object.entries(remote.mcpServers).filter(([, config]) => config.active !== false)
|
|
3958
3856
|
);
|
|
3959
3857
|
return {
|
|
3960
|
-
personas,
|
|
3961
|
-
agents,
|
|
3962
|
-
baseMcpServers,
|
|
3963
|
-
mcpServers:
|
|
3858
|
+
personas: remote.personas.personas.filter((p) => p.active !== false),
|
|
3859
|
+
agents: remote.agents.filter((a) => a.active !== false),
|
|
3860
|
+
baseMcpServers: remote.personas.baseMcpServers,
|
|
3861
|
+
mcpServers: filteredMcpServers
|
|
3964
3862
|
};
|
|
3965
3863
|
}
|
|
3966
3864
|
|
|
@@ -4007,8 +3905,10 @@ async function main() {
|
|
|
4007
3905
|
console.log("One-Shot Setup Installer\n");
|
|
4008
3906
|
try {
|
|
4009
3907
|
const token = await getGitHubToken();
|
|
3908
|
+
console.log(" Locating data repository...");
|
|
3909
|
+
const repo = await discoverRepo(token);
|
|
4010
3910
|
console.log(" Loading configuration...");
|
|
4011
|
-
const options = await loadWizardOptions(token);
|
|
3911
|
+
const options = await loadWizardOptions(token, repo);
|
|
4012
3912
|
const config = await collectInputs(options);
|
|
4013
3913
|
if (!config) {
|
|
4014
3914
|
await waitForEnter();
|
|
@@ -4020,7 +3920,7 @@ async function main() {
|
|
|
4020
3920
|
await waitForEnter();
|
|
4021
3921
|
return;
|
|
4022
3922
|
}
|
|
4023
|
-
const result = await execute(config, token);
|
|
3923
|
+
const result = await execute(config, token, repo);
|
|
4024
3924
|
printSummary(result);
|
|
4025
3925
|
return;
|
|
4026
3926
|
} catch (error) {
|
|
@@ -4100,7 +4000,7 @@ async function previewAndConfirm(config, options) {
|
|
|
4100
4000
|
console.log("\n" + "\u2500".repeat(48));
|
|
4101
4001
|
return esm_default3({ message: "Proceed?", default: true });
|
|
4102
4002
|
}
|
|
4103
|
-
async function execute(config, token) {
|
|
4003
|
+
async function execute(config, token, repo) {
|
|
4104
4004
|
const instructionFilePath = getInstructionFilePath(config.agent);
|
|
4105
4005
|
const mcpConfigPath = getMCPConfigPath(config.agent);
|
|
4106
4006
|
const result = {
|
|
@@ -4119,7 +4019,7 @@ async function execute(config, token) {
|
|
|
4119
4019
|
const domainValues = uniqueDomains.map((d) => d.toLowerCase());
|
|
4120
4020
|
console.log(` Downloading contexts...`);
|
|
4121
4021
|
try {
|
|
4122
|
-
const downloadResult = await fetchContexts({ domains: domainValues, token });
|
|
4022
|
+
const downloadResult = await fetchContexts({ domains: domainValues, token, repo });
|
|
4123
4023
|
result.domainsInstalled = downloadResult.successful;
|
|
4124
4024
|
result.domainsFailed = downloadResult.failed;
|
|
4125
4025
|
result.failureReasons = downloadResult.failureReasons;
|