dlw-machine-setup 0.2.6 → 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.
Files changed (2) hide show
  1. package/bin/installer.js +69 -133
  2. package/package.json +1 -1
package/bin/installer.js CHANGED
@@ -3244,63 +3244,35 @@ 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" },
3251
- { name: "GitHub Copilot", value: "github-copilot" },
3252
- { name: "Cursor", value: "cursor" }
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
- },
3267
- {
3268
- id: "cap-developer",
3269
- name: "CAP Developer",
3270
- description: "Backend development with SAP Cloud Application Programming model",
3271
- domains: ["CAP"],
3272
- mcpServers: ["azure-devops", "context7", "cds-mcp"]
3273
- },
3274
- {
3275
- id: "abap-developer",
3276
- name: "ABAP Developer",
3277
- description: "ABAP and SAP backend development",
3278
- domains: ["ABAP"],
3279
- mcpServers: ["azure-devops", "context7", "abap", "sap-researcher"]
3280
- },
3281
- {
3282
- id: "btp-developer",
3283
- name: "BTP Developer",
3284
- description: "SAP Business Technology Platform development",
3285
- domains: ["BTP"],
3286
- mcpServers: ["azure-devops", "context7"]
3287
- },
3288
- {
3289
- id: "sap-dm-developer",
3290
- name: "SAP Digital Manufacturing Developer",
3291
- description: "SAP Digital Manufacturing development",
3292
- domains: ["SAP_DM"],
3293
- mcpServers: ["azure-devops", "context7"]
3294
- },
3295
- {
3296
- id: "forms-developer",
3297
- name: "Forms Developer",
3298
- description: "SAP Forms development",
3299
- domains: ["FORMS"],
3300
- mcpServers: ["azure-devops", "context7"]
3247
+ // src/utils/data/fetch-wizard-options.ts
3248
+ var GITHUB_REPO = "DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client";
3249
+ async function fetchWizardOptions(token) {
3250
+ try {
3251
+ const headers = {
3252
+ "Accept": "application/vnd.github+json",
3253
+ "Authorization": `Bearer ${token}`
3254
+ };
3255
+ const releaseRes = await fetch(
3256
+ `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`,
3257
+ { headers }
3258
+ );
3259
+ if (!releaseRes.ok) return null;
3260
+ const release = await releaseRes.json();
3261
+ const asset = release.assets?.find((a) => a.name === "wizard-options.json");
3262
+ if (!asset) return null;
3263
+ const assetRes = await fetch(asset.url, {
3264
+ headers: { ...headers, "Accept": "application/octet-stream" }
3265
+ });
3266
+ if (!assetRes.ok) return null;
3267
+ const data = await assetRes.json();
3268
+ if (!Array.isArray(data.agents) || !Array.isArray(data.personas?.personas)) {
3269
+ return null;
3301
3270
  }
3302
- ]
3303
- };
3271
+ return data;
3272
+ } catch {
3273
+ return null;
3274
+ }
3275
+ }
3304
3276
 
3305
3277
  // src/utils/data/fetch-contexts.ts
3306
3278
  var import_fs2 = require("fs");
@@ -3463,12 +3435,12 @@ async function getGitHubToken() {
3463
3435
  }
3464
3436
 
3465
3437
  // src/utils/data/fetch-contexts.ts
3466
- var GITHUB_REPO = "DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client";
3438
+ var GITHUB_REPO2 = "DLW-INT-SAP-DEV/DBE_DLWR_AI_WORKSPACE_SETUP_client";
3467
3439
  var MAX_RETRIES = 3;
3468
3440
  var RETRY_DELAY_MS = 2e3;
3469
3441
  var MIN_FILE_SIZE = 1024;
