imcp 0.1.8 → 0.1.10

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 (88) hide show
  1. package/README.md +9 -4
  2. package/dist/cli/commands/list.js +1 -1
  3. package/dist/cli/commands/list.js.map +1 -1
  4. package/dist/cli/commands/pull.js +1 -1
  5. package/dist/cli/commands/pull.js.map +1 -1
  6. package/dist/cli/commands/serve.js +1 -1
  7. package/dist/cli/commands/serve.js.map +1 -1
  8. package/dist/cli/commands/uninstall.js +1 -1
  9. package/dist/cli/commands/uninstall.js.map +1 -1
  10. package/dist/cli/index.js +1 -1
  11. package/dist/cli/index.js.map +1 -1
  12. package/dist/core/installers/clients/BaseClientInstaller.js +1 -1
  13. package/dist/core/installers/clients/BaseClientInstaller.js.map +1 -1
  14. package/dist/core/installers/clients/ClientInstaller.js +1 -1
  15. package/dist/core/installers/clients/ClientInstaller.js.map +1 -1
  16. package/dist/core/installers/requirements/CommandInstaller.js +1 -1
  17. package/dist/core/installers/requirements/CommandInstaller.js.map +1 -1
  18. package/dist/core/installers/requirements/GeneralInstaller.js +1 -1
  19. package/dist/core/installers/requirements/GeneralInstaller.js.map +1 -1
  20. package/dist/core/installers/requirements/NugetInstaller.js +1 -1
  21. package/dist/core/installers/requirements/NugetInstaller.js.map +1 -1
  22. package/dist/core/installers/requirements/PipInstaller.js +1 -1
  23. package/dist/core/installers/requirements/PipInstaller.js.map +1 -1
  24. package/dist/core/loaders/ConfigurationLoader.js +1 -1
  25. package/dist/core/loaders/ConfigurationLoader.js.map +1 -1
  26. package/dist/core/loaders/ConfigurationProvider.d.ts +1 -1
  27. package/dist/core/loaders/ConfigurationProvider.js +1 -1
  28. package/dist/core/loaders/ConfigurationProvider.js.map +1 -1
  29. package/dist/core/loaders/InstallOperationManager.js +1 -1
  30. package/dist/core/loaders/InstallOperationManager.js.map +1 -1
  31. package/dist/core/loaders/SystemSettingsManager.js +1 -1
  32. package/dist/core/loaders/SystemSettingsManager.js.map +1 -1
  33. package/dist/core/onboard/FeedOnboardService.js +1 -1
  34. package/dist/core/onboard/FeedOnboardService.js.map +1 -1
  35. package/dist/core/onboard/OnboardStatusManager.js +1 -1
  36. package/dist/core/onboard/OnboardStatusManager.js.map +1 -1
  37. package/dist/core/validators/StdioServerValidator.js +1 -1
  38. package/dist/core/validators/StdioServerValidator.js.map +1 -1
  39. package/dist/services/InstallationService.js +1 -1
  40. package/dist/services/InstallationService.js.map +1 -1
  41. package/dist/services/MCPManager.d.ts +1 -1
  42. package/dist/services/MCPManager.js +1 -1
  43. package/dist/services/MCPManager.js.map +1 -1
  44. package/dist/services/RequirementService.js +1 -1
  45. package/dist/services/RequirementService.js.map +1 -1
  46. package/dist/services/ServerService.js +1 -1
  47. package/dist/services/ServerService.js.map +1 -1
  48. package/dist/services/TelemetryService.js +1 -1
  49. package/dist/services/TelemetryService.js.map +1 -1
  50. package/dist/utils/UpdateCheckTracker.js +1 -1
  51. package/dist/utils/UpdateCheckTracker.js.map +1 -1
  52. package/dist/utils/adoUtils.js +1 -1
  53. package/dist/utils/adoUtils.js.map +1 -1
  54. package/dist/utils/clientUtils.js +1 -1
  55. package/dist/utils/clientUtils.js.map +1 -1
  56. package/dist/utils/feedUtils.js +1 -1
  57. package/dist/utils/feedUtils.js.map +1 -1
  58. package/dist/utils/gitUtils.d.ts +15 -0
  59. package/dist/utils/gitUtils.js +2 -0
  60. package/dist/utils/gitUtils.js.map +1 -0
  61. package/dist/utils/logger.js +1 -1
  62. package/dist/utils/logger.js.map +1 -1
  63. package/dist/utils/macroExpressionUtils.js +1 -1
  64. package/dist/utils/macroExpressionUtils.js.map +1 -1
  65. package/dist/utils/osUtils.js +1 -1
  66. package/dist/utils/osUtils.js.map +1 -1
  67. package/dist/utils/versionUtils.js +1 -1
  68. package/dist/utils/versionUtils.js.map +1 -1
  69. package/dist/web/public/js/api.js +1 -1
  70. package/dist/web/public/js/detailsWidget.js +1 -1
  71. package/dist/web/public/js/flights/flights.js +1 -1
  72. package/dist/web/public/js/modal/installModal.js +1 -1
  73. package/dist/web/public/js/modal/installation.js +1 -1
  74. package/dist/web/public/js/modal/loadingModal.js +1 -1
  75. package/dist/web/public/js/modal/modalSetup.js +1 -1
  76. package/dist/web/public/js/modal.js +1 -1
  77. package/dist/web/public/js/notifications.js +1 -1
  78. package/dist/web/public/js/onboard/formProcessor.js +1 -1
  79. package/dist/web/public/js/onboard/index.js +1 -1
  80. package/dist/web/public/js/onboard/publishHandler.js +1 -1
  81. package/dist/web/public/js/onboard/uiHandlers.js +1 -1
  82. package/dist/web/public/js/onboard/validationHandlers.js +1 -1
  83. package/dist/web/public/js/serverCategoryDetails.js +1 -1
  84. package/dist/web/public/js/serverCategoryList.js +1 -1
  85. package/dist/web/public/js/settings.js +1 -1
  86. package/dist/web/server.js +1 -1
  87. package/dist/web/server.js.map +1 -1
  88. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"names":["fs","path","fileURLToPath","axios","Logger","COLORS","reset","yellow","PACKAGE_NAME","getPackageVersion","process","env","npm_package_version","packageName","packageVersion","currentDir","dirname","url","i","packagePath","join","existsSync","JSON","parse","readFileSync","version","error","compareVersions","v1","v2","v1Parts","split","map","Number","v2Parts","Math","max","length","v1Part","v2Part","async","checkForUpdates","debug","getAppVersion","availableUpdate","Error","message","String","npmResponse","get","data","latest","latestVersion","npmError","name"],"sources":["../../src/utils/versionUtils.ts"],"mappings":"OAAOA,OAAQ,YACRC,SAAU,cACRC,kBAAqB,aACvBC,UAAW,eACTC,WAAc,cAGvB,MAAMC,OAAS,CACbC,MAAO,OACPC,OAAQ,SAGJC,aAAe,cAEf,SAAUC,oBACd,IAEE,GAAIC,QAAQC,IAAIC,oBACd,MAAO,CAAEC,YANM,OAMqBC,eAAgBJ,QAAQC,IAAIC,qBAQlE,IAAIG,EAHcd,KAAKe,QAAQd,0BAA0Be,MAIzD,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMC,EAAclB,KAAKmB,KAAKL,EAAY,gBAC1C,GAAIf,GAAGqB,WAAWF,GAEhB,MAAO,CAAEN,YAnBI,OAmBuBC,eADhBQ,KAAKC,MAAMvB,GAAGwB,aAAaL,EAAa,SACIM,SAElEV,EAAad,KAAKmB,KAAKL,EAAY,KACrC,CAEA,MAAO,CAAEF,YAxBQ,OAwBmBC,eAAgB,UACtD,CAAE,MAAOY,GAEP,MAAO,CAAEb,YA3BQ,OA2BmBC,eAAgB,UACtD,CACF,QAcM,SAAUa,gBAAgBC,EAAYC,GAC1C,MAAMC,EAAUF,EAAGG,MAAM,KAAKC,IAAIC,QAC5BC,EAAUL,EAAGE,MAAM,KAAKC,IAAIC,QAElC,IAAK,IAAIf,EAAI,EAAGA,EAAIiB,KAAKC,IAAIN,EAAQO,OAAQH,EAAQG,QAASnB,IAAK,CACjE,MAAMoB,EAASpB,EAAIY,EAAQO,OAASP,EAAQZ,GAAK,EAC3CqB,EAASrB,EAAIgB,EAAQG,OAASH,EAAQhB,GAAK,EAEjD,GAAIoB,IAAWC,EAGb,OAAOD,EAASC,CAEpB,CAEA,OAAO,CACT,QAKOC,eAAeC,kBACpBrC,OAAOsC,MAAM,2BACb,WACwBC,iBACVC,eAKd,CAAE,MAAOlB,GAEPtB,OAAOsC,MAAM,iCAAiChB,aAAiBmB,MAAQnB,EAAMoB,QAAUC,OAAOrB,KAChG,CACF,QAMOc,eAAeG,gBACpB,IAAIC,EAEJ,MAAM/B,YAAEA,EAAWC,eAAEA,GAAmBL,oBAExC,IACE,MAAMuC,QAAoB7C,MAAM8C,IAAI,8BAA8BpC,KAClE,GAAImC,EAAYE,MAAQF,EAAYE,KAAK,cAAgBF,EAAYE,KAAK,aAAaC,OAAQ,CAC7F,MAAMC,EAAgBJ,EAAYE,KAAK,aAAaC,OAChDxB,gBAAgByB,EAAetC,GAAkB,IACnD8B,EAAkB,CAAEQ,gBAAeN,QAAS,gBAAgBM,2CAAuDvC,oBAEvH,CACF,CAAE,MAAOwC,GACPjD,OAAOsC,MAAM,+CAA+C7B,MAAgBwC,aAAoBR,MAAQQ,EAASP,QAAUC,OAAOM,KACpI,CAEA,MAAO,CAAEC,KAAMzC,EAAaY,QAASX,EAAgB8B,kBACvD","ignoreList":[]}
1
+ {"version":3,"names":["fs","path","fileURLToPath","axios","Logger","COLORS","reset","yellow","PACKAGE_NAME","getPackageVersion","process","env","npm_package_version","packageName","packageVersion","currentDir","dirname","url","i","packagePath","join","existsSync","JSON","parse","readFileSync","version","error","console","compareVersions","v1","v2","v1Parts","split","map","Number","v2Parts","Math","max","length","v1Part","v2Part","async","checkForUpdates","debug","getAppVersion","availableUpdate","log","name","latestVersion","Error","message","String","npmResponse","get","data","latest","npmError"],"sources":["../../src/utils/versionUtils.ts"],"mappings":"OAAOA,OAAQ,YACRC,SAAU,cACRC,kBAAqB,aACvBC,UAAW,eACTC,WAAc,cAGvB,MAAMC,OAAS,CACbC,MAAO,OACPC,OAAQ,SAGJC,aAAe,cAEf,SAAUC,oBACd,IAEE,GAAIC,QAAQC,IAAIC,oBACd,MAAO,CAAEC,YANM,OAMqBC,eAAgBJ,QAAQC,IAAIC,qBAQlE,IAAIG,EAHcd,KAAKe,QAAQd,0BAA0Be,MAIzD,IAAK,IAAIC,EAAI,EAAGA,EAAI,EAAGA,IAAK,CAC1B,MAAMC,EAAclB,KAAKmB,KAAKL,EAAY,gBAC1C,GAAIf,GAAGqB,WAAWF,GAAc,CAE9B,MAAO,CAAEN,YAnBI,OAmBuBC,eADhBQ,KAAKC,MAAMvB,GAAGwB,aAAaL,EAAa,SACIM,QAClE,CACAV,EAAad,KAAKmB,KAAKL,EAAY,KACrC,CAEA,MAAO,CAAEF,YAxBQ,OAwBmBC,eAAgB,UACtD,CAAE,MAAOY,GAEP,OADAC,QAAQD,MAAM,iCAAkCA,GACzC,CAAEb,YA3BQ,OA2BmBC,eAAgB,UACtD,CACF,QAcM,SAAUc,gBAAgBC,EAAYC,GAC1C,MAAMC,EAAUF,EAAGG,MAAM,KAAKC,IAAIC,QAC5BC,EAAUL,EAAGE,MAAM,KAAKC,IAAIC,QAElC,IAAK,IAAIhB,EAAI,EAAGA,EAAIkB,KAAKC,IAAIN,EAAQO,OAAQH,EAAQG,QAASpB,IAAK,CACjE,MAAMqB,EAASrB,EAAIa,EAAQO,OAASP,EAAQb,GAAK,EAC3CsB,EAAStB,EAAIiB,EAAQG,OAASH,EAAQjB,GAAK,EAEjD,GAAIqB,IAAWC,EAGb,OAAOD,EAASC,CAEpB,CAEA,OAAO,CACT,QAKOC,eAAeC,kBACpBtC,OAAOuC,MAAM,2BACb,IACE,MAAMlB,QAAgBmB,gBAClBnB,EAAQoB,kBACVlB,QAAQmB,IAAI,GAAGzC,OAAOE,8BAA8BkB,EAAQsB,SAAStB,EAAQA,aAAaA,EAAQoB,gBAAgBG,gBAAgB3C,OAAOC,SACzIqB,QAAQmB,IAAI,GAAGzC,OAAOE,gCAAgCkB,EAAQsB,+DAA+DtB,EAAQsB,gBAAgB1C,OAAOC,SAGhK,CAAE,MAAOoB,GAEPtB,OAAOuC,MAAM,iCAAiCjB,aAAiBuB,MAAQvB,EAAMwB,QAAUC,OAAOzB,KAChG,CACF,QAMOe,eAAeG,gBACpB,IAAIC,EAEJ,MAAMhC,YAAEA,EAAWC,eAAEA,GAAmBL,oBAExC,IACE,MAAM2C,QAAoBjD,MAAMkD,IAAI,8BAA8BxC,KAClE,GAAIuC,EAAYE,MAAQF,EAAYE,KAAK,cAAgBF,EAAYE,KAAK,aAAaC,OAAQ,CAC7F,MAAMP,EAAgBI,EAAYE,KAAK,aAAaC,OAChD3B,gBAAgBoB,EAAelC,GAAkB,IACnD+B,EAAkB,CAAEG,gBAAeE,QAAS,gBAAgBF,2CAAuDnC,oBAEvH,CACF,CAAE,MAAO2C,GACPpD,OAAOuC,MAAM,+CAA+C9B,MAAgB2C,aAAoBP,MAAQO,EAASN,QAAUC,OAAOK,KACpI,CAEA,MAAO,CAAET,KAAMlC,EAAaY,QAASX,EAAgB+B,kBACvD","ignoreList":[]}
@@ -1,2 +1,2 @@
1
- import{renderServerCategoryList}from"./serverCategoryList.js";import{showToast}from"./notifications.js";let allServerCategoriesData=[];async function fetchServerCategories(){try{const e=await fetch("/api/categories");if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const t=await e.json();if(!t.success||!t.data)throw new Error(`API Error fetching servers: ${t.error||"Invalid data format"}`);allServerCategoriesData=window.allServerCategoriesData=t.data,renderServerCategoryList(allServerCategoriesData);const r=document.getElementById("searchBox").value.toLowerCase();if(r){const e=allServerCategoriesData.filter((e=>(e.displayName||e.name).toLowerCase().includes(r)||(e.description||"").toLowerCase().includes(r)));renderServerCategoryList(e)}}catch(e){document.getElementById("serverCategoryList").innerHTML='<p class="text-red-600">Error loading servers. Please check console and try again.</p>',document.getElementById("serverCategoryDetails").innerHTML=""}}async function handleInstallServer(e,t,r,a,o={}){e.preventDefault();const s=o.targets||[...document.querySelectorAll('input[name="targets"]:checked')].map((e=>e.value));if(0===s.length)return void showToast("Please select at least one target","error");const n=e.target,i=new FormData(n),l={};i.forEach(((e,t)=>{!t.startsWith("targets")&&e&&(l[t]=e)}));try{const e={};e[r]={env:l,targetClients:s};const a=await fetch(`/api/categories/${t}/install`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverList:e})});if(!a.ok){const e=await a.text();throw new Error(`Installation failed: ${e||a.statusText}`)}showToast('MCP server "'+r+'" for '+t+" installation initiated successfully!","success"),window.closeModal(),fetchServerCategories(),window.showServerDetails(t)}catch(e){showToast("Error installing MCP server: "+e.message+". Please check console.","error")}}async function uninstallTool(e){const t=document.querySelector("#serverCategoryDetails h3")?.textContent;if(t){if(await showConfirm(`Do you want to uninstall tool '${e}' from ${t}?`))try{const r=await fetch(`/api/categories/${t}/uninstall-tool`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({toolName:e})});if(!r.ok){const e=await r.text();throw new Error(`Uninstall failed: ${e||r.statusText}`)}showToast(`Tool '${e}' uninstall initiated successfully!`,"success"),fetchServerCategories(),window.showServerDetails(t)}catch(e){showToast(`Error uninstalling tool: ${e.message}`,"error")}}else showToast("No server selected.","error")}window.allServerCategoriesData=allServerCategoriesData;export{allServerCategoriesData,fetchServerCategories,handleInstallServer,uninstallTool};
1
+ import{renderServerCategoryList}from"./serverCategoryList.js";import{showToast}from"./notifications.js";let allServerCategoriesData=[];async function fetchServerCategories(){try{const e=await fetch("/api/categories");if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const t=await e.json();if(!t.success||!t.data)throw new Error(`API Error fetching servers: ${t.error||"Invalid data format"}`);allServerCategoriesData=window.allServerCategoriesData=t.data,renderServerCategoryList(allServerCategoriesData);const r=document.getElementById("searchBox").value.toLowerCase();if(r){const e=allServerCategoriesData.filter((e=>(e.displayName||e.name).toLowerCase().includes(r)||(e.description||"").toLowerCase().includes(r)));renderServerCategoryList(e)}}catch(e){console.error("Error fetching servers:",e),document.getElementById("serverCategoryList").innerHTML='<p class="text-red-600">Error loading servers. Please check console and try again.</p>',document.getElementById("serverCategoryDetails").innerHTML=""}}async function handleInstallServer(e,t,r,o,a={}){e.preventDefault(),console.log("Handling install for:",t,r);const s=a.targets||[...document.querySelectorAll('input[name="targets"]:checked')].map((e=>e.value));if(0===s.length)return void showToast("Please select at least one target","error");const n=e.target,i=new FormData(n),l={};i.forEach(((e,t)=>{!t.startsWith("targets")&&e&&(l[t]=e)}));try{const e={};e[r]={env:l,targetClients:s};const o=await fetch(`/api/categories/${t}/install`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverList:e})});if(!o.ok){const e=await o.text();throw new Error(`Installation failed: ${e||o.statusText}`)}showToast('MCP server "'+r+'" for '+t+" installation initiated successfully!","success"),window.closeModal(),fetchServerCategories(),window.showServerDetails(t)}catch(e){console.error("Error installing MCP server:",e),showToast("Error installing MCP server: "+e.message+". Please check console.","error")}}async function uninstallTool(e){const t=document.querySelector("#serverCategoryDetails h3")?.textContent;if(!t)return void showToast("No server selected.","error");if(await showConfirm(`Do you want to uninstall tool '${e}' from ${t}?`))try{const r=await fetch(`/api/categories/${t}/uninstall-tool`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({toolName:e})});if(!r.ok){const e=await r.text();throw new Error(`Uninstall failed: ${e||r.statusText}`)}showToast(`Tool '${e}' uninstall initiated successfully!`,"success"),fetchServerCategories(),window.showServerDetails(t)}catch(e){console.error("Error uninstalling tool:",e),showToast(`Error uninstalling tool: ${e.message}`,"error")}}window.allServerCategoriesData=allServerCategoriesData;export{allServerCategoriesData,fetchServerCategories,handleInstallServer,uninstallTool};
2
2
  //# sourceMappingURL=api.js.map
