@shepai/cli 1.59.0 → 1.61.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 (339) hide show
  1. package/dist/src/presentation/web/app/skills/page.d.ts +2 -0
  2. package/dist/src/presentation/web/app/skills/page.d.ts.map +1 -0
  3. package/dist/src/presentation/web/app/skills/page.js +11 -0
  4. package/dist/src/presentation/web/components/common/action-button/action-button.d.ts.map +1 -1
  5. package/dist/src/presentation/web/components/common/action-button/action-button.js +7 -1
  6. package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts +1 -1
  7. package/dist/src/presentation/web/components/common/action-button/action-button.stories.d.ts.map +1 -1
  8. package/dist/src/presentation/web/components/common/action-button/action-button.stories.js +1 -1
  9. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
  10. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +10 -1
  11. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts +20 -0
  12. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.d.ts.map +1 -0
  13. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.js +68 -0
  14. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  15. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +21 -2
  16. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
  17. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +13 -2
  18. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +16 -3
  20. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts +1 -1
  21. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.d.ts.map +1 -1
  22. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.js +1 -1
  23. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.d.ts.map +1 -1
  24. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.js +14 -1
  25. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts +2 -0
  26. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.js +2 -0
  28. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.js +4 -1
  30. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts +1 -0
  31. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.d.ts.map +1 -1
  32. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.js +1 -0
  33. package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.d.ts.map +1 -1
  34. package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.js +14 -1
  35. package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts +1 -1
  36. package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.d.ts.map +1 -1
  37. package/dist/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.js +1 -1
  38. package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.d.ts.map +1 -1
  39. package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.js +13 -0
  40. package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts +2 -0
  41. package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.js +2 -0
  43. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +2 -2
  44. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  45. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +7 -13
  46. package/dist/src/presentation/web/components/features/skills/category-filter.d.ts +8 -0
  47. package/dist/src/presentation/web/components/features/skills/category-filter.d.ts.map +1 -0
  48. package/dist/src/presentation/web/components/features/skills/category-filter.js +12 -0
  49. package/dist/src/presentation/web/components/features/skills/category-filter.stories.d.ts +9 -0
  50. package/dist/src/presentation/web/components/features/skills/category-filter.stories.d.ts.map +1 -0
  51. package/dist/src/presentation/web/components/features/skills/category-filter.stories.js +36 -0
  52. package/dist/src/presentation/web/components/features/skills/index.d.ts +6 -0
  53. package/dist/src/presentation/web/components/features/skills/index.d.ts.map +1 -0
  54. package/dist/src/presentation/web/components/features/skills/index.js +5 -0
  55. package/dist/src/presentation/web/components/features/skills/skill-card.d.ts +7 -0
  56. package/dist/src/presentation/web/components/features/skills/skill-card.d.ts.map +1 -0
  57. package/dist/src/presentation/web/components/features/skills/skill-card.js +12 -0
  58. package/dist/src/presentation/web/components/features/skills/skill-card.stories.d.ts +11 -0
  59. package/dist/src/presentation/web/components/features/skills/skill-card.stories.d.ts.map +1 -0
  60. package/dist/src/presentation/web/components/features/skills/skill-card.stories.js +88 -0
  61. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.d.ts +7 -0
  62. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.d.ts.map +1 -0
  63. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.js +13 -0
  64. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.d.ts +10 -0
  65. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.d.ts.map +1 -0
  66. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.stories.js +71 -0
  67. package/dist/src/presentation/web/components/features/skills/skill-list.d.ts +7 -0
  68. package/dist/src/presentation/web/components/features/skills/skill-list.d.ts.map +1 -0
  69. package/dist/src/presentation/web/components/features/skills/skill-list.js +21 -0
  70. package/dist/src/presentation/web/components/features/skills/skill-list.stories.d.ts +9 -0
  71. package/dist/src/presentation/web/components/features/skills/skill-list.stories.d.ts.map +1 -0
  72. package/dist/src/presentation/web/components/features/skills/skill-list.stories.js +124 -0
  73. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts +6 -0
  74. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts.map +1 -0
  75. package/dist/src/presentation/web/components/features/skills/skills-page-client.js +52 -0
  76. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts +16 -0
  77. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.d.ts.map +1 -0
  78. package/dist/src/presentation/web/components/features/skills/skills-page-client.stories.js +186 -0
  79. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  80. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +3 -2
  81. package/dist/src/presentation/web/hooks/use-notifications.d.ts.map +1 -1
  82. package/dist/src/presentation/web/hooks/use-notifications.js +18 -18
  83. package/dist/src/presentation/web/hooks/use-sound-action.d.ts +100 -0
  84. package/dist/src/presentation/web/hooks/use-sound-action.d.ts.map +1 -0
  85. package/dist/src/presentation/web/hooks/use-sound-action.js +42 -0
  86. package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts +6 -0
  87. package/dist/src/presentation/web/hooks/use-sound-action.stories.d.ts.map +1 -0
  88. package/dist/src/presentation/web/hooks/use-sound-action.stories.js +61 -0
  89. package/dist/src/presentation/web/lib/feature-flags.d.ts +10 -0
  90. package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -0
  91. package/dist/src/presentation/web/lib/feature-flags.js +12 -0
  92. package/dist/src/presentation/web/lib/skills.d.ts +30 -0
  93. package/dist/src/presentation/web/lib/skills.d.ts.map +1 -0
  94. package/dist/src/presentation/web/lib/skills.js +137 -0
  95. package/dist/tsconfig.build.tsbuildinfo +1 -1
  96. package/package.json +1 -1
  97. package/web/.next/BUILD_ID +1 -1
  98. package/web/.next/app-path-routes-manifest.json +1 -0
  99. package/web/.next/build-manifest.json +4 -4
  100. package/web/.next/cache/.previewinfo +1 -1
  101. package/web/.next/cache/.rscinfo +1 -1
  102. package/web/.next/cache/.tsbuildinfo +1 -1
  103. package/web/.next/cache/config.json +3 -3
  104. package/web/.next/fallback-build-manifest.json +2 -2
  105. package/web/.next/prerender-manifest.json +3 -3
  106. package/web/.next/required-server-files.js +1 -1
  107. package/web/.next/required-server-files.json +1 -1
  108. package/web/.next/routes-manifest.json +6 -0
  109. package/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  110. package/web/.next/server/app/_global-error.html +2 -2
  111. package/web/.next/server/app/_global-error.rsc +1 -1
  112. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  113. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  114. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  115. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  116. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  117. package/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  118. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  119. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  120. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  121. package/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  122. package/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  123. package/web/.next/server/app/page/build-manifest.json +2 -2
  124. package/web/.next/server/app/page/server-reference-manifest.json +14 -14
  125. package/web/.next/server/app/page.js +1 -1
  126. package/web/.next/server/app/page.js.nft.json +1 -1
  127. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  128. package/web/.next/server/app/skills/page/app-paths-manifest.json +3 -0
  129. package/web/.next/server/app/skills/page/build-manifest.json +17 -0
  130. package/web/.next/server/app/skills/page/next-font-manifest.json +6 -0
  131. package/web/.next/server/app/skills/page/react-loadable-manifest.json +1 -0
  132. package/web/.next/server/app/skills/page/server-reference-manifest.json +20 -0
  133. package/web/.next/server/app/skills/page.js +16 -0
  134. package/web/.next/server/app/skills/page.js.map +5 -0
  135. package/web/.next/server/app/skills/page.js.nft.json +1 -0
  136. package/web/.next/server/app/skills/page_client-reference-manifest.js +2 -0
  137. package/web/.next/server/app/tools/page/build-manifest.json +2 -2
  138. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  139. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  140. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  141. package/web/.next/server/app/version/page/build-manifest.json +2 -2
  142. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  143. package/web/.next/server/app/version/page.js.nft.json +1 -1
  144. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  145. package/web/.next/server/app-paths-manifest.json +1 -0
  146. package/web/.next/server/chunks/{[root-of-the-server]__bb619083._.js → [root-of-the-server]__e926de65._.js} +2 -2
  147. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  148. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +3 -0
  150. package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js.map +1 -0
  151. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  154. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  155. package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +3 -0
  156. package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js.map +1 -0
  157. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  158. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
  159. package/web/.next/server/chunks/ssr/{[root-of-the-server]__86c7bba5._.js → [root-of-the-server]__b6839c3f._.js} +3 -3
  160. package/web/.next/server/chunks/ssr/{[root-of-the-server]__86c7bba5._.js.map → [root-of-the-server]__b6839c3f._.js.map} +1 -1
  161. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +4 -0
  162. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js.map +1 -0
  163. package/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js +3 -0
  164. package/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js.map +1 -0
  165. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +3 -0
  166. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js.map +1 -0
  167. package/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
  168. package/web/.next/server/chunks/ssr/_380c6567._.js +6 -0
  169. package/web/.next/server/chunks/ssr/_380c6567._.js.map +1 -0
  170. package/web/.next/server/chunks/ssr/_44cce4e0._.js +4 -0
  171. package/web/.next/server/chunks/ssr/_44cce4e0._.js.map +1 -0
  172. package/web/.next/server/chunks/ssr/_9915d2a7._.js +3 -0
  173. package/web/.next/server/chunks/ssr/_9915d2a7._.js.map +1 -0
  174. package/web/.next/server/chunks/ssr/_a64b7b24._.js +3 -0
  175. package/web/.next/server/chunks/ssr/{_e242b954._.js.map → _a64b7b24._.js.map} +1 -1
  176. package/web/.next/server/chunks/ssr/_d3711354._.js +6 -0
  177. package/web/.next/server/chunks/ssr/_d3711354._.js.map +1 -0
  178. package/web/.next/server/chunks/ssr/_e7a4b0e4._.js +3 -0
  179. package/web/.next/server/chunks/ssr/_e7a4b0e4._.js.map +1 -0
  180. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_d26a7485._.js → server/chunks/ssr/node_modules__pnpm_fe355030._.js} +2 -2
  181. package/web/.next/server/chunks/ssr/node_modules__pnpm_fe355030._.js.map +1 -0
  182. package/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js +3 -0
  183. package/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js.map +1 -0
  184. package/web/.next/server/middleware-build-manifest.js +2 -2
  185. package/web/.next/server/pages/500.html +2 -2
  186. package/web/.next/server/server-reference-manifest.js +1 -1
  187. package/web/.next/server/server-reference-manifest.json +22 -15
  188. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/app-path-routes-manifest.json +1 -0
  190. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +4 -4
  191. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  192. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/routes-manifest.json +6 -0
  194. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error/page/build-manifest.json +2 -2
  195. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  196. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  199. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  201. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/build-manifest.json +2 -2
  203. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  205. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  206. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/app/api/tools/[id]/install/route.js.nft.json +1 -1
  208. package/web/.next/standalone/src/presentation/web/.next/server/app/page/build-manifest.json +2 -2
  209. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
  210. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js +1 -1
  211. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/app-paths-manifest.json +3 -0
  214. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/build-manifest.json +17 -0
  215. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/next-font-manifest.json +6 -0
  216. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/react-loadable-manifest.json +1 -0
  217. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +20 -0
  218. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js +16 -0
  219. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.map +5 -0
  220. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -0
  221. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +2 -0
  222. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/build-manifest.json +2 -2
  223. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  224. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  225. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  226. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/build-manifest.json +2 -2
  227. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  228. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  229. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  230. package/web/.next/standalone/src/presentation/web/.next/server/app-paths-manifest.json +1 -0
  231. package/web/.next/standalone/src/presentation/web/.next/server/chunks/{[root-of-the-server]__bb619083._.js → [root-of-the-server]__e926de65._.js} +2 -2
  232. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  233. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +3 -0
  234. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  235. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  236. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +3 -0
  237. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  238. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{[root-of-the-server]__86c7bba5._.js → [root-of-the-server]__b6839c3f._.js} +3 -3
  239. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +4 -0
  240. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__edca9510._.js +3 -0
  241. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +3 -0
  242. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
  243. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_380c6567._.js +6 -0
  244. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_44cce4e0._.js +4 -0
  245. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9915d2a7._.js +3 -0
  246. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_a64b7b24._.js +3 -0
  247. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_d3711354._.js +6 -0
  248. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_e7a4b0e4._.js +3 -0
  249. package/web/.next/{server/chunks/ssr/node_modules__pnpm_d26a7485._.js → standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_fe355030._.js} +2 -2
  250. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_0286756b._.js +3 -0
  251. package/web/.next/standalone/src/presentation/web/.next/server/middleware-build-manifest.js +2 -2
  252. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  253. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  254. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +22 -15
  255. package/web/.next/standalone/src/presentation/web/app/skills/page.tsx +12 -0
  256. package/web/.next/standalone/src/presentation/web/components/common/action-button/action-button.stories.tsx +1 -1
  257. package/web/.next/standalone/src/presentation/web/components/common/action-button/action-button.tsx +9 -1
  258. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.stories.tsx +82 -0
  259. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +16 -2
  260. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +27 -3
  261. package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +14 -2
  262. package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.stories.tsx +1 -1
  263. package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx +17 -4
  264. package/web/.next/standalone/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.stories.tsx +2 -0
  265. package/web/.next/standalone/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.tsx +14 -1
  266. package/web/.next/standalone/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.stories.tsx +1 -0
  267. package/web/.next/standalone/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.tsx +6 -1
  268. package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.stories.tsx +1 -1
  269. package/web/.next/standalone/src/presentation/web/components/common/tech-decisions-review/tech-decisions-review.tsx +14 -1
  270. package/web/.next/standalone/src/presentation/web/components/common/theme-toggle/theme-toggle.stories.tsx +2 -0
  271. package/web/.next/standalone/src/presentation/web/components/common/theme-toggle/theme-toggle.tsx +14 -0
  272. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +2 -2
  273. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +7 -12
  274. package/web/.next/standalone/src/presentation/web/components/features/skills/category-filter.stories.tsx +57 -0
  275. package/web/.next/standalone/src/presentation/web/components/features/skills/category-filter.tsx +36 -0
  276. package/web/.next/standalone/src/presentation/web/components/features/skills/index.ts +5 -0
  277. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-card.stories.tsx +105 -0
  278. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-card.tsx +48 -0
  279. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-detail-drawer.stories.tsx +96 -0
  280. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-detail-drawer.tsx +100 -0
  281. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-list.stories.tsx +139 -0
  282. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-list.tsx +48 -0
  283. package/web/.next/standalone/src/presentation/web/components/features/skills/skills-page-client.stories.tsx +199 -0
  284. package/web/.next/standalone/src/presentation/web/components/features/skills/skills-page-client.tsx +112 -0
  285. package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +10 -1
  286. package/web/.next/standalone/src/presentation/web/hooks/use-notifications.ts +20 -19
  287. package/web/.next/standalone/src/presentation/web/hooks/use-sound-action.stories.tsx +107 -0
  288. package/web/.next/standalone/src/presentation/web/hooks/use-sound-action.ts +53 -0
  289. package/web/.next/standalone/src/presentation/web/lib/feature-flags.ts +14 -0
  290. package/web/.next/standalone/src/presentation/web/lib/skills.ts +188 -0
  291. package/web/.next/standalone/src/presentation/web/package.json +2 -0
  292. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  293. package/web/.next/static/chunks/09d898be63c54f20.js +1 -0
  294. package/web/.next/static/chunks/13664c029245afc8.js +1 -0
  295. package/web/.next/static/chunks/25f42652257ff43d.js +1 -0
  296. package/web/.next/static/chunks/2934854f0378f815.js +1 -0
  297. package/web/.next/static/chunks/2960a70537e4fd12.js +10 -0
  298. package/web/.next/static/chunks/45f510f84c7c417d.css +2 -0
  299. package/web/.next/static/chunks/79718b1f5713fdc0.js +1 -0
  300. package/web/.next/static/chunks/acdb8af5a21f1ae9.js +1 -0
  301. package/web/.next/static/chunks/{3d4dcf0be654a331.js → cb1b27e4a21415d3.js} +2 -2
  302. package/web/.next/static/chunks/d4379644a6145352.js +1 -0
  303. package/web/.next/static/chunks/{turbopack-6a11f2f1634ff6e0.js → turbopack-eb24b869babb34b4.js} +2 -2
  304. package/web/.next/trace +1 -1
  305. package/web/.next/trace-build +1 -1
  306. package/web/.next/types/link.d.ts +1 -0
  307. package/web/.next/types/routes.d.ts +2 -1
  308. package/web/.next/types/validator.ts +9 -0
  309. package/web/package.json +2 -0
  310. package/web/.next/server/chunks/ssr/[root-of-the-server]__bced1185._.js +0 -3
  311. package/web/.next/server/chunks/ssr/[root-of-the-server]__bced1185._.js.map +0 -1
  312. package/web/.next/server/chunks/ssr/[root-of-the-server]__d21f0894._.js +0 -3
  313. package/web/.next/server/chunks/ssr/[root-of-the-server]__d21f0894._.js.map +0 -1
  314. package/web/.next/server/chunks/ssr/_027596cf._.js +0 -6
  315. package/web/.next/server/chunks/ssr/_027596cf._.js.map +0 -1
  316. package/web/.next/server/chunks/ssr/_e242b954._.js +0 -3
  317. package/web/.next/server/chunks/ssr/node_modules__pnpm_d26a7485._.js.map +0 -1
  318. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +0 -3
  319. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +0 -1
  320. package/web/.next/server/chunks/ssr/src_presentation_web_components_ec3b0a65._.js +0 -3
  321. package/web/.next/server/chunks/ssr/src_presentation_web_components_ec3b0a65._.js.map +0 -1
  322. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__bced1185._.js +0 -3
  323. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__d21f0894._.js +0 -3
  324. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_027596cf._.js +0 -6
  325. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_e242b954._.js +0 -3
  326. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +0 -3
  327. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_ec3b0a65._.js +0 -3
  328. package/web/.next/static/chunks/0cd7c513169faee3.js +0 -1
  329. package/web/.next/static/chunks/4f7d89c9e09aed99.js +0 -10
  330. package/web/.next/static/chunks/67459433cc866344.js +0 -1
  331. package/web/.next/static/chunks/6d33cb9af6245c98.js +0 -1
  332. package/web/.next/static/chunks/a9c2b889c8749a94.js +0 -1
  333. package/web/.next/static/chunks/b511c65023ec1889.css +0 -2
  334. package/web/.next/static/chunks/cda11a2491d519fc.js +0 -1
  335. package/web/.next/static/chunks/d85b95e893db08bc.js +0 -1
  336. /package/web/.next/server/chunks/{[root-of-the-server]__bb619083._.js.map → [root-of-the-server]__e926de65._.js.map} +0 -0
  337. /package/web/.next/static/{xjc1tfvwTdK1Xv5Id2oaO → _DBWexyU1QkK02q15qod2}/_buildManifest.js +0 -0
  338. /package/web/.next/static/{xjc1tfvwTdK1Xv5Id2oaO → _DBWexyU1QkK02q15qod2}/_clientMiddlewareManifest.json +0 -0
  339. /package/web/.next/static/{xjc1tfvwTdK1Xv5Id2oaO → _DBWexyU1QkK02q15qod2}/_ssgManifest.js +0 -0