3470
3442
  async function fetchContexts(options = {}) {
3471
- const { domains = [], targetDir = process.cwd(), force = false } = options;
3443
+ const { domains = [], targetDir = process.cwd(), force = false, token } = options;
3472
3444
  const result = {
3473
3445
  successful: [],
3474
3446
  failed: [],
@@ -3479,9 +3451,9 @@ async function fetchContexts(options = {}) {
3479
3451
  return result;
3480
3452
  }
3481
3453
  await checkPrerequisites();
3482
- const githubToken = await getGitHubToken();
3454
+ const githubToken = token ?? await getGitHubToken();
3483
3455
  try {
3484
- const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO}/releases/latest`;
3456
+ const releaseUrl = `https://api.github.com/repos/${GITHUB_REPO2}/releases/latest`;
3485
3457
  const headers = {
3486
3458
  "Accept": "application/vnd.github+json",
3487
3459
  "Authorization": `Bearer ${githubToken}`
@@ -3656,56 +3628,6 @@ function mergeDirectories(source, target) {
3656
3628
  // src/utils/setup/setup-mcp.ts
3657
3629
  var import_fs3 = require("fs");
3658
3630
  var import_path3 = require("path");
3659
-
3660
- // data/wizard-options/mcp-servers.json
3661
- var mcp_servers_default = {
3662
- "azure-devops": {
3663
- command: "npx",
3664
- args: ["-y", "@azure-devops/mcp", "__AZURE_ORG__"],
3665
- description: "Access Azure DevOps work items, boards, pipelines and repositories",
3666
- useWhen: "User asks about work items, sprints, pipelines, pull requests or Azure DevOps tasks"
3667
- },
3668
- context7: {
3669
- type: "stdio",
3670
- command: "npx",
3671
- args: ["-y", "@upstash/context7-mcp"],
3672
- description: "Fetch up-to-date library and framework documentation",
3673
- useWhen: "User asks how something works in a specific library or framework (e.g. 'how does X work in SAPUI5?')"
3674
- },
3675
- "@ui5/mcp-server": {
3676
- type: "stdio",
3677
- command: "npx",
3678
- args: ["@ui5/mcp-server"],
3679
- description: "SAPUI5-specific tooling for views, controllers, manifest and OData",
3680
- useWhen: "User asks to create or modify SAPUI5 views, controllers, fragments or manifest.json"
3681
- },
3682
- playwright: {
3683
- command: "npx",
3684
- args: ["@playwright/mcp@latest"],
3685
- description: "Browser automation and end-to-end testing",
3686
- useWhen: "User asks to write or run browser tests, or automate browser interactions"
3687
- },
3688
- "cds-mcp": {
3689
- command: "npx",
3690
- args: ["-y", "@cap-js/mcp-server"],
3691
- description: "SAP CAP/CDS tooling for service definitions, handlers and CQL",
3692
- useWhen: "User asks about CAP services, CDS models, handlers or CQL queries"
3693
- },
3694
- abap: {
3695
- type: "http",
3696
- url: "http://localhost:5001/mcp",
3697
- description: "ABAP development assistant for SAP backend development",
3698
- useWhen: "User asks about ABAP code, RAP objects, CDS views or SAP backend logic"
3699
- },
3700
- "sap-researcher": {
3701
- command: "npx",
3702
- args: ["mcp-remote", "http://gsi-em-az1-0057/successormcp/mcp", "--allow-http"],
3703
- description: "Internal SAP knowledge base and documentation search",
3704
- useWhen: "User asks about SAP-specific topics, best practices or internal documentation"
3705
- }
3706
- };
3707
-
3708
- // src/utils/setup/setup-mcp.ts
3709
3631
  function getAgentMCPTarget(agent) {
3710
3632
  switch (agent) {
3711
3633
  case "claude-code":
@@ -3717,7 +3639,6 @@ function getAgentMCPTarget(agent) {
3717
3639
  return { filePath: ".vscode/mcp.json", rootKey: "servers", dir: ".vscode" };
3718
3640
  }
3719
3641
  }
3720
- var ALL_MCP_SERVERS = mcp_servers_default;
3721
3642
  async function setupMCPConfiguration(projectPath, mcpConfig, agent) {
3722
3643
  const target = getAgentMCPTarget(agent);
3723
3644
  const mcpJsonPath = (0, import_path3.join)(projectPath, target.filePath);
@@ -3743,7 +3664,7 @@ async function setupMCPConfiguration(projectPath, mcpConfig, agent) {
3743
3664
  if (mergedServers[serverName]) {
3744
3665
  skippedServers.push(serverName);
3745
3666
  } else {
3746
- const { description, useWhen, ...mcpFields } = serverConfig;
3667
+ const { description, useWhen, active, ...mcpFields } = serverConfig;
3747
3668
  mergedServers[serverName] = mcpFields;
3748
3669
  addedServers.push(serverName);
3749
3670
  }
@@ -3752,17 +3673,17 @@ async function setupMCPConfiguration(projectPath, mcpConfig, agent) {
3752
3673
  (0, import_fs3.writeFileSync)(mcpJsonPath, JSON.stringify(outputFile, null, 2), "utf-8");
3753
3674
  return { addedServers, skippedServers };
3754
3675
  }
3755
- function buildMCPConfiguration(selectedItems, baseMcpServers2) {
3676
+ function buildMCPConfiguration(selectedItems, baseMcpServers, allMcpServers) {
3756
3677
  const config = {};
3757
- for (const serverName of baseMcpServers2) {
3758
- if (ALL_MCP_SERVERS[serverName]) {
3759
- config[serverName] = ALL_MCP_SERVERS[serverName];
3678
+ for (const serverName of baseMcpServers) {
3679
+ if (allMcpServers[serverName]) {
3680
+ config[serverName] = allMcpServers[serverName];
3760
3681
  }
3761
3682
  }
3762
3683
  for (const item of selectedItems) {
3763
3684
  for (const serverName of item.mcpServers) {
3764
- if (ALL_MCP_SERVERS[serverName] && !config[serverName]) {
3765
- config[serverName] = ALL_MCP_SERVERS[serverName];
3685
+ if (allMcpServers[serverName] && !config[serverName]) {
3686
+ config[serverName] = allMcpServers[serverName];
3766
3687
  }
3767
3688
  }
3768
3689
  }
@@ -3892,9 +3813,21 @@ ${body}`;
3892
3813
  }
3893
3814
 
3894
3815
  // src/utils/mod.ts
3895
- var personas = personas_default.personas;
3896
- var baseMcpServers = personas_default.baseMcpServers;
3897
- var agents = agents_default.agents;
3816
+ async function loadWizardOptions(token) {
3817
+ const remote = await fetchWizardOptions(token);
3818
+ if (!remote) {
3819
+ throw new Error("Failed to load configuration from GitHub release. Check your network and token.");
3820
+ }
3821
+ const filteredMcpServers = Object.fromEntries(
3822
+ Object.entries(remote.mcpServers).filter(([, config]) => config.active !== false)
3823
+ );
3824
+ return {
3825
+ personas: remote.personas.personas.filter((p) => p.active !== false),
3826
+ agents: remote.agents.filter((a) => a.active !== false),
3827
+ baseMcpServers: remote.personas.baseMcpServers,
3828
+ mcpServers: filteredMcpServers
3829
+ };
3830
+ }
3898
3831
 
3899
3832
  // src/index.ts
3900
3833
  function getInstructionFilePath(agent) {
@@ -3938,18 +3871,21 @@ async function main() {
3938
3871
  console.clear();
3939
3872
  console.log("One-Shot Setup Installer\n");
3940
3873
  try {
3941
- const config = await collectInputs();
3874
+ const token = await getGitHubToken();
3875
+ console.log(" Loading configuration...");
3876
+ const options = await loadWizardOptions(token);
3877
+ const config = await collectInputs(options);
3942
3878
  if (!config) {
3943
3879
  await waitForEnter();
3944
3880
  return;
3945
3881
  }
3946
- const proceed = await previewAndConfirm(config);
3882
+ const proceed = await previewAndConfirm(config, options);
3947
3883
  if (!proceed) {
3948
3884
  console.log("\nNo changes made.");
3949
3885
  await waitForEnter();
3950
3886
  return;
3951
3887
  }
3952
- const result = await execute(config);
3888
+ const result = await execute(config, token);
3953
3889
  printSummary(result);
3954
3890
  return;
3955
3891
  } catch (error) {
@@ -3957,22 +3893,22 @@ async function main() {
3957
3893
  await waitForEnter();
3958
3894
  }
3959
3895
  }
3960
- async function collectInputs() {
3896
+ async function collectInputs(options) {
3961
3897
  const selectedIds = await esm_default2({
3962
3898
  message: "Personas:",
3963
3899
  instructions: " Space to select \xB7 Enter to confirm",
3964
- choices: personas.map((p) => ({
3900
+ choices: options.personas.map((p) => ({
3965
3901
  name: p.name.replace(/ Developer$/, ""),
3966
3902
  value: p.id
3967
3903
  })),
3968
3904
  required: true
3969
3905
  });
3970
- const selectedPersonas = personas.filter((p) => selectedIds.includes(p.id));
3906
+ const selectedPersonas = options.personas.filter((p) => selectedIds.includes(p.id));
3971
3907
  const agent = await esm_default5({
3972
3908
  message: "AI coding tool:",
3973
- choices: agents
3909
+ choices: options.agents
3974
3910
  });
3975
- const mcpConfig = buildMCPConfiguration(selectedPersonas, baseMcpServers);
3911
+ const mcpConfig = buildMCPConfiguration(selectedPersonas, options.baseMcpServers, options.mcpServers);
3976
3912
  let azureDevOpsOrg = "";
3977
3913
  if (mcpConfig["azure-devops"]) {
3978
3914
  const org = await esm_default4({
@@ -3999,9 +3935,9 @@ async function collectInputs() {
3999
3935
  mcpConfig
4000
3936
  };
4001
3937
  }
4002
- async function previewAndConfirm(config) {
3938
+ async function previewAndConfirm(config, options) {
4003
3939
  const personaNames = config.personas.map((p) => p.name.replace(/ Developer$/, "")).join(", ");
4004
- const agentDisplay = agents.find((a) => a.value === config.agent)?.name ?? config.agent;
3940
+ const agentDisplay = options.agents.find((a) => a.value === config.agent)?.name ?? config.agent;
4005
3941
  const instructionFile = getInstructionFilePath(config.agent);
4006
3942
  const mcpConfigFile = getMCPConfigPath(config.agent);
4007
3943
  const serverEntries = Object.entries(config.mcpConfig);
@@ -4029,7 +3965,7 @@ async function previewAndConfirm(config) {
4029
3965
  console.log("\n" + "\u2500".repeat(48));
4030
3966
  return esm_default3({ message: "Proceed?", default: true });
4031
3967
  }
4032
- async function execute(config) {
3968
+ async function execute(config, token) {
4033
3969
  const instructionFilePath = getInstructionFilePath(config.agent);
4034
3970
  const mcpConfigPath = getMCPConfigPath(config.agent);
4035
3971
  const result = {
@@ -4048,7 +3984,7 @@ async function execute(config) {
4048
3984
  const domainValues = uniqueDomains.map((d) => d.toLowerCase());
4049
3985
  console.log(` Downloading contexts...`);
4050
3986
  try {
4051
- const downloadResult = await fetchContexts({ domains: domainValues });
3987
+ const downloadResult = await fetchContexts({ domains: domainValues, token });
4052
3988
  result.domainsInstalled = downloadResult.successful;
4053
3989
  result.domainsFailed = downloadResult.failed;
4054
3990
  result.failureReasons = downloadResult.failureReasons;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dlw-machine-setup",
3
- "version": "0.2.6",
3
+ "version": "0.3.1",
4
4
  "description": "One-shot installer for The Machine toolchain",
5
5
  "bin": {
6
6
  "dlw-machine-setup": "bin/installer.js"