@jack200714/mafw 4.5.1 → 4.5.2

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 (320) hide show
  1. package/README.md +5 -2
  2. package/bin/mafw.js +16 -14
  3. package/package.json +1 -7
  4. package/.opencode/mafw/.backup-v61/parametric/base-skill-manifest.yaml +0 -2
  5. package/.opencode/mafw/STATUS.md +0 -6
  6. package/.opencode/mafw/ledger.md +0 -20
  7. package/.opencode/mafw/memory/.harmonic_index.json +0 -28
  8. package/.opencode/mafw/memory/.review_queue.json +0 -1
  9. package/.opencode/mafw/memory/tier3/parametric.json +0 -13
  10. package/.opencode/mafw/memory/tier3/test-goal.json +0 -19
  11. package/.opencode/mafw/memory-index.json +0 -6
  12. package/.opencode/mafw/parametric/base-skill-manifest.yaml +0 -2
  13. package/.opencode/mafw/waves.json +0 -4
  14. package/.opencode/opencode.json +0 -3
  15. package/.opencode/plugins/mafw-plugin.ts +0 -8
  16. package/.opencode/skills/banner-design/SKILL.md +0 -196
  17. package/.opencode/skills/banner-design/references/banner-sizes-and-styles.md +0 -118
  18. package/.opencode/skills/brand/SKILL.md +0 -97
  19. package/.opencode/skills/brand/references/approval-checklist.md +0 -169
  20. package/.opencode/skills/brand/references/asset-organization.md +0 -157
  21. package/.opencode/skills/brand/references/brand-guideline-template.md +0 -140
  22. package/.opencode/skills/brand/references/color-palette-management.md +0 -186
  23. package/.opencode/skills/brand/references/consistency-checklist.md +0 -94
  24. package/.opencode/skills/brand/references/logo-usage-rules.md +0 -185
  25. package/.opencode/skills/brand/references/messaging-framework.md +0 -85
  26. package/.opencode/skills/brand/references/typography-specifications.md +0 -214
  27. package/.opencode/skills/brand/references/update.md +0 -118
  28. package/.opencode/skills/brand/references/visual-identity.md +0 -96
  29. package/.opencode/skills/brand/references/voice-framework.md +0 -88
  30. package/.opencode/skills/brand/scripts/extract-colors.cjs +0 -341
  31. package/.opencode/skills/brand/scripts/inject-brand-context.cjs +0 -349
  32. package/.opencode/skills/brand/scripts/sync-brand-to-tokens.cjs +0 -248
  33. package/.opencode/skills/brand/scripts/tests/test_sync_brand_to_tokens.py +0 -52
  34. package/.opencode/skills/brand/scripts/validate-asset.cjs +0 -387
  35. package/.opencode/skills/brand/templates/brand-guidelines-starter.md +0 -275
  36. package/.opencode/skills/design/SKILL.md +0 -313
  37. package/.opencode/skills/design/data/cip/deliverables.csv +0 -51
  38. package/.opencode/skills/design/data/cip/industries.csv +0 -21
  39. package/.opencode/skills/design/data/cip/mockup-contexts.csv +0 -21
  40. package/.opencode/skills/design/data/cip/styles.csv +0 -21
  41. package/.opencode/skills/design/data/icon/styles.csv +0 -16
  42. package/.opencode/skills/design/data/logo/colors.csv +0 -56
  43. package/.opencode/skills/design/data/logo/industries.csv +0 -56
  44. package/.opencode/skills/design/data/logo/styles.csv +0 -56
  45. package/.opencode/skills/design/references/banner-sizes-and-styles.md +0 -118
  46. package/.opencode/skills/design/references/cip-deliverable-guide.md +0 -95
  47. package/.opencode/skills/design/references/cip-design.md +0 -121
  48. package/.opencode/skills/design/references/cip-prompt-engineering.md +0 -84
  49. package/.opencode/skills/design/references/cip-style-guide.md +0 -68
  50. package/.opencode/skills/design/references/design-routing.md +0 -207
  51. package/.opencode/skills/design/references/icon-design.md +0 -122
  52. package/.opencode/skills/design/references/logo-color-psychology.md +0 -101
  53. package/.opencode/skills/design/references/logo-design.md +0 -92
  54. package/.opencode/skills/design/references/logo-prompt-engineering.md +0 -158
  55. package/.opencode/skills/design/references/logo-style-guide.md +0 -109
  56. package/.opencode/skills/design/references/slides-copywriting-formulas.md +0 -84
  57. package/.opencode/skills/design/references/slides-create.md +0 -4
  58. package/.opencode/skills/design/references/slides-html-template.md +0 -295
  59. package/.opencode/skills/design/references/slides-layout-patterns.md +0 -137
  60. package/.opencode/skills/design/references/slides-strategies.md +0 -94
  61. package/.opencode/skills/design/references/slides.md +0 -42
  62. package/.opencode/skills/design/references/social-photos-design.md +0 -329
  63. package/.opencode/skills/design/scripts/cip/core.py +0 -215
  64. package/.opencode/skills/design/scripts/cip/generate.py +0 -484
  65. package/.opencode/skills/design/scripts/cip/render-html.py +0 -424
  66. package/.opencode/skills/design/scripts/cip/search.py +0 -127
  67. package/.opencode/skills/design/scripts/icon/generate.py +0 -487
  68. package/.opencode/skills/design/scripts/logo/core.py +0 -175
  69. package/.opencode/skills/design/scripts/logo/generate.py +0 -362
  70. package/.opencode/skills/design/scripts/logo/search.py +0 -114
  71. package/.opencode/skills/design-system/SKILL.md +0 -244
  72. package/.opencode/skills/design-system/data/slide-backgrounds.csv +0 -11
  73. package/.opencode/skills/design-system/data/slide-charts.csv +0 -26
  74. package/.opencode/skills/design-system/data/slide-color-logic.csv +0 -14
  75. package/.opencode/skills/design-system/data/slide-copy.csv +0 -26
  76. package/.opencode/skills/design-system/data/slide-layout-logic.csv +0 -16
  77. package/.opencode/skills/design-system/data/slide-layouts.csv +0 -26
  78. package/.opencode/skills/design-system/data/slide-strategies.csv +0 -16
  79. package/.opencode/skills/design-system/data/slide-typography.csv +0 -15
  80. package/.opencode/skills/design-system/references/component-specs.md +0 -236
  81. package/.opencode/skills/design-system/references/component-tokens.md +0 -214
  82. package/.opencode/skills/design-system/references/primitive-tokens.md +0 -203
  83. package/.opencode/skills/design-system/references/semantic-tokens.md +0 -215
  84. package/.opencode/skills/design-system/references/states-and-variants.md +0 -241
  85. package/.opencode/skills/design-system/references/tailwind-integration.md +0 -251
  86. package/.opencode/skills/design-system/references/token-architecture.md +0 -224
  87. package/.opencode/skills/design-system/scripts/embed-tokens.cjs +0 -99
  88. package/.opencode/skills/design-system/scripts/fetch-background.py +0 -317
  89. package/.opencode/skills/design-system/scripts/generate-slide.py +0 -770
  90. package/.opencode/skills/design-system/scripts/generate-tokens.cjs +0 -205
  91. package/.opencode/skills/design-system/scripts/html-token-validator.py +0 -327
  92. package/.opencode/skills/design-system/scripts/search-slides.py +0 -218
  93. package/.opencode/skills/design-system/scripts/slide-token-validator.py +0 -35
  94. package/.opencode/skills/design-system/scripts/slide_search_core.py +0 -453
  95. package/.opencode/skills/design-system/scripts/tests/test_validate_tokens.py +0 -48
  96. package/.opencode/skills/design-system/scripts/validate-tokens.cjs +0 -246
  97. package/.opencode/skills/design-system/templates/design-tokens-starter.json +0 -143
  98. package/.opencode/skills/frontend-design/LICENSE.txt +0 -21
  99. package/.opencode/skills/frontend-design/SKILL.md +0 -115
  100. package/.opencode/skills/mafw-automation-interview/SKILL.md +0 -43
  101. package/.opencode/skills/mafw-cli-scanner/SKILL.md +0 -37
  102. package/.opencode/skills/mafw-compression-verifier/SKILL.md +0 -52
  103. package/.opencode/skills/mafw-desktop-inspector/SKILL.md +0 -170
  104. package/.opencode/skills/mafw-execute/SKILL.md +0 -62
  105. package/.opencode/skills/mafw-gateway-restart/SKILL.md +0 -87
  106. package/.opencode/skills/mafw-github-scanner/SKILL.md +0 -38
  107. package/.opencode/skills/mafw-goal/SKILL.md +0 -76
  108. package/.opencode/skills/mafw-interview/SKILL.md +0 -68
  109. package/.opencode/skills/mafw-memory-extractor/SKILL.md +0 -65
  110. package/.opencode/skills/mafw-plan/SKILL.md +0 -58
  111. package/.opencode/skills/mafw-review/SKILL.md +0 -85
  112. package/.opencode/skills/runtime-plugin-authoring/SKILL.md +0 -791
  113. package/.opencode/skills/slides/SKILL.md +0 -40
  114. package/.opencode/skills/slides/references/copywriting-formulas.md +0 -84
  115. package/.opencode/skills/slides/references/create.md +0 -4
  116. package/.opencode/skills/slides/references/html-template.md +0 -295
  117. package/.opencode/skills/slides/references/layout-patterns.md +0 -137
  118. package/.opencode/skills/slides/references/slide-strategies.md +0 -94
  119. package/.opencode/skills/ui-styling/LICENSE.txt +0 -202
  120. package/.opencode/skills/ui-styling/SKILL.md +0 -324
  121. package/.opencode/skills/ui-styling/references/canvas-design-system.md +0 -320
  122. package/.opencode/skills/ui-styling/references/shadcn-accessibility.md +0 -471
  123. package/.opencode/skills/ui-styling/references/shadcn-components.md +0 -424
  124. package/.opencode/skills/ui-styling/references/shadcn-theming.md +0 -373
  125. package/.opencode/skills/ui-styling/references/tailwind-customization.md +0 -483
  126. package/.opencode/skills/ui-styling/references/tailwind-responsive.md +0 -382
  127. package/.opencode/skills/ui-styling/references/tailwind-utilities.md +0 -455
  128. package/.opencode/skills/ui-styling/scripts/requirements.txt +0 -17
  129. package/.opencode/skills/ui-styling/scripts/shadcn_add.py +0 -308
  130. package/.opencode/skills/ui-styling/scripts/tailwind_config_gen.py +0 -473
  131. package/.opencode/skills/ui-styling/scripts/tests/coverage-ui.json +0 -1
  132. package/.opencode/skills/ui-styling/scripts/tests/requirements.txt +0 -3
  133. package/.opencode/skills/ui-styling/scripts/tests/test_shadcn_add.py +0 -266
  134. package/.opencode/skills/ui-styling/scripts/tests/test_tailwind_config_gen.py +0 -394
  135. package/.opencode/skills/ui-ux-pro-max/SKILL.md +0 -388
  136. package/.opencode/skills/ui-ux-pro-max/data/app-interface.csv +0 -31
  137. package/.opencode/skills/ui-ux-pro-max/data/charts.csv +0 -26
  138. package/.opencode/skills/ui-ux-pro-max/data/colors.csv +0 -193
  139. package/.opencode/skills/ui-ux-pro-max/data/google-fonts.csv +0 -1924
  140. package/.opencode/skills/ui-ux-pro-max/data/icons.csv +0 -106
  141. package/.opencode/skills/ui-ux-pro-max/data/landing.csv +0 -35
  142. package/.opencode/skills/ui-ux-pro-max/data/motion.csv +0 -17
  143. package/.opencode/skills/ui-ux-pro-max/data/products.csv +0 -193
  144. package/.opencode/skills/ui-ux-pro-max/data/react-performance.csv +0 -45
  145. package/.opencode/skills/ui-ux-pro-max/data/stacks/angular.csv +0 -51
  146. package/.opencode/skills/ui-ux-pro-max/data/stacks/astro.csv +0 -54
  147. package/.opencode/skills/ui-ux-pro-max/data/stacks/avalonia.csv +0 -57
  148. package/.opencode/skills/ui-ux-pro-max/data/stacks/flutter.csv +0 -53
  149. package/.opencode/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +0 -56
  150. package/.opencode/skills/ui-ux-pro-max/data/stacks/javafx.csv +0 -76
  151. package/.opencode/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +0 -53
  152. package/.opencode/skills/ui-ux-pro-max/data/stacks/laravel.csv +0 -51
  153. package/.opencode/skills/ui-ux-pro-max/data/stacks/nextjs.csv +0 -53
  154. package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +0 -71
  155. package/.opencode/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +0 -59
  156. package/.opencode/skills/ui-ux-pro-max/data/stacks/react-native.csv +0 -52
  157. package/.opencode/skills/ui-ux-pro-max/data/stacks/react.csv +0 -54
  158. package/.opencode/skills/ui-ux-pro-max/data/stacks/shadcn.csv +0 -61
  159. package/.opencode/skills/ui-ux-pro-max/data/stacks/svelte.csv +0 -54
  160. package/.opencode/skills/ui-ux-pro-max/data/stacks/swiftui.csv +0 -51
  161. package/.opencode/skills/ui-ux-pro-max/data/stacks/threejs.csv +0 -54
  162. package/.opencode/skills/ui-ux-pro-max/data/stacks/uno.csv +0 -60
  163. package/.opencode/skills/ui-ux-pro-max/data/stacks/uwp.csv +0 -56
  164. package/.opencode/skills/ui-ux-pro-max/data/stacks/vue.csv +0 -50
  165. package/.opencode/skills/ui-ux-pro-max/data/stacks/winui.csv +0 -60
  166. package/.opencode/skills/ui-ux-pro-max/data/stacks/wpf.csv +0 -57
  167. package/.opencode/skills/ui-ux-pro-max/data/styles.csv +0 -85
  168. package/.opencode/skills/ui-ux-pro-max/data/typography.csv +0 -75
  169. package/.opencode/skills/ui-ux-pro-max/data/ui-reasoning.csv +0 -162
  170. package/.opencode/skills/ui-ux-pro-max/data/ux-guidelines.csv +0 -100
  171. package/.opencode/skills/ui-ux-pro-max/scripts/core.py +0 -464
  172. package/.opencode/skills/ui-ux-pro-max/scripts/design_system.py +0 -1479
  173. package/.opencode/skills/ui-ux-pro-max/scripts/search.py +0 -162
  174. package/.opencode/skills/ui-ux-pro-max/scripts/tests/test_core.py +0 -134
  175. package/.opencode/skills/ui-ux-pro-max/scripts/tests/test_design_system_mode.py +0 -159
  176. package/.opencode/skills/ui-ux-pro-max/scripts/validate_data.py +0 -114
  177. package/dist/hooks/bash-python-guide.d.ts +0 -4
  178. package/dist/hooks/bash-python-guide.d.ts.map +0 -1
  179. package/dist/hooks/bash-python-guide.js +0 -67
  180. package/dist/hooks/bash-python-guide.js.map +0 -1
  181. package/dist/hooks/handoff.d.ts +0 -9
  182. package/dist/hooks/handoff.d.ts.map +0 -1
  183. package/dist/hooks/handoff.js +0 -8
  184. package/dist/hooks/handoff.js.map +0 -1
  185. package/dist/hooks/hook-manager.d.ts +0 -32
  186. package/dist/hooks/hook-manager.d.ts.map +0 -1
  187. package/dist/hooks/hook-manager.js +0 -91
  188. package/dist/hooks/hook-manager.js.map +0 -1
  189. package/dist/hooks/llm-after.d.ts +0 -8
  190. package/dist/hooks/llm-after.d.ts.map +0 -1
  191. package/dist/hooks/llm-after.js +0 -8
  192. package/dist/hooks/llm-after.js.map +0 -1
  193. package/dist/hooks/media-ingest.d.ts +0 -43
  194. package/dist/hooks/media-ingest.d.ts.map +0 -1
  195. package/dist/hooks/media-ingest.js +0 -269
  196. package/dist/hooks/media-ingest.js.map +0 -1
  197. package/dist/hooks/memory-guide.d.ts +0 -3
  198. package/dist/hooks/memory-guide.d.ts.map +0 -1
  199. package/dist/hooks/memory-guide.js +0 -47
  200. package/dist/hooks/memory-guide.js.map +0 -1
  201. package/dist/hooks/observation-capture.d.ts +0 -17
  202. package/dist/hooks/observation-capture.d.ts.map +0 -1
  203. package/dist/hooks/observation-capture.js +0 -20
  204. package/dist/hooks/observation-capture.js.map +0 -1
  205. package/dist/hooks/session-compacting.d.ts +0 -6
  206. package/dist/hooks/session-compacting.d.ts.map +0 -1
  207. package/dist/hooks/session-compacting.js +0 -6
  208. package/dist/hooks/session-compacting.js.map +0 -1
  209. package/dist/hooks/session-ending.d.ts +0 -20
  210. package/dist/hooks/session-ending.d.ts.map +0 -1
  211. package/dist/hooks/session-ending.js +0 -113
  212. package/dist/hooks/session-ending.js.map +0 -1
  213. package/dist/hooks/session-recall.d.ts +0 -2
  214. package/dist/hooks/session-recall.d.ts.map +0 -1
  215. package/dist/hooks/session-recall.js +0 -103
  216. package/dist/hooks/session-recall.js.map +0 -1
  217. package/dist/hooks/session-start.d.ts +0 -9
  218. package/dist/hooks/session-start.d.ts.map +0 -1
  219. package/dist/hooks/session-start.js +0 -42
  220. package/dist/hooks/session-start.js.map +0 -1
  221. package/dist/hooks/tool-before.d.ts +0 -10
  222. package/dist/hooks/tool-before.d.ts.map +0 -1
  223. package/dist/hooks/tool-before.js +0 -6
  224. package/dist/hooks/tool-before.js.map +0 -1
  225. package/dist/hooks/tool-executed.d.ts +0 -19
  226. package/dist/hooks/tool-executed.d.ts.map +0 -1
  227. package/dist/hooks/tool-executed.js +0 -12
  228. package/dist/hooks/tool-executed.js.map +0 -1
  229. package/dist/hooks/user-profile.d.ts +0 -2
  230. package/dist/hooks/user-profile.d.ts.map +0 -1
  231. package/dist/hooks/user-profile.js +0 -30
  232. package/dist/hooks/user-profile.js.map +0 -1
  233. package/dist/hooks/user-prompt.d.ts +0 -9
  234. package/dist/hooks/user-prompt.d.ts.map +0 -1
  235. package/dist/hooks/user-prompt.js +0 -8
  236. package/dist/hooks/user-prompt.js.map +0 -1
  237. package/dist/hooks/voice-guide.d.ts +0 -8
  238. package/dist/hooks/voice-guide.d.ts.map +0 -1
  239. package/dist/hooks/voice-guide.js +0 -101
  240. package/dist/hooks/voice-guide.js.map +0 -1
  241. package/dist/plugin.d.ts +0 -55
  242. package/dist/plugin.d.ts.map +0 -1
  243. package/dist/plugin.js +0 -342
  244. package/dist/plugin.js.map +0 -1
  245. package/dist/tools/add-memory.d.ts +0 -17
  246. package/dist/tools/add-memory.d.ts.map +0 -1
  247. package/dist/tools/add-memory.js +0 -60
  248. package/dist/tools/add-memory.js.map +0 -1
  249. package/dist/tools/media-ask.d.ts +0 -14
  250. package/dist/tools/media-ask.d.ts.map +0 -1
  251. package/dist/tools/media-ask.js +0 -224
  252. package/dist/tools/media-ask.js.map +0 -1
  253. package/dist/tools/media-speak.d.ts +0 -16
  254. package/dist/tools/media-speak.d.ts.map +0 -1
  255. package/dist/tools/media-speak.js +0 -78
  256. package/dist/tools/media-speak.js.map +0 -1
  257. package/dist/tools/media-upload.d.ts +0 -14
  258. package/dist/tools/media-upload.d.ts.map +0 -1
  259. package/dist/tools/media-upload.js +0 -155
  260. package/dist/tools/media-upload.js.map +0 -1
  261. package/dist/tools/python-exec.d.ts +0 -13
  262. package/dist/tools/python-exec.d.ts.map +0 -1
  263. package/dist/tools/python-exec.js +0 -99
  264. package/dist/tools/python-exec.js.map +0 -1
  265. package/dist/tools/python-restart.d.ts +0 -11
  266. package/dist/tools/python-restart.d.ts.map +0 -1
  267. package/dist/tools/python-restart.js +0 -33
  268. package/dist/tools/python-restart.js.map +0 -1
  269. package/dist/utils/circuit-breaker.d.ts +0 -23
  270. package/dist/utils/circuit-breaker.d.ts.map +0 -1
  271. package/dist/utils/circuit-breaker.js +0 -75
  272. package/dist/utils/circuit-breaker.js.map +0 -1
  273. package/dist/utils/config-loader.d.ts +0 -20
  274. package/dist/utils/config-loader.d.ts.map +0 -1
  275. package/dist/utils/config-loader.js +0 -194
  276. package/dist/utils/config-loader.js.map +0 -1
  277. package/dist/utils/fallback.d.ts +0 -7
  278. package/dist/utils/fallback.d.ts.map +0 -1
  279. package/dist/utils/fallback.js +0 -20
  280. package/dist/utils/fallback.js.map +0 -1
  281. package/dist/utils/git.d.ts +0 -24
  282. package/dist/utils/git.d.ts.map +0 -1
  283. package/dist/utils/git.js +0 -71
  284. package/dist/utils/git.js.map +0 -1
  285. package/dist/utils/github.d.ts +0 -37
  286. package/dist/utils/github.d.ts.map +0 -1
  287. package/dist/utils/github.js +0 -53
  288. package/dist/utils/github.js.map +0 -1
  289. package/dist/utils/global-path.d.ts +0 -2
  290. package/dist/utils/global-path.d.ts.map +0 -1
  291. package/dist/utils/global-path.js +0 -32
  292. package/dist/utils/global-path.js.map +0 -1
  293. package/dist/utils/logger.d.ts +0 -6
  294. package/dist/utils/logger.d.ts.map +0 -1
  295. package/dist/utils/logger.js +0 -69
  296. package/dist/utils/logger.js.map +0 -1
  297. package/dist/utils/obs-capture.d.ts +0 -7
  298. package/dist/utils/obs-capture.d.ts.map +0 -1
  299. package/dist/utils/obs-capture.js +0 -49
  300. package/dist/utils/obs-capture.js.map +0 -1
  301. package/dist/utils/retry.d.ts +0 -11
  302. package/dist/utils/retry.d.ts.map +0 -1
  303. package/dist/utils/retry.js +0 -45
  304. package/dist/utils/retry.js.map +0 -1
  305. package/dist/utils/self-wiring.d.ts +0 -13
  306. package/dist/utils/self-wiring.d.ts.map +0 -1
  307. package/dist/utils/self-wiring.js +0 -86
  308. package/dist/utils/self-wiring.js.map +0 -1
  309. package/dist/utils/state.d.ts +0 -106
  310. package/dist/utils/state.d.ts.map +0 -1
  311. package/dist/utils/state.js +0 -166
  312. package/dist/utils/state.js.map +0 -1
  313. package/dist/utils/status.d.ts +0 -47
  314. package/dist/utils/status.d.ts.map +0 -1
  315. package/dist/utils/status.js +0 -147
  316. package/dist/utils/status.js.map +0 -1
  317. package/dist/utils/ttl-map.d.ts +0 -17
  318. package/dist/utils/ttl-map.d.ts.map +0 -1
  319. package/dist/utils/ttl-map.js +0 -67
  320. package/dist/utils/ttl-map.js.map +0 -1
