@shepai/cli 1.149.0 → 1.149.1-pr467.b05cb61

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 (216) hide show
  1. package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts +17 -0
  2. package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.d.ts.map +1 -1
  3. package/dist/packages/core/src/application/ports/output/services/github-repository-service.interface.js +12 -0
  4. package/dist/packages/core/src/application/use-cases/features/get-branch-sync-status.use-case.d.ts.map +1 -1
  5. package/dist/packages/core/src/application/use-cases/features/get-branch-sync-status.use-case.js +4 -0
  6. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts +1 -0
  7. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
  8. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +18 -1
  9. package/dist/src/presentation/web/app/(dashboard)/@drawer/create/page.d.ts.map +1 -1
  10. package/dist/src/presentation/web/app/(dashboard)/@drawer/create/page.js +6 -2
  11. package/dist/src/presentation/web/app/actions/get-viewer-permission.d.ts +4 -0
  12. package/dist/src/presentation/web/app/actions/get-viewer-permission.d.ts.map +1 -0
  13. package/dist/src/presentation/web/app/actions/get-viewer-permission.js +14 -0
  14. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts +2 -1
  15. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.d.ts.map +1 -1
  16. package/dist/src/presentation/web/components/common/control-center-drawer/create-drawer-client.js +2 -2
  17. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.d.ts.map +1 -1
  18. package/dist/src/presentation/web/components/common/control-center-drawer/feature-drawer-client.js +6 -3
  19. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts +3 -1
  20. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.d.ts.map +1 -1
  21. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.js +29 -3
  22. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts +10 -0
  23. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.d.ts.map +1 -1
  24. package/dist/src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.js +37 -3
  25. package/dist/src/presentation/web/next.config.d.ts.map +1 -1
  26. package/dist/src/presentation/web/next.config.js +0 -3
  27. package/dist/tsconfig.build.tsbuildinfo +1 -1
  28. package/package.json +1 -1
  29. package/web/.next/BUILD_ID +1 -1
  30. package/web/.next/build-manifest.json +2 -2
  31. package/web/.next/fallback-build-manifest.json +2 -2
  32. package/web/.next/prerender-manifest.json +3 -3
  33. package/web/.next/required-server-files.js +3 -4
  34. package/web/.next/required-server-files.json +3 -4
  35. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +28 -28
  36. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  37. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  38. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +71 -56
  40. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  41. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  42. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  44. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  45. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  46. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +36 -36
  47. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  48. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  50. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +71 -56
  53. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  54. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  55. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +36 -36
  57. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  58. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  59. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +36 -36
  60. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  61. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  62. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +26 -26
  63. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  64. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  65. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +26 -26
  66. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  67. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/_global-error.html +2 -2
  69. package/web/.next/server/app/_global-error.rsc +1 -1
  70. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  71. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  72. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  73. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  74. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  75. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +3 -3
  76. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  77. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  78. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  79. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  80. package/web/.next/server/app/settings/page/server-reference-manifest.json +8 -8
  81. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  82. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  83. package/web/.next/server/app/skills/page/server-reference-manifest.json +8 -8
  84. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  85. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  86. package/web/.next/server/app/tools/page/server-reference-manifest.json +8 -8
  87. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  88. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/version/page/server-reference-manifest.json +3 -3
  90. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  91. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js +1 -1
  92. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_370c43b1.js.map +1 -1
  93. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js +1 -1
  94. package/web/.next/server/chunks/403f9_next_dist_esm_build_templates_app-route_4d623b8e.js.map +1 -1
  95. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js +1 -1
  96. package/web/.next/server/chunks/[root-of-the-server]__0866d2b5._.js.map +1 -1
  97. package/web/.next/server/chunks/[root-of-the-server]__0d33c29e._.js +1 -1
  98. package/web/.next/server/chunks/[root-of-the-server]__0d33c29e._.js.map +1 -1
  99. package/web/.next/server/chunks/[root-of-the-server]__25f23d5d._.js +1 -1
  100. package/web/.next/server/chunks/[root-of-the-server]__25f23d5d._.js.map +1 -1
  101. package/web/.next/server/chunks/[root-of-the-server]__26565141._.js +1 -1
  102. package/web/.next/server/chunks/[root-of-the-server]__26565141._.js.map +1 -1
  103. package/web/.next/server/chunks/[root-of-the-server]__2b1074db._.js +1 -1
  104. package/web/.next/server/chunks/[root-of-the-server]__2b1074db._.js.map +1 -1
  105. package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js +1 -1
  106. package/web/.next/server/chunks/[root-of-the-server]__2f61738a._.js.map +1 -1
  107. package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js +1 -1
  108. package/web/.next/server/chunks/[root-of-the-server]__332c8d91._.js.map +1 -1
  109. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js +1 -1
  110. package/web/.next/server/chunks/[root-of-the-server]__3b72e8b0._.js.map +1 -1
  111. package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js +1 -1
  112. package/web/.next/server/chunks/[root-of-the-server]__9191749c._.js.map +1 -1
  113. package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js +3 -3
  114. package/web/.next/server/chunks/[root-of-the-server]__9a136c79._.js.map +1 -1
  115. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js +1 -1
  116. package/web/.next/server/chunks/[root-of-the-server]__a402b567._.js.map +1 -1
  117. package/web/.next/server/chunks/[root-of-the-server]__a5879003._.js +1 -1
  118. package/web/.next/server/chunks/[root-of-the-server]__a5879003._.js.map +1 -1
  119. package/web/.next/server/chunks/[root-of-the-server]__b2f9a412._.js +1 -1
  120. package/web/.next/server/chunks/[root-of-the-server]__b2f9a412._.js.map +1 -1
  121. package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js +1 -1
  122. package/web/.next/server/chunks/[root-of-the-server]__b4102cc7._.js.map +1 -1
  123. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js +1 -1
  124. package/web/.next/server/chunks/[root-of-the-server]__d2c18946._.js.map +1 -1
  125. package/web/.next/server/chunks/[root-of-the-server]__d9d410a8._.js +1 -1
  126. package/web/.next/server/chunks/[root-of-the-server]__d9d410a8._.js.map +1 -1
  127. package/web/.next/server/chunks/[root-of-the-server]__e247a485._.js +1 -1
  128. package/web/.next/server/chunks/[root-of-the-server]__e247a485._.js.map +1 -1
  129. package/web/.next/server/chunks/[root-of-the-server]__fc6fd958._.js +1 -1
  130. package/web/.next/server/chunks/[root-of-the-server]__fc6fd958._.js.map +1 -1
  131. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  132. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  133. package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js +2 -2
  134. package/web/.next/server/chunks/ssr/[root-of-the-server]__2138fa7e._.js.map +1 -1
  135. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js +1 -1
  136. package/web/.next/server/chunks/ssr/[root-of-the-server]__29580090._.js.map +1 -1
  137. package/web/.next/server/chunks/ssr/[root-of-the-server]__357d99f9._.js +1 -1
  138. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js +1 -1
  139. package/web/.next/server/chunks/ssr/[root-of-the-server]__3ef34e4c._.js.map +1 -1
  140. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js +1 -1
  141. package/web/.next/server/chunks/ssr/[root-of-the-server]__43f51aa6._.js.map +1 -1
  142. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js +1 -1
  143. package/web/.next/server/chunks/ssr/[root-of-the-server]__815546bd._.js.map +1 -1
  144. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +3 -3
  145. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  146. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js +1 -1
  147. package/web/.next/server/chunks/ssr/[root-of-the-server]__c094882b._.js.map +1 -1
  148. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js +1 -1
  149. package/web/.next/server/chunks/ssr/[root-of-the-server]__c9777776._.js.map +1 -1
  150. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js +1 -1
  151. package/web/.next/server/chunks/ssr/[root-of-the-server]__d48c5b11._.js.map +1 -1
  152. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js +1 -1
  153. package/web/.next/server/chunks/ssr/[root-of-the-server]__dac5dbf1._.js.map +1 -1
  154. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js +1 -1
  155. package/web/.next/server/chunks/ssr/[root-of-the-server]__fae8b355._.js.map +1 -1
  156. package/web/.next/server/chunks/ssr/_05c23ad9._.js +1 -1
  157. package/web/.next/server/chunks/ssr/_05c23ad9._.js.map +1 -1
  158. package/web/.next/server/chunks/ssr/{_0c5f56e3._.js → _0c473fef._.js} +3 -3
  159. package/web/.next/server/chunks/ssr/_0c473fef._.js.map +1 -0
  160. package/web/.next/server/chunks/ssr/_16eb4fec._.js +1 -1
  161. package/web/.next/server/chunks/ssr/_16eb4fec._.js.map +1 -1
  162. package/web/.next/server/chunks/ssr/_1b719e7f._.js +1 -1
  163. package/web/.next/server/chunks/ssr/_1b719e7f._.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/{_5022e2b1._.js → _30459875._.js} +2 -2
  165. package/web/.next/server/chunks/ssr/{_5022e2b1._.js.map → _30459875._.js.map} +1 -1
  166. package/web/.next/server/chunks/ssr/_37e8548b._.js +1 -1
  167. package/web/.next/server/chunks/ssr/_37e8548b._.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/_55d763e2._.js +1 -1
  169. package/web/.next/server/chunks/ssr/_55d763e2._.js.map +1 -1
  170. package/web/.next/server/chunks/ssr/_6256a985._.js +1 -1
  171. package/web/.next/server/chunks/ssr/_6256a985._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/_8fcc39d4._.js +1 -1
  173. package/web/.next/server/chunks/ssr/{_458e9a64._.js → _abec1c45._.js} +2 -2
  174. package/web/.next/server/chunks/ssr/{_458e9a64._.js.map → _abec1c45._.js.map} +1 -1
  175. package/web/.next/server/chunks/ssr/_b71645b4._.js +1 -1
  176. package/web/.next/server/chunks/ssr/_b71645b4._.js.map +1 -1
  177. package/web/.next/server/chunks/ssr/_d8575088._.js +1 -1
  178. package/web/.next/server/chunks/ssr/_d8575088._.js.map +1 -1
  179. package/web/.next/server/chunks/ssr/{_64bdfc6f._.js → _e9e9ed20._.js} +3 -3
  180. package/web/.next/server/chunks/ssr/_e9e9ed20._.js.map +1 -0
  181. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  182. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  183. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js +1 -1
  184. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1b176e3c.js.map +1 -1
  185. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js +1 -1
  186. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_bd9f0dda.js.map +1 -1
  187. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_baaca5d5._.js +1 -1
  188. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js +1 -1
  189. package/web/.next/server/chunks/ssr/src_presentation_web_components_e599bb8c._.js.map +1 -1
  190. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  191. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  192. package/web/.next/server/chunks/ssr/{src_presentation_web_35159458._.js → src_presentation_web_e8241254._.js} +2 -2
  193. package/web/.next/server/chunks/ssr/{src_presentation_web_35159458._.js.map → src_presentation_web_e8241254._.js.map} +1 -1
  194. package/web/.next/server/pages/500.html +2 -2
  195. package/web/.next/server/server-reference-manifest.js +1 -1
  196. package/web/.next/server/server-reference-manifest.json +122 -100
  197. package/web/.next/static/chunks/19935f7b538ef132.js +1 -0
  198. package/web/.next/static/chunks/{eaca60cc3ab0bf9f.js → 530c26ce96fc30d1.js} +2 -2
  199. package/web/.next/static/chunks/{3e7a130816229439.js → 58638a97a465d8fe.js} +1 -1
  200. package/web/.next/static/chunks/{24b1c1e60fd3b7b5.js → 5b4039a7214ebe58.js} +3 -3
  201. package/web/.next/static/chunks/{fe5d48f8ca483935.js → 6ad6451b2946abc2.js} +1 -1
  202. package/web/.next/static/chunks/{3f1b33498b472b00.js → 7c5b13867975dc5f.js} +1 -1
  203. package/web/.next/static/chunks/{75834e430247b325.js → 80e476ff4f527c2b.js} +1 -1
  204. package/web/.next/static/chunks/{a6363f73e05ccf47.js → ad38e805c7d1a020.js} +1 -1
  205. package/web/.next/static/chunks/aed3ea7e8478cbee.js +1 -0
  206. package/web/.next/static/chunks/{b7126c0b3a97e77e.js → b37e4ffbcbeec1ee.js} +1 -1
  207. package/web/.next/static/chunks/cd88a4cf2cb1b10f.js +1 -0
  208. package/web/.next/static/chunks/{d3df6e6434e16519.js → cdab8d275a2bcad7.js} +1 -1
  209. package/web/.next/server/chunks/ssr/_0c5f56e3._.js.map +0 -1
  210. package/web/.next/server/chunks/ssr/_64bdfc6f._.js.map +0 -1
  211. package/web/.next/static/chunks/4ef564fb1174e497.js +0 -1
  212. package/web/.next/static/chunks/79dc2e2f1c2ff519.js +0 -1
  213. package/web/.next/static/chunks/a086f8dfef2c3325.js +0 -1
  214. /package/web/.next/static/{1CQHYZVn3VajyhdvnsCaw → IJF6SpQ55CcjAxQmThTSs}/_buildManifest.js +0 -0
  215. /package/web/.next/static/{1CQHYZVn3VajyhdvnsCaw → IJF6SpQ55CcjAxQmThTSs}/_clientMiddlewareManifest.json +0 -0
  216. /package/web/.next/static/{1CQHYZVn3VajyhdvnsCaw → IJF6SpQ55CcjAxQmThTSs}/_ssgManifest.js +0 -0