@@ -1,2 +1,2 @@
1
- export class DetailsWidget{constructor(e){this.container=e,this.isExpanded=!1,this.expandedTool=null,this.init()}init(){const e=document.createElement("link");e.rel="stylesheet",e.href="/css/detailsWidget.css",document.head.appendChild(e),this.containerWrapper=document.createElement("div"),this.containerWrapper.className="details-widget-container",this.containerWrapper.style.width="100%",this.containerWrapper.style.boxSizing="border-box",this.containerWrapper.style.maxWidth="100%",this.containerWrapper.style.overflow="hidden",this.widgetElement=document.createElement("div"),this.widgetElement.className="details-widget",this.widgetElement.style.width="100%",this.widgetElement.style.boxSizing="border-box",this.widgetElement.style.maxWidth="100%",this.contentElement=document.createElement("div"),this.contentElement.className="details-widget-content",this.contentElement.style.width="100%",this.contentElement.style.boxSizing="border-box",this.widgetElement.appendChild(this.contentElement),this.containerWrapper.appendChild(this.widgetElement),this.container.after(this.containerWrapper)}setContent(e){if("string"!=typeof e)if("object"!=typeof e)this.contentElement.innerHTML="<p>Invalid content format</p>";else{const t=e.schema||e;this.renderToolsList(t)}else this.contentElement.innerHTML=`\n <div class="description-text">\n ${e||"No description available."}\n </div>\n `}toggle(){this.isExpanded?this.collapse():this.expand()}expand(){this.isExpanded=!0,this.widgetElement.classList.add("expanded");const e=this.container.offsetWidth;this.containerWrapper.style.width=`${e}px`,this.containerWrapper.style.maxWidth="100%",this.containerWrapper.style.display="block",this.container&&this.container.classList.add("expanded")}collapse(){this.isExpanded=!1,this.widgetElement.classList.remove("expanded"),this.container&&this.container.classList.remove("expanded"),this.expandedTool=null}renderToolsList(e){if(!e||"object"!=typeof e)return void(this.contentElement.innerHTML="<p>Invalid schema format</p>");let t='\n <div class="tools-list">\n ';Object.entries(e).forEach((([e,s])=>{s&&(t+=`<div class="tool-card" data-tool="${this.escapeHtml(e)}">\n <div class="tool-card-header">\n <div class="tool-header">\n <h3 class="text-md font-semibold text-blue-600">${s.name||e}</h3>\n <div class="text-gray-600 text-sm">${s.description||"No description available"}</div>\n </div>\n </div>\n <div class="tool-details hidden" data-tool-details="${this.escapeHtml(e)}">\n ${this.renderInputSchema(s.inputSchema)}\n </div>\n </div>\n `)})),t+="\n </div>\n ",this.contentElement.innerHTML=t,this.contentElement.querySelectorAll(".tool-card").forEach((e=>{e.querySelector(".tool-card-header").addEventListener("click",(t=>{t.stopPropagation();const s=e.dataset.tool;this.toggleToolDetails(s,e)})),e.querySelector(".tool-details").addEventListener("click",(e=>{e.stopPropagation()}))}))}toggleToolDetails(e,t){const s=t.querySelector(`[data-tool-details="${e}"]`),i=!s.classList.contains("hidden");if(this.expandedTool&&this.expandedTool!==e){const e=this.contentElement.querySelector(`[data-tool="${this.expandedTool}"]`);if(e){const t=e.querySelector(`[data-tool-details="${this.expandedTool}"]`);t?.classList.add("hidden"),e.classList.remove("active"),setTimeout((()=>{t.classList.remove("visible")}),0)}}i?(s.classList.remove("visible"),t.classList.remove("active"),setTimeout((()=>{s.classList.add("hidden")}),300),this.expandedTool=null):(s.classList.remove("hidden"),t.classList.add("active"),setTimeout((()=>{s.classList.add("visible")}),0),this.expandedTool=e,s.scrollIntoView({behavior:"smooth",block:"nearest"}))}renderInputSchema(e){if(!e||"object"!=typeof e)return"<p>No input schema available</p>";if(!e.properties||0===Object.keys(e.properties).length)return"<p>No input properties defined</p>";let t='<div class="properties-list">';try{return Object.entries(e.properties).forEach((([s,i])=>{if(!i)return;const n=e.required?.includes(s),a=this.getPropertyType(i);t+=`<div class="property-item ${n?"required":""}">\n <div class="property-header">\n <span class="property-name">${this.escapeHtml(s)}${n?'<span class="required-star">*</span>':""}</span><span class="property-type">${this.escapeHtml(a)}</span>${i.description?`<span class="property-desc">${this.escapeHtml(i.description)}</span>`:""}\n ${void 0!==i.default?`<div class="property-default">Default: <code>${this.escapeHtml(JSON.stringify(i.default))}</code></div>`:""}\n </div>\n ${this.renderNestedProperties(i)}\n </div>\n `})),t+"</div>"}catch(e){return"<p>Error rendering input schema</p>"}}renderNestedProperties(e){if(e.properties){let t='<div class="nested-properties">';return Object.entries(e.properties).forEach((([e,s])=>{const i=this.getPropertyType(s);t+=`\n <div class="nested-property-item">\n <span class="property-name">${this.escapeHtml(e)}</span><span class="property-type">${this.escapeHtml(i)}</span>\n ${s.description?`<div class="property-desc">${this.escapeHtml(s.description)}</div>`:""}\n </div>\n `})),t+"</div>"}return""}getPropertyType(e){return e.anyOf?`oneOf: [${e.anyOf.map((e=>e.type||"any")).join(", ")}]`:"array"===e.type?`array<${e.items?.type||"any"}>`:e.type||"any"}escapeHtml(e){return null==e?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}isVisible(){return this.isExpanded}}
1
+ export class DetailsWidget{constructor(e){this.container=e,this.isExpanded=!1,this.expandedTool=null,this.init()}init(){const e=document.createElement("link");e.rel="stylesheet",e.href="/css/detailsWidget.css",document.head.appendChild(e),this.containerWrapper=document.createElement("div"),this.containerWrapper.className="details-widget-container",this.containerWrapper.style.width="100%",this.containerWrapper.style.boxSizing="border-box",this.containerWrapper.style.maxWidth="100%",this.containerWrapper.style.overflow="hidden",this.widgetElement=document.createElement("div"),this.widgetElement.className="details-widget",this.widgetElement.style.width="100%",this.widgetElement.style.boxSizing="border-box",this.widgetElement.style.maxWidth="100%",this.contentElement=document.createElement("div"),this.contentElement.className="details-widget-content",this.contentElement.style.width="100%",this.contentElement.style.boxSizing="border-box",this.widgetElement.appendChild(this.contentElement),this.containerWrapper.appendChild(this.widgetElement),this.container.after(this.containerWrapper)}setContent(e){if("string"!=typeof e)if("object"!=typeof e)this.contentElement.innerHTML="<p>Invalid content format</p>";else{const t=e.schema||e;this.renderToolsList(t)}else this.contentElement.innerHTML=`\n <div class="description-text">\n ${e||"No description available."}\n </div>\n `}toggle(){this.isExpanded?this.collapse():this.expand()}expand(){this.isExpanded=!0,this.widgetElement.classList.add("expanded");const e=this.container.offsetWidth;this.containerWrapper.style.width=`${e}px`,this.containerWrapper.style.maxWidth="100%",this.containerWrapper.style.display="block",this.container&&this.container.classList.add("expanded")}collapse(){this.isExpanded=!1,this.widgetElement.classList.remove("expanded"),this.container&&this.container.classList.remove("expanded"),this.expandedTool=null}renderToolsList(e){if(!e||"object"!=typeof e)return void(this.contentElement.innerHTML="<p>Invalid schema format</p>");let t='\n <div class="tools-list">\n ';Object.entries(e).forEach((([e,s])=>{s&&(t+=`<div class="tool-card" data-tool="${this.escapeHtml(e)}">\n <div class="tool-card-header">\n <div class="tool-header">\n <h3 class="text-md font-semibold text-blue-600">${s.name||e}</h3>\n <div class="text-gray-600 text-sm">${s.description||"No description available"}</div>\n </div>\n </div>\n <div class="tool-details hidden" data-tool-details="${this.escapeHtml(e)}">\n ${this.renderInputSchema(s.inputSchema)}\n </div>\n </div>\n `)})),t+="\n </div>\n ",this.contentElement.innerHTML=t,this.contentElement.querySelectorAll(".tool-card").forEach((e=>{e.querySelector(".tool-card-header").addEventListener("click",(t=>{t.stopPropagation();const s=e.dataset.tool;this.toggleToolDetails(s,e)}));e.querySelector(".tool-details").addEventListener("click",(e=>{e.stopPropagation()}))}))}toggleToolDetails(e,t){const s=t.querySelector(`[data-tool-details="${e}"]`),i=!s.classList.contains("hidden");if(this.expandedTool&&this.expandedTool!==e){const e=this.contentElement.querySelector(`[data-tool="${this.expandedTool}"]`);if(e){const t=e.querySelector(`[data-tool-details="${this.expandedTool}"]`);t?.classList.add("hidden"),e.classList.remove("active"),setTimeout((()=>{t.classList.remove("visible")}),0)}}i?(s.classList.remove("visible"),t.classList.remove("active"),setTimeout((()=>{s.classList.add("hidden")}),300),this.expandedTool=null):(s.classList.remove("hidden"),t.classList.add("active"),setTimeout((()=>{s.classList.add("visible")}),0),this.expandedTool=e,s.scrollIntoView({behavior:"smooth",block:"nearest"}))}renderInputSchema(e){if(!e||"object"!=typeof e)return"<p>No input schema available</p>";if(!e.properties||0===Object.keys(e.properties).length)return"<p>No input properties defined</p>";let t='<div class="properties-list">';try{return Object.entries(e.properties).forEach((([s,i])=>{if(!i)return;const n=e.required?.includes(s),r=this.getPropertyType(i);t+=`<div class="property-item ${n?"required":""}">\n <div class="property-header">\n <span class="property-name">${this.escapeHtml(s)}${n?'<span class="required-star">*</span>':""}</span><span class="property-type">${this.escapeHtml(r)}</span>${i.description?`<span class="property-desc">${this.escapeHtml(i.description)}</span>`:""}\n ${void 0!==i.default?`<div class="property-default">Default: <code>${this.escapeHtml(JSON.stringify(i.default))}</code></div>`:""}\n </div>\n ${this.renderNestedProperties(i)}\n </div>\n `})),t+"</div>"}catch(e){return console.error("Error rendering input schema:",e),"<p>Error rendering input schema</p>"}}renderNestedProperties(e){if(e.properties){let t='<div class="nested-properties">';return Object.entries(e.properties).forEach((([e,s])=>{const i=this.getPropertyType(s);t+=`\n <div class="nested-property-item">\n <span class="property-name">${this.escapeHtml(e)}</span><span class="property-type">${this.escapeHtml(i)}</span>\n ${s.description?`<div class="property-desc">${this.escapeHtml(s.description)}</div>`:""}\n </div>\n `})),t+"</div>"}return""}getPropertyType(e){if(e.anyOf)return`oneOf: [${e.anyOf.map((e=>e.type||"any")).join(", ")}]`;if("array"===e.type){return`array<${e.items?.type||"any"}>`}return e.type||"any"}escapeHtml(e){return null==e?"":String(e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}isVisible(){return this.isExpanded}}
2
2
  //# sourceMappingURL=detailsWidget.js.map
@@ -1,2 +1,2 @@
1
- const FLIGHT_STORAGE_KEY="activeFlightSettings",defaultFlights={enableOnboard:!0};let effectiveFlightSettings={};function initializeFlightSettings(){const t=new URLSearchParams(window.location.search);let e={},i=!1;for(const s in defaultFlights)if(t.has(s)){const l=t.get(s);e[s]="true"===l||"false"!==l&&l,i=!0}if(i){for(const t in defaultFlights)Object.hasOwnProperty.call(e,t)||(e[t]=defaultFlights[t]);try{sessionStorage.setItem(FLIGHT_STORAGE_KEY,JSON.stringify(e)),effectiveFlightSettings=e}catch(t){effectiveFlightSettings=e}}else try{const t=sessionStorage.getItem(FLIGHT_STORAGE_KEY);if(t){effectiveFlightSettings=JSON.parse(t);for(const t in defaultFlights)Object.hasOwnProperty.call(effectiveFlightSettings,t)||(effectiveFlightSettings[t]=defaultFlights[t])}else effectiveFlightSettings={...defaultFlights},sessionStorage.setItem(FLIGHT_STORAGE_KEY,JSON.stringify(effectiveFlightSettings))}catch(t){effectiveFlightSettings={...defaultFlights}}}initializeFlightSettings();const flights={};for(const t in defaultFlights)Object.hasOwnProperty.call(defaultFlights,t)&&Object.defineProperty(flights,t,{get:()=>void 0!==effectiveFlightSettings[t]?effectiveFlightSettings[t]:defaultFlights[t],enumerable:!0,configurable:!1});function _buildFlightParams(){const t=new URLSearchParams;for(const e in effectiveFlightSettings)Object.hasOwnProperty.call(effectiveFlightSettings,e)&&Object.hasOwnProperty.call(defaultFlights,e)&&t.set(e,String(effectiveFlightSettings[e]));return t}export function buildUrlWithFlights(t,e={}){const i=_buildFlightParams();for(const t in e)Object.hasOwnProperty.call(e,t)&&void 0!==e[t]&&i.set(t,e[t]);const s=i.toString();return`${t}${s?`?${s}`:""}`}export function getFlightQueryParameters(){const t=_buildFlightParams().toString();return t?`?${t}`:""}export default flights;
1
+ const FLIGHT_STORAGE_KEY="activeFlightSettings",defaultFlights={enableOnboard:!0};let effectiveFlightSettings={};function initializeFlightSettings(){const t=new URLSearchParams(window.location.search);let e={},i=!1;for(const s in defaultFlights)if(t.has(s)){const l=t.get(s);e[s]="true"===l||"false"!==l&&l,i=!0}if(i){for(const t in defaultFlights)Object.hasOwnProperty.call(e,t)||(e[t]=defaultFlights[t]);try{sessionStorage.setItem(FLIGHT_STORAGE_KEY,JSON.stringify(e)),effectiveFlightSettings=e}catch(t){console.error("Failed to write to sessionStorage:",t),effectiveFlightSettings=e}}else try{const t=sessionStorage.getItem(FLIGHT_STORAGE_KEY);if(t){effectiveFlightSettings=JSON.parse(t);for(const t in defaultFlights)Object.hasOwnProperty.call(effectiveFlightSettings,t)||(effectiveFlightSettings[t]=defaultFlights[t])}else effectiveFlightSettings={...defaultFlights},sessionStorage.setItem(FLIGHT_STORAGE_KEY,JSON.stringify(effectiveFlightSettings))}catch(t){console.error("Failed to read/write sessionStorage:",t),effectiveFlightSettings={...defaultFlights}}}initializeFlightSettings();const flights={};for(const t in defaultFlights)Object.hasOwnProperty.call(defaultFlights,t)&&Object.defineProperty(flights,t,{get:()=>void 0!==effectiveFlightSettings[t]?effectiveFlightSettings[t]:defaultFlights[t],enumerable:!0,configurable:!1});function _buildFlightParams(){const t=new URLSearchParams;for(const e in effectiveFlightSettings)Object.hasOwnProperty.call(effectiveFlightSettings,e)&&Object.hasOwnProperty.call(defaultFlights,e)&&t.set(e,String(effectiveFlightSettings[e]));return t}export function buildUrlWithFlights(t,e={}){const i=_buildFlightParams();for(const t in e)Object.hasOwnProperty.call(e,t)&&void 0!==e[t]&&i.set(t,e[t]);const s=i.toString();return`${t}${s?`?${s}`:""}`}export function getFlightQueryParameters(){const t=_buildFlightParams().toString();return t?`?${t}`:""}export default flights;
2
2
  //# sourceMappingURL=flights.js.map
@@ -1,2 +1,2 @@
1
- import{showToast,showConfirm}from"../notifications.js";import{compareVersions}from"./versionUtils.js";import{showInstallLoadingModal}from"./loadingModal.js";import{closeModal,setupToggleStyles}from"./modalUtils.js";import{handleBulkClientInstall,uninstallTools}from"./installation.js";import{setupClientItems,setupEnvironmentVariables,setupInstallationArguments,setupServerRequirements,setupFormSubmitHandler}from"./modalSetup.js";document.addEventListener("DOMContentLoaded",(()=>{setupToggleStyles()}));export async function showInstallModal(t,e,o){await new Promise((t=>setTimeout(t,100)));const n=document.getElementById("installModal");if(!n)return;const s=n.querySelector("#modalTitle"),a=n.querySelector("#modalEnvInputs"),l=n.querySelector("#modalTargets"),r=n.querySelector("#modalRequirements"),i=n.querySelector("#modalArguments");if(window.selectedClients=[],s&&a&&l&&r&&i){s.textContent=`Install ${e}`,a.innerHTML="",l.innerHTML="",r.innerHTML="",i.innerHTML="";try{const[o,n]=await Promise.all([fetch("/api/targets"),fetch(`/api/categories/${t}`)]);if(!o.ok||!n.ok)throw new Error("Failed to fetch required data");const[d,m]=await Promise.all([o.json(),n.json()]);if(!d.success||!m.success)throw new Error("Invalid data received");const u=m.data.feedConfiguration.mcpServers.find((t=>t.name===e));if(!u)throw new Error("Server configuration not found");const c=document.createElement("span");c.textContent=u.mode||"stdio",c.className="ml-2 px-2 py-0.5 text-xs bg-gray-200 text-gray-600 rounded",s.appendChild(c);const p=(m.data.installationStatus||{}).serversStatus||{},w=p[e]||{installedStatus:{}};await setupModalContent(d,u,w,t,e,p,m,l,a,i,r)}catch(t){l.innerHTML=`<p class="text-red-500">Error: ${t.message}</p>`}n.style.display="block"}}async function setupModalContent(t,e,o,n,s,a,l,r,i,d,m){setupClientItems(t.data,o,n,s,r),setupEnvironmentVariables(e,i,t),setupInstallationArguments(e.installation,d,n,e),setupServerRequirements(e,l,n,s,m);const u=document.getElementById("installForm");setupFormSubmitHandler(u,i,d,m,n,s,a,l,e)}window.showInstallModal=showInstallModal,window.closeModal=closeModal,window.uninstallTools=uninstallTools;
1
+ import{showToast,showConfirm}from"../notifications.js";import{compareVersions}from"./versionUtils.js";import{showInstallLoadingModal}from"./loadingModal.js";import{closeModal,setupToggleStyles}from"./modalUtils.js";import{handleBulkClientInstall,uninstallTools}from"./installation.js";import{setupClientItems,setupEnvironmentVariables,setupInstallationArguments,setupServerRequirements,setupFormSubmitHandler}from"./modalSetup.js";document.addEventListener("DOMContentLoaded",(()=>{setupToggleStyles()}));export async function showInstallModal(e,t,o){console.log("Showing install modal for:",t),await new Promise((e=>setTimeout(e,100)));const n=document.getElementById("installModal");if(!n)return void console.error("Modal container not found");const s=n.querySelector("#modalTitle"),l=n.querySelector("#modalEnvInputs"),a=n.querySelector("#modalTargets"),r=n.querySelector("#modalRequirements"),i=n.querySelector("#modalArguments");if(window.selectedClients=[],s&&l&&a&&r&&i){s.textContent=`Install ${t}`,l.innerHTML="",a.innerHTML="",r.innerHTML="",i.innerHTML="";try{const[o,n]=await Promise.all([fetch("/api/targets"),fetch(`/api/categories/${e}`)]);if(!o.ok||!n.ok)throw new Error("Failed to fetch required data");const[d,m]=await Promise.all([o.json(),n.json()]);if(!d.success||!m.success)throw new Error("Invalid data received");const u=m.data.feedConfiguration.mcpServers.find((e=>e.name===t));if(!u)throw new Error("Server configuration not found");const c=document.createElement("span");c.textContent=u.mode||"stdio",c.className="ml-2 px-2 py-0.5 text-xs bg-gray-200 text-gray-600 rounded",s.appendChild(c);const p=(m.data.installationStatus||{}).serversStatus||{},f=p[t]||{installedStatus:{}};await setupModalContent(d,u,f,e,t,p,m,a,l,i,r)}catch(e){console.error("Error loading data:",e),a.innerHTML=`<p class="text-red-500">Error: ${e.message}</p>`}n.style.display="block"}else console.error("Required modal elements not found")}async function setupModalContent(e,t,o,n,s,l,a,r,i,d,m){setupClientItems(e.data,o,n,s,r),setupEnvironmentVariables(t,i,e),setupInstallationArguments(t.installation,d,n,t),setupServerRequirements(t,a,n,s,m);const u=document.getElementById("installForm");setupFormSubmitHandler(u,i,d,m,n,s,l,a,t)}window.showInstallModal=showInstallModal,window.closeModal=closeModal,window.uninstallTools=uninstallTools;
2
2
  //# sourceMappingURL=installModal.js.map
@@ -1,2 +1,2 @@
1
- import{showInstallLoadingModal,updateOverallInstallStatus,addInstallationStep}from"./loadingModal.js";import{showToast}from"../notifications.js";export async function handleBulkClientInstall(t,a,e,s={},l="Starting installation...",n=null,o=null){const i=document.getElementById("installModal");if(i&&(i.style.display="none"),t&&localStorage.setItem("lastSelectedCategory",t),a&&localStorage.setItem("lastSelectedServerName",a),n?.data?.installationStatus?.serversStatus){const t=n.data.installationStatus.serversStatus[a]||{installedStatus:{}};if(e?.length>0){const a=e[0],s=t.installedStatus?.[a]?.message;s&&(l=s)}l&&"Starting installation..."!==l&&delayedAppendInstallLoadingMessage(l)}showInstallLoadingModal(`Installing ${a}`);try{const l={serverList:{[a]:o||{targetClients:e,env:s}}},n=await fetch(`/api/categories/${t}/install`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(l)});if(!n.ok){const t=await n.text();throw updateOverallInstallStatus("failed",`Installation request failed: ${t||n.statusText}`),new Error(`Installation failed: ${t||n.statusText}`)}const i=await n.json();if(!i.success)throw updateOverallInstallStatus("failed",i.error||"Installation operation failed to start."),new Error(i.error||"Installation failed");pollNewInstallStatus(t,a,2e3)}catch(t){updateOverallInstallStatus("failed",`Error: ${t.message}`)}}async function pollNewInstallStatus(t,a,e=2e3){let s=!1;const l=Date.now();for(;Date.now()-l<6e5&&!s;){try{const e=await fetch(`/api/categories/${t}/servers/${a}/installation/status`);if(e.ok){const t=await e.json();if(t.success&&t.data){const{steps:e,overallStatus:l,error:n}=t.data;if(updateOverallInstallStatus(l,n||`Installation ${l}`),e.forEach((t=>{addInstallationStep(t.name,t.message,t.status,t.timestamp)})),"completed"===l||"failed"===l)return s=!0,void updateOverallInstallStatus(l,"completed"===l?`Installation completed successfully for ${a}.`:`Installation failed for ${a}`)}else if(t.success||404!==e.status){if(!t.success)return updateOverallInstallStatus("failed",`Error fetching status: ${t.error||"Unknown error"}`),void(s=!0)}else updateOverallInstallStatus("in-progress",`Waiting for installation to start for ${a}...`)}else{if(404!==e.status){const t=await e.text();return updateOverallInstallStatus("failed",`Error fetching status: ${t||e.statusText}`),void(s=!0)}updateOverallInstallStatus("in-progress",`Installation status not yet available for ${a}. Retrying...`)}}catch(t){return updateOverallInstallStatus("failed",`Error polling status: ${t.message}`),void(s=!0)}await new Promise((t=>setTimeout(t,e)))}s||updateOverallInstallStatus("failed",`Operation timed out for ${a} - Please check logs or refresh.`)}export async function uninstallTools(t,a,e){t&&localStorage.setItem("lastSelectedCategory",t);const s=window.selectedClients||(Array.isArray(e)?e:[e]);if(s&&0!==s.length){"function"==typeof addInstallationStep&&addInstallationStep("Uninstalling",`Uninstallation process started for ${Object.keys(a).join(", ")}`,"in-progress",(new Date).toISOString()),updateOverallInstallStatus("in-progress",`Starting uninstallation for ${Object.keys(a).join(", ")}...`);try{Object.keys(a).forEach((t=>{localStorage.setItem("lastSelectedServerName",t)}));const e=await fetch(`/api/categories/${t}/uninstall`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverList:a,options:{targets:s,removeData:!0}})});if(!e.ok){const t=await e.text();throw updateOverallInstallStatus("failed",`Uninstallation request failed: ${t||e.statusText}`),new Error(`Uninstallation failed: ${t||e.statusText}`)}const l=await e.json();if(!l.success)throw updateOverallInstallStatus("failed",`Uninstallation failed: ${l.error||"Operation failed"}`),new Error(l.error||"Uninstallation failed");"function"==typeof addInstallationStep&&(await new Promise((t=>setTimeout(t,1e3))),addInstallationStep("Uninstalling",`Uninstallation process finished for ${Object.keys(a).join(", ")}`,"completed",(new Date).toISOString()),await new Promise((t=>setTimeout(t,1e3))),addInstallationStep("Uninstall Finished",`Uninstallation finished for ${Object.keys(a).join(", ")}`,"completed",(new Date).toISOString())),await new Promise((t=>setTimeout(t,1e3))),updateOverallInstallStatus("completed",`Successfully uninstalled from ${s.join(", ")}.`),window.selectedClients=[]}catch(t){const a=document.getElementById("overallStatusText");a&&a.textContent.startsWith("Starting uninstallation")&&updateOverallInstallStatus("failed",`Error uninstalling tools: ${t.message}`),showToast(`Error uninstalling tools: ${t.message}`,"error")}}else showToast("Please select at least one client to uninstall.","error")}
1
+ import{showInstallLoadingModal,updateOverallInstallStatus,addInstallationStep}from"./loadingModal.js";import{showToast}from"../notifications.js";export async function handleBulkClientInstall(t,a,e,l={},s="Starting installation...",n=null,o=null){console.log("[LoadingModal] handleBulkClientInstall called",{categoryName:t,serverName:a,targets:e,envVars:l,serverInstallOptions:o});const i=document.getElementById("installModal");if(console.log("[LoadingModal] installModal:",i),i&&(i.style.display="none"),t&&localStorage.setItem("lastSelectedCategory",t),a&&localStorage.setItem("lastSelectedServerName",a),n?.data?.installationStatus?.serversStatus){const t=n.data.installationStatus.serversStatus[a]||{installedStatus:{}};if(e?.length>0){const a=e[0],l=t.installedStatus?.[a]?.message;l&&(s=l)}s&&"Starting installation..."!==s&&delayedAppendInstallLoadingMessage(s)}showInstallLoadingModal(`Installing ${a}`);try{const s={serverList:{[a]:o||{targetClients:e,env:l}}},n=await fetch(`/api/categories/${t}/install`,{method:"POST",headers:{"Content-Type":"application/json",Accept:"application/json"},body:JSON.stringify(s)});if(console.log("[LoadingModal] fetch install response:",n),!n.ok){const t=await n.text();throw updateOverallInstallStatus("failed",`Installation request failed: ${t||n.statusText}`),console.error("[LoadingModal] Failed:",t||n.statusText),new Error(`Installation failed: ${t||n.statusText}`)}const i=await n.json();if(console.log("[LoadingModal] install result:",i),!i.success)throw updateOverallInstallStatus("failed",i.error||"Installation operation failed to start."),console.error("[LoadingModal] Error:",i.error||"Operation failed"),new Error(i.error||"Installation failed");pollNewInstallStatus(t,a,2e3)}catch(t){console.error("[LoadingModal] Error applying configuration:",t),updateOverallInstallStatus("failed",`Error: ${t.message}`)}}async function pollNewInstallStatus(t,a,e=2e3){let l=!1;const s=Date.now();for(;Date.now()-s<6e5&&!l;){try{const e=await fetch(`/api/categories/${t}/servers/${a}/installation/status`);if(e.ok){const t=await e.json();if(t.success&&t.data){const{steps:e,overallStatus:s,error:n}=t.data;if(updateOverallInstallStatus(s,n||`Installation ${s}`),e.forEach((t=>{addInstallationStep(t.name,t.message,t.status,t.timestamp)})),"completed"===s||"failed"===s){l=!0;return void updateOverallInstallStatus(s,"completed"===s?`Installation completed successfully for ${a}.`:`Installation failed for ${a}`)}}else if(t.success||404!==e.status){if(!t.success)return updateOverallInstallStatus("failed",`Error fetching status: ${t.error||"Unknown error"}`),void(l=!0)}else updateOverallInstallStatus("in-progress",`Waiting for installation to start for ${a}...`)}else{if(404!==e.status){const t=await e.text();return updateOverallInstallStatus("failed",`Error fetching status: ${t||e.statusText}`),void(l=!0)}updateOverallInstallStatus("in-progress",`Installation status not yet available for ${a}. Retrying...`)}}catch(t){return console.error("[LoadingModal] Error polling new install status:",t),updateOverallInstallStatus("failed",`Error polling status: ${t.message}`),void(l=!0)}await new Promise((t=>setTimeout(t,e)))}l||updateOverallInstallStatus("failed",`Operation timed out for ${a} - Please check logs or refresh.`)}export async function uninstallTools(t,a,e){console.log("[LoadingModal] uninstallTools called",{categoryName:t,serverList:a,targets:e}),t&&(console.log("[LoadingModal] Setting lastSelectedCategory:",t),localStorage.setItem("lastSelectedCategory",t));const l=window.selectedClients||(Array.isArray(e)?e:[e]);if(l&&0!==l.length){"function"==typeof addInstallationStep&&addInstallationStep("Uninstalling",`Uninstallation process started for ${Object.keys(a).join(", ")}`,"in-progress",(new Date).toISOString()),updateOverallInstallStatus("in-progress",`Starting uninstallation for ${Object.keys(a).join(", ")}...`);try{Object.keys(a).forEach((t=>{console.log("[LoadingModal] Setting lastSelectedServerName:",t),localStorage.setItem("lastSelectedServerName",t)}));const e=await fetch(`/api/categories/${t}/uninstall`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({serverList:a,options:{targets:l,removeData:!0}})});if(!e.ok){const t=await e.text();throw updateOverallInstallStatus("failed",`Uninstallation request failed: ${t||e.statusText}`),new Error(`Uninstallation failed: ${t||e.statusText}`)}const s=await e.json();if(!s.success)throw updateOverallInstallStatus("failed",`Uninstallation failed: ${s.error||"Operation failed"}`),new Error(s.error||"Uninstallation failed");"function"==typeof addInstallationStep&&(await new Promise((t=>setTimeout(t,1e3))),addInstallationStep("Uninstalling",`Uninstallation process finished for ${Object.keys(a).join(", ")}`,"completed",(new Date).toISOString()),await new Promise((t=>setTimeout(t,1e3))),addInstallationStep("Uninstall Finished",`Uninstallation finished for ${Object.keys(a).join(", ")}`,"completed",(new Date).toISOString())),await new Promise((t=>setTimeout(t,1e3))),updateOverallInstallStatus("completed",`Successfully uninstalled from ${l.join(", ")}.`),window.selectedClients=[]}catch(t){console.error("Error uninstalling tools:",t);const a=document.getElementById("overallStatusText");a&&a.textContent.startsWith("Starting uninstallation")&&updateOverallInstallStatus("failed",`Error uninstalling tools: ${t.message}`),showToast(`Error uninstalling tools: ${t.message}`,"error")}}else showToast("Please select at least one client to uninstall.","error")}
2
2
  //# sourceMappingURL=installation.js.map