@@ -1,308 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- shadcn/ui Component Installer
4
-
5
- Add shadcn/ui components to project with automatic dependency handling.
6
- Wraps shadcn CLI for programmatic component installation.
7
- """
8
-
9
- import argparse
10
- import json
11
- import subprocess
12
- import sys
13
- from pathlib import Path
14
- from typing import List, Optional
15
-
16
-
17
- class ShadcnInstaller:
18
- """Handle shadcn/ui component installation."""
19
-
20
- def __init__(self, project_root: Optional[Path] = None, dry_run: bool = False):
21
- """
22
- Initialize installer.
23
-
24
- Args:
25
- project_root: Project root directory (default: current directory)
26
- dry_run: If True, show actions without executing
27
- """
28
- self.project_root = project_root or Path.cwd()
29
- self.dry_run = dry_run
30
- self.components_json = self.project_root / "components.json"
31
-
32
- def check_shadcn_config(self) -> bool:
33
- """
34
- Check if shadcn is initialized in project.
35
-
36
- Returns:
37
- True if components.json exists
38
- """
39
- return self.components_json.exists()
40
-
41
- def get_installed_components(self) -> List[str]:
42
- """
43
- Get list of already installed components.
44
-
45
- Returns:
46
- List of installed component names
47
- """
48
- if not self.check_shadcn_config():
49
- return []
50
-
51
- try:
52
- with open(self.components_json) as f:
53
- config = json.load(f)
54
-
55
- components_dir = self.project_root / config.get("aliases", {}).get(
56
- "components", "components"
57
- ).replace("@/", "")
58
- ui_dir = components_dir / "ui"
59
-
60
- if not ui_dir.exists():
61
- return []
62
-
63
- return [f.stem for f in ui_dir.glob("*.tsx") if f.is_file()]
64
- except (json.JSONDecodeError, KeyError, OSError):
65
- return []
66
-
67
- def _get_shadcn_version(self) -> str:
68
- """Read shadcn version from project package.json; fall back to a pinned default."""
69
- pkg_json = self.project_root / "package.json"
70
- if pkg_json.exists():
71
- try:
72
- pkg = json.loads(pkg_json.read_text())
73
- for section in ("dependencies", "devDependencies"):
74
- version = pkg.get(section, {}).get("shadcn")
75
- if version:
76
- return version.lstrip("^~>=<").split()[0]
77
- except (json.JSONDecodeError, KeyError):
78
- pass
79
- return "2.3.0" # pinned fallback; update when newer stable release is needed
80
-
81
- def add_components(
82
- self, components: List[str], overwrite: bool = False
83
- ) -> tuple[bool, str]:
84
- """
85
- Add shadcn/ui components.
86
-
87
- Args:
88
- components: List of component names to add
89
- overwrite: If True, overwrite existing components
90
-
91
- Returns:
92
- Tuple of (success, message)
93
- """
94
- if not components:
95
- return False, "No components specified"
96
-
97
- if not self.check_shadcn_config():
98
- return (
99
- False,
100
- "shadcn not initialized. Run 'npx shadcn@latest init' first",
101
- )
102
-
103
- # Check which components already exist
104
- installed = self.get_installed_components()
105
- already_installed = [c for c in components if c in installed]
106
-
107
- if already_installed and not overwrite:
108
- return (
109
- False,
110
- f"Components already installed: {', '.join(already_installed)}. "
111
- "Use --overwrite to reinstall",
112
- )
113
-
114
- # Build command
115
- shadcn_version = self._get_shadcn_version()
116
- cmd = ["npx", f"shadcn@{shadcn_version}", "add"] + components
117
-
118
- if overwrite:
119
- cmd.append("--overwrite")
120
-
121
- if self.dry_run:
122
- return True, f"Would run: {' '.join(cmd)}"
123
-
124
- # Execute command
125
- try:
126
- result = subprocess.run(
127
- cmd,
128
- cwd=self.project_root,
129
- capture_output=True,
130
- text=True,
131
- check=True,
132
- )
133
-
134
- success_msg = f"Successfully added components: {', '.join(components)}"
135
- if result.stdout:
136
- success_msg += f"\n\nOutput:\n{result.stdout}"
137
-
138
- return True, success_msg
139
-
140
- except subprocess.CalledProcessError as e:
141
- error_msg = f"Failed to add components: {e.stderr or e.stdout or str(e)}"
142
- return False, error_msg
143
- except FileNotFoundError:
144
- return False, "npx not found. Ensure Node.js is installed"
145
-
146
- def add_all_components(self, overwrite: bool = False) -> tuple[bool, str]:
147
- """
148
- Add all available shadcn/ui components.
149
-
150
- Args:
151
- overwrite: If True, overwrite existing components
152
-
153
- Returns:
154
- Tuple of (success, message)
155
- """
156
- if not self.check_shadcn_config():
157
- return (
158
- False,
159
- "shadcn not initialized. Run 'npx shadcn@latest init' first",
160
- )
161
-
162
- shadcn_version = self._get_shadcn_version()
163
- cmd = ["npx", f"shadcn@{shadcn_version}", "add", "--all"]
164
-
165
- if overwrite:
166
- cmd.append("--overwrite")
167
-
168
- if self.dry_run:
169
- return True, f"Would run: {' '.join(cmd)}"
170
-
171
- try:
172
- result = subprocess.run(
173
- cmd,
174
- cwd=self.project_root,
175
- capture_output=True,
176
- text=True,
177
- check=True,
178
- )
179
-
180
- success_msg = "Successfully added all components"
181
- if result.stdout:
182
- success_msg += f"\n\nOutput:\n{result.stdout}"
183
-
184
- return True, success_msg
185
-
186
- except subprocess.CalledProcessError as e:
187
- error_msg = f"Failed to add all components: {e.stderr or e.stdout or str(e)}"
188
- return False, error_msg
189
- except FileNotFoundError:
190
- return False, "npx not found. Ensure Node.js is installed"
191
-
192
- def list_installed(self) -> tuple[bool, str]:
193
- """
194
- List installed components.
195
-
196
- Returns:
197
- Tuple of (success, message with component list)
198
- """
199
- if not self.check_shadcn_config():
200
- return False, "shadcn not initialized"
201
-
202
- installed = self.get_installed_components()
203
-
204
- if not installed:
205
- return True, "No components installed"
206
-
207
- return True, f"Installed components:\n" + "\n".join(f" - {c}" for c in sorted(installed))
208
-
209
-
210
- def main():
211
- """CLI entry point."""
212
- parser = argparse.ArgumentParser(
213
- description="Add shadcn/ui components to your project",
214
- formatter_class=argparse.RawDescriptionHelpFormatter,
215
- epilog="""
216
- Examples:
217
- # Add single component
218
- python shadcn_add.py button
219
-
220
- # Add multiple components
221
- python shadcn_add.py button card dialog
222
-
223
- # Add all components
224
- python shadcn_add.py --all
225
-
226
- # Overwrite existing components
227
- python shadcn_add.py button --overwrite
228
-
229
- # Dry run (show what would be done)
230
- python shadcn_add.py button card --dry-run
231
-
232
- # List installed components
233
- python shadcn_add.py --list
234
- """,
235
- )
236
-
237
- parser.add_argument(
238
- "components",
239
- nargs="*",
240
- help="Component names to add (e.g., button, card, dialog)",
241
- )
242
-
243
- parser.add_argument(
244
- "--all",
245
- action="store_true",
246
- help="Add all available components",
247
- )
248
-
249
- parser.add_argument(
250
- "--overwrite",
251
- action="store_true",
252
- help="Overwrite existing components",
253
- )
254
-
255
- parser.add_argument(
256
- "--dry-run",
257
- action="store_true",
258
- help="Show what would be done without executing",
259
- )
260
-
261
- parser.add_argument(
262
- "--list",
263
- action="store_true",
264
- help="List installed components",
265
- )
266
-
267
- parser.add_argument(
268
- "--project-root",
269
- type=Path,
270
- help="Project root directory (default: current directory)",
271
- )
272
-
273
- args = parser.parse_args()
274
-
275
- # Initialize installer
276
- installer = ShadcnInstaller(
277
- project_root=args.project_root,
278
- dry_run=args.dry_run,
279
- )
280
-
281
- # Handle list command
282
- if args.list:
283
- success, message = installer.list_installed()
284
- print(message)
285
- sys.exit(0 if success else 1)
286
-
287
- # Handle add all command
288
- if args.all:
289
- success, message = installer.add_all_components(overwrite=args.overwrite)
290
- print(message)
291
- sys.exit(0 if success else 1)
292
-
293
- # Handle add specific components
294
- if not args.components:
295
- parser.print_help()
296
- sys.exit(1)
297
-
298
- success, message = installer.add_components(
299
- args.components,
300
- overwrite=args.overwrite,
301
- )
302
-
303
- print(message)
304
- sys.exit(0 if success else 1)
305
-
306
-
307
- if __name__ == "__main__":
308
- main()