@@ -29,6 +29,12 @@ export declare class GitHubUrlParseError extends Error {
29
29
  export declare class GitHubRepoListError extends Error {
30
30
  constructor(message: string, cause?: Error);
31
31
  }
32
+ /**
33
+ * Thrown when checking the viewer's permission on a repository fails.
34
+ */
35
+ export declare class GitHubPermissionError extends Error {
36
+ constructor(message: string, cause?: Error);
37
+ }
32
38
  /**
33
39
  * A GitHub repository as returned by `gh repo list --json`.
34
40
  */
@@ -114,5 +120,16 @@ export interface IGitHubRepositoryService {
114
120
  * @throws {GitHubUrlParseError} if the URL does not match any supported format
115
121
  */
116
122
  parseGitHubUrl(url: string): ParsedGitHubUrl;
123
+ /**
124
+ * Get the authenticated user's permission level on a GitHub repository.
125
+ *
126
+ * Uses `gh repo view --json viewerPermission` with the given repo path
127
+ * as the working directory.
128
+ *
129
+ * @param repoPath - Absolute path to a local clone of the repository
130
+ * @returns The viewer's permission level: "ADMIN", "MAINTAIN", "WRITE", "TRIAGE", or "READ"
131
+ * @throws {GitHubPermissionError} if the permission check fails (e.g. gh not installed, not authenticated)
132
+ */
133
+ getViewerPermission(repoPath: string): Promise<string>;
117
134
  }
118
135
  //# sourceMappingURL=github-repository-service.interface.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-repository-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAMD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B;;;;;;;OAOG;IACH,eAAe,CACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;OAMG;IACH,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEnF;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;CAC9C"}
1
+ {"version":3,"file":"github-repository-service.interface.d.ts","sourceRoot":"","sources":["../../../../../../../../packages/core/src/application/ports/output/services/github-repository-service.interface.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH;;GAEG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;gBAC7B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAED;;GAEG;AACH,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK;CAM3C;AAMD;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,6DAA6D;IAC7D,aAAa,EAAE,MAAM,CAAC;IACtB,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,SAAS,EAAE,OAAO,CAAC;IACnB,iDAAiD;IACjD,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC1C,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,4EAA4E;IAC5E,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,sDAAsD;IACtD,aAAa,EAAE,MAAM,CAAC;CACvB;AAMD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC;;;;OAIG;IACH,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3B;;;;;;;OAOG;IACH,eAAe,CACb,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;;;;;OAMG;IACH,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC;IAEnF;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,CAAC;IAE7C;;;;;;;;;OASG;IACH,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CACxD"}
@@ -56,3 +56,15 @@ export class GitHubRepoListError extends Error {
56
56
  this.cause = cause;
57
57
  }
58
58
  }
59
+ /**
60
+ * Thrown when checking the viewer's permission on a repository fails.
61
+ */
62
+ export class GitHubPermissionError extends Error {
63
+ constructor(message, cause) {
64
+ super(message);
65
+ this.name = 'GitHubPermissionError';
66
+ Object.setPrototypeOf(this, new.target.prototype);
67
+ if (cause)
68
+ this.cause = cause;
69
+ }
70
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"get-branch-sync-status.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/get-branch-sync-status.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAElG,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBACa,0BAA0B;IAGnC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAJf,WAAW,EAAE,kBAAkB,EAE/B,YAAY,EAAE,aAAa,EAE3B,eAAe,EAAE,gBAAgB;IAG9C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;YA0BnD,UAAU;CAOzB"}
1
+ {"version":3,"file":"get-branch-sync-status.use-case.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/application/use-cases/features/get-branch-sync-status.use-case.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iEAAiE,CAAC;AAC1G,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yDAAyD,CAAC;AAC7F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2DAA2D,CAAC;AAElG,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,qBACa,0BAA0B;IAGnC,OAAO,CAAC,QAAQ,CAAC,WAAW;IAE5B,OAAO,CAAC,QAAQ,CAAC,YAAY;IAE7B,OAAO,CAAC,QAAQ,CAAC,eAAe;gBAJf,WAAW,EAAE,kBAAkB,EAE/B,YAAY,EAAE,aAAa,EAE3B,eAAe,EAAE,gBAAgB;IAG9C,OAAO,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,sBAAsB,CAAC;YA+BnD,UAAU;CAOzB"}
@@ -38,6 +38,10 @@ let GetBranchSyncStatusUseCase = class GetBranchSyncStatusUseCase {
38
38
  throw new Error(`Feature "${featureId}" has no branch`);
39
39
  }
40
40
  const cwd = await this.resolveCwd(feature.repositoryPath, feature.branch);
41
+ const hasRemote = await this.gitPrService.hasRemote(cwd);
42
+ if (!hasRemote) {
43
+ throw new Error('Repository has no remote — branch sync is not available');
44
+ }
41
45
  const baseBranch = await this.gitPrService.getDefaultBranch(feature.repositoryPath);
42
46
  // Sync the remote tracking ref so ahead/behind counts are current
43
47
  await this.gitPrService.syncMain(cwd, baseBranch);
@@ -13,6 +13,7 @@ export declare class GitHubRepositoryService implements IGitHubRepositoryService
13
13
  listUserRepositories(options?: ListUserRepositoriesOptions): Promise<GitHubRepo[]>;
14
14
  cloneRepository(nameWithOwner: string, destination: string, options?: CloneOptions): Promise<void>;
15
15
  parseGitHubUrl(url: string): ParsedGitHubUrl;
16
+ getViewerPermission(repoPath: string): Promise<string>;
16
17
  private cleanupPartialClone;
17
18
  }