@@ -1,2 +1,2 @@
1
- const ICONS={IN_PROGRESS:'<div class="status-spinner"></div>',COMPLETED:'<div class="status-icon-circled icon-check-container"><span class="status-icon icon-check">✓</span></div>',FAILED:'<span class="status-icon icon-cross">✗</span>',CANCELED:'<span class="status-icon icon-minus">–</span>'};let overallStatusIconEl,overallStatusTextEl,installStepDetailsListEl;export function showInstallLoadingModal(t="Installing"){const l=document.getElementById("installLoadingModal"),s=l?l.querySelector(".modal-content"):null;if(l&&s){s.innerHTML=`\n <button id="installLoadingModalCloseBtn" class="modal-close-btn">&times;</button>\n <div class="installation-status-header">\n <div id="overallStatusIconContainer" class="overall-status-icon">\n ${ICONS.IN_PROGRESS}\n </div>\n <h3 id="overallStatusText" class="overall-status-text">${t}...</h3>\n </div>\n <div class="installation-steps-container">\n <ul id="installStepDetailsList" class="install-step-details-list"></ul>\n </div>\n `,overallStatusIconEl=s.querySelector("#overallStatusIconContainer"),overallStatusTextEl=s.querySelector("#overallStatusText"),installStepDetailsListEl=s.querySelector("#installStepDetailsList");const e=s.querySelector("#installLoadingModalCloseBtn");e&&e.addEventListener("click",hideInstallLoadingModal),l.style.display="block"}}export function updateOverallInstallStatus(t,l){if(!overallStatusIconEl||!overallStatusTextEl)return;let s=ICONS.IN_PROGRESS,e="in-progress";switch(t){case"completed":s=ICONS.COMPLETED,e="completed";break;case"failed":s=ICONS.FAILED,e="failed"}overallStatusIconEl.innerHTML=s,overallStatusIconEl.className=`overall-status-icon ${e}`,overallStatusTextEl.textContent=l||t.charAt(0).toUpperCase()+t.slice(1)}export function addInstallationStep(t,l,s,e){if(!installStepDetailsListEl)return;const a=`install-step-${t.replace(/[^a-zA-Z0-9_-]/g,"_")}`;let n=document.getElementById(a),i="",o="";switch(s){case"completed":i="success",o='<span class="step-icon icon-check-small">✓</span>';break;case"failed":i="error",o='<span class="step-icon icon-cross-small">✗</span>';break;case"canceled":i="canceled",o='<span class="step-icon icon-minus-small">–</span>';break;default:i="in-progress",o='<div class="status-spinner step-spinner"></div>'}let c="";if(e)try{c=new Date(e).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}catch(t){}const d=`\n ${o}\n <div class="step-info">\n <span class="step-name">${t}</span>\n <span class="step-message">${l||("completed"===s?"Completed":"failed"===s?"Failed":"canceled"===s?"Canceled":"In Progress")}</span>\n </div>\n <span class="step-timestamp">${c}</span>\n `;n?(n.className=`step-detail-item ${i}`,n.innerHTML=d):(n=document.createElement("li"),n.id=a,n.className=`step-detail-item ${i}`,n.innerHTML=d,installStepDetailsListEl.appendChild(n),installStepDetailsListEl.scrollTop=installStepDetailsListEl.scrollHeight)}export function hideInstallLoadingModal(){const t=document.getElementById("installLoadingModal");t&&(t.style.display="none",overallStatusIconEl=null,overallStatusTextEl=null,installStepDetailsListEl=null,document.dispatchEvent(new CustomEvent("refreshMainModalContent")))}
1
+ const ICONS={IN_PROGRESS:'<div class="status-spinner"></div>',COMPLETED:'<div class="status-icon-circled icon-check-container"><span class="status-icon icon-check">✓</span></div>',FAILED:'<span class="status-icon icon-cross">✗</span>',CANCELED:'<span class="status-icon icon-minus">–</span>'};let overallStatusIconEl,overallStatusTextEl,installStepDetailsListEl;export function showInstallLoadingModal(t="Installing"){const l=document.getElementById("installLoadingModal"),e=l?l.querySelector(".modal-content"):null;if(l&&e){e.innerHTML=`\n <button id="installLoadingModalCloseBtn" class="modal-close-btn">&times;</button>\n <div class="installation-status-header">\n <div id="overallStatusIconContainer" class="overall-status-icon">\n ${ICONS.IN_PROGRESS}\n </div>\n <h3 id="overallStatusText" class="overall-status-text">${t}...</h3>\n </div>\n <div class="installation-steps-container">\n <ul id="installStepDetailsList" class="install-step-details-list"></ul>\n </div>\n `,overallStatusIconEl=e.querySelector("#overallStatusIconContainer"),overallStatusTextEl=e.querySelector("#overallStatusText"),installStepDetailsListEl=e.querySelector("#installStepDetailsList");const s=e.querySelector("#installLoadingModalCloseBtn");s&&s.addEventListener("click",hideInstallLoadingModal),l.style.display="block"}else console.error("[LoadingModal] Required elements not found: #installLoadingModal or .modal-content")}export function updateOverallInstallStatus(t,l){if(!overallStatusIconEl||!overallStatusTextEl)return;let e=ICONS.IN_PROGRESS,s="in-progress";switch(t){case"completed":e=ICONS.COMPLETED,s="completed";break;case"failed":e=ICONS.FAILED,s="failed"}overallStatusIconEl.innerHTML=e,overallStatusIconEl.className=`overall-status-icon ${s}`,overallStatusTextEl.textContent=l||t.charAt(0).toUpperCase()+t.slice(1)}export function addInstallationStep(t,l,e,s){if(!installStepDetailsListEl)return;const a=`install-step-${t.replace(/[^a-zA-Z0-9_-]/g,"_")}`;let n=document.getElementById(a),o="",i="";switch(e){case"completed":o="success",i='<span class="step-icon icon-check-small">✓</span>';break;case"failed":o="error",i='<span class="step-icon icon-cross-small">✗</span>';break;case"canceled":o="canceled",i='<span class="step-icon icon-minus-small">–</span>';break;default:o="in-progress",i='<div class="status-spinner step-spinner"></div>'}let c="";if(s)try{c=new Date(s).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit",hour12:!1})}catch(t){}const d=`\n ${i}\n <div class="step-info">\n <span class="step-name">${t}</span>\n <span class="step-message">${l||("completed"===e?"Completed":"failed"===e?"Failed":"canceled"===e?"Canceled":"In Progress")}</span>\n </div>\n <span class="step-timestamp">${c}</span>\n `;n?(n.className=`step-detail-item ${o}`,n.innerHTML=d):(n=document.createElement("li"),n.id=a,n.className=`step-detail-item ${o}`,n.innerHTML=d,installStepDetailsListEl.appendChild(n),installStepDetailsListEl.scrollTop=installStepDetailsListEl.scrollHeight)}export function hideInstallLoadingModal(){console.log("[LoadingModal] Hiding installation modal");const t=document.getElementById("installLoadingModal");t?(t.style.display="none",overallStatusIconEl=null,overallStatusTextEl=null,installStepDetailsListEl=null,document.dispatchEvent(new CustomEvent("refreshMainModalContent")),console.log("[LoadingModal] Dispatched refreshMainModalContent event.")):console.error("[LoadingModal] loading modal DOM not found")}
2
2
  //# sourceMappingURL=loadingModal.js.map
@@ -1,2 +1,2 @@
1
- import{showToast,showConfirm}from"../notifications.js";import{showInstallLoadingModal,updateOverallInstallStatus}from"./loadingModal.js";import{uninstallTools}from"./installation.js";import{handleBulkClientInstall}from"./installation.js";import{compareVersions}from"./versionUtils.js";export function setupClientItems(e,t,n,s,a){e.forEach((e=>{const l=t.installedStatus[e]||{status:"not-installed",type:"check",target:"server"};let i="",o="";"completed"===l.status&&"install"===l.type?(i="Installed",o="installed"):"pending"===l.status?(i="Pending Requirements",o="pending"):"in-progress"===l.status?(i="In Progress",o="pending"):"failed"===l.status&&(i="Failed",o="not-installed");const r="completed"===l.status&&"install"===l.type,d="in-progress"===l.status,c=!r&&!d,m=createClientItem(e,i,o,c,r,d);setupClientItemListeners(m,e,c),setupUninstallButton(m,i,l,e,n,s,o),a.appendChild(m)})),addSectionTitle(a)}export function setupEnvironmentVariables(e,t,n){if("sse"===e.mode)return void(t.style.display="none");const s=e.installation?.env||e.installation?.env||{};addEnvironmentTitle(t),fetch("/api/settings").then((e=>e.json())).then((a=>{const l=a&&a.data&&a.data.userConfigurations?a.data.userConfigurations:{};0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,l)})).catch((()=>{0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,{})}))}export function setupInstallationArguments(e,t,n,s){if("sse"===s?.mode)return void(t.style.display="none");if(!e)return;addArgumentsTitle(t);const a=createArgumentsContainer();t.appendChild(a),e.args&&Array.isArray(e.args)?e.args.forEach((e=>{a.appendChild(createArgumentInput(e))})):a.appendChild(createArgumentInput()),("python"===e.command||e.command.includes("python"))&&addPythonEnvironmentInput(n,s.name,t)}export function setupServerRequirements(e,t,n,s,a){if("sse"===e.mode)return void(a.style.display="none");const l=e.dependencies?.requirements||[],i=t.data.installationStatus?.requirementsStatus||{};if(l.length>0){const e=renderRequirements(l,i,n,s);a.innerHTML=`\n <h3 class="text-lg font-semibold text-gray-700 mb-3">Dependencies</h3>\n <p class="text-sm text-gray-600 mb-4">These dependencies will be automatically installed when installing the server</p>\n ${e}\n `,setupUpdateToggles(a)}else a.innerHTML='<p class="text-gray-600">No additional dependencies required.</p>'}export function setupFormSubmitHandler(e,t,n,s,a,l,i,o,r){e.onsubmit=e=>{e.preventDefault();const d={},c=[],m=[];let u;if("sse"!==r?.mode){t.querySelectorAll("input").forEach((e=>{e.name&&e.value&&(d[e.name]=e.value)}));const e=n.querySelectorAll(".arg-input");c.push(...Array.from(e).map((e=>e.value.trim())).filter((e=>""!==e)));const a=document.getElementById("python_env");u=a?.value?.trim(),s.querySelectorAll(".toggle-update:checked").forEach((e=>{m.push({name:e.dataset.name,version:e.dataset.version})}))}function p(){const e=m.length>0,t=document.querySelector(".uninstall-btn");if(!t||!t.matches(":active")){const t=window.selectedClients;if(0===t.length&&!e)return void showToast("Please select at least one client to configure.","error");let n="Starting installation...";const s=i[l]||{installedStatus:{}};if(t.length>0){const e=t[0],a=s.installedStatus?.[e]?.message;a&&(n=a)}const r={targetClients:t,env:d,args:c,settings:u?{pythonEnv:u}:{}};m.length>0&&(r.requirements=m),handleBulkClientInstall(a,l,t,d,n,o,r)}}fetch("/api/settings").then((e=>e.json())).then((e=>{const t=e&&e.data&&e.data.userConfigurations?e.data.userConfigurations:{},n=e&&e.data&&e.data.pythonEnvs?e.data.pythonEnvs:{},s={...t},i={...n};Object.keys(d).forEach((e=>{s[e]=d[e]}));let o=!1;const r=new Set([...Object.keys(t),...Object.keys(d)]);for(const e of r)if(t[e]!==s[e]){o=!0;break}let c=!1;if(void 0!==u&&u!==n[`${a}:${l}`]&&(i[`${a}:${l}`]=u,c=!0),o||c){const e={};o&&(e.userConfigurations=s),c&&(e.pythonEnvs=i),fetch("/api/settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then((()=>{p()})).catch((()=>{p()}))}else p()})).catch((()=>{p()}))}}function createClientItem(e,t,n,s,a,l){const i=document.createElement("div");i.className="client-item",i.dataset.target=e,i.dataset.selected="false";const o=document.createElement("div");o.className="client-info";const r=document.createElement("span");return r.className="text-sm font-medium text-gray-900",r.textContent=e,o.appendChild(r),i.appendChild(o),s||(i.classList.add("non-selectable"),a?(i.classList.add("installed-item"),i.title="Already installed"):l&&(i.classList.add("in-progress-item"),i.title="Installation in progress")),i}function setupClientItemListeners(e,t,n){n&&e.addEventListener("click",(()=>{const n="true"===e.dataset.selected;e.dataset.selected=n?"false":"true",n?(e.classList.remove("selected"),window.selectedClients=window.selectedClients.filter((e=>e!==t))):(e.classList.add("selected"),window.selectedClients.includes(t)||window.selectedClients.push(t))}))}function setupUninstallButton(e,t,n,s,a,l,i){if(t){const o=document.createElement("div");o.className="status-container";const r=document.createElement("span");if(r.className=`status-badge ${i}`,r.textContent=t,o.appendChild(r),"completed"===n.status&&"install"===n.type){const e=createUninstallButton(s,a,l);o.appendChild(e)}e.appendChild(o)}}function createUninstallButton(e,t,n){const s=document.createElement("button");return s.className="uninstall-btn text-red-600 hover:text-red-800 ml-2",s.innerHTML='<i class="bx bx-trash"></i>',s.title="Uninstall from this client",s.onclick=async s=>{if(s.stopPropagation(),s.preventDefault(),await showConfirm("Uninstall Confirmation",`Are you sure you want to uninstall ${n} from ${e}?`)){window.selectedClients=[e],showInstallLoadingModal("Uninstalling");const s={[n]:{removeData:!0}};try{updateOverallInstallStatus("in-progress",`Uninstalling ${n} from ${e}...`),await uninstallTools(t,s,[e])}catch(e){updateOverallInstallStatus("failed",`Error during uninstall: ${e.message}`)}}return!1},s}function addSectionTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Client Status",e.insertBefore(t,e.firstChild)}}function addEnvironmentTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Environment Variables",e.insertBefore(t,e.firstChild)}}function addNoEnvMessage(e){const t=document.createElement("p");t.className="text-gray-600",t.textContent="No environment variables required for this MCP server.",e.appendChild(t)}function createEnvironmentInputs(e,t,n,s,a={}){Object.keys(e).forEach((l=>{const i=e[l],o=`env_${l}`,r=document.createElement("div");r.className="mb-3";const d=document.createElement("label");d.htmlFor=o,d.className="block text-sm font-medium text-gray-700 mb-1",d.innerHTML=`${l} ${i.Required?'<span class="text-red-500">*</span>':""}`;const c=document.createElement("input");c.type=i.isSecret?"password":"text",c.id=o,c.name=l,c.placeholder=i.Description||l,c.required=i.Required,c.className="input-field";let m=i.Default||"";if(a&&a[l]?m=a[l]:n&&n.MSRooCode&&n.MSRooCode.mcpServers&&n.MSRooCode.mcpServers[s]&&n.MSRooCode.mcpServers[s].env&&n.MSRooCode.mcpServers[s].env[l]&&(m=n.MSRooCode.mcpServers[s].env[l]),c.value=m,r.appendChild(d),r.appendChild(c),i.Description){const e=document.createElement("p");e.className="text-xs text-gray-500 mt-1",e.textContent=i.Description,r.appendChild(e)}t.appendChild(r)}))}function addArgumentsTitle(e){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Arguments",e.appendChild(t)}function createArgumentsContainer(){const e=document.createElement("div");e.className="args-container mb-3";const t=document.createElement("button");return t.type="button",t.className="add-arg-button px-3 py-1 text-sm text-blue-600 hover:text-blue-800 border border-blue-600 hover:border-blue-800 rounded-md mb-2",t.innerHTML='<i class="bx bx-plus"></i> Add Argument',t.onclick=()=>e.appendChild(createArgumentInput()),e.appendChild(t),e}function createArgumentInput(e=""){const t=document.createElement("div");t.className="arg-wrapper flex items-center gap-2 mb-2";const n=document.createElement("input");n.type="text",n.className="arg-input flex-grow",n.value=e,n.placeholder="Enter argument value";const s=document.createElement("button");return s.type="button",s.className="remove-arg-button text-red-600 hover:text-red-800",s.innerHTML='<i class="bx bx-trash"></i>',s.onclick=()=>t.remove(),t.appendChild(n),t.appendChild(s),t}function addPythonEnvironmentInput(e,t,n){const s=document.createElement("div");s.className="mt-4";const a=document.createElement("label");a.htmlFor="python_env",a.className="block text-sm font-medium text-gray-700 mb-1",a.textContent="Python Environment";const l=document.createElement("input");l.type="text",l.id="python_env",l.className="input-field",l.placeholder="Enter Python environment path (optional)";const i=document.createElement("p");i.className="text-xs text-gray-500 mt-1",i.textContent="Specify the Python exectable file(e.g. C:/python312/python) to use for installation. Leave empty to use system default. You can specify value in Settings page",s.appendChild(a),s.appendChild(l),s.appendChild(i),n.appendChild(s),fetch("/api/settings").then((e=>e.json())).then((n=>{n&&n.data&&n.data.pythonEnvs&&(l.value=n.data.pythonEnvs[`${e}:${t}`]||n.data.pythonEnvs.system||"")})).catch((()=>{}))}function renderRequirements(e,t,n,s){return e.map((e=>{const a=t[e.name]||{};let l=a.installed?"text-green-600 bg-green-50":"text-yellow-600 bg-yellow-50",i=a.installed?"Installed":"Required",o=a.version?` • <span class="font-medium">${a.version}</span>`:"",r="";return a.installed&&a.availableUpdate&&a.availableUpdate.version&&a.version&&compareVersions(a.availableUpdate.version,a.version)>0&&(l="text-yellow-600 bg-yellow-50",i=`<span style="color: #f59e0b; font-weight: bold; margin-right: 5px;">↑</span>${a.availableUpdate.version}`,r=`\n <label class="inline-flex items-center cursor-pointer ml-2">\n <input type="checkbox" class="toggle-update sr-only"\n data-name="${e.name}"\n data-version="${a.availableUpdate.version}"\n data-category="${n}"\n data-server="${s}">\n <div class="relative w-10 h-5 bg-gray-200 rounded-full toggle-bg">\n <div class="absolute inset-y-0 left-0 w-5 h-5 bg-white rounded-full transition-transform duration-300 transform"></div>\n </div>\n <span class="ml-2 text-sm text-gray-700">Update</span>\n </label>\n `),`\n <div class="border border-gray-200 p-3 rounded-lg mb-2 hover:bg-gray-50">\n <div class="flex justify-between items-center">\n <div>\n <div class="font-semibold text-gray-800">${e.name}</div>\n <div class="text-sm text-gray-600 shadow-sm p-1 rounded bg-gray-50">\n <span class="font-medium">${a.type||"package"}</span>${o}\n </div>\n </div>\n <div class="flex items-center">\n <span class="${l} inline-flex items-center px-3 py-1 rounded-full text-sm">\n ${i}\n </span>\n ${r}\n </div>\n </div>\n </div>\n `})).join("")}function setupUpdateToggles(e){e.querySelectorAll(".toggle-update").forEach((e=>{e.addEventListener("change",(function(){const e=this.parentElement.querySelector(".toggle-bg");this.checked?(e.classList.add("bg-blue-500"),e.querySelector("div").classList.add("translate-x-5")):(e.classList.remove("bg-blue-500"),e.querySelector("div").classList.remove("translate-x-5"))}))}))}
1
+ import{showToast,showConfirm}from"../notifications.js";import{showInstallLoadingModal,updateOverallInstallStatus}from"./loadingModal.js";import{uninstallTools}from"./installation.js";import{handleBulkClientInstall}from"./installation.js";import{compareVersions}from"./versionUtils.js";export function setupClientItems(e,t,n,s,a){e.forEach((e=>{const l=t.installedStatus[e]||{status:"not-installed",type:"check",target:"server"};let o="",i="";"completed"===l.status&&"install"===l.type?(o="Installed",i="installed"):"pending"===l.status?(o="Pending Requirements",i="pending"):"in-progress"===l.status?(o="In Progress",i="pending"):"failed"===l.status&&(o="Failed",i="not-installed");const r="completed"===l.status&&"install"===l.type,d="in-progress"===l.status,c=!r&&!d,m=createClientItem(e,o,i,c,r,d);setupClientItemListeners(m,e,c),setupUninstallButton(m,o,l,e,n,s,i),a.appendChild(m)})),addSectionTitle(a)}export function setupEnvironmentVariables(e,t,n){if("sse"===e.mode)return void(t.style.display="none");const s=e.installation?.env||e.installation?.env||{};addEnvironmentTitle(t),fetch("/api/settings").then((e=>e.json())).then((a=>{const l=a&&a.data&&a.data.userConfigurations?a.data.userConfigurations:{};0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,l)})).catch((()=>{0===Object.keys(s).length?addNoEnvMessage(t):createEnvironmentInputs(s,t,n.clientMcpSettings,e.name,{})}))}export function setupInstallationArguments(e,t,n,s){if("sse"===s?.mode)return void(t.style.display="none");if(!e)return;addArgumentsTitle(t);const a=createArgumentsContainer();t.appendChild(a),e.args&&Array.isArray(e.args)?e.args.forEach((e=>{a.appendChild(createArgumentInput(e))})):a.appendChild(createArgumentInput()),("python"===e.command||e.command.includes("python"))&&addPythonEnvironmentInput(n,s.name,t)}export function setupServerRequirements(e,t,n,s,a){if("sse"===e.mode)return void(a.style.display="none");const l=e.dependencies?.requirements||[],o=t.data.installationStatus?.requirementsStatus||{};if(l.length>0){const e=renderRequirements(l,o,n,s);a.innerHTML=`\n <h3 class="text-lg font-semibold text-gray-700 mb-3">Dependencies</h3>\n <p class="text-sm text-gray-600 mb-4">These dependencies will be automatically installed when installing the server</p>\n ${e}\n `,setupUpdateToggles(a)}else a.innerHTML='<p class="text-gray-600">No additional dependencies required.</p>'}export function setupFormSubmitHandler(e,t,n,s,a,l,o,i,r){e.onsubmit=e=>{e.preventDefault();const d={},c=[],m=[];let u;if("sse"!==r?.mode){t.querySelectorAll("input").forEach((e=>{e.name&&e.value&&(d[e.name]=e.value)}));const e=n.querySelectorAll(".arg-input");c.push(...Array.from(e).map((e=>e.value.trim())).filter((e=>""!==e)));const a=document.getElementById("python_env");u=a?.value?.trim();s.querySelectorAll(".toggle-update:checked").forEach((e=>{m.push({name:e.dataset.name,version:e.dataset.version})}))}function proceedInstall(){const e=m.length>0,t=document.querySelector(".uninstall-btn");if(!t||!t.matches(":active")){const t=window.selectedClients;if(0===t.length&&!e)return void showToast("Please select at least one client to configure.","error");let n="Starting installation...";const s=o[l]||{installedStatus:{}};if(t.length>0){const e=t[0],a=s.installedStatus?.[e]?.message;a&&(n=a)}const r={targetClients:t,env:d,args:c,settings:u?{pythonEnv:u}:{}};m.length>0&&(r.requirements=m),handleBulkClientInstall(a,l,t,d,n,i,r)}}fetch("/api/settings").then((e=>e.json())).then((e=>{const t=e&&e.data&&e.data.userConfigurations?e.data.userConfigurations:{},n=e&&e.data&&e.data.pythonEnvs?e.data.pythonEnvs:{},s={...t},o={...n};Object.keys(d).forEach((e=>{s[e]=d[e]}));let i=!1;const r=new Set([...Object.keys(t),...Object.keys(d)]);for(const e of r)if(t[e]!==s[e]){i=!0;break}let c=!1;if(void 0!==u&&u!==n[`${a}:${l}`]&&(o[`${a}:${l}`]=u,c=!0),i||c){const e={};i&&(e.userConfigurations=s),c&&(e.pythonEnvs=o),fetch("/api/settings",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}).then((()=>{proceedInstall()})).catch((()=>{proceedInstall()}))}else proceedInstall()})).catch((()=>{proceedInstall()}))}}function createClientItem(e,t,n,s,a,l){const o=document.createElement("div");o.className="client-item",o.dataset.target=e,o.dataset.selected="false";const i=document.createElement("div");i.className="client-info";const r=document.createElement("span");return r.className="text-sm font-medium text-gray-900",r.textContent=e,i.appendChild(r),o.appendChild(i),s||(o.classList.add("non-selectable"),a?(o.classList.add("installed-item"),o.title="Already installed"):l&&(o.classList.add("in-progress-item"),o.title="Installation in progress")),o}function setupClientItemListeners(e,t,n){n&&e.addEventListener("click",(()=>{const n="true"===e.dataset.selected;e.dataset.selected=n?"false":"true",n?(e.classList.remove("selected"),window.selectedClients=window.selectedClients.filter((e=>e!==t))):(e.classList.add("selected"),window.selectedClients.includes(t)||window.selectedClients.push(t))}))}function setupUninstallButton(e,t,n,s,a,l,o){if(t){const i=document.createElement("div");i.className="status-container";const r=document.createElement("span");if(r.className=`status-badge ${o}`,r.textContent=t,i.appendChild(r),"completed"===n.status&&"install"===n.type){const e=createUninstallButton(s,a,l);i.appendChild(e)}e.appendChild(i)}}function createUninstallButton(e,t,n){const s=document.createElement("button");return s.className="uninstall-btn text-red-600 hover:text-red-800 ml-2",s.innerHTML='<i class="bx bx-trash"></i>',s.title="Uninstall from this client",s.onclick=async s=>{s.stopPropagation(),s.preventDefault();if(await showConfirm("Uninstall Confirmation",`Are you sure you want to uninstall ${n} from ${e}?`)){window.selectedClients=[e],showInstallLoadingModal("Uninstalling");const s={[n]:{removeData:!0}};try{updateOverallInstallStatus("in-progress",`Uninstalling ${n} from ${e}...`),await uninstallTools(t,s,[e])}catch(e){updateOverallInstallStatus("failed",`Error during uninstall: ${e.message}`)}}return!1},s}function addSectionTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Client Status",e.insertBefore(t,e.firstChild)}}function addEnvironmentTitle(e){if(!e.querySelector(".section-title")){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Environment Variables",e.insertBefore(t,e.firstChild)}}function addNoEnvMessage(e){const t=document.createElement("p");t.className="text-gray-600",t.textContent="No environment variables required for this MCP server.",e.appendChild(t)}function createEnvironmentInputs(e,t,n,s,a={}){Object.keys(e).forEach((l=>{const o=e[l],i=`env_${l}`,r=document.createElement("div");r.className="mb-3";const d=document.createElement("label");d.htmlFor=i,d.className="block text-sm font-medium text-gray-700 mb-1",d.innerHTML=`${l} ${o.Required?'<span class="text-red-500">*</span>':""}`;const c=document.createElement("input");c.type=o.isSecret?"password":"text",c.id=i,c.name=l,c.placeholder=o.Description||l,c.required=o.Required,c.className="input-field";let m=o.Default||"";if(a&&a[l]?m=a[l]:n&&n.MSRooCode&&n.MSRooCode.mcpServers&&n.MSRooCode.mcpServers[s]&&n.MSRooCode.mcpServers[s].env&&n.MSRooCode.mcpServers[s].env[l]&&(m=n.MSRooCode.mcpServers[s].env[l]),c.value=m,r.appendChild(d),r.appendChild(c),o.Description){const e=document.createElement("p");e.className="text-xs text-gray-500 mt-1",e.textContent=o.Description,r.appendChild(e)}t.appendChild(r)}))}function addArgumentsTitle(e){const t=document.createElement("h3");t.className="section-title text-lg font-semibold text-gray-700 mb-3",t.textContent="Arguments",e.appendChild(t)}function createArgumentsContainer(){const e=document.createElement("div");e.className="args-container mb-3";const t=document.createElement("button");return t.type="button",t.className="add-arg-button px-3 py-1 text-sm text-blue-600 hover:text-blue-800 border border-blue-600 hover:border-blue-800 rounded-md mb-2",t.innerHTML='<i class="bx bx-plus"></i> Add Argument',t.onclick=()=>e.appendChild(createArgumentInput()),e.appendChild(t),e}function createArgumentInput(e=""){const t=document.createElement("div");t.className="arg-wrapper flex items-center gap-2 mb-2";const n=document.createElement("input");n.type="text",n.className="arg-input flex-grow",n.value=e,n.placeholder="Enter argument value";const s=document.createElement("button");return s.type="button",s.className="remove-arg-button text-red-600 hover:text-red-800",s.innerHTML='<i class="bx bx-trash"></i>',s.onclick=()=>t.remove(),t.appendChild(n),t.appendChild(s),t}function addPythonEnvironmentInput(e,t,n){const s=document.createElement("div");s.className="mt-4";const a=document.createElement("label");a.htmlFor="python_env",a.className="block text-sm font-medium text-gray-700 mb-1",a.textContent="Python Environment";const l=document.createElement("input");l.type="text",l.id="python_env",l.className="input-field",l.placeholder="Enter Python environment path (optional)";const o=document.createElement("p");o.className="text-xs text-gray-500 mt-1",o.textContent="Specify the Python exectable file(e.g. C:/python312/python) to use for installation. Leave empty to use system default. You can specify value in Settings page",s.appendChild(a),s.appendChild(l),s.appendChild(o),n.appendChild(s),fetch("/api/settings").then((e=>e.json())).then((n=>{n&&n.data&&n.data.pythonEnvs&&(l.value=n.data.pythonEnvs[`${e}:${t}`]||n.data.pythonEnvs.system||"")})).catch((()=>{}))}function renderRequirements(e,t,n,s){return e.map((e=>{const a=t[e.name]||{};let l=a.installed?"text-green-600 bg-green-50":"text-yellow-600 bg-yellow-50",o=a.installed?"Installed":"Required",i=a.version?` • <span class="font-medium">${a.version}</span>`:"",r="";return a.installed&&a.availableUpdate&&a.availableUpdate.version&&a.version&&compareVersions(a.availableUpdate.version,a.version)>0&&(l="text-yellow-600 bg-yellow-50",o=`<span style="color: #f59e0b; font-weight: bold; margin-right: 5px;">↑</span>${a.availableUpdate.version}`,r=`\n <label class="inline-flex items-center cursor-pointer ml-2">\n <input type="checkbox" class="toggle-update sr-only"\n data-name="${e.name}"\n data-version="${a.availableUpdate.version}"\n data-category="${n}"\n data-server="${s}">\n <div class="relative w-10 h-5 bg-gray-200 rounded-full toggle-bg">\n <div class="absolute inset-y-0 left-0 w-5 h-5 bg-white rounded-full transition-transform duration-300 transform"></div>\n </div>\n <span class="ml-2 text-sm text-gray-700">Update</span>\n </label>\n `),`\n <div class="border border-gray-200 p-3 rounded-lg mb-2 hover:bg-gray-50">\n <div class="flex justify-between items-center">\n <div>\n <div class="font-semibold text-gray-800">${e.name}</div>\n <div class="text-sm text-gray-600 shadow-sm p-1 rounded bg-gray-50">\n <span class="font-medium">${a.type||"package"}</span>${i}\n </div>\n </div>\n <div class="flex items-center">\n <span class="${l} inline-flex items-center px-3 py-1 rounded-full text-sm">\n ${o}\n </span>\n ${r}\n </div>\n </div>\n </div>\n `})).join("")}function setupUpdateToggles(e){e.querySelectorAll(".toggle-update").forEach((e=>{e.addEventListener("change",(function(){const e=this.parentElement.querySelector(".toggle-bg");this.checked?(e.classList.add("bg-blue-500"),e.querySelector("div").classList.add("translate-x-5")):(e.classList.remove("bg-blue-500"),e.querySelector("div").classList.remove("translate-x-5"))}))}))}
2
2
  //# sourceMappingURL=modalSetup.js.map
