@launch77/cli 1.2.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 (398) hide show
  1. package/.eslintrc.json +6 -0
  2. package/dist/app-templates/webapp/.env.ci +6 -0
  3. package/dist/app-templates/webapp/.env.example +9 -0
  4. package/dist/app-templates/webapp/.eslintrc.json +6 -0
  5. package/dist/app-templates/webapp/README.md.hbs +80 -0
  6. package/dist/app-templates/webapp/app/about/page.tsx.hbs +41 -0
  7. package/dist/app-templates/webapp/app/dashboard/page.tsx.hbs +51 -0
  8. package/dist/app-templates/webapp/app/globals.css +31 -0
  9. package/dist/app-templates/webapp/app/layout.tsx.hbs +26 -0
  10. package/dist/app-templates/webapp/app/page.tsx.hbs +30 -0
  11. package/dist/app-templates/webapp/next.config.js +99 -0
  12. package/dist/app-templates/webapp/package.json.hbs +30 -0
  13. package/dist/app-templates/webapp/postcss.config.js +6 -0
  14. package/dist/app-templates/webapp/tailwind.config.ts +24 -0
  15. package/dist/app-templates/webapp/tsconfig.json +29 -0
  16. package/dist/app-templates/webapp/vercel.json.hbs +7 -0
  17. package/dist/cli.d.ts +3 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +29 -0
  20. package/dist/cli.js.map +1 -0
  21. package/dist/infrastructure/filesystem.d.ts +41 -0
  22. package/dist/infrastructure/filesystem.d.ts.map +1 -0
  23. package/dist/infrastructure/filesystem.js +61 -0
  24. package/dist/infrastructure/filesystem.js.map +1 -0
  25. package/dist/infrastructure/npm.d.ts +9 -0
  26. package/dist/infrastructure/npm.d.ts.map +1 -0
  27. package/dist/infrastructure/npm.js +17 -0
  28. package/dist/infrastructure/npm.js.map +1 -0
  29. package/dist/infrastructure/template-engine.d.ts +12 -0
  30. package/dist/infrastructure/template-engine.d.ts.map +1 -0
  31. package/dist/infrastructure/template-engine.js +40 -0
  32. package/dist/infrastructure/template-engine.js.map +1 -0
  33. package/dist/infrastructure/template-generator.d.ts +9 -0
  34. package/dist/infrastructure/template-generator.d.ts.map +1 -0
  35. package/dist/infrastructure/template-generator.js +19 -0
  36. package/dist/infrastructure/template-generator.js.map +1 -0
  37. package/dist/infrastructure/template.d.ts +20 -0
  38. package/dist/infrastructure/template.d.ts.map +1 -0
  39. package/dist/infrastructure/template.js +53 -0
  40. package/dist/infrastructure/template.js.map +1 -0
  41. package/dist/modules/app/commands/create-app.d.ts +3 -0
  42. package/dist/modules/app/commands/create-app.d.ts.map +1 -0
  43. package/dist/modules/app/commands/create-app.js +51 -0
  44. package/dist/modules/app/commands/create-app.js.map +1 -0
  45. package/dist/modules/app/commands/delete-app.d.ts +3 -0
  46. package/dist/modules/app/commands/delete-app.d.ts.map +1 -0
  47. package/dist/modules/app/commands/delete-app.js +109 -0
  48. package/dist/modules/app/commands/delete-app.js.map +1 -0
  49. package/dist/modules/app/commands/generate-manifest.d.ts +3 -0
  50. package/dist/modules/app/commands/generate-manifest.d.ts.map +1 -0
  51. package/dist/modules/app/commands/generate-manifest.js +62 -0
  52. package/dist/modules/app/commands/generate-manifest.js.map +1 -0
  53. package/dist/modules/app/commands/validate-manifest.d.ts +3 -0
  54. package/dist/modules/app/commands/validate-manifest.d.ts.map +1 -0
  55. package/dist/modules/app/commands/validate-manifest.js +68 -0
  56. package/dist/modules/app/commands/validate-manifest.js.map +1 -0
  57. package/dist/modules/app/errors/app-errors.d.ts +19 -0
  58. package/dist/modules/app/errors/app-errors.d.ts.map +1 -0
  59. package/dist/modules/app/errors/app-errors.js +37 -0
  60. package/dist/modules/app/errors/app-errors.js.map +1 -0
  61. package/dist/modules/app/index.d.ts +10 -0
  62. package/dist/modules/app/index.d.ts.map +1 -0
  63. package/dist/modules/app/index.js +11 -0
  64. package/dist/modules/app/index.js.map +1 -0
  65. package/dist/modules/app/lib/manifest-schema.d.ts +39 -0
  66. package/dist/modules/app/lib/manifest-schema.d.ts.map +1 -0
  67. package/dist/modules/app/lib/manifest-schema.js +44 -0
  68. package/dist/modules/app/lib/manifest-schema.js.map +1 -0
  69. package/dist/modules/app/services/app-svc.d.ts +15 -0
  70. package/dist/modules/app/services/app-svc.d.ts.map +1 -0
  71. package/dist/modules/app/services/app-svc.js +90 -0
  72. package/dist/modules/app/services/app-svc.js.map +1 -0
  73. package/dist/modules/app/services/manifest-svc.d.ts +28 -0
  74. package/dist/modules/app/services/manifest-svc.d.ts.map +1 -0
  75. package/dist/modules/app/services/manifest-svc.js +119 -0
  76. package/dist/modules/app/services/manifest-svc.js.map +1 -0
  77. package/dist/modules/app/types/app-types.d.ts +21 -0
  78. package/dist/modules/app/types/app-types.d.ts.map +1 -0
  79. package/dist/modules/app/types/app-types.js +5 -0
  80. package/dist/modules/app/types/app-types.js.map +1 -0
  81. package/dist/modules/catalog/commands/generate.d.ts +9 -0
  82. package/dist/modules/catalog/commands/generate.d.ts.map +1 -0
  83. package/dist/modules/catalog/commands/generate.js +94 -0
  84. package/dist/modules/catalog/commands/generate.js.map +1 -0
  85. package/dist/modules/catalog/commands/scan.d.ts +9 -0
  86. package/dist/modules/catalog/commands/scan.d.ts.map +1 -0
  87. package/dist/modules/catalog/commands/scan.js +43 -0
  88. package/dist/modules/catalog/commands/scan.js.map +1 -0
  89. package/dist/modules/catalog/config/catalog-config.d.ts +49 -0
  90. package/dist/modules/catalog/config/catalog-config.d.ts.map +1 -0
  91. package/dist/modules/catalog/config/catalog-config.js +116 -0
  92. package/dist/modules/catalog/config/catalog-config.js.map +1 -0
  93. package/dist/modules/catalog/config/catalog-config.test.d.ts +2 -0
  94. package/dist/modules/catalog/config/catalog-config.test.d.ts.map +1 -0
  95. package/dist/modules/catalog/config/catalog-config.test.js +362 -0
  96. package/dist/modules/catalog/config/catalog-config.test.js.map +1 -0
  97. package/dist/modules/catalog/index.d.ts +9 -0
  98. package/dist/modules/catalog/index.d.ts.map +1 -0
  99. package/dist/modules/catalog/index.js +9 -0
  100. package/dist/modules/catalog/index.js.map +1 -0
  101. package/dist/modules/catalog/parsers/typescript-parser.d.ts +15 -0
  102. package/dist/modules/catalog/parsers/typescript-parser.d.ts.map +1 -0
  103. package/dist/modules/catalog/parsers/typescript-parser.js +82 -0
  104. package/dist/modules/catalog/parsers/typescript-parser.js.map +1 -0
  105. package/dist/modules/catalog/scanners/metadata-extractor.d.ts +10 -0
  106. package/dist/modules/catalog/scanners/metadata-extractor.d.ts.map +1 -0
  107. package/dist/modules/catalog/scanners/metadata-extractor.js +122 -0
  108. package/dist/modules/catalog/scanners/metadata-extractor.js.map +1 -0
  109. package/dist/modules/catalog/scanners/metadata-validator.d.ts +6 -0
  110. package/dist/modules/catalog/scanners/metadata-validator.d.ts.map +1 -0
  111. package/dist/modules/catalog/scanners/metadata-validator.js +57 -0
  112. package/dist/modules/catalog/scanners/metadata-validator.js.map +1 -0
  113. package/dist/modules/catalog/scanners/ui-component-scanner.d.ts +11 -0
  114. package/dist/modules/catalog/scanners/ui-component-scanner.d.ts.map +1 -0
  115. package/dist/modules/catalog/scanners/ui-component-scanner.js +147 -0
  116. package/dist/modules/catalog/scanners/ui-component-scanner.js.map +1 -0
  117. package/dist/modules/catalog/schemas/catalog-ui-components.schema.json +161 -0
  118. package/dist/modules/catalog/schemas/schemas/catalog-ui-components.schema.json +145 -0
  119. package/dist/modules/catalog/services/catalog-generator-svc.d.ts +27 -0
  120. package/dist/modules/catalog/services/catalog-generator-svc.d.ts.map +1 -0
  121. package/dist/modules/catalog/services/catalog-generator-svc.js +100 -0
  122. package/dist/modules/catalog/services/catalog-generator-svc.js.map +1 -0
  123. package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts +2 -0
  124. package/dist/modules/catalog/services/catalog-generator-svc.test.d.ts.map +1 -0
  125. package/dist/modules/catalog/services/catalog-generator-svc.test.js +201 -0
  126. package/dist/modules/catalog/services/catalog-generator-svc.test.js.map +1 -0
  127. package/dist/modules/catalog/services/catalog-svc.d.ts +39 -0
  128. package/dist/modules/catalog/services/catalog-svc.d.ts.map +1 -0
  129. package/dist/modules/catalog/services/catalog-svc.js +163 -0
  130. package/dist/modules/catalog/services/catalog-svc.js.map +1 -0
  131. package/dist/modules/catalog/types/catalog-types.d.ts +120 -0
  132. package/dist/modules/catalog/types/catalog-types.d.ts.map +1 -0
  133. package/dist/modules/catalog/types/catalog-types.js +5 -0
  134. package/dist/modules/catalog/types/catalog-types.js.map +1 -0
  135. package/dist/modules/catalog/utils/examples-generator.d.ts +6 -0
  136. package/dist/modules/catalog/utils/examples-generator.d.ts.map +1 -0
  137. package/dist/modules/catalog/utils/examples-generator.js +55 -0
  138. package/dist/modules/catalog/utils/examples-generator.js.map +1 -0
  139. package/dist/modules/catalog/utils/quality-reporter.d.ts +13 -0
  140. package/dist/modules/catalog/utils/quality-reporter.d.ts.map +1 -0
  141. package/dist/modules/catalog/utils/quality-reporter.js +64 -0
  142. package/dist/modules/catalog/utils/quality-reporter.js.map +1 -0
  143. package/dist/modules/catalog/validators/component-name-validator.d.ts +20 -0
  144. package/dist/modules/catalog/validators/component-name-validator.d.ts.map +1 -0
  145. package/dist/modules/catalog/validators/component-name-validator.js +33 -0
  146. package/dist/modules/catalog/validators/component-name-validator.js.map +1 -0
  147. package/dist/modules/catalog/validators/component-name-validator.test.d.ts +2 -0
  148. package/dist/modules/catalog/validators/component-name-validator.test.d.ts.map +1 -0
  149. package/dist/modules/catalog/validators/component-name-validator.test.js +196 -0
  150. package/dist/modules/catalog/validators/component-name-validator.test.js.map +1 -0
  151. package/dist/modules/deploy/commands/deploy-init-action.d.ts +12 -0
  152. package/dist/modules/deploy/commands/deploy-init-action.d.ts.map +1 -0
  153. package/dist/modules/deploy/commands/deploy-init-action.js +220 -0
  154. package/dist/modules/deploy/commands/deploy-init-action.js.map +1 -0
  155. package/dist/modules/deploy/commands/deploy-init.d.ts +6 -0
  156. package/dist/modules/deploy/commands/deploy-init.d.ts.map +1 -0
  157. package/dist/modules/deploy/commands/deploy-init.js +16 -0
  158. package/dist/modules/deploy/commands/deploy-init.js.map +1 -0
  159. package/dist/modules/deploy/commands/deploy-logs-action.d.ts +12 -0
  160. package/dist/modules/deploy/commands/deploy-logs-action.d.ts.map +1 -0
  161. package/dist/modules/deploy/commands/deploy-logs-action.js +113 -0
  162. package/dist/modules/deploy/commands/deploy-logs-action.js.map +1 -0
  163. package/dist/modules/deploy/commands/deploy-logs.d.ts +6 -0
  164. package/dist/modules/deploy/commands/deploy-logs.d.ts.map +1 -0
  165. package/dist/modules/deploy/commands/deploy-logs.js +17 -0
  166. package/dist/modules/deploy/commands/deploy-logs.js.map +1 -0
  167. package/dist/modules/deploy/commands/deploy-status-action.d.ts +8 -0
  168. package/dist/modules/deploy/commands/deploy-status-action.d.ts.map +1 -0
  169. package/dist/modules/deploy/commands/deploy-status-action.js +153 -0
  170. package/dist/modules/deploy/commands/deploy-status-action.js.map +1 -0
  171. package/dist/modules/deploy/commands/deploy-status.d.ts +6 -0
  172. package/dist/modules/deploy/commands/deploy-status.d.ts.map +1 -0
  173. package/dist/modules/deploy/commands/deploy-status.js +13 -0
  174. package/dist/modules/deploy/commands/deploy-status.js.map +1 -0
  175. package/dist/modules/deploy/index.d.ts +7 -0
  176. package/dist/modules/deploy/index.d.ts.map +1 -0
  177. package/dist/modules/deploy/index.js +7 -0
  178. package/dist/modules/deploy/index.js.map +1 -0
  179. package/dist/modules/deploy/services/deploy-svc.d.ts +17 -0
  180. package/dist/modules/deploy/services/deploy-svc.d.ts.map +1 -0
  181. package/dist/modules/deploy/services/deploy-svc.js +25 -0
  182. package/dist/modules/deploy/services/deploy-svc.js.map +1 -0
  183. package/dist/modules/deploy/utils/vercel-extended.d.ts +63 -0
  184. package/dist/modules/deploy/utils/vercel-extended.d.ts.map +1 -0
  185. package/dist/modules/deploy/utils/vercel-extended.js +238 -0
  186. package/dist/modules/deploy/utils/vercel-extended.js.map +1 -0
  187. package/dist/modules/plugin/commands/plugin-install.d.ts +3 -0
  188. package/dist/modules/plugin/commands/plugin-install.d.ts.map +1 -0
  189. package/dist/modules/plugin/commands/plugin-install.js +45 -0
  190. package/dist/modules/plugin/commands/plugin-install.js.map +1 -0
  191. package/dist/modules/plugin/errors/plugin-errors.d.ts +16 -0
  192. package/dist/modules/plugin/errors/plugin-errors.d.ts.map +1 -0
  193. package/dist/modules/plugin/errors/plugin-errors.js +39 -0
  194. package/dist/modules/plugin/errors/plugin-errors.js.map +1 -0
  195. package/dist/modules/plugin/index.d.ts +6 -0
  196. package/dist/modules/plugin/index.d.ts.map +1 -0
  197. package/dist/modules/plugin/index.js +9 -0
  198. package/dist/modules/plugin/index.js.map +1 -0
  199. package/dist/modules/plugin/lib/plugin-registry.d.ts +15 -0
  200. package/dist/modules/plugin/lib/plugin-registry.d.ts.map +1 -0
  201. package/dist/modules/plugin/lib/plugin-registry.js +47 -0
  202. package/dist/modules/plugin/lib/plugin-registry.js.map +1 -0
  203. package/dist/modules/plugin/services/plugin-svc.d.ts +10 -0
  204. package/dist/modules/plugin/services/plugin-svc.d.ts.map +1 -0
  205. package/dist/modules/plugin/services/plugin-svc.js +44 -0
  206. package/dist/modules/plugin/services/plugin-svc.js.map +1 -0
  207. package/dist/modules/plugin/types/plugin-types.d.ts +19 -0
  208. package/dist/modules/plugin/types/plugin-types.d.ts.map +1 -0
  209. package/dist/modules/plugin/types/plugin-types.js +2 -0
  210. package/dist/modules/plugin/types/plugin-types.js.map +1 -0
  211. package/dist/modules/startup/commands/create-startup.d.ts +3 -0
  212. package/dist/modules/startup/commands/create-startup.d.ts.map +1 -0
  213. package/dist/modules/startup/commands/create-startup.js +43 -0
  214. package/dist/modules/startup/commands/create-startup.js.map +1 -0
  215. package/dist/modules/startup/errors/startup-errors.d.ts +13 -0
  216. package/dist/modules/startup/errors/startup-errors.d.ts.map +1 -0
  217. package/dist/modules/startup/errors/startup-errors.js +25 -0
  218. package/dist/modules/startup/errors/startup-errors.js.map +1 -0
  219. package/dist/modules/startup/index.d.ts +5 -0
  220. package/dist/modules/startup/index.d.ts.map +1 -0
  221. package/dist/modules/startup/index.js +7 -0
  222. package/dist/modules/startup/index.js.map +1 -0
  223. package/dist/modules/startup/services/startup-service.d.ts +7 -0
  224. package/dist/modules/startup/services/startup-service.d.ts.map +1 -0
  225. package/dist/modules/startup/services/startup-service.js +43 -0
  226. package/dist/modules/startup/services/startup-service.js.map +1 -0
  227. package/dist/modules/startup/types/startup-types.d.ts +8 -0
  228. package/dist/modules/startup/types/startup-types.d.ts.map +1 -0
  229. package/dist/modules/startup/types/startup-types.js +2 -0
  230. package/dist/modules/startup/types/startup-types.js.map +1 -0
  231. package/dist/modules/startup/utils/startup-validators.d.ts +8 -0
  232. package/dist/modules/startup/utils/startup-validators.d.ts.map +1 -0
  233. package/dist/modules/startup/utils/startup-validators.js +17 -0
  234. package/dist/modules/startup/utils/startup-validators.js.map +1 -0
  235. package/dist/modules/workspace/commands/init-workspace.d.ts +3 -0
  236. package/dist/modules/workspace/commands/init-workspace.d.ts.map +1 -0
  237. package/dist/modules/workspace/commands/init-workspace.js +54 -0
  238. package/dist/modules/workspace/commands/init-workspace.js.map +1 -0
  239. package/dist/modules/workspace/errors/workspace-errors.d.ts +10 -0
  240. package/dist/modules/workspace/errors/workspace-errors.d.ts.map +1 -0
  241. package/dist/modules/workspace/errors/workspace-errors.js +19 -0
  242. package/dist/modules/workspace/errors/workspace-errors.js.map +1 -0
  243. package/dist/modules/workspace/index.d.ts +5 -0
  244. package/dist/modules/workspace/index.d.ts.map +1 -0
  245. package/dist/modules/workspace/index.js +7 -0
  246. package/dist/modules/workspace/index.js.map +1 -0
  247. package/dist/modules/workspace/services/workspace-service.d.ts +6 -0
  248. package/dist/modules/workspace/services/workspace-service.d.ts.map +1 -0
  249. package/dist/modules/workspace/services/workspace-service.js +46 -0
  250. package/dist/modules/workspace/services/workspace-service.js.map +1 -0
  251. package/dist/modules/workspace/types/workspace-types.d.ts +8 -0
  252. package/dist/modules/workspace/types/workspace-types.d.ts.map +1 -0
  253. package/dist/modules/workspace/types/workspace-types.js +2 -0
  254. package/dist/modules/workspace/types/workspace-types.js.map +1 -0
  255. package/dist/modules/workspace/utils/workspace-validators.d.ts +8 -0
  256. package/dist/modules/workspace/utils/workspace-validators.d.ts.map +1 -0
  257. package/dist/modules/workspace/utils/workspace-validators.js +17 -0
  258. package/dist/modules/workspace/utils/workspace-validators.js.map +1 -0
  259. package/dist/plugins/theme/package.json +32 -0
  260. package/dist/plugins/theme/plugin.json +9 -0
  261. package/dist/plugins/theme/src/generator.ts +92 -0
  262. package/dist/plugins/theme/src/utils/config-modifier.ts +142 -0
  263. package/dist/plugins/theme/src/utils/css-modifier.ts +89 -0
  264. package/dist/plugins/theme/templates/app/theme-test/page.tsx +156 -0
  265. package/dist/plugins/theme/templates/src/modules/theme/README.md +209 -0
  266. package/dist/plugins/theme/templates/src/modules/theme/config/brand.css +23 -0
  267. package/dist/plugins/theme/tsconfig.json +14 -0
  268. package/dist/plugins/theme/tsup.config.ts +10 -0
  269. package/dist/templates/startup/apps/.gitkeep +8 -0
  270. package/dist/templates/templates/startup/apps/.gitkeep +8 -0
  271. package/dist/templates/templates/workspace/.eslintignore +7 -0
  272. package/dist/templates/templates/workspace/.eslintrc.js +38 -0
  273. package/dist/templates/templates/workspace/.husky/pre-push +24 -0
  274. package/dist/templates/templates/workspace/.launch77/workspace.json +3 -0
  275. package/dist/templates/templates/workspace/.lintstagedrc.json +4 -0
  276. package/dist/templates/templates/workspace/.prettierrc +9 -0
  277. package/dist/templates/templates/workspace/README.md +62 -0
  278. package/dist/templates/templates/workspace/app-templates/.gitkeep +1 -0
  279. package/dist/templates/templates/workspace/apps/.gitkeep +1 -0
  280. package/dist/templates/templates/workspace/libraries/.gitkeep +1 -0
  281. package/dist/templates/templates/workspace/package.json +31 -0
  282. package/dist/templates/templates/workspace/plugins/.gitkeep +1 -0
  283. package/dist/templates/templates/workspace/tsconfig.json +22 -0
  284. package/dist/templates/templates/workspace/turbo.json +25 -0
  285. package/dist/templates/workspace/.launch77/workspace.json +3 -0
  286. package/dist/templates/workspace/README.md +62 -0
  287. package/dist/templates/workspace/app-templates/.gitkeep +1 -0
  288. package/dist/templates/workspace/apps/.gitkeep +1 -0
  289. package/dist/templates/workspace/libraries/.gitkeep +1 -0
  290. package/dist/templates/workspace/package.json +21 -0
  291. package/dist/templates/workspace/plugins/.gitkeep +1 -0
  292. package/dist/templates/workspace/tsconfig.json +22 -0
  293. package/dist/templates/workspace/turbo.json +25 -0
  294. package/dist/utils/launch77-context.d.ts +16 -0
  295. package/dist/utils/launch77-context.d.ts.map +1 -0
  296. package/dist/utils/launch77-context.js +111 -0
  297. package/dist/utils/launch77-context.js.map +1 -0
  298. package/dist/utils/launch77-validation.d.ts +17 -0
  299. package/dist/utils/launch77-validation.d.ts.map +1 -0
  300. package/dist/utils/launch77-validation.js +44 -0
  301. package/dist/utils/launch77-validation.js.map +1 -0
  302. package/dist/utils/monorepo.d.ts +19 -0
  303. package/dist/utils/monorepo.d.ts.map +1 -0
  304. package/dist/utils/monorepo.js +100 -0
  305. package/dist/utils/monorepo.js.map +1 -0
  306. package/dist/utils/validation.d.ts +32 -0
  307. package/dist/utils/validation.d.ts.map +1 -0
  308. package/dist/utils/validation.js +92 -0
  309. package/dist/utils/validation.js.map +1 -0
  310. package/dist/utils/version.d.ts +7 -0
  311. package/dist/utils/version.d.ts.map +1 -0
  312. package/dist/utils/version.js +16 -0
  313. package/dist/utils/version.js.map +1 -0
  314. package/launch77-cli-1.2.0.tgz +0 -0
  315. package/package.json +48 -0
  316. package/src/cli.ts +34 -0
  317. package/src/infrastructure/filesystem.ts +69 -0
  318. package/src/infrastructure/npm.ts +18 -0
  319. package/src/infrastructure/template-engine.ts +48 -0
  320. package/src/infrastructure/template-generator.ts +26 -0
  321. package/src/infrastructure/template.ts +66 -0
  322. package/src/modules/app/commands/create-app.ts +60 -0
  323. package/src/modules/app/commands/delete-app.ts +123 -0
  324. package/src/modules/app/commands/generate-manifest.ts +75 -0
  325. package/src/modules/app/commands/validate-manifest.ts +78 -0
  326. package/src/modules/app/errors/app-errors.ts +41 -0
  327. package/src/modules/app/index.ts +16 -0
  328. package/src/modules/app/lib/manifest-schema.ts +65 -0
  329. package/src/modules/app/services/app-svc.ts +115 -0
  330. package/src/modules/app/services/manifest-svc.ts +144 -0
  331. package/src/modules/app/types/app-types.ts +27 -0
  332. package/src/modules/catalog/commands/generate.ts +115 -0
  333. package/src/modules/catalog/commands/scan.ts +48 -0
  334. package/src/modules/catalog/config/catalog-config.test.ts +404 -0
  335. package/src/modules/catalog/config/catalog-config.ts +130 -0
  336. package/src/modules/catalog/index.ts +9 -0
  337. package/src/modules/catalog/parsers/typescript-parser.ts +93 -0
  338. package/src/modules/catalog/scanners/metadata-extractor.ts +134 -0
  339. package/src/modules/catalog/scanners/metadata-validator.ts +67 -0
  340. package/src/modules/catalog/scanners/ui-component-scanner.ts +185 -0
  341. package/src/modules/catalog/schemas/catalog-ui-components.schema.json +145 -0
  342. package/src/modules/catalog/services/catalog-generator-svc.test.ts +233 -0
  343. package/src/modules/catalog/services/catalog-generator-svc.ts +124 -0
  344. package/src/modules/catalog/services/catalog-svc.ts +222 -0
  345. package/src/modules/catalog/types/catalog-types.ts +149 -0
  346. package/src/modules/catalog/utils/examples-generator.ts +68 -0
  347. package/src/modules/catalog/utils/quality-reporter.ts +76 -0
  348. package/src/modules/catalog/validators/component-name-validator.test.ts +233 -0
  349. package/src/modules/catalog/validators/component-name-validator.ts +43 -0
  350. package/src/modules/deploy/commands/deploy-init-action.ts +247 -0
  351. package/src/modules/deploy/commands/deploy-init.ts +19 -0
  352. package/src/modules/deploy/commands/deploy-logs-action.ts +135 -0
  353. package/src/modules/deploy/commands/deploy-logs.ts +20 -0
  354. package/src/modules/deploy/commands/deploy-status-action.ts +175 -0
  355. package/src/modules/deploy/commands/deploy-status.ts +16 -0
  356. package/src/modules/deploy/index.ts +7 -0
  357. package/src/modules/deploy/services/deploy-svc.ts +31 -0
  358. package/src/modules/deploy/utils/vercel-extended.ts +286 -0
  359. package/src/modules/plugin/commands/plugin-install.ts +51 -0
  360. package/src/modules/plugin/errors/plugin-errors.ts +44 -0
  361. package/src/modules/plugin/index.ts +14 -0
  362. package/src/modules/plugin/lib/launch77-workspace.code-workspace +14 -0
  363. package/src/modules/plugin/lib/plugin-registry.ts +59 -0
  364. package/src/modules/plugin/services/plugin-svc.ts +53 -0
  365. package/src/modules/plugin/types/plugin-types.ts +21 -0
  366. package/src/modules/startup/commands/create-startup.ts +53 -0
  367. package/src/modules/startup/errors/startup-errors.ts +23 -0
  368. package/src/modules/startup/index.ts +11 -0
  369. package/src/modules/startup/services/startup-service.ts +57 -0
  370. package/src/modules/startup/types/startup-types.ts +8 -0
  371. package/src/modules/startup/utils/startup-validators.ts +19 -0
  372. package/src/modules/workspace/commands/init-workspace.ts +63 -0
  373. package/src/modules/workspace/errors/workspace-errors.ts +16 -0
  374. package/src/modules/workspace/index.ts +11 -0
  375. package/src/modules/workspace/services/workspace-service.ts +59 -0
  376. package/src/modules/workspace/types/workspace-types.ts +8 -0
  377. package/src/modules/workspace/utils/workspace-validators.ts +19 -0
  378. package/src/utils/launch77-context.ts +152 -0
  379. package/src/utils/launch77-validation.ts +59 -0
  380. package/src/utils/monorepo.ts +137 -0
  381. package/src/utils/validation.ts +117 -0
  382. package/src/utils/version.ts +16 -0
  383. package/templates/startup/apps/.gitkeep +8 -0
  384. package/templates/workspace/.eslintignore +7 -0
  385. package/templates/workspace/.eslintrc.js +38 -0
  386. package/templates/workspace/.husky/pre-push +24 -0
  387. package/templates/workspace/.launch77/workspace.json +3 -0
  388. package/templates/workspace/.lintstagedrc.json +4 -0
  389. package/templates/workspace/.prettierrc +9 -0
  390. package/templates/workspace/README.md +62 -0
  391. package/templates/workspace/app-templates/.gitkeep +1 -0
  392. package/templates/workspace/apps/.gitkeep +1 -0
  393. package/templates/workspace/libraries/.gitkeep +1 -0
  394. package/templates/workspace/package.json +31 -0
  395. package/templates/workspace/plugins/.gitkeep +1 -0
  396. package/templates/workspace/tsconfig.json +22 -0
  397. package/templates/workspace/turbo.json +25 -0
  398. package/tsconfig.json +23 -0