18
19
  //# sourceMappingURL=github-repository.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"github-repository.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/external/github-repository.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EACV,wBAAwB,EACxB,UAAU,EACV,2BAA2B,EAC3B,YAAY,EACZ,eAAe,EAChB,MAAM,mFAAmF,CAAC;AAwB3F,qBACa,uBAAwB,YAAW,wBAAwB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB1B,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAsClF,eAAe,CACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC;IAgDhB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;YA2C9B,mBAAmB;CAOlC"}
1
+ {"version":3,"file":"github-repository.service.d.ts","sourceRoot":"","sources":["../../../../../../../packages/core/src/infrastructure/services/external/github-repository.service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAC/D,OAAO,KAAK,EACV,wBAAwB,EACxB,UAAU,EACV,2BAA2B,EAC3B,YAAY,EACZ,eAAe,EAChB,MAAM,mFAAmF,CAAC;AAyB3F,qBACa,uBAAwB,YAAW,wBAAwB;IAClC,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,YAAY;IAErE,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAyB1B,oBAAoB,CAAC,OAAO,CAAC,EAAE,2BAA2B,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC;IAsClF,eAAe,CACnB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,IAAI,CAAC;IAgDhB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe;IA2CtC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAyB9C,mBAAmB;CAOlC"}
@@ -20,7 +20,7 @@ import { injectable, inject } from 'tsyringe';
20
20
  import { resolve, normalize } from 'node:path';
21
21
  import { rm } from 'node:fs/promises';
22
22
  import { spawn } from 'node:child_process';
23
- import { GitHubAuthError, GitHubCloneError, GitHubRepoListError, GitHubUrlParseError, } from '../../../application/ports/output/services/github-repository-service.interface.js';
23
+ import { GitHubAuthError, GitHubCloneError, GitHubPermissionError, GitHubRepoListError, GitHubUrlParseError, } from '../../../application/ports/output/services/github-repository-service.interface.js';
24
24
  // ---------------------------------------------------------------------------
25
25
  // URL regex patterns
26
26
  // ---------------------------------------------------------------------------
@@ -154,6 +154,23 @@ let GitHubRepositoryService = class GitHubRepositoryService {
154
154
  'Supported formats: https://github.com/owner/repo, ' +
155
155
  'git@github.com:owner/repo.git, or owner/repo shorthand.');
156
156
  }
