loukai-app 0.3.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 (290) hide show
  1. package/README.md +558 -0
  2. package/bin/loukai.js +32 -0
  3. package/package.json +243 -0
  4. package/src/main/appState.js +250 -0
  5. package/src/main/audioEngine.js +478 -0
  6. package/src/main/creator/conversionService.js +503 -0
  7. package/src/main/creator/downloadManager.js +1128 -0
  8. package/src/main/creator/ffmpegService.js +487 -0
  9. package/src/main/creator/installLogger.js +51 -0
  10. package/src/main/creator/keyDetection.js +212 -0
  11. package/src/main/creator/llmService.js +370 -0
  12. package/src/main/creator/lrclibService.js +340 -0
  13. package/src/main/creator/python/crepe_runner.py +189 -0
  14. package/src/main/creator/python/demucs_runner.py +158 -0
  15. package/src/main/creator/python/whisper_runner.py +172 -0
  16. package/src/main/creator/pythonRunner.js +268 -0
  17. package/src/main/creator/stemBuilder.js +491 -0
  18. package/src/main/creator/systemChecker.js +474 -0
  19. package/src/main/handlers/appHandlers.js +45 -0
  20. package/src/main/handlers/audioHandlers.js +33 -0
  21. package/src/main/handlers/autotuneHandlers.js +28 -0
  22. package/src/main/handlers/canvasHandlers.js +84 -0
  23. package/src/main/handlers/creatorHandlers.js +159 -0
  24. package/src/main/handlers/editorHandlers.js +98 -0
  25. package/src/main/handlers/effectsHandlers.js +100 -0
  26. package/src/main/handlers/fileHandlers.js +45 -0
  27. package/src/main/handlers/index.js +78 -0
  28. package/src/main/handlers/libraryHandlers.js +96 -0
  29. package/src/main/handlers/mixerHandlers.js +64 -0
  30. package/src/main/handlers/playerHandlers.js +39 -0
  31. package/src/main/handlers/preferencesHandlers.js +46 -0
  32. package/src/main/handlers/queueHandlers.js +81 -0
  33. package/src/main/handlers/rendererHandlers.js +63 -0
  34. package/src/main/handlers/settingsHandlers.js +42 -0
  35. package/src/main/handlers/webServerHandlers.js +105 -0
  36. package/src/main/main.js +2351 -0
  37. package/src/main/preload.js +252 -0
  38. package/src/main/settingsManager.js +139 -0
  39. package/src/main/statePersistence.js +193 -0
  40. package/src/main/utils/pathValidator.js +112 -0
  41. package/src/main/webServer.js +2535 -0
  42. package/src/native/autotune.js +417 -0
  43. package/src/renderer/adapters/ElectronBridge.js +677 -0
  44. package/src/renderer/canvas.html +80 -0
  45. package/src/renderer/components/App.jsx +303 -0
  46. package/src/renderer/components/AppRoot.jsx +37 -0
  47. package/src/renderer/components/AudioDeviceSettings.jsx +145 -0
  48. package/src/renderer/components/EffectsPanelWrapper.jsx +267 -0
  49. package/src/renderer/components/MixerTab.jsx +233 -0
  50. package/src/renderer/components/MixerTabWrapper.jsx +31 -0
  51. package/src/renderer/components/PortalSelect.jsx +239 -0
  52. package/src/renderer/components/QueueTab.jsx +116 -0
  53. package/src/renderer/components/RequestsListWrapper.jsx +78 -0
  54. package/src/renderer/components/ServerTab.jsx +472 -0
  55. package/src/renderer/components/SongInfoBarWrapper.jsx +77 -0
  56. package/src/renderer/components/StatusBar.jsx +92 -0
  57. package/src/renderer/components/TabNavigation.jsx +77 -0
  58. package/src/renderer/components/TransportControlsWrapper.jsx +69 -0
  59. package/src/renderer/components/creator/CreateTab.jsx +1236 -0
  60. package/src/renderer/dist/assets/kaiPlayer-CoMx__a_.js +2 -0
  61. package/src/renderer/dist/assets/kaiPlayer-CoMx__a_.js.map +1 -0
  62. package/src/renderer/dist/assets/microphoneEngine-BaCUhhQc.js +2 -0
  63. package/src/renderer/dist/assets/microphoneEngine-BaCUhhQc.js.map +1 -0
  64. package/src/renderer/dist/assets/player-DVrqp7N5.js +3 -0
  65. package/src/renderer/dist/assets/player-DVrqp7N5.js.map +1 -0
  66. package/src/renderer/dist/assets/songLoaders-BaTgGib4.js +2 -0
  67. package/src/renderer/dist/assets/songLoaders-BaTgGib4.js.map +1 -0
  68. package/src/renderer/dist/assets/webrtcManager-BhCHWceK.js +2 -0
  69. package/src/renderer/dist/assets/webrtcManager-BhCHWceK.js.map +1 -0
  70. package/src/renderer/dist/js/autoTuneWorklet.js +224 -0
  71. package/src/renderer/dist/js/micPitchDetectorWorklet.js +137 -0
  72. package/src/renderer/dist/js/musicAnalysisWorklet.js +216 -0
  73. package/src/renderer/dist/js/phaseVocoderWorklet.js +341 -0
  74. package/src/renderer/dist/js/soundtouch-worklet.js +1395 -0
  75. package/src/renderer/dist/renderer.css +1 -0
  76. package/src/renderer/dist/renderer.js +62 -0
  77. package/src/renderer/dist/renderer.js.map +1 -0
  78. package/src/renderer/dist/renderer.woff2 +0 -0
  79. package/src/renderer/hooks/useKeyboardShortcuts.js +154 -0
  80. package/src/renderer/index.html +24 -0
  81. package/src/renderer/index.html.backup +372 -0
  82. package/src/renderer/js/PlayerInterface.js +267 -0
  83. package/src/renderer/js/autoTuneWorklet.js +224 -0
  84. package/src/renderer/js/butterchurnVerify.js +46 -0
  85. package/src/renderer/js/canvas-app.js +114 -0
  86. package/src/renderer/js/cdgPlayer.js +685 -0
  87. package/src/renderer/js/kaiPlayer.js +1200 -0
  88. package/src/renderer/js/karaokeRenderer.js +3392 -0
  89. package/src/renderer/js/micPitchDetectorWorklet.js +137 -0
  90. package/src/renderer/js/microphoneEngine.js +656 -0
  91. package/src/renderer/js/musicAnalysisWorklet.js +216 -0
  92. package/src/renderer/js/phaseVocoderWorklet.js +341 -0
  93. package/src/renderer/js/player.js +232 -0
  94. package/src/renderer/js/referencePitchTracker.js +130 -0
  95. package/src/renderer/js/songLoaders.js +334 -0
  96. package/src/renderer/js/soundtouch-worklet.js +1395 -0
  97. package/src/renderer/js/webrtcManager.js +511 -0
  98. package/src/renderer/lib/butterchurn.min.js +6739 -0
  99. package/src/renderer/lib/butterchurnPresets.min.js +1 -0
  100. package/src/renderer/lib/cdgraphics-wrapper.js +16 -0
  101. package/src/renderer/lib/cdgraphics.js +299 -0
  102. package/src/renderer/public/js/autoTuneWorklet.js +224 -0
  103. package/src/renderer/public/js/micPitchDetectorWorklet.js +137 -0
  104. package/src/renderer/public/js/musicAnalysisWorklet.js +216 -0
  105. package/src/renderer/public/js/phaseVocoderWorklet.js +341 -0
  106. package/src/renderer/public/js/soundtouch-worklet.js +1395 -0
  107. package/src/renderer/react-entry.jsx +44 -0
  108. package/src/renderer/styles/tailwind.css +106 -0
  109. package/src/renderer/utils/qrCodeGenerator.js +98 -0
  110. package/src/renderer/vite.config.js +31 -0
  111. package/src/shared/adapters/BridgeInterface.js +195 -0
  112. package/src/shared/components/EffectsPanel.jsx +177 -0
  113. package/src/shared/components/LibraryPanel.jsx +701 -0
  114. package/src/shared/components/LineDetailCanvas.jsx +167 -0
  115. package/src/shared/components/LyricLine.jsx +505 -0
  116. package/src/shared/components/LyricRejection.jsx +84 -0
  117. package/src/shared/components/LyricSuggestion.jsx +80 -0
  118. package/src/shared/components/LyricsEditorCanvas.jsx +271 -0
  119. package/src/shared/components/MixerPanel.jsx +94 -0
  120. package/src/shared/components/PlayerControls.jsx +206 -0
  121. package/src/shared/components/PortalSelect.jsx +239 -0
  122. package/src/shared/components/QueueList.jsx +365 -0
  123. package/src/shared/components/QuickSearch.jsx +126 -0
  124. package/src/shared/components/RequestsList.jsx +121 -0
  125. package/src/shared/components/SongEditor.jsx +1362 -0
  126. package/src/shared/components/SongInfoBar.jsx +81 -0
  127. package/src/shared/components/ThemeToggle.jsx +106 -0
  128. package/src/shared/components/Toast.jsx +30 -0
  129. package/src/shared/components/VisualizationSettings.jsx +243 -0
  130. package/src/shared/constants.js +95 -0
  131. package/src/shared/context/BridgeContext.jsx +32 -0
  132. package/src/shared/contexts/AudioContext.jsx +37 -0
  133. package/src/shared/contexts/PlayerContext.jsx +66 -0
  134. package/src/shared/contexts/SettingsContext.jsx +50 -0
  135. package/src/shared/defaults.js +158 -0
  136. package/src/shared/formatUtils.js +59 -0
  137. package/src/shared/formatUtils.test.js +207 -0
  138. package/src/shared/hooks/useAppState.js +97 -0
  139. package/src/shared/hooks/useAudioEngine.js +264 -0
  140. package/src/shared/hooks/usePlayer.js +89 -0
  141. package/src/shared/hooks/useSettingsPersistence.js +74 -0
  142. package/src/shared/hooks/useWebRTC.js +118 -0
  143. package/src/shared/ipcContracts.js +299 -0
  144. package/src/shared/package.json +3 -0
  145. package/src/shared/services/creatorService.js +373 -0
  146. package/src/shared/services/creatorService.test.js +413 -0
  147. package/src/shared/services/editorService.js +213 -0
  148. package/src/shared/services/editorService.test.js +219 -0
  149. package/src/shared/services/effectsService.js +271 -0
  150. package/src/shared/services/effectsService.test.js +418 -0
  151. package/src/shared/services/libraryService.js +438 -0
  152. package/src/shared/services/libraryService.test.js +474 -0
  153. package/src/shared/services/mixerService.js +172 -0
  154. package/src/shared/services/mixerService.test.js +399 -0
  155. package/src/shared/services/playerService.js +221 -0
  156. package/src/shared/services/playerService.test.js +357 -0
  157. package/src/shared/services/preferencesService.js +219 -0
  158. package/src/shared/services/queueService.js +226 -0
  159. package/src/shared/services/queueService.test.js +430 -0
  160. package/src/shared/services/requestsService.js +155 -0
  161. package/src/shared/services/requestsService.test.js +362 -0
  162. package/src/shared/services/serverSettingsService.js +151 -0
  163. package/src/shared/services/settingsService.js +257 -0
  164. package/src/shared/services/settingsService.test.js +295 -0
  165. package/src/shared/state/StateManager.js +263 -0
  166. package/src/shared/utils/audio.js +42 -0
  167. package/src/shared/utils/format.js +32 -0
  168. package/src/shared/utils/lyricsUtils.js +162 -0
  169. package/src/test/setup.js +40 -0
  170. package/src/utils/cdgLoader.js +180 -0
  171. package/src/utils/m4aLoader.js +333 -0
  172. package/src/web/App.jsx +578 -0
  173. package/src/web/adapters/WebBridge.js +428 -0
  174. package/src/web/components/PlayerSettingsPanel.jsx +231 -0
  175. package/src/web/components/SongSearch.jsx +180 -0
  176. package/src/web/dist/assets/index-0H-RnRrV.js +51 -0
  177. package/src/web/dist/assets/index-0H-RnRrV.js.map +1 -0
  178. package/src/web/dist/assets/index-DYW2zB0u.css +1 -0
  179. package/src/web/dist/index.html +15 -0
  180. package/src/web/index.html +14 -0
  181. package/src/web/main.jsx +10 -0
  182. package/src/web/package-lock.json +1765 -0
  183. package/src/web/pages/SongRequestPage.jsx +619 -0
  184. package/src/web/styles/tailwind.css +68 -0
  185. package/src/web/vite.config.js +27 -0
  186. package/static/fonts/material-icons.woff2 +0 -0
  187. package/static/images/butterchurn-screenshots/Aderrasi - Potion of Spirits.png +0 -0
  188. package/static/images/butterchurn-screenshots/Aderrasi - Songflower _Moss Posy_.png +0 -0
  189. package/static/images/butterchurn-screenshots/Aderrasi - Storm of the Eye _Thunder_ - mash0000 - quasi pseudo meta concentrics.png +0 -0
  190. package/static/images/butterchurn-screenshots/Aderrasi _ Geiss - Airhandler _Kali Mix_ - Canvas Mix.png +0 -0
  191. package/static/images/butterchurn-screenshots/An AdamFX n Martin Infusion 2 flexi - Why The Sky Looks Diffrent Today - AdamFx n Martin Infusion - Tack Tile Disfunction B.png +0 -0
  192. package/static/images/butterchurn-screenshots/Cope - The Neverending Explosion of Red Liquid Fire.png +0 -0
  193. proton lights __Krash_s beat code_ _Phat_remix02b.png +0 -0
  194. package/static/images/butterchurn-screenshots/Eo_S_ _ Phat - cubetrace - v2.png +0 -0
  195. package/static/images/butterchurn-screenshots/Eo_S_ _ Zylot - skylight _Stained Glass Majesty mix_.png +0 -0
  196. package/static/images/butterchurn-screenshots/Flexi - alien fish pond.png +0 -0
  197. package/static/images/butterchurn-screenshots/Flexi - area 51.png +0 -0
  198. package/static/images/butterchurn-screenshots/Flexi - infused with the spiral.png +0 -0
  199. package/static/images/butterchurn-screenshots/Flexi - mindblob _shiny mix_.png +0 -0
  200. package/static/images/butterchurn-screenshots/Flexi - mindblob mix.png +0 -0
  201. package/static/images/butterchurn-screenshots/Flexi - predator-prey-spirals.png +0 -0
  202. package/static/images/butterchurn-screenshots/Flexi - smashing fractals _acid etching mix_.png +0 -0
  203. package/static/images/butterchurn-screenshots/Flexi - truly soft piece of software - this is generic texturing _Jelly_ .png +0 -0
  204. package/static/images/butterchurn-screenshots/Flexi _ Martin - astral projection.png +0 -0
  205. package/static/images/butterchurn-screenshots/Flexi _ Martin - cascading decay swing.png +0 -0
  206. package/static/images/butterchurn-screenshots/Flexi _ amandio c - piercing 05 - Kopie _2_ - Kopie.png +0 -0
  207. package/static/images/butterchurn-screenshots/Flexi _ stahlregen - jelly showoff parade.png +0 -0
  208. package/static/images/butterchurn-screenshots/Flexi_ fishbrain_ Geiss _ Martin - tokamak witchery.png +0 -0
  209. package/static/images/butterchurn-screenshots/Flexi_ martin _ geiss - dedicated to the sherwin maxawow.png +0 -0
  210. package/static/images/butterchurn-screenshots/Fumbling_Foo _ Flexi_ Martin_ Orb_ Unchained - Star Nova v7b.png +0 -0
  211. package/static/images/butterchurn-screenshots/Geiss - Cauldron - painterly 2 _saturation remix_.png +0 -0
  212. package/static/images/butterchurn-screenshots/Geiss - Reaction Diffusion 2.png +0 -0
  213. package/static/images/butterchurn-screenshots/Geiss - Spiral Artifact.png +0 -0
  214. package/static/images/butterchurn-screenshots/Geiss - Thumb Drum.png +0 -0
  215. package/static/images/butterchurn-screenshots/Geiss _ Flexi _ Martin - disconnected.png +0 -0
  216. package/static/images/butterchurn-screenshots/Geiss_ Flexi _ Stahlregen - Thumbdrum Tokamak _crossfiring aftermath jelly mashup_.png +0 -0
  217. package/static/images/butterchurn-screenshots/Goody - The Wild Vort.png +0 -0
  218. package/static/images/butterchurn-screenshots/Idiot - Star Of Annon.png +0 -0
  219. package/static/images/butterchurn-screenshots/Krash _ Illusion - Spiral Movement.png +0 -0
  220. package/static/images/butterchurn-screenshots/Martin - QBikal - Surface Turbulence IIb.png +0 -0
  221. package/static/images/butterchurn-screenshots/Martin - acid wiring.png +0 -0
  222. package/static/images/butterchurn-screenshots/Martin - charisma.png +0 -0
  223. package/static/images/butterchurn-screenshots/Martin - liquid arrows.png +0 -0
  224. package/static/images/butterchurn-screenshots/Milk Artist At our Best - FED - SlowFast Ft AdamFX n Martin - HD CosmoFX.png +0 -0
  225. package/static/images/butterchurn-screenshots/ORB - Waaa.png +0 -0
  226. package/static/images/butterchurn-screenshots/Phat_fiShbRaiN_Eo_S_Mandala_Chasers_remix.png +0 -0
  227. package/static/images/butterchurn-screenshots/Rovastar - Oozing Resistance.png +0 -0
  228. package/static/images/butterchurn-screenshots/Rovastar _ Loadus _ Geiss - FractalDrop _Triple Mix_.png +0 -0
  229. package/static/images/butterchurn-screenshots/TonyMilkdrop - Leonardo Da Vinci_s Balloon _Flexi - merry-go-round _ techstyle_.png +0 -0
  230. package/static/images/butterchurn-screenshots/TonyMilkdrop - Magellan_s Nebula _Flexi - you enter first _ multiverse_.png +0 -0
  231. package/static/images/butterchurn-screenshots/Unchained - Rewop.png +0 -0
  232. package/static/images/butterchurn-screenshots/Unchained - Unified Drag 2.png +0 -0
  233. package/static/images/butterchurn-screenshots/Unchained _ Rovastar - Wormhole Pillars _Hall of Shadows mix_.png +0 -0
  234. package/static/images/butterchurn-screenshots/Zylot - Paint Spill _Music Reactive Paint Mix_.png +0 -0
  235. package/static/images/butterchurn-screenshots/Zylot - Star Ornament.png +0 -0
  236. package/static/images/butterchurn-screenshots/Zylot - True Visionary _Final Mix_.png +0 -0
  237. package/static/images/butterchurn-screenshots/_Aderrasi - Wanderer in Curved Space - mash0000 - faclempt kibitzing meshuggana schmaltz _Geiss color mix_.png +0 -0
  238. package/static/images/butterchurn-screenshots/_Geiss - Artifact 01.png +0 -0
  239. package/static/images/butterchurn-screenshots/_Geiss - Desert Rose 2.png +0 -0
  240. package/static/images/butterchurn-screenshots/_Geiss - untitled.png +0 -0
  241. package/static/images/butterchurn-screenshots/_Mig_049.png +0 -0
  242. package/static/images/butterchurn-screenshots/_Mig_085.png +0 -0
  243. package/static/images/butterchurn-screenshots/_Rovastar _ Geiss - Hurricane Nightmare _Posterize Mix_.png +0 -0
  244. package/static/images/butterchurn-screenshots/___ Royal - Mashup _197_.png +0 -0
  245. package/static/images/butterchurn-screenshots/___ Royal - Mashup _220_.png +0 -0
  246. package/static/images/butterchurn-screenshots/___ Royal - Mashup _431_.png +0 -0
  247. package/static/images/butterchurn-screenshots/cope _ martin - mother-of-pearl.png +0 -0
  248. package/static/images/butterchurn-screenshots/fiShbRaiN _ Flexi - witchcraft 2_0.png +0 -0
  249. package/static/images/butterchurn-screenshots/flexi - bouncing balls _double mindblob neon mix_.png +0 -0
  250. package/static/images/butterchurn-screenshots/flexi - mom_ why the sky looks different today.png +0 -0
  251. package/static/images/butterchurn-screenshots/flexi - patternton_ district of media_ capitol of the united abstractions of fractopia.png +0 -0
  252. package/static/images/butterchurn-screenshots/flexi - swing out on the spiral.png +0 -0
  253. package/static/images/butterchurn-screenshots/flexi - what is the matrix.png +0 -0
  254. package/static/images/butterchurn-screenshots/flexi _ amandio c - organic _random mashup_.png +0 -0
  255. package/static/images/butterchurn-screenshots/flexi _ amandio c - organic12-3d-2_milk.png +0 -0
  256. package/static/images/butterchurn-screenshots/flexi _ fishbrain - neon mindblob grafitti.png +0 -0
  257. package/static/images/butterchurn-screenshots/flexi _ geiss - pogo cubes vs_ tokamak vs_ game of life _stahls jelly 4_5 finish_.png +0 -0
  258. package/static/images/butterchurn-screenshots/high-altitude basket unraveling - singh grooves nitrogen argon nz_.png +0 -0
  259. package/static/images/butterchurn-screenshots/martin - The Bridge of Khazad-Dum.png +0 -0
  260. package/static/images/butterchurn-screenshots/martin - angel flight.png +0 -0
  261. package/static/images/butterchurn-screenshots/martin - another kind of groove.png +0 -0
  262. package/static/images/butterchurn-screenshots/martin - bombyx mori.png +0 -0
  263. package/static/images/butterchurn-screenshots/martin - castle in the air.png +0 -0
  264. package/static/images/butterchurn-screenshots/martin - chain breaker.png +0 -0
  265. package/static/images/butterchurn-screenshots/martin - disco mix 4.png +0 -0
  266. package/static/images/butterchurn-screenshots/martin - extreme heat.png +0 -0
  267. package/static/images/butterchurn-screenshots/martin - frosty caves 2.png +0 -0
  268. package/static/images/butterchurn-screenshots/martin - fruit machine.png +0 -0
  269. package/static/images/butterchurn-screenshots/martin - ghost city.png +0 -0
  270. package/static/images/butterchurn-screenshots/martin - glass corridor.png +0 -0
  271. package/static/images/butterchurn-screenshots/martin - infinity _2010 update_.png +0 -0
  272. package/static/images/butterchurn-screenshots/martin - mandelbox explorer - high speed demo version.png +0 -0
  273. package/static/images/butterchurn-screenshots/martin - mucus cervix.png +0 -0
  274. package/static/images/butterchurn-screenshots/martin - reflections on black tiles.png +0 -0
  275. package/static/images/butterchurn-screenshots/martin - stormy sea _2010 update_.png +0 -0
  276. package/static/images/butterchurn-screenshots/martin - witchcraft reloaded.png +0 -0
  277. package/static/images/butterchurn-screenshots/martin _ flexi - diamond cutter _prismaticvortex_com_ - camille - i wish i wish i wish i was constrained.png +0 -0
  278. package/static/images/butterchurn-screenshots/martin _shadow harlequins shape code_ - fata morgana.png +0 -0
  279. package/static/images/butterchurn-screenshots/martin_ flexi_ fishbrain _ sto - enterstate _random mashup_.png +0 -0
  280. package/static/images/butterchurn-screenshots/sawtooth grin roam.png +0 -0
  281. package/static/images/butterchurn-screenshots/shifter - dark tides bdrv mix 2.png +0 -0
  282. package/static/images/butterchurn-screenshots/suksma - Rovastar - Sunflower Passion _Enlightment Mix__Phat_edit _ flexi und martin shaders - circumflex in character classes in regular expression.png +0 -0
  283. package/static/images/butterchurn-screenshots/suksma - heretical crosscut playpen.png +0 -0
  284. package/static/images/butterchurn-screenshots/suksma - uninitialized variabowl _hydroponic chronic_.png +0 -0
  285. package/static/images/butterchurn-screenshots/suksma - vector exp 1 - couldn_t not.png +0 -0
  286. package/static/images/butterchurn-screenshots/yin - 191 - Temporal singularities.png +0 -0
  287. package/static/images/logo-512.png +0 -0
  288. package/static/images/logo.png +0 -0
  289. package/static/loukai-logo.png +0 -0
  290. package/static/screenshot-generator.html +610 -0
