@factorim/monotui 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 (666) hide show
  1. package/.github/workflows/ci.yml +36 -0
  2. package/.github/workflows/publish-to-npm.yml +36 -0
  3. package/.husky/commit-msg +2 -0
  4. package/.husky/pre-commit +2 -0
  5. package/.vscode/settings.json +34 -0
  6. package/LICENSE +21 -0
  7. package/README.md +78 -0
  8. package/biome.json +37 -0
  9. package/commitlint.config.cjs +3 -0
  10. package/dist/app/App.d.ts +2 -0
  11. package/dist/app/App.d.ts.map +1 -0
  12. package/dist/app/App.js +15 -0
  13. package/dist/app/App.js.map +1 -0
  14. package/dist/app/Layout.d.ts +2 -0
  15. package/dist/app/Layout.d.ts.map +1 -0
  16. package/dist/app/Layout.js +25 -0
  17. package/dist/app/Layout.js.map +1 -0
  18. package/dist/app/pages/About.d.ts +2 -0
  19. package/dist/app/pages/About.d.ts.map +1 -0
  20. package/dist/app/pages/About.js +6 -0
  21. package/dist/app/pages/About.js.map +1 -0
  22. package/dist/app/pages/AboutPage.d.ts +2 -0
  23. package/dist/app/pages/AboutPage.d.ts.map +1 -0
  24. package/dist/app/pages/AboutPage.js +6 -0
  25. package/dist/app/pages/AboutPage.js.map +1 -0
  26. package/dist/app/pages/Exit.d.ts +2 -0
  27. package/dist/app/pages/Exit.d.ts.map +1 -0
  28. package/dist/app/pages/Exit.js +6 -0
  29. package/dist/app/pages/Exit.js.map +1 -0
  30. package/dist/app/pages/ProjectPage.d.ts +2 -0
  31. package/dist/app/pages/ProjectPage.d.ts.map +1 -0
  32. package/dist/app/pages/ProjectPage.js +20 -0
  33. package/dist/app/pages/ProjectPage.js.map +1 -0
  34. package/dist/app/pages/Workspace.d.ts +2 -0
  35. package/dist/app/pages/Workspace.d.ts.map +1 -0
  36. package/dist/app/pages/Workspace.js +14 -0
  37. package/dist/app/pages/Workspace.js.map +1 -0
  38. package/dist/app/pages/WorkspacePage.d.ts +2 -0
  39. package/dist/app/pages/WorkspacePage.d.ts.map +1 -0
  40. package/dist/app/pages/WorkspacePage.js +16 -0
  41. package/dist/app/pages/WorkspacePage.js.map +1 -0
  42. package/dist/app/pages/Workspaces.d.ts +2 -0
  43. package/dist/app/pages/Workspaces.d.ts.map +1 -0
  44. package/dist/app/pages/Workspaces.js +16 -0
  45. package/dist/app/pages/Workspaces.js.map +1 -0
  46. package/dist/app/pages/WorkspacesPage.d.ts +2 -0
  47. package/dist/app/pages/WorkspacesPage.d.ts.map +1 -0
  48. package/dist/app/pages/WorkspacesPage.js +15 -0
  49. package/dist/app/pages/WorkspacesPage.js.map +1 -0
  50. package/dist/bin/init.d.ts +3 -0
  51. package/dist/bin/init.d.ts.map +1 -0
  52. package/dist/bin/init.js +7 -0
  53. package/dist/bin/init.js.map +1 -0
  54. package/dist/bin/trace-warnings.d.ts +3 -0
  55. package/dist/bin/trace-warnings.d.ts.map +1 -0
  56. package/dist/bin/trace-warnings.js +17 -0
  57. package/dist/bin/trace-warnings.js.map +1 -0
  58. package/dist/commands/init.d.ts +5 -0
  59. package/dist/commands/init.d.ts.map +1 -0
  60. package/dist/commands/init.js +65 -0
  61. package/dist/commands/init.js.map +1 -0
  62. package/dist/components/features/ProjectGrid/ColCompose.d.ts +12 -0
  63. package/dist/components/features/ProjectGrid/ColCompose.d.ts.map +1 -0
  64. package/dist/components/features/ProjectGrid/ColCompose.js +16 -0
  65. package/dist/components/features/ProjectGrid/ColCompose.js.map +1 -0
  66. package/dist/components/features/ProjectGrid/ColMakefile.d.ts +9 -0
  67. package/dist/components/features/ProjectGrid/ColMakefile.d.ts.map +1 -0
  68. package/dist/components/features/ProjectGrid/ColMakefile.js +8 -0
  69. package/dist/components/features/ProjectGrid/ColMakefile.js.map +1 -0
  70. package/dist/components/features/ProjectGrid/ColPackageJson.d.ts +11 -0
  71. package/dist/components/features/ProjectGrid/ColPackageJson.d.ts.map +1 -0
  72. package/dist/components/features/ProjectGrid/ColPackageJson.js +8 -0
  73. package/dist/components/features/ProjectGrid/ColPackageJson.js.map +1 -0
  74. package/dist/components/features/ProjectGrid/EmptyCol.d.ts +2 -0
  75. package/dist/components/features/ProjectGrid/EmptyCol.d.ts.map +1 -0
  76. package/dist/components/features/ProjectGrid/EmptyCol.js +8 -0
  77. package/dist/components/features/ProjectGrid/EmptyCol.js.map +1 -0
  78. package/dist/components/features/ProjectGrid/ProjectCommands.d.ts +2 -0
  79. package/dist/components/features/ProjectGrid/ProjectCommands.d.ts.map +1 -0
  80. package/dist/components/features/ProjectGrid/ProjectCommands.js +6 -0
  81. package/dist/components/features/ProjectGrid/ProjectCommands.js.map +1 -0
  82. package/dist/components/features/ProjectGrid/ProjectGrid.d.ts +2 -0
  83. package/dist/components/features/ProjectGrid/ProjectGrid.d.ts.map +1 -0
  84. package/dist/components/features/ProjectGrid/ProjectGrid.js +25 -0
  85. package/dist/components/features/ProjectGrid/ProjectGrid.js.map +1 -0
  86. package/dist/components/features/ProjectGrid/ProjectInfo.d.ts +2 -0
  87. package/dist/components/features/ProjectGrid/ProjectInfo.d.ts.map +1 -0
  88. package/dist/components/features/ProjectGrid/ProjectInfo.js +13 -0
  89. package/dist/components/features/ProjectGrid/ProjectInfo.js.map +1 -0
  90. package/dist/components/features/ProjectGrid/WorkspaceCommands.d.ts +2 -0
  91. package/dist/components/features/ProjectGrid/WorkspaceCommands.d.ts.map +1 -0
  92. package/dist/components/features/ProjectGrid/WorkspaceCommands.js +6 -0
  93. package/dist/components/features/ProjectGrid/WorkspaceCommands.js.map +1 -0
  94. package/dist/components/features/ProjectGrid/WorkspaceDetail.d.ts +2 -0
  95. package/dist/components/features/ProjectGrid/WorkspaceDetail.d.ts.map +1 -0
  96. package/dist/components/features/ProjectGrid/WorkspaceDetail.js +16 -0
  97. package/dist/components/features/ProjectGrid/WorkspaceDetail.js.map +1 -0
  98. package/dist/components/features/ProjectGrid/WorkspaceInfo.d.ts +2 -0
  99. package/dist/components/features/ProjectGrid/WorkspaceInfo.d.ts.map +1 -0
  100. package/dist/components/features/ProjectGrid/WorkspaceInfo.js +11 -0
  101. package/dist/components/features/ProjectGrid/WorkspaceInfo.js.map +1 -0
  102. package/dist/components/features/WorkspaceDetail/ColCompose.d.ts +10 -0
  103. package/dist/components/features/WorkspaceDetail/ColCompose.d.ts.map +1 -0
  104. package/dist/components/features/WorkspaceDetail/ColCompose.js +6 -0
  105. package/dist/components/features/WorkspaceDetail/ColCompose.js.map +1 -0
  106. package/dist/components/features/WorkspaceDetail/ColMakefile.d.ts +9 -0
  107. package/dist/components/features/WorkspaceDetail/ColMakefile.d.ts.map +1 -0
  108. package/dist/components/features/WorkspaceDetail/ColMakefile.js +6 -0
  109. package/dist/components/features/WorkspaceDetail/ColMakefile.js.map +1 -0
  110. package/dist/components/features/WorkspaceDetail/ColPackageJson.d.ts +11 -0
  111. package/dist/components/features/WorkspaceDetail/ColPackageJson.d.ts.map +1 -0
  112. package/dist/components/features/WorkspaceDetail/ColPackageJson.js +6 -0
  113. package/dist/components/features/WorkspaceDetail/ColPackageJson.js.map +1 -0
  114. package/dist/components/features/WorkspaceDetail/ComposeCol copy 2.d.ts +1 -0
  115. package/dist/components/features/WorkspaceDetail/ComposeCol copy 2.d.ts.map +1 -0
  116. package/dist/components/features/WorkspaceDetail/ComposeCol copy 2.js +2 -0
  117. package/dist/components/features/WorkspaceDetail/ComposeCol copy 2.js.map +1 -0
  118. package/dist/components/features/WorkspaceDetail/ComposeCol copy.d.ts +1 -0
  119. package/dist/components/features/WorkspaceDetail/ComposeCol copy.d.ts.map +1 -0
  120. package/dist/components/features/WorkspaceDetail/ComposeCol copy.js +2 -0
  121. package/dist/components/features/WorkspaceDetail/ComposeCol copy.js.map +1 -0
  122. package/dist/components/features/WorkspaceDetail/ComposeCol.d.ts +1 -0
  123. package/dist/components/features/WorkspaceDetail/ComposeCol.d.ts.map +1 -0
  124. package/dist/components/features/WorkspaceDetail/ComposeCol.js +2 -0
  125. package/dist/components/features/WorkspaceDetail/ComposeCol.js.map +1 -0
  126. package/dist/components/features/WorkspaceDetail/EmptyCol.d.ts +2 -0
  127. package/dist/components/features/WorkspaceDetail/EmptyCol.d.ts.map +1 -0
  128. package/dist/components/features/WorkspaceDetail/EmptyCol.js +6 -0
  129. package/dist/components/features/WorkspaceDetail/EmptyCol.js.map +1 -0
  130. package/dist/components/features/WorkspaceDetail/EmptyRow.d.ts +2 -0
  131. package/dist/components/features/WorkspaceDetail/EmptyRow.d.ts.map +1 -0
  132. package/dist/components/features/WorkspaceDetail/EmptyRow.js +6 -0
  133. package/dist/components/features/WorkspaceDetail/EmptyRow.js.map +1 -0
  134. package/dist/components/features/WorkspaceDetail/PackageJsonCol.d.ts +1 -0
  135. package/dist/components/features/WorkspaceDetail/PackageJsonCol.d.ts.map +1 -0
  136. package/dist/components/features/WorkspaceDetail/PackageJsonCol.js +2 -0
  137. package/dist/components/features/WorkspaceDetail/PackageJsonCol.js.map +1 -0
  138. package/dist/components/features/WorkspaceDetail/WorkspaceDetail copy.d.ts +2 -0
  139. package/dist/components/features/WorkspaceDetail/WorkspaceDetail copy.d.ts.map +1 -0
  140. package/dist/components/features/WorkspaceDetail/WorkspaceDetail copy.js +12 -0
  141. package/dist/components/features/WorkspaceDetail/WorkspaceDetail copy.js.map +1 -0
  142. package/dist/components/features/WorkspaceDetail/WorkspaceDetail.d.ts +2 -0
  143. package/dist/components/features/WorkspaceDetail/WorkspaceDetail.d.ts.map +1 -0
  144. package/dist/components/features/WorkspaceDetail/WorkspaceDetail.js +16 -0
  145. package/dist/components/features/WorkspaceDetail/WorkspaceDetail.js.map +1 -0
  146. package/dist/components/features/WorkspaceDetail/WorkspaceInfo.d.ts +2 -0
  147. package/dist/components/features/WorkspaceDetail/WorkspaceInfo.d.ts.map +1 -0
  148. package/dist/components/features/WorkspaceDetail/WorkspaceInfo.js +11 -0
  149. package/dist/components/features/WorkspaceDetail/WorkspaceInfo.js.map +1 -0
  150. package/dist/components/features/WorkspaceGrid/WorkspaceCommands.d.ts +2 -0
  151. package/dist/components/features/WorkspaceGrid/WorkspaceCommands.d.ts.map +1 -0
  152. package/dist/components/features/WorkspaceGrid/WorkspaceCommands.js +6 -0
  153. package/dist/components/features/WorkspaceGrid/WorkspaceCommands.js.map +1 -0
  154. package/dist/components/features/WorkspaceGrid/WorkspaceGrid.d.ts +2 -0
  155. package/dist/components/features/WorkspaceGrid/WorkspaceGrid.d.ts.map +1 -0
  156. package/dist/components/features/WorkspaceGrid/WorkspaceGrid.js +15 -0
  157. package/dist/components/features/WorkspaceGrid/WorkspaceGrid.js.map +1 -0
  158. package/dist/components/features/WorkspaceGrid/WorkspaceInfo copy.d.ts +2 -0
  159. package/dist/components/features/WorkspaceGrid/WorkspaceInfo copy.d.ts.map +1 -0
  160. package/dist/components/features/WorkspaceGrid/WorkspaceInfo copy.js +11 -0
  161. package/dist/components/features/WorkspaceGrid/WorkspaceInfo copy.js.map +1 -0
  162. package/dist/components/features/WorkspaceGrid/WorkspaceInfo.d.ts +2 -0
  163. package/dist/components/features/WorkspaceGrid/WorkspaceInfo.d.ts.map +1 -0
  164. package/dist/components/features/WorkspaceGrid/WorkspaceInfo.js +13 -0
  165. package/dist/components/features/WorkspaceGrid/WorkspaceInfo.js.map +1 -0
  166. package/dist/components/features/WorkspaceGrid/WorkspaceRow.d.ts +9 -0
  167. package/dist/components/features/WorkspaceGrid/WorkspaceRow.d.ts.map +1 -0
  168. package/dist/components/features/WorkspaceGrid/WorkspaceRow.js +18 -0
  169. package/dist/components/features/WorkspaceGrid/WorkspaceRow.js.map +1 -0
  170. package/dist/components/features/WorkspaceGrid/WorkspacesGrid.d.ts +2 -0
  171. package/dist/components/features/WorkspaceGrid/WorkspacesGrid.d.ts.map +1 -0
  172. package/dist/components/features/WorkspaceGrid/WorkspacesGrid.js +10 -0
  173. package/dist/components/features/WorkspaceGrid/WorkspacesGrid.js.map +1 -0
  174. package/dist/components/features/WorkspaceGrid/WorkspacesInfo.d.ts +2 -0
  175. package/dist/components/features/WorkspaceGrid/WorkspacesInfo.d.ts.map +1 -0
  176. package/dist/components/features/WorkspaceGrid/WorkspacesInfo.js +11 -0
  177. package/dist/components/features/WorkspaceGrid/WorkspacesInfo.js.map +1 -0
  178. package/dist/components/features/WorkspaceGrid/WorkspacesRow.d.ts +8 -0
  179. package/dist/components/features/WorkspaceGrid/WorkspacesRow.d.ts.map +1 -0
  180. package/dist/components/features/WorkspaceGrid/WorkspacesRow.js +18 -0
  181. package/dist/components/features/WorkspaceGrid/WorkspacesRow.js.map +1 -0
  182. package/dist/components/features/WorkspaceList/WorkspaceList.d.ts +2 -0
  183. package/dist/components/features/WorkspaceList/WorkspaceList.d.ts.map +1 -0
  184. package/dist/components/features/WorkspaceList/WorkspaceList.js +10 -0
  185. package/dist/components/features/WorkspaceList/WorkspaceList.js.map +1 -0
  186. package/dist/components/features/WorkspaceList/WorkspacesRow.d.ts +8 -0
  187. package/dist/components/features/WorkspaceList/WorkspacesRow.d.ts.map +1 -0
  188. package/dist/components/features/WorkspaceList/WorkspacesRow.js +15 -0
  189. package/dist/components/features/WorkspaceList/WorkspacesRow.js.map +1 -0
  190. package/dist/components/features/WorkspaceList/responsiveColumnWidths.d.ts +4 -0
  191. package/dist/components/features/WorkspaceList/responsiveColumnWidths.d.ts.map +1 -0
  192. package/dist/components/features/WorkspaceList/responsiveColumnWidths.js +11 -0
  193. package/dist/components/features/WorkspaceList/responsiveColumnWidths.js.map +1 -0
  194. package/dist/components/features/WorkspaceList/responsiveWidth.d.ts +4 -0
  195. package/dist/components/features/WorkspaceList/responsiveWidth.d.ts.map +1 -0
  196. package/dist/components/features/WorkspaceList/responsiveWidth.js +11 -0
  197. package/dist/components/features/WorkspaceList/responsiveWidth.js.map +1 -0
  198. package/dist/components/features/WorkspacesGrid/WorkspaceInfo.d.ts +2 -0
  199. package/dist/components/features/WorkspacesGrid/WorkspaceInfo.d.ts.map +1 -0
  200. package/dist/components/features/WorkspacesGrid/WorkspaceInfo.js +13 -0
  201. package/dist/components/features/WorkspacesGrid/WorkspaceInfo.js.map +1 -0
  202. package/dist/components/features/WorkspacesGrid/WorkspaceList.d.ts +2 -0
  203. package/dist/components/features/WorkspacesGrid/WorkspaceList.d.ts.map +1 -0
  204. package/dist/components/features/WorkspacesGrid/WorkspaceList.js +10 -0
  205. package/dist/components/features/WorkspacesGrid/WorkspaceList.js.map +1 -0
  206. package/dist/components/features/WorkspacesGrid/WorkspacesGrid.d.ts +2 -0
  207. package/dist/components/features/WorkspacesGrid/WorkspacesGrid.d.ts.map +1 -0
  208. package/dist/components/features/WorkspacesGrid/WorkspacesGrid.js +10 -0
  209. package/dist/components/features/WorkspacesGrid/WorkspacesGrid.js.map +1 -0
  210. package/dist/components/features/WorkspacesGrid/WorkspacesInfo.d.ts +2 -0
  211. package/dist/components/features/WorkspacesGrid/WorkspacesInfo.d.ts.map +1 -0
  212. package/dist/components/features/WorkspacesGrid/WorkspacesInfo.js +11 -0
  213. package/dist/components/features/WorkspacesGrid/WorkspacesInfo.js.map +1 -0
  214. package/dist/components/features/WorkspacesGrid/WorkspacesRow.d.ts +8 -0
  215. package/dist/components/features/WorkspacesGrid/WorkspacesRow.d.ts.map +1 -0
  216. package/dist/components/features/WorkspacesGrid/WorkspacesRow.js +18 -0
  217. package/dist/components/features/WorkspacesGrid/WorkspacesRow.js.map +1 -0
  218. package/dist/components/layouts/Footer/Footer.d.ts +2 -0
  219. package/dist/components/layouts/Footer/Footer.d.ts.map +1 -0
  220. package/dist/components/layouts/Footer/Footer.js +7 -0
  221. package/dist/components/layouts/Footer/Footer.js.map +1 -0
  222. package/dist/components/layouts/Header/Header.d.ts +2 -0
  223. package/dist/components/layouts/Header/Header.d.ts.map +1 -0
  224. package/dist/components/layouts/Header/Header.js +22 -0
  225. package/dist/components/layouts/Header/Header.js.map +1 -0
  226. package/dist/components/layouts/Header/ProjectCommands.d.ts +2 -0
  227. package/dist/components/layouts/Header/ProjectCommands.d.ts.map +1 -0
  228. package/dist/components/layouts/Header/ProjectCommands.js +8 -0
  229. package/dist/components/layouts/Header/ProjectCommands.js.map +1 -0
  230. package/dist/components/layouts/Header/WorkspaceCommands copy.d.ts +2 -0
  231. package/dist/components/layouts/Header/WorkspaceCommands copy.d.ts.map +1 -0
  232. package/dist/components/layouts/Header/WorkspaceCommands copy.js +6 -0
  233. package/dist/components/layouts/Header/WorkspaceCommands copy.js.map +1 -0
  234. package/dist/components/layouts/Header/WorkspaceCommands.d.ts +2 -0
  235. package/dist/components/layouts/Header/WorkspaceCommands.d.ts.map +1 -0
  236. package/dist/components/layouts/Header/WorkspaceCommands.js +13 -0
  237. package/dist/components/layouts/Header/WorkspaceCommands.js.map +1 -0
  238. package/dist/config/config.d.ts +8 -0
  239. package/dist/config/config.d.ts.map +1 -0
  240. package/dist/config/config.js +39 -0
  241. package/dist/config/config.js.map +1 -0
  242. package/dist/config/defaults.d.ts +10 -0
  243. package/dist/config/defaults.d.ts.map +1 -0
  244. package/dist/config/defaults.js +43 -0
  245. package/dist/config/defaults.js.map +1 -0
  246. package/dist/contexts/NavigationContext.d.ts +27 -0
  247. package/dist/contexts/NavigationContext.d.ts.map +1 -0
  248. package/dist/contexts/NavigationContext.js +33 -0
  249. package/dist/contexts/NavigationContext.js.map +1 -0
  250. package/dist/contexts/PageNavigationContext.d.ts +15 -0
  251. package/dist/contexts/PageNavigationContext.d.ts.map +1 -0
  252. package/dist/contexts/PageNavigationContext.js +16 -0
  253. package/dist/contexts/PageNavigationContext.js.map +1 -0
  254. package/dist/contexts/ProjectGridContext.d.ts +20 -0
  255. package/dist/contexts/ProjectGridContext.d.ts.map +1 -0
  256. package/dist/contexts/ProjectGridContext.js +40 -0
  257. package/dist/contexts/ProjectGridContext.js.map +1 -0
  258. package/dist/contexts/ProjectNavigationContext.d.ts +20 -0
  259. package/dist/contexts/ProjectNavigationContext.d.ts.map +1 -0
  260. package/dist/contexts/ProjectNavigationContext.js +35 -0
  261. package/dist/contexts/ProjectNavigationContext.js.map +1 -0
  262. package/dist/contexts/ResponsizeContext.d.ts +14 -0
  263. package/dist/contexts/ResponsizeContext.d.ts.map +1 -0
  264. package/dist/contexts/ResponsizeContext.js +34 -0
  265. package/dist/contexts/ResponsizeContext.js.map +1 -0
  266. package/dist/contexts/WorkspaceDiscoveryContext.d.ts +15 -0
  267. package/dist/contexts/WorkspaceDiscoveryContext.d.ts.map +1 -0
  268. package/dist/contexts/WorkspaceDiscoveryContext.js +14 -0
  269. package/dist/contexts/WorkspaceDiscoveryContext.js.map +1 -0
  270. package/dist/contexts/WorkspaceGridContext.d.ts +29 -0
  271. package/dist/contexts/WorkspaceGridContext.d.ts.map +1 -0
  272. package/dist/contexts/WorkspaceGridContext.js +47 -0
  273. package/dist/contexts/WorkspaceGridContext.js.map +1 -0
  274. package/dist/contexts/WorkspaceNavigationContext.d.ts +29 -0
  275. package/dist/contexts/WorkspaceNavigationContext.d.ts.map +1 -0
  276. package/dist/contexts/WorkspaceNavigationContext.js +41 -0
  277. package/dist/contexts/WorkspaceNavigationContext.js.map +1 -0
  278. package/dist/contexts/WorkspacesNavigationContext.d.ts +29 -0
  279. package/dist/contexts/WorkspacesNavigationContext.d.ts.map +1 -0
  280. package/dist/contexts/WorkspacesNavigationContext.js +37 -0
  281. package/dist/contexts/WorkspacesNavigationContext.js.map +1 -0
  282. package/dist/hooks/useDisovery.d.ts +7 -0
  283. package/dist/hooks/useDisovery.d.ts.map +1 -0
  284. package/dist/hooks/useDisovery.js +38 -0
  285. package/dist/hooks/useDisovery.js.map +1 -0
  286. package/dist/hooks/useGridNavigation.d.ts +19 -0
  287. package/dist/hooks/useGridNavigation.d.ts.map +1 -0
  288. package/dist/hooks/useGridNavigation.js +52 -0
  289. package/dist/hooks/useGridNavigation.js.map +1 -0
  290. package/dist/hooks/useNavigation.d.ts +10 -0
  291. package/dist/hooks/useNavigation.d.ts.map +1 -0
  292. package/dist/hooks/useNavigation.js +43 -0
  293. package/dist/hooks/useNavigation.js.map +1 -0
  294. package/dist/hooks/useNavigationMatrix.d.ts +6 -0
  295. package/dist/hooks/useNavigationMatrix.d.ts.map +1 -0
  296. package/dist/hooks/useNavigationMatrix.js +34 -0
  297. package/dist/hooks/useNavigationMatrix.js.map +1 -0
  298. package/dist/hooks/useProjectGrid.d.ts +12 -0
  299. package/dist/hooks/useProjectGrid.d.ts.map +1 -0
  300. package/dist/hooks/useProjectGrid.js +62 -0
  301. package/dist/hooks/useProjectGrid.js.map +1 -0
  302. package/dist/hooks/useRuntime.d.ts +1 -0
  303. package/dist/hooks/useRuntime.d.ts.map +1 -0
  304. package/dist/hooks/useRuntime.js +2 -0
  305. package/dist/hooks/useRuntime.js.map +1 -0
  306. package/dist/hooks/useWorkspaceDiscovery.d.ts +11 -0
  307. package/dist/hooks/useWorkspaceDiscovery.d.ts.map +1 -0
  308. package/dist/hooks/useWorkspaceDiscovery.js +48 -0
  309. package/dist/hooks/useWorkspaceDiscovery.js.map +1 -0
  310. package/dist/hooks/useWorkspaceGrid.d.ts +11 -0
  311. package/dist/hooks/useWorkspaceGrid.d.ts.map +1 -0
  312. package/dist/hooks/useWorkspaceGrid.js +59 -0
  313. package/dist/hooks/useWorkspaceGrid.js.map +1 -0
  314. package/dist/hooks/useWorkspaceNavigation.d.ts +10 -0
  315. package/dist/hooks/useWorkspaceNavigation.d.ts.map +1 -0
  316. package/dist/hooks/useWorkspaceNavigation.js +31 -0
  317. package/dist/hooks/useWorkspaceNavigation.js.map +1 -0
  318. package/dist/hooks/useWorkspaceQuickActions.d.ts +4 -0
  319. package/dist/hooks/useWorkspaceQuickActions.d.ts.map +1 -0
  320. package/dist/hooks/useWorkspaceQuickActions.js +100 -0
  321. package/dist/hooks/useWorkspaceQuickActions.js.map +1 -0
  322. package/dist/hooks/useWorkspaceQuickActionts.d.ts +4 -0
  323. package/dist/hooks/useWorkspaceQuickActionts.d.ts.map +1 -0
  324. package/dist/hooks/useWorkspaceQuickActionts.js +28 -0
  325. package/dist/hooks/useWorkspaceQuickActionts.js.map +1 -0
  326. package/dist/hooks/useWorkspaceRuntime.d.ts +4 -0
  327. package/dist/hooks/useWorkspaceRuntime.d.ts.map +1 -0
  328. package/dist/hooks/useWorkspaceRuntime.js +65 -0
  329. package/dist/hooks/useWorkspaceRuntime.js.map +1 -0
  330. package/dist/hooks/useWorkspacesGrid copy.d.ts +10 -0
  331. package/dist/hooks/useWorkspacesGrid copy.d.ts.map +1 -0
  332. package/dist/hooks/useWorkspacesGrid copy.js +31 -0
  333. package/dist/hooks/useWorkspacesGrid copy.js.map +1 -0
  334. package/dist/hooks/useWorkspacesGrid.d.ts +11 -0
  335. package/dist/hooks/useWorkspacesGrid.d.ts.map +1 -0
  336. package/dist/hooks/useWorkspacesGrid.js +31 -0
  337. package/dist/hooks/useWorkspacesGrid.js.map +1 -0
  338. package/dist/hooks/useWorkspacesNavigation.d.ts +10 -0
  339. package/dist/hooks/useWorkspacesNavigation.d.ts.map +1 -0
  340. package/dist/hooks/useWorkspacesNavigation.js +31 -0
  341. package/dist/hooks/useWorkspacesNavigation.js.map +1 -0
  342. package/dist/index.d.ts +3 -0
  343. package/dist/index.d.ts.map +1 -0
  344. package/dist/index.js +9 -0
  345. package/dist/index.js.map +1 -0
  346. package/dist/services/discovery/facets/biome-parser.d.ts +3 -0
  347. package/dist/services/discovery/facets/biome-parser.d.ts.map +1 -0
  348. package/dist/services/discovery/facets/biome-parser.js +73 -0
  349. package/dist/services/discovery/facets/biome-parser.js.map +1 -0
  350. package/dist/services/discovery/facets/compose-parser.d.ts +17 -0
  351. package/dist/services/discovery/facets/compose-parser.d.ts.map +1 -0
  352. package/dist/services/discovery/facets/compose-parser.js +168 -0
  353. package/dist/services/discovery/facets/compose-parser.js.map +1 -0
  354. package/dist/services/discovery/facets/composeParser.d.ts +1 -0
  355. package/dist/services/discovery/facets/composeParser.d.ts.map +1 -0
  356. package/dist/services/discovery/facets/composeParser.js +2 -0
  357. package/dist/services/discovery/facets/composeParser.js.map +1 -0
  358. package/dist/services/discovery/facets/makefile-parser.d.ts +8 -0
  359. package/dist/services/discovery/facets/makefile-parser.d.ts.map +1 -0
  360. package/dist/services/discovery/facets/makefile-parser.js +143 -0
  361. package/dist/services/discovery/facets/makefile-parser.js.map +1 -0
  362. package/dist/services/discovery/facets/makefileParser.d.ts +1 -0
  363. package/dist/services/discovery/facets/makefileParser.d.ts.map +1 -0
  364. package/dist/services/discovery/facets/makefileParser.js +2 -0
  365. package/dist/services/discovery/facets/makefileParser.js.map +1 -0
  366. package/dist/services/discovery/facets/manifest-parser.d.ts +7 -0
  367. package/dist/services/discovery/facets/manifest-parser.d.ts.map +1 -0
  368. package/dist/services/discovery/facets/manifest-parser.js +43 -0
  369. package/dist/services/discovery/facets/manifest-parser.js.map +1 -0
  370. package/dist/services/discovery/facets/manifestParser.d.ts +1 -0
  371. package/dist/services/discovery/facets/manifestParser.d.ts.map +1 -0
  372. package/dist/services/discovery/facets/manifestParser.js +2 -0
  373. package/dist/services/discovery/facets/manifestParser.js.map +1 -0
  374. package/dist/services/discovery/facets/package-json-parser.d.ts +7 -0
  375. package/dist/services/discovery/facets/package-json-parser.d.ts.map +1 -0
  376. package/dist/services/discovery/facets/package-json-parser.js +118 -0
  377. package/dist/services/discovery/facets/package-json-parser.js.map +1 -0
  378. package/dist/services/discovery/index.d.ts +2 -0
  379. package/dist/services/discovery/index.d.ts.map +1 -0
  380. package/dist/services/discovery/index.js +2 -0
  381. package/dist/services/discovery/index.js.map +1 -0
  382. package/dist/services/discovery/workspace-discovery.d.ts +4 -0
  383. package/dist/services/discovery/workspace-discovery.d.ts.map +1 -0
  384. package/dist/services/discovery/workspace-discovery.js +86 -0
  385. package/dist/services/discovery/workspace-discovery.js.map +1 -0
  386. package/dist/services/discovery/workspaceDiscovery.d.ts +3 -0
  387. package/dist/services/discovery/workspaceDiscovery.d.ts.map +1 -0
  388. package/dist/services/discovery/workspaceDiscovery.js +17 -0
  389. package/dist/services/discovery/workspaceDiscovery.js.map +1 -0
  390. package/dist/services/runtime/command-runner.d.ts +17 -0
  391. package/dist/services/runtime/command-runner.d.ts.map +1 -0
  392. package/dist/services/runtime/command-runner.js +70 -0
  393. package/dist/services/runtime/command-runner.js.map +1 -0
  394. package/dist/services/runtime/docker-runtime.d.ts +15 -0
  395. package/dist/services/runtime/docker-runtime.d.ts.map +1 -0
  396. package/dist/services/runtime/docker-runtime.js +133 -0
  397. package/dist/services/runtime/docker-runtime.js.map +1 -0
  398. package/dist/services/runtime/node-runtime.d.ts +4 -0
  399. package/dist/services/runtime/node-runtime.d.ts.map +1 -0
  400. package/dist/services/runtime/node-runtime.js +210 -0
  401. package/dist/services/runtime/node-runtime.js.map +1 -0
  402. package/dist/services/runtime/resolve-runtime-conflicts.d.ts +15 -0
  403. package/dist/services/runtime/resolve-runtime-conflicts.d.ts.map +1 -0
  404. package/dist/services/runtime/resolve-runtime-conflicts.js +36 -0
  405. package/dist/services/runtime/resolve-runtime-conflicts.js.map +1 -0
  406. package/dist/services/runtime/resolve-runtime.d.ts +15 -0
  407. package/dist/services/runtime/resolve-runtime.d.ts.map +1 -0
  408. package/dist/services/runtime/resolve-runtime.js +36 -0
  409. package/dist/services/runtime/resolve-runtime.js.map +1 -0
  410. package/dist/services/runtime/stop-runtime.d.ts +14 -0
  411. package/dist/services/runtime/stop-runtime.d.ts.map +1 -0
  412. package/dist/services/runtime/stop-runtime.js +48 -0
  413. package/dist/services/runtime/stop-runtime.js.map +1 -0
  414. package/dist/theme/theme.d.ts +33 -0
  415. package/dist/theme/theme.d.ts.map +1 -0
  416. package/dist/theme/theme.js +61 -0
  417. package/dist/theme/theme.js.map +1 -0
  418. package/dist/types/config.d.ts +44 -0
  419. package/dist/types/config.d.ts.map +1 -0
  420. package/dist/types/config.js +2 -0
  421. package/dist/types/config.js.map +1 -0
  422. package/dist/types/navigation.d.ts +10 -0
  423. package/dist/types/navigation.d.ts.map +1 -0
  424. package/dist/types/navigation.js +59 -0
  425. package/dist/types/navigation.js.map +1 -0
  426. package/dist/types/page.d.ts +6 -0
  427. package/dist/types/page.d.ts.map +1 -0
  428. package/dist/types/page.js +7 -0
  429. package/dist/types/page.js.map +1 -0
  430. package/dist/types/project-grid.d.ts +48 -0
  431. package/dist/types/project-grid.d.ts.map +1 -0
  432. package/dist/types/project-grid.js +9 -0
  433. package/dist/types/project-grid.js.map +1 -0
  434. package/dist/types/project.d.ts +64 -0
  435. package/dist/types/project.d.ts.map +1 -0
  436. package/dist/types/project.js +2 -0
  437. package/dist/types/project.js.map +1 -0
  438. package/dist/types/projects-grid.d.ts +32 -0
  439. package/dist/types/projects-grid.d.ts.map +1 -0
  440. package/dist/types/projects-grid.js +2 -0
  441. package/dist/types/projects-grid.js.map +1 -0
  442. package/dist/types/quick-actions.d.ts +7 -0
  443. package/dist/types/quick-actions.d.ts.map +1 -0
  444. package/dist/types/quick-actions.js +2 -0
  445. package/dist/types/quick-actions.js.map +1 -0
  446. package/dist/types/runtime.d.ts +16 -0
  447. package/dist/types/runtime.d.ts.map +1 -0
  448. package/dist/types/runtime.js +2 -0
  449. package/dist/types/runtime.js.map +1 -0
  450. package/dist/types/workpace-grid.d.ts +32 -0
  451. package/dist/types/workpace-grid.d.ts.map +1 -0
  452. package/dist/types/workpace-grid.js +2 -0
  453. package/dist/types/workpace-grid.js.map +1 -0
  454. package/dist/types/workspace-grid.d.ts +32 -0
  455. package/dist/types/workspace-grid.d.ts.map +1 -0
  456. package/dist/types/workspace-grid.js +2 -0
  457. package/dist/types/workspace-grid.js.map +1 -0
  458. package/dist/types/workspace-navigation.d.ts +37 -0
  459. package/dist/types/workspace-navigation.d.ts.map +1 -0
  460. package/dist/types/workspace-navigation.js +7 -0
  461. package/dist/types/workspace-navigation.js.map +1 -0
  462. package/dist/types/workspace-quick-actions.d.ts +12 -0
  463. package/dist/types/workspace-quick-actions.d.ts.map +1 -0
  464. package/dist/types/workspace-quick-actions.js +2 -0
  465. package/dist/types/workspace-quick-actions.js.map +1 -0
  466. package/dist/types/workspace-runtime.d.ts +21 -0
  467. package/dist/types/workspace-runtime.d.ts.map +1 -0
  468. package/dist/types/workspace-runtime.js +2 -0
  469. package/dist/types/workspace-runtime.js.map +1 -0
  470. package/dist/types/workspace.d.ts +63 -0
  471. package/dist/types/workspace.d.ts.map +1 -0
  472. package/dist/types/workspace.js +2 -0
  473. package/dist/types/workspace.js.map +1 -0
  474. package/dist/types/workspaces-grid copy.d.ts +37 -0
  475. package/dist/types/workspaces-grid copy.d.ts.map +1 -0
  476. package/dist/types/workspaces-grid copy.js +7 -0
  477. package/dist/types/workspaces-grid copy.js.map +1 -0
  478. package/dist/types/workspaces-grid.d.ts +37 -0
  479. package/dist/types/workspaces-grid.d.ts.map +1 -0
  480. package/dist/types/workspaces-grid.js +7 -0
  481. package/dist/types/workspaces-grid.js.map +1 -0
  482. package/dist/types/worspace-state.d.ts +19 -0
  483. package/dist/types/worspace-state.d.ts.map +1 -0
  484. package/dist/types/worspace-state.js +2 -0
  485. package/dist/types/worspace-state.js.map +1 -0
  486. package/dist/utils/framework-detector.d.ts +7 -0
  487. package/dist/utils/framework-detector.d.ts.map +1 -0
  488. package/dist/utils/framework-detector.js +111 -0
  489. package/dist/utils/framework-detector.js.map +1 -0
  490. package/dist/utils/fs/directories.d.ts +7 -0
  491. package/dist/utils/fs/directories.d.ts.map +1 -0
  492. package/dist/utils/fs/directories.js +41 -0
  493. package/dist/utils/fs/directories.js.map +1 -0
  494. package/dist/utils/fs/file.d.ts +8 -0
  495. package/dist/utils/fs/file.d.ts.map +1 -0
  496. package/dist/utils/fs/file.js +31 -0
  497. package/dist/utils/fs/file.js.map +1 -0
  498. package/dist/utils/fs/package-json.d.ts +2 -0
  499. package/dist/utils/fs/package-json.d.ts.map +1 -0
  500. package/dist/utils/fs/package-json.js +11 -0
  501. package/dist/utils/fs/package-json.js.map +1 -0
  502. package/dist/utils/fs/scanner.d.ts +6 -0
  503. package/dist/utils/fs/scanner.d.ts.map +1 -0
  504. package/dist/utils/fs/scanner.js +32 -0
  505. package/dist/utils/fs/scanner.js.map +1 -0
  506. package/dist/utils/getPackageVersion.d.ts +2 -0
  507. package/dist/utils/getPackageVersion.d.ts.map +1 -0
  508. package/dist/utils/getPackageVersion.js +6 -0
  509. package/dist/utils/getPackageVersion.js.map +1 -0
  510. package/dist/utils/logger.d.ts +14 -0
  511. package/dist/utils/logger.d.ts.map +1 -0
  512. package/dist/utils/logger.js +99 -0
  513. package/dist/utils/logger.js.map +1 -0
  514. package/dist/utils/logging/logger.d.ts +14 -0
  515. package/dist/utils/logging/logger.d.ts.map +1 -0
  516. package/dist/utils/logging/logger.js +99 -0
  517. package/dist/utils/logging/logger.js.map +1 -0
  518. package/dist/utils/navigation/grid-navigation.d.ts +9 -0
  519. package/dist/utils/navigation/grid-navigation.d.ts.map +1 -0
  520. package/dist/utils/navigation/grid-navigation.js +53 -0
  521. package/dist/utils/navigation/grid-navigation.js.map +1 -0
  522. package/dist/utils/navigation/navigation-helper.d.ts +19 -0
  523. package/dist/utils/navigation/navigation-helper.d.ts.map +1 -0
  524. package/dist/utils/navigation/navigation-helper.js +66 -0
  525. package/dist/utils/navigation/navigation-helper.js.map +1 -0
  526. package/dist/utils/navigation-helper.d.ts +9 -0
  527. package/dist/utils/navigation-helper.d.ts.map +1 -0
  528. package/dist/utils/navigation-helper.js +53 -0
  529. package/dist/utils/navigation-helper.js.map +1 -0
  530. package/dist/utils/package-json.d.ts +2 -0
  531. package/dist/utils/package-json.d.ts.map +1 -0
  532. package/dist/utils/package-json.js +11 -0
  533. package/dist/utils/package-json.js.map +1 -0
  534. package/dist/utils/port.d.ts +6 -0
  535. package/dist/utils/port.d.ts.map +1 -0
  536. package/dist/utils/port.js +24 -0
  537. package/dist/utils/port.js.map +1 -0
  538. package/dist/utils/project/project-grid.d.ts +17 -0
  539. package/dist/utils/project/project-grid.d.ts.map +1 -0
  540. package/dist/utils/project/project-grid.js +121 -0
  541. package/dist/utils/project/project-grid.js.map +1 -0
  542. package/dist/utils/project/workspace-grid.d.ts +17 -0
  543. package/dist/utils/project/workspace-grid.d.ts.map +1 -0
  544. package/dist/utils/project/workspace-grid.js +121 -0
  545. package/dist/utils/project/workspace-grid.js.map +1 -0
  546. package/dist/utils/runtime/port.d.ts +6 -0
  547. package/dist/utils/runtime/port.d.ts.map +1 -0
  548. package/dist/utils/runtime/port.js +24 -0
  549. package/dist/utils/runtime/port.js.map +1 -0
  550. package/dist/utils/workpace/workspace-grid.d.ts +17 -0
  551. package/dist/utils/workpace/workspace-grid.d.ts.map +1 -0
  552. package/dist/utils/workpace/workspace-grid.js +121 -0
  553. package/dist/utils/workpace/workspace-grid.js.map +1 -0
  554. package/dist/utils/workpace/workspace-helper.d.ts +7 -0
  555. package/dist/utils/workpace/workspace-helper.d.ts.map +1 -0
  556. package/dist/utils/workpace/workspace-helper.js +10 -0
  557. package/dist/utils/workpace/workspace-helper.js.map +1 -0
  558. package/dist/utils/workpace/workspace-navigation.d.ts +17 -0
  559. package/dist/utils/workpace/workspace-navigation.d.ts.map +1 -0
  560. package/dist/utils/workpace/workspace-navigation.js +123 -0
  561. package/dist/utils/workpace/workspace-navigation.js.map +1 -0
  562. package/dist/utils/workpace/workspaces-grid copy.d.ts +30 -0
  563. package/dist/utils/workpace/workspaces-grid copy.d.ts.map +1 -0
  564. package/dist/utils/workpace/workspaces-grid copy.js +97 -0
  565. package/dist/utils/workpace/workspaces-grid copy.js.map +1 -0
  566. package/dist/utils/workpace/workspaces-grid.d.ts +22 -0
  567. package/dist/utils/workpace/workspaces-grid.d.ts.map +1 -0
  568. package/dist/utils/workpace/workspaces-grid.js +123 -0
  569. package/dist/utils/workpace/workspaces-grid.js.map +1 -0
  570. package/dist/utils/workpace/worspace-state.d.ts +18 -0
  571. package/dist/utils/workpace/worspace-state.d.ts.map +1 -0
  572. package/dist/utils/workpace/worspace-state.js +2 -0
  573. package/dist/utils/workpace/worspace-state.js.map +1 -0
  574. package/dist/utils/workspace/framework-detector.d.ts +7 -0
  575. package/dist/utils/workspace/framework-detector.d.ts.map +1 -0
  576. package/dist/utils/workspace/framework-detector.js +111 -0
  577. package/dist/utils/workspace/framework-detector.js.map +1 -0
  578. package/dist/utils/workspace/workspace-grid.d.ts +22 -0
  579. package/dist/utils/workspace/workspace-grid.d.ts.map +1 -0
  580. package/dist/utils/workspace/workspace-grid.js +123 -0
  581. package/dist/utils/workspace/workspace-grid.js.map +1 -0
  582. package/dist/utils/workspace/workspace-helper.d.ts +7 -0
  583. package/dist/utils/workspace/workspace-helper.d.ts.map +1 -0
  584. package/dist/utils/workspace/workspace-helper.js +10 -0
  585. package/dist/utils/workspace/workspace-helper.js.map +1 -0
  586. package/dist/utils/workspace/workspaces-grid.d.ts +22 -0
  587. package/dist/utils/workspace/workspaces-grid.d.ts.map +1 -0
  588. package/dist/utils/workspace/workspaces-grid.js +123 -0
  589. package/dist/utils/workspace/workspaces-grid.js.map +1 -0
  590. package/dist/utils/workspace-helper.d.ts +10 -0
  591. package/dist/utils/workspace-helper.d.ts.map +1 -0
  592. package/dist/utils/workspace-helper.js +46 -0
  593. package/dist/utils/workspace-helper.js.map +1 -0
  594. package/dist/utils/workspace-navigation.d.ts +1 -0
  595. package/dist/utils/workspace-navigation.d.ts.map +1 -0
  596. package/dist/utils/workspace-navigation.js +2 -0
  597. package/dist/utils/workspace-navigation.js.map +1 -0
  598. package/jest.config.mjs +31 -0
  599. package/package.json +69 -0
  600. package/scripts/run-commitlint.sh +48 -0
  601. package/src/app/App.tsx +25 -0
  602. package/src/app/Layout.tsx +37 -0
  603. package/src/app/pages/Exit.tsx +9 -0
  604. package/src/app/pages/ProjectPage.tsx +37 -0
  605. package/src/app/pages/WorkspacePage.tsx +33 -0
  606. package/src/bin/init.ts +7 -0
  607. package/src/bin/trace-warnings.ts +25 -0
  608. package/src/commands/init.ts +80 -0
  609. package/src/components/features/ProjectGrid/ColCompose.tsx +99 -0
  610. package/src/components/features/ProjectGrid/ColMakefile.tsx +44 -0
  611. package/src/components/features/ProjectGrid/ColPackageJson.tsx +54 -0
  612. package/src/components/features/ProjectGrid/EmptyCol.tsx +28 -0
  613. package/src/components/features/ProjectGrid/ProjectGrid.tsx +94 -0
  614. package/src/components/features/ProjectGrid/ProjectInfo.tsx +67 -0
  615. package/src/components/features/WorkspaceGrid/WorkspaceGrid.tsx +52 -0
  616. package/src/components/features/WorkspaceGrid/WorkspaceInfo.tsx +89 -0
  617. package/src/components/features/WorkspaceGrid/WorkspaceRow.tsx +115 -0
  618. package/src/components/layouts/Header/Header.tsx +51 -0
  619. package/src/components/layouts/Header/ProjectCommands.tsx +17 -0
  620. package/src/components/layouts/Header/WorkspaceCommands.tsx +60 -0
  621. package/src/config/config.ts +46 -0
  622. package/src/config/defaults.ts +44 -0
  623. package/src/contexts/PageNavigationContext.tsx +39 -0
  624. package/src/contexts/ProjectGridContext.tsx +92 -0
  625. package/src/contexts/WorkspaceDiscoveryContext.tsx +46 -0
  626. package/src/contexts/WorkspaceGridContext.tsx +113 -0
  627. package/src/hooks/useProjectGrid.ts +77 -0
  628. package/src/hooks/useWorkspaceDiscovery.ts +61 -0
  629. package/src/hooks/useWorkspaceGrid.ts +85 -0
  630. package/src/hooks/useWorkspaceQuickActions.ts +114 -0
  631. package/src/hooks/useWorkspaceRuntime.ts +92 -0
  632. package/src/index.ts +10 -0
  633. package/src/services/discovery/facets/compose-parser.ts +236 -0
  634. package/src/services/discovery/facets/makefile-parser.ts +196 -0
  635. package/src/services/discovery/facets/package-json-parser.ts +151 -0
  636. package/src/services/discovery/index.ts +1 -0
  637. package/src/services/discovery/workspace-discovery.ts +105 -0
  638. package/src/services/runtime/command-runner.ts +87 -0
  639. package/src/services/runtime/docker-runtime.ts +171 -0
  640. package/src/services/runtime/node-runtime.ts +253 -0
  641. package/src/services/runtime/resolve-runtime.ts +45 -0
  642. package/src/services/runtime/stop-runtime.ts +52 -0
  643. package/src/theme/theme.ts +72 -0
  644. package/src/types/config.ts +50 -0
  645. package/src/types/page.ts +5 -0
  646. package/src/types/project-grid.ts +73 -0
  647. package/src/types/project.ts +81 -0
  648. package/src/types/workspace-grid.ts +41 -0
  649. package/src/types/workspace-quick-actions.ts +12 -0
  650. package/src/types/workspace-runtime.ts +28 -0
  651. package/src/utils/fs/directories.test.ts +60 -0
  652. package/src/utils/fs/directories.ts +54 -0
  653. package/src/utils/fs/file.test.ts +90 -0
  654. package/src/utils/fs/file.ts +32 -0
  655. package/src/utils/fs/package-json.ts +12 -0
  656. package/src/utils/logging/logger.ts +103 -0
  657. package/src/utils/navigation/grid-navigation.ts +60 -0
  658. package/src/utils/navigation/navigation-helper.ts +84 -0
  659. package/src/utils/project/project-grid.ts +165 -0
  660. package/src/utils/runtime/port.test.ts +34 -0
  661. package/src/utils/runtime/port.ts +26 -0
  662. package/src/utils/workspace/framework-detector.ts +77 -0
  663. package/src/utils/workspace/workspace-grid.ts +161 -0
  664. package/src/utils/workspace/workspace-helper.ts +21 -0
  665. package/tsconfig.json +23 -0
  666. package/workspace-cli.mjs +18 -0