157
+ async getViewerPermission(repoPath) {
158
+ try {
159
+ const { stdout } = await this.execFile('gh', ['repo', 'view', '--json', 'viewerPermission'], {
160
+ cwd: repoPath,
161
+ });
162
+ const parsed = JSON.parse(stdout);
163
+ return parsed.viewerPermission;
164
+ }
165
+ catch (error) {
166
+ const cause = error instanceof Error ? error : undefined;
167
+ const errnoCode = error?.code;
168
+ if (errnoCode === 'ENOENT') {
169
+ throw new GitHubPermissionError('GitHub CLI (gh) is not installed. Install it from https://cli.github.com/', cause);
170
+ }
171
+ throw new GitHubPermissionError(`Failed to check repository permission: ${cause?.message ?? String(error)}`, cause);
172
+ }
173
+ }
157
174
  async cleanupPartialClone(destination) {
158
175
  try {
159
176
  await rm(destination, { recursive: true, force: true });
@@ -1 +1 @@
1
- {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/create/page.tsx"],"names":[],"mappings":"AAOA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,qBAAqB;IAC7B,YAAY,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,wBAA8B,gBAAgB,CAAC,EAAE,YAAY,EAAE,EAAE,qBAAqB,oDAmCrF"}
1
+ {"version":3,"file":"page.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/(dashboard)/@drawer/create/page.tsx"],"names":[],"mappings":"AAQA,oEAAoE;AACpE,eAAO,MAAM,OAAO,kBAAkB,CAAC;AAEvC,UAAU,qBAAqB;IAC7B,YAAY,EAAE,OAAO,CAAC;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC5E;AAED,wBAA8B,gBAAgB,CAAC,EAAE,YAAY,EAAE,EAAE,qBAAqB,oDAuCrF"}
@@ -2,6 +2,7 @@ import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { resolve } from '../../../../lib/server-container.js';
3
3
  import { getSettings } from '../../../../../../../packages/core/src/infrastructure/services/settings.service.js';
4
4
  import { getWorkflowDefaults } from '../../../actions/get-workflow-defaults.js';
5
+ import { getViewerPermission } from '../../../actions/get-viewer-permission.js';
5
6
  import { CreateDrawerClient } from '../../../../components/common/control-center-drawer/create-drawer-client.js';
6
7
  /** Skip static pre-rendering since we need runtime DI container. */
7
8
  export const dynamic = 'force-dynamic';
@@ -10,10 +11,13 @@ export default async function CreateDrawerPage({ searchParams }) {
10
11
  const listFeatures = resolve('ListFeaturesUseCase');
11
12
  const listRepos = resolve('ListRepositoriesUseCase');
12
13
  const settings = getSettings();
13
- const [features, repositories, workflowDefaults] = await Promise.all([
14
+ const [features, repositories, workflowDefaults, viewerPerm] = await Promise.all([
14
15
  listFeatures.execute(),
15
16
  listRepos.execute().catch(() => []),
16
17
  getWorkflowDefaults().catch(() => undefined),
18
+ repo
19
+ ? getViewerPermission(repo).catch(() => ({ canPushDirectly: false }))
20
+ : Promise.resolve({ canPushDirectly: false }),
17
21
  ]);
18
22
  const featureOptions = features
19
23
  .map((f) => ({ id: f.id, name: f.name }))
@@ -23,5 +27,5 @@ export default async function CreateDrawerPage({ searchParams }) {
23
27
  name: r.name,
24
28
  path: r.path,
25
29
  }));
26
- return (_jsx(CreateDrawerClient, { repositoryPath: repo ?? '', initialParentId: parent, initialDescription: prompt, features: featureOptions, repositories: repositoryOptions, workflowDefaults: workflowDefaults, currentAgentType: settings.agent.type, currentModel: settings.models.default }));
30
+ return (_jsx(CreateDrawerClient, { repositoryPath: repo ?? '', initialParentId: parent, initialDescription: prompt, features: featureOptions, repositories: repositoryOptions, workflowDefaults: workflowDefaults, currentAgentType: settings.agent.type, currentModel: settings.models.default, canPushDirectly: viewerPerm.canPushDirectly }));
27
31
  }
@@ -0,0 +1,4 @@
1
+ export declare function getViewerPermission(repoPath: string): Promise<{
2
+ canPushDirectly: boolean;
3
+ }>;
4
+ //# sourceMappingURL=get-viewer-permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-viewer-permission.d.ts","sourceRoot":"","sources":["../../../../../../src/presentation/web/app/actions/get-viewer-permission.ts"],"names":[],"mappings":"AAQA,wBAAsB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,eAAe,EAAE,OAAO,CAAA;CAAE,CAAC,CAQjG"}
@@ -0,0 +1,14 @@
1
+ 'use server';
2
+ import { resolve } from '../../lib/server-container.js';
3
+ /** Permissions that grant direct push access to a repository. */
4
+ const PUSH_PERMISSIONS = new Set(['ADMIN', 'MAINTAIN', 'WRITE']);
5
+ export async function getViewerPermission(repoPath) {
6
+ try {
7
+ const service = resolve('IGitHubRepositoryService');
8
+ const permission = await service.getViewerPermission(repoPath);
9
+ return { canPushDirectly: PUSH_PERMISSIONS.has(permission) };
10
+ }
11
+ catch {
12
+ return { canPushDirectly: false };
13
+ }
14
+ }
@@ -10,6 +10,7 @@ export interface CreateDrawerClientProps {
10
10
  workflowDefaults?: WorkflowDefaults;
11
11
  currentAgentType?: string;
12
12
  currentModel?: string;
13
+ canPushDirectly?: boolean;
13
14
  }
14
- export declare function CreateDrawerClient({ repositoryPath, initialParentId, initialDescription, features, repositories, workflowDefaults, currentAgentType, currentModel, }: CreateDrawerClientProps): import("react/jsx-runtime").JSX.Element;
15
+ export declare function CreateDrawerClient({ repositoryPath, initialParentId, initialDescription, features, repositories, workflowDefaults, currentAgentType, currentModel, canPushDirectly, }: CreateDrawerClientProps): import("react/jsx-runtime").JSX.Element;
15
16
  //# sourceMappingURL=create-drawer-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"create-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAC3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iEAAiE,CAAC;AACxG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,kBAAkB,CAAC,EACjC,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,GACb,EAAE,uBAAuB,2CA+EzB"}
1
+ {"version":3,"file":"create-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/create-drawer-client.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,iEAAiE,CAAC;AAC3G,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iEAAiE,CAAC;AACxG,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qCAAqC,CAAC;AAE5E,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAClC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,wBAAgB,kBAAkB,CAAC,EACjC,cAAc,EACd,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EAChB,YAAY,EACZ,eAAe,GAChB,EAAE,uBAAuB,2CAgFzB"}
@@ -5,7 +5,7 @@ import { useRouter, usePathname } from 'next/navigation';
5
5
  import { toast } from 'sonner';
6
6
  import { createFeature } from '../../../app/actions/create-feature.js';
7
7
  import { FeatureCreateDrawer } from '../../common/feature-create-drawer/index.js';
8
- export function CreateDrawerClient({ repositoryPath, initialParentId, initialDescription, features, repositories, workflowDefaults, currentAgentType, currentModel, }) {
8
+ export function CreateDrawerClient({ repositoryPath, initialParentId, initialDescription, features, repositories, workflowDefaults, currentAgentType, currentModel, canPushDirectly, }) {
9
9
  const router = useRouter();
10
10
  const [isSubmitting, setIsSubmitting] = useState(false);
11
11
  // Derive open state from the URL. Next.js parallel routes preserve slot
@@ -56,5 +56,5 @@ export function CreateDrawerClient({ repositoryPath, initialParentId, initialDes
56
56
  setIsSubmitting(false);
57
57
  });
58
58
  }, [router]);
59
- return (_jsx(FeatureCreateDrawer, { open: isOpen, onClose: onClose, onSubmit: onSubmit, repositoryPath: repositoryPath, features: features, repositories: repositories, workflowDefaults: workflowDefaults, initialParentId: initialParentId, initialDescription: initialDescription, isSubmitting: isSubmitting, currentAgentType: currentAgentType, currentModel: currentModel }));
59
+ return (_jsx(FeatureCreateDrawer, { open: isOpen, onClose: onClose, onSubmit: onSubmit, repositoryPath: repositoryPath, features: features, repositories: repositories, workflowDefaults: workflowDefaults, initialParentId: initialParentId, initialDescription: initialDescription, isSubmitting: isSubmitting, currentAgentType: currentAgentType, currentModel: currentModel, canPushDirectly: canPushDirectly }));
60
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CAyoB1F"}
1
+ {"version":3,"file":"feature-drawer-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/control-center-drawer/feature-drawer-client.tsx"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAK/D,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,8FAA8F;IAC9F,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,wBAAgB,mBAAmB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,EAAE,wBAAwB,2CA4oB1F"}
@@ -333,8 +333,11 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
333
333
  }
334
334
  : null;
335
335
  const featureActions = useFeatureActions(featureActionsInput);
336
- // Branch sync status — only when the feature flag is on and the feature has a branch
337
- const syncFeatureId = featureFlags.gitRebaseSync && featureNode?.branch ? featureNode.featureId : null;
336
+ // Branch sync status — only when the feature flag is on, the feature has a branch,
337
+ // and the repository has a remote (no remote = no sync needed)
338
+ const syncFeatureId = featureFlags.gitRebaseSync && featureNode?.branch && featureNode?.remoteUrl
339
+ ? featureNode.featureId
340
+ : null;
338
341
  const { data: syncData, loading: syncLoading, error: syncError, refresh: refreshSync, } = useBranchSyncStatus(syncFeatureId);
339
342
  // Auto-refresh sync status after a successful rebase
340
343
  const prevRebaseLoadingRef = useRef(featureActions.rebaseLoading);
@@ -383,7 +386,7 @@ export function FeatureDrawerClient({ view: initialView, urlTab }) {
383
386
  ...(featureNode.state === 'error' && { onRetry: handleRetry }),
384
387
  ...(featureNode.state === 'pending' && { onStart: handleStart }),
385
388
  };
386
- body = (_jsx(FeatureDrawerTabs, { featureNode: enrichedNode, featureId: featureNode.featureId, initialTab: view.initialTab, urlTab: urlTab, sseEvents: events, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, syncStatus: featureFlags.gitRebaseSync ? syncData : undefined, syncLoading: syncLoading, syncError: syncError, onRefreshSync: featureFlags.gitRebaseSync ? refreshSync : undefined, onRebaseOnMain: featureFlags.gitRebaseSync ? featureActions.rebaseOnMain : undefined, rebaseLoading: featureActions.rebaseLoading, rebaseError: featureActions.rebaseError, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput }));
389
+ body = (_jsx(FeatureDrawerTabs, { featureNode: enrichedNode, featureId: featureNode.featureId, initialTab: view.initialTab, urlTab: urlTab, sseEvents: events, prdData: prdData, prdSelections: prdSelections, onPrdSelect: (qId, oId) => setPrdSelections((prev) => ({ ...prev, [qId]: oId })), onPrdApprove: handlePrdApprove, onPrdReject: handlePrdReject, isPrdLoading: isLoadingPrd, techData: techData, onTechApprove: handleTechApprove, onTechReject: handleTechReject, isTechLoading: isLoadingTech, productData: isLoadingTechProduct ? null : techProductData, mergeData: mergeData, onMergeApprove: handleMergeApprove, onMergeReject: handleMergeReject, isMergeLoading: isLoadingMerge, syncStatus: syncFeatureId ? syncData : undefined, syncLoading: syncLoading, syncError: syncError, onRefreshSync: syncFeatureId ? refreshSync : undefined, onRebaseOnMain: syncFeatureId ? featureActions.rebaseOnMain : undefined, rebaseLoading: featureActions.rebaseLoading, rebaseError: featureActions.rebaseError, isRejecting: isRejecting, chatInput: chatInput, onChatInputChange: setChatInput }));
387
390
  }
388
391
  return (_jsx(BaseDrawer, { open: isOpen, onClose: attemptClose, size: "md", modal: false, header: header, "data-testid": view.type === 'feature' ? 'feature-drawer' : 'repository-drawer', children: body }));
389
392
  }
