@shepai/cli 1.72.3 → 1.72.5

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 (268) hide show
  1. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  2. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +1 -1
  3. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.d.ts.map +1 -1
  4. package/dist/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.js +4 -0
  5. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  6. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +36 -6
  7. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts +4 -0
  8. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.d.ts.map +1 -1
  9. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts +1 -1
  10. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.d.ts.map +1 -1
  11. package/dist/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.js +4 -2
  12. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  13. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +6 -5
  14. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +5 -0
  15. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +24 -0
  17. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts +4 -0
  18. package/dist/src/presentation/web/components/common/merge-review/merge-review-config.d.ts.map +1 -1
  19. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts +1 -1
  20. package/dist/src/presentation/web/components/common/merge-review/merge-review.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/common/merge-review/merge-review.js +2 -2
  22. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.d.ts +4 -0
  23. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.d.ts.map +1 -1
  24. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts +1 -1
  25. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.d.ts.map +1 -1
  26. package/dist/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.js +2 -2
  27. package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts +4 -0
  28. package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts +1 -1
  30. package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.d.ts.map +1 -1
  31. package/dist/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.js +2 -2
  32. package/dist/src/presentation/web/components/features/control-center/control-center-inner.d.ts.map +1 -1
  33. package/dist/src/presentation/web/components/features/control-center/control-center-inner.js +12 -8
  34. package/dist/src/presentation/web/components/features/control-center/control-center.stories.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/features/control-center/control-center.stories.js +2 -1
  36. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts +3 -1
  37. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.d.ts.map +1 -1
  38. package/dist/src/presentation/web/components/features/control-center/use-control-center-state.js +13 -5
  39. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/layouts/app-shell/app-shell.js +7 -5
  41. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +1 -1
  42. package/dist/src/presentation/web/components/ui/alert-dialog.stories.js +1 -1
  43. package/dist/src/presentation/web/hooks/drawer-close-guard.d.ts +26 -0
  44. package/dist/src/presentation/web/hooks/drawer-close-guard.d.ts.map +1 -0
  45. package/dist/src/presentation/web/hooks/drawer-close-guard.js +74 -0
  46. package/dist/tsconfig.build.tsbuildinfo +1 -1
  47. package/package.json +1 -1
  48. package/web/.next/BUILD_ID +1 -1
  49. package/web/.next/build-manifest.json +2 -2
  50. package/web/.next/cache/.previewinfo +1 -1
  51. package/web/.next/cache/.rscinfo +1 -1
  52. package/web/.next/cache/.tsbuildinfo +1 -1
  53. package/web/.next/cache/config.json +3 -3
  54. package/web/.next/fallback-build-manifest.json +2 -2
  55. package/web/.next/prerender-manifest.json +3 -3
  56. package/web/.next/required-server-files.js +1 -1
  57. package/web/.next/required-server-files.json +1 -1
  58. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  59. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  61. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  62. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  65. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  66. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  67. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  68. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  69. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  70. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  71. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  72. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  73. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  74. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  77. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  78. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/_global-error.html +2 -2
  80. package/web/.next/server/app/_global-error.rsc +1 -1
  81. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  82. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  83. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  84. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  85. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  86. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  87. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  88. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  90. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  91. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  92. package/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  93. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  94. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  95. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  96. package/web/.next/server/app/version/page.js.nft.json +1 -1
  97. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  98. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  99. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  100. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  101. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js.map +1 -1
  102. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  103. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js.map +1 -1
  104. package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
  105. package/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js.map +1 -1
  106. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  107. package/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js.map +1 -1
  108. package/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  109. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  110. package/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js.map +1 -1
  111. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
  112. package/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js.map +1 -1
  113. package/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
  114. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  115. package/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js.map +1 -1
  116. package/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
  117. package/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  118. package/web/.next/server/chunks/ssr/_00e6c698._.js.map +1 -1
  119. package/web/.next/server/chunks/ssr/_07c2a32a._.js +9 -0
  120. package/web/.next/server/chunks/ssr/_07c2a32a._.js.map +1 -0
  121. package/web/.next/server/chunks/ssr/_26129e04._.js +3 -0
  122. package/web/.next/server/chunks/ssr/_26129e04._.js.map +1 -0
  123. package/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  124. package/web/.next/server/chunks/ssr/_37259405._.js.map +1 -1
  125. package/web/.next/server/chunks/ssr/_85d0351b._.js +1 -1
  126. package/web/.next/server/chunks/ssr/_85d0351b._.js.map +1 -1
  127. package/web/.next/{standalone/src/presentation/web/.next/server/chunks/ssr/_9f5276de._.js → server/chunks/ssr/_8fcb97eb._.js} +3 -9
  128. package/web/.next/server/chunks/ssr/_8fcb97eb._.js.map +1 -0
  129. package/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  130. package/web/.next/server/chunks/ssr/_fc3a6895._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  132. package/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  134. package/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  136. package/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  138. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js.map +1 -1
  139. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  140. package/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js.map +1 -1
  141. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  142. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  143. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  144. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  145. package/web/.next/server/pages/500.html +2 -2
  146. package/web/.next/server/server-reference-manifest.js +1 -1
  147. package/web/.next/server/server-reference-manifest.json +20 -20
  148. package/web/.next/standalone/src/presentation/web/.next/BUILD_ID +1 -1
  149. package/web/.next/standalone/src/presentation/web/.next/build-manifest.json +2 -2
  150. package/web/.next/standalone/src/presentation/web/.next/prerender-manifest.json +3 -3
  151. package/web/.next/standalone/src/presentation/web/.next/required-server-files.json +1 -1
  152. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +14 -14
  153. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  154. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  155. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +17 -17
  156. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  157. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  158. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  159. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  160. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  161. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +14 -14
  162. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  163. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  164. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +17 -17
  165. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  166. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  167. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +12 -12
  168. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  169. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  170. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +12 -12
  171. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  172. package/web/.next/standalone/src/presentation/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  173. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.html +2 -2
  174. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.rsc +1 -1
  175. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  176. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  177. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  178. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  179. package/web/.next/standalone/src/presentation/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  180. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  181. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  182. package/web/.next/standalone/src/presentation/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  183. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  184. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page.js.nft.json +1 -1
  185. package/web/.next/standalone/src/presentation/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  186. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page/server-reference-manifest.json +1 -1
  187. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page.js.nft.json +1 -1
  188. package/web/.next/standalone/src/presentation/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  189. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  190. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page.js.nft.json +1 -1
  191. package/web/.next/standalone/src/presentation/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  192. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  193. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_2b7834f6.js +1 -1
  194. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_6923c575.js +1 -1
  195. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__07385073._.js +2 -2
  196. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__08ba9bd3._.js +1 -1
  197. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__249c74f6._.js +1 -1
  198. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6b17a22d._.js +1 -1
  199. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6bb00d90._.js +1 -1
  200. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__6db85a66._.js +2 -2
  201. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__804c006d._.js +1 -1
  202. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/[root-of-the-server]__8fcb9132._.js +2 -2
  203. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_00e6c698._.js +1 -1
  204. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_07c2a32a._.js +9 -0
  205. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_26129e04._.js +3 -0
  206. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_37259405._.js +1 -1
  207. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_85d0351b._.js +1 -1
  208. package/web/.next/{server/chunks/ssr/_9f5276de._.js → standalone/src/presentation/web/.next/server/chunks/ssr/_8fcb97eb._.js} +3 -9
  209. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_fc3a6895._.js +1 -1
  210. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_1a32dbcb._.js +2 -2
  211. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_398553b0._.js +1 -1
  212. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_5c87e8e4._.js +1 -1
  213. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_f4952172.js +1 -1
  214. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_c1bc6240._.js +2 -2
  215. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  216. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  217. package/web/.next/standalone/src/presentation/web/.next/server/pages/500.html +2 -2
  218. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.js +1 -1
  219. package/web/.next/standalone/src/presentation/web/.next/server/server-reference-manifest.json +20 -20
  220. package/web/.next/standalone/src/presentation/web/components/common/base-drawer/base-drawer.tsx +1 -0
  221. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/control-center-drawer.stories.tsx +8 -0
  222. package/web/.next/standalone/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx +45 -3
  223. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar-config.ts +4 -0
  224. package/web/.next/standalone/src/presentation/web/components/common/drawer-action-bar/drawer-action-bar.tsx +5 -1
  225. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx +32 -0
  226. package/web/.next/standalone/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx +8 -6
  227. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review-config.ts +4 -0
  228. package/web/.next/standalone/src/presentation/web/components/common/merge-review/merge-review.tsx +4 -0
  229. package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire-config.ts +4 -0
  230. package/web/.next/standalone/src/presentation/web/components/common/prd-questionnaire/prd-questionnaire.tsx +4 -0
  231. package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs-config.ts +4 -0
  232. package/web/.next/standalone/src/presentation/web/components/common/tech-review-tabs/tech-review-tabs.tsx +4 -0
  233. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center-inner.tsx +12 -8
  234. package/web/.next/standalone/src/presentation/web/components/features/control-center/control-center.stories.tsx +6 -3
  235. package/web/.next/standalone/src/presentation/web/components/features/control-center/use-control-center-state.ts +11 -5
  236. package/web/.next/standalone/src/presentation/web/components/layouts/app-shell/app-shell.tsx +11 -7
  237. package/web/.next/standalone/src/presentation/web/components/layouts/app-sidebar/app-sidebar.tsx +1 -1
  238. package/web/.next/standalone/src/presentation/web/components/ui/alert-dialog.stories.tsx +1 -1
  239. package/web/.next/standalone/src/presentation/web/hooks/drawer-close-guard.tsx +149 -0
  240. package/web/.next/standalone/src/presentation/web/server.js +1 -1
  241. package/web/.next/static/chunks/00adfce42dbbd5ef.js +1 -0
  242. package/web/.next/static/chunks/06dfd668334ffb4e.js +7 -0
  243. package/web/.next/static/chunks/{311b817783b3ebd7.js → 0f3e1ea42efba7e8.js} +1 -1
  244. package/web/.next/static/chunks/{47435830535491e8.js → 3c79bca4d3f18f66.js} +1 -1
  245. package/web/.next/static/chunks/{e44849eb58a3335f.js → 515d5b157a7620b9.js} +1 -1
  246. package/web/.next/static/chunks/{7183f9b53504c911.js → 5a962b5baf7c4d1d.js} +1 -1
  247. package/web/.next/static/chunks/{6310c6efd3e3ff8c.js → 87db91411a520cea.js} +1 -1
  248. package/web/.next/static/chunks/{0274480f2b09f92e.js → 9261e2adb145d388.js} +1 -1
  249. package/web/.next/static/chunks/{c6a53b653c68f935.js → 92ebb1cad6f24333.js} +4 -10
  250. package/web/.next/static/chunks/952c8aa7247dcb3f.js +1 -0
  251. package/web/.next/static/chunks/d2e6361bdd7a02a5.js +1 -0
  252. package/web/.next/static/chunks/{8d3e12279b2aa76b.js → ebfd2ed5b143b5b6.js} +1 -1
  253. package/web/.next/trace +1 -1
  254. package/web/.next/trace-build +1 -1
  255. package/web/.next/server/chunks/ssr/_45715073._.js +0 -3
  256. package/web/.next/server/chunks/ssr/_45715073._.js.map +0 -1
  257. package/web/.next/server/chunks/ssr/_9f5276de._.js.map +0 -1
  258. package/web/.next/server/chunks/ssr/node_modules__pnpm_11589942._.js +0 -3
  259. package/web/.next/server/chunks/ssr/node_modules__pnpm_11589942._.js.map +0 -1
  260. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/_45715073._.js +0 -3
  261. package/web/.next/standalone/src/presentation/web/.next/server/chunks/ssr/node_modules__pnpm_11589942._.js +0 -3
  262. package/web/.next/static/chunks/0b99eb9664d47ca7.js +0 -1
  263. package/web/.next/static/chunks/3e46df89d84cae41.js +0 -1
  264. package/web/.next/static/chunks/c279e0294d864963.js +0 -1
  265. package/web/.next/static/chunks/c4b35853f5a100b6.js +0 -1
  266. /package/web/.next/static/{he5MpZ65Zlh6SbVlx_mbE → KbyvoLS1Q62iF5F25ZKYW}/_buildManifest.js +0 -0
  267. /package/web/.next/static/{he5MpZ65Zlh6SbVlx_mbE → KbyvoLS1Q62iF5F25ZKYW}/_clientMiddlewareManifest.json +0 -0
  268. /package/web/.next/static/{he5MpZ65Zlh6SbVlx_mbE → KbyvoLS1Q62iF5F25ZKYW}/_ssgManifest.js +0 -0