@@ -0,0 +1,87 @@
1
+ import { spawn } from "node:child_process"
2
+
3
+ import type { ProjectGridCell } from "../../types/project-grid"
4
+
5
+ /**
6
+ * Extracts the shell command string from a navigation cell.
7
+ */
8
+ export function getCommandFromCell(cell: ProjectGridCell): string | null {
9
+ switch (cell.type) {
10
+ case "makefile":
11
+ return cell.command.command
12
+ case "packageJson":
13
+ return cell.script.command
14
+ case "composeCommand":
15
+ return cell.action.command
16
+ case "composeService":
17
+ return null
18
+ }
19
+ }
20
+
21
+ /**
22
+ * Extracts the shell command string from a navigation cell.
23
+ */
24
+ export function getExecFromCell(cell: ProjectGridCell): string | null {
25
+ switch (cell.type) {
26
+ case "makefile":
27
+ return cell.command.exec
28
+ case "packageJson":
29
+ return cell.script.exec
30
+ case "composeCommand":
31
+ return cell.action.command
32
+ }
33
+ return null
34
+ }
35
+
36
+ export function runCellCommand(
37
+ command: string,
38
+ cwd: string,
39
+ options?: { detached?: boolean },
40
+ ): void {
41
+ if (!command) {
42
+ return
43
+ }
44
+
45
+ const detached = options?.detached ?? false
46
+
47
+ if (detached) {
48
+ const child = spawn(command, {
49
+ cwd,
50
+ shell: true,
51
+ detached: true,
52
+ stdio: "ignore",
53
+ })
54
+ child.unref()
55
+ return
56
+ }
57
+
58
+ // Restore terminal to cooked mode so the TTY driver handles Ctrl+C → SIGINT
59
+ if (process.stdin.isTTY) {
60
+ process.stdin.setRawMode(false)
61
+ }
62
+
63
+ spawn(command, {
64
+ cwd,
65
+ stdio: "inherit",
66
+ shell: true,
67
+ })
68
+ }
69
+
70
+ /**
71
+ * Returns true when a command is expected to detach
72
+ */
73
+ export function shouldKeepTuiOpen(command: string): boolean {
74
+ const normalized = command.trim().toLowerCase()
75
+ if (!normalized) {
76
+ return false
77
+ }
78
+
79
+ const isDockerCompose = /\bdocker(?:\s+compose|\s+-compose)\b/.test(
80
+ normalized,
81
+ )
82
+ const isUpCommand = /\bup\b/.test(normalized)
83
+ const isDownOrStopCommand = /\b(down|stop)\b/.test(normalized)
84
+ const isDetached = /(^|\s)(-d|--detach)(\s|$)/.test(normalized)
85
+
86
+ return isDockerCompose && ((isUpCommand && isDetached) || isDownOrStopCommand)
87
+ }
@@ -0,0 +1,171 @@
1
+ import { execFile } from "node:child_process"
2
+ import { promisify } from "node:util"
3
+
4
+ import type { ComposeService } from "../../types/project"
5
+ import type { RunState, RuntimeStatus } from "../../types/workspace-runtime"
6
+ import { logger } from "../../utils/logging/logger.js"
7
+ import { isPortInUse } from "../../utils/runtime/port.js"
8
+
9
+ const execFileAsync = promisify(execFile)
10
+
11
+ /**
12
+ * Shape returned by `docker ps --format '{{json .}}'` (one JSON object per line)
13
+ */
14
+ interface DockerPsEntry {
15
+ ID: string
16
+ Names: string
17
+ Image: string
18
+ State: string // "running", "exited", "paused", etc.
19
+ Status: string // "Up 2 hours", "Exited (0) 3 minutes ago"
20
+ Ports: string // "0.0.0.0:5432->5432/tcp" or ""
21
+ }
22
+
23
+ /**
24
+ * Fetch all Docker containers (running + stopped) as structured JSON.
25
+ */
26
+ async function getDockerContainers(): Promise<DockerPsEntry[]> {
27
+ try {
28
+ const { stdout } = await execFileAsync("docker", [
29
+ "ps",
30
+ "-a",
31
+ "--format",
32
+ "{{json .}}",
33
+ ])
34
+
35
+ // Each line is a separate JSON object
36
+ return stdout
37
+ .trim()
38
+ .split("\n")
39
+ .filter(Boolean)
40
+ .map((line) => JSON.parse(line) as DockerPsEntry)
41
+ } catch (error) {
42
+ logger.debug(error, "Failed to get Docker containers")
43
+ return []
44
+ }
45
+ }
46
+
47
+ /**
48
+ * Extract host ports from Docker's Ports string.
49
+ * e.g. "0.0.0.0:5432->5432/tcp, :::5432->5432/tcp" → [5432]
50
+ */
51
+ function parseDockerPorts(portsStr: string): number[] {
52
+ if (!portsStr) return []
53
+ const ports = new Set<number>()
54
+ // Match patterns like "0.0.0.0:5432->5432/tcp" or ":::3000->3000/tcp"
55
+ const matches = portsStr.matchAll(/:(\d+)->/g)
56
+ for (const match of matches) {
57
+ ports.add(Number.parseInt(match[1], 10))
58
+ }
59
+ return [...ports]
60
+ }
61
+
62
+ /**
63
+ * Build RunState[] for compose services.
64
+ *
65
+ * 1. Get all running Docker containers.
66
+ * 2. For each compose service, check if a running container matches the service name.
67
+ * - Name matches → "running"
68
+ * - A container is running on the same port but with a different name → "conflict"
69
+ * 3. No matching container found → check if the port is already in use.
70
+ * - Port in use → "conflict"
71
+ * - Port free → "stopped"
72
+ */
73
+ export async function getDockerRunStates(
74
+ workspacePath: string,
75
+ services: ComposeService[],
76
+ ): Promise<RunState[]> {
77
+ if (services.length === 0) return []
78
+
79
+ // Only get running containers
80
+ const allContainers = await getDockerContainers()
81
+ const runningContainers = allContainers.filter(
82
+ (c) => c.State.toLowerCase() === "running",
83
+ )
84
+
85
+ const results: RunState[] = []
86
+
87
+ for (const service of services) {
88
+ let status: RuntimeStatus = "stopped"
89
+ let statusMessage: string | undefined
90
+ const port = service.ports?.[0]
91
+
92
+ // 1. Check if a running container matches the service name
93
+ const nameMatch = runningContainers.find((c) =>
94
+ c.Names.toLowerCase().includes(service.name.toLowerCase()),
95
+ )
96
+
97
+ if (nameMatch) {
98
+ // If containerName is set, also verify it matches
99
+ if (
100
+ service.containerName &&
101
+ !nameMatch.Names.toLowerCase().includes(
102
+ service.containerName.toLowerCase(),
103
+ )
104
+ ) {
105
+ // Service name matches but containerName doesn't → conflict
106
+ status = "conflict"
107
+ statusMessage = `Conflict with running container: ${nameMatch.Names}`
108
+ } else {
109
+ // Both names match (or no containerName set) → running
110
+ status = "running"
111
+ const containerPorts = parseDockerPorts(nameMatch.Ports)
112
+ const resolvedPort =
113
+ containerPorts.length > 0 ? containerPorts[0] : port
114
+
115
+ results.push({
116
+ id: `${workspacePath}::compose::${service.name}`,
117
+ name: service.name,
118
+ type: "service" as const,
119
+ status,
120
+ statusMessage,
121
+ command: `docker compose up ${service.name}`,
122
+ port: resolvedPort,
123
+ })
124
+ continue
125
+ }
126
+ } else if (service.containerName) {
127
+ // No match on service name — also try matching by containerName
128
+ const containerName = service.containerName
129
+ const containerNameMatch = runningContainers.find((c) =>
130
+ c.Names.toLowerCase().includes(containerName.toLowerCase()),
131
+ )
132
+
133
+ if (containerNameMatch) {
134
+ // containerName matches but service name didn't → conflict
135
+ status = "conflict"
136
+ statusMessage = `Conflict with running container: ${containerNameMatch.Names}`
137
+ }
138
+ }
139
+
140
+ // 2. No match at all — check if the port is already in use
141
+ if (status === "stopped" && port != null) {
142
+ const portConflict = runningContainers.find((c) => {
143
+ const containerPorts = parseDockerPorts(c.Ports)
144
+ return containerPorts.includes(port)
145
+ })
146
+
147
+ if (portConflict) {
148
+ status = "conflict"
149
+ statusMessage = `Conflict with running container: ${portConflict.Names}`
150
+ } else {
151
+ const taken = await isPortInUse(port)
152
+ if (taken) {
153
+ status = "conflict"
154
+ statusMessage = `Port ${port} is already in use`
155
+ }
156
+ }
157
+ }
158
+
159
+ results.push({
160
+ id: `${workspacePath}::compose::${service.name}`,
161
+ name: service.name,
162
+ type: "service" as const,
163
+ status,
164
+ statusMessage,
165
+ command: `docker compose up ${service.name}`,
166
+ port,
167
+ })
168
+ }
169
+
170
+ return results
171
+ }
@@ -0,0 +1,253 @@
1
+ import { execFile } from "node:child_process"
2
+ import { promisify } from "node:util"
3
+
4
+ import type { PackageJsonScript } from "../../types/project"
5
+ import type { RunState } from "../../types/workspace-runtime"
6
+
7
+ const execFileAsync = promisify(execFile)
8
+
9
+ async function sh(cmd: string, args: string[], opts?: { cwd?: string }) {
10
+ const { stdout } = await execFileAsync(cmd, args, {
11
+ cwd: opts?.cwd,
12
+ maxBuffer: 10 * 1024 * 1024,
13
+ })
14
+ return String(stdout ?? "")
15
+ }
16
+
17
+ async function getPsOutput(): Promise<string> {
18
+ // Try GNU procps first
19
+ try {
20
+ // Include both command and working directory
21
+ return await sh("ps", ["-eo", "pid=,args=,cwd="])
22
+ } catch {
23
+ // Fallback: BSD / busybox style
24
+ // BSD ps doesn't have cwd, so we'll need to read it from /proc later
25
+ return await sh("ps", ["ax", "-o", "pid=", "-o", "command="])
26
+ }
27
+ }
28
+
29
+ async function getPidCwd(pid: number): Promise<string | null> {
30
+ try {
31
+ // On Linux, read the cwd symlink
32
+ const cwd = await sh("readlink", ["-f", `/proc/${pid}/cwd`])
33
+ return cwd.trim()
34
+ } catch {
35
+ return null
36
+ }
37
+ }
38
+
39
+ function extractCoreCommand(command: string): string {
40
+ // Remove common package managers and extract the actual command
41
+ const trimmed = command.trim()
42
+
43
+ // Strip npm/yarn/pnpm run prefix
44
+ const withoutPkgManager = trimmed
45
+ .replace(/^(npm|yarn|pnpm|bun)\s+run\s+/, "")
46
+ .replace(/^(npx|bunx)\s+/, "")
47
+
48
+ // Get the first significant part (the actual executable/script)
49
+ // e.g., "next dev --turbo -p 3001" -> "next dev"
50
+ // e.g., "vite --port 5173" -> "vite"
51
+ const parts = withoutPkgManager.split(/\s+/)
52
+
53
+ // Take first 1-2 parts depending on common patterns
54
+ if (
55
+ parts.length >= 2 &&
56
+ (parts[1] === "dev" ||
57
+ parts[1] === "start" ||
58
+ parts[1] === "serve" ||
59
+ parts[1] === "preview")
60
+ ) {
61
+ return `${parts[0]} ${parts[1]}`
62
+ }
63
+
64
+ return parts[0] || withoutPkgManager
65
+ }
66
+
67
+ async function getPidsMatchingCommandInWorkspace(params: {
68
+ command: string
69
+ absolutePath: string
70
+ }): Promise<number[]> {
71
+ const out = await getPsOutput()
72
+
73
+ // Extract core command for more flexible matching
74
+ const coreCommand = extractCoreCommand(params.command)
75
+ const wsNeedle = params.absolutePath.trim()
76
+ const pids: number[] = []
77
+
78
+ for (const line of out.split("\n")) {
79
+ const trimmed = line.trim()
80
+ if (!trimmed) continue
81
+
82
+ // Parse pid and command
83
+ const firstSpace = trimmed.indexOf(" ")
84
+ if (firstSpace <= 0) continue
85
+
86
+ const pidStr = trimmed.slice(0, firstSpace).trim()
87
+ const rest = trimmed.slice(firstSpace + 1)
88
+
89
+ const pid = Number(pidStr)
90
+ if (!Number.isFinite(pid)) continue
91
+
92
+ // Check if command matches the core command
93
+ // This allows "next dev --turbo" to match "next dev --turbopack -p 3001"
94
+ if (!rest.includes(coreCommand)) continue
95
+
96
+ // Check if the command line includes the workspace path OR
97
+ // check if the process cwd is within the workspace
98
+ if (rest.includes(wsNeedle)) {
99
+ pids.push(pid)
100
+ } else {
101
+ // Fallback: check the process working directory
102
+ const cwd = await getPidCwd(pid)
103
+ if (cwd?.startsWith(wsNeedle)) {
104
+ pids.push(pid)
105
+ }
106
+ }
107
+ }
108
+
109
+ return Array.from(new Set(pids))
110
+ }
111
+
112
+ type PidToPorts = Map<number, Set<number>>
113
+
114
+ function parseSsListeningTcp(out: string): PidToPorts {
115
+ const pidToPorts: PidToPorts = new Map()
116
+
117
+ for (const rawLine of out.split("\n")) {
118
+ const line = rawLine.trim()
119
+ if (!line) continue
120
+
121
+ // Grab a port from "*:3000", "127.0.0.1:5173", "[::]:3000", etc.
122
+ // This is a heuristic that works for typical `ss -lptnH` output.
123
+ const portMatch = line.match(/:(\d+)\s+/)
124
+ if (!portMatch) continue
125
+ const port = Number(portMatch[1])
126
+ if (!Number.isFinite(port)) continue
127
+
128
+ // Extract pids from users:(("...",pid=123,...),(...pid=456...))
129
+ const pidMatches = line.matchAll(/pid=(\d+)/g)
130
+ for (const m of pidMatches) {
131
+ const pid = Number(m[1])
132
+ if (!Number.isFinite(pid)) continue
133
+
134
+ if (!pidToPorts.has(pid)) pidToPorts.set(pid, new Set())
135
+ pidToPorts.get(pid)?.add(port)
136
+ }
137
+ }
138
+
139
+ return pidToPorts
140
+ }
141
+
142
+ async function getListeningPortsForPids(
143
+ pids: number[],
144
+ ): Promise<Map<number, number[]>> {
145
+ if (pids.length === 0) return new Map()
146
+
147
+ const ssOut = await sh("ss", ["-lptnH"])
148
+ const pidToPortsSet = parseSsListeningTcp(ssOut)
149
+
150
+ const pidToPorts = new Map<number, number[]>()
151
+ for (const pid of pids) {
152
+ const ports = pidToPortsSet.get(pid)
153
+ pidToPorts.set(pid, ports ? Array.from(ports).sort((a, b) => a - b) : [])
154
+ }
155
+ return pidToPorts
156
+ }
157
+
158
+ async function getChildPids(parentPid: number): Promise<number[]> {
159
+ try {
160
+ const out = await sh("pgrep", ["-P", String(parentPid)])
161
+ return out
162
+ .trim()
163
+ .split("\n")
164
+ .filter(Boolean)
165
+ .map(Number)
166
+ .filter(Number.isFinite)
167
+ } catch {
168
+ return []
169
+ }
170
+ }
171
+
172
+ async function getAllDescendantPids(pid: number): Promise<number[]> {
173
+ const descendants: number[] = [pid]
174
+ const children = await getChildPids(pid)
175
+
176
+ for (const child of children) {
177
+ const childDescendants = await getAllDescendantPids(child)
178
+ descendants.push(...childDescendants)
179
+ }
180
+
181
+ return descendants
182
+ }
183
+
184
+ export async function getNodeRunStates(
185
+ absolutePath: string,
186
+ workspacePath: string,
187
+ scripts: PackageJsonScript[],
188
+ ): Promise<RunState[]> {
189
+ const results: RunState[] = []
190
+
191
+ for (const script of scripts) {
192
+ const name = script.name as string
193
+ const command = script.command as string
194
+
195
+ const pids = await getPidsMatchingCommandInWorkspace({
196
+ command,
197
+ absolutePath,
198
+ })
199
+
200
+ // Get all descendant processes
201
+ const allPids = new Set<number>()
202
+ for (const pid of pids) {
203
+ const descendants = await getAllDescendantPids(pid)
204
+ descendants.forEach((p) => {
205
+ allPids.add(p)
206
+ })
207
+ }
208
+
209
+ const allPidsArray = Array.from(allPids)
210
+ const pidToPorts = await getListeningPortsForPids(allPidsArray)
211
+
212
+ const allPorts = new Set<number>()
213
+ for (const ports of pidToPorts.values()) {
214
+ for (const p of ports) allPorts.add(p)
215
+ }
216
+
217
+ const portsSorted = Array.from(allPorts).sort((a, b) => a - b)
218
+
219
+ let status: RunState["status"] = "stopped"
220
+ let port: number | undefined
221
+ let statusMessage: string | undefined
222
+
223
+ if (pids.length === 0) {
224
+ status = "stopped"
225
+ } else {
226
+ status = "running"
227
+ if (portsSorted.length === 1) {
228
+ port = portsSorted[0]
229
+ } else if (portsSorted.length > 1) {
230
+ status = "conflict"
231
+ statusMessage = `Multiple listening ports detected: ${portsSorted.join(
232
+ ", ",
233
+ )} (pids: ${allPidsArray.join(", ")})`
234
+ } else {
235
+ statusMessage = `Process running (pids: ${allPidsArray.join(
236
+ ", ",
237
+ )}) but no LISTEN TCP port detected`
238
+ }
239
+ }
240
+
241
+ results.push({
242
+ id: `${workspacePath}::packageJson::${name}`,
243
+ name,
244
+ type: "script",
245
+ status,
246
+ statusMessage,
247
+ command,
248
+ port,
249
+ })
250
+ }
251
+
252
+ return results
253
+ }
@@ -0,0 +1,45 @@
1
+ import type { RunState } from "../../types/workspace-runtime"
2
+
3
+ /**
4
+ * Resolves conflicts between Node and Docker run states.
5
+ * If a service is "conflict" in one runtime but "running" in the other,
6
+ * change the "conflict" status to "stopped" (or another status if needed).
7
+ *
8
+ * @param nodeStates RunState[] from Node runtime
9
+ * @param dockerStates RunState[] from Docker runtime
10
+ * @returns { node: RunState[], docker: RunState[] }
11
+ */
12
+ export function resolveRuntimeConflicts(
13
+ nodeStates: RunState[],
14
+ dockerStates: RunState[],
15
+ ): { node: RunState[]; docker: RunState[] } {
16
+ // Helper to find a running service in the other runtime by port or name
17
+ function findRunningOther(states: RunState[], name: string, port?: number) {
18
+ return states.find(
19
+ (s) =>
20
+ s.status === "running" &&
21
+ ((port != null && s.port === port) || s.name === name),
22
+ )
23
+ }
24
+
25
+ function resolve(states: RunState[], otherStates: RunState[]): RunState[] {
26
+ return states.map((state) => {
27
+ if (state.status === "conflict") {
28
+ const other = findRunningOther(otherStates, state.name, state.port)
29
+ if (other) {
30
+ return {
31
+ ...state,
32
+ status: "stopped",
33
+ statusMessage: "Stopped due to other runtime running",
34
+ }
35
+ }
36
+ }
37
+ return state
38
+ })
39
+ }
40
+
41
+ return {
42
+ node: resolve(nodeStates, dockerStates),
43
+ docker: resolve(dockerStates, nodeStates),
44
+ }
45
+ }
@@ -0,0 +1,52 @@
1
+ import { exec } from "node:child_process"
2
+
3
+ import { logger } from "../../utils/logging/logger.js"
4
+
5
+ /**
6
+ * Stop a running script process by port (using fuser)
7
+ */
8
+ export function stopScriptProcess(runState: { port?: number }) {
9
+ if (runState.port) {
10
+ exec(`fuser -k ${runState.port}/tcp`, (err) => {
11
+ if (err) {
12
+ // eslint-disable-next-line no-console
13
+ console.error(`Failed to kill process on port ${runState.port}: ${err}`)
14
+ } else {
15
+ // eslint-disable-next-line no-console
16
+ logger.debug(`Stopped process on port ${runState.port}`)
17
+ }
18
+ })
19
+ } else {
20
+ // eslint-disable-next-line no-console
21
+ console.warn("No port found for running script, cannot stop.")
22
+ }
23
+ }
24
+
25
+ /**
26
+ * Stop a running Docker Compose service
27
+ */
28
+ export function stopComposeService(runState: { id: string; name: string }) {
29
+ // Try to extract workspace path from runState.id (format: workspacePath::compose::<service>)
30
+ const match = runState.id.match(/^(.*)::compose::/)
31
+ const workspacePath = match ? match[1] : undefined
32
+ if (workspacePath) {
33
+ exec(
34
+ `docker compose stop ${runState.name}`,
35
+ { cwd: workspacePath },
36
+ (err) => {
37
+ if (err) {
38
+ // eslint-disable-next-line no-console
39
+ console.error(
40
+ `Failed to stop docker service ${runState.name}: ${err}`,
41
+ )
42
+ } else {
43
+ // eslint-disable-next-line no-console
44
+ logger.debug(`Stopped docker service ${runState.name}`)
45
+ }
46
+ },
47
+ )
48
+ } else {
49
+ // eslint-disable-next-line no-console
50
+ console.warn("Could not determine workspace path for docker compose stop.")
51
+ }
52
+ }
@@ -0,0 +1,72 @@
1
+ import { type ComponentTheme, defaultTheme, extendTheme } from "@inkjs/ui"
2
+ import type { BoxProps, TextProps } from "ink"
3
+ import type { ThemeName } from "../types/config.js"
4
+
5
+ const appLayoutTheme = {
6
+ styles: {
7
+ container: (): BoxProps => ({
8
+ borderColor: "cyan",
9
+ }),
10
+ },
11
+ } satisfies ComponentTheme
12
+
13
+ const gridTheme = {
14
+ styles: {
15
+ title: (): TextProps => ({
16
+ color: "cyan",
17
+ }),
18
+ headerText: (): TextProps => ({
19
+ color: "white",
20
+ }),
21
+ text: (): TextProps => ({
22
+ color: "white",
23
+ }),
24
+ info: (): TextProps => ({
25
+ color: "cyan",
26
+ }),
27
+ workspaceName: (): TextProps => ({
28
+ color: "white",
29
+ }),
30
+ action: (): TextProps => ({
31
+ color: "cyan",
32
+ }),
33
+ error: (): TextProps => ({
34
+ color: "red",
35
+ }),
36
+ border: (): BoxProps => ({
37
+ borderColor: "cyan",
38
+ }),
39
+ runtime: ({ status }: { status?: string }): TextProps => ({
40
+ color:
41
+ status === "failed" || status === "conflict"
42
+ ? "red"
43
+ : status === "starting" || status === "stopping"
44
+ ? "yellow"
45
+ : status === "running"
46
+ ? "green"
47
+ : "white",
48
+ }),
49
+ },
50
+ } satisfies ComponentTheme
51
+
52
+ export type AppLayoutTheme = typeof appLayoutTheme
53
+ export type GridTheme = typeof gridTheme
54
+
55
+ export const darkTheme = extendTheme(defaultTheme, {
56
+ components: {
57
+ AppLayout: appLayoutTheme,
58
+ GridTheme: gridTheme,
59
+ },
60
+ })
61
+
62
+ const themes: Record<ThemeName, typeof darkTheme> = {
63
+ dark: darkTheme,
64
+ }
65
+
66
+ export function getAppTheme(themeName?: ThemeName) {
67
+ if (!themeName) {
68
+ return darkTheme
69
+ }
70
+
71
+ return themes[themeName] ?? darkTheme
72
+ }