@@ -70,8 +70,10 @@ export interface FeatureCreateDrawerProps {
70
70
  currentModel?: string;
71
71
  /** Pre-fill the description textarea (e.g. from session context) */
72
72
  initialDescription?: string;
73
+ /** When true, user has push access — Fork & PR toggle will be hidden. */
74
+ canPushDirectly?: boolean;
73
75
  }
74
- export declare function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, isSubmitting, workflowDefaults, features, repositories, initialParentId, currentAgentType, currentModel, initialDescription, }: FeatureCreateDrawerProps): import("react/jsx-runtime").JSX.Element;
76
+ export declare function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, isSubmitting, workflowDefaults, features, repositories, initialParentId, currentAgentType, currentModel, initialDescription, canPushDirectly, }: FeatureCreateDrawerProps): import("react/jsx-runtime").JSX.Element;
75
77
  export interface RepositoryComboboxProps {
76
78
  repositories: RepositoryOption[];
77
79
  value: string | undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"feature-create-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.tsx"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import { Switch } from '../../ui/switch.js';
16
16
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../../ui/tooltip.js';
17
17
  import { useGuardedDrawerClose } from '../../../hooks/drawer-close-guard.js';
18
18
  import { AttachmentChip } from '../../common/attachment-chip/index.js';
19
+ import { getViewerPermission } from '../../../app/actions/get-viewer-permission.js';
19
20
  import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
20
21
  import { Separator } from '../../ui/separator.js';
21
22
  import { pickFolder } from '../../common/add-repository-button/pick-folder.js';
@@ -95,7 +96,7 @@ const EMPTY_GATES = {
95
96
  allowPlan: false,
96
97
  allowMerge: false,
97
98
  };
98
- export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, isSubmitting = false, workflowDefaults, features, repositories, initialParentId, currentAgentType, currentModel, initialDescription, }) {
99
+ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, isSubmitting = false, workflowDefaults, features, repositories, initialParentId, currentAgentType, currentModel, initialDescription, canPushDirectly, }) {
99
100
  const createSound = useSoundAction('create');
100
101
  // Validate repositoryPath from URL against active repos — prevents stale URL params
101
102
  // from selecting deleted repos after add/delete/re-add cycles.
@@ -165,6 +166,31 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
165
166
  setParentId(initialParentId);
166
167
  }