@@ -4,6 +4,7 @@ import { PanelLeft } from 'lucide-react';
4
4
  import { useSidebar } from '@/components/ui/sidebar';
5
5
  import { Button } from '@/components/ui/button';
6
6
  import { cn } from '@/lib/utils';
7
+ import { useSoundAction } from '@/hooks/use-sound-action';
7
8
 
8
9
  export interface SidebarCollapseToggleProps {
9
10
  className?: string;
@@ -11,8 +12,20 @@ export interface SidebarCollapseToggleProps {
11
12
 
12
13
  export function SidebarCollapseToggle({ className }: SidebarCollapseToggleProps) {
13
14
  const { toggleSidebar, open } = useSidebar();
15
+ const expandSound = useSoundAction('expand');
16
+ const collapseSound = useSoundAction('collapse');
14
17
  const label = open ? 'Collapse sidebar' : 'Expand sidebar';
15
18
 
19
+ const handleClick = () => {
20
+ // Play sound based on current state (before toggle)
21
+ if (open) {
22
+ collapseSound.play();
23
+ } else {
24
+ expandSound.play();
25
+ }
26
+ toggleSidebar();
27
+ };
28
+
16
29
  return (
17
30
  <div className={cn('flex', className)}>
18
31
  <Button
@@ -20,7 +33,7 @@ export function SidebarCollapseToggle({ className }: SidebarCollapseToggleProps)
20
33
  variant="ghost"
21
34
  size="icon"
22
35
  className="size-7 cursor-pointer group-data-[collapsible=icon]:size-8!"
23
- onClick={toggleSidebar}
36
+ onClick={handleClick}
24
37
  aria-label={label}
25
38
  >
26
39
  <PanelLeft className="size-4" />
@@ -24,6 +24,7 @@ const meta: Meta<typeof SidebarNavItem> = {
24
24
  export default meta;
25
25
  type Story = StoryObj<typeof meta>;
26
26
 
27
+ /** Default — clicking plays "navigate" sound. */
27
28
  export const Default: Story = {
28
29
  args: {
29
30
  icon: Home,
@@ -1,7 +1,10 @@
1
+ 'use client';
2
+
1
3
  import Link from 'next/link';
2
4
  import type { Route } from 'next';
3
5
  import type { LucideIcon } from 'lucide-react';
4
6
  import { SidebarMenuItem, SidebarMenuButton } from '@/components/ui/sidebar';
7
+ import { useSoundAction } from '@/hooks/use-sound-action';
5
8
 
6
9
  export interface SidebarNavItemProps {
7
10
  icon: LucideIcon;
@@ -11,10 +14,12 @@ export interface SidebarNavItemProps {
11
14
  }
12
15
 
13
16
  export function SidebarNavItem({ icon: Icon, label, href, active = false }: SidebarNavItemProps) {
17
+ const navigateSound = useSoundAction('navigate');
18
+
14
19
  return (
15
20
  <SidebarMenuItem data-testid="sidebar-nav-item">
16
21
  <SidebarMenuButton asChild isActive={active} tooltip={label}>
17
- <Link href={href as Route}>
22
+ <Link href={href as Route} onClick={() => navigateSound.play()}>
18
23
  <Icon />
19
24
  <span>{label}</span>
20
25
  </Link>
@@ -63,7 +63,7 @@ const meta: Meta<typeof TechDecisionsReview> = {
63
63
  export default meta;
64
64
  type Story = StoryObj<typeof TechDecisionsReview>;
65
65
 
66
- /** Default — scrollable list of decisions taken. */
66
+ /** Default — scrollable list of decisions taken. "Other Options Considered" toggle plays expand/collapse sounds. */
67
67
  export const Default: Story = {
68
68
  args: {
69
69
  data: mockData,
@@ -6,6 +6,7 @@ import Markdown from 'react-markdown';
6
6
  import { Check, ChevronRight, GitCompareArrows, Layers } from 'lucide-react';
7
7
  import { Badge } from '@/components/ui/badge';
8
8
  import { DrawerActionBar } from '@/components/common/drawer-action-bar';
9
+ import { useSoundAction } from '@/hooks/use-sound-action';
9
10
  import type { TechDecisionsReviewProps, TechDecision } from './tech-decisions-review-config';
10
11
 
11
12
  const markdownComponents: Components = {
@@ -46,6 +47,18 @@ const markdownComponents: Components = {
46
47
 
47
48
  function DecisionCard({ decision, index }: { decision: TechDecision; index: number }) {
48
49
  const [alternativesOpen, setAlternativesOpen] = useState(false);
50
+ const expandSound = useSoundAction('expand');
51
+ const collapseSound = useSoundAction('collapse');
52
+
53
+ const handleToggleAlternatives = () => {
54
+ // Play sound based on current state (before toggle)
55
+ if (alternativesOpen) {
56
+ collapseSound.play();
57
+ } else {
58
+ expandSound.play();
59
+ }
60
+ setAlternativesOpen((prev) => !prev);
61
+ };
49
62
 
50
63
  return (
51
64
  <div className="border-border rounded-lg border">
@@ -82,7 +95,7 @@ function DecisionCard({ decision, index }: { decision: TechDecision; index: numb
82
95
  <div className="border-border border-t">
83
96
  <button
84
97
  type="button"
85
- onClick={() => setAlternativesOpen((prev) => !prev)}
98
+ onClick={handleToggleAlternatives}
86
99
  className="text-muted-foreground hover:bg-muted/50 flex w-full items-center gap-1.5 px-4 py-3 text-xs font-medium transition-colors"
87
100
  >
88
101
  <ChevronRight
@@ -13,10 +13,12 @@ const meta: Meta<typeof ThemeToggle> = {
13
13
  export default meta;
14
14
  type Story = StoryObj<typeof meta>;
15
15
 
16
+ /** Default — click to toggle theme. Plays toggle-on (dark) or toggle-off (light) sound. */
16
17
  export const Default: Story = {
17
18
  render: () => <ThemeToggle />,
18
19
  };
19
20
 
21
+ /** In context with label. Sounds play on each toggle click. */
20
22
  export const InContext: Story = {
21
23
  render: () => (
22
24
  <div className="flex items-center gap-4 rounded-lg border p-4">
@@ -3,11 +3,25 @@
3
3
  import { Moon, Sun } from 'lucide-react';
4
4
  import { Button } from '@/components/ui/button';
5
5
  import { useTheme } from '@/hooks/useTheme';
6
+ import { useSoundAction } from '@/hooks/use-sound-action';
6
7
 
7
8
  export function ThemeToggle() {
8
9
  const { theme, resolvedTheme, setTheme } = useTheme();
10
+ const toggleOnSound = useSoundAction('toggle-on');
11
+ const toggleOffSound = useSoundAction('toggle-off');
9
12
 
10
13
  const toggleTheme = () => {
14
+ // Determine target theme before switching
15
+ const currentResolved = theme === 'system' ? resolvedTheme : theme;
16
+ const goingToDark = currentResolved !== 'dark';
17
+
18
+ // Play sound before setTheme for immediate feedback
19
+ if (goingToDark) {
20
+ toggleOnSound.play();
21
+ } else {
22
+ toggleOffSound.play();
23
+ }
24
+
11
25
  // If system theme, switch to explicit light/dark
12
26
  // If explicit, toggle between light and dark
13
27
  if (theme === 'system') {
@@ -25,7 +25,7 @@ import type { PrdQuestionnaireData } from '@/components/common/prd-questionnaire
25
25
  import { TechDecisionsDrawer } from '@/components/common/tech-decisions-review';
26
26
  import { MergeReviewDrawer } from '@/components/common/merge-review';
27
27
  import { NotificationPermissionBanner } from '@/components/common/notification-permission-banner';
28
- import { useSound } from '@/hooks/use-sound';
28
+ import { useSoundAction } from '@/hooks/use-sound-action';
29
29
  import { ControlCenterEmptyState } from './control-center-empty-state';
30
30
  import { useControlCenterState } from './use-control-center-state';
31
31
 
@@ -88,7 +88,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
88
88
 
89
89
  // Reject state (shared by both drawers)
90
90
  const [isRejecting, setIsRejecting] = useState(false);
91
- const rejectSound = useSound('caution', { volume: 0.5 });
91
+ const rejectSound = useSoundAction('reject');
92
92
 
93
93
  // Tech decisions drawer state
94
94
  const [techDecisionsData, setTechDecisionsData] = useState<TechDecisionsReviewData | null>(null);
@@ -14,7 +14,7 @@ import { deleteFeature } from '@/app/actions/delete-feature';
14
14
  import { addRepository } from '@/app/actions/add-repository';
15
15
  import { deleteRepository } from '@/app/actions/delete-repository';
16
16
  import { useAgentEventsContext } from '@/hooks/agent-events-provider';
17
- import { useSound } from '@/hooks/use-sound';
17
+ import { useSoundAction } from '@/hooks/use-sound-action';
18
18
  import {
19
19
  mapEventTypeToState,
20
20
  mapPhaseNameToLifecycle,
@@ -73,9 +73,9 @@ export function useControlCenterState(
73
73
  const [selectedNode, setSelectedNode] = useState<FeatureNodeData | null>(null);
74
74
  const [isCreateDrawerOpen, setIsCreateDrawerOpen] = useState(false);
75
75
  const [isDeleting, setIsDeleting] = useState(false);
76
- const deleteSound = useSound('transition_down', { volume: 0.5 });
77
- const createSound = useSound('transition_up', { volume: 0.5 });
78
- const clickSound = useSound('tap_01', { volume: 0.3 });
76
+ const deleteSound = useSoundAction('delete');
77
+ const createSound = useSoundAction('create');
78
+ const clickSound = useSoundAction('click');
79
79
  const [pendingRepoNodeId, setPendingRepoNodeId] = useState<string | null>(null);
80
80
 
81
81
  // Sync server props into local state when router.refresh() delivers new data
@@ -262,13 +262,9 @@ export function useControlCenterState(
262
262
  setNodes((ns) => applyNodeChanges(changes, ns));
263
263
  }, []);
264
264
 
265
- const closeSound = useSound('transition_down', { volume: 0.01 });
266
265
  const clearSelection = useCallback(() => {
267
- setSelectedNode((prev) => {
268
- if (prev) closeSound.play();
269
- return null;
270
- });
271
- }, [closeSound]);
266
+ setSelectedNode(null);
267
+ }, []);
272
268
 
273
269
  const handleNodeClick = useCallback(
274
270
  (_event: React.MouseEvent, node: CanvasNodeType) => {
@@ -509,10 +505,9 @@ export function useControlCenterState(
509
505
  );
510
506
 
511
507
  const closeCreateDrawer = useCallback(() => {
512
- closeSound.play();
513
508
  setIsCreateDrawerOpen(false);
514
509
  setPendingParentFeatureId(undefined);
515
- }, [closeSound]);
510
+ }, []);
516
511
 
517
512
  const handleDeleteFeature = useCallback(
518
513
  async (featureId: string) => {
@@ -0,0 +1,57 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { CategoryFilter } from './category-filter';
4
+ import type { SkillCategory } from '@/lib/skills';
5
+
6
+ const meta: Meta<typeof CategoryFilter> = {
7
+ title: 'Features/CategoryFilter',
8
+ component: CategoryFilter,
9
+ tags: ['autodocs'],
10
+ parameters: {
11
+ layout: 'padded',
12
+ },
13
+ };
14
+
15
+ export default meta;
16
+ type Story = StoryObj<typeof CategoryFilter>;
17
+
18
+ /* ---------------------------------------------------------------------------
19
+ * Interactive wrapper — manages activeCategory state
20
+ * ------------------------------------------------------------------------- */
21
+
22
+ function InteractiveCategoryFilter({
23
+ initial,
24
+ counts,
25
+ }: {
26
+ initial: SkillCategory | null;
27
+ counts?: Record<SkillCategory, number>;
28
+ }) {
29
+ const [active, setActive] = useState<SkillCategory | null>(initial);
30
+ return <CategoryFilter activeCategory={active} onCategoryChange={setActive} counts={counts} />;
31
+ }
32
+
33
+ /* ---------------------------------------------------------------------------
34
+ * Stories
35
+ * ------------------------------------------------------------------------- */
36
+
37
+ export const AllSelected: Story = {
38
+ render: () => <InteractiveCategoryFilter initial={null} />,
39
+ };
40
+
41
+ export const WorkflowSelected: Story = {
42
+ render: () => <InteractiveCategoryFilter initial="Workflow" />,
43
+ };
44
+
45
+ export const WithCounts: Story = {
46
+ render: () => (
47
+ <InteractiveCategoryFilter
48
+ initial={null}
49
+ counts={{
50
+ Workflow: 8,
51
+ 'Code Generation': 1,
52
+ Analysis: 2,
53
+ Reference: 7,
54
+ }}
55
+ />
56
+ ),
57
+ };
@@ -0,0 +1,36 @@
1
+ import { Button } from '@/components/ui/button';
2
+ import type { SkillCategory } from '@/lib/skills';
3
+
4
+ const CATEGORIES: { label: string; value: SkillCategory | null }[] = [
5
+ { label: 'All', value: null },
6
+ { label: 'Workflow', value: 'Workflow' },
7
+ { label: 'Code Generation', value: 'Code Generation' },
8
+ { label: 'Analysis', value: 'Analysis' },
9
+ { label: 'Reference', value: 'Reference' },
10
+ ];
11
+
12
+ export interface CategoryFilterProps {
13
+ activeCategory: SkillCategory | null;
14
+ onCategoryChange: (category: SkillCategory | null) => void;
15
+ counts?: Record<SkillCategory, number>;
16
+ }
17
+
18
+ export function CategoryFilter({ activeCategory, onCategoryChange, counts }: CategoryFilterProps) {
19
+ return (
20
+ <div className="flex flex-wrap gap-2" role="group" aria-label="Filter by category">
21
+ {CATEGORIES.map(({ label, value }) => (
22
+ <Button
23
+ key={label}
24
+ variant={activeCategory === value ? 'default' : 'outline'}
25
+ size="sm"
26
+ onClick={() => onCategoryChange(value)}
27
+ >
28
+ {label}
29
+ {counts && value ? (
30
+ <span className="ml-1 text-xs opacity-70">({counts[value]})</span>
31
+ ) : null}
32
+ </Button>
33
+ ))}
34
+ </div>
35
+ );
36
+ }
@@ -0,0 +1,5 @@
1
+ export { SkillsPageClient, type SkillsPageClientProps } from './skills-page-client';
2
+ export { SkillCard, type SkillCardProps } from './skill-card';
3
+ export { CategoryFilter, type CategoryFilterProps } from './category-filter';
4
+ export { SkillList, type SkillListProps } from './skill-list';
5
+ export { SkillDetailDrawer, type SkillDetailDrawerProps } from './skill-detail-drawer';
@@ -0,0 +1,105 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { fn } from '@storybook/test';
3
+ import { SkillCard } from './skill-card';
4
+ import type { SkillData } from '@/lib/skills';
5
+
6
+ const meta: Meta<typeof SkillCard> = {
7
+ title: 'Features/SkillCard',
8
+ component: SkillCard,
9
+ tags: ['autodocs'],
10
+ parameters: {
11
+ layout: 'centered',
12
+ },
13
+ args: {
14
+ onSelect: fn(),
15
+ },
16
+ };
17
+
18
+ export default meta;
19
+ type Story = StoryObj<typeof meta>;
20
+
21
+ /* ---------------------------------------------------------------------------
22
+ * Data fixtures
23
+ * ------------------------------------------------------------------------- */
24
+
25
+ const baseSkill: SkillData = {
26
+ name: 'shep-kit:implement',
27
+ displayName: 'implement',
28
+ description: 'Validate specs and autonomously execute implementation tasks with status tracking.',
29
+ category: 'Workflow',
30
+ source: 'project',
31
+ body: '## Usage\n\nRun /shep-kit:implement after planning is complete.',
32
+ resources: [],
33
+ };
34
+
35
+ const skillWithAllBadges: SkillData = {
36
+ name: 'shep:ui-component',
37
+ displayName: 'ui-component',
38
+ description:
39
+ 'Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI".',
40
+ context: 'fork',
41
+ allowedTools: 'Read, Write, Bash, Edit, Glob',
42
+ category: 'Code Generation',
43
+ source: 'project',
44
+ body: '## Overview\n\nScaffolds UI components following the four-tier hierarchy.',
45
+ resources: [
46
+ { name: 'references', fileCount: 7 },
47
+ { name: 'templates', fileCount: 3 },
48
+ { name: 'rules', fileCount: 2 },
49
+ ],
50
+ };
51
+
52
+ const globalSkill: SkillData = {
53
+ name: 'vercel-react-best-practices',
54
+ displayName: 'vercel-react-best-practices',
55
+ description: 'React and Next.js performance optimization guidelines from Vercel Engineering.',
56
+ category: 'Reference',
57
+ source: 'global',
58
+ body: 'Performance patterns for React and Next.js applications.',
59
+ resources: [{ name: 'references', fileCount: 4 }],
60
+ };
61
+
62
+ const skillWithContext: SkillData = {
63
+ name: 'architecture-reviewer',
64
+ displayName: 'architecture-reviewer',
65
+ description: 'Use when making architectural decisions, planning features, or reviewing PRs.',
66
+ context: 'fork',
67
+ category: 'Analysis',
68
+ source: 'project',
69
+ body: '',
70
+ resources: [],
71
+ };
72
+
73
+ /* ---------------------------------------------------------------------------
74
+ * Stories
75
+ * ------------------------------------------------------------------------- */
76
+
77
+ export const Default: Story = {
78
+ args: {
79
+ skill: baseSkill,
80
+ },
81
+ };
82
+
83
+ export const WithContext: Story = {
84
+ args: {
85
+ skill: skillWithContext,
86
+ },
87
+ };
88
+
89
+ export const WithAllBadges: Story = {
90
+ args: {
91
+ skill: skillWithAllBadges,
92
+ },
93
+ };
94
+
95
+ export const ProjectSource: Story = {
96
+ args: {
97
+ skill: baseSkill,
98
+ },
99
+ };
100
+
101
+ export const GlobalSource: Story = {
102
+ args: {
103
+ skill: globalSkill,
104
+ },
105
+ };
@@ -0,0 +1,48 @@
1
+ import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
2
+ import { Badge } from '@/components/ui/badge';
3
+ import type { SkillData } from '@/lib/skills';
4
+ import { FolderOpen } from 'lucide-react';
5
+
6
+ export interface SkillCardProps {
7
+ skill: SkillData;
8
+ onSelect: (skill: SkillData) => void;
9
+ }
10
+
11
+ export function SkillCard({ skill, onSelect }: SkillCardProps) {
12
+ return (
13
+ <Card
14
+ className="hover:border-primary/50 cursor-pointer transition-colors"
15
+ role="button"
16
+ tabIndex={0}
17
+ onClick={() => onSelect(skill)}
18
+ onKeyDown={(e) => {
19
+ if (e.key === 'Enter' || e.key === ' ') {
20
+ e.preventDefault();
21
+ onSelect(skill);
22
+ }
23
+ }}
24
+ data-testid={`skill-card-${skill.name}`}
25
+ >
26
+ <CardHeader className="pb-3">
27
+ <CardTitle className="text-base">{skill.displayName}</CardTitle>
28
+ <p className="text-muted-foreground font-mono text-xs">{skill.name}</p>
29
+ </CardHeader>
30
+ <CardContent className="space-y-3">
31
+ <p className="text-muted-foreground line-clamp-2 text-sm">{skill.description}</p>
32
+ <div className="flex flex-wrap items-center gap-1.5">
33
+ <Badge variant={skill.source === 'project' ? 'secondary' : 'outline'}>
34
+ {skill.source === 'project' ? 'Project' : 'Global'}
35
+ </Badge>
36
+ {skill.context ? <Badge variant="outline">{skill.context}</Badge> : null}
37
+ {skill.allowedTools ? <Badge variant="outline">Tools</Badge> : null}
38
+ {skill.resources.length > 0 ? (
39
+ <span className="text-muted-foreground inline-flex items-center gap-1 text-xs">
40
+ <FolderOpen className="size-3" />
41
+ {skill.resources.length} {skill.resources.length === 1 ? 'resource' : 'resources'}
42
+ </span>
43
+ ) : null}
44
+ </div>
45
+ </CardContent>
46
+ </Card>
47
+ );
48
+ }
@@ -0,0 +1,96 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { SkillDetailDrawer } from './skill-detail-drawer';
4
+ import { Button } from '@/components/ui/button';
5
+ import type { SkillData } from '@/lib/skills';
6
+
7
+ const meta: Meta<typeof SkillDetailDrawer> = {
8
+ title: 'Features/SkillDetailDrawer',
9
+ component: SkillDetailDrawer,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof SkillDetailDrawer>;
18
+
19
+ /* ---------------------------------------------------------------------------
20
+ * Data fixtures
21
+ * ------------------------------------------------------------------------- */
22
+
23
+ const skillWithResources: SkillData = {
24
+ name: 'shep:ui-component',
25
+ displayName: 'ui-component',
26
+ description:
27
+ 'Use when creating, modifying, or reviewing web UI components. Triggers include "new component", "add component", "create UI", "build a widget".',
28
+ context: 'fork',
29
+ allowedTools: 'Read, Write, Bash, Edit, Glob, Grep',
30
+ category: 'Code Generation',
31
+ source: 'project',
32
+ body: '## Overview\n\nScaffolds UI components following the four-tier hierarchy.\n\n## Usage\n\nRun /shep:ui-component when you need to create or modify components.',
33
+ resources: [
34
+ { name: 'references', fileCount: 7 },
35
+ { name: 'templates', fileCount: 3 },
36
+ { name: 'rules', fileCount: 2 },
37
+ ],
38
+ };
39
+
40
+ const skillWithoutResources: SkillData = {
41
+ name: 'shep-kit:implement',
42
+ displayName: 'implement',
43
+ description:
44
+ 'Validate specs and autonomously execute implementation tasks with status tracking. Use after /shep-kit:plan when ready to start implementation.',
45
+ category: 'Workflow',
46
+ source: 'project',
47
+ body: '## Usage\n\nRun /shep-kit:implement after planning is complete to start autonomous implementation.\n\n## What it does\n\n1. Pre-Implementation Validation Gate\n2. Autonomous Execution\n3. Status Tracking',
48
+ resources: [],
49
+ };
50
+
51
+ const minimalSkill: SkillData = {
52
+ name: 'find-skills',
53
+ displayName: 'find-skills',
54
+ description: 'Helps users discover and install agent skills.',
55
+ category: 'Reference',
56
+ source: 'global',
57
+ body: '',
58
+ resources: [],
59
+ };
60
+
61
+ /* ---------------------------------------------------------------------------
62
+ * Trigger wrapper — starts closed, click to open
63
+ * ------------------------------------------------------------------------- */
64
+
65
+ function DrawerTrigger({ skill, label }: { skill: SkillData; label: string }) {
66
+ const [selected, setSelected] = useState<SkillData | null>(null);
67
+
68
+ return (
69
+ <div className="flex h-screen items-start p-4">
70
+ <Button variant="outline" onClick={() => setSelected(skill)}>
71
+ {label}
72
+ </Button>
73
+ <SkillDetailDrawer skill={selected} onClose={() => setSelected(null)} />
74
+ </div>
75
+ );
76
+ }
77
+
78
+ /* ---------------------------------------------------------------------------
79
+ * Stories
80
+ * ------------------------------------------------------------------------- */
81
+
82
+ export const Open: Story = {
83
+ render: () => <DrawerTrigger skill={skillWithResources} label="Open Skill Detail" />,
84
+ };
85
+
86
+ export const WithResources: Story = {
87
+ render: () => <DrawerTrigger skill={skillWithResources} label="Open With Resources" />,
88
+ };
89
+
90
+ export const WithoutResources: Story = {
91
+ render: () => <DrawerTrigger skill={skillWithoutResources} label="Open Without Resources" />,
92
+ };
93
+
94
+ export const MinimalSkill: Story = {
95
+ render: () => <DrawerTrigger skill={minimalSkill} label="Open Minimal Skill" />,
96
+ };