@@ -0,0 +1,78 @@
1
+ /* eslint-disable no-console */
2
+ import * as path from 'path'
3
+
4
+ import chalk from 'chalk'
5
+ import { Command } from 'commander'
6
+
7
+ import { ManifestService } from '../services/manifest-svc.js'
8
+
9
+ export function validateManifestCommand(): Command {
10
+ const command = new Command('app:validate-manifest')
11
+ .description('Validate a Launch77 manifest file')
12
+ .option('--path <folder>', 'Path to search for manifest (defaults to current directory)')
13
+ .action(async (options) => {
14
+ try {
15
+ const searchPath = options.path ? path.resolve(options.path) : process.cwd()
16
+
17
+ console.log(chalk.blue('šŸ” Searching for Launch77 manifest (.launch/app.json)...\n'))
18
+
19
+ const manifestService = new ManifestService()
20
+ const { manifest, manifestPath, appRoot } = await manifestService.loadManifest(searchPath)
21
+
22
+ console.log(chalk.green('āœ… Valid manifest found!\n'))
23
+ console.log(chalk.gray('Path:'), manifestPath)
24
+ console.log(chalk.gray('App root:'), appRoot)
25
+ console.log()
26
+ console.log(chalk.cyan('Manifest details:'))
27
+ console.log(chalk.gray(' Schema version:'), manifest.schemaVersion)
28
+ console.log(chalk.gray(' App type:'), manifest.type)
29
+ console.log(chalk.gray(' Package:'), manifest.package)
30
+
31
+ if ('name' in manifest && manifest.name) {
32
+ console.log(chalk.gray(' Name:'), manifest.name)
33
+ }
34
+
35
+ // Check if deployment field exists
36
+ if (manifest.deployment) {
37
+ console.log(chalk.gray(' Deployment platform:'), manifest.deployment.platform)
38
+ if (manifest.deployment.connected) {
39
+ console.log(chalk.gray(' Connected:'), 'Yes')
40
+ if (manifest.deployment.projectName) {
41
+ console.log(chalk.gray(' Project:'), manifest.deployment.projectName)
42
+ }
43
+ }
44
+ }
45
+
46
+ console.log()
47
+ console.log(chalk.green('✨ Manifest validation successful!'))
48
+
49
+ // Exit with success code
50
+ process.exit(0)
51
+ } catch (error) {
52
+ console.error(chalk.red('āŒ Manifest validation failed:\n'))
53
+
54
+ if (error instanceof Error) {
55
+ // If it's our formatted error with validation issues, print it as-is
56
+ if (error.message.includes('Manifest validation failed:')) {
57
+ console.error(error.message)
58
+ } else {
59
+ console.error(chalk.red(error.message))
60
+ }
61
+ } else {
62
+ console.error(chalk.red('Unknown error occurred'))
63
+ }
64
+
65
+ console.log()
66
+ console.log(chalk.gray('To create a new manifest, use:'))
67
+ console.log(chalk.cyan(' launch77 create-app <type> <name>'))
68
+ console.log()
69
+ console.log(chalk.gray('Or create one manually at .launch/app.json following the schema at:'))
70
+ console.log(chalk.cyan(' launch77/cli/schemas/app.launch77.schema.json'))
71
+
72
+ // Exit with error code
73
+ process.exit(1)
74
+ }
75
+ })
76
+
77
+ return command
78
+ }
@@ -0,0 +1,41 @@
1
+ export class AppAlreadyExistsError extends Error {
2
+ constructor(appName: string, appPath: string) {
3
+ super(`App ${appName} already exists at ${appPath}`)
4
+ this.name = 'AppAlreadyExistsError'
5
+ }
6
+ }
7
+
8
+ export class AppNotFoundError extends Error {
9
+ constructor(appName: string, expectedPath: string) {
10
+ super(`App '${appName}' does not exist at ${expectedPath}`)
11
+ this.name = 'AppNotFoundError'
12
+ }
13
+ }
14
+
15
+ export class InvalidAppNameError extends Error {
16
+ constructor(appName: string, reason: string) {
17
+ super(`Invalid app name '${appName}': ${reason}`)
18
+ this.name = 'InvalidAppNameError'
19
+ }
20
+ }
21
+
22
+ export class TemplateNotFoundError extends Error {
23
+ constructor(templateType: string) {
24
+ super(`Template not found for type: ${templateType}`)
25
+ this.name = 'TemplateNotFoundError'
26
+ }
27
+ }
28
+
29
+ export class ManifestNotFoundError extends Error {
30
+ constructor(searchDir: string) {
31
+ super(`No Launch77 manifest found in ${searchDir} or any parent directory`)
32
+ this.name = 'ManifestNotFoundError'
33
+ }
34
+ }
35
+
36
+ export class InvalidManifestError extends Error {
37
+ constructor(message: string) {
38
+ super(`Invalid manifest: ${message}`)
39
+ this.name = 'InvalidManifestError'
40
+ }
41
+ }
@@ -0,0 +1,16 @@
1
+ // Services
2
+ export { AppService } from './services/app-svc.js'
3
+ export { ManifestService } from './services/manifest-svc.js'
4
+
5
+ // Types
6
+ export type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult, AppType } from './types/app-types.js'
7
+ export type { AppManifest, DeploymentConfig } from './lib/manifest-schema.js'
8
+
9
+ // Errors
10
+ export { AppAlreadyExistsError, AppNotFoundError, InvalidAppNameError, TemplateNotFoundError, ManifestNotFoundError, InvalidManifestError } from './errors/app-errors.js'
11
+
12
+ // Commands
13
+ export { createAppCommand } from './commands/create-app.js'
14
+ export { deleteAppCommand } from './commands/delete-app.js'
15
+ export { generateManifestCommand } from './commands/generate-manifest.js'
16
+ export { validateManifestCommand } from './commands/validate-manifest.js'
@@ -0,0 +1,65 @@
1
+ import { z } from 'zod'
2
+
3
+ import type { AppType } from '../types/app-types.js'
4
+
5
+ // Deployment configuration
6
+ export type DeploymentConfig = {
7
+ platform: 'vercel'
8
+ connected: boolean
9
+ connectedAt?: string
10
+ projectName?: string
11
+ }
12
+
13
+ // App manifest
14
+ export type AppManifest = {
15
+ schemaVersion: 1
16
+ name: string
17
+ type: AppType | 'marketing' // Support both 'marketing' and 'marketing-site'
18
+ package: string
19
+ deployment?: DeploymentConfig
20
+ }
21
+
22
+ // Zod schemas
23
+ const deploymentConfigZ = z.object({
24
+ platform: z.literal('vercel'),
25
+ connected: z.boolean(),
26
+ connectedAt: z.string().optional(),
27
+ projectName: z.string().optional(),
28
+ })
29
+
30
+ // Main manifest schema - strict mode to reject extra fields
31
+ // Note: Manifests store 'marketing' but we accept 'marketing-site' in commands
32
+ export const manifestZ = z
33
+ .object({
34
+ schemaVersion: z.literal(1),
35
+ name: z.string().min(1),
36
+ type: z.enum(['marketing', 'webapp', 'api']),
37
+ package: z.string().min(1),
38
+ deployment: deploymentConfigZ.optional(),
39
+ })
40
+ .strict()
41
+
42
+ /**
43
+ * Parse and validate a manifest from unknown JSON data
44
+ * @param json - Unknown JSON data to parse
45
+ * @returns Validated AppManifest
46
+ * @throws ZodError with aggregated error messages
47
+ */
48
+ export function parseManifest(json: unknown): AppManifest {
49
+ try {
50
+ return manifestZ.parse(json) as AppManifest
51
+ } catch (error) {
52
+ if (error instanceof z.ZodError) {
53
+ // Format error messages nicely
54
+ const errorMessages = error.issues
55
+ .map((err: z.ZodIssue) => {
56
+ const path = err.path.join('.')
57
+ return ` - ${path ? `${path}: ` : ''}${err.message}`
58
+ })
59
+ .join('\n')
60
+
61
+ throw new Error(`Manifest validation failed:\n${errorMessages}`)
62
+ }
63
+ throw error
64
+ }
65
+ }
@@ -0,0 +1,115 @@
1
+ import * as path from 'path'
2
+
3
+ import fs from 'fs-extra'
4
+
5
+ import { ManifestService } from './manifest-svc.js'
6
+ import * as filesystem from '../../../infrastructure/filesystem.js'
7
+ import * as npm from '../../../infrastructure/npm.js'
8
+ import { generateFromTemplate } from '../../../infrastructure/template-generator.js'
9
+ import { templateExists } from '../../../infrastructure/template.js'
10
+ import { validateWorkspaceContext } from '../../../utils/launch77-validation.js'
11
+ import { validateAppName } from '../../../utils/validation.js'
12
+
13
+ import type { Launch77Context } from '../../../utils/launch77-context.js'
14
+ import type { CreateAppRequest, CreateAppResult, DeleteAppRequest, DeleteAppResult } from '../types/app-types.js'
15
+
16
+ export class AppService {
17
+ private manifestService: ManifestService
18
+
19
+ constructor() {
20
+ this.manifestService = new ManifestService()
21
+ }
22
+
23
+ /**
24
+ * Create a new app from template
25
+ */
26
+ async createApp(request: CreateAppRequest, context: Launch77Context): Promise<CreateAppResult> {
27
+ const { type, appName, port } = request
28
+
29
+ // 1. Validate app name
30
+ const nameValidation = validateAppName(appName)
31
+ if (!nameValidation.valid) {
32
+ throw new Error(nameValidation.errorMessage)
33
+ }
34
+
35
+ // 2. Validate workspace context
36
+ const contextValidation = validateWorkspaceContext(context)
37
+ if (!contextValidation.valid) {
38
+ throw new Error(contextValidation.errorMessage)
39
+ }
40
+
41
+ // 3. Determine app path
42
+ const appPath = path.join(context.appsDir, appName)
43
+
44
+ // 4. Check if app already exists
45
+ if (await fs.pathExists(appPath)) {
46
+ throw new Error(`App ${appName} already exists at ${appPath}`)
47
+ }
48
+
49
+ // 5. Validate template exists
50
+ if (!(await templateExists(type))) {
51
+ throw new Error(`Unknown app type: ${type}. Currently supported: api, webapp, marketing-site`)
52
+ }
53
+
54
+ // 6. Generate from template (context already has packageName computed)
55
+ await generateFromTemplate(type, appPath, appName, context, { port })
56
+
57
+ // 7. Generate and write app manifest
58
+ const manifest = this.manifestService.generateManifest(type, appName, context, { port })
59
+ const launchDir = path.join(appPath, '.launch')
60
+ await filesystem.ensureDir(launchDir)
61
+ const manifestPath = path.join(launchDir, 'app.json')
62
+ await filesystem.writeJSON(manifestPath, manifest)
63
+
64
+ // 8. Install dependencies
65
+ await npm.install(context.workspaceRoot)
66
+
67
+ return {
68
+ appPath,
69
+ appName,
70
+ type,
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Delete an existing app
76
+ */
77
+ async deleteApp(request: DeleteAppRequest, context: Launch77Context): Promise<DeleteAppResult> {
78
+ const { appName } = request
79
+
80
+ // 1. Validate app name
81
+ const nameValidation = validateAppName(appName)
82
+ if (!nameValidation.valid) {
83
+ throw new Error(nameValidation.errorMessage)
84
+ }
85
+
86
+ // 2. Validate workspace context
87
+ const contextValidation = validateWorkspaceContext(context)
88
+ if (!contextValidation.valid) {
89
+ throw new Error(contextValidation.errorMessage)
90
+ }
91
+
92
+ // 3. Determine app path
93
+ const appPath = path.join(context.appsDir, appName)
94
+
95
+ // 4. Check if app exists
96
+ if (!(await fs.pathExists(appPath))) {
97
+ throw new Error(`App '${appName}' does not exist.\n\n` + `Expected location: ${appPath}\n\n` + `Available apps:\n` + ` cd apps/\n` + ` ls`)
98
+ }
99
+
100
+ // 5. Check for Docker resources
101
+ const dockerComposePath = path.join(appPath, 'docker-compose.db.yml')
102
+ const hasDockerResources = await fs.pathExists(dockerComposePath)
103
+
104
+ // 6. Delete the app directory
105
+ await fs.remove(appPath)
106
+
107
+ // 7. Update dependencies
108
+ await npm.install(context.workspaceRoot)
109
+
110
+ return {
111
+ appName,
112
+ hadDockerResources: hasDockerResources,
113
+ }
114
+ }
115
+ }
@@ -0,0 +1,144 @@
1
+ import * as fs from 'fs/promises'
2
+ import * as path from 'path'
3
+
4
+ import { parseManifest } from '../lib/manifest-schema.js'
5
+
6
+ import type { Launch77Context } from '../../../utils/launch77-context.js'
7
+ import type { AppManifest } from '../lib/manifest-schema.js'
8
+
9
+ /**
10
+ * Convert kebab-case to Title Case
11
+ * e.g., "my-startup-name" -> "My Startup Name"
12
+ */
13
+ function toTitleCase(str: string): string {
14
+ return str
15
+ .split('-')
16
+ .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
17
+ .join(' ')
18
+ }
19
+
20
+ /**
21
+ * Generate a manifest for a marketing app
22
+ */
23
+ function generateMarketingManifest(appName: string, context: Launch77Context): AppManifest {
24
+ const workspaceName = context.workspaceName
25
+
26
+ return {
27
+ schemaVersion: 1,
28
+ name: `${toTitleCase(workspaceName)} Marketing`,
29
+ type: 'marketing',
30
+ package: `@${workspaceName}/${appName}`,
31
+ }
32
+ }
33
+
34
+ /**
35
+ * Generate a manifest for a webapp
36
+ */
37
+ function generateWebappManifest(appName: string, context: Launch77Context): AppManifest {
38
+ const workspaceName = context.workspaceName
39
+
40
+ return {
41
+ schemaVersion: 1,
42
+ name: `${toTitleCase(workspaceName)} Web`,
43
+ type: 'webapp',
44
+ package: `@${workspaceName}/${appName}`,
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Generate a manifest for an API app
50
+ */
51
+ function generateApiManifest(appName: string, context: Launch77Context): AppManifest {
52
+ const workspaceName = context.workspaceName
53
+
54
+ return {
55
+ schemaVersion: 1,
56
+ name: `${toTitleCase(workspaceName)} API`,
57
+ type: 'api',
58
+ package: `@${workspaceName}/${appName}`,
59
+ }
60
+ }
61
+
62
+ export class ManifestService {
63
+ /**
64
+ * Generate an app manifest based on app type
65
+ */
66
+ generateManifest(type: string, appName: string, context: Launch77Context, _options: { port?: string }): AppManifest {
67
+ switch (type) {
68
+ case 'marketing-site':
69
+ case 'marketing':
70
+ return generateMarketingManifest(appName, context)
71
+
72
+ case 'webapp':
73
+ return generateWebappManifest(appName, context)
74
+
75
+ case 'api':
76
+ return generateApiManifest(appName, context)
77
+
78
+ default:
79
+ throw new Error(`Unsupported app type for manifest generation: ${type}. Supported types: api, webapp, marketing-site`)
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Load and validate a Launch77 app manifest file
85
+ * @param startDir - Directory to start searching from (defaults to process.cwd())
86
+ * @returns Object containing manifest, manifestPath, and appRoot
87
+ * @throws Error if manifest not found or invalid
88
+ */
89
+ async loadManifest(startDir?: string): Promise<{
90
+ manifest: AppManifest
91
+ manifestPath: string
92
+ appRoot: string
93
+ }> {
94
+ const searchDir = startDir || process.cwd()
95
+ let currentDir = path.resolve(searchDir)
96
+ const root = path.parse(currentDir).root
97
+
98
+ // Walk up the directory tree looking for .launch/app.json
99
+ while (currentDir !== root) {
100
+ const manifestPath = path.join(currentDir, '.launch', 'app.json')
101
+
102
+ try {
103
+ const fileContent = await fs.readFile(manifestPath, 'utf-8')
104
+ const jsonData = JSON.parse(fileContent)
105
+ const manifest = parseManifest(jsonData)
106
+
107
+ return {
108
+ manifest,
109
+ manifestPath,
110
+ appRoot: currentDir,
111
+ }
112
+ } catch (error) {
113
+ // If file doesn't exist, continue searching up
114
+ if ((error as NodeJS.ErrnoException).code === 'ENOENT') {
115
+ const parentDir = path.dirname(currentDir)
116
+ if (parentDir === currentDir) {
117
+ break // Reached root
118
+ }
119
+ currentDir = parentDir
120
+ continue
121
+ }
122
+
123
+ // If JSON parse error or validation error, throw with helpful message
124
+ if (error instanceof SyntaxError) {
125
+ throw new Error(`Invalid JSON in ${manifestPath}: ${error.message}`)
126
+ }
127
+
128
+ // Re-throw validation errors as-is
129
+ throw error
130
+ }
131
+ }
132
+
133
+ throw new Error(`No Launch77 manifest found in ${searchDir} or any parent directory.\n` + `Looking for .launch/app.json.\n` + `Create one using 'launch77 create-app' or manually add a .launch/app.json file.`)
134
+ }
135
+
136
+ /**
137
+ * Save a manifest file
138
+ * @param manifestPath - Path to save the manifest
139
+ * @param manifest - Manifest data to save
140
+ */
141
+ async saveManifest(manifestPath: string, manifest: AppManifest): Promise<void> {
142
+ await fs.writeFile(manifestPath, JSON.stringify(manifest, null, 2) + '\n', 'utf-8')
143
+ }
144
+ }
@@ -0,0 +1,27 @@
1
+ // Supported app types
2
+ export const APP_TYPES = ['api', 'webapp', 'marketing-site'] as const
3
+ export type AppType = (typeof APP_TYPES)[number]
4
+
5
+ // Display list for error messages
6
+ export const APP_TYPES_LIST = APP_TYPES.join(', ')
7
+
8
+ export interface CreateAppRequest {
9
+ type: AppType
10
+ appName: string
11
+ port: string
12
+ }
13
+
14
+ export interface CreateAppResult {
15
+ appPath: string
16
+ appName: string
17
+ type: AppType
18
+ }
19
+
20
+ export interface DeleteAppRequest {
21
+ appName: string
22
+ }
23
+
24
+ export interface DeleteAppResult {
25
+ appName: string
26
+ hadDockerResources: boolean
27
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * CLI command for generating catalog metadata files
3
+ */
4
+
5
+ import path from 'path'
6
+
7
+ import chalk from 'chalk'
8
+ import { Command } from 'commander'
9
+ import ora from 'ora'
10
+
11
+ import { readCatalogConfig } from '../config/catalog-config.js'
12
+ import { CatalogGeneratorService } from '../services/catalog-generator-svc.js'
13
+ import { printQualityReport } from '../utils/quality-reporter.js'
14
+
15
+ interface GenerateOptions {
16
+ library: string
17
+ config: string
18
+ strict?: boolean
19
+ }
20
+
21
+ /**
22
+ * Create the catalog:generate command
23
+ */
24
+ export function createGenerateCommand(): Command {
25
+ const command = new Command('catalog:generate')
26
+ .description('Generate catalog metadata for a component library')
27
+ .option('-l, --library <path>', 'Library directory path', process.cwd())
28
+ .option('-c, --config <file>', 'Config file name', 'catalog.config.js')
29
+ .option('--no-strict', 'Allow generation with validation errors (warnings only)')
30
+ .action(async (options: GenerateOptions) => {
31
+ try {
32
+ await generateCatalog(options)
33
+ } catch (error) {
34
+ console.error(chalk.red('\\nāœ— Catalog generation failed\\n'))
35
+ if (error instanceof Error) {
36
+ console.error(chalk.red(error.message))
37
+ } else {
38
+ console.error(chalk.red(String(error)))
39
+ }
40
+ process.exit(1)
41
+ }
42
+ })
43
+
44
+ return command
45
+ }
46
+
47
+ /**
48
+ * Execute catalog generation
49
+ */
50
+ async function generateCatalog(options: GenerateOptions): Promise<void> {
51
+ const libraryPath = path.resolve(options.library)
52
+
53
+ console.log(chalk.blue('\\nšŸ“š Generating catalog metadata...\\n'))
54
+ console.log(chalk.gray('Library: ' + libraryPath))
55
+ console.log(chalk.gray('Config: ' + options.config + '\\n'))
56
+
57
+ // Read and validate configuration
58
+ const spinner = ora('Reading configuration...').start()
59
+
60
+ let config
61
+ try {
62
+ config = await readCatalogConfig(libraryPath)
63
+ spinner.succeed('Configuration loaded')
64
+ } catch (error) {
65
+ spinner.fail('Failed to load configuration')
66
+ throw error
67
+ }
68
+
69
+ // Override strict mode if --no-strict flag provided
70
+ if (options.strict === false) {
71
+ config.validation.strict = false
72
+ console.log(chalk.yellow('⚠ Running in non-strict mode (validation errors will not fail build)\\n'))
73
+ }
74
+
75
+ // Display configuration
76
+ console.log(chalk.gray('Configuration:'))
77
+ console.log(chalk.gray(' Package: ' + config.packageName))
78
+ console.log(chalk.gray(' Catalog version: ' + config.catalogVersion))
79
+ console.log(chalk.gray(' Output file: ' + config.outputFile))
80
+ console.log(chalk.gray(' Strict mode: ' + (config.validation.strict ? 'enabled' : 'disabled') + '\\n'))
81
+
82
+ // Generate catalog
83
+ const generationSpinner = ora('Scanning components...').start()
84
+
85
+ const service = new CatalogGeneratorService()
86
+ const result = await service.generateForLibrary(libraryPath, config)
87
+
88
+ generationSpinner.stop()
89
+
90
+ // Display quality report
91
+ console.log(chalk.blue('\\nšŸ“Š Quality Report\\n'))
92
+ printQualityReport(result.qualityReport, config.validation.strict)
93
+
94
+ // Handle result
95
+ if (!result.success) {
96
+ console.log(chalk.red('\\nāœ— Catalog generation failed\\n'))
97
+ console.log(chalk.red('Validation errors must be fixed before building.'))
98
+ console.log(chalk.gray('\\nTo fix:'))
99
+ console.log(chalk.gray(' 1. Add @launch77-component JSDoc to components listed above'))
100
+ console.log(chalk.gray(' 2. Or add @launch77-ignore to exclude internal/WIP components'))
101
+ console.log(chalk.gray(' 3. Or run with --no-strict to allow warnings\\n'))
102
+ process.exit(1)
103
+ }
104
+
105
+ // Success!
106
+ console.log(chalk.green('\\nāœ“ Generated ' + config.outputFile))
107
+ console.log(chalk.gray(' Quality score: ' + result.qualityReport.qualityScore + '%'))
108
+ console.log(chalk.gray(' Total components: ' + result.qualityReport.totalComponents))
109
+
110
+ if (result.warnings.length > 0) {
111
+ console.log(chalk.yellow(' Warnings: ' + result.warnings.length))
112
+ }
113
+
114
+ console.log()
115
+ }
@@ -0,0 +1,48 @@
1
+ import chalk from 'chalk'
2
+ import { Command } from 'commander'
3
+
4
+ import { detectMonorepoContext } from '../../../utils/monorepo.js'
5
+ import { CatalogService } from '../services/catalog-svc.js'
6
+
7
+ /**
8
+ * Scan command - Generate catalog.json from Launch77 artifacts
9
+ *
10
+ * Scans UI components, libraries, plugins, and utilities from the Launch77 monorepo
11
+ * and generates a machine-readable catalog for AI discovery.
12
+ */
13
+ export function scanCommand(): Command {
14
+ const command = new Command('catalog:scan')
15
+ .description('Scan Launch77 artifacts and generate catalog.json')
16
+ .option('--no-strict', 'Skip validation errors and generate catalog anyway')
17
+ .option('--quiet', 'Suppress quality report output')
18
+ .action(async (options) => {
19
+ try {
20
+ const context = await detectMonorepoContext(process.cwd())
21
+
22
+ if (!context.isValid) {
23
+ console.error(chalk.red('\nāœ– Must be run from within a Launch77 monorepo\n'))
24
+ process.exit(1)
25
+ }
26
+
27
+ const catalogService = new CatalogService()
28
+
29
+ await catalogService.scanCatalog(context, {
30
+ strict: options.strict,
31
+ quiet: options.quiet,
32
+ })
33
+ } catch (error) {
34
+ const message = error instanceof Error ? error.message : String(error)
35
+
36
+ if (message.includes('validation failed')) {
37
+ console.log(chalk.red('\nāŒ Catalog validation failed in strict mode.\n'))
38
+ console.log(chalk.yellow('Fix validation errors or use --no-strict flag to generate catalog anyway.\n'))
39
+ } else {
40
+ console.error(chalk.red(`\nāœ– Error: ${message}\n`))
41
+ }
42
+
43
+ process.exit(1)
44
+ }
45
+ })
46
+
47
+ return command
48
+ }