167
168
  }, [open, initialParentId]);
169
+ // Permission-aware Fork & PR toggle visibility
170
+ const [canPush, setCanPush] = useState(canPushDirectly ?? false);
171
+ // Sync canPush from prop when it changes (e.g. initial server-side value)
172
+ useEffect(() => {
173
+ setCanPush(canPushDirectly ?? false);
174
+ }, [canPushDirectly]);
175
+ // Re-check permission when user switches repos via the combobox
176
+ const prevRepoRef = useRef(selectedRepoPath);
177
+ useEffect(() => {
178
+ if (selectedRepoPath && selectedRepoPath !== prevRepoRef.current) {
179
+ prevRepoRef.current = selectedRepoPath;
180
+ getViewerPermission(selectedRepoPath)
181
+ .then((result) => setCanPush(result.canPushDirectly))
182
+ .catch(() => setCanPush(false));
183
+ }
184
+ }, [selectedRepoPath]);
185
+ // Auto-reset forkAndPr and dependent states when canPush becomes true
186
+ useEffect(() => {
187
+ if (canPush) {
188
+ setForkAndPr(false);
189
+ setPush(defaultPush);
190
+ setOpenPr(defaultOpenPr);
191
+ setCommitSpecs(true);
192
+ }
193
+ }, [canPush, defaultPush, defaultOpenPr]);
168
194
  const resetForm = useCallback(() => {
169
195
  setDescription('');
170
196
  setAttachments([]);
@@ -476,12 +502,12 @@ export function FeatureCreateDrawer({ open, onClose, onSubmit, repositoryPath, i
476
502
  setCommitEvidence(false);
477
503
  }, disabled: isSubmitting || forkAndPr }), _jsx(Label, { htmlFor: "open-pr", className: cn('cursor-pointer text-xs font-medium', forkAndPr && 'opacity-50'), children: "PR" })] }) }), _jsx(TooltipContent, { side: "bottom", children: forkAndPr
478
504
  ? 'Enabled — contributing to upstream'
479
- : 'Open a pull request after pushing.' })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "ci-watch", size: "sm", checked: ciWatchEnabled, onCheckedChange: setCiWatchEnabled, disabled: isSubmitting }), _jsx(Label, { htmlFor: "ci-watch", className: "cursor-pointer text-xs font-medium", children: "Watch" })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Watch CI and auto-fix after push." })] }), _jsx("div", { className: "bg-border h-4 w-px shrink-0" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "commit-specs", size: "sm", checked: commitSpecs, onCheckedChange: setCommitSpecs, disabled: isSubmitting }), _jsxs(Label, { htmlFor: "commit-specs", className: "flex cursor-pointer items-center gap-1 text-xs font-medium", children: [_jsx(FileText, { className: "h-3 w-3" }), "Commit Specs"] })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Commit specs to repository." })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "fork-and-pr", size: "sm", checked: forkAndPr, onCheckedChange: (v) => {
505
+ : 'Open a pull request after pushing.' })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "ci-watch", size: "sm", checked: ciWatchEnabled, onCheckedChange: setCiWatchEnabled, disabled: isSubmitting }), _jsx(Label, { htmlFor: "ci-watch", className: "cursor-pointer text-xs font-medium", children: "Watch" })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Watch CI and auto-fix after push." })] }), _jsx("div", { className: "bg-border h-4 w-px shrink-0" }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "commit-specs", size: "sm", checked: commitSpecs, onCheckedChange: setCommitSpecs, disabled: isSubmitting }), _jsxs(Label, { htmlFor: "commit-specs", className: "flex cursor-pointer items-center gap-1 text-xs font-medium", children: [_jsx(FileText, { className: "h-3 w-3" }), "Commit Specs"] })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Commit specs to repository." })] }), !canPush && (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsxs("div", { className: "flex cursor-pointer items-center gap-1.5", children: [_jsx(Switch, { id: "fork-and-pr", size: "sm", checked: forkAndPr, onCheckedChange: (v) => {
480
506
  setForkAndPr(v);
481
507
  // Auto-flip commitSpecs to false when enabling contribute mode
482
508
  if (v)
483
509
  setCommitSpecs(false);
484
- }, disabled: isSubmitting }), _jsxs(Label, { htmlFor: "fork-and-pr", className: "flex cursor-pointer items-center gap-1 text-xs font-medium", children: [_jsx(GitFork, { className: "h-3 w-3" }), "Fork & PR"] })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Contribute via fork (PR to upstream)." })] })] })] })] })] }) }) }) }));
510
+ }, disabled: isSubmitting }), _jsxs(Label, { htmlFor: "fork-and-pr", className: "flex cursor-pointer items-center gap-1 text-xs font-medium", children: [_jsx(GitFork, { className: "h-3 w-3" }), "Fork & PR"] })] }) }), _jsx(TooltipContent, { side: "bottom", children: "Contribute via fork (PR to upstream)." })] }))] })] })] })] }) }) }) }));
485
511
  }
