@shepai/cli 1.61.0 → 1.63.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 (201) hide show
  1. package/dist/packages/core/src/infrastructure/services/pr-sync/pr-sync-watcher.service.js +1 -1
  2. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts +17 -0
  3. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -0
  4. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +23 -0
  5. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts +22 -0
  6. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.d.ts.map +1 -0
  7. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.stories.js +56 -0
  8. package/dist/src/presentation/web/components/common/base-drawer/index.d.ts +2 -0
  9. package/dist/src/presentation/web/components/common/base-drawer/index.d.ts.map +1 -0
  10. package/dist/src/presentation/web/components/common/base-drawer/index.js +1 -0
  11. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  12. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +11 -16
  13. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +1 -1
  14. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +1 -1
  15. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/feature-drawer/feature-drawer.js +14 -14
  17. package/dist/src/presentation/web/components/common/repository-node/index.d.ts +1 -0
  18. package/dist/src/presentation/web/components/common/repository-node/index.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/repository-node/index.js +1 -0
  20. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts +7 -0
  21. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.d.ts.map +1 -0
  22. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.js +12 -0
  23. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts +9 -0
  24. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -0
  25. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js +34 -0
  26. package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.js +4 -6
  28. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +20 -2
  30. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts +3 -1
  31. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  32. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +4 -2
  33. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.d.ts.map +1 -1
  34. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.js +3 -6
  35. package/dist/tsconfig.build.tsbuildinfo +1 -1
  36. package/package.json +1 -1
  37. package/web/.next/BUILD_ID +1 -1
  38. package/web/.next/build-manifest.json +2 -2
  39. package/web/.next/cache/.previewinfo +1 -1
  40. package/web/.next/cache/.rscinfo +1 -1
  41. package/web/.next/cache/.tsbuildinfo +1 -1
  42. package/web/.next/cache/config.json +3 -3
  43. package/web/.next/fallback-build-manifest.json +2 -2
  44. package/web/.next/prerender-manifest.json +3 -3
  45. package/web/.next/required-server-files.js +1 -1
  46. package/web/.next/required-server-files.json +1 -1
  47. package/web/.next/server/app/_global-error.html +2 -2
  48. package/web/.next/server/app/_global-error.rsc +1 -1
  49. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  50. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  51. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  52. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  53. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  54. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  55. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  56. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  57. package/web/.next/server/app/page/server-reference-manifest.json +14 -14
  58. package/web/.next/server/app/page.js.nft.json +1 -1
  59. package/web/.next/server/app/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
  61. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  62. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  63. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  64. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  65. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  66. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  67. package/web/.next/server/app/version/page.js.nft.json +1 -1
  68. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  69. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  70. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  71. package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +3 -0
  72. package/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js.map +1 -0
  73. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  74. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  75. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  76. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  77. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  78. package/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js.map +1 -1
  79. package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +3 -0
  80. package/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js.map +1 -0
  81. package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
  82. package/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js.map +1 -1
  83. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
  84. package/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js.map +1 -1
  85. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js +3 -0
  86. package/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js.map +1 -0
  87. package/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
  88. package/web/.next/server/chunks/ssr/_73d14b70._.js +3 -0
  89. package/web/.next/server/chunks/ssr/_73d14b70._.js.map +1 -0
  90. package/web/.next/server/chunks/ssr/_7f386377._.js +3 -0
  91. package/web/.next/server/chunks/ssr/_7f386377._.js.map +1 -0
  92. package/web/.next/server/chunks/ssr/_d3711354._.js +2 -2
  93. package/web/.next/server/chunks/ssr/_d3711354._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/{_a64b7b24._.js → _d81184e2._.js} +2 -2
  95. package/web/.next/server/chunks/ssr/_d81184e2._.js.map +1 -0
  96. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_fe355030._.js → server/chunks/ssr/node_modules__pnpm_87f920e7._.js} +2 -2
  97. package/web/.next/server/chunks/ssr/{node_modules__pnpm_fe355030._.js.map → node_modules__pnpm_87f920e7._.js.map} +1 -1
  98. package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +3 -0
  99. package/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js.map +1 -0
  100. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +3 -0
  101. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -0
  102. package/web/.next/server/pages/500.html +2 -2
  103. package/web/.next/server/server-reference-manifest.js +1 -1
  104. package/web/.next/server/server-reference-manifest.json +15 -15
  105. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  106. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  107. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  108. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  109. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  110. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  111. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  112. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  113. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  114. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  115. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  116. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  117. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  118. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  119. package/web/.next/standalone/src/presentation/web/.next/server/app/page/server-reference-manifest.json +14 -14
  120. package/web/.next/standalone/src/presentation/web/.next/server/app/page.js.nft.json +1 -1
  121. package/web/.next/standalone/src/presentation/web/.next/server/app/page_client-reference-manifest.js +1 -1
  122. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +1 -1
  123. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  124. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  125. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  126. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  127. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  128. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  129. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  130. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  131. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  132. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__5e0f14e9._.js +3 -0
  133. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  134. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  135. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__9add7c3a._.js +4 -4
  136. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ae251147._.js +3 -0
  137. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__b6839c3f._.js +2 -2
  138. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__da0ade1f._.js +1 -1
  139. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__dd5b62cb._.js +3 -0
  140. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__fbc89707._.js +1 -1
  141. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_73d14b70._.js +3 -0
  142. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_7f386377._.js +3 -0
  143. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_d3711354._.js +2 -2
  144. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/{_a64b7b24._.js → _d81184e2._.js} +2 -2
  145. package/web/.next/{server/chunks/ssr/node_modules__pnpm_fe355030._.js → standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_87f920e7._.js} +2 -2
  146. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_7a0b09da._.js +3 -0
  147. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +3 -0
  148. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  149. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  150. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +15 -15
  151. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.stories.tsx +207 -0
  152. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +90 -0
  153. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/index.ts +1 -0
  154. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +1 -1
  155. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +145 -172
  156. package/web/.next/standalone/src/presentation/web/components/common/feature-drawer/feature-drawer.tsx +119 -133
  157. package/web/.next/standalone/src/presentation/web/components/common/repository-node/index.ts +1 -0
  158. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.stories.tsx +58 -0
  159. package/web/.next/standalone/src/presentation/web/components/common/repository-node/repository-drawer.tsx +82 -0
  160. package/web/.next/standalone/src/presentation/web/components/common/review-drawer-shell/review-drawer-shell.tsx +79 -96
  161. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +30 -2
  162. package/web/.next/standalone/src/presentation/web/components/features/features-canvas/features-canvas.tsx +7 -0
  163. package/web/.next/standalone/src/presentation/web/components/features/skills/skill-detail-drawer.tsx +71 -77
  164. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  165. package/web/.next/static/chunks/0c6654ec27f11c7e.js +1 -0
  166. package/web/.next/static/chunks/12c70bfd5951cf9b.js +1 -0
  167. package/web/.next/static/chunks/21541b346dd4dd28.js +1 -0
  168. package/web/.next/static/chunks/{cb1b27e4a21415d3.js → 3b941e59ac013e12.js} +2 -2
  169. package/web/.next/static/chunks/426292e5fb0b2a61.js +1 -0
  170. package/web/.next/static/chunks/{09d898be63c54f20.js → 78919481e7c5ad4f.js} +1 -1
  171. package/web/.next/static/chunks/a5b6a22de303e877.css +2 -0
  172. package/web/.next/static/chunks/af7a5bcb7c49e46e.js +1 -0
  173. package/web/.next/static/chunks/be784143669bb992.js +1 -0
  174. package/web/.next/static/chunks/ea57f9afe9055c7a.js +10 -0
  175. package/web/.next/trace +1 -1
  176. package/web/.next/trace-build +1 -1
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +0 -3
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js.map +0 -1
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +0 -3
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js.map +0 -1
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +0 -3
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js.map +0 -1
  183. package/web/.next/server/chunks/ssr/_9915d2a7._.js +0 -3
  184. package/web/.next/server/chunks/ssr/_9915d2a7._.js.map +0 -1
  185. package/web/.next/server/chunks/ssr/_a64b7b24._.js.map +0 -1
  186. package/web/.next/server/chunks/ssr/_e7a4b0e4._.js +0 -3
  187. package/web/.next/server/chunks/ssr/_e7a4b0e4._.js.map +0 -1
  188. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__2395adc6._.js +0 -3
  189. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__87fda958._.js +0 -3
  190. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__ee7cffe1._.js +0 -3
  191. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_9915d2a7._.js +0 -3
  192. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_e7a4b0e4._.js +0 -3
  193. package/web/.next/static/chunks/13664c029245afc8.js +0 -1
  194. package/web/.next/static/chunks/25f42652257ff43d.js +0 -1
  195. package/web/.next/static/chunks/2934854f0378f815.js +0 -1
  196. package/web/.next/static/chunks/2960a70537e4fd12.js +0 -10
  197. package/web/.next/static/chunks/45f510f84c7c417d.css +0 -2
  198. package/web/.next/static/chunks/79718b1f5713fdc0.js +0 -1
  199. /package/web/.next/static/{_DBWexyU1QkK02q15qod2 → 23Y-ea-5g4_fUHZyGpCb0}/_buildManifest.js +0 -0
  200. /package/web/.next/static/{_DBWexyU1QkK02q15qod2 → 23Y-ea-5g4_fUHZyGpCb0}/_clientMiddlewareManifest.json +0 -0
  201. /package/web/.next/static/{_DBWexyU1QkK02q15qod2 → 23Y-ea-5g4_fUHZyGpCb0}/_ssgManifest.js +0 -0
