codebase-onboarder 0.1.0

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 (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +275 -0
  3. package/bin/onboarder.js +14 -0
  4. package/bin/postinstall.js +6 -0
  5. package/cli/commands.js +436 -0
  6. package/cli/main.js +129 -0
  7. package/cli/prompt.js +101 -0
  8. package/cli/ui.js +55 -0
  9. package/cli/wizard.js +325 -0
  10. package/package.json +48 -0
  11. package/public/app.js +1339 -0
  12. package/public/index.html +455 -0
  13. package/public/js/about.js +284 -0
  14. package/public/js/aiDraft.js +163 -0
  15. package/public/js/analysisPanel.js +270 -0
  16. package/public/js/analysisReport.js +154 -0
  17. package/public/js/api.js +264 -0
  18. package/public/js/atlas.js +98 -0
  19. package/public/js/blameView.js +41 -0
  20. package/public/js/codeTab.js +256 -0
  21. package/public/js/codeViewer.js +184 -0
  22. package/public/js/components/FileChip.js +102 -0
  23. package/public/js/components/MetricSparkline.js +89 -0
  24. package/public/js/components/RiskBadge.js +105 -0
  25. package/public/js/deepAnalysisView.js +496 -0
  26. package/public/js/diagramPane.js +154 -0
  27. package/public/js/diffView.js +352 -0
  28. package/public/js/docsView.js +566 -0
  29. package/public/js/fileSourceBrowser.js +47 -0
  30. package/public/js/flameGraph.js +75 -0
  31. package/public/js/forceGraph.js +592 -0
  32. package/public/js/heatmap.js +185 -0
  33. package/public/js/highlight.js +122 -0
  34. package/public/js/html.js +50 -0
  35. package/public/js/insightsView.js +236 -0
  36. package/public/js/inspector.js +535 -0
  37. package/public/js/llm.js +345 -0
  38. package/public/js/mapView.js +159 -0
  39. package/public/js/markdown.js +119 -0
  40. package/public/js/mindmap.js +289 -0
  41. package/public/js/repoFiles.js +44 -0
  42. package/public/js/sbomView.js +142 -0
  43. package/public/js/scanCache.js +76 -0
  44. package/public/js/search.js +874 -0
  45. package/public/js/serverSettings.js +169 -0
  46. package/public/js/state.js +192 -0
  47. package/public/js/tour.js +17 -0
  48. package/public/js/transitions.js +15 -0
  49. package/public/js/tree.js +200 -0
  50. package/public/js/workflowsView.js +95 -0
  51. package/public/styles.css +2767 -0
  52. package/public/vendor/mermaid.min.js +3587 -0
  53. package/public/vendor/monaco/vs/base/browser/ui/codicons/codicon/codicon.ttf +0 -0
  54. package/public/vendor/monaco/vs/base/worker/workerMain.js +31 -0
  55. package/public/vendor/monaco/vs/basic-languages/abap/abap.js +10 -0
  56. package/public/vendor/monaco/vs/basic-languages/apex/apex.js +10 -0
  57. package/public/vendor/monaco/vs/basic-languages/azcli/azcli.js +10 -0
  58. package/public/vendor/monaco/vs/basic-languages/bat/bat.js +10 -0
  59. package/public/vendor/monaco/vs/basic-languages/bicep/bicep.js +11 -0
  60. package/public/vendor/monaco/vs/basic-languages/cameligo/cameligo.js +10 -0
  61. package/public/vendor/monaco/vs/basic-languages/clojure/clojure.js +10 -0
  62. package/public/vendor/monaco/vs/basic-languages/coffee/coffee.js +10 -0
  63. package/public/vendor/monaco/vs/basic-languages/cpp/cpp.js +10 -0
  64. package/public/vendor/monaco/vs/basic-languages/csharp/csharp.js +10 -0
  65. package/public/vendor/monaco/vs/basic-languages/csp/csp.js +10 -0
  66. package/public/vendor/monaco/vs/basic-languages/css/css.js +12 -0
  67. package/public/vendor/monaco/vs/basic-languages/cypher/cypher.js +10 -0
  68. package/public/vendor/monaco/vs/basic-languages/dart/dart.js +10 -0
  69. package/public/vendor/monaco/vs/basic-languages/dockerfile/dockerfile.js +10 -0
  70. package/public/vendor/monaco/vs/basic-languages/ecl/ecl.js +10 -0
  71. package/public/vendor/monaco/vs/basic-languages/elixir/elixir.js +10 -0
  72. package/public/vendor/monaco/vs/basic-languages/flow9/flow9.js +10 -0
  73. package/public/vendor/monaco/vs/basic-languages/freemarker2/freemarker2.js +12 -0
  74. package/public/vendor/monaco/vs/basic-languages/fsharp/fsharp.js +10 -0
  75. package/public/vendor/monaco/vs/basic-languages/go/go.js +10 -0
  76. package/public/vendor/monaco/vs/basic-languages/graphql/graphql.js +10 -0
  77. package/public/vendor/monaco/vs/basic-languages/handlebars/handlebars.js +10 -0
  78. package/public/vendor/monaco/vs/basic-languages/hcl/hcl.js +10 -0
  79. package/public/vendor/monaco/vs/basic-languages/html/html.js +10 -0
  80. package/public/vendor/monaco/vs/basic-languages/ini/ini.js +10 -0
  81. package/public/vendor/monaco/vs/basic-languages/java/java.js +10 -0
  82. package/public/vendor/monaco/vs/basic-languages/javascript/javascript.js +10 -0
  83. package/public/vendor/monaco/vs/basic-languages/julia/julia.js +10 -0
  84. package/public/vendor/monaco/vs/basic-languages/kotlin/kotlin.js +10 -0
  85. package/public/vendor/monaco/vs/basic-languages/less/less.js +11 -0
  86. package/public/vendor/monaco/vs/basic-languages/lexon/lexon.js +10 -0
  87. package/public/vendor/monaco/vs/basic-languages/liquid/liquid.js +10 -0
  88. package/public/vendor/monaco/vs/basic-languages/lua/lua.js +10 -0
  89. package/public/vendor/monaco/vs/basic-languages/m3/m3.js +10 -0
  90. package/public/vendor/monaco/vs/basic-languages/markdown/markdown.js +10 -0
  91. package/public/vendor/monaco/vs/basic-languages/mdx/mdx.js +10 -0
  92. package/public/vendor/monaco/vs/basic-languages/mips/mips.js +10 -0
  93. package/public/vendor/monaco/vs/basic-languages/msdax/msdax.js +10 -0
  94. package/public/vendor/monaco/vs/basic-languages/mysql/mysql.js +10 -0
  95. package/public/vendor/monaco/vs/basic-languages/objective-c/objective-c.js +10 -0
  96. package/public/vendor/monaco/vs/basic-languages/pascal/pascal.js +10 -0
  97. package/public/vendor/monaco/vs/basic-languages/pascaligo/pascaligo.js +10 -0
  98. package/public/vendor/monaco/vs/basic-languages/perl/perl.js +10 -0
  99. package/public/vendor/monaco/vs/basic-languages/pgsql/pgsql.js +10 -0
  100. package/public/vendor/monaco/vs/basic-languages/php/php.js +10 -0
  101. package/public/vendor/monaco/vs/basic-languages/pla/pla.js +10 -0
  102. package/public/vendor/monaco/vs/basic-languages/postiats/postiats.js +10 -0
  103. package/public/vendor/monaco/vs/basic-languages/powerquery/powerquery.js +10 -0
  104. package/public/vendor/monaco/vs/basic-languages/powershell/powershell.js +10 -0
  105. package/public/vendor/monaco/vs/basic-languages/protobuf/protobuf.js +11 -0
  106. package/public/vendor/monaco/vs/basic-languages/pug/pug.js +10 -0
  107. package/public/vendor/monaco/vs/basic-languages/python/python.js +10 -0
  108. package/public/vendor/monaco/vs/basic-languages/qsharp/qsharp.js +10 -0
  109. package/public/vendor/monaco/vs/basic-languages/r/r.js +10 -0
  110. package/public/vendor/monaco/vs/basic-languages/razor/razor.js +10 -0
  111. package/public/vendor/monaco/vs/basic-languages/redis/redis.js +10 -0
  112. package/public/vendor/monaco/vs/basic-languages/redshift/redshift.js +10 -0
  113. package/public/vendor/monaco/vs/basic-languages/restructuredtext/restructuredtext.js +10 -0
  114. package/public/vendor/monaco/vs/basic-languages/ruby/ruby.js +10 -0
  115. package/public/vendor/monaco/vs/basic-languages/rust/rust.js +10 -0
  116. package/public/vendor/monaco/vs/basic-languages/sb/sb.js +10 -0
  117. package/public/vendor/monaco/vs/basic-languages/scala/scala.js +10 -0
  118. package/public/vendor/monaco/vs/basic-languages/scheme/scheme.js +10 -0
  119. package/public/vendor/monaco/vs/basic-languages/scss/scss.js +12 -0
  120. package/public/vendor/monaco/vs/basic-languages/shell/shell.js +10 -0
  121. package/public/vendor/monaco/vs/basic-languages/solidity/solidity.js +10 -0
  122. package/public/vendor/monaco/vs/basic-languages/sophia/sophia.js +10 -0
  123. package/public/vendor/monaco/vs/basic-languages/sparql/sparql.js +10 -0
  124. package/public/vendor/monaco/vs/basic-languages/sql/sql.js +10 -0
  125. package/public/vendor/monaco/vs/basic-languages/st/st.js +10 -0
  126. package/public/vendor/monaco/vs/basic-languages/swift/swift.js +13 -0
  127. package/public/vendor/monaco/vs/basic-languages/systemverilog/systemverilog.js +10 -0
  128. package/public/vendor/monaco/vs/basic-languages/tcl/tcl.js +10 -0
  129. package/public/vendor/monaco/vs/basic-languages/twig/twig.js +10 -0
  130. package/public/vendor/monaco/vs/basic-languages/typescript/typescript.js +10 -0
  131. package/public/vendor/monaco/vs/basic-languages/typespec/typespec.js +10 -0
  132. package/public/vendor/monaco/vs/basic-languages/vb/vb.js +10 -0
  133. package/public/vendor/monaco/vs/basic-languages/wgsl/wgsl.js +307 -0
  134. package/public/vendor/monaco/vs/basic-languages/xml/xml.js +10 -0
  135. package/public/vendor/monaco/vs/basic-languages/yaml/yaml.js +10 -0
  136. package/public/vendor/monaco/vs/editor/editor.main.css +8 -0
  137. package/public/vendor/monaco/vs/editor/editor.main.js +798 -0
  138. package/public/vendor/monaco/vs/language/css/cssMode.js +13 -0
  139. package/public/vendor/monaco/vs/language/css/cssWorker.js +77 -0
  140. package/public/vendor/monaco/vs/language/html/htmlMode.js +13 -0
  141. package/public/vendor/monaco/vs/language/html/htmlWorker.js +454 -0
  142. package/public/vendor/monaco/vs/language/json/jsonMode.js +19 -0
  143. package/public/vendor/monaco/vs/language/json/jsonWorker.js +42 -0
  144. package/public/vendor/monaco/vs/language/typescript/tsMode.js +20 -0
  145. package/public/vendor/monaco/vs/language/typescript/tsWorker.js +51328 -0
  146. package/public/vendor/monaco/vs/loader.js +11 -0
  147. package/public/vendor/monaco/worker-boot.js +9 -0
  148. package/server/.fuse_hidden0000000800000001 +36 -0
  149. package/server/apiDiff.js +25 -0
  150. package/server/apiDocs.js +67 -0
  151. package/server/apiFile.js +36 -0
  152. package/server/apiGitBlame.js +63 -0
  153. package/server/apiMcp.js +110 -0
  154. package/server/apiScan.js +119 -0
  155. package/server/apiSearch.js +253 -0
  156. package/server/apiSettings.js +118 -0
  157. package/server/apiTools.js +90 -0
  158. package/server/config.js +227 -0
  159. package/server/fileSourceNode.js +44 -0
  160. package/server/gitClone.js +95 -0
  161. package/server/gitDiff.js +184 -0
  162. package/server/gitHistory.js +110 -0
  163. package/server/htmlText.js +44 -0
  164. package/server/http.js +55 -0
  165. package/server/httpGuards.js +87 -0
  166. package/server/index.js +156 -0
  167. package/server/llmProxy.js +162 -0
  168. package/server/logger.js +29 -0
  169. package/server/mcp/analysis.js +209 -0
  170. package/server/mcp/http.js +213 -0
  171. package/server/mcp/runner.js +278 -0
  172. package/server/mcp/server.js +241 -0
  173. package/server/mcp/standalone.js +42 -0
  174. package/server/mcp/tools.js +683 -0
  175. package/server/paths.js +39 -0
  176. package/server/router.js +218 -0
  177. package/server/searchIndex.js +118 -0
  178. package/server/sessions.js +163 -0
  179. package/server/static.js +59 -0
  180. package/server/tools/install.js +246 -0
  181. package/server/tools/parse.js +170 -0
  182. package/server/tools/platform.js +91 -0
  183. package/server/tools/registry.js +212 -0
  184. package/server/tools/scan.js +136 -0
  185. package/server/tools.js +212 -0
  186. package/server/tunnel.js +92 -0
  187. package/shared/analyzer/docs.js +135 -0
  188. package/shared/analyzer/explainLocal.js +163 -0
  189. package/shared/analyzer/graph.js +461 -0
  190. package/shared/analyzer/health.js +215 -0
  191. package/shared/analyzer/history.js +146 -0
  192. package/shared/analyzer/languages/csharp.js +39 -0
  193. package/shared/analyzer/languages/generic.js +131 -0
  194. package/shared/analyzer/languages/go.js +70 -0
  195. package/shared/analyzer/languages/index.js +43 -0
  196. package/shared/analyzer/languages/java.js +39 -0
  197. package/shared/analyzer/languages/javascript.js +240 -0
  198. package/shared/analyzer/languages/python.js +120 -0
  199. package/shared/analyzer/languages/rust.js +42 -0
  200. package/shared/analyzer/languages/typescript.js +138 -0
  201. package/shared/analyzer/licenses.js +151 -0
  202. package/shared/analyzer/metrics.js +120 -0
  203. package/shared/analyzer/pathUtil.js +69 -0
  204. package/shared/analyzer/patterns.js +272 -0
  205. package/shared/analyzer/scan.js +473 -0
  206. package/shared/analyzer/security.js +187 -0
  207. package/shared/analyzer/services.js +157 -0
  208. package/shared/analyzer/stack.js +173 -0
  209. package/shared/analyzer/tour.js +69 -0
  210. package/shared/analyzer/util.js +123 -0
  211. package/shared/analyzer/workflows.js +143 -0
  212. package/shared/diagram/aiFacts.js +145 -0
  213. package/shared/diagram/aiMermaid.js +59 -0
  214. package/shared/diagram/atlas.js +93 -0
  215. package/shared/diagram/mermaid.js +459 -0
  216. package/shared/search/query.js +518 -0
@@ -0,0 +1,11 @@
1
+ "use strict";/*!-----------------------------------------------------------
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Version: 0.52.2(404545bded1df6ffa41ea0af4e8ddb219018c6c1)
4
+ * Released under the MIT license
5
+ * https://github.com/microsoft/vscode/blob/main/LICENSE.txt
6
+ *-----------------------------------------------------------*/const _amdLoaderGlobal=this,_commonjsGlobal=typeof global=="object"?global:{};var AMDLoader;(function(u){u.global=_amdLoaderGlobal;class y{get isWindows(){return this._detect(),this._isWindows}get isNode(){return this._detect(),this._isNode}get isElectronRenderer(){return this._detect(),this._isElectronRenderer}get isWebWorker(){return this._detect(),this._isWebWorker}get isElectronNodeIntegrationWebWorker(){return this._detect(),this._isElectronNodeIntegrationWebWorker}constructor(){this._detected=!1,this._isWindows=!1,this._isNode=!1,this._isElectronRenderer=!1,this._isWebWorker=!1,this._isElectronNodeIntegrationWebWorker=!1}_detect(){this._detected||(this._detected=!0,this._isWindows=y._isWindows(),this._isNode=typeof module<"u"&&!!module.exports,this._isElectronRenderer=typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="renderer",this._isWebWorker=typeof u.global.importScripts=="function",this._isElectronNodeIntegrationWebWorker=this._isWebWorker&&typeof process<"u"&&typeof process.versions<"u"&&typeof process.versions.electron<"u"&&process.type==="worker")}static _isWindows(){return typeof navigator<"u"&&navigator.userAgent&&navigator.userAgent.indexOf("Windows")>=0?!0:typeof process<"u"?process.platform==="win32":!1}}u.Environment=y})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{constructor(r,c,a){this.type=r,this.detail=c,this.timestamp=a}}u.LoaderEvent=y;class m{constructor(r){this._events=[new y(1,"",r)]}record(r,c){this._events.push(new y(r,c,u.Utilities.getHighPerformanceTimestamp()))}getEvents(){return this._events}}u.LoaderEventRecorder=m;class p{record(r,c){}getEvents(){return[]}}p.INSTANCE=new p,u.NullLoaderEventRecorder=p})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{static fileUriToFilePath(p,h){if(h=decodeURI(h).replace(/%23/g,"#"),p){if(/^file:\/\/\//.test(h))return h.substr(8);if(/^file:\/\//.test(h))return h.substr(5)}else if(/^file:\/\//.test(h))return h.substr(7);return h}static startsWith(p,h){return p.length>=h.length&&p.substr(0,h.length)===h}static endsWith(p,h){return p.length>=h.length&&p.substr(p.length-h.length)===h}static containsQueryString(p){return/^[^\#]*\?/gi.test(p)}static isAbsolutePath(p){return/^((http:\/\/)|(https:\/\/)|(file:\/\/)|(\/))/.test(p)}static forEachProperty(p,h){if(p){let r;for(r in p)p.hasOwnProperty(r)&&h(r,p[r])}}static isEmpty(p){let h=!0;return y.forEachProperty(p,()=>{h=!1}),h}static recursiveClone(p){if(!p||typeof p!="object"||p instanceof RegExp||!Array.isArray(p)&&Object.getPrototypeOf(p)!==Object.prototype)return p;let h=Array.isArray(p)?[]:{};return y.forEachProperty(p,(r,c)=>{c&&typeof c=="object"?h[r]=y.recursiveClone(c):h[r]=c}),h}static generateAnonymousModule(){return"===anonymous"+y.NEXT_ANONYMOUS_ID+++"==="}static isAnonymousModule(p){return y.startsWith(p,"===anonymous")}static getHighPerformanceTimestamp(){return this.PERFORMANCE_NOW_PROBED||(this.PERFORMANCE_NOW_PROBED=!0,this.HAS_PERFORMANCE_NOW=u.global.performance&&typeof u.global.performance.now=="function"),this.HAS_PERFORMANCE_NOW?u.global.performance.now():Date.now()}}y.NEXT_ANONYMOUS_ID=1,y.PERFORMANCE_NOW_PROBED=!1,y.HAS_PERFORMANCE_NOW=!1,u.Utilities=y})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){function y(h){if(h instanceof Error)return h;const r=new Error(h.message||String(h)||"Unknown Error");return h.stack&&(r.stack=h.stack),r}u.ensureError=y;class m{static validateConfigurationOptions(r){function c(a){if(a.phase==="loading"){console.error('Loading "'+a.moduleId+'" failed'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}if(a.phase==="factory"){console.error('The factory function of "'+a.moduleId+'" has thrown an exception'),console.error(a),console.error("Here are the modules that depend on it:"),console.error(a.neededBy);return}}if(r=r||{},typeof r.baseUrl!="string"&&(r.baseUrl=""),typeof r.isBuild!="boolean"&&(r.isBuild=!1),typeof r.paths!="object"&&(r.paths={}),typeof r.config!="object"&&(r.config={}),typeof r.catchError>"u"&&(r.catchError=!1),typeof r.recordStats>"u"&&(r.recordStats=!1),typeof r.urlArgs!="string"&&(r.urlArgs=""),typeof r.onError!="function"&&(r.onError=c),Array.isArray(r.ignoreDuplicateModules)||(r.ignoreDuplicateModules=[]),r.baseUrl.length>0&&(u.Utilities.endsWith(r.baseUrl,"/")||(r.baseUrl+="/")),typeof r.cspNonce!="string"&&(r.cspNonce=""),typeof r.preferScriptTags>"u"&&(r.preferScriptTags=!1),r.nodeCachedData&&typeof r.nodeCachedData=="object"&&(typeof r.nodeCachedData.seed!="string"&&(r.nodeCachedData.seed="seed"),(typeof r.nodeCachedData.writeDelay!="number"||r.nodeCachedData.writeDelay<0)&&(r.nodeCachedData.writeDelay=1e3*7),!r.nodeCachedData.path||typeof r.nodeCachedData.path!="string")){const a=y(new Error("INVALID cached data configuration, 'path' MUST be set"));a.phase="configuration",r.onError(a),r.nodeCachedData=void 0}return r}static mergeConfigurationOptions(r=null,c=null){let a=u.Utilities.recursiveClone(c||{});return u.Utilities.forEachProperty(r,(t,e)=>{t==="ignoreDuplicateModules"&&typeof a.ignoreDuplicateModules<"u"?a.ignoreDuplicateModules=a.ignoreDuplicateModules.concat(e):t==="paths"&&typeof a.paths<"u"?u.Utilities.forEachProperty(e,(i,s)=>a.paths[i]=s):t==="config"&&typeof a.config<"u"?u.Utilities.forEachProperty(e,(i,s)=>a.config[i]=s):a[t]=u.Utilities.recursiveClone(e)}),m.validateConfigurationOptions(a)}}u.ConfigurationOptionsUtil=m;class p{constructor(r,c){if(this._env=r,this.options=m.mergeConfigurationOptions(c),this._createIgnoreDuplicateModulesMap(),this._createSortedPathsRules(),this.options.baseUrl===""&&this.options.nodeRequire&&this.options.nodeRequire.main&&this.options.nodeRequire.main.filename&&this._env.isNode){let a=this.options.nodeRequire.main.filename,t=Math.max(a.lastIndexOf("/"),a.lastIndexOf("\\"));this.options.baseUrl=a.substring(0,t+1)}}_createIgnoreDuplicateModulesMap(){this.ignoreDuplicateModulesMap={};for(let r=0;r<this.options.ignoreDuplicateModules.length;r++)this.ignoreDuplicateModulesMap[this.options.ignoreDuplicateModules[r]]=!0}_createSortedPathsRules(){this.sortedPathsRules=[],u.Utilities.forEachProperty(this.options.paths,(r,c)=>{Array.isArray(c)?this.sortedPathsRules.push({from:r,to:c}):this.sortedPathsRules.push({from:r,to:[c]})}),this.sortedPathsRules.sort((r,c)=>c.from.length-r.from.length)}cloneAndMerge(r){return new p(this._env,m.mergeConfigurationOptions(r,this.options))}getOptionsLiteral(){return this.options}_applyPaths(r){let c;for(let a=0,t=this.sortedPathsRules.length;a<t;a++)if(c=this.sortedPathsRules[a],u.Utilities.startsWith(r,c.from)){let e=[];for(let i=0,s=c.to.length;i<s;i++)e.push(c.to[i]+r.substr(c.from.length));return e}return[r]}_addUrlArgsToUrl(r){return u.Utilities.containsQueryString(r)?r+"&"+this.options.urlArgs:r+"?"+this.options.urlArgs}_addUrlArgsIfNecessaryToUrl(r){return this.options.urlArgs?this._addUrlArgsToUrl(r):r}_addUrlArgsIfNecessaryToUrls(r){if(this.options.urlArgs)for(let c=0,a=r.length;c<a;c++)r[c]=this._addUrlArgsToUrl(r[c]);return r}moduleIdToPaths(r){if(this._env.isNode&&this.options.amdModulesPattern instanceof RegExp&&!this.options.amdModulesPattern.test(r))return this.isBuild()?["empty:"]:["node|"+r];let c=r,a;if(!u.Utilities.endsWith(c,".js")&&!u.Utilities.isAbsolutePath(c)){a=this._applyPaths(c);for(let t=0,e=a.length;t<e;t++)this.isBuild()&&a[t]==="empty:"||(u.Utilities.isAbsolutePath(a[t])||(a[t]=this.options.baseUrl+a[t]),!u.Utilities.endsWith(a[t],".js")&&!u.Utilities.containsQueryString(a[t])&&(a[t]=a[t]+".js"))}else!u.Utilities.endsWith(c,".js")&&!u.Utilities.containsQueryString(c)&&(c=c+".js"),a=[c];return this._addUrlArgsIfNecessaryToUrls(a)}requireToUrl(r){let c=r;return u.Utilities.isAbsolutePath(c)||(c=this._applyPaths(c)[0],u.Utilities.isAbsolutePath(c)||(c=this.options.baseUrl+c)),this._addUrlArgsIfNecessaryToUrl(c)}isBuild(){return this.options.isBuild}shouldInvokeFactory(r){return!!(!this.options.isBuild||u.Utilities.isAnonymousModule(r)||this.options.buildForceInvokeFactory&&this.options.buildForceInvokeFactory[r])}isDuplicateMessageIgnoredFor(r){return this.ignoreDuplicateModulesMap.hasOwnProperty(r)}getConfigForModule(r){if(this.options.config)return this.options.config[r]}shouldCatchError(){return this.options.catchError}shouldRecordStats(){return this.options.recordStats}onError(r){this.options.onError(r)}}u.Configuration=p})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{constructor(e){this._env=e,this._scriptLoader=null,this._callbackMap={}}load(e,i,s,n){if(!this._scriptLoader)if(this._env.isWebWorker)this._scriptLoader=new h;else if(this._env.isElectronRenderer){const{preferScriptTags:d}=e.getConfig().getOptionsLiteral();d?this._scriptLoader=new m:this._scriptLoader=new r(this._env)}else this._env.isNode?this._scriptLoader=new r(this._env):this._scriptLoader=new m;let l={callback:s,errorback:n};if(this._callbackMap.hasOwnProperty(i)){this._callbackMap[i].push(l);return}this._callbackMap[i]=[l],this._scriptLoader.load(e,i,()=>this.triggerCallback(i),d=>this.triggerErrorback(i,d))}triggerCallback(e){let i=this._callbackMap[e];delete this._callbackMap[e];for(let s=0;s<i.length;s++)i[s].callback()}triggerErrorback(e,i){let s=this._callbackMap[e];delete this._callbackMap[e];for(let n=0;n<s.length;n++)s[n].errorback(i)}}class m{attachListeners(e,i,s){let n=()=>{e.removeEventListener("load",l),e.removeEventListener("error",d)},l=o=>{n(),i()},d=o=>{n(),s(o)};e.addEventListener("load",l),e.addEventListener("error",d)}load(e,i,s,n){if(/^node\|/.test(i)){let l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=i.split("|"),_=null;try{_=d(o[1])}catch(f){n(f);return}e.enqueueDefineAnonymousModule([],()=>_),s()}else{let l=document.createElement("script");l.setAttribute("async","async"),l.setAttribute("type","text/javascript"),this.attachListeners(l,s,n);const{trustedTypesPolicy:d}=e.getConfig().getOptionsLiteral();d&&(i=d.createScriptURL(i)),l.setAttribute("src",i);const{cspNonce:o}=e.getConfig().getOptionsLiteral();o&&l.setAttribute("nonce",o),document.getElementsByTagName("head")[0].appendChild(l)}}}function p(t){const{trustedTypesPolicy:e}=t.getConfig().getOptionsLiteral();try{return(e?self.eval(e.createScript("","true")):new Function("true")).call(self),!0}catch{return!1}}class h{constructor(){this._cachedCanUseEval=null}_canUseEval(e){return this._cachedCanUseEval===null&&(this._cachedCanUseEval=p(e)),this._cachedCanUseEval}load(e,i,s,n){if(/^node\|/.test(i)){const l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=i.split("|");let _=null;try{_=d(o[1])}catch(f){n(f);return}e.enqueueDefineAnonymousModule([],function(){return _}),s()}else{const{trustedTypesPolicy:l}=e.getConfig().getOptionsLiteral();if(!(/^((http:)|(https:)|(file:))/.test(i)&&i.substring(0,self.origin.length)!==self.origin)&&this._canUseEval(e)){fetch(i).then(o=>{if(o.status!==200)throw new Error(o.statusText);return o.text()}).then(o=>{o=`${o}
7
+ //# sourceURL=${i}`,(l?self.eval(l.createScript("",o)):new Function(o)).call(self),s()}).then(void 0,n);return}try{l&&(i=l.createScriptURL(i)),importScripts(i),s()}catch(o){n(o)}}}}class r{constructor(e){this._env=e,this._didInitialize=!1,this._didPatchNodeRequire=!1}_init(e){this._didInitialize||(this._didInitialize=!0,this._fs=e("fs"),this._vm=e("vm"),this._path=e("path"),this._crypto=e("crypto"))}_initNodeRequire(e,i){const{nodeCachedData:s}=i.getConfig().getOptionsLiteral();if(!s||this._didPatchNodeRequire)return;this._didPatchNodeRequire=!0;const n=this,l=e("module");function d(o){const _=o.constructor;let f=function(v){try{return o.require(v)}finally{}};return f.resolve=function(v,E){return _._resolveFilename(v,o,!1,E)},f.resolve.paths=function(v){return _._resolveLookupPaths(v,o)},f.main=process.mainModule,f.extensions=_._extensions,f.cache=_._cache,f}l.prototype._compile=function(o,_){const f=l.wrap(o.replace(/^#!.*/,"")),g=i.getRecorder(),v=n._getCachedDataPath(s,_),E={filename:_};let I;try{const D=n._fs.readFileSync(v);I=D.slice(0,16),E.cachedData=D.slice(16),g.record(60,v)}catch{g.record(61,v)}const C=new n._vm.Script(f,E),P=C.runInThisContext(E),w=n._path.dirname(_),R=d(this),U=[this.exports,R,this,_,w,process,_commonjsGlobal,Buffer],b=P.apply(this.exports,U);return n._handleCachedData(C,f,v,!E.cachedData,i),n._verifyCachedData(C,f,v,I,i),b}}load(e,i,s,n){const l=e.getConfig().getOptionsLiteral(),d=c(e.getRecorder(),l.nodeRequire||u.global.nodeRequire),o=l.nodeInstrumenter||function(f){return f};this._init(d),this._initNodeRequire(d,e);let _=e.getRecorder();if(/^node\|/.test(i)){let f=i.split("|"),g=null;try{g=d(f[1])}catch(v){n(v);return}e.enqueueDefineAnonymousModule([],()=>g),s()}else{i=u.Utilities.fileUriToFilePath(this._env.isWindows,i);const f=this._path.normalize(i),g=this._getElectronRendererScriptPathOrUri(f),v=!!l.nodeCachedData,E=v?this._getCachedDataPath(l.nodeCachedData,i):void 0;this._readSourceAndCachedData(f,E,_,(I,C,P,w)=>{if(I){n(I);return}let R;C.charCodeAt(0)===r._BOM?R=r._PREFIX+C.substring(1)+r._SUFFIX:R=r._PREFIX+C+r._SUFFIX,R=o(R,f);const U={filename:g,cachedData:P},b=this._createAndEvalScript(e,R,U,s,n);this._handleCachedData(b,R,E,v&&!P,e),this._verifyCachedData(b,R,E,w,e)})}}_createAndEvalScript(e,i,s,n,l){const d=e.getRecorder();d.record(31,s.filename);const o=new this._vm.Script(i,s),_=o.runInThisContext(s),f=e.getGlobalAMDDefineFunc();let g=!1;const v=function(){return g=!0,f.apply(null,arguments)};return v.amd=f.amd,_.call(u.global,e.getGlobalAMDRequireFunc(),v,s.filename,this._path.dirname(s.filename)),d.record(32,s.filename),g?n():l(new Error(`Didn't receive define call in ${s.filename}!`)),o}_getElectronRendererScriptPathOrUri(e){if(!this._env.isElectronRenderer)return e;let i=e.match(/^([a-z])\:(.*)/i);return i?`file:///${(i[1].toUpperCase()+":"+i[2]).replace(/\\/g,"/")}`:`file://${e}`}_getCachedDataPath(e,i){const s=this._crypto.createHash("md5").update(i,"utf8").update(e.seed,"utf8").update(process.arch,"").digest("hex"),n=this._path.basename(i).replace(/\.js$/,"");return this._path.join(e.path,`${n}-${s}.code`)}_handleCachedData(e,i,s,n,l){e.cachedDataRejected?this._fs.unlink(s,d=>{l.getRecorder().record(62,s),this._createAndWriteCachedData(e,i,s,l),d&&l.getConfig().onError(d)}):n&&this._createAndWriteCachedData(e,i,s,l)}_createAndWriteCachedData(e,i,s,n){let l=Math.ceil(n.getConfig().getOptionsLiteral().nodeCachedData.writeDelay*(1+Math.random())),d=-1,o=0,_;const f=()=>{setTimeout(()=>{_||(_=this._crypto.createHash("md5").update(i,"utf8").digest());const g=e.createCachedData();if(!(g.length===0||g.length===d||o>=5)){if(g.length<d){f();return}d=g.length,this._fs.writeFile(s,Buffer.concat([_,g]),v=>{v&&n.getConfig().onError(v),n.getRecorder().record(63,s),f()})}},l*Math.pow(4,o++))};f()}_readSourceAndCachedData(e,i,s,n){if(!i)this._fs.readFile(e,{encoding:"utf8"},n);else{let l,d,o,_=2;const f=g=>{g?n(g):--_===0&&n(void 0,l,d,o)};this._fs.readFile(e,{encoding:"utf8"},(g,v)=>{l=v,f(g)}),this._fs.readFile(i,(g,v)=>{!g&&v&&v.length>0?(o=v.slice(0,16),d=v.slice(16),s.record(60,i)):s.record(61,i),f()})}}_verifyCachedData(e,i,s,n,l){n&&(e.cachedDataRejected||setTimeout(()=>{const d=this._crypto.createHash("md5").update(i,"utf8").digest();n.equals(d)||(l.getConfig().onError(new Error(`FAILED TO VERIFY CACHED DATA, deleting stale '${s}' now, but a RESTART IS REQUIRED`)),this._fs.unlink(s,o=>{o&&l.getConfig().onError(o)}))},Math.ceil(5e3*(1+Math.random()))))}}r._BOM=65279,r._PREFIX="(function (require, define, __filename, __dirname) { ",r._SUFFIX=`
8
+ });`;function c(t,e){if(e.__$__isRecorded)return e;const i=function(n){t.record(33,n);try{return e(n)}finally{t.record(34,n)}};return i.__$__isRecorded=!0,i}u.ensureRecordedNodeRequire=c;function a(t){return new y(t)}u.createScriptLoader=a})(AMDLoader||(AMDLoader={}));var AMDLoader;(function(u){class y{constructor(t){let e=t.lastIndexOf("/");e!==-1?this.fromModulePath=t.substr(0,e+1):this.fromModulePath=""}static _normalizeModuleId(t){let e=t,i;for(i=/\/\.\//;i.test(e);)e=e.replace(i,"/");for(e=e.replace(/^\.\//g,""),i=/\/(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//;i.test(e);)e=e.replace(i,"/");return e=e.replace(/^(([^\/])|([^\/][^\/\.])|([^\/\.][^\/])|([^\/][^\/][^\/]+))\/\.\.\//,""),e}resolveModule(t){let e=t;return u.Utilities.isAbsolutePath(e)||(u.Utilities.startsWith(e,"./")||u.Utilities.startsWith(e,"../"))&&(e=y._normalizeModuleId(this.fromModulePath+e)),e}}y.ROOT=new y(""),u.ModuleIdResolver=y;class m{constructor(t,e,i,s,n,l){this.id=t,this.strId=e,this.dependencies=i,this._callback=s,this._errorback=n,this.moduleIdResolver=l,this.exports={},this.error=null,this.exportsPassedIn=!1,this.unresolvedDependenciesCount=this.dependencies.length,this._isComplete=!1}static _safeInvokeFunction(t,e){try{return{returnedValue:t.apply(u.global,e),producedError:null}}catch(i){return{returnedValue:null,producedError:i}}}static _invokeFactory(t,e,i,s){return t.shouldInvokeFactory(e)?t.shouldCatchError()?this._safeInvokeFunction(i,s):{returnedValue:i.apply(u.global,s),producedError:null}:{returnedValue:null,producedError:null}}complete(t,e,i,s){this._isComplete=!0;let n=null;if(this._callback)if(typeof this._callback=="function"){t.record(21,this.strId);let l=m._invokeFactory(e,this.strId,this._callback,i);n=l.producedError,t.record(22,this.strId),!n&&typeof l.returnedValue<"u"&&(!this.exportsPassedIn||u.Utilities.isEmpty(this.exports))&&(this.exports=l.returnedValue)}else this.exports=this._callback;if(n){let l=u.ensureError(n);l.phase="factory",l.moduleId=this.strId,l.neededBy=s(this.id),this.error=l,e.onError(l)}this.dependencies=null,this._callback=null,this._errorback=null,this.moduleIdResolver=null}onDependencyError(t){return this._isComplete=!0,this.error=t,this._errorback?(this._errorback(t),!0):!1}isComplete(){return this._isComplete}}u.Module=m;class p{constructor(){this._nextId=0,this._strModuleIdToIntModuleId=new Map,this._intModuleIdToStrModuleId=[],this.getModuleId("exports"),this.getModuleId("module"),this.getModuleId("require")}getMaxModuleId(){return this._nextId}getModuleId(t){let e=this._strModuleIdToIntModuleId.get(t);return typeof e>"u"&&(e=this._nextId++,this._strModuleIdToIntModuleId.set(t,e),this._intModuleIdToStrModuleId[e]=t),e}getStrModuleId(t){return this._intModuleIdToStrModuleId[t]}}class h{constructor(t){this.id=t}}h.EXPORTS=new h(0),h.MODULE=new h(1),h.REQUIRE=new h(2),u.RegularDependency=h;class r{constructor(t,e,i){this.id=t,this.pluginId=e,this.pluginParam=i}}u.PluginDependency=r;class c{constructor(t,e,i,s,n=0){this._env=t,this._scriptLoader=e,this._loaderAvailableTimestamp=n,this._defineFunc=i,this._requireFunc=s,this._moduleIdProvider=new p,this._config=new u.Configuration(this._env),this._hasDependencyCycle=!1,this._modules2=[],this._knownModules2=[],this._inverseDependencies2=[],this._inversePluginDependencies2=new Map,this._currentAnonymousDefineCall=null,this._recorder=null,this._buildInfoPath=[],this._buildInfoDefineStack=[],this._buildInfoDependencies=[],this._requireFunc.moduleManager=this}reset(){return new c(this._env,this._scriptLoader,this._defineFunc,this._requireFunc,this._loaderAvailableTimestamp)}getGlobalAMDDefineFunc(){return this._defineFunc}getGlobalAMDRequireFunc(){return this._requireFunc}static _findRelevantLocationInStack(t,e){let i=l=>l.replace(/\\/g,"/"),s=i(t),n=e.split(/\n/);for(let l=0;l<n.length;l++){let d=n[l].match(/(.*):(\d+):(\d+)\)?$/);if(d){let o=d[1],_=d[2],f=d[3],g=Math.max(o.lastIndexOf(" ")+1,o.lastIndexOf("(")+1);if(o=o.substr(g),o=i(o),o===s){let v={line:parseInt(_,10),col:parseInt(f,10)};return v.line===1&&(v.col-=53),v}}}throw new Error("Could not correlate define call site for needle "+t)}getBuildInfo(){if(!this._config.isBuild())return null;let t=[],e=0;for(let i=0,s=this._modules2.length;i<s;i++){let n=this._modules2[i];if(!n)continue;let l=this._buildInfoPath[n.id]||null,d=this._buildInfoDefineStack[n.id]||null,o=this._buildInfoDependencies[n.id];t[e++]={id:n.strId,path:l,defineLocation:l&&d?c._findRelevantLocationInStack(l,d):null,dependencies:o,shim:null,exports:n.exports}}return t}getRecorder(){return this._recorder||(this._config.shouldRecordStats()?this._recorder=new u.LoaderEventRecorder(this._loaderAvailableTimestamp):this._recorder=u.NullLoaderEventRecorder.INSTANCE),this._recorder}getLoaderEvents(){return this.getRecorder().getEvents()}enqueueDefineAnonymousModule(t,e){if(this._currentAnonymousDefineCall!==null)throw new Error("Can only have one anonymous define call per script file");let i=null;this._config.isBuild()&&(i=new Error("StackLocation").stack||null),this._currentAnonymousDefineCall={stack:i,dependencies:t,callback:e}}defineModule(t,e,i,s,n,l=new y(t)){let d=this._moduleIdProvider.getModuleId(t);if(this._modules2[d]){this._config.isDuplicateMessageIgnoredFor(t)||console.warn("Duplicate definition of module '"+t+"'");return}let o=new m(d,t,this._normalizeDependencies(e,l),i,s,l);this._modules2[d]=o,this._config.isBuild()&&(this._buildInfoDefineStack[d]=n,this._buildInfoDependencies[d]=(o.dependencies||[]).map(_=>this._moduleIdProvider.getStrModuleId(_.id))),this._resolve(o)}_normalizeDependency(t,e){if(t==="exports")return h.EXPORTS;if(t==="module")return h.MODULE;if(t==="require")return h.REQUIRE;let i=t.indexOf("!");if(i>=0){let s=e.resolveModule(t.substr(0,i)),n=e.resolveModule(t.substr(i+1)),l=this._moduleIdProvider.getModuleId(s+"!"+n),d=this._moduleIdProvider.getModuleId(s);return new r(l,d,n)}return new h(this._moduleIdProvider.getModuleId(e.resolveModule(t)))}_normalizeDependencies(t,e){let i=[],s=0;for(let n=0,l=t.length;n<l;n++)i[s++]=this._normalizeDependency(t[n],e);return i}_relativeRequire(t,e,i,s){if(typeof e=="string")return this.synchronousRequire(e,t);this.defineModule(u.Utilities.generateAnonymousModule(),e,i,s,null,t)}synchronousRequire(t,e=new y(t)){let i=this._normalizeDependency(t,e),s=this._modules2[i.id];if(!s)throw new Error("Check dependency list! Synchronous require cannot resolve module '"+t+"'. This is the first mention of this module!");if(!s.isComplete())throw new Error("Check dependency list! Synchronous require cannot resolve module '"+t+"'. This module has not been resolved completely yet.");if(s.error)throw s.error;return s.exports}configure(t,e){let i=this._config.shouldRecordStats();e?this._config=new u.Configuration(this._env,t):this._config=this._config.cloneAndMerge(t),this._config.shouldRecordStats()&&!i&&(this._recorder=null)}getConfig(){return this._config}_onLoad(t){if(this._currentAnonymousDefineCall!==null){let e=this._currentAnonymousDefineCall;this._currentAnonymousDefineCall=null,this.defineModule(this._moduleIdProvider.getStrModuleId(t),e.dependencies,e.callback,null,e.stack)}}_createLoadError(t,e){let i=this._moduleIdProvider.getStrModuleId(t),s=(this._inverseDependencies2[t]||[]).map(l=>this._moduleIdProvider.getStrModuleId(l));const n=u.ensureError(e);return n.phase="loading",n.moduleId=i,n.neededBy=s,n}_onLoadError(t,e){const i=this._createLoadError(t,e);this._modules2[t]||(this._modules2[t]=new m(t,this._moduleIdProvider.getStrModuleId(t),[],()=>{},null,null));let s=[];for(let d=0,o=this._moduleIdProvider.getMaxModuleId();d<o;d++)s[d]=!1;let n=!1,l=[];for(l.push(t),s[t]=!0;l.length>0;){let d=l.shift(),o=this._modules2[d];o&&(n=o.onDependencyError(i)||n);let _=this._inverseDependencies2[d];if(_)for(let f=0,g=_.length;f<g;f++){let v=_[f];s[v]||(l.push(v),s[v]=!0)}}n||this._config.onError(i)}_hasDependencyPath(t,e){let i=this._modules2[t];if(!i)return!1;let s=[];for(let l=0,d=this._moduleIdProvider.getMaxModuleId();l<d;l++)s[l]=!1;let n=[];for(n.push(i),s[t]=!0;n.length>0;){let d=n.shift().dependencies;if(d)for(let o=0,_=d.length;o<_;o++){let f=d[o];if(f.id===e)return!0;let g=this._modules2[f.id];g&&!s[f.id]&&(s[f.id]=!0,n.push(g))}}return!1}_findCyclePath(t,e,i){if(t===e||i===50)return[t];let s=this._modules2[t];if(!s)return null;let n=s.dependencies;if(n)for(let l=0,d=n.length;l<d;l++){let o=this._findCyclePath(n[l].id,e,i+1);if(o!==null)return o.push(t),o}return null}_createRequire(t){let e=(i,s,n)=>this._relativeRequire(t,i,s,n);return e.toUrl=i=>this._config.requireToUrl(t.resolveModule(i)),e.getStats=()=>this.getLoaderEvents(),e.hasDependencyCycle=()=>this._hasDependencyCycle,e.config=(i,s=!1)=>{this.configure(i,s)},e.__$__nodeRequire=u.global.nodeRequire,e}_loadModule(t){if(this._modules2[t]||this._knownModules2[t])return;this._knownModules2[t]=!0;let e=this._moduleIdProvider.getStrModuleId(t),i=this._config.moduleIdToPaths(e),s=/^@[^\/]+\/[^\/]+$/;this._env.isNode&&(e.indexOf("/")===-1||s.test(e))&&i.push("node|"+e);let n=-1,l=d=>{if(n++,n>=i.length)this._onLoadError(t,d);else{let o=i[n],_=this.getRecorder();if(this._config.isBuild()&&o==="empty:"){this._buildInfoPath[t]=o,this.defineModule(this._moduleIdProvider.getStrModuleId(t),[],null,null,null),this._onLoad(t);return}_.record(10,o),this._scriptLoader.load(this,o,()=>{this._config.isBuild()&&(this._buildInfoPath[t]=o),_.record(11,o),this._onLoad(t)},f=>{_.record(12,o),l(f)})}};l(null)}_loadPluginDependency(t,e){if(this._modules2[e.id]||this._knownModules2[e.id])return;this._knownModules2[e.id]=!0;let i=s=>{this.defineModule(this._moduleIdProvider.getStrModuleId(e.id),[],s,null,null)};i.error=s=>{this._config.onError(this._createLoadError(e.id,s))},t.load(e.pluginParam,this._createRequire(y.ROOT),i,this._config.getOptionsLiteral())}_resolve(t){let e=t.dependencies;if(e)for(let i=0,s=e.length;i<s;i++){let n=e[i];if(n===h.EXPORTS){t.exportsPassedIn=!0,t.unresolvedDependenciesCount--;continue}if(n===h.MODULE){t.unresolvedDependenciesCount--;continue}if(n===h.REQUIRE){t.unresolvedDependenciesCount--;continue}let l=this._modules2[n.id];if(l&&l.isComplete()){if(l.error){t.onDependencyError(l.error);return}t.unresolvedDependenciesCount--;continue}if(this._hasDependencyPath(n.id,t.id)){this._hasDependencyCycle=!0,console.warn("There is a dependency cycle between '"+this._moduleIdProvider.getStrModuleId(n.id)+"' and '"+this._moduleIdProvider.getStrModuleId(t.id)+"'. The cyclic path follows:");let d=this._findCyclePath(n.id,t.id,0)||[];d.reverse(),d.push(n.id),console.warn(d.map(o=>this._moduleIdProvider.getStrModuleId(o)).join(` =>
9
+ `)),t.unresolvedDependenciesCount--;continue}if(this._inverseDependencies2[n.id]=this._inverseDependencies2[n.id]||[],this._inverseDependencies2[n.id].push(t.id),n instanceof r){let d=this._modules2[n.pluginId];if(d&&d.isComplete()){this._loadPluginDependency(d.exports,n);continue}let o=this._inversePluginDependencies2.get(n.pluginId);o||(o=[],this._inversePluginDependencies2.set(n.pluginId,o)),o.push(n),this._loadModule(n.pluginId);continue}this._loadModule(n.id)}t.unresolvedDependenciesCount===0&&this._onModuleComplete(t)}_onModuleComplete(t){let e=this.getRecorder();if(t.isComplete())return;let i=t.dependencies,s=[];if(i)for(let o=0,_=i.length;o<_;o++){let f=i[o];if(f===h.EXPORTS){s[o]=t.exports;continue}if(f===h.MODULE){s[o]={id:t.strId,config:()=>this._config.getConfigForModule(t.strId)};continue}if(f===h.REQUIRE){s[o]=this._createRequire(t.moduleIdResolver);continue}let g=this._modules2[f.id];if(g){s[o]=g.exports;continue}s[o]=null}const n=o=>(this._inverseDependencies2[o]||[]).map(_=>this._moduleIdProvider.getStrModuleId(_));t.complete(e,this._config,s,n);let l=this._inverseDependencies2[t.id];if(this._inverseDependencies2[t.id]=null,l)for(let o=0,_=l.length;o<_;o++){let f=l[o],g=this._modules2[f];g.unresolvedDependenciesCount--,g.unresolvedDependenciesCount===0&&this._onModuleComplete(g)}let d=this._inversePluginDependencies2.get(t.id);if(d){this._inversePluginDependencies2.delete(t.id);for(let o=0,_=d.length;o<_;o++)this._loadPluginDependency(t.exports,d[o])}}}u.ModuleManager=c})(AMDLoader||(AMDLoader={}));var define,AMDLoader;(function(u){const y=new u.Environment;let m=null;const p=function(a,t,e){typeof a!="string"&&(e=t,t=a,a=null),(typeof t!="object"||!Array.isArray(t))&&(e=t,t=null),t||(t=["require","exports","module"]),a?m.defineModule(a,t,e,null,null):m.enqueueDefineAnonymousModule(t,e)};p.amd={jQuery:!0};const h=function(a,t=!1){m.configure(a,t)},r=function(){if(arguments.length===1){if(arguments[0]instanceof Object&&!Array.isArray(arguments[0])){h(arguments[0]);return}if(typeof arguments[0]=="string")return m.synchronousRequire(arguments[0])}if((arguments.length===2||arguments.length===3)&&Array.isArray(arguments[0])){m.defineModule(u.Utilities.generateAnonymousModule(),arguments[0],arguments[1],arguments[2],null);return}throw new Error("Unrecognized require call")};r.config=h,r.getConfig=function(){return m.getConfig().getOptionsLiteral()},r.reset=function(){m=m.reset()},r.getBuildInfo=function(){return m.getBuildInfo()},r.getStats=function(){return m.getLoaderEvents()},r.define=p;function c(){if(typeof u.global.require<"u"||typeof require<"u"){const a=u.global.require||require;if(typeof a=="function"&&typeof a.resolve=="function"){const t=u.ensureRecordedNodeRequire(m.getRecorder(),a);u.global.nodeRequire=t,r.nodeRequire=t,r.__$__nodeRequire=t}}y.isNode&&!y.isElectronRenderer&&!y.isElectronNodeIntegrationWebWorker?module.exports=r:(y.isElectronRenderer||(u.global.define=p),u.global.require=r)}u.init=c,(typeof u.global.define!="function"||!u.global.define.amd)&&(m=new u.ModuleManager(y,u.createScriptLoader(y),p,r,u.Utilities.getHighPerformanceTimestamp()),typeof u.global.require<"u"&&typeof u.global.require!="function"&&r.config(u.global.require),define=function(){return p.apply(null,arguments)},define.amd=p.amd,typeof doNotInitLoader>"u"&&c())})(AMDLoader||(AMDLoader={}));
10
+
11
+ //# sourceMappingURL=../../min-maps/vs/loader.js.map
@@ -0,0 +1,9 @@
1
+ // Worker bootstrap for the vendored Monaco build. The language workers
2
+ // (tsWorker & friends) are AMD modules, so they need the loader inside the
3
+ // worker first; the module to run arrives as the query string:
4
+ // worker-boot.js?vs/language/typescript/tsWorker
5
+ self.MonacoEnvironment = { baseUrl: location.origin + '/vendor/monaco/' };
6
+ importScripts(location.origin + '/vendor/monaco/vs/loader.js');
7
+ require.config({ paths: { vs: location.origin + '/vendor/monaco/vs' } });
8
+ const mod = decodeURIComponent(location.search.slice(1));
9
+ require([mod], () => {}, (err) => { throw err; });
@@ -0,0 +1,36 @@
1
+ // HTML to readable text, for the docs fetch. Not a parser and not trying to be:
2
+ // the output is fed to a language model as context, so what matters is that the
3
+ // prose survives and the markup, scripts and styles do not.
4
+ //
5
+ // Order is the whole trick. Script and style bodies go first — their contents are
6
+ // text, not tags, so stripping tags first would leave a page of minified
7
+ // JavaScript behind. The title is lifted before the general tag strip, because
8
+ // after it there is no way to tell the title from the first paragraph. Entities
9
+ // are decoded last, so a `&lt;script&gt;` written *about* HTML in the docs
10
+ // cannot turn back into markup that the earlier passes would have removed.
11
+
12
+ // Enough context for a model to summarise from without sending a whole site.
13
+ const MAX_TEXT = 14000;
14
+
15
+ const ENTITIES = {
16
+ '&nbsp;': ' ', '&amp;': '&', '&lt;': '<', '&gt;': '>', '&quot;': '"', '&#39;': "'",
17
+ };
18
+
19
+ export function htmlToText(html, limit = MAX_TEXT) {
20
+ let s = String(html);
21
+ s = s.replace(/<script[\s\S]*?<\/script>/gi, ' ');
22
+ s = s.replace(/<style[\s\S]*?<\/style>/gi, ' ');
23
+
24
+ const rawTitle = (s.match(/<title[^>]*>([\s\S]*?)<\/title>/i) || [, ''])[1];
25
+ const title = collapse(rawTitle.replace(/<[^>]+>/g, ' '));
26
+
27
+ s = s.replace(/<[^>]+>/g, ' ');
28
+ s = s.replace(/&nbsp;|&amp;|&lt;|&gt;|&quot;|&#39;/g, (m) => ENTITIES[m]);
29
+ // Horizontal whitespace collapses but newlines survive as paragraph breaks:
30
+ // a docs page read as one long line loses the structure a summary needs.
31
+ s = s.replace(/[ \t ]+/g, ' ').replace(/\n\s*\n+/g, '\n\n').trim();
32
+
33
+ return { title, text: s.slice(0, limit) };
34
+ }
35
+
36
+ const collapse = (s) => s.replace(/\s+/g, ' ').trim();
@@ -0,0 +1,25 @@
1
+ // GET /api/diff and GET /api/diff/refs — Git diff and branch endpoints.
2
+
3
+ import { getGitDiff, getGitRefs } from './gitDiff.js';
4
+ import { sendError, sendJSON } from './http.js';
5
+ import { getSession } from './sessions.js';
6
+
7
+ export async function handleDiffRefs(res, scanId) {
8
+ const session = getSession(scanId);
9
+ if (!session) return sendError(res, 404, 'Scan session not found.');
10
+
11
+ const refs = await getGitRefs(session.root);
12
+ sendJSON(res, 200, refs);
13
+ }
14
+
15
+ export async function handleDiff(res, scanId, queryParams = {}) {
16
+ const session = getSession(scanId);
17
+ if (!session) return sendError(res, 404, 'Scan session not found.');
18
+
19
+ const base = queryParams.get('base') || '';
20
+ const head = queryParams.get('head') || '';
21
+ const file = queryParams.get('file') || '';
22
+
23
+ const diff = await getGitDiff(session.root, { base, head, file });
24
+ sendJSON(res, 200, diff);
25
+ }
@@ -0,0 +1,67 @@
1
+ // POST /api/doc — fetch a library's official documentation page as text.
2
+ //
3
+ // This exists because the browser cannot: docs sites do not send CORS headers,
4
+ // so the page has no way to read them. That makes this endpoint a fetcher acting
5
+ // on behalf of whoever can reach it, which is the definition of an SSRF hazard,
6
+ // and the reason for the two gates below.
7
+ //
8
+ // https only, and a host allowlist. The allowlist is not written here — it is
9
+ // derived from the docs URLs `shared/analyzer/stack.js` already knows, which
10
+ // means the set of fetchable hosts is exactly the set of hosts a scanned
11
+ // dependency can point at. Nothing else is reachable: no private addresses, no
12
+ // loopback, no arbitrary sites, and no host that drifted into a hand-kept list.
13
+
14
+ import { DOC_HOSTS } from '../shared/analyzer/stack.js';
15
+ import { htmlToText } from './htmlText.js';
16
+ import { sendError, sendJSON } from './http.js';
17
+
18
+ const FETCH_TIMEOUT_MS = 12_000;
19
+
20
+ export function isAllowedDocHost(hostname) {
21
+ const host = String(hostname).replace(/^www\./, '').toLowerCase();
22
+ // Subdomains of an allowed host are allowed — docs sites move between
23
+ // `example.com` and `docs.example.com` and the allowlist names one of them.
24
+ return DOC_HOSTS.some((allowed) => host === allowed || host.endsWith('.' + allowed));
25
+ }
26
+
27
+ // A failure here is not fatal to the caller: `about.js` falls back to summarising
28
+ // the library from the model's own knowledge when no text comes back. That is
29
+ // what makes it safe to refuse in the ambiguous cases below rather than guess.
30
+ //
31
+ // `fetchImpl` is injectable so the redirect check can be tested without a
32
+ // docs site that redirects.
33
+ export async function handleDocs(res, body, fetchImpl = fetch) {
34
+ if (!body || typeof body.url !== 'string') return sendError(res, 400, 'Bad url.');
35
+
36
+ let url;
37
+ try {
38
+ url = new URL(body.url);
39
+ } catch {
40
+ return sendError(res, 400, 'Bad url.');
41
+ }
42
+
43
+ if (url.protocol !== 'https:') return sendError(res, 400, 'Only https docs are fetched.');
44
+ if (!isAllowedDocHost(url.hostname)) {
45
+ return sendError(res, 403, 'That is not an allowed docs site.');
46
+ }
47
+
48
+ try {
49
+ const response = await fetchImpl(url.toString(), {
50
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
51
+ // Redirects are followed because docs sites are full of them, and checked
52
+ // again on the way out. An allowlisted host with an open redirect would
53
+ // otherwise be a way through this guard to anywhere — including the
54
+ // link-local metadata address that is the reason the guard exists.
55
+ redirect: 'follow',
56
+ headers: { 'user-agent': 'onboarder/1.0' },
57
+ });
58
+ const landed = new URL(response.url || url.toString());
59
+ if (!isAllowedDocHost(landed.hostname)) {
60
+ return sendError(res, 403, 'That page redirected somewhere we do not fetch from.');
61
+ }
62
+ const { title, text } = htmlToText(await response.text());
63
+ sendJSON(res, 200, { url: landed.toString(), title, text, status: response.status });
64
+ } catch (err) {
65
+ sendError(res, 502, 'Could not fetch: ' + err.message);
66
+ }
67
+ }
@@ -0,0 +1,36 @@
1
+ // GET /api/file?scan=…&path=… — one file's text, for the code viewer and for the
2
+ // AI explainer's context.
3
+ //
4
+ // This is the only endpoint that returns the contents of something on the
5
+ // person's disk, which makes it the one worth being strict at. Three gates, and
6
+ // none of them is authentication: the scan id has to name a live session, the
7
+ // path has to resolve inside that session's root, and the file has to be small
8
+ // enough that reading it is not itself the problem. The router adds a fourth —
9
+ // it is the single GET that the cross-origin check applies to, because a page on
10
+ // another site could otherwise read files through the browser.
11
+
12
+ import { promises as fs } from 'node:fs';
13
+
14
+ import { sendError, sendText } from './http.js';
15
+ import { resolveInside } from './paths.js';
16
+ import { getSession } from './sessions.js';
17
+
18
+ // Code, not assets. Past this the viewer would choke anyway, and a 200 MB
19
+ // checked-in binary should not be buffered into a response to find that out.
20
+ const MAX_FILE_BYTES = 200 * 1024;
21
+
22
+ export async function handleFile(res, scanId, relPath) {
23
+ const session = getSession(scanId);
24
+ if (!session) return sendError(res, 404, 'That scan is gone. Rescan the repo.');
25
+
26
+ const abs = resolveInside(session.root, relPath);
27
+ if (!abs) return sendError(res, 400, 'Bad path.');
28
+
29
+ const stat = await fs.stat(abs).catch(() => null);
30
+ if (!stat?.isFile()) return sendError(res, 404, 'No such file in the repo.');
31
+ if (stat.size > MAX_FILE_BYTES) {
32
+ return sendError(res, 413, 'That file is too large to send around.');
33
+ }
34
+
35
+ sendText(res, 200, await fs.readFile(abs, 'utf8'));
36
+ }
@@ -0,0 +1,63 @@
1
+ import { execFile } from 'node:child_process';
2
+ import { promisify } from 'node:util';
3
+ import { resolveInside } from './paths.js';
4
+ import { getSession } from './sessions.js';
5
+ import { sendError, sendJSON } from './http.js';
6
+ import { promises as fs } from 'node:fs';
7
+
8
+ const execAsync = promisify(execFile);
9
+
10
+ export function parsePorcelainBlame(stdout) {
11
+ const lines = [];
12
+ const linesArr = stdout.split('\n');
13
+ let currentCommit = {};
14
+ let currentLine = null;
15
+ const commits = new Map();
16
+
17
+ for (let i = 0; i < linesArr.length; i++) {
18
+ const line = linesArr[i];
19
+ if (!line) continue;
20
+
21
+ if (/^[0-9a-f]{40} \d+ \d+/.test(line)) {
22
+ const parts = line.split(' ');
23
+ const sha = parts[0];
24
+ const lineNo = parseInt(parts[2], 10);
25
+
26
+ currentLine = { lineNo, sha, content: '' };
27
+
28
+ if (!commits.has(sha)) {
29
+ commits.set(sha, { sha });
30
+ }
31
+ currentCommit = commits.get(sha);
32
+ } else if (line.startsWith('author ')) {
33
+ currentCommit.author = line.slice(7);
34
+ } else if (line.startsWith('author-time ')) {
35
+ currentCommit.date = new Date(parseInt(line.slice(12), 10) * 1000).toISOString();
36
+ } else if (line.startsWith('\t')) {
37
+ if (currentLine) {
38
+ currentLine.content = line.slice(1);
39
+ currentLine.author = currentCommit.author || 'Unknown';
40
+ currentLine.date = currentCommit.date || '';
41
+ lines.push(currentLine);
42
+ currentLine = null;
43
+ }
44
+ }
45
+ }
46
+ return lines;
47
+ }
48
+
49
+ export async function handleBlame(res, scanId, filePath) {
50
+ const session = getSession(scanId);
51
+ if (!session) return sendError(res, 404, 'Scan not found.');
52
+
53
+ const absPath = resolveInside(session.root, filePath);
54
+ if (!absPath) return sendError(res, 400, 'Bad path.');
55
+
56
+ try {
57
+ const { stdout } = await execAsync('git', ['blame', '--porcelain', absPath], { cwd: session.root });
58
+ const lines = parsePorcelainBlame(stdout);
59
+ return sendJSON(res, 200, { lines });
60
+ } catch (err) {
61
+ return sendJSON(res, 200, { available: false, reason: 'Git blame failed or not a git repository.' });
62
+ }
63
+ }
@@ -0,0 +1,110 @@
1
+ // The endpoints behind the topbar button:
2
+ //
3
+ // GET /api/mcp — is it running, what is it offering, what happened
4
+ // POST /api/mcp/start — start the child process
5
+ // POST /api/mcp/stop — stop it
6
+ //
7
+ // The control surface and the protocol are deliberately separate. This process
8
+ // never speaks MCP itself; it supervises a child that does. That is what makes
9
+ // "stop" real — closing stdin lets the server drain and exit on its own terms
10
+ // rather than leaving a half-torn-down process holding the scan cache.
11
+ //
12
+ // Starting a server is a side effect on the person's machine, so start and stop
13
+ // take a body like every other POST and are same-origin like every other POST.
14
+ // The GET is guarded too: the status includes the command line an agent is
15
+ // configured with, which a foreign page has no business having even though it is
16
+ // not a secret.
17
+
18
+ import { sendJSON } from './http.js';
19
+ import { mcpCommand, mcpEntryPoint } from './mcp/runner.js';
20
+
21
+ // Every handler here has the same shape: work out the answer, then let whoever is
22
+ // driving decide how it gets sent. That split exists so `config.handleMcp` — a test
23
+ // double, or an embedding that supervises MCP itself — can observe the real result
24
+ // of the real action rather than standing in for it. A hook that skipped the
25
+ // action would make a start endpoint that never starts anything look fine.
26
+ //
27
+ // The hook owns the response when present. `server/index.js` supplies none, so the
28
+ // ordinary path is exactly what it was.
29
+ function reply(res, config, method, req, result) {
30
+ if (typeof config?.handleMcp === 'function') {
31
+ config.handleMcp(method, req, res, result);
32
+ return;
33
+ }
34
+ sendJSON(res, result.status, result.body);
35
+ }
36
+
37
+ // The runner, however the caller named it. `mcp` is what `server/index.js` sets;
38
+ // `runner` is accepted because that is the obvious name and a test reaching for it
39
+ // should not have to read the index to find the convention.
40
+ function runnerFor(config) {
41
+ return config?.mcp || config?.runner || null;
42
+ }
43
+
44
+ export function handleMcpStatus(req, res, config) {
45
+ const runner = runnerFor(config);
46
+ if (!runner) {
47
+ // The app is running without the control surface (a test, or an embedding
48
+ // that drives MCP itself). Say so rather than pretending it is stopped.
49
+ return reply(res, config, 'GET /api/mcp', req, {
50
+ status: 200,
51
+ body: {
52
+ running: false,
53
+ state: 'unavailable',
54
+ reason: 'MCP supervision is not enabled in this process.',
55
+ tools: [],
56
+ },
57
+ });
58
+ }
59
+ reply(res, config, 'GET /api/mcp', req, { status: 200, body: runner.status() });
60
+ }
61
+
62
+ export async function handleMcpStart(req, res, config) {
63
+ const runner = runnerFor(config);
64
+ if (!runner) return reply(res, config, 'POST /api/mcp/start', req, { status: 501, body: { error: 'MCP supervision is not enabled in this process.' } });
65
+ try {
66
+ const status = await runner.start();
67
+ reply(res, config, 'POST /api/mcp/start', req, { status: 200, body: status });
68
+ } catch (err) {
69
+ // A start that cannot happen is usually a missing Node, a bad path, or a
70
+ // child that failed its handshake — the message says which, because the
71
+ // person clicking the button can only fix one of those three.
72
+ reply(res, config, 'POST /api/mcp/start', req, { status: 500, body: { error: err.message || 'The MCP server could not be started.' } });
73
+ }
74
+ }
75
+
76
+ export async function handleMcpStop(req, res, config) {
77
+ const runner = runnerFor(config);
78
+ if (!runner) return reply(res, config, 'POST /api/mcp/stop', req, { status: 501, body: { error: 'MCP supervision is not enabled in this process.' } });
79
+ try {
80
+ const status = await runner.stop();
81
+ reply(res, config, 'POST /api/mcp/stop', req, { status: 200, body: status });
82
+ } catch (err) {
83
+ reply(res, config, 'POST /api/mcp/stop', req, { status: 500, body: { error: err.message || 'The MCP server could not be stopped.' } });
84
+ }
85
+ }
86
+
87
+ // The command an agent harness is configured with, shown in the panel so nobody
88
+ // has to read the README to find it. The paths come from the same function that
89
+ // starts the child, so the copy-paste text cannot drift from what actually runs.
90
+ export function handleMcpCommand(req, res, config) {
91
+ // The absolute path, not the relative one the runner uses: this text gets
92
+ // pasted into a client config that spawns the command from the harness's own
93
+ // working directory, where a relative path does not resolve.
94
+ const entry = mcpEntryPoint();
95
+ reply(res, config, 'GET /api/mcp/command', req, {
96
+ status: 200,
97
+ body: {
98
+ command: entry,
99
+ relative: mcpCommand(),
100
+ transports: ['stdio'],
101
+ // The two config shapes a client is overwhelmingly likely to want. Both use
102
+ // the absolute path, for the reason above.
103
+ examples: [
104
+ { name: 'node', command: process.execPath, args: [entry] },
105
+ { name: 'node (assuming node is on PATH)', command: 'node', args: [entry] },
106
+ ],
107
+ docs: 'https://modelcontextprotocol.io/docs/develop/connect-local-servers',
108
+ },
109
+ });
110
+ }
@@ -0,0 +1,119 @@
1
+ // POST /api/scan and DELETE /api/scan/:cloneId — the endpoint the whole app
2
+ // starts from.
3
+ //
4
+ // Three ways in, one way out. A local path, a git URL to clone, or `demo: true`
5
+ // meaning "scan Onboarder itself", which is how the app has something to show
6
+ // before you have chosen anything. All three end at a root directory, and from
7
+ // there the work is the same three calls the browser would make against its own
8
+ // file source: scan, detect the manifest, compute the facts.
9
+ //
10
+ // The response is deliberately whole. The front end gets scan, facts and
11
+ // manifest in one round trip and holds them for the session, because every view
12
+ // is a projection of those three and re-fetching per view would put a network
13
+ // hop inside a filter keystroke. The search index travels the same way: built
14
+ // once at scan time, attached to the session, and queried without re-walking
15
+ // the tree.
16
+
17
+ import { promises as fs } from 'node:fs';
18
+ import path from 'node:path';
19
+
20
+ import { computeFacts } from '../shared/analyzer/graph.js';
21
+ import { scanRepo } from '../shared/analyzer/scan.js';
22
+ import { detectManifest } from '../shared/analyzer/services.js';
23
+ import { analyzeHistory, unavailableHistory } from '../shared/analyzer/history.js';
24
+ import { buildSearchIndex } from './searchIndex.js';
25
+ import { nodeFileSource } from './fileSourceNode.js';
26
+ import { assertGitUrl, cloneRepo, removeClone, repoNameFromUrl } from './gitClone.js';
27
+ import { gitLog, parseGitLog } from './gitHistory.js';
28
+ import { sendError, sendJSON } from './http.js';
29
+ import { expandHome } from './paths.js';
30
+ import { closeClone, isCloneId, openSession } from './sessions.js';
31
+
32
+ export async function handleScan(res, body, { projectRoot }) {
33
+ const target = await resolveTarget(body, projectRoot);
34
+ if (target.error) return sendError(res, 400, target.error);
35
+
36
+ const { root, cloneDir, cloneId, gitMeta } = target;
37
+ try {
38
+ const source = nodeFileSource(root);
39
+ const scan = await scanRepo(source);
40
+ if (gitMeta) {
41
+ // Show the repo's real name up top; keep the temp dir name for honesty,
42
+ // so a path in the UI is still a path you could go and look at.
43
+ scan.name = gitMeta.repoName;
44
+ scan.tempId = path.basename(root);
45
+ scan.gitUrl = gitMeta.gitUrl;
46
+ }
47
+ const manifest = await detectManifest(source);
48
+ const facts = computeFacts(scan, manifest);
49
+
50
+ // The search index is built from the same files the scanner accepted.
51
+ // Doing it here, against the same FileSource, means a search request
52
+ // becomes a Map lookup plus a scoring pass; the per-file reads the old
53
+ // `/api/search` did on first use are gone. Cap behaviour and skip rules
54
+ // live in `searchIndex.js` and are tested there.
55
+ const codeFiles = scan.files.map((f) => f.path);
56
+ const searchIndexData = await buildSearchIndex(source, codeFiles);
57
+
58
+ const history = await collectHistory(root, scan);
59
+ const scanId = openSession({ root, cloneDir, searchIndex: searchIndexData });
60
+ sendJSON(res, 200, { scan, facts, manifest, history, scanId, cloneId });
61
+ } catch (err) {
62
+ // A clone that was never scanned successfully has no session to evict it
63
+ // later, so it has to go now or it is a temp directory nobody owns.
64
+ if (cloneDir) await removeClone(cloneDir);
65
+ sendError(res, 500, 'The scan failed: ' + err.message);
66
+ }
67
+ }
68
+
69
+ // History is a bonus layer over the scan, never a reason for it to fail. When
70
+ // git is missing, the folder has no .git, or the log somehow blows up, the
71
+ // payload carries the honest unavailable shape instead — the UI says why
72
+ // rather than inventing zeros.
73
+ async function collectHistory(root, scan) {
74
+ try {
75
+ const log = await gitLog(root);
76
+ if (!log.ok) return unavailableHistory(log.reason);
77
+ return analyzeHistory(scan, parseGitLog(log.text), { totalCommits: log.totalCommits });
78
+ } catch {
79
+ return unavailableHistory('The history could not be read — the scan itself is unaffected.');
80
+ }
81
+ }
82
+
83
+ // The three request shapes, reduced to a directory. Cloning happens here, which
84
+ // is why this returns rather than sends: the caller owns cleanup if the scan that
85
+ // follows fails.
86
+ async function resolveTarget(body, projectRoot) {
87
+ if (body.demo) return { root: projectRoot };
88
+
89
+ if (body.path) {
90
+ const root = expandHome(String(body.path));
91
+ const stat = await fs.stat(root).catch(() => null);
92
+ if (!stat?.isDirectory()) {
93
+ return { error: 'No folder at ' + root + '. Check the path and try again.' };
94
+ }
95
+ return { root };
96
+ }
97
+
98
+ if (body.gitUrl) {
99
+ const url = assertGitUrl(body.gitUrl);
100
+ const clone = await cloneRepo(url);
101
+ return {
102
+ root: clone.dir,
103
+ cloneDir: clone.dir,
104
+ cloneId: clone.id,
105
+ gitMeta: { gitUrl: url, repoName: repoNameFromUrl(url) },
106
+ };
107
+ }
108
+
109
+ return { error: 'Send a path, a gitUrl, or { demo: true }.' };
110
+ }
111
+
112
+ // The page sends this when it is done with a cloned repo. Nothing is reported
113
+ // about whether the clone was there: the browser cannot act on the difference,
114
+ // and an unload-time request that 404s looks like a bug in the console.
115
+ export async function handleCleanup(res, cloneId) {
116
+ if (!isCloneId(cloneId)) return sendError(res, 400, 'That is not a clone id.');
117
+ await closeClone(cloneId);
118
+ sendJSON(res, 200, { ok: true });
119
+ }