486
512
  function ParentFeatureCombobox({ features, value, onChange, disabled, }) {
487
513
  const [open, setOpen] = useState(false);
@@ -143,4 +143,14 @@ export declare const WithRepoSelector: Story;
143
143
  * The submit button remains disabled until a repository is added.
144
144
  */
145
145
  export declare const WithRepoSelectorEmpty: Story;
146
+ /**
147
+ * Fork & PR toggle visible — user does NOT have push access (canPushDirectly=false).
148
+ * The Fork & PR toggle is rendered in the GIT row.
149
+ */
150
+ export declare const ForkToggleVisible: Story;
151
+ /**
152
+ * Fork & PR toggle hidden — user HAS push access (canPushDirectly=true).
153
+ * The Fork & PR toggle is not rendered in the GIT row.
154
+ */
155
+ export declare const ForkToggleHidden: Story;
146
156
  //# sourceMappingURL=feature-create-drawer.stories.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"feature-create-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAU9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAgC1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAmDlD,uFAAuF;AACvF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAiBvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAMhC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAeF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAWlC,CAAC;AAkDF,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAwCF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,KAY3B,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,KAwCzB,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAU9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,KAatC,CAAC;AAuCF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AA6BF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAMnC,CAAC"}
1
+ {"version":3,"file":"feature-create-drawer.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/feature-create-drawer/feature-create-drawer.stories.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAU9D;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,OAAO,mBAAmB,CAgC1C,CAAC;AAEF,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAsDlD,uFAAuF;AACvF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAiBvB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,kBAAkB,EAAE,KAMhC,CAAC;AAEF,4DAA4D;AAC5D,eAAO,MAAM,SAAS,EAAE,KAMvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,OAAO,EAAE,KAUrB,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,SAAS,EAAE,KAUvB,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,EAAE,KAUxB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAeF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,KAWlC,CAAC;AAkDF,+EAA+E;AAC/E,eAAO,MAAM,QAAQ,EAAE,KAEtB,CAAC;AAwCF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAM/B,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,KAgBjC,CAAC;AAMF;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,KAY3B,CAAC;AAMF,eAAO,MAAM,WAAW,EAAE,KAwCzB,CAAC;AAMF;;;;;GAKG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAU9B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,EAAE,KAatC,CAAC;AAuCF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAM9B,CAAC;AA6BF;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,EAAE,KAMnC,CAAC;AAMF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,KAU/B,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,KAa9B,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { useState } from 'react';
3
- import { within, userEvent, fn } from '@storybook/test';
3
+ import { within, userEvent, fn, expect } from '@storybook/test';
4
4
  import { FeatureCreateDrawer } from './feature-create-drawer.js';
5
5
  import { Button } from '../../ui/button.js';
6
6
  import { DrawerCloseGuardProvider } from '../../../hooks/drawer-close-guard.js';
@@ -73,7 +73,7 @@ const logClose = fn().mockName('onClose');
73
73
  * Trigger wrapper — every story uses this so nothing auto-opens on Docs page
74
74
  * ------------------------------------------------------------------------- */
75
75
  /** Starts closed — click button to open. Actions are logged. */
76
- function CreateDrawerTrigger({ label = 'Open Create Feature', workflowDefaults, }) {
76
+ function CreateDrawerTrigger({ label = 'Open Create Feature', workflowDefaults, canPushDirectly, }) {
77
77
  const [open, setOpen] = useState(false);
78
78
  return (_jsxs("div", { className: "flex h-screen items-start p-4", children: [_jsx(Button, { variant: "outline", onClick: () => setOpen(true), children: label }), _jsx(FeatureCreateDrawer, { open: open, onClose: () => {
79
79
  setOpen(false);
@@ -81,7 +81,7 @@ function CreateDrawerTrigger({ label = 'Open Create Feature', workflowDefaults,
81
81
  }, onSubmit: (data) => {
82
82
  logSubmit(data);
83
83
  setOpen(false);
84
- }, repositoryPath: "/Users/dev/my-repo", workflowDefaults: workflowDefaults, currentAgentType: "claude-code", currentModel: "claude-sonnet-4-6" })] }));
84
+ }, repositoryPath: "/Users/dev/my-repo", workflowDefaults: workflowDefaults, canPushDirectly: canPushDirectly, currentAgentType: "claude-code", currentModel: "claude-sonnet-4-6" })] }));
85
85
  }