@@ -16,8 +16,12 @@ export function DrawerActionBar({
16
16
  isProcessing = false,
17
17
  isRejecting = false,
18
18
  children,
19
+ chatInput: controlledChatInput,
20
+ onChatInputChange,
19
21
  }: DrawerActionBarProps) {
20
- const [chatInput, setChatInput] = useState('');
22
+ const [internalChatInput, setInternalChatInput] = useState('');
23
+ const chatInput = controlledChatInput ?? internalChatInput;
24
+ const setChatInput = onChatInputChange ?? setInternalChatInput;
21
25
  const approveSound = useSoundAction('approve');
22
26
  const disabled = isProcessing || isRejecting;
23
27
 
@@ -5,6 +5,7 @@ import { FeatureCreateDrawer } from './feature-create-drawer';
5
5
  import type { FeatureCreatePayload } from './feature-create-drawer';
6
6
  import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
7
7
  import { Button } from '@/components/ui/button';
8
+ import { DrawerCloseGuardProvider } from '@/hooks/drawer-close-guard';
8
9
 
9
10
  /* ---------------------------------------------------------------------------
10
11
  * Meta — component-level docs + interactive controls
@@ -44,6 +45,13 @@ const meta: Meta<typeof FeatureCreateDrawer> = {
44
45
  title: 'Drawers/Feature/FeatureCreateDrawer',
45
46
  component: FeatureCreateDrawer,
46
47
  tags: ['autodocs'],
48
+ decorators: [
49
+ (Story) => (
50
+ <DrawerCloseGuardProvider>
51
+ <Story />
52
+ </DrawerCloseGuardProvider>
53
+ ),
54
+ ],
47
55
  parameters: {
48
56
  layout: 'fullscreen',
49
57
  },
@@ -346,6 +354,30 @@ export const InDrawer: Story = {
346
354
  render: () => <CreateDrawerShellTemplate />,
347
355
  };
348
356
 
357
+ /* ---------------------------------------------------------------------------
358
+ * Discard confirmation stories
359
+ * ------------------------------------------------------------------------- */
360
+
361
+ /**
362
+ * Discard confirmation — type text, then click Cancel to trigger the
363
+ * "Discard unsaved changes?" dialog. Demonstrates the dirty-form guard.
364
+ */
365
+ export const DiscardConfirmation: Story = {
366
+ render: () => <CreateDrawerTrigger label="Open (Discard Confirmation)" />,
367
+ play: async ({ canvasElement }) => {
368
+ const canvas = within(canvasElement);
369
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Discard Confirmation)' }));
370
+
371
+ const body = within(canvasElement.ownerDocument.body);
372
+ const nameInput = await body.findByPlaceholderText('e.g. GitHub OAuth Login');
373
+ await userEvent.type(nameInput, 'My Feature');
374
+
375
+ // Click Cancel — should show the discard confirmation dialog
376
+ const cancelButton = body.getByRole('button', { name: 'Cancel' });
377
+ await userEvent.click(cancelButton);
378
+ },
379
+ };
380
+
349
381
  /* ---------------------------------------------------------------------------
350
382
  * Interactive story — full paths shown in submitted data panel
351
383
  * ------------------------------------------------------------------------- */