@@ -1,2 +1,2 @@
1
- import{showInstallModal,closeModal,uninstallTools,showInstallLoadingModal,hideInstallLoadingModal}from"./modal/index.js";export{showInstallModal,closeModal,uninstallTools,showInstallLoadingModal,hideInstallLoadingModal};window.showInstallModal=showInstallModal,window.showInstallLoadingModal=showInstallLoadingModal,window.hideInstallLoadingModal=hideInstallLoadingModal,document.addEventListener("refreshMainModalContent",(()=>{const l=localStorage.getItem("lastSelectedCategory"),o=localStorage.getItem("lastSelectedServerName"),a=l&&""!==l.trim()&&"undefined"!==l&&"null"!==l,d=o&&""!==o.trim()&&"undefined"!==o&&"null"!==o;a&&d&&window.showInstallModal(l,o)}));
1
+ import{showInstallModal,closeModal,uninstallTools,showInstallLoadingModal,hideInstallLoadingModal}from"./modal/index.js";export{showInstallModal,closeModal,uninstallTools,showInstallLoadingModal,hideInstallLoadingModal};window.showInstallModal=showInstallModal,window.showInstallLoadingModal=showInstallLoadingModal,window.hideInstallLoadingModal=hideInstallLoadingModal,document.addEventListener("refreshMainModalContent",(()=>{console.log("[ModalJS] Received refreshMainModalContent event. Refreshing main modal.");const l=localStorage.getItem("lastSelectedCategory"),o=localStorage.getItem("lastSelectedServerName"),a=l&&""!==l.trim()&&"undefined"!==l&&"null"!==l,e=o&&""!==o.trim()&&"undefined"!==o&&"null"!==o;a&&e?window.showInstallModal(l,o):console.warn(`[ModalJS] Not refreshing modal. Category valid: ${a} (value: "${l}"), ServerName valid: ${e} (value: "${o}")`)}));
2
2
  //# sourceMappingURL=modal.js.map