86
86
  /* ---------------------------------------------------------------------------
87
87
  * Per-state stories
@@ -484,3 +484,37 @@ export const WithRepoSelectorEmpty = {
484
484
  await userEvent.click(canvas.getByRole('button', { name: 'Open (No Repos)' }));
485
485
  },
486
486
  };
487
+ /* ---------------------------------------------------------------------------
488
+ * Fork & PR toggle visibility stories (canPushDirectly)
489
+ * ------------------------------------------------------------------------- */
490
+ /**
491
+ * Fork & PR toggle visible — user does NOT have push access (canPushDirectly=false).
492
+ * The Fork & PR toggle is rendered in the GIT row.
493
+ */
494
+ export const ForkToggleVisible = {
495
+ render: () => _jsx(CreateDrawerTrigger, { label: "Open (Fork Toggle Visible)", canPushDirectly: false }),
496
+ play: async ({ canvasElement }) => {
497
+ const canvas = within(canvasElement);
498
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Fork Toggle Visible)' }));
499
+ const body = within(canvasElement.ownerDocument.body);
500
+ const forkToggle = await body.findByLabelText('Fork & PR');
501
+ await expect(forkToggle).toBeInTheDocument();
502
+ },
503
+ };
504
+ /**
505
+ * Fork & PR toggle hidden — user HAS push access (canPushDirectly=true).
506
+ * The Fork & PR toggle is not rendered in the GIT row.
507
+ */
508
+ export const ForkToggleHidden = {
509
+ render: () => _jsx(CreateDrawerTrigger, { label: "Open (Fork Toggle Hidden)", canPushDirectly: true }),
510
+ play: async ({ canvasElement }) => {
511
+ const canvas = within(canvasElement);
512
+ await userEvent.click(canvas.getByRole('button', { name: 'Open (Fork Toggle Hidden)' }));
513
+ const body = within(canvasElement.ownerDocument.body);
514
+ // Wait for drawer to render
515
+ await body.findByText('GIT');
516
+ // Fork & PR toggle should NOT be in the DOM
517
+ const forkToggle = body.queryByLabelText('Fork & PR');
518
+ await expect(forkToggle).toBeNull();
519
+ },
520
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"next.config.d.ts","sourceRoot":"","sources":["../../../../src/presentation/web/next.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAiDvC,QAAA,MAAM,UAAU,EAAE,UAsCjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
1
+ {"version":3,"file":"next.config.d.ts","sourceRoot":"","sources":["../../../../src/presentation/web/next.config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAiDvC,QAAA,MAAM,UAAU,EAAE,UAkCjB,CAAC;AAEF,eAAe,UAAU,CAAC"}
@@ -67,9 +67,6 @@ const nextConfig = {
67
67
  distDir: '.next',
68
68
  // Inject version info from package.json for the web UI
69
69
  env: loadDevFallbacks(),
70
- // Use standalone output mode for server-side rendering on demand
71
- // This prevents issues with statically prerendering pages that depend on client context
72
- output: 'standalone',
73
70
  // Allow attachment uploads up to 11 MB (10 MB limit + multipart overhead)
74
71
  experimental: {
75
72
  serverActions: {