package/README.md ADDED
@@ -0,0 +1,558 @@
1
+ # Loukai Karaoke
2
+
3
+ 🌐 **[https://loukai.com](https://loukai.com)**
4
+
5
+ **Free and open source karaoke software for playing and creating stem-based karaoke files from your own music**
6
+
7
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
8
+ [![React 19](https://img.shields.io/badge/React-19-blue)](https://react.dev/)
9
+ [![Electron 38](https://img.shields.io/badge/Electron-38-blue)](https://www.electronjs.org/)
10
+ [![Tests](https://img.shields.io/badge/tests-283-green)](./docs/PHASE2-SUMMARY.md)
11
+
12
+ Loukai is a free, open source karaoke software that runs locally on your computer to **play** and **create** karaoke files from your own music. Built on M4A Stems (MPEG-4 multi-track audio), it uses industry-standard formats compatible with DJ software, giving you full control over your personal karaoke library.
13
+
14
+ **Key highlights:**
15
+ - **Open Format**: Built on NI Stems — no vendor lock-in, works with Traktor, Mixxx, and other DJ software
16
+ - **Create Your Own**: Built-in Creator processes your audio files into stem-separated karaoke with AI-transcribed lyrics
17
+ - **Play Anywhere**: Cross-platform desktop app (Linux, Windows, macOS) with web remote control
18
+ - **Fully Open Source**: AGPL-3.0 licensed — inspect, modify, and contribute
19
+
20
+ ![Loukai Application](./Loukai_app.png)
21
+
22
+ ---
23
+
24
+ ## Features
25
+
26
+ ### Audio & Playback
27
+ - **M4A Stems Format (Primary)**: Built on [NI Stems](https://www.native-instruments.com/en/specials/stems/) with karaoke extensions
28
+ - Compatible with DJ software (Traktor, Mixxx) via standard NI Stems metadata
29
+ - Smaller file sizes than legacy formats
30
+ - Embedded lyrics with word-level timing in custom atoms
31
+ - **Real-Time Stem Control**: Individual volume, mute, and solo controls for vocals, drums, bass, and other stems
32
+ - **Legacy Format Support**: CDG/MP3 pairs
33
+ - **Dual Output Routing**: Independent PA and IEM (in-ear monitor) outputs with per-stem routing
34
+ - **High-Quality Audio**: Web Audio API with real-time processing and pitch correction
35
+ - **Auto-Tune System**: Real-time pitch correction for microphone input
36
+ - AudioWorklet processing (< 5ms latency)
37
+ - Autocorrelation pitch detection (80-800 Hz vocal range)
38
+ - Musical key support (12 major keys with scale snapping)
39
+ - Adjustable strength and speed parameters
40
+ - Phase vocoder architecture prepared for future enhancement
41
+ - **Queue Management**: Add, remove, reorder songs with drag-and-drop
42
+
43
+ ### Visual Effects
44
+ - **Butterchurn Integration**: 200+ Milkdrop-style audio-reactive visualizations
45
+ - **CDG Graphics**: Classic karaoke graphics rendering with full format support
46
+ - **Canvas Window**: Dedicated fullscreen window for visuals with multi-monitor support
47
+ - **Lyric Display**: Real-time synchronized lyrics with customizable styling
48
+ - **QR Code Display**: Scannable QR code on canvas for easy mobile device connection (configurable)
49
+ - **Queue Display**: "Next up" overlay showing upcoming 1-3 songs with singer names (configurable)
50
+ - **Singer Identification**: Color-coded singer names (yellow for guests, white for KJ)
51
+
52
+ ### Library & Search
53
+ - **Fast Library Scanning**: Automatic metadata extraction from thousands of songs
54
+ - **M4A Stems Native**: Optimized for MPEG-4 multi-track audio with full metadata support
55
+ - **Legacy Format Support**: Also reads CDG/MP3 pairs
56
+ - **Smart Search**: Fuzzy search across titles, artists, and albums
57
+ - **Alphabet Navigation**: Quick filtering by first letter
58
+ - **Pagination**: Efficient handling of large libraries (tested with 23K+ songs)
59
+
60
+ ### Web Admin Interface
61
+ - **Remote Control**: Full player control from any device on the network
62
+ - **Song Requests**: Allow singers to browse and request songs remotely
63
+ - **Request Management**: Approve/reject song requests with real-time notifications
64
+ - **QR Code Access**: Scan QR code from canvas for instant mobile connection
65
+ - **WebRTC Streaming**: Stream audio and video to remote devices (optional)
66
+ - **Multi-Device Sync**: Real-time state synchronization via Socket.IO
67
+
68
+ ### Mixer & Editor
69
+ - **Advanced Mixer**: Per-stem gain control, routing, and effects
70
+ - **Preset Management**: Save and load mixer presets
71
+ - **Lyrics Editor**: Edit lyrics line-by-line with timing adjustments
72
+ - **Song Metadata Editor**: Update title, artist, album, and other metadata
73
+
74
+ ### Developer Features
75
+ - **Modern Stack**: React 19, Vite 7, Electron 38
76
+ - **Comprehensive Testing**: 52% code coverage with Vitest
77
+ - **ESLint + Prettier**: Automated code formatting and linting
78
+ - **Pre-commit Hooks**: Husky + lint-staged for quality assurance
79
+ - **Hot Module Replacement**: Fast development with Vite HMR
80
+
81
+ ---
82
+
83
+ ## Quick Start
84
+
85
+ ### Prerequisites
86
+
87
+ - **Node.js 18+** (LTS recommended)
88
+ - **npm 9+** or **yarn 1.22+**
89
+ - **Git**
90
+
91
+ ### Installation
92
+
93
+ ```bash
94
+ # Clone the repository
95
+ git clone https://github.com/monteslu/loukai.git
96
+ cd loukai
97
+
98
+ # Install dependencies
99
+ npm install
100
+ ```
101
+
102
+ ### Development
103
+
104
+ ```bash
105
+ # Start the Electron app in dev mode with hot reload
106
+ npm run dev
107
+
108
+ # Run tests
109
+ npm test
110
+
111
+ # Run tests with coverage
112
+ npm run test:coverage
113
+
114
+ # Run tests with UI
115
+ npm run test:ui
116
+
117
+ # Lint code
118
+ npm run lint
119
+
120
+ # Auto-fix linting issues
121
+ npm run lint:fix
122
+
123
+ # Format code
124
+ npm run format
125
+ ```
126
+
127
+ ### Building
128
+
129
+ ```bash
130
+ # Build all assets (renderer + web)
131
+ npm run build:all
132
+
133
+ # Build for Linux (AppImage x64/ARM64 + Flatpak x64/ARM64)
134
+ npm run build:linux
135
+
136
+ # Build for Windows (NSIS installer x64)
137
+ npm run build:win
138
+
139
+ # Build for macOS (DMG x64 + ARM64)
140
+ npm run build:mac
141
+ ```
142
+
143
+ **Build Output:**
144
+
145
+ | Platform | Format | Architectures | Size |
146
+ |----------|--------|---------------|------|
147
+ | **Linux** | AppImage | x64, ARM64 | ~143 MB each |
148
+ | **Linux** | Flatpak | x64, ARM64 | ~104 MB each |
149
+ | **Windows** | NSIS | x64 | ~150 MB |
150
+ | **macOS** | DMG | x64 (Intel), ARM64 (Apple Silicon) | ~150 MB each |
151
+
152
+ **Build Requirements:**
153
+
154
+ - **Linux builds**: Requires `flatpak-builder` and Flatpak runtimes (24.08)
155
+ ```bash
156
+ # Install flatpak-builder
157
+ sudo apt-get install flatpak-builder flatpak
158
+
159
+ # Add Flathub repository
160
+ flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
161
+
162
+ # Install required runtimes
163
+ flatpak install --user -y flathub \
164
+ org.electronjs.Electron2.BaseApp/x86_64/24.08 \
165
+ org.freedesktop.Platform/x86_64/24.08 \
166
+ org.freedesktop.Sdk/x86_64/24.08 \
167
+ org.electronjs.Electron2.BaseApp/aarch64/24.08 \
168
+ org.freedesktop.Platform/aarch64/24.08 \
169
+ org.freedesktop.Sdk/aarch64/24.08
170
+ ```
171
+
172
+ - **ARM64 builds**: x64 hosts use QEMU for cross-compilation
173
+ - AppImages: Built via QEMU (supported out of the box)
174
+ - Flatpak: Requires ARM64 runtimes (installed above)
175
+
176
+ - **macOS builds**: Both Intel and Apple Silicon DMGs built simultaneously
177
+ - **Windows builds**: x64 NSIS installer with auto-updater support
178
+
179
+ ### Production
180
+
181
+ ```bash
182
+ # Start the app (after building)
183
+ npm start
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Architecture
189
+
190
+ Loukai is built with a multi-process architecture:
191
+
192
+ ### Main Process (Electron)
193
+ - **Audio Engine**: Native audio processing with dual outputs
194
+ - **Library Scanner**: Metadata extraction and caching
195
+ - **Web Server**: Express 5 REST API + Socket.IO
196
+ - **State Management**: Centralized app state with event emitters
197
+ - **File System**: M4A/CDG file parsing and manipulation
198
+ - **IPC Handlers**: Communication bridge to renderer
199
+
200
+ ### Renderer Process (React)
201
+ - **React 19**: Modern UI with concurrent features
202
+ - **Vite 7**: Lightning-fast builds and HMR
203
+ - **Tailwind CSS**: Utility-first styling with dark mode
204
+ - **Web Audio API**: Real-time audio processing
205
+ - **Butterchurn**: Audio visualization engine
206
+ - **Socket.IO Client**: Real-time updates from main process
207
+
208
+ ### Web Admin (React)
209
+ - **Standalone Web UI**: Accessible from any device
210
+ - **Socket.IO**: Real-time bidirectional communication
211
+ - **Responsive Design**: Mobile-friendly interface
212
+ - **Authentication**: Session-based login with bcrypt
213
+ - **WebRTC**: Optional audio/video streaming
214
+
215
+ ### Key Technologies
216
+
217
+ | Category | Technology |
218
+ |----------|------------|
219
+ | **Frontend** | React 19, Tailwind CSS 3 |
220
+ | **Build Tool** | Vite 7 |
221
+ | **Desktop** | Electron 38 |
222
+ | **Backend** | Node.js, Express 5 |
223
+ | **Real-time** | Socket.IO 4 |
224
+ | **Testing** | Vitest 3, Testing Library 16 |
225
+ | **Audio** | Web Audio API, Custom Worklets |
226
+ | **Graphics** | Butterchurn, CDGGraphics |
227
+ | **Linting** | ESLint 9, Prettier 3 |
228
+ | **Pre-commit** | Husky 9, lint-staged 16 |
229
+ | **Packaging** | electron-builder 26 |
230
+
231
+ ### Packaging & Distribution
232
+
233
+ | Platform | Formats | Architecture Support |
234
+ |----------|---------|---------------------|
235
+ | **Linux** | AppImage, Flatpak | x64, ARM64 |
236
+ | **Windows** | NSIS Installer | x64 |
237
+ | **macOS** | DMG | Intel (x64), Apple Silicon (ARM64) |
238
+
239
+ **Flatpak Configuration:**
240
+ - Runtime: org.freedesktop.Platform 24.08
241
+ - SDK: org.freedesktop.Sdk 24.08
242
+ - Base: org.electronjs.Electron2.BaseApp 24.08
243
+ - Permissions: Wayland, X11, Audio, Network, Home filesystem
244
+
245
+ **GitHub Actions CI:**
246
+ - Automated builds for all platforms
247
+ - Multi-architecture support (x64, ARM64)
248
+ - Automatic releases on version tags
249
+
250
+ ---
251
+
252
+ ## File Formats
253
+
254
+ ### M4A Stems Format (Primary - Recommended)
255
+
256
+ **Industry-standard MPEG-4 multi-track audio** - the modern karaoke format:
257
+
258
+ #### Why M4A Stems?
259
+ - ✅ **DJ Software Compatible**: Works with Traktor, Mixxx, and other NI Stems-compatible software
260
+ - ✅ **Smaller Files**: 30-50% smaller than ZIP-based formats due to MPEG-4 compression
261
+ - ✅ **Better Metadata**: Native MP4 atoms for rich metadata (title, artist, album art, BPM, key)
262
+ - ✅ **Karaoke Extensions**: Custom atoms for lyrics with word-level timing
263
+ - ✅ **Single File**: No unpacking required - instant playback
264
+ - ✅ **Dual Purpose**: Same file works for both DJing and karaoke
265
+
266
+ #### Structure
267
+ - **Multi-track audio**: Master + 4 stems (drums, bass, other, vocals)
268
+ - **NI Stems atom**: `stem` - standard metadata for DJ software compatibility
269
+ - **Karaoke atom**: `kara` (lyrics with word-level timing)
270
+ - **File extension**: `.stem.m4a` or `.m4a`
271
+
272
+ **Full specification:** [docs/m4a_format.md](./docs/m4a_format.md)
273
+
274
+ #### Creating M4A Files
275
+ Use the built-in **Creator** tab in Loukai:
276
+
277
+ 1. Open Loukai and go to the **Creator** tab
278
+ 2. Drop your audio file (MP3, FLAC, WAV, etc.)
279
+ 3. The Creator will:
280
+ - Separate audio into stems using Demucs (AI stem separation)
281
+ - Transcribe lyrics using Whisper (AI speech recognition)
282
+ - Detect musical key using CREPE
283
+ - Package everything into a `.stem.m4a` file
284
+
285
+ **Output:** `Artist - Title.stem.m4a` saved to your songs folder
286
+
287
+ ### CDG Format (Legacy)
288
+
289
+ Classic karaoke format with graphics - widely available but limited features:
290
+
291
+ - **MP3 + CDG pairs**: `song.mp3` + `song.cdg`
292
+ - **Limitations**: No stem separation, basic graphics, no metadata
293
+
294
+ ---
295
+
296
+ ## Configuration
297
+
298
+ ### Audio Settings
299
+ Configure audio devices in the Mixer tab:
300
+ - **PA Output**: Main speakers/sound system
301
+ - **IEM Output**: Stage monitors/headphones
302
+ - **Input Device**: Microphone for vocal processing
303
+
304
+ ### Web Server Settings
305
+ Access in the Server tab:
306
+ - **Port**: Default 3069
307
+ - **Server Name**: Custom server name for identification
308
+ - **Authentication**: Enable/disable login
309
+ - **Requests**: Allow remote song requests
310
+ - **Max Requests**: Limit requests per user
311
+ - **Show QR Code**: Display QR code on canvas for easy mobile access (on by default)
312
+ - **Display Queue**: Show upcoming songs on canvas (on by default)
313
+
314
+ ### Settings Persistence
315
+ All settings are automatically saved to:
316
+ - **Linux**: `~/.config/loukai/`
317
+ - **Windows**: `%APPDATA%\loukai\`
318
+ - **macOS**: `~/Library/Application Support/loukai/`
319
+
320
+ ---
321
+
322
+ ## Usage
323
+
324
+ ### Loading Songs
325
+
326
+ 1. **Set Songs Folder**: Settings tab → Browse for your karaoke library (M4A files recommended)
327
+ 2. **Scan Library**: Click "Scan Library" to index all songs
328
+ 3. **Search & Play**: Use the Library tab to find and play songs
329
+
330
+ **Tip:** For best results, use `.stem.m4a` files created with the built-in Creator. M4A files load faster and take less disk space than legacy formats.
331
+
332
+ ### Playing Karaoke
333
+
334
+ 1. **Load Song**: Double-click a song or add to queue
335
+ 2. **Adjust Mixer**: Control stem volumes in the Mixer tab
336
+ 3. **Enable Effects**: Choose visual effects in the Effects tab
337
+ 4. **Open Canvas**: Project visuals to a second screen
338
+
339
+ ### Remote Access
340
+
341
+ 1. **Enable Web Server**: Settings → Server → Enable
342
+ 2. **Set Password**: Configure authentication credentials
343
+ 3. **Share URL**: Give singers the URL (shown in Server tab)
344
+ 4. **QR Code**: Singers can scan the QR code from the canvas for instant access
345
+ 5. **Manage Requests**: Approve/reject requests in the Requests tab
346
+
347
+ ### Canvas Display Features
348
+
349
+ The karaoke canvas shows helpful information when not playing:
350
+
351
+ - **QR Code** (bottom left): Scannable code for mobile device access
352
+ - Toggle: Server tab → "Show QR Code" checkbox
353
+ - Only visible when not playing
354
+
355
+ - **Queue Display** (bottom right): Shows upcoming songs
356
+ - Toggle: Server tab → "Display Queue" checkbox
357
+ - Displays "Next up:" with 1-3 upcoming songs
358
+ - Singer names shown in yellow (guests) or white (KJ)
359
+ - Only visible when not playing and queue has items
360
+
361
+ ### Keyboard Shortcuts
362
+
363
+ | Shortcut | Action |
364
+ |----------|--------|
365
+ | `Space` | Play/Pause |
366
+ | `←` | Seek backward 5s |
367
+ | `→` | Seek forward 5s |
368
+ | `R` | Restart song |
369
+ | `N` | Next song |
370
+ | `M` | Toggle mute |
371
+ | `F` | Toggle fullscreen canvas |
372
+
373
+ ---
374
+
375
+ ## Testing
376
+
377
+ Loukai has comprehensive test coverage using Vitest:
378
+
379
+ ```bash
380
+ # Run all tests
381
+ npm test
382
+
383
+ # Run tests once (CI mode)
384
+ npm run test:run
385
+
386
+ # Run with coverage report
387
+ npm run test:coverage
388
+
389
+ # Interactive test UI
390
+ npm run test:ui
391
+ ```
392
+
393
+ **Current Coverage:** 283 tests
394
+
395
+ See [PHASE2-SUMMARY.md](./docs/PHASE2-SUMMARY.md) for detailed testing information.
396
+
397
+ ---
398
+
399
+ ## Development
400
+
401
+ ### Project Structure
402
+
403
+ ```
404
+ loukai/
405
+ ├── src/
406
+ │ ├── main/ # Electron main process
407
+ │ │ ├── main.js # Entry point
408
+ │ │ ├── appState.js # Centralized state
409
+ │ │ ├── audioEngine.js # Audio processing
410
+ │ │ ├── webServer.js # Express + Socket.IO
411
+ │ │ └── handlers/ # IPC handlers
412
+ │ │ └── autotuneHandlers.js # Auto-tune IPC
413
+ │ ├── renderer/ # Electron renderer (React)
414
+ │ │ ├── components/ # React components
415
+ │ │ ├── hooks/ # Custom React hooks
416
+ │ │ ├── js/ # Audio engine (vanilla JS)
417
+ │ │ │ ├── autoTuneWorklet.js # Auto-tune processor
418
+ │ │ │ └── playerController.js # Unified control
419
+ │ │ └── vite.config.js # Renderer build config
420
+ │ ├── web/ # Web admin interface
421
+ │ │ ├── App.jsx # Web admin root
422
+ │ │ ├── components/ # Web-specific components
423
+ │ │ └── vite.config.js # Web build config
424
+ │ ├── shared/ # Shared code (renderer + web)
425
+ │ │ ├── components/ # Reusable React components
426
+ │ │ ├── services/ # Business logic
427
+ │ │ └── utils/ # Utility functions
428
+ │ ├── native/ # Native modules
429
+ │ │ └── autotune.js # Auto-tune utilities
430
+ │ └── test/ # Test setup
431
+ │ └── setup.js # Vitest config
432
+ ├── static/ # Static assets
433
+ ├── docs/ # Documentation
434
+ ├── coverage/ # Test coverage reports
435
+ └── dist/ # Build output
436
+ ```
437
+
438
+ ### Code Style
439
+
440
+ This project uses ESLint and Prettier for code quality:
441
+
442
+ ```bash
443
+ # Check linting
444
+ npm run lint
445
+
446
+ # Auto-fix linting issues
447
+ npm run lint:fix
448
+
449
+ # Format all files
450
+ npm run format
451
+
452
+ # Check formatting
453
+ npm run format:check
454
+ ```
455
+
456
+ **Pre-commit hooks** automatically run linting and formatting on staged files.
457
+
458
+ ### Adding Tests
459
+
460
+ Create test files next to source files with `.test.js` extension:
461
+
462
+ ```javascript
463
+ // src/shared/services/myService.test.js
464
+ import { describe, it, expect } from 'vitest';
465
+ import * as myService from './myService.js';
466
+
467
+ describe('myService', () => {
468
+ it('should do something', () => {
469
+ const result = myService.doSomething();
470
+ expect(result).toBe(true);
471
+ });
472
+ });
473
+ ```
474
+
475
+ ### Contributing
476
+
477
+ See [CONTRIBUTING.md](./CONTRIBUTING.md) for development guidelines.
478
+
479
+ ---
480
+
481
+ ## Documentation
482
+
483
+ | Document | Description |
484
+ |----------|-------------|
485
+ | [m4a_format.md](./docs/m4a_format.md) | M4A Stems karaoke format specification |
486
+ | [architecture.md](./docs/architecture.md) | System architecture and design |
487
+ | [PHASE2-SUMMARY.md](./docs/PHASE2-SUMMARY.md) | Testing infrastructure guide |
488
+ | [MODERNIZATION-PLAN.md](./docs/MODERNIZATION-PLAN.md) | Development roadmap |
489
+ | [PACKAGING.md](./PACKAGING.md) | Build and packaging guide |
490
+ | [WEB-API-REFERENCE.md](./docs/wip/WEB-API-REFERENCE.md) | REST API documentation |
491
+ | [SECURITY-MODEL.md](./docs/wip/SECURITY-MODEL.md) | Security architecture |
492
+ | [REFACTORING-SUMMARY.md](./docs/wip/REFACTORING-SUMMARY.md) | Architecture decisions |
493
+
494
+ ---
495
+
496
+ ## Troubleshooting
497
+
498
+ ### Audio Not Playing
499
+ - Check audio device selection in Mixer tab
500
+ - Verify output device permissions (especially on Linux)
501
+ - Try switching between PA and IEM outputs
502
+
503
+ ### Library Not Scanning
504
+ - Ensure songs folder path is correct
505
+ - Check file permissions (read access required)
506
+ - Supported formats: `.m4a` (recommended), `.stem.m4a`, `.cdg` + `.mp3` pairs
507
+ - For best performance, use M4A Stems format
508
+
509
+ ### Web Server Not Accessible
510
+ - Check firewall settings
511
+ - Verify server is enabled in Settings
512
+ - Check port is not in use (default: 3000)
513
+ - Try accessing via IP address instead of hostname
514
+
515
+ ### Build Errors
516
+ ```bash
517
+ # Clear node_modules and reinstall
518
+ rm -rf node_modules package-lock.json
519
+ npm install
520
+
521
+ # Clear build cache
522
+ rm -rf dist/ coverage/
523
+ npm run build:all
524
+ ```
525
+
526
+ ---
527
+
528
+ ## License
529
+
530
+ **AGPL-3.0**
531
+
532
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
533
+
534
+ This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
535
+
536
+ See [LICENSE](./LICENSE) for full text.
537
+
538
+ ---
539
+
540
+ ## Acknowledgments
541
+
542
+ - **Butterchurn** - Audio visualization engine
543
+ - **CDGraphics** - CDG format support
544
+ - **React** - UI framework
545
+ - **Electron** - Desktop framework
546
+ - **Vite** - Build tool
547
+
548
+ ---
549
+
550
+ ## Support
551
+
552
+ - **Issues**: [GitHub Issues](https://github.com/monteslu/loukai/issues)
553
+ - **Discussions**: [GitHub Discussions](https://github.com/monteslu/loukai/discussions)
554
+ - **Documentation**: [docs/](./docs/)
555
+
556
+ ---
557
+
558
+ **Made with ♪ for karaoke enthusiasts**
package/bin/loukai.js ADDED
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Loukai Karaoke - CLI Launcher
5
+ *
6
+ * Launches the Loukai Karaoke Electron app in production mode.
7
+ *
8
+ * Usage: npx loukai
9
+ */
10
+
11
+ import { spawn } from 'child_process';
12
+ import { createRequire } from 'module';
13
+ import { fileURLToPath } from 'url';
14
+ import path from 'path';
15
+
16
+ const __filename = fileURLToPath(import.meta.url);
17
+ const __dirname = path.dirname(__filename);
18
+ const appRoot = path.join(__dirname, '..');
19
+
20
+ // Find the electron binary
21
+ const require = createRequire(import.meta.url);
22
+ const electronPath = require('electron');
23
+
24
+ // Launch Electron pointing at the app root
25
+ const child = spawn(electronPath, [appRoot, '--no-sandbox'], {
26
+ stdio: 'inherit',
27
+ env: { ...process.env },
28
+ });
29
+
30
+ child.on('close', (code) => {
31
+ process.exit(code);
32
+ });