@@ -1,2 +1,2 @@
1
- function showToast(e,t="success"){const n=document.querySelector(".alert-container");if(!n)return;const o=`alert-${Date.now()}`;let i="";switch(t){case"success":i='<i class="bi bi-check-circle-fill alert-icon"></i>';break;case"error":i='<i class="bi bi-x-octagon-fill alert-icon"></i>';break;case"info":i='<i class="bi bi-info-circle-fill alert-icon"></i>';break;case"warning":i='<i class="bi bi-exclamation-triangle-fill alert-icon"></i>';break;default:i='<i class="bi bi-bell-fill alert-icon"></i>'}const s=`\n <div id="${o}" class="alert alert-${t}" role="alert">\n ${i}\n <span>${e}</span>\n <button type="button" class="btn-close" aria-label="Close"></button>\n </div>\n `;n.insertAdjacentHTML("beforeend",s);const a=document.getElementById(o);if(!a)return;requestAnimationFrame((()=>{requestAnimationFrame((()=>{a.classList.add("show")}))}));const l=a.querySelector(".btn-close"),r=()=>{a.classList.remove("show"),a.addEventListener("transitionend",(()=>{a.remove()}),{once:!0})};l&&l.addEventListener("click",r),setTimeout(r,5e3)}function showConfirm(e,t){return new Promise((n=>{const o=`confirm-modal-${Date.now()}`,i=`\n <div id="${o}" class="modal" style="display: none;">\n <div class="modal-content" style="max-width: 400px; margin: 15% auto;">\n <div class="modal-header">\n <h3 class="text-lg font-semibold text-gray-700">${e}</h3>\n </div>\n <div style="margin: 1rem 0;">\n ${t}\n </div>\n <div style="display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem;">\n <button type="button" class="cancel-button px-4 py-2 text-gray-600 hover:text-gray-800 font-medium rounded-lg hover:bg-gray-100 transition-colors">\n Cancel\n </button>\n <button type="button" class="confirm-button submit-button">\n Confirm\n </button>\n </div>\n </div>\n </div>\n `;document.body.insertAdjacentHTML("beforeend",i);const s=document.getElementById(o);requestAnimationFrame((()=>{s.style.display="block"})),s.querySelector(".confirm-button").addEventListener("click",(()=>{s.style.display="none",s.remove(),n(!0)})),s.querySelector(".cancel-button").addEventListener("click",(()=>{s.style.display="none",s.remove(),n(!1)})),s.addEventListener("click",(e=>{e.target===s&&(s.style.display="none",s.remove(),n(!1))}))}))}export{showToast,showConfirm};document.addEventListener("DOMContentLoaded",(()=>{const e=sessionStorage.getItem("installNotification");if(e){const{message:t,type:n}=JSON.parse(e);showToast(t,n),sessionStorage.removeItem("installNotification")}}));
1
+ function showToast(e,t="success"){const n=document.querySelector(".alert-container");if(!n)return void console.error("Alert container not found. Notifications will not be displayed.");const o=`alert-${Date.now()}`;let i="";switch(t){case"success":i='<i class="bi bi-check-circle-fill alert-icon"></i>';break;case"error":i='<i class="bi bi-x-octagon-fill alert-icon"></i>';break;case"info":i='<i class="bi bi-info-circle-fill alert-icon"></i>';break;case"warning":i='<i class="bi bi-exclamation-triangle-fill alert-icon"></i>';break;default:i='<i class="bi bi-bell-fill alert-icon"></i>'}const s=`\n <div id="${o}" class="alert alert-${t}" role="alert">\n ${i}\n <span>${e}</span>\n <button type="button" class="btn-close" aria-label="Close"></button>\n </div>\n `;n.insertAdjacentHTML("beforeend",s);const a=document.getElementById(o);if(!a)return;requestAnimationFrame((()=>{requestAnimationFrame((()=>{a.classList.add("show")}))}));const l=a.querySelector(".btn-close"),dismissAlert=()=>{a.classList.remove("show"),a.addEventListener("transitionend",(()=>{a.remove()}),{once:!0})};l&&l.addEventListener("click",dismissAlert),setTimeout(dismissAlert,5e3)}function showConfirm(e,t){return new Promise((n=>{const o=`confirm-modal-${Date.now()}`,i=`\n <div id="${o}" class="modal" style="display: none;">\n <div class="modal-content" style="max-width: 400px; margin: 15% auto;">\n <div class="modal-header">\n <h3 class="text-lg font-semibold text-gray-700">${e}</h3>\n </div>\n <div style="margin: 1rem 0;">\n ${t}\n </div>\n <div style="display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1rem;">\n <button type="button" class="cancel-button px-4 py-2 text-gray-600 hover:text-gray-800 font-medium rounded-lg hover:bg-gray-100 transition-colors">\n Cancel\n </button>\n <button type="button" class="confirm-button submit-button">\n Confirm\n </button>\n </div>\n </div>\n </div>\n `;document.body.insertAdjacentHTML("beforeend",i);const s=document.getElementById(o);requestAnimationFrame((()=>{s.style.display="block"})),s.querySelector(".confirm-button").addEventListener("click",(()=>{s.style.display="none",s.remove(),n(!0)})),s.querySelector(".cancel-button").addEventListener("click",(()=>{s.style.display="none",s.remove(),n(!1)})),s.addEventListener("click",(e=>{e.target===s&&(s.style.display="none",s.remove(),n(!1))}))}))}export{showToast,showConfirm};document.addEventListener("DOMContentLoaded",(()=>{const e=sessionStorage.getItem("installNotification");if(e){const{message:t,type:n}=JSON.parse(e);showToast(t,n),sessionStorage.removeItem("installNotification")}}));
2
2
  //# sourceMappingURL=notifications.js.map