@@ -24,6 +24,7 @@ import { CheckboxGroup } from '@/components/ui/checkbox-group';
24
24
  import { CheckboxGroupItem } from '@/components/ui/checkbox-group-item';
25
25
  import { Badge } from '@/components/ui/badge';
26
26
  import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
27
+ import { useGuardedDrawerClose } from '@/hooks/drawer-close-guard';
27
28
  import type { FileAttachment } from '@shepai/core/infrastructure/services/file-dialog.service';
28
29
  import type { WorkflowDefaults } from '@/app/actions/get-workflow-defaults';
29
30
  import { pickFiles } from './pick-files';
@@ -125,10 +126,11 @@ export function FeatureCreateDrawer({
125
126
  setParentId(undefined);
126
127
  }, [defaultGates, defaultPush, defaultOpenPr]);
127
128
 
128
- const handleClose = useCallback(() => {
129
- resetForm();
130
- onClose();
131
- }, [onClose, resetForm]);
129
+ // Track whether the form has unsaved data
130
+ const isDirty = name.trim() !== '' || description.trim() !== '' || attachments.length > 0;
131
+
132
+ // Shared close guard — shows confirmation when dirty, prevents navigation
133
+ const { attemptClose } = useGuardedDrawerClose({ open, isDirty, onClose, onReset: resetForm });
132
134
 
