@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,236 @@
1
+ import { readFile } from "node:fs/promises"
2
+ import { dirname, join, relative } from "node:path"
3
+ import { parse as parseYaml } from "yaml"
4
+
5
+ import type { ComposeFacet } from "../../../types/project.js"
6
+ import { fileExists } from "../../../utils/fs/file.js"
7
+ import { logger } from "../../../utils/logging/logger.js"
8
+
9
+ const ENV_VAR_PATTERN = /\$\{([^}:]+)(?::-([^}]*))?\}|\$([A-Za-z_]\w*)/
10
+ const ENV_VAR_PATTERN_GLOBAL = /\$\{([^}:]+)(?::-([^}]*))?\}|\$([A-Za-z_]\w*)/g
11
+
12
+ /**
13
+ * Resolve all env variable references in a string.
14
+ * Supports: ${VAR}, ${VAR:-default}, $VAR
15
+ * Returns the string with all variables replaced, or undefined if any remain unresolved.
16
+ */
17
+ function resolveEnvVars(
18
+ raw: string,
19
+ envVars: Record<string, string>,
20
+ ): string | undefined {
21
+ let hasUnresolved = false
22
+ const result = raw.replace(
23
+ ENV_VAR_PATTERN_GLOBAL,
24
+ (_match, braced, defaultVal, bare) => {
25
+ const varName = braced ?? bare
26
+ const resolved = envVars[varName] ?? defaultVal
27
+ if (resolved == null) {
28
+ hasUnresolved = true
29
+ logger.debug(`Unresolved env variable $${varName} in "${raw}"`)
30
+ return _match
31
+ }
32
+ return resolved
33
+ },
34
+ )
35
+ return hasUnresolved ? undefined : result
36
+ }
37
+
38
+ /**
39
+ * Parse an .env file into a key→value map.
40
+ * Handles KEY=VALUE, quotes, and inline comments.
41
+ */
42
+ async function parseEnvFile(envPath: string): Promise<Record<string, string>> {
43
+ const vars: Record<string, string> = {}
44
+ if (!(await fileExists(envPath))) {
45
+ return vars
46
+ }
47
+ try {
48
+ const content = await readFile(envPath, "utf-8")
49
+ for (const line of content.split("\n")) {
50
+ const trimmed = line.trim()
51
+ if (!trimmed || trimmed.startsWith("#")) continue
52
+ const eqIndex = trimmed.indexOf("=")
53
+ if (eqIndex === -1) continue
54
+ const key = trimmed.slice(0, eqIndex).trim()
55
+ let value = trimmed.slice(eqIndex + 1).trim()
56
+ // Strip surrounding quotes
57
+ if (
58
+ (value.startsWith('"') && value.endsWith('"')) ||
59
+ (value.startsWith("'") && value.endsWith("'"))
60
+ ) {
61
+ value = value.slice(1, -1)
62
+ }
63
+ vars[key] = value
64
+ }
65
+ } catch {
66
+ // Silently ignore unreadable env files
67
+ }
68
+ return vars
69
+ }
70
+
71
+ /**
72
+ * Resolve a port string that may contain env variable references.
73
+ * Supports: ${VAR}, ${VAR:-default}, $VAR
74
+ * Falls back to the env file(s), then the default value, then null.
75
+ */
76
+ function resolvePortValue(
77
+ raw: string,
78
+ envVars: Record<string, string>,
79
+ ): number | null {
80
+ const match = raw.match(ENV_VAR_PATTERN)
81
+ if (!match) {
82
+ // No variable — plain number
83
+ const n = Number.parseInt(raw, 10)
84
+ return Number.isNaN(n) ? null : n
85
+ }
86
+
87
+ const varName = match[1] ?? match[3]
88
+ const defaultValue = match[2] // from ${VAR:-default} syntax
89
+
90
+ const resolved = envVars[varName] ?? defaultValue
91
+ if (resolved == null) {
92
+ logger.debug(`Unresolved env variable $${varName} in port mapping "${raw}"`)
93
+ return null
94
+ }
95
+
96
+ const n = Number.parseInt(resolved, 10)
97
+ return Number.isNaN(n) ? null : n
98
+ }
99
+
100
+ /**
101
+ * Extract and resolve host ports from a compose service's port mappings.
102
+ * Resolves env variables (${VAR}, ${VAR:-default}, $VAR) using the
103
+ * .env file located next to the compose file.
104
+ */
105
+ export async function getPorts(
106
+ rawPorts: (string | number)[],
107
+ composeDir: string,
108
+ envFileName = ".env",
109
+ ): Promise<number[]> {
110
+ const envVars = await parseEnvFile(join(composeDir, envFileName))
111
+ const resolved: number[] = []
112
+
113
+ for (const p of rawPorts) {
114
+ if (typeof p === "number") {
115
+ resolved.push(p)
116
+ continue
117
+ }
118
+
119
+ // Extract the host part from "host:container" or "host:container/proto"
120
+ const hostPart = p.toString().split(":")[0]
121
+ const port = resolvePortValue(hostPart, envVars)
122
+ if (port != null) {
123
+ resolved.push(port)
124
+ }
125
+ }
126
+
127
+ return resolved
128
+ }
129
+
130
+ export interface ComposeParseOptions {
131
+ filenames?: string[]
132
+ services?: {
133
+ include?: string[]
134
+ exclude?: string[]
135
+ }
136
+ envFile?: string
137
+ }
138
+
139
+ export async function parseDockerCompose(
140
+ dir: string,
141
+ options: ComposeParseOptions = {},
142
+ ): Promise<ComposeFacet | null> {
143
+ const filenames = options.filenames ?? [
144
+ "docker-compose.yml",
145
+ "docker-compose.yaml",
146
+ "compose.yml",
147
+ "compose.yaml",
148
+ ]
149
+ const envFileName = options.envFile ?? ".env"
150
+
151
+ const services: Array<{
152
+ name: string
153
+ containerName?: string
154
+ image?: string
155
+ ports?: number[]
156
+ }> = []
157
+ let foundFile: string | null = null
158
+
159
+ for (const filename of filenames) {
160
+ const composePath = join(dir, filename)
161
+
162
+ if (!(await fileExists(composePath))) {
163
+ continue
164
+ }
165
+
166
+ try {
167
+ const content = await readFile(composePath, "utf-8")
168
+ const data = parseYaml(content) as {
169
+ services?: Record<
170
+ string,
171
+ {
172
+ container_name?: string
173
+ image?: string
174
+ ports?: (string | number)[]
175
+ env_file?: string | string[]
176
+ }
177
+ >
178
+ }
179
+
180
+ if (!data.services) {
181
+ continue
182
+ }
183
+
184
+ foundFile = filename
185
+ const composeDir = dirname(composePath)
186
+ const envVars = await parseEnvFile(join(composeDir, envFileName))
187
+
188
+ for (const [serviceName, serviceConfig] of Object.entries(
189
+ data.services,
190
+ )) {
191
+ // Apply service include/exclude filters
192
+ if (
193
+ options.services?.include &&
194
+ !options.services.include.includes(serviceName)
195
+ ) {
196
+ continue
197
+ }
198
+ if (options.services?.exclude?.includes(serviceName)) {
199
+ continue
200
+ }
201
+
202
+ const ports = serviceConfig.ports
203
+ ? await getPorts(serviceConfig.ports, composeDir, envFileName)
204
+ : []
205
+
206
+ // Resolve env variables in container_name (e.g. "${NAMESPACE}-postgres")
207
+ const containerName = serviceConfig.container_name
208
+ ? resolveEnvVars(serviceConfig.container_name, envVars)
209
+ : undefined
210
+
211
+ services.push({
212
+ name: serviceName,
213
+ containerName,
214
+ image: serviceConfig.image,
215
+ ports,
216
+ })
217
+ }
218
+
219
+ break // Only parse the first found compose file
220
+ } catch (error) {
221
+ // Skip invalid YAML files
222
+ logger.debug(error, `Failed to parse ${filename}:`)
223
+ }
224
+ }
225
+
226
+ if (!foundFile || services.length === 0) {
227
+ return null
228
+ }
229
+
230
+ return {
231
+ type: "compose",
232
+ filename: foundFile,
233
+ path: relative(process.cwd(), join(dir, foundFile)),
234
+ services,
235
+ }
236
+ }
@@ -0,0 +1,196 @@
1
+ import { readFile } from "node:fs/promises"
2
+ import { dirname, join, relative, resolve } from "node:path"
3
+
4
+ import type { MakefileFacet } from "../../../types/project.js"
5
+ import { fileExists } from "../../../utils/fs/file.js"
6
+ import { logger } from "../../../utils/logging/logger.js"
7
+
8
+ export interface MakefileParseOptions {
9
+ include?: string[]
10
+ exclude?: string[]
11
+ followIncludes?: boolean
12
+ }
13
+
14
+ export async function parseMakefile(
15
+ dir: string,
16
+ options: MakefileParseOptions = {},
17
+ ): Promise<MakefileFacet | null> {
18
+ const config = getConfig()
19
+ const filenames = ["Makefile", "makefile", "GNUmakefile"]
20
+ let foundFile: string | null = null
21
+ let allTargets: MakefileCommand[] = []
22
+
23
+ for (const filename of filenames) {
24
+ const makefilePath = join(dir, filename)
25
+
26
+ if (!(await fileExists(makefilePath))) {
27
+ continue
28
+ }
29
+
30
+ const followIncludes = options.followIncludes ?? true
31
+ const targets = await parseMakefileTargets(makefilePath, followIncludes)
32
+
33
+ // Apply exclude filter
34
+ let filteredTargets = targets
35
+
36
+ // Hide "default" target unless showDefault is true
37
+ if (config.discovery?.makefile?.showDefault === false) {
38
+ filteredTargets = filteredTargets.filter((t) => t.name !== "default")
39
+ }
40
+
41
+ if (options.exclude && options.exclude.length > 0) {
42
+ filteredTargets = filteredTargets.filter(
43
+ (t) => !options.exclude?.includes(t.name),
44
+ )
45
+ }
46
+
47
+ if (filteredTargets.length > 0) {
48
+ foundFile = filename
49
+ allTargets = filteredTargets
50
+ break // Only parse the first found Makefile
51
+ }
52
+ }
53
+
54
+ if (!foundFile || allTargets.length === 0) {
55
+ return null
56
+ }
57
+
58
+ // Remove duplicates (keep first occurrence)
59
+ const seenNames = new Set<string>()
60
+ const commands = allTargets.filter((target) => {
61
+ if (seenNames.has(target.name)) {
62
+ return false
63
+ }
64
+ seenNames.add(target.name)
65
+ return true
66
+ })
67
+
68
+ return {
69
+ type: "makefile",
70
+ filename: foundFile,
71
+ path: relative(process.cwd(), join(dir, foundFile)),
72
+ commands,
73
+ }
74
+ }
75
+
76
+ import { getConfig } from "../../../config/config.js"
77
+ import type { MakefileCommand } from "../../../types/project.js"
78
+
79
+ async function parseSingleMakefile(
80
+ makefilePath: string,
81
+ visitedFiles: Set<string> = new Set(),
82
+ ): Promise<{ targets: MakefileCommand[]; includes: string[] }> {
83
+ // Prevent infinite loops
84
+ if (visitedFiles.has(makefilePath)) {
85
+ return { targets: [], includes: [] }
86
+ }
87
+ visitedFiles.add(makefilePath)
88
+
89
+ if (!(await fileExists(makefilePath))) {
90
+ return { targets: [], includes: [] }
91
+ }
92
+
93
+ try {
94
+ const content = await readFile(makefilePath, "utf-8")
95
+ const targets: MakefileCommand[] = []
96
+ const includes: string[] = []
97
+ const lines = content.split("\n")
98
+ let currentTarget: string | null = null
99
+ let currentCommand = ""
100
+
101
+ for (const line of lines) {
102
+ // Skip comments and empty lines
103
+ if (line.trim().startsWith("#") || line.trim() === "") {
104
+ continue
105
+ }
106
+
107
+ // Collect include statements
108
+ if (line.trim().startsWith("include ")) {
109
+ const includeMatch = line.match(/^include\s+(.+)$/)
110
+ if (includeMatch) {
111
+ const includePath = includeMatch[1].trim()
112
+ const absolutePath = resolve(dirname(makefilePath), includePath)
113
+ includes.push(absolutePath)
114
+ }
115
+ continue
116
+ }
117
+
118
+ // Target line (starts at column 0, contains :)
119
+ if (line[0] !== "\t" && line.includes(":")) {
120
+ // Skip variable assignments (NAME := value or NAME = value)
121
+ if (line.includes(":=") || line.match(/^\s*[A-Z_]+\s*=/)) {
122
+ continue
123
+ }
124
+
125
+ // Save previous target
126
+ if (currentTarget) {
127
+ targets.push({
128
+ name: currentTarget,
129
+ command: `make ${currentTarget}`,
130
+ exec: currentCommand.trim(),
131
+ port: undefined,
132
+ description: undefined,
133
+ dependencies: undefined,
134
+ })
135
+ }
136
+
137
+ // Extract new target name (before the colon)
138
+ const match = line.match(/^([a-zA-Z0-9_-]+)\s*:/)
139
+ if (match) {
140
+ currentTarget = match[1]
141
+ currentCommand = ""
142
+ }
143
+ }
144
+ // Command line (starts with tab)
145
+ else if (line[0] === "\t" && currentTarget) {
146
+ currentCommand += (currentCommand ? " && " : "") + line.trim()
147
+ }
148
+ }
149
+
150
+ // Save last target
151
+ if (currentTarget) {
152
+ targets.push({
153
+ name: currentTarget,
154
+ command: `make ${currentTarget}`,
155
+ exec: currentCommand.trim(),
156
+ port: undefined,
157
+ description: undefined,
158
+ dependencies: undefined,
159
+ })
160
+ }
161
+
162
+ return { targets, includes }
163
+ } catch (error) {
164
+ logger.debug(error, `Failed to read or parse Makefile at ${makefilePath}:`)
165
+ return { targets: [], includes: [] }
166
+ }
167
+ }
168
+
169
+ async function parseMakefileTargets(
170
+ makefilePath: string,
171
+ followIncludes = true,
172
+ visitedFiles: Set<string> = new Set(),
173
+ ): Promise<MakefileCommand[]> {
174
+ const { targets, includes } = await parseSingleMakefile(
175
+ makefilePath,
176
+ visitedFiles,
177
+ )
178
+
179
+ if (!followIncludes) {
180
+ return targets
181
+ }
182
+
183
+ // First add main file commands, then process includes in order
184
+ const allTargets: MakefileCommand[] = [...targets]
185
+
186
+ for (const includePath of includes) {
187
+ const includedTargets = await parseMakefileTargets(
188
+ includePath,
189
+ true,
190
+ visitedFiles,
191
+ )
192
+ allTargets.push(...includedTargets)
193
+ }
194
+
195
+ return allTargets
196
+ }
@@ -0,0 +1,151 @@
1
+ import { existsSync } from "node:fs"
2
+ import { join, relative } from "node:path"
3
+ import type { PackageJson } from "type-fest"
4
+
5
+ import type {
6
+ PackageJsonFacet,
7
+ PackageJsonScript,
8
+ PackageManager,
9
+ } from "../../../types/project.js"
10
+ import { getPackageJson } from "../../../utils/fs/file.js"
11
+ import { detectFramework } from "../../../utils/workspace/framework-detector.js"
12
+
13
+ export interface ManifestParseOptions {
14
+ include?: string[]
15
+ exclude?: string[]
16
+ }
17
+
18
+ export async function parsePackageJson(
19
+ dir: string,
20
+ options: ManifestParseOptions = {},
21
+ ): Promise<PackageJsonFacet | null> {
22
+ const pkg = await getPackageJson(dir)
23
+
24
+ if (!pkg) return null
25
+
26
+ let scripts = pkg.scripts || {}
27
+
28
+ // Apply exclude filter
29
+ if (options.exclude && options.exclude.length > 0) {
30
+ scripts = Object.fromEntries(
31
+ Object.entries(scripts).filter(
32
+ ([key]) => !options.exclude?.includes(key),
33
+ ),
34
+ )
35
+ }
36
+
37
+ const framework = detectFramework(pkg)
38
+ const packageManager = await detectPackageManager(dir, pkg)
39
+ const scriptArray = parseScripts(scripts, packageManager)
40
+
41
+ return {
42
+ type: "packageJson",
43
+ filename: "package.json",
44
+ path: relative(process.cwd(), join(dir, "package.json")),
45
+ name: pkg.name ?? "",
46
+ version: pkg.version,
47
+ framework,
48
+ packageManager,
49
+ description: pkg.description,
50
+ scripts: scriptArray,
51
+ }
52
+ }
53
+
54
+ function parseScripts(
55
+ scripts: PackageJson.Scripts,
56
+ packageManager: PackageManager,
57
+ ): PackageJsonScript[] {
58
+ return Object.entries(scripts)
59
+ .filter((entry): entry is [string, string] => typeof entry[1] === "string")
60
+ .map(([name, exec]) => {
61
+ // Extract port from common patterns
62
+ const port = extractPort(exec)
63
+
64
+ // Build the command to run the script
65
+ const command = buildScriptCommand(packageManager, name)
66
+
67
+ return {
68
+ name,
69
+ command,
70
+ exec,
71
+ port,
72
+ }
73
+ })
74
+ }
75
+
76
+ function buildScriptCommand(
77
+ packageManager: PackageManager,
78
+ scriptName: string,
79
+ ): string {
80
+ switch (packageManager) {
81
+ case "npm":
82
+ return `npm run ${scriptName}`
83
+ case "yarn":
84
+ return `yarn ${scriptName}`
85
+ case "pnpm":
86
+ return `pnpm run ${scriptName}`
87
+ case "bun":
88
+ return `bun run ${scriptName}`
89
+ case "deno":
90
+ return `deno task ${scriptName}`
91
+ default:
92
+ return `npm run ${scriptName}`
93
+ }
94
+ }
95
+
96
+ function extractPort(exec: string): number {
97
+ // Match common port patterns
98
+ const patterns = [
99
+ /-p\s+(\d+)/, // -p 8000
100
+ /--port[=\s]+(\d+)/, // --port=8000 or --port 8000
101
+ /PORT=(\d+)/, // PORT=8000
102
+ /:(\d{4,5})\b/, // :8000
103
+ ]
104
+
105
+ for (const pattern of patterns) {
106
+ const match = exec.match(pattern)
107
+ if (match?.[1]) {
108
+ const port = parseInt(match[1], 10)
109
+ if (port > 0 && port <= 65535) {
110
+ return port
111
+ }
112
+ }
113
+ }
114
+
115
+ return 0
116
+ }
117
+
118
+ async function detectPackageManager(
119
+ dir: string,
120
+ pkg: PackageJson,
121
+ ): Promise<PackageManager> {
122
+ // 1. Check package.json packageManager field (most explicit)
123
+ if (pkg.packageManager) {
124
+ if (pkg.packageManager.startsWith("npm")) return "npm"
125
+ if (pkg.packageManager.startsWith("yarn")) return "yarn"
126
+ if (pkg.packageManager.startsWith("pnpm")) return "pnpm"
127
+ if (pkg.packageManager.startsWith("bun")) return "bun"
128
+ if (pkg.packageManager.startsWith("deno")) return "deno"
129
+ }
130
+
131
+ // 2. Check for lockfiles (most reliable heuristic)
132
+ if (existsSync(join(dir, "bun.lockb"))) return "bun"
133
+ if (existsSync(join(dir, "pnpm-lock.yaml"))) return "pnpm"
134
+ if (existsSync(join(dir, "yarn.lock"))) return "yarn"
135
+ if (existsSync(join(dir, "package-lock.json"))) return "npm"
136
+ if (existsSync(join(dir, "deno.lock"))) return "deno"
137
+
138
+ // 3. Check for workspace configuration files
139
+ if (existsSync(join(dir, "pnpm-workspace.yaml"))) return "pnpm"
140
+
141
+ // 4. Check package.json workspaces field format
142
+ if (pkg.workspaces) {
143
+ // Yarn berry uses a specific format
144
+ if (typeof pkg.workspaces === "object" && "packages" in pkg.workspaces) {
145
+ return "yarn"
146
+ }
147
+ }
148
+
149
+ // 5. Default fallback
150
+ return "npm"
151
+ }
@@ -0,0 +1 @@
1
+ export * from "./workspace-discovery.js"
@@ -0,0 +1,105 @@
1
+ import { basename } from "node:path"
2
+
3
+ import { getConfig } from "../../config/config.js"
4
+ import type { Project, ProjectType } from "../../types/project"
5
+ import { scanDirectories } from "../../utils/fs/directories.js"
6
+ import { logger } from "../../utils/logging/logger.js"
7
+ import { parseDockerCompose } from "./facets/compose-parser.js"
8
+ import { parseMakefile } from "./facets/makefile-parser.js"
9
+ import { parsePackageJson } from "./facets/package-json-parser.js"
10
+
11
+ export async function discoverWorkspaces(rootPath: string): Promise<Project[]> {
12
+ const config = getConfig()
13
+ const directories = await scanDirectories(rootPath, {
14
+ maxDepth: 4,
15
+ ignore: config.discovery?.ignore || [],
16
+ })
17
+ logger.debug(directories, "Scanned Directories")
18
+
19
+ const workspaces: Project[] = []
20
+ for (const dir of directories) {
21
+ const packageFacet = await parsePackageJson(dir)
22
+
23
+ const composeFacet = await parseDockerCompose(dir)
24
+
25
+ const makefileFacet = await parseMakefile(dir)
26
+
27
+ if (packageFacet || composeFacet || makefileFacet) {
28
+ const relPath = dir.startsWith(rootPath)
29
+ ? dir.slice(rootPath.length).replace(/^\/+/, "")
30
+ : dir
31
+ const type = await determineProjectType(relPath)
32
+ const workspace: Project = {
33
+ type,
34
+ folder: basename(dir),
35
+ path: relPath || ".",
36
+ absolutePath: dir,
37
+ facets: {
38
+ packageJson: packageFacet || undefined,
39
+ compose: composeFacet || undefined,
40
+ makefile: makefileFacet || undefined,
41
+ },
42
+ }
43
+ workspaces.push(workspace)
44
+ }
45
+ }
46
+
47
+ const orderedWorkspaces = orderWorkspaces(
48
+ workspaces,
49
+ config.discovery?.order || [],
50
+ )
51
+
52
+ return orderedWorkspaces
53
+ }
54
+
55
+ /**
56
+ * Determine the workspace type based on location and facets
57
+ */
58
+ async function determineProjectType(dir: string): Promise<ProjectType> {
59
+ const config = getConfig()
60
+
61
+ const appFolders = config.discovery?.folders?.app || ["apps"]
62
+ const packageFolders = config.discovery?.folders?.package || ["packages"]
63
+ const infraFolders = config.discovery?.folders?.infra || ["infra"]
64
+ const contractFolders = config.discovery?.folders?.contract || ["contracts"]
65
+
66
+ if (dir === "") {
67
+ return "workspace"
68
+ }
69
+ for (const folder of appFolders) {
70
+ if (dir.split("/").includes(folder)) {
71
+ return "app"
72
+ }
73
+ }
74
+ for (const folder of infraFolders) {
75
+ if (dir.split("/").includes(folder)) {
76
+ return "infra"
77
+ }
78
+ }
79
+ for (const folder of packageFolders) {
80
+ if (dir.split("/").includes(folder)) {
81
+ return "package"
82
+ }
83
+ }
84
+ for (const folder of contractFolders) {
85
+ if (dir.split("/").includes(folder)) {
86
+ return "contract"
87
+ }
88
+ }
89
+
90
+ // 5. Default to 'app'
91
+ return "app"
92
+ }
93
+
94
+ export function orderWorkspaces(
95
+ workspaces: Project[],
96
+ order: string[],
97
+ ): Project[] {
98
+ return workspaces
99
+ .filter((w) => order.includes(w.type))
100
+ .sort((a, b) => {
101
+ const aIndex = order.indexOf(a.type)
102
+ const bIndex = order.indexOf(b.type)
103
+ return aIndex - bIndex
104
+ })
105
+ }