@@ -0,0 +1,207 @@
1
+ import { useState } from 'react';
2
+ import type { Meta, StoryObj } from '@storybook/react';
3
+ import { BaseDrawer } from './base-drawer';
4
+ import { DrawerTitle, DrawerDescription } from '@/components/ui/drawer';
5
+ import { Button } from '@/components/ui/button';
6
+
7
+ const meta: Meta<typeof BaseDrawer> = {
8
+ title: 'Common/BaseDrawer',
9
+ component: BaseDrawer,
10
+ tags: ['autodocs'],
11
+ parameters: {
12
+ layout: 'fullscreen',
13
+ },
14
+ };
15
+
16
+ export default meta;
17
+ type Story = StoryObj<typeof BaseDrawer>;
18
+
19
+ /* ---------------------------------------------------------------------------
20
+ * Trigger wrapper — starts closed, click to open
21
+ * ------------------------------------------------------------------------- */
22
+
23
+ function DrawerTrigger(props: Omit<React.ComponentProps<typeof BaseDrawer>, 'open' | 'onClose'>) {
24
+ const [open, setOpen] = useState(false);
25
+
26
+ return (
27
+ <div className="flex h-screen items-start p-4">
28
+ <Button variant="outline" onClick={() => setOpen(true)}>
29
+ Open Drawer
30
+ </Button>
31
+ <BaseDrawer {...props} open={open} onClose={() => setOpen(false)} />
32
+ </div>
33
+ );
34
+ }
35
+
36
+ /* ---------------------------------------------------------------------------
37
+ * Stories
38
+ * ------------------------------------------------------------------------- */
39
+
40
+ /** Default drawer with sm size, non-modal, children only. */
41
+ export const Default: Story = {
42
+ render: () => (
43
+ <DrawerTrigger>
44
+ <div className="p-4">
45
+ <p className="text-muted-foreground text-sm">Default drawer content</p>
46
+ </div>
47
+ </DrawerTrigger>
48
+ ),
49
+ };
50
+
51
+ /** Explicit sm size with inspector-style content. */
52
+ export const SmallSize: Story = {
53
+ render: () => (
54
+ <DrawerTrigger size="sm">
55
+ <div className="flex flex-col gap-3 p-4">
56
+ <h3 className="text-sm font-semibold">Feature Inspector</h3>
57
+ <div className="flex flex-col gap-1">
58
+ <span className="text-muted-foreground text-xs">Status</span>
59
+ <span className="text-sm">Running</span>
60
+ </div>
61
+ <div className="flex flex-col gap-1">
62
+ <span className="text-muted-foreground text-xs">Progress</span>
63
+ <div className="bg-muted h-2 w-full overflow-hidden rounded-full">
64
+ <div className="bg-primary h-full w-[45%] rounded-full" />
65
+ </div>
66
+ </div>
67
+ </div>
68
+ </DrawerTrigger>
69
+ ),
70
+ };
71
+
72
+ /** Medium size with content-rich review-style content. */
73
+ export const MediumSize: Story = {
74
+ render: () => (
75
+ <DrawerTrigger size="md">
76
+ <div className="flex flex-col gap-4 p-4">
77
+ <h3 className="text-sm font-semibold">Review Content</h3>
78
+ <p className="text-muted-foreground text-sm">
79
+ This drawer uses size=&quot;md&quot; (w-xl / 576px) for content-rich review panels that
80
+ need more horizontal space for diff summaries, tables, and code blocks.
81
+ </p>
82
+ <div className="bg-muted rounded-md p-3">
83
+ <pre className="text-xs">
84
+ {`+ Added authentication middleware\n- Removed legacy session handler\n Updated user model schema`}
85
+ </pre>
86
+ </div>
87
+ </div>
88
+ </DrawerTrigger>
89
+ ),
90
+ };
91
+
92
+ /** Modal drawer with overlay. */
93
+ export const Modal: Story = {
94
+ render: () => (
95
+ <DrawerTrigger modal>
96
+ <div className="p-4">
97
+ <p className="text-muted-foreground text-sm">
98
+ This drawer is modal — an overlay blocks background interaction and focus is trapped.
99
+ </p>
100
+ </div>
101
+ </DrawerTrigger>
102
+ ),
103
+ };
104
+
105
+ /** Drawer with header slot containing DrawerTitle and DrawerDescription. */
106
+ export const WithHeader: Story = {
107
+ render: () => (
108
+ <DrawerTrigger
109
+ header={
110
+ <>
111
+ <DrawerTitle>Feature Details</DrawerTitle>
112
+ <DrawerDescription>FEAT-042 — Authentication Flow</DrawerDescription>
113
+ </>
114
+ }
115
+ >
116
+ <div className="p-4">
117
+ <p className="text-muted-foreground text-sm">Content below the header.</p>
118
+ </div>
119
+ </DrawerTrigger>
120
+ ),
121
+ };
122
+
123
+ /** Drawer with footer slot containing action buttons. */
124
+ export const WithFooter: Story = {
125
+ render: () => (
126
+ <DrawerTrigger
127
+ footer={
128
+ <div className="flex gap-2">
129
+ <Button variant="outline" className="flex-1">
130
+ Cancel
131
+ </Button>
132
+ <Button className="flex-1">Save</Button>
133
+ </div>
134
+ }
135
+ >
136
+ <div className="p-4">
137
+ <p className="text-muted-foreground text-sm">Content above the footer.</p>
138
+ </div>
139
+ </DrawerTrigger>
140
+ ),
141
+ };
142
+
143
+ /** Drawer with both header and footer slots populated. */
144
+ export const WithHeaderAndFooter: Story = {
145
+ render: () => (
146
+ <DrawerTrigger
147
+ header={
148
+ <>
149
+ <DrawerTitle>Create Feature</DrawerTitle>
150
+ <DrawerDescription>Fill in the details below</DrawerDescription>
151
+ </>
152
+ }
153
+ footer={
154
+ <div className="flex gap-2">
155
+ <Button variant="outline" className="flex-1">
156
+ Cancel
157
+ </Button>
158
+ <Button className="flex-1">Create</Button>
159
+ </div>
160
+ }
161
+ >
162
+ <div className="flex flex-col gap-4 p-4">
163
+ <div className="flex flex-col gap-1">
164
+ <label className="text-sm font-medium">Name</label>
165
+ <input
166
+ type="text"
167
+ className="border-input bg-background rounded-md border px-3 py-2 text-sm"
168
+ placeholder="Feature name"
169
+ />
170
+ </div>
171
+ <div className="flex flex-col gap-1">
172
+ <label className="text-sm font-medium">Description</label>
173
+ <textarea
174
+ className="border-input bg-background rounded-md border px-3 py-2 text-sm"
175
+ rows={3}
176
+ placeholder="Optional description"
177
+ />
178
+ </div>
179
+ </div>
180
+ </DrawerTrigger>
181
+ ),
182
+ };
183
+
184
+ /** Drawer with content that exceeds viewport to demonstrate scroll behavior. */
185
+ export const ScrollableContent: Story = {
186
+ render: () => (
187
+ <DrawerTrigger
188
+ header={
189
+ <>
190
+ <DrawerTitle>Scrollable Content</DrawerTitle>
191
+ <DrawerDescription>Content below overflows and scrolls</DrawerDescription>
192
+ </>
193
+ }
194
+ >
195
+ <div className="flex flex-col gap-4 p-4">
196
+ {Array.from({ length: 30 }, (_, i) => (
197
+ <div key={i} className="border-border rounded-md border p-3">
198
+ <h4 className="text-sm font-medium">Item {i + 1}</h4>
199
+ <p className="text-muted-foreground text-xs">
200
+ This is a scrollable content item to demonstrate overflow handling.
201
+ </p>
202
+ </div>
203
+ ))}
204
+ </div>
205
+ </DrawerTrigger>
206
+ ),
207
+ };
@@ -0,0 +1,90 @@
1
+ 'use client';
2
+
3
+ import { XIcon } from 'lucide-react';
4
+ import { cva, type VariantProps } from 'class-variance-authority';
5
+ import { cn } from '@/lib/utils';
6
+ import {
7
+ Drawer,
8
+ DrawerContent,
9
+ DrawerHeader,
10
+ DrawerFooter,
11
+ DrawerOverlay,
12
+ } from '@/components/ui/drawer';
13
+
14
+ const drawerVariants = cva('', {
15
+ variants: {
16
+ size: {
17
+ sm: 'w-96',
18
+ md: 'w-xl',
19
+ },
20
+ },
21
+ defaultVariants: {
22
+ size: 'sm',
23
+ },
24
+ });
25
+
26
+ export interface BaseDrawerProps extends VariantProps<typeof drawerVariants> {
27
+ open: boolean;
28
+ onClose: () => void;
29
+ modal?: boolean;
30
+ header?: React.ReactNode;
31
+ children: React.ReactNode;
32
+ footer?: React.ReactNode;
33
+ className?: string;
34
+ 'data-testid'?: string;
35
+ }
36
+
37
+ export function BaseDrawer({
38
+ open,
39
+ onClose,
40
+ modal = false,
41
+ size,
42
+ header,
43
+ children,
44
+ footer,
45
+ className,
46
+ 'data-testid': testId,
47
+ }: BaseDrawerProps) {
48
+ return (
49
+ <Drawer
50
+ direction="right"
51
+ modal={modal}
52
+ handleOnly
53
+ open={open}
54
+ onOpenChange={(isOpen) => {
55
+ if (!isOpen) onClose();
56
+ }}
57
+ >
58
+ {modal ? <DrawerOverlay /> : null}
59
+ <DrawerContent
60
+ direction="right"
61
+ showCloseButton={false}
62
+ className={cn(drawerVariants({ size }), className)}
63
+ data-testid={testId}
64
+ >
65
+ {/* Close button */}
66
+ <button
67
+ type="button"
68
+ aria-label="Close"
69
+ onClick={onClose}
70
+ className="ring-offset-background focus:ring-ring absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden"
71
+ data-testid={testId ? `${testId}-close-button` : undefined}
72
+ >
73
+ <XIcon className="size-4" />
74
+ <span className="sr-only">Close</span>
75
+ </button>
76
+
77
+ {/* Header slot */}
78
+ {header ? <DrawerHeader>{header}</DrawerHeader> : null}
79
+
80
+ {/* Scrollable content area */}
81
+ <div className="flex-1 overflow-y-auto">
82
+ <div className="flex flex-col">{children}</div>
83
+ </div>
84
+
85
+ {/* Footer slot */}
86
+ {footer ? <DrawerFooter>{footer}</DrawerFooter> : null}
87
+ </DrawerContent>
88
+ </Drawer>
89
+ );
90
+ }
@@ -0,0 +1 @@
1
+ export { BaseDrawer, type BaseDrawerProps } from './base-drawer';
@@ -36,7 +36,7 @@ import { Button } from '@/components/ui/button';
36
36
  * - Submit button is disabled when name is empty
37
37
  * - `approvalGates` always included: `{ allowPrd, allowPlan, allowMerge }` (all false by default)
38
38
  * - Non-modal (`modal={false}`) — canvas stays interactive behind the drawer
39
- * - Fixed width: 384px (`w-96`)
39
+ * - Fixed width: 448px (`w-xl`) — matches review drawers (PRD, Plan, Merge)
40
40
  * - Attachments use native OS file picker via `pickFiles()` — returns `FileAttachment[]`
41
41
  * with full absolute paths, filenames, and sizes
42
42
  */