133
135
  const handleSubmit = useCallback(
134
136
  (e: React.FormEvent) => {
@@ -187,7 +189,7 @@ export function FeatureCreateDrawer({
187
189
  return (
188
190
  <BaseDrawer
189
191
  open={open}
190
- onClose={handleClose}
192
+ onClose={attemptClose}
191
193
  size="md"
192
194
  modal={false}
193
195
  data-testid="feature-create-drawer"
@@ -206,7 +208,7 @@ export function FeatureCreateDrawer({
206
208
  }
207
209
  footer={
208
210
  <div className="flex flex-row justify-end gap-2">
209
- <Button variant="outline" onClick={handleClose} disabled={isSubmitting}>
211
+ <Button variant="outline" onClick={attemptClose} disabled={isSubmitting}>
210
212
  Cancel
211
213
  </Button>
212
214
  <Button type="submit" form="create-feature-form" disabled={!name.trim() || isSubmitting}>
@@ -58,6 +58,10 @@ export interface MergeReviewProps {
58
58
  isProcessing?: boolean;
59
59
  /** Whether a reject operation is in flight */
60
60
  isRejecting?: boolean;
61
+ /** Controlled chat input for the revision input. */
62
+ chatInput?: string;
63
+ /** Handler for chat input changes. */
64
+ onChatInputChange?: (value: string) => void;
61
65
  }
62
66
 
63
67
  /** Props for the merge review drawer (shell wrapper) */
@@ -52,6 +52,8 @@ export function MergeReview({
52
52
  onReject,
53
53
  isProcessing = false,
54
54
  isRejecting = false,
55
+ chatInput,
56
+ onChatInputChange,
55
57
  }: MergeReviewProps) {
56
58
  const { pr, diffSummary, phases, branch, warning } = data;
57
59
 
@@ -188,6 +190,8 @@ export function MergeReview({
188
190
  revisionPlaceholder="Ask AI to revise before merging..."
189
191
  isProcessing={isProcessing}
190
192
  isRejecting={isRejecting}
193
+ chatInput={chatInput}
194
+ onChatInputChange={onChatInputChange}
191
195
  />
192
196
  </div>
193
197
  );
@@ -24,6 +24,10 @@ export interface PrdQuestionnaireProps {
24
24
  isRejecting?: boolean;
25
25
  /** Show the goal/context header (default: false) */
26
26
  showHeader?: boolean;
27
+ /** Controlled chat input for the revision input. */
28
+ chatInput?: string;
29
+ /** Handler for chat input changes. */
30
+ onChatInputChange?: (value: string) => void;
27
31
  }
28
32
 
29
33
  export interface PrdQuestionnaireDrawerProps extends Omit<PrdQuestionnaireProps, 'data'> {
@@ -18,6 +18,8 @@ export function PrdQuestionnaire({
18
18
  isProcessing = false,
19
19
  isRejecting = false,
20
20
  showHeader = false,
21
+ chatInput,
22
+ onChatInputChange,
21
23
  }: PrdQuestionnaireProps) {
22
24
  const { question, context, questions, finalAction } = data;
23
25
  const [currentStep, setCurrentStep] = useState(0);
@@ -171,6 +173,8 @@ export function PrdQuestionnaire({
171
173
  revisionPlaceholder="Ask AI to refine requirements..."
172
174
  isProcessing={isProcessing}
173
175
  isRejecting={isRejecting}
176
+ chatInput={chatInput}
177
+ onChatInputChange={onChatInputChange}
174
178
  >
175
179
  <div
176
180
  className={cn(
@@ -14,4 +14,8 @@ export interface TechReviewTabsProps {
14
14
  isProcessing?: boolean;
15
15
  /** Whether a reject operation is in flight */
16
16
  isRejecting?: boolean;
17
+ /** Controlled chat input for the revision input. */
18
+ chatInput?: string;
19
+ /** Handler for chat input changes. */
20
+ onChatInputChange?: (value: string) => void;
17
21
  }
@@ -14,6 +14,8 @@ export function TechReviewTabs({
14
14
  onReject,
15
15
  isProcessing = false,
16
16
  isRejecting = false,
17
+ chatInput,
18
+ onChatInputChange,
17
19
  }: TechReviewTabsProps) {
18
20
  if (techData.decisions.length === 0) return null;
19
21
 
@@ -54,6 +56,8 @@ export function TechReviewTabs({
54
56
  revisionPlaceholder="Ask AI to revise the plan..."
55
57
  isProcessing={isProcessing}
56
58
  isRejecting={isRejecting}
59
+ chatInput={chatInput}
60
+ onChatInputChange={onChatInputChange}
57
61
  />
58
62
  </div>
59
63
  );
@@ -14,6 +14,7 @@ import {
14
14
  } from '@/hooks/sidebar-features-context';
15
15
  import { useSelectedFeatureId } from '@/hooks/use-selected-feature-id';
16
16
  import { useSoundAction } from '@/hooks/use-sound-action';
17
+ import { useDrawerCloseGuard } from '@/hooks/drawer-close-guard';
17
18
  import { ControlCenterEmptyState } from './control-center-empty-state';
18
19
  import { useControlCenterState } from './use-control-center-state';
19
20
 
@@ -27,6 +28,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
27
28
  const pathname = usePathname();
28
29
  const selectedFeatureId = useSelectedFeatureId();
29
30
  const clickSound = useSoundAction('click');
31
+ const { guardedNavigate, getIsDirty } = useDrawerCloseGuard();
30
32
 
31
33
  const {
32
34
  nodes,
@@ -37,7 +39,7 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
37
39
  handleDeleteFeature,
38
40
  handleDeleteRepository,
39
41
  createFeatureNode,
40
- } = useControlCenterState(initialNodes, initialEdges);
42
+ } = useControlCenterState(initialNodes, initialEdges, getIsDirty);
41
43
 
42
44
  // Publish sidebar features to context whenever feature node data changes
43
45
  const { setFeatures: setSidebarFeatures } = useSidebarFeaturesContext();
@@ -86,11 +88,13 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
86
88
  if (node.type === 'featureNode') {
87
89
  const data = node.data as FeatureNodeData;
88
90
  if (data.state === 'creating') return;
89
- clickSound.play();
90
- router.push(`/feature/${data.featureId}`);
91
+ guardedNavigate(() => {
92
+ clickSound.play();
93
+ router.push(`/feature/${data.featureId}`);
94
+ });
91
95
  }
92
96
  },
93
- [router, clickSound]
97
+ [router, clickSound, guardedNavigate]
94
98
  );
95
99
 
96
100
  const handleAddFeature = useCallback(() => {
@@ -135,19 +139,19 @@ export function ControlCenterInner({ initialNodes, initialEdges }: ControlCenter
135
139
  if (node?.type === 'repositoryNode') {
136
140
  const data = node.data as RepositoryNodeData;
137
141
  if (data.id) {
138
- router.push(`/repository/${data.id}`);
142
+ guardedNavigate(() => router.push(`/repository/${data.id}`));
139
143
  }
140
144
  }
141
145
  },
142
- [nodes, router]
146
+ [nodes, router, guardedNavigate]
143
147
  );
144
148
 
145
149
  // Close all drawers — navigate back to root
146
150
  const handleClearDrawers = useCallback(() => {
147
151
  if (pathname !== '/') {
148
- router.push('/');
152
+ guardedNavigate(() => router.push('/'));
149
153
  }
150
- }, [router, pathname]);
154
+ }, [router, pathname, guardedNavigate]);
151
155
 
152
156
  // Listen for global "add repository" events from the top bar button
153
157
  useEffect(() => {
@@ -7,6 +7,7 @@ import type { RepositoryNodeType } from '@/components/common/repository-node';
7
7
  import type { AddRepositoryNodeType } from '@/components/common/add-repository-node';
8
8
  import { layoutWithDagre } from '@/lib/layout-with-dagre';
9
9
  import { AgentEventsProvider } from '@/hooks/agent-events-provider';
10
+ import { DrawerCloseGuardProvider } from '@/hooks/drawer-close-guard';
10
11
 
11
12
  const meta: Meta<typeof ControlCenter> = {
12
13
  title: 'Features/ControlCenter',
@@ -18,9 +19,11 @@ const meta: Meta<typeof ControlCenter> = {
18
19
  decorators: [
19
20
  (Story) => (
20
21
  <AgentEventsProvider>
21
- <div style={{ height: '100vh' }}>
22
- <Story />
23
- </div>
22
+ <DrawerCloseGuardProvider>
23
+ <div style={{ height: '100vh' }}>
24
+ <Story />
25
+ </div>
26
+ </DrawerCloseGuardProvider>
24
27
  </AgentEventsProvider>
25
28
  ),
26
29
  ],
@@ -37,7 +37,9 @@ let nextFeatureId = 0;
37
37
 
38
38
  export function useControlCenterState(
39
39
  initialNodes: CanvasNodeType[],
40
- initialEdges: Edge[]
40
+ initialEdges: Edge[],
41
+ /** When true, background router.refresh() calls (polling / SSE debounce) are suppressed. */
42
+ isRefreshBlocked?: () => boolean
41
43
  ): ControlCenterState {
42
44
  const router = useRouter();
43
45
  const [nodes, setNodes] = useState<CanvasNodeType[]>(initialNodes);
@@ -202,8 +204,10 @@ export function useControlCenterState(
202
204
 
203
205
  // Debounced background reconciliation (3s after last SSE event)
204
206
  clearTimeout(reconcileTimerRef.current);
205
- reconcileTimerRef.current = setTimeout(() => router.refresh(), 3000);
206
- }, [events, router]);
207
+ reconcileTimerRef.current = setTimeout(() => {
208
+ if (!isRefreshBlocked?.()) router.refresh();
209
+ }, 3000);
210
+ }, [events, router, isRefreshBlocked]);
207
211
 
208
212
  // Periodic polling fallback: refresh server data every 5s when any feature
209
213
  // is in an active state (running/action-required). This ensures the UI stays
@@ -219,9 +223,11 @@ export function useControlCenterState(
219
223
 
220
224
  if (!hasActiveFeature) return;
221
225
 
222
- const interval = setInterval(() => router.refresh(), 5_000);
226
+ const interval = setInterval(() => {
227
+ if (!isRefreshBlocked?.()) router.refresh();
228
+ }, 5_000);
223
229
  return () => clearInterval(interval);
224
- }, [nodes, router]);
230
+ }, [nodes, router, isRefreshBlocked]);
225
231
 
226
232
  const onNodesChange = useCallback((changes: NodeChange<CanvasNodeType>[]) => {
227
233
  setNodes((ns) => applyNodeChanges(changes, ns));
@@ -8,6 +8,7 @@ import { AddRepositoryButton } from '@/components/common/add-repository-node';
8
8
  import { ThemeToggle } from '@/components/common/theme-toggle';
9
9
  import { SoundToggle } from '@/components/common/sound-toggle';
10
10
  import { AgentEventsProvider } from '@/hooks/agent-events-provider';
11
+ import { DrawerCloseGuardProvider, useDrawerCloseGuard } from '@/hooks/drawer-close-guard';
11
12
  import {
12
13
  SidebarFeaturesProvider,
13
14
  useSidebarFeaturesContext,
@@ -21,6 +22,7 @@ interface AppShellProps {
21
22
  /** Inner shell that consumes the agent-events context for notifications. */
22
23
  function AppShellInner({ children }: AppShellProps) {
23
24
  const router = useRouter();
25
+ const { guardedNavigate } = useDrawerCloseGuard();
24
26
 
25
27
  // Subscribe to agent lifecycle events and dispatch toast/browser notifications
26
28
  useNotifications();
@@ -28,14 +30,14 @@ function AppShellInner({ children }: AppShellProps) {
28
30
  const { features } = useSidebarFeaturesContext();
29
31
 
30
32
  const handleNewFeature = useCallback(() => {
31
- router.push('/create');
32
- }, [router]);
33
+ guardedNavigate(() => router.push('/create'));
34
+ }, [router, guardedNavigate]);
33
35
 
34
36
  const handleFeatureClick = useCallback(
35
37
  (featureId: string) => {
36
- router.push(`/feature/${featureId}`);
38
+ guardedNavigate(() => router.push(`/feature/${featureId}`));
37
39
  },
38
- [router]
40
+ [router, guardedNavigate]
39
41
  );
40
42
 
41
43
  const handleRepositorySelect = useCallback((path: string) => {
@@ -66,9 +68,11 @@ function AppShellInner({ children }: AppShellProps) {
66
68
  export function AppShell({ children }: AppShellProps) {
67
69
  return (
68
70
  <AgentEventsProvider>
69
- <SidebarFeaturesProvider>
70
- <AppShellInner>{children}</AppShellInner>
71
- </SidebarFeaturesProvider>
71
+ <DrawerCloseGuardProvider>
72
+ <SidebarFeaturesProvider>
73
+ <AppShellInner>{children}</AppShellInner>
74
+ </SidebarFeaturesProvider>
75
+ </DrawerCloseGuardProvider>
72
76
  </AgentEventsProvider>
73
77
  );
74
78
  }
@@ -60,7 +60,7 @@ export function AppSidebar({
60
60
  });
61
61
 
62
62
  return (
63
- <Sidebar data-testid="app-sidebar" collapsible="icon">
63
+ <Sidebar data-testid="app-sidebar" data-no-drawer-close collapsible="icon">
64
64
  <SidebarHeader>
65
65
  <SidebarMenu>
66
66
  <SidebarMenuItem>
@@ -84,8 +84,8 @@ export const WithDescription: Story = {
84
84
  </AlertDialogDescription>
85
85
  </AlertDialogHeader>
86
86
  <AlertDialogFooter>
87
- <AlertDialogCancel>Keep Editing</AlertDialogCancel>
88
87
  <AlertDialogAction variant="destructive">Discard</AlertDialogAction>
88
+ <AlertDialogCancel>Keep Editing</AlertDialogCancel>
89
89
  </AlertDialogFooter>
90
90
  </AlertDialogContent>
91
91
  </AlertDialog>
@@ -0,0 +1,149 @@
1
+ 'use client';
2
+
3
+ import {
4
+ createContext,
5
+ useContext,
6
+ useState,
7
+ useCallback,
8
+ useEffect,
9
+ useRef,
10
+ type ReactNode,
11
+ } from 'react';
12
+ import {
13
+ AlertDialog,
14
+ AlertDialogAction,
15
+ AlertDialogCancel,
16
+ AlertDialogContent,
17
+ AlertDialogDescription,
18
+ AlertDialogFooter,
19
+ AlertDialogHeader,
20
+ AlertDialogTitle,
21
+ } from '@/components/ui/alert-dialog';
22
+
23
+ /* ---------------------------------------------------------------------------
24
+ * Context
25
+ * ------------------------------------------------------------------------- */
26
+
27
+ interface DrawerCloseGuardContextValue {
28
+ /** Register a drawer's dirty state and reset callback. Pass `null` to unregister. */
29
+ setGuard: (guard: { isDirty: boolean; onReset: () => void } | null) => void;
30
+ /** Navigate only if no dirty drawer is registered; otherwise show confirmation. */
31
+ guardedNavigate: (navigate: () => void) => void;
32
+ /** Returns true when any drawer has unsaved changes. Safe to call from effects/intervals. */
33
+ getIsDirty: () => boolean;
34
+ }
35
+
36
+ const DrawerCloseGuardContext = createContext<DrawerCloseGuardContextValue | null>(null);
37
+
38
+ /* ---------------------------------------------------------------------------
39
+ * Provider — renders the shared confirmation dialog
40
+ * ------------------------------------------------------------------------- */
41
+
42
+ export function DrawerCloseGuardProvider({ children }: { children: ReactNode }) {
43
+ // Use a ref so guard updates (on every keystroke) don't re-render the provider tree.
44
+ const guardRef = useRef<{ isDirty: boolean; onReset: () => void } | null>(null);
45
+ const pendingNavigateRef = useRef<(() => void) | null>(null);
46
+ const [showConfirmation, setShowConfirmation] = useState(false);
47
+
48
+ const setGuard = useCallback((guard: { isDirty: boolean; onReset: () => void } | null) => {
49
+ guardRef.current = guard;
50
+ }, []);
51
+
52
+ const guardedNavigate = useCallback((navigate: () => void) => {
53
+ if (guardRef.current?.isDirty) {
54
+ pendingNavigateRef.current = navigate;
55
+ setShowConfirmation(true);
56
+ return;
57
+ }
58
+ navigate();
59
+ }, []);
60
+
61
+ const confirmDiscard = useCallback(() => {
62
+ setShowConfirmation(false);
63
+ guardRef.current?.onReset();
64
+ guardRef.current = null;
65
+ pendingNavigateRef.current?.();
66
+ pendingNavigateRef.current = null;
67
+ }, []);
68
+
69
+ const cancelDiscard = useCallback(() => {
70
+ setShowConfirmation(false);
71
+ pendingNavigateRef.current = null;
72
+ }, []);
73
+
74
+ const getIsDirty = useCallback(() => guardRef.current?.isDirty ?? false, []);
75
+
76
+ return (
77
+ <DrawerCloseGuardContext value={{ setGuard, guardedNavigate, getIsDirty }}>
78
+ {children}
79
+
80
+ <AlertDialog open={showConfirmation}>
81
+ <AlertDialogContent>
82
+ <AlertDialogHeader>
83
+ <AlertDialogTitle>Discard unsaved changes?</AlertDialogTitle>
84
+ <AlertDialogDescription>
85
+ You have unsaved changes. Are you sure you want to discard them?
86
+ </AlertDialogDescription>
87
+ </AlertDialogHeader>
88
+ <AlertDialogFooter>
89
+ <AlertDialogAction variant="destructive" onClick={confirmDiscard}>
90
+ Discard
91
+ </AlertDialogAction>
92
+ <AlertDialogCancel onClick={cancelDiscard}>Keep editing</AlertDialogCancel>
93
+ </AlertDialogFooter>
94
+ </AlertDialogContent>
95
+ </AlertDialog>
96
+ </DrawerCloseGuardContext>
97
+ );
98
+ }
99
+
100
+ /* ---------------------------------------------------------------------------
101
+ * Hook — access the guard from any child component
102
+ * ------------------------------------------------------------------------- */
103
+
104
+ export function useDrawerCloseGuard() {
105
+ const ctx = useContext(DrawerCloseGuardContext);
106
+ if (!ctx) throw new Error('useDrawerCloseGuard must be used within DrawerCloseGuardProvider');
107
+ return ctx;
108
+ }
109
+
110
+ /* ---------------------------------------------------------------------------
111
+ * Convenience hook for drawer components
112
+ *
113
+ * Registers dirty state + reset callback with the guard, and returns an
114
+ * `attemptClose` function that goes through the guard before closing.
115
+ * ------------------------------------------------------------------------- */
116
+
117
+ export function useGuardedDrawerClose({
118
+ open,
119
+ isDirty,
120
+ onClose,
121
+ onReset,
122
+ }: {
123
+ open: boolean;
124
+ isDirty: boolean;
125
+ onClose: () => void;
126
+ onReset: () => void;
127
+ }) {
128
+ const { setGuard, guardedNavigate } = useDrawerCloseGuard();
129
+
130
+ // Keep the guard in sync with dirty state. Because setGuard writes to a ref,
131
+ // this doesn't trigger re-renders in the provider.
132
+ useEffect(() => {
133
+ if (open) {
134
+ setGuard({ isDirty, onReset });
135
+ } else {
136
+ setGuard(null);
137
+ }
138
+ return () => setGuard(null);
139
+ }, [open, isDirty, onReset, setGuard]);
140
+
141
+ const attemptClose = useCallback(() => {
142
+ guardedNavigate(() => {
143
+ onReset();
144
+ onClose();
145
+ });
146
+ }, [guardedNavigate, onClose, onReset]);
147
+
148
+ return { attemptClose };
149
+ }
@@ -15,7 +15,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
15
15
  const hostname = process.env.HOSTNAME || '0.0.0.0'
16
16
 
17
17
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
18
- const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.72.2","NEXT_PUBLIC_SHEP_PACKAGE_NAME":"@shepai/cli","NEXT_PUBLIC_SHEP_DESCRIPTION":"Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":true,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/cli/cli","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/cli/cli"},"serverExternalPackages":["tsyringe","reflect-metadata","better-sqlite3","node:os","node:child_process","node:fs"],"distDirRoot":".next"}
18
+ const nextConfig = {"env":{"NEXT_PUBLIC_SHEP_VERSION":"1.72.4","NEXT_PUBLIC_SHEP_PACKAGE_NAME":"@shepai/cli","NEXT_PUBLIC_SHEP_DESCRIPTION":"Autonomous AI Native SDLC Platform - Automate the development cycle from idea to deploy"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":true,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/cli/cli","cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"dynamicOnHover":false,"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"imgOptSkipMetadata":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"viewTransition":false,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":false,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":false,"serverComponentsHmrCache":true,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":false,"lockDistDir":true,"isolatedDevBuild":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":false,"turbopackInferModuleSideEffects":false,"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","turbopack":{"root":"/home/runner/work/cli/cli"},"serverExternalPackages":["tsyringe","reflect-metadata","better-sqlite3","node:os","node:child_process","node:fs"],"distDirRoot":".next"}
19
19
 
20
20
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
21
21