@@ -1,2 +1,2 @@
1
- import{showToast}from"../notifications.js";import{state,setServerCounter,getServerCounter,clearEnvCountersForTab,clearServerRequirementCountersForTab}from"./state.js";function setupRealTimeValidation(e){const t=document.getElementById(e);if(!t)return;if(!t)return;const r=t.querySelector('input[name="name"]');r&&r.addEventListener("input",(e=>{const t=e.target.value.trim();t?/^[a-zA-Z0-9-_]+$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Only alphanumeric characters, hyphens, and underscores allowed"):showValidationMessage(e.target,"Name is required")}));const s=t.querySelector('input[name="displayName"]');s&&s.addEventListener("input",(e=>{const t=e.target.value.trim();t?t.length>100?showValidationMessage(e.target,"Must not exceed 100 characters"):showValidationMessage(e.target,"Valid display name",!1):showValidationMessage(e.target,"Display name is required")}));const a=t.querySelector('textarea[name="description"]');a&&a.addEventListener("input",(e=>{const t=e.target.value.trim();t.length>500?showValidationMessage(e.target,"Must not exceed 500 characters"):0===t.length?showValidationMessage(e.target,"Description is required"):showValidationMessage(e.target,"Valid description",!1)}));const n=t.querySelector('input[name="repository"]');n&&n.addEventListener("input",(e=>{const t=e.target.value.trim();if(t)try{new URL(t),showValidationMessage(e.target,"Valid URL",!1)}catch(t){showValidationMessage(e.target,"Invalid URL format")}else e.target.nextElementSibling?.remove()})),t.addEventListener("change",(e=>{if(e.target.name?.match(/servers\[\d+\]\.mode/)){const r=e.target.name.match(/servers\[(\d+)\]/)[1],s=t.querySelector(`[name="servers[${r}].installation.command"]`),a=t.querySelector(`[name="servers[${r}].installation.url"]`),n=t.querySelector(`[name="servers[${r}].installation.args"]`);"stdio"===e.target.value?(s&&(s.required=!0,showValidationMessage(s,"Command is required for stdio mode")),a&&(a.required=!1,a.value="",a.nextElementSibling?.remove())):"sse"===e.target.value&&(a&&(a.required=!0,showValidationMessage(a,"URL is required for sse mode")),s&&(s.required=!1,s.value="",s.nextElementSibling?.remove()),n&&(n.value="",n.nextElementSibling?.remove()))}})),t.addEventListener("input",(e=>{if(e.target.name?.includes(".installation.env[")){const t=e.target.name.match(/servers\[(\d+)\]\.installation\.env\[(\d+)\]\.(name|default)/);if(t){const[,r,s,a]=t;if("name"===a){const t=e.target.value.trim();t?/^[A-Z_][A-Z0-9_]*$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Must be uppercase with only letters, numbers, and underscores"):showValidationMessage(e.target,"Environment variable name is required")}}}}))}export async function submitForm(e,t,r=null){e.preventDefault();const s=e.target;let a,n=!1;if("create-category"===t)try{a=formDataToFeedConfiguration(s);const e=new URLSearchParams(window.location.search);n="edit"===e.get("action")&&e.get("category")===a.name}catch(e){return}else{if("create-server"!==t)return void showToast("Invalid tab context for submission.","error");{if(!r||!r.name)return void showToast("No existing category selected or category data is missing.","error");const e=formDataToFeedConfiguration(s,!0,r);a=JSON.parse(JSON.stringify(r)),a.mcpServers=e.mcpServers||[];const t=new Set((a.requirements||[]).map((e=>`${e.type}|${e.name}|${e.version}`)));(e.requirements||[]).forEach((e=>{const r=`${e.type}|${e.name}|${e.version}`;t.has(r)||(a.requirements.push(e),t.add(r))})),n=!0}}try{const e=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:a,isUpdate:n})});if(!e.ok){const t=await e.json().catch((()=>({error:"Failed to parse error response"})));throw new Error(`HTTP error! status: ${e.status}, message: ${t.error||e.statusText}`)}await e.json(),showToast("Form submitted successfully! See console for operation details.","success")}catch(e){showToast(`Error submitting form: ${e.message}. Please try again.`,"error")}}export function getFormData(e,t=!1,r=null){return formDataToFeedConfiguration(e,t,r)}function validateServerConfig(e){const t=[];if(e.name?/^[a-zA-Z0-9-_]+$/.test(e.name)?e.name.length>50&&t.push("Server name must not exceed 50 characters"):t.push("Server name must only contain alphanumeric characters, hyphens, and underscores"):t.push("Server name is required"),e.description&&""!==e.description.trim()?e.description.length>200&&t.push("Server description must not exceed 200 characters"):t.push("Server description is required"),e.mode?["stdio","sse"].includes(e.mode)||t.push('Server mode must be either "stdio" or "sse"'):t.push("Server mode is required"),"stdio"===e.mode)e.installation?.command?/^[a-zA-Z0-9-_.\\/]+$/.test(e.installation.command)||t.push("Command must only contain alphanumeric characters, hyphens, underscores, dots, and slashes"):t.push("Command is required for stdio server"),e.installation?.args?.length>0&&e.installation.args.forEach(((e,r)=>{/^[a-zA-Z0-9-_./\\]+$/.test(e)||t.push(`Argument ${r+1} must only contain alphanumeric characters, hyphens, underscores, dots, and slashes`)}));else if("sse"===e.mode)if(e.installation?.url)try{new URL(e.installation.url)}catch(e){t.push("Invalid URL format")}else t.push("URL is required for sse server");if(e.installation?.env&&Object.entries(e.installation.env).forEach((([e,r])=>{e?/^[A-Z_][A-Z0-9_]*$/.test(e)?e.length>50&&t.push(`Environment variable name "${e}" must not exceed 50 characters`):t.push(`Environment variable name "${e}" must be uppercase with only letters, numbers, and underscores`):t.push("Environment variable name is required"),r.Required&&!r.Default&&t.push(`Required environment variable "${e}" should have a default value`),r.Description&&r.Description.length>200&&t.push(`Description for environment variable "${e}" must not exceed 200 characters`)})),e.schemas)try{JSON.parse(e.schemas)}catch(e){t.push("Invalid JSON format in schemas")}return t}export function formDataToFeedConfiguration(e,t=!1,r=null){const s=new FormData(e),a={requirements:[],mcpServers:[]};let n;"onboardForm"===e.id?n="serversList":"onboardServerForm"===e.id&&(n="existingCategoryServersList"),t?r&&(a.name=r.name):(a.name=s.get("name")||"",a.displayName=s.get("displayName")||"",a.description=s.get("description")||"",a.repository=s.get("repository")||void 0);const i=new Map,o=new Map;for(const[e,r]of s.entries()){if(t&&!e.startsWith("servers["))continue;const a=e.match(/^servers\[(\d+)\]\.(.+)$/);if(a){let t=parseInt(a[1],10);const n=a[2];let o=t;i.has(o)||i.set(o,{installation:{env:new Map},dependencies:{requirements:new Map},isNew:!0});const l=i.get(o);if("name"===n)l.name=r;else if("description"===n)l.description=r;else if("mode"===n)l.mode=r;else if("repository"===n)l.repository=r||void 0;else if("schemas"===n)l.schemas=r||void 0;else if("installation.command"===n)l.installation.command=r;else if("installation.args"===n)l.installation.args=r?r.split(",").map((e=>e.trim())).filter((e=>e)):[];else if("installation.url"===n)l.installation.url=r;else if(n.startsWith("installation.env[")){const t=n.match(/^installation\.env\[(\d+)\]\.(name|default|required|description)$/);if(t){const a=parseInt(t[1],10),n=t[2];l.installation.env.has(a)||l.installation.env.set(a,{});l.installation.env.get(a)[n]="required"===n?"on"===s.get(e):r||void 0}}else if(n.startsWith("requirements[")){const e=n.match(/^requirements\[(\d+)\]\.(.+)$/);if(e){const t=parseInt(e[1],10),s=e[2];l.dependencies.requirements.has(t)||l.dependencies.requirements.set(t,{registry:{}});const a=l.dependencies.requirements.get(t);"name"===s?a.name=r:"type"===s?a.type=r:"version"===s?a.version=r:"order"===s?a.order=r?parseInt(r,10):void 0:"alias"===s?a.alias=r||void 0:"registryType"===s?a.registryType=r:s.startsWith("registry.githubRelease.")?(a.registry.githubRelease=a.registry.githubRelease||{},a.registry.githubRelease[s.substring(23)]=r||void 0):s.startsWith("registry.artifacts.")?(a.registry.artifacts=a.registry.artifacts||{},a.registry.artifacts[s.substring(19)]=r||void 0):s.startsWith("registry.local.")&&(a.registry.local=a.registry.local||{},a.registry.local[s.substring(15)]=r||void 0)}}}}i.forEach(((t,r)=>{let s;if("sse"===t.mode)s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{url:t.installation.url||""},dependencies:{requirements:[]}};else{s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{command:t.installation.command,args:t.installation.args||[],env:{}},dependencies:{requirements:[]}};const e={};t.installation.env.forEach((t=>{t.name&&(e[t.name]={Required:t.required||!1,Description:t.description||"",Default:t.default||void 0})})),Object.keys(e).length>0?s.installation.env=e:delete s.installation.env}if(t.dependencies.requirements.forEach((e=>{if(!e.name||!e.type||!e.version)return;const t={name:e.name,type:e.type,version:e.version,alias:e.alias,order:e.order};e.registryType&&"public"!==e.registryType&&(t.registry={},"github"===e.registryType&&e.registry.githubRelease?t.registry.githubRelease={repository:e.registry.githubRelease.repository,assetsName:e.registry.githubRelease.assetsName,assetName:e.registry.githubRelease.assetName}:"artifacts"===e.registryType&&e.registry.artifacts?t.registry.artifacts={registryUrl:e.registry.artifacts.registryUrl,registryName:e.registry.artifacts.registryName}:"local"===e.registryType&&e.registry.local&&(t.registry.local={localPath:e.registry.local.localPath,assetName:e.registry.local.assetName}),t.registry.githubRelease&&!t.registry.githubRelease.repository&&delete t.registry.githubRelease,t.registry.artifacts&&!t.registry.artifacts.registryUrl&&delete t.registry.artifacts,t.registry.local&&!t.registry.local.localPath&&delete t.registry.local,0===Object.keys(t.registry).length&&delete t.registry),s.dependencies.requirements.push({name:e.name,version:e.version,order:e.order});const r=`${e.type}|${e.name}|${e.version}`;if(!o.has(r)){const{order:e,...s}=t;o.set(r,s)}})),0===s.dependencies.requirements.length&&delete s.dependencies,"onboardServerForm"===e.id&&n){const e=`#${n} .server-item[data-index="${r}"]`,t=document.querySelector(e);if(t&&t.dataset.systemTags)try{s.systemTags=JSON.parse(t.dataset.systemTags)}catch(e){s.systemTags={parseError:!0}}}else delete s.systemTags;a.mcpServers.push(s)})),t&&r&&Array.isArray(r.mcpServers)&&r.mcpServers.forEach((e=>{a.mcpServers.some((t=>t.name===e.name))||e.systemTags&&"true"===e.systemTags.adhoc||(a.mcpServers.push(JSON.parse(JSON.stringify(e))),e.dependencies&&Array.isArray(e.dependencies.requirements)&&e.dependencies.requirements.forEach((e=>{const t=r.requirements?.find((t=>t.name===e.name&&t.type&&t.version===e.version));if(t){const e=`${t.type}|${t.name}|${t.version}`;o.has(e)||o.set(e,JSON.parse(JSON.stringify(t)))}else{const t=r.requirements?.find((t=>t.name===e.name&&t.version===e.version));if(t&&t.type){const r=`${t.type}|${e.name}|${e.version}`;o.has(r)||o.set(r,{name:e.name,version:e.version,type:t.type})}}})))})),a.requirements=Array.from(o.values());const l=[];return t||(a.name?/^[a-zA-Z0-9-_]+$/.test(a.name)||l.push("Category name must only contain alphanumeric characters, hyphens, and underscores"):l.push("Category name is required"),a.displayName||l.push("Display name is required")),a.mcpServers.forEach(((e,t)=>{const r=validateServerConfig(e);r.length>0&&l.push(`Server ${t+1} (${e.name||"unnamed"}): ${r.join(", ")}`)})),a.requirements.forEach(((e,t)=>{if(e.name&&e.type&&e.version||l.push(`Requirement ${t+1}: name, type, and version are required`),e.registry){const r=Object.keys(e.registry)[0];["githubRelease","artifacts","local"].includes(r)||l.push(`Requirement ${t+1}: Invalid registry type ${r}`)}})),l.length>0&&(e.querySelectorAll(".validation-error-message").forEach((e=>e.remove())),l.forEach((t=>{let r=null;if(t.includes("Category name")?r='input[name="name"]':t.includes("Display name")&&(r='input[name="displayName"]'),r){const s=e.querySelector(r);if(s){const e=document.createElement("div");e.className="validation-error-message text-red-500 text-xs mt-1",e.textContent=t,s.insertAdjacentElement("afterend",e)}}}))),a}export function populateForm(e,t="onboardForm",r=!1,s=null){const a=document.getElementById(t);if(!a)return;const n=s||("onboardForm"===t?"serversList":"existingCategoryServersList");if(resetOnboardFormDynamicContent(t,n),setupRealTimeValidation(t),e){if("onboardForm"===t){a.querySelector('[name="name"]').value=e.name||"",a.querySelector('[name="displayName"]').value=e.displayName||"",a.querySelector('[name="description"]').value=e.description||"",e.repository&&(a.querySelector('[name="repository"]').value=e.repository);const t=new URLSearchParams(window.location.search);if("edit"===t.get("action")&&t.get("category")===e.name){const e=a.querySelector('[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed"))}}else if("onboardServerForm"===t&&e){a.querySelector('input[name="name"]').value=e.name||"",a.querySelector('input[name="displayName"]').value=e.displayName||"",a.querySelector('textarea[name="description"]').value=e.description||"",a.querySelector('input[name="repository"]').value=e.repository||"";const t=document.getElementById("existingCategoryBasicInfoContainer");t&&t.classList.remove("hidden");const r=document.getElementById("existingCategoryMcpServersContainer");r&&r.classList.remove("hidden")}setServerCounter(n,0),clearEnvCountersForTab(n),clearServerRequirementCountersForTab(n),(e.mcpServers||[]).forEach((s=>{const i=getServerCounter(n);window.addServer(n,r,s);const o=a.querySelector(`#${n} .server-item[data-index="${i}"]`);if(o)if("onboardServerForm"===t)if("true"===s.systemTags?.adhoc)o.dataset.systemTags=JSON.stringify(s.systemTags);else if(state.originalServerNamesForFormPopulation&&s.name&&state.originalServerNamesForFormPopulation.has(s.name))o.dataset.systemTags=JSON.stringify({adhoc:"true"});else if(s.systemTags&&Object.keys(s.systemTags).length>0){const e={...s.systemTags};delete e.adhoc,Object.keys(e).length>0?o.dataset.systemTags=JSON.stringify(e):delete o.dataset.systemTags}else delete o.dataset.systemTags;else s.systemTags?o.dataset.systemTags=JSON.stringify(s.systemTags):delete o.dataset.systemTags;const l=a.querySelector(`[name="servers[${i}].name"]`);l&&(l.value=s.name||"");const c=a.querySelector(`[name="servers[${i}].mode"]`);c&&(c.value=s.mode||"stdio","function"==typeof window.renderInstallationConfig&&window.renderInstallationConfig(i,n,s.mode||"stdio",r,s.installation));const m=a.querySelector(`[name="servers[${i}].description"]`);if(m&&(m.value=s.description||""),s.schemas){const e=document.getElementById(`schema-path-${i}`);e&&(e.value=s.schemas)}if(s.repository){const e=a.querySelector(`[name="servers[${i}].repository"]`);e&&(e.value=s.repository)}if(s.installation)if("sse"===s.mode){const e=a.querySelector(`[name="servers[${i}].installation.url"]`);e&&(e.value=s.installation.url||"")}else{const e=a.querySelector(`[name="servers[${i}].installation.command"]`);if(e&&(e.value=s.installation.command||""),s.installation.args&&Array.isArray(s.installation.args)){const e=a.querySelector(`[name="servers[${i}].installation.args"]`);e&&(e.value=s.installation.args.join(", "))}s.installation.env&&Object.entries(s.installation.env).forEach((([e,t])=>{const s=window.addEnvVariable(i,n,r),o=a.querySelector(`[name="servers[${i}].installation.env[${s}].name"]`);if(o&&(o.value=e),t.Default){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].default"]`);e&&(e.value=t.Default)}if(t.Required){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].required"]`);e&&(e.checked=!0)}if(t.Description){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].description"]`);e&&(e.value=t.Description)}}))}if(s.dependencies&&s.dependencies.requirements){const t=r&&!("true"===s.systemTags?.adhoc);s.dependencies.requirements.forEach((r=>{const s=(e.requirements||[]).find((e=>e.name===r.name));if(!s)return;const o=window.addServerRequirement(i,n,t);a.querySelector(`[name="servers[${i}].requirements[${o}].name"]`).value=s.name||"",a.querySelector(`[name="servers[${i}].requirements[${o}].type"]`).value=s.type||"",a.querySelector(`[name="servers[${i}].requirements[${o}].version"]`).value=s.version||"",void 0!==r.order&&(a.querySelector(`[name="servers[${i}].requirements[${o}].order"]`).value=r.order),"command"===s.type&&s.alias&&(a.querySelector(`[name="servers[${i}].requirements[${o}].alias"]`).value=s.alias,window.toggleServerAliasField(i,o,n));let l="public";s.registry&&(s.registry.githubRelease?l="github":s.registry.artifacts?l="artifacts":s.registry.local&&(l="local"));const c=a.querySelector(`[name="servers[${i}].requirements[${o}].registryType"]`);if(c&&(c.value=l,window.toggleServerRegistryConfig(i,o,n)),"github"===l&&s.registry.githubRelease){const e=s.registry.githubRelease;e.repository&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.repository"]`).value=e.repository),e.assetsName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetsName"]`).value=e.assetsName),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetName"]`).value=e.assetName)}else if("artifacts"===l&&s.registry.artifacts){const e=s.registry.artifacts;e.registryUrl&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryUrl"]`).value=e.registryUrl),e.registryName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryName"]`).value=e.registryName)}else if("local"===l&&s.registry.local){const e=s.registry.local;e.localPath&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.localPath"]`).value=e.localPath),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.assetName"]`).value=e.assetName)}}))}}))}}export function resetOnboardFormDynamicContent(e="onboardForm",t="serversList"){const r=document.getElementById(e);r&&"onboardServerForm"!==e&&r.reset();const s=document.getElementById(t);let a,n;if(s&&(s.innerHTML=""),setServerCounter(0),state&&state.envCounters&&"function"==typeof state.envCounters.clear&&state.envCounters.clear(),state&&state.serverRequirementCounters&&"function"==typeof state.serverRequirementCounters.clear&&state.serverRequirementCounters.clear(),"onboardForm"===e?(a="validationStatusPanelNewCategory",n="validationStatusContentNewCategory"):"onboardServerForm"===e&&(a="validationStatusPanelExistingCategory",n="validationStatusContentExistingCategoryTab"),a){const e=document.getElementById(a);e&&e.classList.add("hidden")}if(n){const e=document.getElementById(n);e&&(e.innerHTML="")}if("onboardServerForm"===e){const e=document.getElementById("existingCategoryBasicInfoContainer");e&&e.classList.add("hidden");const t=document.getElementById("existingCategoryMcpServersContainer");t&&t.classList.add("hidden")}setupRealTimeValidation(e)}export function showValidationMessage(e,t,r=!0){let s=e.nextElementSibling;s&&s.classList.contains("validation-message")||(s=document.createElement("div"),s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500"),e.insertAdjacentElement("afterend",s)),s.textContent=t,s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500")}export{setupRealTimeValidation};
1
+ import{showToast}from"../notifications.js";import{state,setServerCounter,getServerCounter,clearEnvCountersForTab,clearServerRequirementCountersForTab}from"./state.js";function setupRealTimeValidation(e){const t=document.getElementById(e);if(!t)return;if(!t)return;const r=t.querySelector('input[name="name"]');r&&r.addEventListener("input",(e=>{const t=e.target.value.trim();t?/^[a-zA-Z0-9-_]+$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Only alphanumeric characters, hyphens, and underscores allowed"):showValidationMessage(e.target,"Name is required")}));const s=t.querySelector('input[name="displayName"]');s&&s.addEventListener("input",(e=>{const t=e.target.value.trim();t?t.length>100?showValidationMessage(e.target,"Must not exceed 100 characters"):showValidationMessage(e.target,"Valid display name",!1):showValidationMessage(e.target,"Display name is required")}));const a=t.querySelector('textarea[name="description"]');a&&a.addEventListener("input",(e=>{const t=e.target.value.trim();t.length>500?showValidationMessage(e.target,"Must not exceed 500 characters"):0===t.length?showValidationMessage(e.target,"Description is required"):showValidationMessage(e.target,"Valid description",!1)}));const n=t.querySelector('input[name="repository"]');n&&n.addEventListener("input",(e=>{const t=e.target.value.trim();if(t)try{new URL(t),showValidationMessage(e.target,"Valid URL",!1)}catch(t){showValidationMessage(e.target,"Invalid URL format")}else e.target.nextElementSibling?.remove()})),t.addEventListener("change",(e=>{if(e.target.name?.match(/servers\[\d+\]\.mode/)){const r=e.target.name.match(/servers\[(\d+)\]/)[1],s=t.querySelector(`[name="servers[${r}].installation.command"]`),a=t.querySelector(`[name="servers[${r}].installation.url"]`),n=t.querySelector(`[name="servers[${r}].installation.args"]`);"stdio"===e.target.value?(s&&(s.required=!0,showValidationMessage(s,"Command is required for stdio mode")),a&&(a.required=!1,a.value="",a.nextElementSibling?.remove())):"sse"===e.target.value&&(a&&(a.required=!0,showValidationMessage(a,"URL is required for sse mode")),s&&(s.required=!1,s.value="",s.nextElementSibling?.remove()),n&&(n.value="",n.nextElementSibling?.remove()))}})),t.addEventListener("input",(e=>{if(e.target.name?.includes(".installation.env[")){const t=e.target.name.match(/servers\[(\d+)\]\.installation\.env\[(\d+)\]\.(name|default)/);if(t){const[,r,s,a]=t;if("name"===a){const t=e.target.value.trim();t?/^[A-Z_][A-Z0-9_]*$/.test(t)?t.length>50?showValidationMessage(e.target,"Must not exceed 50 characters"):showValidationMessage(e.target,"Valid name",!1):showValidationMessage(e.target,"Must be uppercase with only letters, numbers, and underscores"):showValidationMessage(e.target,"Environment variable name is required")}}}}))}export async function submitForm(e,t,r=null){e.preventDefault();const s=e.target;let a,n=!1;if("create-category"===t)try{a=formDataToFeedConfiguration(s);const e=new URLSearchParams(window.location.search);n="edit"===e.get("action")&&e.get("category")===a.name}catch(e){return void console.error("Validation error:",e)}else{if("create-server"!==t)return void showToast("Invalid tab context for submission.","error");{if(!r||!r.name)return void showToast("No existing category selected or category data is missing.","error");const e=formDataToFeedConfiguration(s,!0,r);a=JSON.parse(JSON.stringify(r)),a.mcpServers=e.mcpServers||[];const t=new Set((a.requirements||[]).map((e=>`${e.type}|${e.name}|${e.version}`)));(e.requirements||[]).forEach((e=>{const r=`${e.type}|${e.name}|${e.version}`;t.has(r)||(a.requirements.push(e),t.add(r))})),n=!0}}try{const e=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({categoryData:a,isUpdate:n})});if(!e.ok){const t=await e.json().catch((()=>({error:"Failed to parse error response"})));throw new Error(`HTTP error! status: ${e.status}, message: ${t.error||e.statusText}`)}await e.json();showToast("Form submitted successfully! See console for operation details.","success")}catch(e){console.error("Error submitting form:",e),showToast(`Error submitting form: ${e.message}. Please try again.`,"error")}}export function getFormData(e,t=!1,r=null){return formDataToFeedConfiguration(e,t,r)}function validateServerConfig(e){const t=[];if(e.name?/^[a-zA-Z0-9-_]+$/.test(e.name)?e.name.length>50&&t.push("Server name must not exceed 50 characters"):t.push("Server name must only contain alphanumeric characters, hyphens, and underscores"):t.push("Server name is required"),e.description&&""!==e.description.trim()?e.description.length>200&&t.push("Server description must not exceed 200 characters"):t.push("Server description is required"),e.mode?["stdio","sse"].includes(e.mode)||t.push('Server mode must be either "stdio" or "sse"'):t.push("Server mode is required"),"stdio"===e.mode)e.installation?.command?/^[a-zA-Z0-9-_.\\/]+$/.test(e.installation.command)||t.push("Command must only contain alphanumeric characters, hyphens, underscores, dots, and slashes"):t.push("Command is required for stdio server"),e.installation?.args?.length>0&&e.installation.args.forEach(((e,r)=>{/^[a-zA-Z0-9-_./\\]+$/.test(e)||t.push(`Argument ${r+1} must only contain alphanumeric characters, hyphens, underscores, dots, and slashes`)}));else if("sse"===e.mode)if(e.installation?.url)try{new URL(e.installation.url)}catch(e){t.push("Invalid URL format")}else t.push("URL is required for sse server");if(e.installation?.env&&Object.entries(e.installation.env).forEach((([e,r])=>{e?/^[A-Z_][A-Z0-9_]*$/.test(e)?e.length>50&&t.push(`Environment variable name "${e}" must not exceed 50 characters`):t.push(`Environment variable name "${e}" must be uppercase with only letters, numbers, and underscores`):t.push("Environment variable name is required"),r.Required&&!r.Default&&t.push(`Required environment variable "${e}" should have a default value`),r.Description&&r.Description.length>200&&t.push(`Description for environment variable "${e}" must not exceed 200 characters`)})),e.schemas)try{JSON.parse(e.schemas)}catch(e){t.push("Invalid JSON format in schemas")}return t}export function formDataToFeedConfiguration(e,t=!1,r=null){const s=new FormData(e),a={requirements:[],mcpServers:[]};let n;"onboardForm"===e.id?n="serversList":"onboardServerForm"===e.id?n="existingCategoryServersList":console.warn("[formDataToFeedConfiguration] Could not determine serversListId from formElement.id:",e.id),t?r&&(a.name=r.name):(a.name=s.get("name")||"",a.displayName=s.get("displayName")||"",a.description=s.get("description")||"",a.repository=s.get("repository")||void 0);const i=new Map,o=new Map;for(const[e,r]of s.entries()){if(t&&!e.startsWith("servers["))continue;const a=e.match(/^servers\[(\d+)\]\.(.+)$/);if(a){let t=parseInt(a[1],10);const n=a[2];let o=t;i.has(o)||i.set(o,{installation:{env:new Map},dependencies:{requirements:new Map},isNew:!0});const l=i.get(o);if("name"===n)l.name=r;else if("description"===n)l.description=r;else if("mode"===n)l.mode=r;else if("repository"===n)l.repository=r||void 0;else if("schemas"===n)l.schemas=r||void 0;else if("installation.command"===n)l.installation.command=r;else if("installation.args"===n)l.installation.args=r?r.split(",").map((e=>e.trim())).filter((e=>e)):[];else if("installation.url"===n)l.installation.url=r;else if(n.startsWith("installation.env[")){const t=n.match(/^installation\.env\[(\d+)\]\.(name|default|required|description)$/);if(t){const a=parseInt(t[1],10),n=t[2];l.installation.env.has(a)||l.installation.env.set(a,{});const i=l.installation.env.get(a);i[n]="required"===n?"on"===s.get(e):r||void 0}}else if(n.startsWith("requirements[")){const e=n.match(/^requirements\[(\d+)\]\.(.+)$/);if(e){const t=parseInt(e[1],10),s=e[2];l.dependencies.requirements.has(t)||l.dependencies.requirements.set(t,{registry:{}});const a=l.dependencies.requirements.get(t);"name"===s?a.name=r:"type"===s?a.type=r:"version"===s?a.version=r:"order"===s?a.order=r?parseInt(r,10):void 0:"alias"===s?a.alias=r||void 0:"registryType"===s?a.registryType=r:s.startsWith("registry.githubRelease.")?(a.registry.githubRelease=a.registry.githubRelease||{},a.registry.githubRelease[s.substring(23)]=r||void 0):s.startsWith("registry.artifacts.")?(a.registry.artifacts=a.registry.artifacts||{},a.registry.artifacts[s.substring(19)]=r||void 0):s.startsWith("registry.local.")&&(a.registry.local=a.registry.local||{},a.registry.local[s.substring(15)]=r||void 0)}}}}i.forEach(((t,r)=>{let s;if("sse"===t.mode)s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{url:t.installation.url||""},dependencies:{requirements:[]}};else{s={name:t.name,description:t.description,mode:t.mode,schemas:t.schemas,repository:t.repository,installation:{command:t.installation.command,args:t.installation.args||[],env:{}},dependencies:{requirements:[]}};const e={};t.installation.env.forEach((t=>{t.name&&(e[t.name]={Required:t.required||!1,Description:t.description||"",Default:t.default||void 0})})),Object.keys(e).length>0?s.installation.env=e:delete s.installation.env}if(t.dependencies.requirements.forEach((e=>{if(!e.name||!e.type||!e.version)return;const t={name:e.name,type:e.type,version:e.version,alias:e.alias,order:e.order};e.registryType&&"public"!==e.registryType&&(t.registry={},"github"===e.registryType&&e.registry.githubRelease?t.registry.githubRelease={repository:e.registry.githubRelease.repository,assetsName:e.registry.githubRelease.assetsName,assetName:e.registry.githubRelease.assetName}:"artifacts"===e.registryType&&e.registry.artifacts?t.registry.artifacts={registryUrl:e.registry.artifacts.registryUrl,registryName:e.registry.artifacts.registryName}:"local"===e.registryType&&e.registry.local&&(t.registry.local={localPath:e.registry.local.localPath,assetName:e.registry.local.assetName}),t.registry.githubRelease&&!t.registry.githubRelease.repository&&delete t.registry.githubRelease,t.registry.artifacts&&!t.registry.artifacts.registryUrl&&delete t.registry.artifacts,t.registry.local&&!t.registry.local.localPath&&delete t.registry.local,0===Object.keys(t.registry).length&&delete t.registry),s.dependencies.requirements.push({name:e.name,version:e.version,order:e.order});const r=`${e.type}|${e.name}|${e.version}`;if(!o.has(r)){const{order:e,...s}=t;o.set(r,s)}})),0===s.dependencies.requirements.length&&delete s.dependencies,"onboardServerForm"===e.id&&n){const t=`#${n} .server-item[data-index="${r}"]`,a=document.querySelector(t);if(a&&a.dataset.systemTags)try{s.systemTags=JSON.parse(a.dataset.systemTags)}catch(t){console.error(`[formDataToFeedConfiguration] Error parsing systemTags for server index ${r} ('${s.name}') on ${e.id}:`,t,a.dataset.systemTags),s.systemTags={parseError:!0}}}else delete s.systemTags;a.mcpServers.push(s)})),t&&r&&Array.isArray(r.mcpServers)&&r.mcpServers.forEach((e=>{a.mcpServers.some((t=>t.name===e.name))||e.systemTags&&"true"===e.systemTags.adhoc||(a.mcpServers.push(JSON.parse(JSON.stringify(e))),e.dependencies&&Array.isArray(e.dependencies.requirements)&&e.dependencies.requirements.forEach((t=>{const s=r.requirements?.find((e=>e.name===t.name&&e.type&&e.version===t.version));if(s){const e=`${s.type}|${s.name}|${s.version}`;o.has(e)||o.set(e,JSON.parse(JSON.stringify(s)))}else{const s=r.requirements?.find((e=>e.name===t.name&&e.version===t.version));if(s&&s.type){const e=`${s.type}|${t.name}|${t.version}`;o.has(e)||o.set(e,{name:t.name,version:t.version,type:s.type})}else console.warn(`Could not find full global requirement definition (or type) for ${t.name} v${t.version} from original server ${e.name}`)}})))})),a.requirements=Array.from(o.values());const l=[];if(t||(a.name?/^[a-zA-Z0-9-_]+$/.test(a.name)||l.push("Category name must only contain alphanumeric characters, hyphens, and underscores"):l.push("Category name is required"),a.displayName||l.push("Display name is required")),a.mcpServers.forEach(((e,t)=>{const r=validateServerConfig(e);r.length>0&&l.push(`Server ${t+1} (${e.name||"unnamed"}): ${r.join(", ")}`)})),a.requirements.forEach(((e,t)=>{if(e.name&&e.type&&e.version||l.push(`Requirement ${t+1}: name, type, and version are required`),e.registry){const r=Object.keys(e.registry)[0];["githubRelease","artifacts","local"].includes(r)||l.push(`Requirement ${t+1}: Invalid registry type ${r}`)}})),l.length>0){e.querySelectorAll(".validation-error-message").forEach((e=>e.remove()));l.forEach((t=>{let r=null;if(t.includes("Category name")?r='input[name="name"]':t.includes("Display name")&&(r='input[name="displayName"]'),r){const s=e.querySelector(r);if(s){const e=document.createElement("div");e.className="validation-error-message text-red-500 text-xs mt-1",e.textContent=t,s.insertAdjacentElement("afterend",e)}}}))}return a}export function populateForm(e,t="onboardForm",r=!1,s=null){const a=document.getElementById(t);if(!a)return void console.error(`populateForm: Form with ID "${t}" not found.`);const n=s||("onboardForm"===t?"serversList":"existingCategoryServersList");if(resetOnboardFormDynamicContent(t,n),setupRealTimeValidation(t),e){if("onboardForm"===t){a.querySelector('[name="name"]').value=e.name||"",a.querySelector('[name="displayName"]').value=e.displayName||"",a.querySelector('[name="description"]').value=e.description||"",e.repository&&(a.querySelector('[name="repository"]').value=e.repository);const t=new URLSearchParams(window.location.search);if("edit"===t.get("action")&&t.get("category")===e.name){const e=a.querySelector('[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed"))}}else if("onboardServerForm"===t&&e){a.querySelector('input[name="name"]').value=e.name||"",a.querySelector('input[name="displayName"]').value=e.displayName||"",a.querySelector('textarea[name="description"]').value=e.description||"",a.querySelector('input[name="repository"]').value=e.repository||"";const t=document.getElementById("existingCategoryBasicInfoContainer");t&&t.classList.remove("hidden");const r=document.getElementById("existingCategoryMcpServersContainer");r&&r.classList.remove("hidden")}setServerCounter(n,0),clearEnvCountersForTab(n),clearServerRequirementCountersForTab(n),(e.mcpServers||[]).forEach((s=>{const i=getServerCounter(n);window.addServer(n,r,s);const o=a.querySelector(`#${n} .server-item[data-index="${i}"]`);if(o)if("onboardServerForm"===t)if("true"===s.systemTags?.adhoc)o.dataset.systemTags=JSON.stringify(s.systemTags);else if(state.originalServerNamesForFormPopulation&&s.name&&state.originalServerNamesForFormPopulation.has(s.name))o.dataset.systemTags=JSON.stringify({adhoc:"true"});else if(s.systemTags&&Object.keys(s.systemTags).length>0){const e={...s.systemTags};delete e.adhoc,Object.keys(e).length>0?o.dataset.systemTags=JSON.stringify(e):delete o.dataset.systemTags}else delete o.dataset.systemTags;else s.systemTags?o.dataset.systemTags=JSON.stringify(s.systemTags):delete o.dataset.systemTags;const l=a.querySelector(`[name="servers[${i}].name"]`);l&&(l.value=s.name||"");const m=a.querySelector(`[name="servers[${i}].mode"]`);m&&(m.value=s.mode||"stdio","function"==typeof window.renderInstallationConfig&&window.renderInstallationConfig(i,n,s.mode||"stdio",r,s.installation));const c=a.querySelector(`[name="servers[${i}].description"]`);if(c&&(c.value=s.description||""),s.schemas){const e=document.getElementById(`schema-path-${i}`);e&&(e.value=s.schemas)}if(s.repository){const e=a.querySelector(`[name="servers[${i}].repository"]`);e&&(e.value=s.repository)}if(s.installation)if("sse"===s.mode){const e=a.querySelector(`[name="servers[${i}].installation.url"]`);e&&(e.value=s.installation.url||"")}else{const e=a.querySelector(`[name="servers[${i}].installation.command"]`);if(e&&(e.value=s.installation.command||""),s.installation.args&&Array.isArray(s.installation.args)){const e=a.querySelector(`[name="servers[${i}].installation.args"]`);e&&(e.value=s.installation.args.join(", "))}s.installation.env&&Object.entries(s.installation.env).forEach((([e,t])=>{const s=window.addEnvVariable(i,n,r),o=a.querySelector(`[name="servers[${i}].installation.env[${s}].name"]`);if(o&&(o.value=e),t.Default){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].default"]`);e&&(e.value=t.Default)}if(t.Required){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].required"]`);e&&(e.checked=!0)}if(t.Description){const e=a.querySelector(`[name="servers[${i}].installation.env[${s}].description"]`);e&&(e.value=t.Description)}}))}if(s.dependencies&&s.dependencies.requirements){const t=r&&!("true"===s.systemTags?.adhoc);s.dependencies.requirements.forEach((r=>{const s=(e.requirements||[]).find((e=>e.name===r.name));if(!s)return void console.warn(`Could not find full requirement config for dependency name: ${r.name} (version ${r.version} specified by server, but lookup is by name only). Skipping.`);const o=window.addServerRequirement(i,n,t);a.querySelector(`[name="servers[${i}].requirements[${o}].name"]`).value=s.name||"",a.querySelector(`[name="servers[${i}].requirements[${o}].type"]`).value=s.type||"",a.querySelector(`[name="servers[${i}].requirements[${o}].version"]`).value=s.version||"",void 0!==r.order&&(a.querySelector(`[name="servers[${i}].requirements[${o}].order"]`).value=r.order),"command"===s.type&&s.alias&&(a.querySelector(`[name="servers[${i}].requirements[${o}].alias"]`).value=s.alias,window.toggleServerAliasField(i,o,n));let l="public";s.registry&&(s.registry.githubRelease?l="github":s.registry.artifacts?l="artifacts":s.registry.local&&(l="local"));const m=a.querySelector(`[name="servers[${i}].requirements[${o}].registryType"]`);if(m&&(m.value=l,window.toggleServerRegistryConfig(i,o,n)),"github"===l&&s.registry.githubRelease){const e=s.registry.githubRelease;e.repository&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.repository"]`).value=e.repository),e.assetsName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetsName"]`).value=e.assetsName),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.githubRelease.assetName"]`).value=e.assetName)}else if("artifacts"===l&&s.registry.artifacts){const e=s.registry.artifacts;e.registryUrl&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryUrl"]`).value=e.registryUrl),e.registryName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.artifacts.registryName"]`).value=e.registryName)}else if("local"===l&&s.registry.local){const e=s.registry.local;e.localPath&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.localPath"]`).value=e.localPath),e.assetName&&(a.querySelector(`[name="servers[${i}].requirements[${o}].registry.local.assetName"]`).value=e.assetName)}}))}}))}}export function resetOnboardFormDynamicContent(e="onboardForm",t="serversList"){const r=document.getElementById(e);r&&"onboardServerForm"!==e&&r.reset();const s=document.getElementById(t);let a,n;if(s&&(s.innerHTML=""),setServerCounter(0),state&&state.envCounters&&"function"==typeof state.envCounters.clear&&state.envCounters.clear(),state&&state.serverRequirementCounters&&"function"==typeof state.serverRequirementCounters.clear&&state.serverRequirementCounters.clear(),"onboardForm"===e?(a="validationStatusPanelNewCategory",n="validationStatusContentNewCategory"):"onboardServerForm"===e&&(a="validationStatusPanelExistingCategory",n="validationStatusContentExistingCategoryTab"),a){const e=document.getElementById(a);e&&e.classList.add("hidden")}if(n){const e=document.getElementById(n);e&&(e.innerHTML="")}if("onboardServerForm"===e){const e=document.getElementById("existingCategoryBasicInfoContainer");e&&e.classList.add("hidden");const t=document.getElementById("existingCategoryMcpServersContainer");t&&t.classList.add("hidden")}setupRealTimeValidation(e)}export function showValidationMessage(e,t,r=!0){let s=e.nextElementSibling;s&&s.classList.contains("validation-message")||(s=document.createElement("div"),s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500"),e.insertAdjacentElement("afterend",s)),s.textContent=t,s.className="validation-message text-xs mt-1 "+(r?"text-red-500":"text-green-500")}export{setupRealTimeValidation};
2
2
  //# sourceMappingURL=formProcessor.js.map
@@ -1,2 +1,2 @@
1
- import{addServer,toggleViewMode,saveJsonData,copyJsonToClipboard,toggleSectionContent}from"./uiHandlers.js";import{populateForm,resetOnboardFormDynamicContent}from"./formProcessor.js";import{showToast}from"../notifications.js";import{handleValidation}from"./validationHandlers.js";import{handlePublish}from"./publishHandler.js";export function showOnboardModal(){window.location.href="onboard.html"}window.showOnboardModal=showOnboardModal;let activeTab="create-category",categoriesLoaded=!1,currentSelectedCategoryData=null;async function loadExistingCategoryForEdit(){const e=new URLSearchParams(window.location.search),t=e.get("category"),a="edit"===e.get("action");if(window.isEditingCategory=!1,t&&a){document.getElementById("tab-create-category").click();try{const e=await fetch(`/api/categories/${t}`);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const a=await e.json();if(!a.success||!a.data)throw new Error(a.error||"Failed to load category data.");{populateForm(a.data.feedConfiguration,"onboardForm");const e=document.querySelector('#panel-create-category input[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed")),window.isEditingCategory=!0}}catch(e){showToast(`Error loading category for editing: ${e.message}`,"error"),window.isEditingCategory=!1}}else t&&!a&&document.getElementById("tab-create-server")&&document.getElementById("tab-create-server").click()}async function loadAndPopulateCategoriesDropdown(){if(categoriesLoaded)return;const e=document.getElementById("existingCategorySelect");if(e){e.innerHTML='<option value="">Loading categories...</option>';try{const t=await fetch("/api/categories?local=true");if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const a=await t.json();if(!a.success||!Array.isArray(a.data))throw new Error(a.error||"Failed to load categories.");e.innerHTML='<option value="">Select a category</option>',a.data.forEach((t=>{const a=document.createElement("option");a.value=t.name,a.textContent=t.displayName||t.name,e.appendChild(a)})),categoriesLoaded=!0}catch(t){e.innerHTML='<option value="">Error loading categories</option>',showToast(`Error loading categories: ${t.message}`,"error")}}}async function handleExistingCategorySelection(e){const t=e.target.value,a=document.getElementById("existingCategoryBasicInfoContainer"),r=document.getElementById("existingCategoryMcpServersContainer"),o=document.getElementById("existingCategoryServersList");if(o.innerHTML="",document.querySelector('#existingCategoryBasicInfoContainer input[name="name"]').value="",document.querySelector('#existingCategoryBasicInfoContainer input[name="displayName"]').value="",document.querySelector('#existingCategoryBasicInfoContainer textarea[name="description"]').value="",document.querySelector('#existingCategoryBasicInfoContainer input[name="repository"]').value="",!t)return a.classList.add("hidden"),r.classList.add("hidden"),void(currentSelectedCategoryData=null);try{const e=await fetch(`/api/categories/${t}`);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=await e.json();if(!(n.success&&n.data&&n.data.feedConfiguration))throw new Error(n.error||"Failed to load category details.");{currentSelectedCategoryData=n.data.feedConfiguration;const e=document.getElementById("onboardServerForm");e.querySelector('input[name="name"]').value=currentSelectedCategoryData.name||"",e.querySelector('input[name="displayName"]').value=currentSelectedCategoryData.displayName||"",e.querySelector('textarea[name="description"]').value=currentSelectedCategoryData.description||"",e.querySelector('input[name="repository"]').value=currentSelectedCategoryData.repository||"",a.classList.remove("hidden"),r.classList.remove("hidden"),currentSelectedCategoryData.mcpServers&&currentSelectedCategoryData.mcpServers.length>0?(populateForm(currentSelectedCategoryData,"onboardServerForm",!0),r.classList.remove("hidden")):o.innerHTML='<p class="text-gray-500">No servers defined in this category yet. You can add new ones.</p>';const t=r.querySelector('button[onclick*="addServer"]');t&&(t.disabled=!1)}}catch(e){showToast(`Error fetching category details: ${e.message}`,"error"),a.classList.add("hidden"),r.classList.add("hidden"),currentSelectedCategoryData=null}}window.isEditingCategory=!1,document.addEventListener("DOMContentLoaded",(async()=>{await loadExistingCategoryForEdit();const e=document.getElementById("existingCategorySelect");e&&e.addEventListener("change",handleExistingCategorySelection);const t=document.getElementById("tab-create-category"),a=document.getElementById("tab-create-server"),r=document.getElementById("panel-create-category"),o=document.getElementById("panel-create-server");if(t&&a&&r&&o){function n(e){if(e===activeTab)return;const n=document.getElementById("viewModeToggle");n.checked&&(toggleViewMode(!1,"create-category"===activeTab?"onboardForm":"onboardServerForm","create-category"===activeTab?"serversList":"existingCategoryServersList","create-server"===activeTab?currentSelectedCategoryData:null,"create-server"===activeTab),n.checked=!1),"create-category"===e?(activeTab="create-category",t.classList.add("text-blue-600","border-blue-600"),t.classList.remove("text-gray-600","border-transparent","hover:border-blue-600"),a.classList.remove("text-blue-600","border-blue-600"),a.classList.add("text-gray-600","border-transparent","hover:border-blue-600"),r.classList.remove("hidden"),o.classList.add("hidden")):"create-server"===e&&(activeTab="create-server",a.classList.add("text-blue-600","border-blue-600"),a.classList.remove("text-gray-600","border-transparent","hover:border-blue-600"),t.classList.remove("text-blue-600","border-blue-600"),t.classList.add("text-gray-600","border-transparent","hover:border-blue-600"),o.classList.remove("hidden"),r.classList.add("hidden"),loadAndPopulateCategoriesDropdown());const i=document.getElementById("panel-json-editor");i&&i.classList.add("hidden")}t.addEventListener("click",(()=>n("create-category"))),a.addEventListener("click",(()=>n("create-server")))}const i=document.getElementById("addServerBtnNewCategory");i&&i.addEventListener("click",(()=>window.addServer("serversList",!1,null)));const d=document.getElementById("addServerToExistingCategoryBtn");d&&d.addEventListener("click",(()=>{addServer("existingCategoryServersList",!1,null)}));const c=document.getElementById("validateButtonNewCategory");c&&c.addEventListener("click",(e=>handleValidation(e,"create-category",currentSelectedCategoryData)));const s=document.getElementById("validateButtonExistingCategory");s&&s.addEventListener("click",(e=>handleValidation(e,"create-server",currentSelectedCategoryData)));const l=document.getElementById("publishButtonNewCategory");l&&l.addEventListener("click",(e=>{handlePublish(e,"create-category",currentSelectedCategoryData,window.isEditingCategory)}));const g=document.getElementById("publishButtonExistingCategory");g&&g.addEventListener("click",(e=>{handlePublish(e,"create-server",currentSelectedCategoryData,!0)}));const u=document.getElementById("viewModeToggle");u&&u.addEventListener("change",(e=>{const t="create-category"===activeTab?"onboardForm":"onboardServerForm",a="create-category"===activeTab?"serversList":"existingCategoryServersList";toggleViewMode(e.target.checked,t,a,"create-server"===activeTab?currentSelectedCategoryData:null,"create-server"===activeTab)}));const y=document.getElementById("saveJsonButton");y&&y.addEventListener("click",(()=>saveJsonData(activeTab,currentSelectedCategoryData)));const m=document.getElementById("copyJsonButton");m&&m.addEventListener("click",copyJsonToClipboard),Object.assign(window,{handleValidation:handleValidation,handlePublish:handlePublish})}));
1
+ import{addServer,toggleViewMode,saveJsonData,copyJsonToClipboard,toggleSectionContent}from"./uiHandlers.js";import{populateForm,resetOnboardFormDynamicContent}from"./formProcessor.js";import{showToast}from"../notifications.js";import{handleValidation}from"./validationHandlers.js";import{handlePublish}from"./publishHandler.js";export function showOnboardModal(){window.location.href="onboard.html"}window.showOnboardModal=showOnboardModal;let activeTab="create-category",categoriesLoaded=!1,currentSelectedCategoryData=null;async function loadExistingCategoryForEdit(){const e=new URLSearchParams(window.location.search),t=e.get("category"),r="edit"===e.get("action");if(window.isEditingCategory=!1,t&&r){document.getElementById("tab-create-category").click();try{const e=await fetch(`/api/categories/${t}`);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const r=await e.json();if(!r.success||!r.data)throw new Error(r.error||"Failed to load category data.");{populateForm(r.data.feedConfiguration,"onboardForm");const e=document.querySelector('#panel-create-category input[name="name"]');e&&(e.readOnly=!0,e.classList.add("bg-gray-100","cursor-not-allowed")),window.isEditingCategory=!0}}catch(e){console.error("Error loading category for editing:",e),showToast(`Error loading category for editing: ${e.message}`,"error"),window.isEditingCategory=!1}}else t&&!r&&document.getElementById("tab-create-server")&&document.getElementById("tab-create-server").click()}async function loadAndPopulateCategoriesDropdown(){if(categoriesLoaded)return;const e=document.getElementById("existingCategorySelect");if(e){e.innerHTML='<option value="">Loading categories...</option>';try{const t=await fetch("/api/categories?local=true");if(!t.ok)throw new Error(`HTTP error! status: ${t.status}`);const r=await t.json();if(!r.success||!Array.isArray(r.data))throw new Error(r.error||"Failed to load categories.");e.innerHTML='<option value="">Select a category</option>',r.data.forEach((t=>{const r=document.createElement("option");r.value=t.name,r.textContent=t.displayName||t.name,e.appendChild(r)})),categoriesLoaded=!0}catch(t){console.error("Error loading categories:",t),e.innerHTML='<option value="">Error loading categories</option>',showToast(`Error loading categories: ${t.message}`,"error")}}}async function handleExistingCategorySelection(e){const t=e.target.value,r=document.getElementById("existingCategoryBasicInfoContainer"),a=document.getElementById("existingCategoryMcpServersContainer"),o=document.getElementById("existingCategoryServersList");if(o.innerHTML="",document.querySelector('#existingCategoryBasicInfoContainer input[name="name"]').value="",document.querySelector('#existingCategoryBasicInfoContainer input[name="displayName"]').value="",document.querySelector('#existingCategoryBasicInfoContainer textarea[name="description"]').value="",document.querySelector('#existingCategoryBasicInfoContainer input[name="repository"]').value="",!t)return r.classList.add("hidden"),a.classList.add("hidden"),void(currentSelectedCategoryData=null);try{const e=await fetch(`/api/categories/${t}`);if(!e.ok)throw new Error(`HTTP error! status: ${e.status}`);const n=await e.json();if(!(n.success&&n.data&&n.data.feedConfiguration))throw new Error(n.error||"Failed to load category details.");{currentSelectedCategoryData=n.data.feedConfiguration;const e=document.getElementById("onboardServerForm");e.querySelector('input[name="name"]').value=currentSelectedCategoryData.name||"",e.querySelector('input[name="displayName"]').value=currentSelectedCategoryData.displayName||"",e.querySelector('textarea[name="description"]').value=currentSelectedCategoryData.description||"",e.querySelector('input[name="repository"]').value=currentSelectedCategoryData.repository||"",r.classList.remove("hidden"),a.classList.remove("hidden"),currentSelectedCategoryData.mcpServers&&currentSelectedCategoryData.mcpServers.length>0?(populateForm(currentSelectedCategoryData,"onboardServerForm",!0),a.classList.remove("hidden")):o.innerHTML='<p class="text-gray-500">No servers defined in this category yet. You can add new ones.</p>';const t=a.querySelector('button[onclick*="addServer"]');t&&(t.disabled=!1)}}catch(e){console.error("[index.js] Error in handleExistingCategorySelection (fetch/parse block):",e),showToast(`Error fetching category details: ${e.message}`,"error"),r.classList.add("hidden"),a.classList.add("hidden"),currentSelectedCategoryData=null}}window.isEditingCategory=!1,document.addEventListener("DOMContentLoaded",(async()=>{await loadExistingCategoryForEdit();const e=document.getElementById("existingCategorySelect");e&&e.addEventListener("change",handleExistingCategorySelection);const t=document.getElementById("tab-create-category"),r=document.getElementById("tab-create-server"),a=document.getElementById("panel-create-category"),o=document.getElementById("panel-create-server");if(t&&r&&a&&o){function switchTab(e){if(e===activeTab)return;const n=document.getElementById("viewModeToggle");if(n.checked){toggleViewMode(!1,"create-category"===activeTab?"onboardForm":"onboardServerForm","create-category"===activeTab?"serversList":"existingCategoryServersList","create-server"===activeTab?currentSelectedCategoryData:null,"create-server"===activeTab),n.checked=!1}"create-category"===e?(activeTab="create-category",t.classList.add("text-blue-600","border-blue-600"),t.classList.remove("text-gray-600","border-transparent","hover:border-blue-600"),r.classList.remove("text-blue-600","border-blue-600"),r.classList.add("text-gray-600","border-transparent","hover:border-blue-600"),a.classList.remove("hidden"),o.classList.add("hidden")):"create-server"===e&&(activeTab="create-server",r.classList.add("text-blue-600","border-blue-600"),r.classList.remove("text-gray-600","border-transparent","hover:border-blue-600"),t.classList.remove("text-blue-600","border-blue-600"),t.classList.add("text-gray-600","border-transparent","hover:border-blue-600"),o.classList.remove("hidden"),a.classList.add("hidden"),loadAndPopulateCategoriesDropdown());const i=document.getElementById("panel-json-editor");i&&i.classList.add("hidden")}t.addEventListener("click",(()=>switchTab("create-category"))),r.addEventListener("click",(()=>switchTab("create-server")))}const n=document.getElementById("addServerBtnNewCategory");n&&n.addEventListener("click",(()=>window.addServer("serversList",!1,null)));const i=document.getElementById("addServerToExistingCategoryBtn");i&&i.addEventListener("click",(()=>{console.log('[index.js] "Add MCP Server" button clicked for EXISTING CATEGORY tab.'),addServer("existingCategoryServersList",!1,null)}));const d=document.getElementById("validateButtonNewCategory");d&&d.addEventListener("click",(e=>handleValidation(e,"create-category",currentSelectedCategoryData)));const c=document.getElementById("validateButtonExistingCategory");c&&c.addEventListener("click",(e=>handleValidation(e,"create-server",currentSelectedCategoryData)));const s=document.getElementById("publishButtonNewCategory");s&&s.addEventListener("click",(e=>{handlePublish(e,"create-category",currentSelectedCategoryData,window.isEditingCategory)}));const l=document.getElementById("publishButtonExistingCategory");l&&l.addEventListener("click",(e=>{handlePublish(e,"create-server",currentSelectedCategoryData,!0)}));const g=document.getElementById("viewModeToggle");g&&g.addEventListener("change",(e=>{const t="create-category"===activeTab?"onboardForm":"onboardServerForm",r="create-category"===activeTab?"serversList":"existingCategoryServersList";toggleViewMode(e.target.checked,t,r,"create-server"===activeTab?currentSelectedCategoryData:null,"create-server"===activeTab)}));const u=document.getElementById("saveJsonButton");u&&u.addEventListener("click",(()=>saveJsonData(activeTab,currentSelectedCategoryData)));const y=document.getElementById("copyJsonButton");y&&y.addEventListener("click",copyJsonToClipboard),Object.assign(window,{handleValidation:handleValidation,handlePublish:handlePublish})}));
2
2
  //# sourceMappingURL=index.js.map
@@ -1,2 +1,2 @@
1
- import{showToast}from"../notifications.js";import{getFormData}from"./formProcessor.js";import{validateFormFields,pollOperationStatus,updateOperationDisplay,getElementIdsByTab,ensureStatusPanelVisible}from"./validationHandlers.js";const POLLING_INTERVAL=3e3;let pollingIntervalId=null;export async function handlePublish(e,s,a=null,r=!1){const{panelId:t,contentId:i,formId:o,validateButtonId:l,publishButtonId:n}=getElementIdsByTab(s),d=document.getElementById(i);"function"==typeof ensureProgressToggleListener&&ensureProgressToggleListener(d);const c=document.getElementById(o),p=document.getElementById(l),u=document.getElementById(n);if(!(c&&d&&p&&u))return void showToast("Required form or panel elements not found for publishing.","error");if(!validateFormFields(c,s).isValid)return void showToast("Please fix all validation errors before proceeding.","error");let m=!1;if("create-category"===s){const e=getFormData(c,!1);if(!e.mcpServers||0===e.mcpServers.length)return void showToast("At least one MCP server must be configured for a new category.","error");const s=c.querySelector('input[name="name"]');s&&s.value.trim()&&(/^[a-zA-Z0-9-_]+$/.test(s.value.trim())||(showValidationMessage(s,"Only alphanumeric characters, hyphens, and underscores allowed",!0),m=!0))}if(m)return void showToast("Please fix all validation errors before proceeding.","error");u.disabled=!0,u.innerHTML="<i class='bx bx-loader-alt bx-spin mr-2'></i>Publishing...",p.disabled=!0,pollingIntervalId&&(clearInterval(pollingIntervalId),pollingIntervalId=null);const g="create-server"===s,b=getFormData(c,g,a);let h;g&&a?(h=JSON.parse(JSON.stringify(a)),h.mcpServers=b.mcpServers||[],h.requirements=b.requirements||[]):h=b,d.innerHTML='<p class="text-gray-500">Initiating publish...</p>',ensureStatusPanelVisible(t,i);try{const e={categoryData:h,isUpdate:r,forExistingCategory:g},s=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),a=await s.json();if(a.success&&a.data){updateOperationDisplay(a.data,d);const e=h.name,s="FULL_ONBOARDING",r=a.data.status;e&&"string"==typeof r&&"COMPLETED"!==r.toUpperCase()&&"FAILED"!==r.toUpperCase()&&"SUCCEEDED"!==r.toUpperCase()?pollingIntervalId=setInterval((async()=>{await pollOperationStatus(e,i,l,n,"publish",s)||(clearInterval(pollingIntervalId),pollingIntervalId=null)}),3e3):(u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50"),"COMPLETED"===r.toUpperCase()||"SUCCEEDED"===r.toUpperCase()?showToast(a.data.message||"Publish successful!","success"):"FAILED"===r.toUpperCase()&&showToast(a.data.errorMessage||a.data.message||"Publish failed.","error"))}else{const e=a.data&&a.data.message||a.error||a.message||"Publish request failed: Unknown error";a.data?updateOperationDisplay(a.data,d):d.innerHTML=`<p class="text-red-500">${e}</p>`,showToast(e,"error"),u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50")}}catch(e){d.innerHTML='<p class="text-red-500">An error occurred while initiating publish. Please check the console.</p>',showToast("An error occurred during publish. Check console.","error"),u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50")}}
1
+ import{showToast}from"../notifications.js";import{getFormData}from"./formProcessor.js";import{validateFormFields,pollOperationStatus,updateOperationDisplay,getElementIdsByTab,ensureStatusPanelVisible}from"./validationHandlers.js";const POLLING_INTERVAL=3e3;let pollingIntervalId=null;export async function handlePublish(e,r,s=null,a=!1){const{panelId:t,contentId:o,formId:i,validateButtonId:l,publishButtonId:n}=getElementIdsByTab(r),d=document.getElementById(o);"function"==typeof ensureProgressToggleListener&&ensureProgressToggleListener(d);const c=document.getElementById(i),p=document.getElementById(l),u=document.getElementById(n);if(!(c&&d&&p&&u))return console.error("Required form or panel elements not found for publishing."),void showToast("Required form or panel elements not found for publishing.","error");if(!validateFormFields(c,r).isValid)return void showToast("Please fix all validation errors before proceeding.","error");let m=!1;if("create-category"===r){const e=getFormData(c,!1);if(!e.mcpServers||0===e.mcpServers.length)return void showToast("At least one MCP server must be configured for a new category.","error");const r=c.querySelector('input[name="name"]');r&&r.value.trim()&&(/^[a-zA-Z0-9-_]+$/.test(r.value.trim())||(showValidationMessage(r,"Only alphanumeric characters, hyphens, and underscores allowed",!0),m=!0))}if(m)return void showToast("Please fix all validation errors before proceeding.","error");u.disabled=!0,u.innerHTML="<i class='bx bx-loader-alt bx-spin mr-2'></i>Publishing...",p.disabled=!0,pollingIntervalId&&(clearInterval(pollingIntervalId),pollingIntervalId=null);const g="create-server"===r,b=getFormData(c,g,s);let h;g&&s?(h=JSON.parse(JSON.stringify(s)),h.mcpServers=b.mcpServers||[],h.requirements=b.requirements||[]):h=b,d.innerHTML='<p class="text-gray-500">Initiating publish...</p>',ensureStatusPanelVisible(t,o);try{const e={categoryData:h,isUpdate:a,forExistingCategory:g},r=await fetch("/api/categories/onboard",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),s=await r.json();if(s.success&&s.data){updateOperationDisplay(s.data,d);const e=h.name,r="FULL_ONBOARDING",a=s.data.status;e&&"string"==typeof a&&"COMPLETED"!==a.toUpperCase()&&"FAILED"!==a.toUpperCase()&&"SUCCEEDED"!==a.toUpperCase()?pollingIntervalId=setInterval((async()=>{await pollOperationStatus(e,o,l,n,"publish",r)||(clearInterval(pollingIntervalId),pollingIntervalId=null)}),3e3):(u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50"),"COMPLETED"===a.toUpperCase()||"SUCCEEDED"===a.toUpperCase()?showToast(s.data.message||"Publish successful!","success"):"FAILED"===a.toUpperCase()&&showToast(s.data.errorMessage||s.data.message||"Publish failed.","error"))}else{const e=s.data&&s.data.message||s.error||s.message||"Publish request failed: Unknown error";s.data?updateOperationDisplay(s.data,d):d.innerHTML=`<p class="text-red-500">${e}</p>`,showToast(e,"error"),u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50")}}catch(e){console.error("Error during publish:",e),d.innerHTML='<p class="text-red-500">An error occurred while initiating publish. Please check the console.</p>',showToast("An error occurred during publish. Check console.","error"),u.disabled=!1,u.innerHTML="<i class='bx bx-cloud-upload mr-2'></i>Publish",u.classList.remove("opacity-50"),p.disabled=!1,p.innerHTML="<i class='bx bx-check-shield mr-2'></i>Validate",p.classList.remove("opacity-50")}}
2
2
  //# sourceMappingURL=publishHandler.js.map