@shipit-ai/cli 1.166.1 → 1.166.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (283) hide show
  1. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.d.ts.map +1 -1
  2. package/dist/packages/core/src/application/use-cases/features/create/create-feature.use-case.js +19 -2
  3. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.d.ts.map +1 -1
  4. package/dist/packages/core/src/infrastructure/services/external/github-repository.service.js +14 -3
  5. package/dist/src/presentation/web/app/actions/deploy-repository.d.ts.map +1 -1
  6. package/dist/src/presentation/web/app/actions/deploy-repository.js +14 -7
  7. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -1
  8. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +66 -23
  9. package/dist/src/presentation/web/app/actions/open-folder.d.ts.map +1 -1
  10. package/dist/src/presentation/web/app/actions/open-folder.js +12 -4
  11. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  12. package/dist/src/presentation/web/app/actions/open-shell.js +46 -7
  13. package/dist/src/presentation/web/app/api/agent-events/route.d.ts.map +1 -1
  14. package/dist/src/presentation/web/app/api/agent-events/route.js +2 -6
  15. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.d.ts.map +1 -1
  16. package/dist/src/presentation/web/app/api/attachments/upload-from-path/route.js +21 -17
  17. package/dist/src/presentation/web/app/api/deployment-logs/route.d.ts.map +1 -1
  18. package/dist/src/presentation/web/app/api/deployment-logs/route.js +2 -6
  19. package/dist/src/presentation/web/app/api/directory/list/route.d.ts.map +1 -1
  20. package/dist/src/presentation/web/app/api/directory/list/route.js +39 -24
  21. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.d.ts.map +1 -1
  22. package/dist/src/presentation/web/app/api/interactive/chat/[featureId]/stream/route.js +2 -6
  23. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.d.ts.map +1 -1
  24. package/dist/src/presentation/web/app/api/interactive/sessions/[id]/stream/route.js +2 -6
  25. package/dist/src/presentation/web/lib/path-sanitizers.d.ts +50 -0
  26. package/dist/src/presentation/web/lib/path-sanitizers.d.ts.map +1 -0
  27. package/dist/src/presentation/web/lib/path-sanitizers.js +136 -0
  28. package/dist/tsconfig.build.tsbuildinfo +1 -1
  29. package/package.json +6 -6
  30. package/web/.next/BUILD_ID +1 -1
  31. package/web/.next/build-manifest.json +3 -3
  32. package/web/.next/fallback-build-manifest.json +3 -3
  33. package/web/.next/prerender-manifest.json +3 -3
  34. package/web/.next/required-server-files.js +2 -2
  35. package/web/.next/required-server-files.json +2 -2
  36. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  37. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  38. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  39. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  40. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  41. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -1
  42. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  43. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  44. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +30 -30
  45. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  46. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  47. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  48. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  49. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +3 -2
  50. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  51. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  52. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  53. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +3 -2
  54. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  55. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  56. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  57. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -1
  58. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  59. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  60. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  61. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  62. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  63. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  64. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  65. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  66. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  67. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  68. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +30 -30
  69. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  70. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  71. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  72. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  73. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +3 -2
  74. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  75. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  76. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  77. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +3 -2
  78. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  79. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  80. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  81. package/web/.next/server/app/(dashboard)/page.js +1 -1
  82. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  83. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  84. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  85. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -1
  86. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  87. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  88. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  89. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  90. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  91. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  92. package/web/.next/server/app/_global-error.html +1 -1
  93. package/web/.next/server/app/_global-error.rsc +1 -1
  94. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  95. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  96. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  97. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  98. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  99. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  100. package/web/.next/server/app/_not-found/page.js +1 -1
  101. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  102. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  103. package/web/.next/server/app/api/agent-events/route.js +2 -1
  104. package/web/.next/server/app/api/agent-events/route.js.nft.json +1 -1
  105. package/web/.next/server/app/api/attachments/preview/route.js +1 -1
  106. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  107. package/web/.next/server/app/api/attachments/upload-from-path/route.js +1 -1
  108. package/web/.next/server/app/api/attachments/upload-from-path/route.js.nft.json +1 -1
  109. package/web/.next/server/app/api/deployment-logs/route.js +2 -1
  110. package/web/.next/server/app/api/deployment-logs/route.js.nft.json +1 -1
  111. package/web/.next/server/app/api/dialog/pick-files/route.js +1 -1
  112. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  113. package/web/.next/server/app/api/directory/list/route.js +1 -1
  114. package/web/.next/server/app/api/directory/list/route.js.nft.json +1 -1
  115. package/web/.next/server/app/api/evidence/route.js +1 -1
  116. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  117. package/web/.next/server/app/api/graph-data/route.js +1 -1
  118. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  119. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js +1 -1
  120. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  121. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js +2 -1
  122. package/web/.next/server/app/api/interactive/chat/[featureId]/stream/route.js.nft.json +1 -1
  123. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js +2 -1
  124. package/web/.next/server/app/api/interactive/sessions/[id]/stream/route.js.nft.json +1 -1
  125. package/web/.next/server/app/api/sessions-batch/route.js +1 -1
  126. package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
  127. package/web/.next/server/app/settings/page/server-reference-manifest.json +11 -11
  128. package/web/.next/server/app/settings/page.js +1 -1
  129. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  130. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  131. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  132. package/web/.next/server/app/skills/page.js +1 -1
  133. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  134. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  135. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  136. package/web/.next/server/app/tools/page.js +1 -1
  137. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  138. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  140. package/web/.next/server/app/version/page.js +1 -1
  141. package/web/.next/server/app/version/page.js.nft.json +1 -1
  142. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  143. package/web/.next/server/chunks/{[root-of-the-server]__02xmnal._.js → [root-of-the-server]__08cpfre._.js} +2 -2
  144. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js +3 -0
  145. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js.map +1 -0
  146. package/web/.next/server/chunks/[root-of-the-server]__0aft8l4._.js +9 -0
  147. package/web/.next/server/chunks/{[root-of-the-server]__0_6fhza._.js.map → [root-of-the-server]__0aft8l4._.js.map} +1 -1
  148. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js +3 -0
  149. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js.map +1 -0
  150. package/web/.next/server/chunks/{[root-of-the-server]__0.2exzi._.js → [root-of-the-server]__0gfvkg8._.js} +2 -2
  151. package/web/.next/server/chunks/{[root-of-the-server]__0ip_e1x._.js → [root-of-the-server]__0hcp97v._.js} +2 -2
  152. package/web/.next/server/chunks/{[root-of-the-server]__09118p2._.js → [root-of-the-server]__0iel39d._.js} +2 -2
  153. package/web/.next/server/chunks/[root-of-the-server]__0kc8ify._.js +12 -0
  154. package/web/.next/server/chunks/[root-of-the-server]__0kc8ify._.js.map +1 -0
  155. package/web/.next/server/chunks/[root-of-the-server]__0r5uk_8._.js +9 -0
  156. package/web/.next/server/chunks/[root-of-the-server]__0r5uk_8._.js.map +1 -0
  157. package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
  158. package/web/.next/server/chunks/{[root-of-the-server]__04jjtl_._.js → [root-of-the-server]__0u1jyv9._.js} +2 -2
  159. package/web/.next/server/chunks/{[root-of-the-server]__07suer1._.js → [root-of-the-server]__0zu_byw._.js} +2 -2
  160. package/web/.next/server/chunks/[root-of-the-server]__13e2_kk._.js +18 -0
  161. package/web/.next/server/chunks/[root-of-the-server]__13e2_kk._.js.map +1 -0
  162. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js +1 -1
  163. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_adopt_page_actions_00~eq5i.js.map +1 -1
  164. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js +1 -1
  165. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_@drawer_chat_page_actions_0979_c..js.map +1 -1
  166. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js +1 -1
  167. package/web/.next/server/chunks/ssr/0j.8_web__next-internal_server_app_(dashboard)_chat_page_actions_0dqll_1.js.map +1 -1
  168. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
  169. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
  170. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
  171. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
  172. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
  173. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
  174. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
  175. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
  176. package/web/.next/server/chunks/ssr/[root-of-the-server]__04nnbmc._.js +3 -0
  177. package/web/.next/server/chunks/ssr/[root-of-the-server]__04nnbmc._.js.map +1 -0
  178. package/web/.next/server/chunks/ssr/[root-of-the-server]__07740t6._.js +3 -0
  179. package/web/.next/server/chunks/ssr/[root-of-the-server]__07740t6._.js.map +1 -0
  180. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l~puw4._.js +3 -0
  181. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l~puw4._.js.map +1 -0
  182. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js +1 -1
  183. package/web/.next/server/chunks/ssr/[root-of-the-server]__0o3qggc._.js.map +1 -1
  184. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0qh.wn.._.js → [root-of-the-server]__0q3-gz.._.js} +2 -2
  185. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
  186. package/web/.next/server/chunks/ssr/[root-of-the-server]__0vwjc_m._.js +3 -0
  187. package/web/.next/server/chunks/ssr/[root-of-the-server]__0vwjc_m._.js.map +1 -0
  188. package/web/.next/server/chunks/ssr/{[root-of-the-server]__12g8h3_._.js → [root-of-the-server]__0w4__yd._.js} +3 -3
  189. package/web/.next/server/chunks/ssr/_01mq~sm._.js +1 -1
  190. package/web/.next/server/chunks/ssr/_01mq~sm._.js.map +1 -1
  191. package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
  192. package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
  193. package/web/.next/server/chunks/ssr/{_0e4npv~._.js → _04rrcmm._.js} +2 -2
  194. package/web/.next/server/chunks/ssr/{_0e4npv~._.js.map → _04rrcmm._.js.map} +1 -1
  195. package/web/.next/server/chunks/ssr/{_0nvrqsj._.js → _0c497sr._.js} +2 -2
  196. package/web/.next/server/chunks/ssr/{_0nvrqsj._.js.map → _0c497sr._.js.map} +1 -1
  197. package/web/.next/server/chunks/ssr/{_0a-ddx-._.js → _0c741v_._.js} +2 -2
  198. package/web/.next/server/chunks/ssr/{_0a-ddx-._.js.map → _0c741v_._.js.map} +1 -1
  199. package/web/.next/server/chunks/ssr/_0jpbsh_._.js +1 -1
  200. package/web/.next/server/chunks/ssr/_0jpbsh_._.js.map +1 -1
  201. package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
  202. package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
  203. package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
  204. package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
  205. package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
  206. package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
  207. package/web/.next/server/chunks/ssr/_109n-y4._.js +1 -1
  208. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js +1 -1
  209. package/web/.next/server/chunks/ssr/src_presentation_web_0.e4~xc._.js.map +1 -1
  210. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js +1 -1
  211. package/web/.next/server/chunks/ssr/src_presentation_web_00dvh.m._.js.map +1 -1
  212. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js +2 -2
  213. package/web/.next/server/chunks/ssr/src_presentation_web_06b6~lt._.js.map +1 -1
  214. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js +1 -1
  215. package/web/.next/server/chunks/ssr/src_presentation_web_08fy2mf._.js.map +1 -1
  216. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js +1 -1
  217. package/web/.next/server/chunks/ssr/src_presentation_web_0f~udu1._.js.map +1 -1
  218. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js +2 -2
  219. package/web/.next/server/chunks/ssr/src_presentation_web_0qys821._.js.map +1 -1
  220. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js +1 -1
  221. package/web/.next/server/chunks/ssr/src_presentation_web_0q~dt0o._.js.map +1 -1
  222. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js +1 -1
  223. package/web/.next/server/chunks/ssr/src_presentation_web_11jrkxt._.js.map +1 -1
  224. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js +1 -1
  225. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_1199d3x.js.map +1 -1
  226. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js +1 -1
  227. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app__not-found_page_actions_0m2jqxx.js.map +1 -1
  228. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js +1 -1
  229. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_version_page_actions_0krkh_0.js.map +1 -1
  230. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +3 -0
  231. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js.map +1 -0
  232. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js +1 -1
  233. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
  234. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map +1 -1
  235. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
  236. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
  237. package/web/.next/server/middleware-build-manifest.js +3 -3
  238. package/web/.next/server/pages/500.html +1 -1
  239. package/web/.next/server/server-reference-manifest.js +1 -1
  240. package/web/.next/server/server-reference-manifest.json +49 -49
  241. package/web/.next/static/chunks/{0t.pzrmeoq6th.js → 0-fy~80ui.5os.js} +1 -1
  242. package/web/.next/static/chunks/{00dg6gti40.3i.js → 039ic1ygq-to3.js} +1 -1
  243. package/web/.next/static/chunks/{0ntgq3d_.m5el.js → 04xk1iouwcfcq.js} +3 -3
  244. package/web/.next/static/chunks/{0njrgvmyafrod.js → 07a4jt64wdipb.js} +1 -1
  245. package/web/.next/static/chunks/{14g1l3~6i5251.js → 07gx-h_y91lay.js} +1 -1
  246. package/web/.next/static/chunks/{0ist7260j__0m.js → 0_imq4rg3q.fe.js} +2 -2
  247. package/web/.next/static/chunks/{09dqgshddfxff.js → 0c_bi0dck80dt.js} +1 -1
  248. package/web/.next/static/chunks/{0awttldb-.7m..js → 0ex35-_jtxyjc.js} +1 -1
  249. package/web/.next/static/chunks/{0_c5~n__lz4ks.js → 0i084mozx131g.js} +1 -1
  250. package/web/.next/static/chunks/{0_--5mgqukm__.js → 0k~55i.ofbdeb.js} +1 -1
  251. package/web/.next/static/chunks/{0t8zwgaz.d1s5.js → 0oq-cvtg8rjjp.js} +1 -1
  252. package/web/.next/static/chunks/{0d-2jp.f._l2e.js → 0t_6hx6ul7umb.js} +1 -1
  253. package/web/.next/static/chunks/{0nk2r-18.7g6r.js → 0whez3wju~9ok.js} +1 -1
  254. package/web/.next/server/chunks/[root-of-the-server]__0-3b27b._.js +0 -9
  255. package/web/.next/server/chunks/[root-of-the-server]__0-3b27b._.js.map +0 -1
  256. package/web/.next/server/chunks/[root-of-the-server]__0_6fhza._.js +0 -9
  257. package/web/.next/server/chunks/[root-of-the-server]__0esdmru._.js +0 -12
  258. package/web/.next/server/chunks/[root-of-the-server]__0esdmru._.js.map +0 -1
  259. package/web/.next/server/chunks/[root-of-the-server]__0l1p8bx._.js +0 -3
  260. package/web/.next/server/chunks/[root-of-the-server]__0l1p8bx._.js.map +0 -1
  261. package/web/.next/server/chunks/[root-of-the-server]__0p~owgt._.js +0 -18
  262. package/web/.next/server/chunks/[root-of-the-server]__0p~owgt._.js.map +0 -1
  263. package/web/.next/server/chunks/[root-of-the-server]__0rru~m.._.js +0 -3
  264. package/web/.next/server/chunks/[root-of-the-server]__0rru~m.._.js.map +0 -1
  265. package/web/.next/server/chunks/ssr/[root-of-the-server]__045sv4b._.js +0 -3
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__045sv4b._.js.map +0 -1
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d_0_fp._.js +0 -3
  268. package/web/.next/server/chunks/ssr/[root-of-the-server]__0d_0_fp._.js.map +0 -1
  269. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l4d7e.._.js +0 -3
  270. package/web/.next/server/chunks/ssr/[root-of-the-server]__0l4d7e.._.js.map +0 -1
  271. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r32z03._.js +0 -3
  272. package/web/.next/server/chunks/ssr/[root-of-the-server]__0r32z03._.js.map +0 -1
  273. /package/web/.next/server/chunks/{[root-of-the-server]__02xmnal._.js.map → [root-of-the-server]__08cpfre._.js.map} +0 -0
  274. /package/web/.next/server/chunks/{[root-of-the-server]__0.2exzi._.js.map → [root-of-the-server]__0gfvkg8._.js.map} +0 -0
  275. /package/web/.next/server/chunks/{[root-of-the-server]__0ip_e1x._.js.map → [root-of-the-server]__0hcp97v._.js.map} +0 -0
  276. /package/web/.next/server/chunks/{[root-of-the-server]__09118p2._.js.map → [root-of-the-server]__0iel39d._.js.map} +0 -0
  277. /package/web/.next/server/chunks/{[root-of-the-server]__04jjtl_._.js.map → [root-of-the-server]__0u1jyv9._.js.map} +0 -0
  278. /package/web/.next/server/chunks/{[root-of-the-server]__07suer1._.js.map → [root-of-the-server]__0zu_byw._.js.map} +0 -0
  279. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__0qh.wn.._.js.map → [root-of-the-server]__0q3-gz.._.js.map} +0 -0
  280. /package/web/.next/server/chunks/ssr/{[root-of-the-server]__12g8h3_._.js.map → [root-of-the-server]__0w4__yd._.js.map} +0 -0
  281. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ynyh_sSxbFA995FRvBUxs}/_buildManifest.js +0 -0
  282. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ynyh_sSxbFA995FRvBUxs}/_clientMiddlewareManifest.js +0 -0
  283. /package/web/.next/static/{ZpPnD_b687G9xVr2nzrds → ynyh_sSxbFA995FRvBUxs}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/approve-feature.ts","../../../../../../../src/presentation/web/app/actions/reject-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-research-artifact.ts","../../../../../../../src/presentation/web/app/actions/get-merge-review-data.ts","../../../../../../../src/presentation/web/lib/path-sanitizers.ts","../../../../../../../src/presentation/web/app/actions/get-feature-phase-timings.ts","../../../../../../../src/presentation/web/app/actions/get-feature-plan.ts","../../../../../../../src/presentation/web/app/actions/rebase-feature.ts","../../../../../../../src/presentation/web/app/actions/get-feature-drawer-data.ts","../../../../../../../src/presentation/web/app/actions/get-branch-sync-status.ts"],"sourcesContent":["'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ApproveAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/approve-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { PrdApprovalPayload } from '@shipit-ai/core/domain/generated/output';\n\nexport async function approveFeature(\n featureId: string,\n payload?: PrdApprovalPayload\n): Promise<{ approved: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { approved: false, error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { approved: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { approved: false, error: 'Feature has no agent run' };\n }\n\n // Always use ApproveAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures approval is propagated via\n // Command({update: {_approvalAction: 'approved'}}) so the graph node\n // receives it on resume.\n const approveUseCase = resolve<ApproveAgentRunUseCase>('ApproveAgentRunUseCase');\n const result = await approveUseCase.execute(feature.agentRunId, payload);\n\n if (!result.approved) {\n return { approved: false, error: result.reason };\n }\n\n return { approved: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to approve feature';\n return { approved: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RejectAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/reject-agent-run.use-case';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport async function rejectFeature(\n featureId: string,\n feedback: string,\n attachments?: string[]\n): Promise<{\n rejected: boolean;\n iteration?: number;\n iterationWarning?: boolean;\n error?: string;\n}> {\n if (!featureId.trim()) {\n return { rejected: false, error: 'Feature id is required' };\n }\n\n if (!feedback.trim()) {\n return { rejected: false, error: 'Feedback is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { rejected: false, error: 'Feature not found' };\n }\n\n if (!feature.agentRunId) {\n return { rejected: false, error: 'Feature has no agent run' };\n }\n\n // Always use RejectAgentRunUseCase — it handles waitingApproval, failed,\n // and interrupted statuses. This ensures rejection feedback is propagated\n // via Command({update: {_approvalAction, _rejectionFeedback}}) so the\n // graph node receives the feedback on resume.\n const rejectUseCase = resolve<RejectAgentRunUseCase>('RejectAgentRunUseCase');\n const result = await rejectUseCase.execute(feature.agentRunId, feedback, attachments);\n\n if (!result.rejected) {\n return { rejected: false, error: result.reason };\n }\n\n return {\n rejected: true,\n iteration: result.iteration,\n iterationWarning: result.iterationWarning,\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to reject feature';\n return { rejected: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { FeatureArtifact } from '@shipit-ai/core/domain/generated/output';\nimport type { PrdQuestionnaireData } from '@shipit-ai/core/domain/generated/output';\nimport type { ProductDecisionsSummaryData } from '@/components/common/product-decisions-summary';\n\ninterface GetFeatureArtifactResult {\n questionnaire?: PrdQuestionnaireData;\n productDecisions?: ProductDecisionsSummaryData;\n artifact?: FeatureArtifact;\n error?: string;\n}\n\n/**\n * Map FeatureArtifact openQuestions into the PrdQuestionnaireData shape\n * expected by the PrdQuestionnaireDrawer component.\n */\nfunction toQuestionnaireData(artifact: FeatureArtifact): PrdQuestionnaireData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions.map((oq, idx) => ({\n id: `q-${idx}`,\n question: oq.question,\n type: 'select' as const,\n options: (oq.options ?? []).map((opt, optIdx) => ({\n id: `q-${idx}-opt-${optIdx}`,\n label: opt.option,\n rationale: opt.description,\n ...(opt.selected ? { recommended: true } : {}),\n })),\n })),\n finalAction: {\n id: 'approve-reqs',\n label: 'Approve Requirements',\n description: 'Finalize and lock the requirements for implementation',\n },\n };\n}\n\n/**\n * Map FeatureArtifact openQuestions into a read-only summary for the\n * Product Decisions tab in the tech review drawer.\n */\nfunction toProductDecisionsData(artifact: FeatureArtifact): ProductDecisionsSummaryData {\n return {\n question: 'Goal',\n context: artifact.oneLiner,\n questions: artifact.openQuestions\n .filter((oq) => oq.resolved)\n .map((oq) => {\n const selected = oq.options?.find((o) => o.selected);\n return {\n question: oq.question,\n selectedOption: selected?.option ?? oq.answer ?? 'N/A',\n rationale: oq.selectionRationale ?? selected?.description ?? '',\n wasRecommended: false,\n };\n }),\n };\n}\n\nexport async function getFeatureArtifact(featureId: string): Promise<GetFeatureArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const questionnaire = toQuestionnaireData(artifact);\n const productDecisions = toProductDecisionsData(artifact);\n return { questionnaire, productDecisions, artifact };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetResearchArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-research-artifact.use-case';\nimport type { ResearchArtifact, TechDecision } from '@shipit-ai/core/domain/generated/output';\n\nexport interface TechDecisionsReviewData {\n name: string;\n summary: string;\n decisions: TechDecision[];\n technologies: string[];\n}\n\ninterface GetResearchArtifactResult {\n techDecisions?: TechDecisionsReviewData;\n error?: string;\n}\n\nfunction toTechDecisionsData(artifact: ResearchArtifact): TechDecisionsReviewData {\n return {\n name: artifact.name,\n summary: artifact.summary,\n decisions: artifact.decisions,\n technologies: artifact.technologies,\n };\n}\n\nexport async function getResearchArtifact(featureId: string): Promise<GetResearchArtifactResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetResearchArtifactUseCase>('GetResearchArtifactUseCase');\n const artifact = await useCase.execute(featureId);\n const techDecisions = toTechDecisionsData(artifact);\n return { techDecisions };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load research artifact';\n return { error: message };\n }\n}\n","'use server';\n\nimport { createHash } from 'node:crypto';\nimport { readFileSync } from 'node:fs';\nimport { basename, join, dirname } from 'node:path';\nimport { resolve } from '@/lib/server-container';\nimport { realpathOrNull, isWithinRoot } from '@/lib/path-sanitizers';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type {\n MergeReviewData,\n MergeReviewEvidence,\n} from '@/components/common/merge-review/merge-review-config';\nimport { computeWorktreePath, getShipitAiHomeDir } from '@/lib/core-utils';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\n\ntype GetMergeReviewDataResult = MergeReviewData | { error: string };\n\n/**\n * Compute the ShipIT evidence directory for a given repository and feature.\n * Path: ~/.shipit-ai/repos/<sha256-hash-prefix>/evidence/<featureId>/\n *\n * The sha256 hash of the repository path makes the resulting directory name\n * deterministic and hex-only, neutralizing any path-injection risk from the\n * repositoryPath input. The featureId is a UUID from the DB lookup.\n */\nfunction computeEvidenceDir(repositoryPath: string, featureId: string): string {\n const repoHash = createHash('sha256').update(repositoryPath).digest('hex').slice(0, 16);\n return join(getShipitAiHomeDir(), 'repos', repoHash, 'evidence', featureId).replace(/\\\\/g, '/');\n}\n\n/**\n * Normalize evidence paths so they all point to the ShipIT evidence directory.\n * When commitEvidence was enabled, the manifest may contain relative paths\n * (e.g. \"specs/066-feature/evidence/file.png\"). After merge the worktree is\n * deleted so those paths no longer resolve. The evidence files were also saved\n * to the ShipIT evidence dir with the same filename, so we map relative paths\n * to absolute paths there.\n *\n * IMPORTANT: the returned paths must remain in the SAME form as the\n * `/api/evidence` route expects (it uses `path.resolve` + `.startsWith`\n * against the unresolved `SHIPIT_AI_HOME/repos` root). Do not pass\n * realpath-resolved paths here, because on macOS `SHIPIT_AI_HOME=/tmp/...`\n * resolves to `/private/tmp/...` and the evidence route's prefix check\n * would reject the realpath'd form. Basename-only containment (strip any\n * directory traversal via `basename()` then `join()` with the known-safe\n * `evidenceDir`) is sufficient sanitization for this taint source because\n * `basename()` cannot return a path-traversal string.\n */\nfunction normalizeEvidencePaths(\n evidence: MergeReviewEvidence[],\n evidenceDir: string\n): MergeReviewEvidence[] {\n return evidence.map((e) => {\n // If the manifest path is absolute and already present on disk, keep\n // it verbatim — this preserves the original reference and matches the\n // pre-fix behavior for already-migrated evidence. We do NOT realpath\n // the result because the evidence route does not realpath its input,\n // and mismatching normalization forms would cause 404s.\n if (e.relativePath.startsWith('/')) {\n return e;\n }\n // Relative path — map to evidenceDir using basename() only. `basename`\n // strips any directory components including `..` sequences, so the\n // joined result is guaranteed to live directly inside evidenceDir\n // regardless of what the manifest file contained.\n const safeName = basename(e.relativePath);\n const target = join(evidenceDir, safeName).replace(/\\\\/g, '/');\n return { ...e, relativePath: target };\n });\n}\n\nexport async function getMergeReviewData(featureId: string): Promise<GetMergeReviewDataResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n const pr = feature.pr\n ? {\n url: feature.pr.url,\n number: feature.pr.number,\n status: feature.pr.status,\n commitHash: feature.pr.commitHash,\n ciStatus: feature.pr.ciStatus,\n mergeable: feature.pr.mergeable,\n }\n : undefined;\n\n const worktreePath =\n feature.worktreePath ??\n (feature.repositoryPath && feature.branch\n ? computeWorktreePath(feature.repositoryPath, feature.branch)\n : null);\n\n // Detect the actual default branch (main, master, etc.) for diff comparison.\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const diffCwd = worktreePath ?? feature.repositoryPath ?? null;\n let defaultBranch = 'main';\n if (diffCwd) {\n try {\n defaultBranch = await gitPrService.getDefaultBranch(diffCwd);\n } catch {\n // Fall back to 'main' if detection fails\n }\n }\n\n const branch = feature.branch ? { source: feature.branch, target: defaultBranch } : undefined;\n\n // Load evidence manifest (best-effort).\n // Evidence is stored independently of the worktree at:\n // ~/.shipit-ai/repos/<hash>/evidence/<featureId>/manifest.json\n // We compute this path from repositoryPath so evidence is accessible\n // even after the worktree has been deleted post-merge.\n let evidence: MergeReviewEvidence[] | undefined;\n const evidenceDir = feature.repositoryPath\n ? computeEvidenceDir(feature.repositoryPath, featureId)\n : worktreePath\n ? join(dirname(dirname(worktreePath)), 'evidence', featureId).replace(/\\\\/g, '/')\n : null;\n\n if (evidenceDir) {\n try {\n // SECURITY: validate the manifest we're about to read lives inside\n // SHIPIT_AI_HOME. computeEvidenceDir() already hashes repositoryPath\n // to a hex directory name, but we still run a realpath containment\n // check because CodeQL's js/path-injection analysis recognizes the\n // realpathOrNull + isWithinRoot pair as a sanitizer chain.\n //\n // Resolve-once semantics: realpath the shipit home dir and the\n // evidence dir exactly once each, then reuse those resolved values\n // for every subsequent containment check. This avoids both the\n // extra syscalls and the TOCTOU window that a recursive resolve-\n // and-check helper would introduce.\n //\n // IMPORTANT: the resolved paths are used ONLY for the read-time\n // security check. The unresolved `evidenceDir` is what we pass to\n // normalizeEvidencePaths so the paths returned to the client match\n // what the /api/evidence route expects — see the comment on\n // normalizeEvidencePaths for the full rationale.\n const resolvedHome = realpathOrNull(getShipitAiHomeDir());\n const resolvedEvidenceDir = realpathOrNull(evidenceDir);\n if (\n resolvedHome &&\n resolvedEvidenceDir &&\n isWithinRoot(resolvedEvidenceDir, resolvedHome)\n ) {\n const resolvedManifest = realpathOrNull(join(resolvedEvidenceDir, 'manifest.json'));\n if (resolvedManifest && isWithinRoot(resolvedManifest, resolvedEvidenceDir)) {\n const raw: MergeReviewEvidence[] = JSON.parse(readFileSync(resolvedManifest, 'utf-8'));\n // Pass the UNRESOLVED evidenceDir so returned paths share the\n // same root form the evidence route's prefix check expects.\n const normalized = normalizeEvidencePaths(raw, evidenceDir);\n // Deduplicate: same type + relativePath means the same evidence entry\n const seen = new Set<string>();\n evidence = normalized.filter((e) => {\n const key = `${e.type}:${e.relativePath}`;\n if (seen.has(key)) return false;\n seen.add(key);\n return true;\n });\n }\n }\n } catch {\n // Evidence unavailable — not critical\n }\n }\n\n if (!worktreePath) {\n return {\n pr,\n branch,\n evidence,\n warning: pr ? undefined : 'No PR or diff data available',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n\n try {\n const [diffSummary, fileDiffs] = await Promise.all([\n gitPrService.getPrDiffSummary(worktreePath, defaultBranch),\n gitPrService.getFileDiffs(worktreePath, defaultBranch).catch(() => undefined),\n ]);\n return { pr, branch, diffSummary, fileDiffs, evidence, hideCiStatus: workflow.hideCiStatus };\n } catch {\n return {\n pr,\n branch,\n evidence,\n warning: 'Diff statistics unavailable',\n hideCiStatus: workflow.hideCiStatus,\n };\n }\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load merge review data';\n return { error: message };\n }\n}\n","/**\n * Path sanitization helpers for the web presentation layer.\n *\n * Provides the small set of primitives used by every route and server\n * action that touches a user-influenced filesystem path. Each helper\n * does one thing, is recognized by CodeQL's js/path-injection taint\n * analysis as a sanitizer, and is portable across macOS/Linux/Windows.\n *\n * Design principles:\n *\n * - `realpathOrNull(p)` resolves a path through `realpath` and returns\n * `null` on any error (missing file, permission denied, broken symlink).\n * Callers never have to care about the thrown error variants.\n *\n * - `isWithinRoot(candidate, root)` is a pure string containment check\n * that expects both arguments to already be realpath-resolved. It\n * normalizes backslash separators to forward slashes before comparing,\n * so Windows realpath output matches the forward-slash roots that\n * shipit uses throughout the codebase for persistence and comparison.\n *\n * - `realpathWithinAllowedRoots(candidate, roots)` combines the two:\n * resolves the candidate once, resolves each root once (with graceful\n * fallback to the unresolved form for the roots), then checks\n * containment. Returns the resolved candidate on success, `null` on\n * failure. Use this when a value must live under one of several\n * permitted directories (e.g. cwd OR home-dir for the uploads API).\n *\n * These helpers intentionally do NOT compose realpath with the\n * containment check into a single `realpathWithinRoot(candidate, root)`\n * function, because that composition re-resolves an already-resolved\n * root on every nested call and opens a TOCTOU window where filesystem\n * state can change between the resolve and the containment check. Keep\n * realpath and containment separate so the caller can resolve once and\n * validate many.\n */\nimport { realpathSync } from 'node:fs';\nimport { realpath } from 'node:fs/promises';\n\n/**\n * Resolve a path through `realpath` and return the resolved absolute path,\n * or `null` if the path is missing, unreadable, or cannot be canonicalized\n * for any other reason. Never throws.\n *\n * CodeQL recognizes `realpathSync` output as a sanitizer for\n * `js/path-injection`, so the returned value is safe to flow into `stat`,\n * `readFile`, `readdir`, `spawn`, and other filesystem sinks.\n */\nexport function realpathOrNull(p: string): string | null {\n try {\n return realpathSync(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Pure string containment check: does `resolvedCandidate` live at or\n * beneath `resolvedRoot`? BOTH arguments are expected to already be\n * realpath-resolved absolute paths — this helper does NOT resolve them.\n * Separate the resolve step from the containment check so the caller can\n * resolve once and validate many times without redundant syscalls or\n * TOCTOU windows.\n *\n * Uses forward-slash normalization on both sides before comparing, which\n * is lossless on POSIX (separator is already `/`) and lossless on Windows\n * (where `/` cannot appear inside a path component). This makes the\n * helper safe to use across all three platforms.\n */\nexport function isWithinRoot(resolvedCandidate: string, resolvedRoot: string): boolean {\n const normRoot = resolvedRoot.replace(/\\\\/g, '/');\n const normCandidate = resolvedCandidate.replace(/\\\\/g, '/');\n return normCandidate === normRoot || normCandidate.startsWith(`${normRoot}/`);\n}\n\n/**\n * Resolve `candidate` through realpath and assert the result lives under\n * at least one of the provided `allowedRoots`. Returns the resolved\n * candidate path on success, or `null` if the candidate cannot be resolved\n * or does not fall under any allowed root.\n *\n * The roots are resolved once, up-front, with graceful fallback to the\n * unresolved form on failure (so a root that does not yet exist on disk\n * is still honored as a literal prefix — this matches the existing\n * behavior of the upload and directory-list routes). If the caller wants\n * strict resolution of the roots too, pre-resolve them with\n * `realpathOrNull` and filter out `null`s before calling this helper.\n */\nexport function realpathWithinAllowedRoots(\n candidate: string,\n allowedRoots: readonly string[]\n): string | null {\n const resolvedCandidate = realpathOrNull(candidate);\n if (!resolvedCandidate) return null;\n\n for (const root of allowedRoots) {\n const resolvedRoot = realpathOrNull(root) ?? root;\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n\n// ─── Async variants ─────────────────────────────────────────────────────\n//\n// Route handlers that already use async fs APIs should use these rather\n// than the sync variants so they don't block the event loop under\n// concurrent load. The async helpers mirror the sync ones exactly in\n// semantics — same null-on-error contract, same normalization, same\n// containment rules.\n\n/**\n * Async variant of `realpathOrNull`. See the sync version for semantics.\n */\nexport async function realpathOrNullAsync(p: string): Promise<string | null> {\n try {\n return await realpath(p);\n } catch {\n return null;\n }\n}\n\n/**\n * Async variant of `realpathWithinAllowedRoots`. See the sync version for\n * semantics. Resolves the candidate and each root concurrently via\n * `Promise.all` so the worst-case wall-clock time is a single realpath,\n * not N of them serialized.\n */\nexport async function realpathWithinAllowedRootsAsync(\n candidate: string,\n allowedRoots: readonly string[]\n): Promise<string | null> {\n const [resolvedCandidate, ...resolvedRoots] = await Promise.all([\n realpathOrNullAsync(candidate),\n ...allowedRoots.map((r) => realpathOrNullAsync(r)),\n ]);\n if (!resolvedCandidate) return null;\n\n for (let i = 0; i < resolvedRoots.length; i++) {\n const resolvedRoot = resolvedRoots[i] ?? allowedRoots[i];\n if (isWithinRoot(resolvedCandidate, resolvedRoot)) {\n return resolvedCandidate;\n }\n }\n return null;\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IPhaseTimingRepository } from '@shipit-ai/core/application/ports/output/agents/phase-timing-repository.interface';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface PhaseTimingData {\n agentRunId: string;\n phase: string;\n startedAt: string;\n completedAt?: string;\n durationMs?: number;\n waitingApprovalAt?: string;\n approvalWaitMs?: number;\n inputTokens?: number;\n outputTokens?: number;\n cacheCreationInputTokens?: number;\n cacheReadInputTokens?: number;\n costUsd?: number;\n numTurns?: number;\n durationApiMs?: number;\n exitCode?: string;\n errorMessage?: string;\n prompt?: string;\n}\n\nexport interface RejectionFeedbackData {\n iteration: number;\n message: string;\n phase?: string;\n timestamp?: string;\n attachments?: string[];\n}\n\ntype GetPhaseTimingsResult =\n | { timings: PhaseTimingData[]; rejectionFeedback: RejectionFeedbackData[] }\n | { error: string };\n\nexport async function getFeaturePhaseTimings(featureId: string): Promise<GetPhaseTimingsResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IPhaseTimingRepository>('IPhaseTimingRepository');\n const phaseTimings = await repo.findByFeatureId(featureId);\n\n const timings: PhaseTimingData[] = phaseTimings.map((t) => ({\n agentRunId: t.agentRunId,\n phase: t.phase,\n startedAt: t.startedAt.toISOString(),\n completedAt: t.completedAt?.toISOString(),\n durationMs: t.durationMs != null ? Number(t.durationMs) : undefined,\n waitingApprovalAt: t.waitingApprovalAt?.toISOString(),\n approvalWaitMs: t.approvalWaitMs != null ? Number(t.approvalWaitMs) : undefined,\n inputTokens: t.inputTokens != null ? Number(t.inputTokens) : undefined,\n outputTokens: t.outputTokens != null ? Number(t.outputTokens) : undefined,\n cacheCreationInputTokens:\n t.cacheCreationInputTokens != null ? Number(t.cacheCreationInputTokens) : undefined,\n cacheReadInputTokens:\n t.cacheReadInputTokens != null ? Number(t.cacheReadInputTokens) : undefined,\n costUsd: t.costUsd != null ? Number(t.costUsd) : undefined,\n numTurns: t.numTurns ?? undefined,\n durationApiMs: t.durationApiMs != null ? Number(t.durationApiMs) : undefined,\n exitCode: t.exitCode ?? undefined,\n errorMessage: t.errorMessage ?? undefined,\n prompt: t.prompt ?? undefined,\n }));\n\n // Read rejection feedback from spec.yaml\n const rejectionFeedback = await readRejectionFeedback(featureId);\n\n return { timings, rejectionFeedback };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load phase timings';\n return { error: message };\n }\n}\n\nasync function readRejectionFeedback(featureId: string): Promise<RejectionFeedbackData[]> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n if (!feature?.specPath) return [];\n\n const { readFileSync } = await import('node:fs');\n const { join } = await import('node:path');\n const yaml = (await import('js-yaml')).default;\n\n const specContent = readFileSync(join(feature.specPath, 'spec.yaml'), 'utf-8');\n const spec = yaml.load(specContent) as Record<string, unknown>;\n\n if (!Array.isArray(spec?.rejectionFeedback)) return [];\n\n return (spec.rejectionFeedback as Record<string, unknown>[]).map((entry) => ({\n iteration: Number(entry.iteration ?? 1),\n message: String(entry.message ?? ''),\n phase: entry.phase ? String(entry.phase) : undefined,\n timestamp: entry.timestamp ? String(entry.timestamp) : undefined,\n attachments: Array.isArray(entry.attachments)\n ? (entry.attachments as unknown[]).map(String)\n : undefined,\n }));\n } catch {\n return [];\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\nexport interface AcceptanceCriterionData {\n description: string;\n verified: boolean;\n}\n\nexport interface ActionItemData {\n name: string;\n description: string;\n acceptanceCriteria: AcceptanceCriterionData[];\n}\n\nexport interface PlanTaskData {\n title: string;\n description: string;\n state: string;\n actionItems: ActionItemData[];\n}\n\nexport interface PlanData {\n state: string;\n overview: string;\n tasks: PlanTaskData[];\n}\n\ntype GetPlanResult = { plan: PlanData | undefined } | { error: string };\n\nexport async function getFeaturePlan(featureId: string): Promise<GetPlanResult> {\n if (!featureId.trim()) {\n return { error: 'Feature id is required' };\n }\n\n try {\n const repo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await repo.findById(featureId);\n\n if (!feature) {\n return { error: 'Feature not found' };\n }\n\n if (!feature.plan) {\n return { plan: undefined };\n }\n\n const plan: PlanData = {\n state: feature.plan.state,\n overview: feature.plan.overview,\n tasks: feature.plan.tasks.map((t) => ({\n title: t.title ?? '',\n description: t.description ?? '',\n state: t.state,\n actionItems: (t.actionItems ?? []).map((ai) => ({\n name: ai.name,\n description: ai.description,\n acceptanceCriteria: (ai.acceptanceCriteria ?? []).map((ac) => ({\n description: ac.description,\n verified: ac.verified,\n })),\n })),\n })),\n };\n\n return { plan };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to load feature plan';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { RebaseFeatureOnMainUseCase } from '@shipit-ai/core/application/use-cases/features/rebase-feature-on-main.use-case';\n\nexport async function rebaseFeature(\n featureId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<RebaseFeatureOnMainUseCase>('RebaseFeatureOnMainUseCase');\n await useCase.execute(featureId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to rebase feature';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\nimport type { IAgentRunRepository } from '@shipit-ai/core/application/ports/output/agents/agent-run-repository.interface';\nimport type { IRepositoryRepository } from '@shipit-ai/core/application/ports/output/repositories/repository-repository.interface';\nimport type { IGitPrService } from '@shipit-ai/core/application/ports/output/services/git-pr-service.interface';\nimport type { GetFeatureArtifactUseCase } from '@shipit-ai/core/application/use-cases/features/get-feature-artifact.use-case';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport { buildFeatureNodeData } from '@/app/build-feature-node-data';\nimport type { FeatureNodeData } from '@/components/common/feature-node';\n\n/**\n * Fetches full FeatureNodeData for a given feature ID.\n * Used by the drawer for targeted data syncing without triggering\n * a full router.refresh() / server component re-render.\n *\n * CI status and mergeable status are read from the DB (already updated\n * by PrSyncWatcherService) instead of making duplicate GitHub API calls.\n */\nexport async function getFeatureDrawerData(featureId: string): Promise<FeatureNodeData | null> {\n try {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const agentRunRepo = resolve<IAgentRunRepository>('IAgentRunRepository');\n const repoRepo = resolve<IRepositoryRepository>('IRepositoryRepository');\n const gitPrService = resolve<IGitPrService>('IGitPrService');\n const getArtifact = resolve<GetFeatureArtifactUseCase>('GetFeatureArtifactUseCase');\n\n const feature = await featureRepo.findById(featureId);\n if (!feature) return null;\n\n const run = feature.agentRunId ? await agentRunRepo.findById(feature.agentRunId) : null;\n\n // CI status and mergeable status are read from the feature record (updated by\n // PrSyncWatcherService every 30s) — no duplicate GitHub API calls needed.\n // Only getDefaultBranch and getRemoteUrl are kept as they are local git operations.\n const [repo, baseBranch, artifact, remoteUrl] = await Promise.all([\n repoRepo.findByPath(feature.repositoryPath).catch(() => null),\n gitPrService.getDefaultBranch(feature.repositoryPath).catch(() => 'main'),\n getArtifact.execute(featureId).catch(() => null),\n gitPrService.getRemoteUrl(feature.repositoryPath).catch(() => null),\n ]);\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const { workflow } = await loadSettings.execute();\n\n return buildFeatureNodeData(feature, run, {\n repositoryName: repo?.name,\n baseBranch,\n oneLiner: artifact?.oneLiner,\n remoteUrl: remoteUrl ?? undefined,\n enableEvidence: workflow.enableEvidence,\n commitEvidence: workflow.commitEvidence,\n hideCiStatus: workflow.hideCiStatus,\n });\n } catch {\n return null;\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { GetBranchSyncStatusUseCase } from '@shipit-ai/core/application/use-cases/features/get-branch-sync-status.use-case';\n\nexport async function getBranchSyncStatus(featureId: string): Promise<{\n success: boolean;\n data?: { ahead: number; behind: number; baseBranch: string; checkedAt: string };\n error?: string;\n}> {\n if (!featureId?.trim()) {\n return { success: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<GetBranchSyncStatusUseCase>('GetBranchSyncStatusUseCase');\n const result = await useCase.execute(featureId);\n return {\n success: true,\n data: {\n ...result,\n checkedAt: new Date().toISOString(),\n },\n };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to get branch sync status';\n return { success: false, error: message };\n }\n}\n"],"names":["approveFeature","featureId","payload","trim","approved","error","featureRepo","feature","findById","agentRunId","approveUseCase","result","execute","reason","message","Error"],"mappings":"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"}
@@ -1,3 +1,3 @@
1
- module.exports=[86561,8275,75854,85653,a=>{"use strict";var b=a.i(2211),c=a.i(2157),d=a.i(50227),e=a.i(96380);a.i(1442);var f=a.i(83771),g=a.i(50961);async function h(){try{let b=(0,e.resolve)("LoadSettingsUseCase"),g=await b.execute(),h=(0,f.getShipitAiHomeDir)(),i="Unknown";try{var a;let b=(0,d.join)(h,"data");i=(a=(0,c.statSync)(b).size)<1024?`${a} B`:a<1048576?`${(a/1024).toFixed(1)} KB`:`${(a/1048576).toFixed(1)} MB`}catch{}return{settings:g,shipitAiHome:h,dbFileSize:i}}catch(a){return{error:a instanceof Error?a.message:"Failed to load settings"}}}async function i(){try{let a=(0,e.resolve)("IToolInstallerService");return await a.listAvailableTerminals()}catch{return[{id:"system",name:"System Terminal",available:!0}]}}async function j(){try{let a=(0,e.resolve)("IEnvironmentDetectorService");return await a.listAvailableEditors()}catch{return[{id:"vscode",name:"VS Code",available:!0},{id:"cursor",name:"Cursor",available:!0},{id:"windsurf",name:"Windsurf",available:!0},{id:"zed",name:"Zed",available:!0},{id:"antigravity",name:"Antigravity",available:!0}]}}async function k(){try{let a=(0,e.resolve)("IEnvironmentDetectorService");return await a.listAvailableShells()}catch{return[{id:"bash",name:"Bash",available:!0},{id:"zsh",name:"Zsh",available:!0},{id:"fish",name:"Fish",available:!0}]}}(0,g.ensureServerEntryExports)([h]),(0,b.registerServerReference)(h,"00d1b48398282a4cfc160045f6a49d21724acca5c9",null),a.s(["loadSettings",0,h],86561),(0,g.ensureServerEntryExports)([i]),(0,b.registerServerReference)(i,"0008131d9405eb98f49c0ded5bfb14062832c7838d",null),a.s(["getAvailableTerminals",0,i],8275),(0,g.ensureServerEntryExports)([j]),(0,b.registerServerReference)(j,"005f1133ac9e6e169d4f8f6a69b03b192b9a2c96d8",null),a.s(["getAvailableEditors",0,j],75854),(0,g.ensureServerEntryExports)([k]),(0,b.registerServerReference)(k,"00877577bbef68a3538896c6805818445b190170ab",null),a.s(["getAvailableShells",0,k],85653)}];
1
+ module.exports=[86561,8275,75854,85653,a=>{"use strict";var b=a.i(2211),c=a.i(2157),d=a.i(50227),e=a.i(96380);a.i(1442);var f=a.i(83771),g=a.i(50961);async function h(){try{let b=(0,e.resolve)("LoadSettingsUseCase"),g=await b.execute(),h=(0,f.getShipitAiHomeDir)(),i="Unknown";try{var a;let b=(0,d.join)(h,"data");i=(a=(0,c.statSync)(b).size)<1024?`${a} B`:a<1048576?`${(a/1024).toFixed(1)} KB`:`${(a/1048576).toFixed(1)} MB`}catch{}return{settings:g,shipitAiHome:h,dbFileSize:i}}catch(a){return{error:a instanceof Error?a.message:"Failed to load settings"}}}async function i(){try{let a=(0,e.resolve)("IToolInstallerService");return await a.listAvailableTerminals()}catch{return[{id:"system",name:"System Terminal",available:!0}]}}async function j(){try{let a=(0,e.resolve)("IEnvironmentDetectorService");return await a.listAvailableEditors()}catch{return[{id:"vscode",name:"VS Code",available:!0},{id:"cursor",name:"Cursor",available:!0},{id:"windsurf",name:"Windsurf",available:!0},{id:"zed",name:"Zed",available:!0},{id:"antigravity",name:"Antigravity",available:!0}]}}async function k(){try{let a=(0,e.resolve)("IEnvironmentDetectorService");return await a.listAvailableShells()}catch{return[{id:"bash",name:"Bash",available:!0},{id:"zsh",name:"Zsh",available:!0},{id:"fish",name:"Fish",available:!0}]}}(0,g.ensureServerEntryExports)([h]),(0,b.registerServerReference)(h,"0003df294c388fb598cec985c2a93dded3f0599a5e",null),a.s(["loadSettings",0,h],86561),(0,g.ensureServerEntryExports)([i]),(0,b.registerServerReference)(i,"00ade0c1968c419328283e854002f40f25b8bcc3c1",null),a.s(["getAvailableTerminals",0,i],8275),(0,g.ensureServerEntryExports)([j]),(0,b.registerServerReference)(j,"00af9752e2e7c8520f0a159ceaed7ae50240072383",null),a.s(["getAvailableEditors",0,j],75854),(0,g.ensureServerEntryExports)([k]),(0,b.registerServerReference)(k,"0056046435a13014c0903d2304b0ee98e27c22d1ae",null),a.s(["getAvailableShells",0,k],85653)}];
2
2
 
3
3
  //# sourceMappingURL=src_presentation_web_app_actions_load-settings_ts_0b8f3pf._.js.map
@@ -1,3 +1,3 @@
1
- module.exports=[84095,56799,80496,93225,41872,9959,79124,29207,10528,50845,26604,54723,18942,42886,49560,39353,a=>{"use strict";var b=a.i(2211),c=a.i(50227),d=a.i(96380),e=a.i(50961);async function f(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};let f=(0,d.resolve)("LoadSettingsUseCase"),g=(await f.execute()).environment.defaultEditor,h=(0,d.resolve)("LaunchIdeUseCase"),i=await h.execute({editorId:g,repositoryPath:b,branch:e,checkAvailability:!0});return i.ok?{success:!0,editor:i.editorName,path:i.worktreePath}:{success:!1,error:i.message}}(0,e.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"40e1d5fd96662092ef0a2bd4ea2e6d2697f3ab4c6a",null),a.s(["openIde",0,f],84095);var g=a.i(2157),h=a.i(60526),i=a.i(74533);a.i(1442);var j=a.i(29918);let k={darwin:{cmd:"open",args:a=>["-a","Terminal",a]},linux:{cmd:"x-terminal-emulator",args:a=>[`--working-directory=${a}`]},win32:{cmd:"cmd.exe",args:a=>["/c","start","powershell","-NoExit","-Command",`Set-Location "${a}"`]}};async function l(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};try{let a=(0,d.resolve)("LoadSettingsUseCase"),c=await a.execute(),f=c.environment.shellPreference,l=c.environment.terminalPreference??"system",m=e?(0,j.computeWorktreePath)(b,e):b;if(!(0,g.existsSync)(m))return{success:!1,error:`Path does not exist: ${m}`};if("system"!==l)try{let a=(0,d.resolve)("IToolInstallerService").getTerminalOpenConfig(l);if(a?.openDirectory.includes("{dir}")){let b=a.openDirectory.replace("{dir}",m);if(a.shell){let a=(0,i.spawn)(b,[],{detached:!0,stdio:"ignore",shell:!0});a.on("error",()=>void 0),a.unref()}else{let[a,...c]=b.split(/\s+/),d=(0,i.spawn)(a,c,{detached:!0,stdio:"ignore"});d.on("error",()=>void 0),d.unref()}return{success:!0,path:m,shell:f}}}catch{}let n=k[(0,h.platform)()];if(!n)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let o=(0,i.spawn)(n.cmd,n.args(m),{detached:!0,stdio:"ignore"});return o.on("error",()=>void 0),o.unref(),{success:!0,path:m,shell:f}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open shell"}}}(0,e.ensureServerEntryExports)([l]),(0,b.registerServerReference)(l,"40eb06a9ce08102cf20c1cb5e3a0e0aeb9bd30770b",null),a.s(["openShell",0,l],56799);let m={darwin:{cmd:"open",args:a=>[a]},linux:{cmd:"xdg-open",args:a=>[a]},win32:{cmd:"explorer",args:a=>[a]}};async function n(a){if(!a||!(0,c.isAbsolute)(a))return{success:!1,error:"repositoryPath must be an absolute path"};try{if(!(0,g.existsSync)(a))return{success:!1,error:"Directory not found"};let b=m[(0,h.platform)()];if(!b)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let d=(0,c.normalize)(a),e=(0,i.spawn)(b.cmd,b.args(d),{detached:!0,stdio:"ignore"});return e.on("error",()=>void 0),e.unref(),{success:!0,path:a}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open folder"}}}async function o(a){if(!a?.trim())return{success:!1,error:"Repository id is required"};try{let b=(0,d.resolve)("SyncRepositoryMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to sync repository"}}}async function p(){try{let a=(0,d.resolve)("LoadSettingsUseCase");return(await a.execute()).onboardingComplete}catch{return!1}}(0,e.ensureServerEntryExports)([n]),(0,b.registerServerReference)(n,"406aac6bb69cb2108ce05345c74e9fb7e72dffe3b0",null),a.s(["openFolder",0,n],80496),(0,e.ensureServerEntryExports)([o]),(0,b.registerServerReference)(o,"4031454b289e8be2efef97c9616a65533d8a72eb59",null),a.s(["syncRepository",0,o],93225),(0,e.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"006d6a821da9c521f994872f6661ea6406703cf09d",null),a.s(["isAgentSetupComplete",0,p],41872);var q=a.i(37512);let r={"claude-code":"Claude Code","codex-cli":"Codex CLI","copilot-cli":"GitHub Copilot CLI",cursor:"Cursor CLI","gemini-cli":"Gemini CLI","rovo-dev":"Rovo Dev CLI",aider:"Aider",continue:"Continue",dev:"Demo"},s={"claude-code":"claude-code","codex-cli":"codex-cli","copilot-cli":"copilot-cli",cursor:"cursor-cli","gemini-cli":"gemini-cli","rovo-dev":"rovo-dev"},t={"claude-code":"claude","codex-cli":"codex","copilot-cli":"copilot",cursor:"cursor-agent","gemini-cli":"gemini","rovo-dev":"acli"};function u(a,b){return new Promise(c=>{let d,e;switch(a){case"claude-code":d=b,e=["auth","status"];break;case"cursor":d=b,e=["status"];break;case"codex-cli":c(!1);return;case"copilot-cli":default:c(!0);return;case"rovo-dev":{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)("acli",["rovodev","auth","status"],a,a=>{c(!a)});return}}try{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(d,e,a,a=>{c(!a)})}catch{c(!1)}})}async function v(){let a;try{let b=(0,d.resolve)("LoadSettingsUseCase");a=(await b.execute()).agent.type}catch{return{agentType:"unknown",installed:!1,authenticated:!1,label:"Unknown",binaryName:null,installCommand:null,authCommand:null}}let b=r[a]??a,e=s[a]??null,f=t[a]??null;if(!e)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:null,installCommand:null,authCommand:null};let i=!1,j=null;try{let a=(0,d.resolve)("ListToolsUseCase"),b=(await a.execute()).find(a=>a.id===e);i=b?.status.status==="available",j=b?.installCommand??null}catch{i=!1}if(!i)return{agentType:a,installed:!1,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f?`Install ${b} first`:null};let k=function(a){let b=(0,h.homedir)();switch(a){case"claude-code":{if(process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_USE_BEDROCK||process.env.CLAUDE_CODE_USE_VERTEX||process.env.CLAUDE_CODE_OAUTH_TOKEN)return"env-var";let a=(0,c.join)(b,".claude",".credentials.json");return!!(0,g.existsSync)(a)&&"file"}case"codex-cli":if(process.env.OPENAI_API_KEY)return"env-var";return!1;case"cursor":{if(process.env.CURSOR_API_KEY)return"env-var";let a=(0,c.join)(b,".cursor");return!!(0,g.existsSync)(a)&&"file"}case"gemini-cli":{if(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_APPLICATION_CREDENTIALS)return"env-var";let a=(0,c.join)(b,".gemini","google_accounts.json");return!!(0,g.existsSync)(a)&&"file"}case"copilot-cli":{if(process.env.COPILOT_GITHUB_TOKEN||process.env.GH_TOKEN||process.env.GITHUB_TOKEN)return"env-var";let a=process.env.COPILOT_HOME?(0,c.join)(process.env.COPILOT_HOME,"config.json"):(0,c.join)(b,".copilot","config.json");return!!(0,g.existsSync)(a)&&"file"}case"rovo-dev":{if(process.env.ATLASSIAN_API_TOKEN)return"env-var";let a=(0,c.join)(b,".acli");return!!(0,g.existsSync)(a)&&"file"}default:return"env-var"}}(a);if("env-var"===k)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null};if("file"===k){let c=!0;return f&&(c=await u(a,f)),{agentType:a,installed:!0,authenticated:c,label:b,binaryName:f,installCommand:j,authCommand:c?null:f}}return f&&await u(a,f)?{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null}:{agentType:a,installed:!0,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f}}function w(a,b){return new Promise(c=>{try{let d=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(a,b,d,(a,b)=>{if(a)return void c({installed:!1,version:null});let d=b.match(/(\d+\.\d+(?:\.\d+)?)/);c({installed:!0,version:d?.[1]??null})})}catch{c({installed:!1,version:null})}})}async function x(){let[a,b,c]=await Promise.all([w("git",["--version"]),w("gh",["--version"]),(async()=>{try{let a=(0,d.resolve)("ListToolsUseCase");return await a.execute()}catch{return[]}})()]),e=c.find(a=>"git"===a.id),f=c.find(a=>"gh"===a.id);return{git:{...a,installCommand:e?.installCommand??null,installUrl:e?.website??"https://git-scm.com"},gh:{...b,installCommand:f?.installCommand??null,installUrl:f?.website??"https://cli.github.com"}}}async function y(a){let b=(0,d.resolve)("IFeatureRepository"),c=await b.findById(a);return c?{name:c.name,description:c.description}:null}async function z(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("ArchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to archive feature"}}}async function A(a,b,c,e){if(!a?.trim())return{error:"id is required"};try{let f=(0,d.resolve)("DeleteFeatureUseCase"),g={};return void 0!==b&&(g.cleanup=b),void 0!==c&&(g.cascadeDelete=c),void 0!==e&&(g.closePr=e),{feature:Object.keys(g).length>0?await f.execute(a,g):await f.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to delete feature"}}}async function B(a){if(!a.trim())return{resumed:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("ResumeFeatureUseCase");return await b.execute(a),{resumed:!0}}catch(a){return{resumed:!1,error:a instanceof Error?a.message:"Failed to resume feature"}}}async function C(a){if(!a.trim())return{started:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("StartFeatureUseCase");return await b.execute(a),{started:!0}}catch(a){return{started:!1,error:a instanceof Error?a.message:"Failed to start feature"}}}async function D(a){if(!a.trim())return{stopped:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("IAgentRunRepository"),c=(await b.list()).find(b=>b.featureId===a&&"completed"!==b.status&&"failed"!==b.status&&"interrupted"!==b.status&&"cancelled"!==b.status);if(!c)return{stopped:!1,error:"No active agent run found for this feature"};let e=(0,d.resolve)("StopAgentRunUseCase"),f=await e.execute(c.id);if(!f.stopped)return{stopped:!1,error:f.reason};return{stopped:!0}}catch(a){return{stopped:!1,error:a instanceof Error?a.message:"Failed to stop agent"}}}async function E(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("UnarchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to unarchive feature"}}}async function F(a){let{path:b,name:c}=a;if(!b?.trim())return{error:"path is required"};try{let a=(0,d.resolve)("AddRepositoryUseCase");return{repository:await a.execute({path:b,name:c})}}catch(a){return{error:a instanceof Error?a.message:"Failed to add repository"}}}async function G(a){if(!a?.trim())return{success:!1,error:"id is required"};try{let b=(0,d.resolve)("DeleteRepositoryUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to delete repository"}}}(0,e.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"0060e775107df16b7b19d6e47a7415dd6aedad7619",null),a.s(["checkAgentAuth",0,v],9959),(0,e.ensureServerEntryExports)([x]),(0,b.registerServerReference)(x,"009df0ec5808a1a338bfdec3c05ddefa2e7406617a",null),a.s(["checkToolStatus",0,x],79124),(0,e.ensureServerEntryExports)([y]),(0,b.registerServerReference)(y,"40306a89a2c907442e515b25e00379f8fd0b4403d3",null),a.s(["getFeatureMetadata",0,y],29207),(0,e.ensureServerEntryExports)([z]),(0,b.registerServerReference)(z,"409c6a3d317fe8f02d58823e588796a071e81be44f",null),a.s(["archiveFeature",0,z],10528),(0,e.ensureServerEntryExports)([A]),(0,b.registerServerReference)(A,"785f41cd02af89c4b44f8d222d661a4a534b081923",null),a.s(["deleteFeature",0,A],50845),(0,e.ensureServerEntryExports)([B]),(0,b.registerServerReference)(B,"402a5001445d8c354653c4a59447732df930eeeae9",null),a.s(["resumeFeature",0,B],26604),(0,e.ensureServerEntryExports)([C]),(0,b.registerServerReference)(C,"40217ab39df4c598292e413589a39a03ff1567821b",null),a.s(["startFeature",0,C],54723),(0,e.ensureServerEntryExports)([D]),(0,b.registerServerReference)(D,"405314689dc2fdc3d3267320760cc2912860068706",null),a.s(["stopFeature",0,D],18942),(0,e.ensureServerEntryExports)([E]),(0,b.registerServerReference)(E,"4056493ad4e1f0b52d9ffb6cd926ce616630546083",null),a.s(["unarchiveFeature",0,E],42886),(0,e.ensureServerEntryExports)([F]),(0,b.registerServerReference)(F,"40885ae2064e9aa9d12636caabc74c8e36c76939e2",null),a.s(["addRepository",0,F],49560),(0,e.ensureServerEntryExports)([G]),(0,b.registerServerReference)(G,"40090d50d2dfeaaa5c021cfb7c005a37c84488a7f7",null),a.s(["deleteRepository",0,G],39353)}];
1
+ module.exports=[84095,56799,80496,93225,41872,9959,79124,29207,10528,50845,26604,54723,18942,42886,49560,39353,a=>{"use strict";var b=a.i(2211),c=a.i(50227),d=a.i(96380),e=a.i(50961);async function f(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};let f=(0,d.resolve)("LoadSettingsUseCase"),g=(await f.execute()).environment.defaultEditor,h=(0,d.resolve)("LaunchIdeUseCase"),i=await h.execute({editorId:g,repositoryPath:b,branch:e,checkAvailability:!0});return i.ok?{success:!0,editor:i.editorName,path:i.worktreePath}:{success:!1,error:i.message}}(0,e.ensureServerEntryExports)([f]),(0,b.registerServerReference)(f,"4007721bb168054f860a3df6cd060e0f3807aad0b7",null),a.s(["openIde",0,f],84095);var g=a.i(2157),h=a.i(60526),i=a.i(74533);a.i(1442);var j=a.i(29918);let k={darwin:{cmd:"open",args:a=>["-a","Terminal",a]},linux:{cmd:"x-terminal-emulator",args:a=>[`--working-directory=${a}`]},win32:{cmd:"cmd.exe",args:a=>["/c","start","powershell","-NoExit","-Command",`Set-Location "${a}"`]}};async function l(a){let{repositoryPath:b,branch:e}=a;if(!b||!(0,c.isAbsolute)(b))return{success:!1,error:"repositoryPath must be an absolute path"};try{let a=(0,d.resolve)("LoadSettingsUseCase"),c=await a.execute(),f=c.environment.shellPreference,l=c.environment.terminalPreference??"system",m=function(a,b){try{let c=b?(0,j.computeWorktreePath)(a,b):a;return(0,g.realpathSync)(c)}catch{return null}}(b,e);if(!m)return{success:!1,error:"Path does not exist"};if("system"!==l)try{let a=(0,d.resolve)("IToolInstallerService").getTerminalOpenConfig(l);if(a?.openDirectory.includes("{dir}")){if(a.shell){let b=`'${m.replace(/'/g,"'\\''")}'`,c=a.openDirectory.replaceAll("{dir}",b),d=(0,i.spawn)(c,[],{detached:!0,stdio:"ignore",shell:!0});d.on("error",()=>void 0),d.unref()}else{let b=a.openDirectory.split(/\s+/).filter(Boolean),c=b[0],d=b.slice(1).map(a=>a.replaceAll("{dir}",m)),e=(0,i.spawn)(c,d,{detached:!0,stdio:"ignore"});e.on("error",()=>void 0),e.unref()}return{success:!0,path:m,shell:f}}}catch{}let n=k[(0,h.platform)()];if(!n)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let o=(0,i.spawn)(n.cmd,n.args(m),{detached:!0,stdio:"ignore"});return o.on("error",()=>void 0),o.unref(),{success:!0,path:m,shell:f}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open shell"}}}(0,e.ensureServerEntryExports)([l]),(0,b.registerServerReference)(l,"4004781548c34747283fe284c8d195ca487357e06e",null),a.s(["openShell",0,l],56799);let m={darwin:{cmd:"open",args:a=>[a]},linux:{cmd:"xdg-open",args:a=>[a]},win32:{cmd:"explorer",args:a=>[a]}};async function n(a){if(!a||!(0,c.isAbsolute)(a))return{success:!1,error:"repositoryPath must be an absolute path"};try{let b;try{b=(0,g.realpathSync)(a)}catch{return{success:!1,error:"Directory not found"}}let d=m[(0,h.platform)()];if(!d)return{success:!1,error:`Unsupported platform: ${(0,h.platform)()}`};let e=(0,c.normalize)(b),f=(0,i.spawn)(d.cmd,d.args(e),{detached:!0,stdio:"ignore"});return f.on("error",()=>void 0),f.unref(),{success:!0,path:b}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to open folder"}}}async function o(a){if(!a?.trim())return{success:!1,error:"Repository id is required"};try{let b=(0,d.resolve)("SyncRepositoryMainUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to sync repository"}}}async function p(){try{let a=(0,d.resolve)("LoadSettingsUseCase");return(await a.execute()).onboardingComplete}catch{return!1}}(0,e.ensureServerEntryExports)([n]),(0,b.registerServerReference)(n,"4079ba07e5d8c86c4880360723f3c69e3f51f09301",null),a.s(["openFolder",0,n],80496),(0,e.ensureServerEntryExports)([o]),(0,b.registerServerReference)(o,"40056e63d366d69696c57d7b5a4664d89f6b096689",null),a.s(["syncRepository",0,o],93225),(0,e.ensureServerEntryExports)([p]),(0,b.registerServerReference)(p,"004c1cd5bd750d92e24559b76d2d8a527b9fcb81f2",null),a.s(["isAgentSetupComplete",0,p],41872);var q=a.i(37512);let r={"claude-code":"Claude Code","codex-cli":"Codex CLI","copilot-cli":"GitHub Copilot CLI",cursor:"Cursor CLI","gemini-cli":"Gemini CLI","rovo-dev":"Rovo Dev CLI",aider:"Aider",continue:"Continue",dev:"Demo"},s={"claude-code":"claude-code","codex-cli":"codex-cli","copilot-cli":"copilot-cli",cursor:"cursor-cli","gemini-cli":"gemini-cli","rovo-dev":"rovo-dev"},t={"claude-code":"claude","codex-cli":"codex","copilot-cli":"copilot",cursor:"cursor-agent","gemini-cli":"gemini","rovo-dev":"acli"};function u(a,b){return new Promise(c=>{let d,e;switch(a){case"claude-code":d=b,e=["auth","status"];break;case"cursor":d=b,e=["status"];break;case"codex-cli":c(!1);return;case"copilot-cli":default:c(!0);return;case"rovo-dev":{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)("acli",["rovodev","auth","status"],a,a=>{c(!a)});return}}try{let a=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(d,e,a,a=>{c(!a)})}catch{c(!1)}})}async function v(){let a;try{let b=(0,d.resolve)("LoadSettingsUseCase");a=(await b.execute()).agent.type}catch{return{agentType:"unknown",installed:!1,authenticated:!1,label:"Unknown",binaryName:null,installCommand:null,authCommand:null}}let b=r[a]??a,e=s[a]??null,f=t[a]??null;if(!e)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:null,installCommand:null,authCommand:null};let i=!1,j=null;try{let a=(0,d.resolve)("ListToolsUseCase"),b=(await a.execute()).find(a=>a.id===e);i=b?.status.status==="available",j=b?.installCommand??null}catch{i=!1}if(!i)return{agentType:a,installed:!1,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f?`Install ${b} first`:null};let k=function(a){let b=(0,h.homedir)();switch(a){case"claude-code":{if(process.env.ANTHROPIC_API_KEY||process.env.CLAUDE_CODE_USE_BEDROCK||process.env.CLAUDE_CODE_USE_VERTEX||process.env.CLAUDE_CODE_OAUTH_TOKEN)return"env-var";let a=(0,c.join)(b,".claude",".credentials.json");return!!(0,g.existsSync)(a)&&"file"}case"codex-cli":if(process.env.OPENAI_API_KEY)return"env-var";return!1;case"cursor":{if(process.env.CURSOR_API_KEY)return"env-var";let a=(0,c.join)(b,".cursor");return!!(0,g.existsSync)(a)&&"file"}case"gemini-cli":{if(process.env.GEMINI_API_KEY||process.env.GOOGLE_API_KEY||process.env.GOOGLE_APPLICATION_CREDENTIALS)return"env-var";let a=(0,c.join)(b,".gemini","google_accounts.json");return!!(0,g.existsSync)(a)&&"file"}case"copilot-cli":{if(process.env.COPILOT_GITHUB_TOKEN||process.env.GH_TOKEN||process.env.GITHUB_TOKEN)return"env-var";let a=process.env.COPILOT_HOME?(0,c.join)(process.env.COPILOT_HOME,"config.json"):(0,c.join)(b,".copilot","config.json");return!!(0,g.existsSync)(a)&&"file"}case"rovo-dev":{if(process.env.ATLASSIAN_API_TOKEN)return"env-var";let a=(0,c.join)(b,".acli");return!!(0,g.existsSync)(a)&&"file"}default:return"env-var"}}(a);if("env-var"===k)return{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null};if("file"===k){let c=!0;return f&&(c=await u(a,f)),{agentType:a,installed:!0,authenticated:c,label:b,binaryName:f,installCommand:j,authCommand:c?null:f}}return f&&await u(a,f)?{agentType:a,installed:!0,authenticated:!0,label:b,binaryName:f,installCommand:j,authCommand:null}:{agentType:a,installed:!0,authenticated:!1,label:b,binaryName:f,installCommand:j,authCommand:f}}function w(a,b){return new Promise(c=>{try{let d=q.IS_WINDOWS?{timeout:5e3,windowsHide:!0}:{timeout:5e3};(0,i.execFile)(a,b,d,(a,b)=>{if(a)return void c({installed:!1,version:null});let d=b.match(/(\d+\.\d+(?:\.\d+)?)/);c({installed:!0,version:d?.[1]??null})})}catch{c({installed:!1,version:null})}})}async function x(){let[a,b,c]=await Promise.all([w("git",["--version"]),w("gh",["--version"]),(async()=>{try{let a=(0,d.resolve)("ListToolsUseCase");return await a.execute()}catch{return[]}})()]),e=c.find(a=>"git"===a.id),f=c.find(a=>"gh"===a.id);return{git:{...a,installCommand:e?.installCommand??null,installUrl:e?.website??"https://git-scm.com"},gh:{...b,installCommand:f?.installCommand??null,installUrl:f?.website??"https://cli.github.com"}}}async function y(a){let b=(0,d.resolve)("IFeatureRepository"),c=await b.findById(a);return c?{name:c.name,description:c.description}:null}async function z(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("ArchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to archive feature"}}}async function A(a,b,c,e){if(!a?.trim())return{error:"id is required"};try{let f=(0,d.resolve)("DeleteFeatureUseCase"),g={};return void 0!==b&&(g.cleanup=b),void 0!==c&&(g.cascadeDelete=c),void 0!==e&&(g.closePr=e),{feature:Object.keys(g).length>0?await f.execute(a,g):await f.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to delete feature"}}}async function B(a){if(!a.trim())return{resumed:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("ResumeFeatureUseCase");return await b.execute(a),{resumed:!0}}catch(a){return{resumed:!1,error:a instanceof Error?a.message:"Failed to resume feature"}}}async function C(a){if(!a.trim())return{started:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("StartFeatureUseCase");return await b.execute(a),{started:!0}}catch(a){return{started:!1,error:a instanceof Error?a.message:"Failed to start feature"}}}async function D(a){if(!a.trim())return{stopped:!1,error:"Feature id is required"};try{let b=(0,d.resolve)("IAgentRunRepository"),c=(await b.list()).find(b=>b.featureId===a&&"completed"!==b.status&&"failed"!==b.status&&"interrupted"!==b.status&&"cancelled"!==b.status);if(!c)return{stopped:!1,error:"No active agent run found for this feature"};let e=(0,d.resolve)("StopAgentRunUseCase"),f=await e.execute(c.id);if(!f.stopped)return{stopped:!1,error:f.reason};return{stopped:!0}}catch(a){return{stopped:!1,error:a instanceof Error?a.message:"Failed to stop agent"}}}async function E(a){if(!a?.trim())return{error:"id is required"};try{let b=(0,d.resolve)("UnarchiveFeatureUseCase");return{feature:await b.execute(a)}}catch(a){return{error:a instanceof Error?a.message:"Failed to unarchive feature"}}}async function F(a){let{path:b,name:c}=a;if(!b?.trim())return{error:"path is required"};try{let a=(0,d.resolve)("AddRepositoryUseCase");return{repository:await a.execute({path:b,name:c})}}catch(a){return{error:a instanceof Error?a.message:"Failed to add repository"}}}async function G(a){if(!a?.trim())return{success:!1,error:"id is required"};try{let b=(0,d.resolve)("DeleteRepositoryUseCase");return await b.execute(a),{success:!0}}catch(a){return{success:!1,error:a instanceof Error?a.message:"Failed to delete repository"}}}(0,e.ensureServerEntryExports)([v]),(0,b.registerServerReference)(v,"008bb64e62c8da45930ed722f946b39495438d9fe4",null),a.s(["checkAgentAuth",0,v],9959),(0,e.ensureServerEntryExports)([x]),(0,b.registerServerReference)(x,"002809c4bbafc76cdc68bbb45f0e98f2c4f4a2c326",null),a.s(["checkToolStatus",0,x],79124),(0,e.ensureServerEntryExports)([y]),(0,b.registerServerReference)(y,"405c0161a824d7c6bfb099b9a201402629f9a809f4",null),a.s(["getFeatureMetadata",0,y],29207),(0,e.ensureServerEntryExports)([z]),(0,b.registerServerReference)(z,"40a85456a342184720e7bd43147ef6d61ed80fe86a",null),a.s(["archiveFeature",0,z],10528),(0,e.ensureServerEntryExports)([A]),(0,b.registerServerReference)(A,"7830a0050246cf0a7c64eb408158d03b581fa9fd2d",null),a.s(["deleteFeature",0,A],50845),(0,e.ensureServerEntryExports)([B]),(0,b.registerServerReference)(B,"40cc33d9eef0ed0ff39c963fb96616983a83d163c9",null),a.s(["resumeFeature",0,B],26604),(0,e.ensureServerEntryExports)([C]),(0,b.registerServerReference)(C,"409a12726d14b0171bed27175fc895f1737e25a59f",null),a.s(["startFeature",0,C],54723),(0,e.ensureServerEntryExports)([D]),(0,b.registerServerReference)(D,"409ca41fe22f43beef5f6007804d4ea4af1c742d6e",null),a.s(["stopFeature",0,D],18942),(0,e.ensureServerEntryExports)([E]),(0,b.registerServerReference)(E,"401724219fbd15d0044167e2ceadcb426a1b88b6f1",null),a.s(["unarchiveFeature",0,E],42886),(0,e.ensureServerEntryExports)([F]),(0,b.registerServerReference)(F,"40eabff44164a320ffdbb4d78762d986a3a08e9cb3",null),a.s(["addRepository",0,F],49560),(0,e.ensureServerEntryExports)([G]),(0,b.registerServerReference)(G,"4094b8bc3c9b9c623df2845c71dc8335b7bc03f8dc",null),a.s(["deleteRepository",0,G],39353)}];
2
2
 
3
3
  //# sourceMappingURL=src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/open-ide.ts","../../../../../../../src/presentation/web/app/actions/open-shell.ts","../../../../../../../src/presentation/web/app/actions/open-folder.ts","../../../../../../../src/presentation/web/app/actions/sync-repository.ts","../../../../../../../src/presentation/web/app/actions/agent-setup-flag.ts","../../../../../../../src/presentation/web/app/actions/check-agent-auth.ts","../../../../../../../src/presentation/web/app/actions/check-tool-status.ts","../../../../../../../src/presentation/web/app/actions/get-feature-metadata.ts","../../../../../../../src/presentation/web/app/actions/archive-feature.ts","../../../../../../../src/presentation/web/app/actions/delete-feature.ts","../../../../../../../src/presentation/web/app/actions/resume-feature.ts","../../../../../../../src/presentation/web/app/actions/start-feature.ts","../../../../../../../src/presentation/web/app/actions/stop-feature.ts","../../../../../../../src/presentation/web/app/actions/unarchive-feature.ts","../../../../../../../src/presentation/web/app/actions/add-repository.ts","../../../../../../../src/presentation/web/app/actions/delete-repository.ts"],"sourcesContent":["'use server';\n\nimport { isAbsolute } from 'node:path';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { LaunchIdeUseCase } from '@shipit-ai/core/application/use-cases/ide/launch-ide.use-case';\n\ninterface OpenIdeInput {\n repositoryPath: string;\n branch?: string;\n}\n\nexport async function openIde(\n input: OpenIdeInput\n): Promise<{ success: boolean; error?: string; editor?: string; path?: string }> {\n const { repositoryPath, branch } = input;\n\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n const editor = settings.environment.defaultEditor;\n\n const useCase = resolve<LaunchIdeUseCase>('LaunchIdeUseCase');\n const result = await useCase.execute({\n editorId: editor,\n repositoryPath,\n branch,\n checkAvailability: true,\n });\n\n if (!result.ok) {\n return { success: false, error: result.message };\n }\n\n return { success: true, editor: result.editorName, path: result.worktreePath };\n}\n","'use server';\n\nimport { existsSync } from 'node:fs';\nimport { platform } from 'node:os';\nimport { isAbsolute } from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { computeWorktreePath } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { IToolInstallerService } from '@shipit-ai/core/application/ports/output/services/tool-installer.service';\n\n// Fallback commands for the \"system\" terminal when no tool metadata entry exists.\n// Uses a record lookup instead of if/else to prevent the bundler from\n// tree-shaking platform branches at build time. Turbopack evaluates\n// os.platform() during the build and dead-code-eliminates unused branches,\n// baking in the CI platform (linux) and breaking macOS/Windows installs.\nconst SYSTEM_TERMINAL_COMMANDS: Record<string, { cmd: string; args: (path: string) => string[] }> =\n {\n darwin: { cmd: 'open', args: (p) => ['-a', 'Terminal', p] },\n linux: { cmd: 'x-terminal-emulator', args: (p) => [`--working-directory=${p}`] },\n win32: {\n cmd: 'cmd.exe',\n args: (p) => ['/c', 'start', 'powershell', '-NoExit', '-Command', `Set-Location \"${p}\"`],\n },\n };\n\ninterface OpenShellInput {\n repositoryPath: string;\n branch?: string;\n}\n\nexport async function openShell(\n input: OpenShellInput\n): Promise<{ success: boolean; error?: string; path?: string; shell?: string }> {\n const { repositoryPath, branch } = input;\n\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n try {\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n const shell = settings.environment.shellPreference;\n const terminalPref = settings.environment.terminalPreference ?? 'system';\n const targetPath = branch ? computeWorktreePath(repositoryPath, branch) : repositoryPath;\n\n if (!existsSync(targetPath)) {\n return { success: false, error: `Path does not exist: ${targetPath}` };\n }\n\n // Try to find the terminal in tool metadata via DI container.\n // Using DI (not a direct import from tool-metadata) ensures that\n // TOOL_METADATA is read from the correct tools/ directory path — it is loaded once\n // in the Node.js CLI bootstrap context where import.meta.url resolves correctly.\n // Direct imports of tool-metadata break in standalone production builds.\n if (terminalPref !== 'system') {\n try {\n const service = resolve<IToolInstallerService>('IToolInstallerService');\n const config = service.getTerminalOpenConfig(terminalPref);\n\n if (config?.openDirectory.includes('{dir}')) {\n const resolved = config.openDirectory.replace('{dir}', targetPath);\n\n if (config.shell) {\n const child = spawn(resolved, [], {\n detached: true,\n stdio: 'ignore',\n shell: true,\n });\n child.on('error', () => undefined);\n child.unref();\n } else {\n const [command, ...args] = resolved.split(/\\s+/);\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined);\n child.unref();\n }\n\n return { success: true, path: targetPath, shell };\n }\n } catch {\n // DI container not available — fall through to system terminal\n }\n }\n\n // Fallback to system terminal\n const entry = SYSTEM_TERMINAL_COMMANDS[platform()];\n if (!entry) {\n return {\n success: false,\n error: `Unsupported platform: ${platform()}`,\n };\n }\n\n const child = spawn(entry.cmd, entry.args(targetPath), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined); // Prevent uncaught exception on spawn failure\n child.unref();\n\n return { success: true, path: targetPath, shell };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to open shell';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { existsSync } from 'node:fs';\nimport { platform } from 'node:os';\nimport { isAbsolute, normalize } from 'node:path';\nimport { spawn } from 'node:child_process';\n\n// Use a record lookup instead of if/else to prevent the bundler from\n// tree-shaking platform branches at build time. Turbopack evaluates\n// os.platform() during the build and dead-code-eliminates unused branches,\n// baking in the CI platform (linux) and breaking macOS/Windows installs.\nconst FOLDER_COMMANDS: Record<string, { cmd: string; args: (path: string) => string[] }> = {\n darwin: { cmd: 'open', args: (p) => [p] },\n linux: { cmd: 'xdg-open', args: (p) => [p] },\n win32: { cmd: 'explorer', args: (p) => [p] },\n};\n\nexport async function openFolder(\n repositoryPath: string\n): Promise<{ success: boolean; error?: string; path?: string }> {\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n try {\n if (!existsSync(repositoryPath)) {\n return { success: false, error: 'Directory not found' };\n }\n\n const entry = FOLDER_COMMANDS[platform()];\n if (!entry) {\n return {\n success: false,\n error: `Unsupported platform: ${platform()}`,\n };\n }\n\n // Normalize to platform-native separators — explorer.exe on Windows\n // does not understand forward-slash paths and falls back to Documents.\n const nativePath = normalize(repositoryPath);\n\n const child = spawn(entry.cmd, entry.args(nativePath), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined); // Prevent uncaught exception on spawn failure\n child.unref();\n\n return { success: true, path: repositoryPath };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to open folder';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { SyncRepositoryMainUseCase } from '@shipit-ai/core/application/use-cases/repositories/sync-repository-main.use-case';\n\nexport async function syncRepository(\n repositoryId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!repositoryId?.trim()) {\n return { success: false, error: 'Repository id is required' };\n }\n\n try {\n const useCase = resolve<SyncRepositoryMainUseCase>('SyncRepositoryMainUseCase');\n await useCase.execute(repositoryId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to sync repository';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\n\n/**\n * Check whether onboarding has been completed.\n */\nexport async function isAgentSetupComplete(): Promise<boolean> {\n try {\n const useCase = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await useCase.execute();\n return settings.onboardingComplete;\n } catch {\n return false;\n }\n}\n","'use server';\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { execFile } from 'node:child_process';\nimport { IS_WINDOWS } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { ListToolsUseCase } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface AgentAuthStatus {\n agentType: string;\n /** Whether the CLI tool binary is installed */\n installed: boolean;\n /** Whether credentials / auth appear valid */\n authenticated: boolean;\n /** Human-readable label for the agent */\n label: string;\n /** CLI binary name (e.g. \"claude\", \"gemini\") */\n binaryName: string | null;\n /** Shell command to install the tool (e.g. \"npm install -g @anthropic-ai/claude-code\") */\n installCommand: string | null;\n /** Instructions to authenticate if not authenticated */\n authCommand: string | null;\n}\n\nconst AGENT_LABELS: Record<string, string> = {\n 'claude-code': 'Claude Code',\n 'codex-cli': 'Codex CLI',\n 'copilot-cli': 'GitHub Copilot CLI',\n cursor: 'Cursor CLI',\n 'gemini-cli': 'Gemini CLI',\n 'rovo-dev': 'Rovo Dev CLI',\n aider: 'Aider',\n continue: 'Continue',\n dev: 'Demo',\n};\n\nconst AGENT_TOOL_MAP: Record<string, string> = {\n 'claude-code': 'claude-code',\n 'codex-cli': 'codex-cli',\n 'copilot-cli': 'copilot-cli',\n cursor: 'cursor-cli',\n 'gemini-cli': 'gemini-cli',\n 'rovo-dev': 'rovo-dev',\n};\n\nconst AGENT_BINARY_MAP: Record<string, string> = {\n 'claude-code': 'claude',\n 'codex-cli': 'codex',\n 'copilot-cli': 'copilot',\n cursor: 'cursor-agent',\n 'gemini-cli': 'gemini',\n 'rovo-dev': 'acli',\n};\n\n/**\n * Tier 1 result indicating how auth was detected.\n * - 'env-var': Explicit env var config (e.g. ANTHROPIC_API_KEY for proxy/gateway) — skip Tier 2\n * - 'file': Credential file found — run Tier 2 to verify tokens aren't expired\n * - false: No credentials found in known locations\n */\ntype Tier1Result = 'env-var' | 'file' | false;\n\n/**\n * Tier 1: Instant credential/env check (~5ms, no subprocess).\n * Distinguishes env-var auth (explicit user config, e.g. API key for a proxy)\n * from file-based auth (may be stale, needs Tier 2 verification).\n */\nfunction tier1AuthCheck(agentType: string): Tier1Result {\n const home = homedir();\n\n switch (agentType) {\n case 'claude-code': {\n if (process.env['ANTHROPIC_API_KEY']) return 'env-var';\n if (process.env['CLAUDE_CODE_USE_BEDROCK']) return 'env-var';\n if (process.env['CLAUDE_CODE_USE_VERTEX']) return 'env-var';\n if (process.env['CLAUDE_CODE_OAUTH_TOKEN']) return 'env-var';\n const credPath = join(home, '.claude', '.credentials.json');\n return existsSync(credPath) ? 'file' : false;\n }\n case 'codex-cli': {\n if (process.env['OPENAI_API_KEY']) return 'env-var';\n return false;\n }\n case 'cursor': {\n if (process.env['CURSOR_API_KEY']) return 'env-var';\n const cursorDir = join(home, '.cursor');\n return existsSync(cursorDir) ? 'file' : false;\n }\n case 'gemini-cli': {\n if (process.env['GEMINI_API_KEY']) return 'env-var';\n if (process.env['GOOGLE_API_KEY']) return 'env-var';\n if (process.env['GOOGLE_APPLICATION_CREDENTIALS']) return 'env-var';\n const accountsPath = join(home, '.gemini', 'google_accounts.json');\n return existsSync(accountsPath) ? 'file' : false;\n }\n case 'copilot-cli': {\n if (process.env['COPILOT_GITHUB_TOKEN']) return 'env-var';\n if (process.env['GH_TOKEN']) return 'env-var';\n if (process.env['GITHUB_TOKEN']) return 'env-var';\n const configPath = process.env['COPILOT_HOME']\n ? join(process.env['COPILOT_HOME'], 'config.json')\n : join(home, '.copilot', 'config.json');\n return existsSync(configPath) ? 'file' : false;\n }\n case 'rovo-dev': {\n if (process.env['ATLASSIAN_API_TOKEN']) return 'env-var';\n const acliDir = join(home, '.acli');\n return existsSync(acliDir) ? 'file' : false;\n }\n default:\n // dev, aider, continue — assume no auth needed\n return 'env-var';\n }\n}\n\n/**\n * Tier 2: Subprocess verification (~200ms).\n * Only called if tier 1 passes, to confirm tokens aren't expired.\n */\nfunction tier2AuthVerify(agentType: string, binaryName: string): Promise<boolean> {\n return new Promise((resolve) => {\n let cmd: string;\n let args: string[];\n\n switch (agentType) {\n case 'claude-code':\n cmd = binaryName;\n args = ['auth', 'status'];\n break;\n case 'cursor':\n cmd = binaryName;\n args = ['status'];\n break;\n case 'codex-cli':\n // Codex CLI has no `auth status` command — cannot verify via subprocess\n resolve(false);\n return;\n case 'copilot-cli':\n // No auth status command — trust tier 1\n resolve(true);\n return;\n case 'rovo-dev': {\n const rovoOpts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile('acli', ['rovodev', 'auth', 'status'], rovoOpts, (error) => {\n resolve(!error);\n });\n return;\n }\n default:\n // No tier 2 command available — trust tier 1\n resolve(true);\n return;\n }\n\n try {\n const opts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile(cmd, args, opts, (error) => {\n resolve(!error);\n });\n } catch {\n resolve(false);\n }\n });\n}\n\n/**\n * Check agent tool installation + auth status.\n * Uses two-tier detection: instant file/env check, then optional subprocess verify.\n */\nexport async function checkAgentAuth(): Promise<AgentAuthStatus> {\n let agentType: string;\n try {\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n agentType = settings.agent.type;\n } catch {\n return {\n agentType: 'unknown',\n installed: false,\n authenticated: false,\n label: 'Unknown',\n binaryName: null,\n installCommand: null,\n authCommand: null,\n };\n }\n\n const label = AGENT_LABELS[agentType] ?? agentType;\n const toolId = AGENT_TOOL_MAP[agentType] ?? null;\n const binaryName = AGENT_BINARY_MAP[agentType] ?? null;\n\n // Dev/demo agents — always good\n if (!toolId) {\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName: null,\n installCommand: null,\n authCommand: null,\n };\n }\n\n // Check if tool is installed (also grab install command from metadata)\n let installed = false;\n let installCommand: string | null = null;\n try {\n const useCase = resolve<ListToolsUseCase>('ListToolsUseCase');\n const tools = await useCase.execute();\n const tool = tools.find((t) => t.id === toolId);\n installed = tool?.status.status === 'available';\n installCommand = tool?.installCommand ?? null;\n } catch {\n installed = false;\n }\n\n if (!installed) {\n return {\n agentType,\n installed: false,\n authenticated: false,\n label,\n binaryName,\n installCommand,\n authCommand: binaryName ? `Install ${label} first` : null,\n };\n }\n\n // Tier 1: instant file/env check — fast path for known credential locations\n const tier1 = tier1AuthCheck(agentType);\n\n if (tier1 === 'env-var') {\n // Explicit env var auth (e.g. ANTHROPIC_API_KEY for LiteLLM proxy).\n // Trust the user's config — skip Tier 2 subprocess check which may\n // fail against a proxy that the CLI binary doesn't know about.\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName,\n installCommand,\n authCommand: null,\n };\n }\n\n if (tier1 === 'file') {\n // Credential file found but may be stale/expired.\n // Run Tier 2 subprocess verify to confirm tokens are still valid (~200ms).\n let authenticated = true;\n if (binaryName) {\n authenticated = await tier2AuthVerify(agentType, binaryName);\n }\n return {\n agentType,\n installed: true,\n authenticated,\n label,\n binaryName,\n installCommand,\n authCommand: authenticated ? null : binaryName,\n };\n }\n\n // Tier 1 found nothing — credentials not in expected locations.\n // Fall through to Tier 2 because some auth methods (e.g. Claude Code OAuth\n // via claude.ai) store credentials outside the paths Tier 1 checks.\n if (binaryName) {\n const authenticated = await tier2AuthVerify(agentType, binaryName);\n if (authenticated) {\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName,\n installCommand,\n authCommand: null,\n };\n }\n }\n\n // Both tiers failed — agent genuinely needs authentication\n return {\n agentType,\n installed: true,\n authenticated: false,\n label,\n binaryName,\n installCommand,\n authCommand: binaryName,\n };\n}\n","'use server';\n\nimport { execFile } from 'node:child_process';\nimport { IS_WINDOWS } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { ListToolsUseCase } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolStatusEntry {\n installed: boolean;\n version: string | null;\n /** Platform-specific install command from tool JSON metadata */\n installCommand: string | null;\n /** Documentation/website URL */\n installUrl: string | null;\n}\n\nexport interface ToolStatusResult {\n git: ToolStatusEntry;\n gh: ToolStatusEntry;\n}\n\nfunction getVersion(\n command: string,\n args: string[]\n): Promise<{ installed: boolean; version: string | null }> {\n return new Promise((resolve) => {\n try {\n const opts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile(command, args, opts, (error, stdout) => {\n if (error) {\n resolve({ installed: false, version: null });\n return;\n }\n // Extract version number from output like \"git version 2.43.0\" or \"gh version 2.40.1\"\n const match = stdout.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n resolve({ installed: true, version: match?.[1] ?? null });\n });\n } catch {\n resolve({ installed: false, version: null });\n }\n });\n}\n\nexport async function checkToolStatus(): Promise<ToolStatusResult> {\n // Run version checks and tool metadata lookup in parallel\n const [gitVersion, ghVersion, tools] = await Promise.all([\n getVersion('git', ['--version']),\n getVersion('gh', ['--version']),\n (async () => {\n try {\n const useCase = resolve<ListToolsUseCase>('ListToolsUseCase');\n return await useCase.execute();\n } catch {\n return [];\n }\n })(),\n ]);\n\n const gitTool = tools.find((t) => t.id === 'git');\n const ghTool = tools.find((t) => t.id === 'gh');\n\n return {\n git: {\n ...gitVersion,\n installCommand: gitTool?.installCommand ?? null,\n installUrl: gitTool?.website ?? 'https://git-scm.com',\n },\n gh: {\n ...ghVersion,\n installCommand: ghTool?.installCommand ?? null,\n installUrl: ghTool?.website ?? 'https://cli.github.com',\n },\n };\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\n/**\n * Lightweight server action to fetch a single feature's name and description.\n * Used by the SSE effect to update node metadata after AI metadata generation\n * without a full graph reconcile (which can overwrite SSE-driven state).\n */\nexport async function getFeatureMetadata(\n featureId: string\n): Promise<{ name: string; description: string } | null> {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n if (!feature) return null;\n return { name: feature.name, description: feature.description };\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ArchiveFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/archive-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function archiveFeature(\n featureId: string\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const archiveFeatureUseCase = resolve<ArchiveFeatureUseCase>('ArchiveFeatureUseCase');\n const feature = await archiveFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to archive feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { DeleteFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/delete-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function deleteFeature(\n featureId: string,\n cleanup?: boolean,\n cascadeDelete?: boolean,\n closePr?: boolean\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const deleteFeatureUseCase = resolve<DeleteFeatureUseCase>('DeleteFeatureUseCase');\n const options: { cleanup?: boolean; cascadeDelete?: boolean; closePr?: boolean } = {};\n if (cleanup !== undefined) options.cleanup = cleanup;\n if (cascadeDelete !== undefined) options.cascadeDelete = cascadeDelete;\n if (closePr !== undefined) options.closePr = closePr;\n const feature =\n Object.keys(options).length > 0\n ? await deleteFeatureUseCase.execute(featureId, options)\n : await deleteFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to delete feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ResumeFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/resume-feature.use-case';\n\nexport async function resumeFeature(\n featureId: string\n): Promise<{ resumed: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { resumed: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<ResumeFeatureUseCase>('ResumeFeatureUseCase');\n await useCase.execute(featureId);\n return { resumed: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to resume feature';\n return { resumed: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { StartFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/start-feature.use-case';\n\nexport async function startFeature(\n featureId: string\n): Promise<{ started: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { started: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<StartFeatureUseCase>('StartFeatureUseCase');\n await useCase.execute(featureId);\n return { started: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to start feature';\n return { started: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { StopAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/stop-agent-run.use-case';\nimport type { IAgentRunRepository } from '@shipit-ai/core/application/ports/output/agents/agent-run-repository.interface';\n\nexport async function stopFeature(\n featureId: string\n): Promise<{ stopped: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { stopped: false, error: 'Feature id is required' };\n }\n\n try {\n // Find the active agent run for this feature\n const runRepo = resolve<IAgentRunRepository>('IAgentRunRepository');\n const allRuns = await runRepo.list();\n const activeRun = allRuns.find(\n (r) =>\n r.featureId === featureId &&\n r.status !== 'completed' &&\n r.status !== 'failed' &&\n r.status !== 'interrupted' &&\n r.status !== 'cancelled'\n );\n\n if (!activeRun) {\n return { stopped: false, error: 'No active agent run found for this feature' };\n }\n\n const useCase = resolve<StopAgentRunUseCase>('StopAgentRunUseCase');\n const result = await useCase.execute(activeRun.id);\n\n if (!result.stopped) {\n return { stopped: false, error: result.reason };\n }\n return { stopped: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to stop agent';\n return { stopped: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { UnarchiveFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/unarchive-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function unarchiveFeature(\n featureId: string\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const unarchiveFeatureUseCase = resolve<UnarchiveFeatureUseCase>('UnarchiveFeatureUseCase');\n const feature = await unarchiveFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to unarchive feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { AddRepositoryUseCase } from '@shipit-ai/core/application/use-cases/repositories/add-repository.use-case';\nimport type { Repository } from '@shipit-ai/core/domain/generated/output';\n\ninterface AddRepositoryInput {\n path: string;\n name?: string;\n}\n\nexport async function addRepository(\n input: AddRepositoryInput\n): Promise<{ repository?: Repository; error?: string }> {\n const { path, name } = input;\n\n if (!path?.trim()) {\n return { error: 'path is required' };\n }\n\n try {\n const addRepoUseCase = resolve<AddRepositoryUseCase>('AddRepositoryUseCase');\n const repository = await addRepoUseCase.execute({ path, name });\n return { repository };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to add repository';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { DeleteRepositoryUseCase } from '@shipit-ai/core/application/use-cases/repositories/delete-repository.use-case';\n\nexport async function deleteRepository(\n repositoryId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!repositoryId?.trim()) {\n return { success: false, error: 'id is required' };\n }\n\n try {\n const useCase = resolve<DeleteRepositoryUseCase>('DeleteRepositoryUseCase');\n await useCase.execute(repositoryId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to delete repository';\n return { success: false, error: message };\n }\n}\n"],"names":["openIde","input","repositoryPath","branch","success","error","loadSettings","settings","execute","editor","environment","defaultEditor","useCase","result","editorId","checkAvailability","ok","message","editorName","path","worktreePath"],"mappings":"gJAEA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,EAAA,CAAA,CAAA,oBASO,eAAeA,EACpBC,CAAmB,EAEnB,GAAM,gBAAEC,CAAc,CAAEC,QAAM,CAAE,CAAGF,EAEnC,GAAI,CAACC,GAAkB,CAAC,CAAA,EAAA,EAAA,UAAA,AAAU,EAACA,GACjC,MAAO,CAAEE,OADyC,EAChC,EAAOC,MAAO,yCAA0C,EAG5E,IAAMC,EAAe,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBAE5CG,EAASF,CADE,MAAMD,EAAaE,OAAO,EAAA,EACnBE,WAAW,CAACC,aAAa,CAE3CC,EAAU,CAAA,EAAA,EAAA,OAAO,AAAP,EAA0B,oBACpCC,EAAS,MAAMD,EAAQJ,OAAO,CAAC,CACnCM,SAAUL,iBACVP,SACAC,EACAY,mBAAmB,CACrB,UAEA,AAAKF,EAAOG,EAAR,AAAU,CAIP,CAJS,AAIPZ,SAAS,EAAMK,OAAQI,EAAOK,UAAU,CAAEC,KAAMN,EAAOO,YAAY,AAAC,EAHpE,CAAEhB,SAAS,EAAOC,MAAOQ,EAAOI,OAAO,AAAC,CAInD,iCA1BsBjB,IAAAA,CAAAA,EAAAA,EAAAA,uBAAAA,EAAAA,EAAAA,6CAAAA,iCCVtB,IAAA,EAAA,EAAA,CAAA,CAAA,MACA,EAAA,EAAA,CAAA,CAAA,OAEA,EAAA,EAAA,CAAA,CAAA,OACA,EAAA,CAAA,CAAA,MAAA,IAAA,EAAA,EAAA,CAAA,CAAA,OAUA,IAAM,EACJ,CACEQ,OAAQ,CAAE,IAAK,OAAQ,KAAM,AAAC,GAAMN,CAAC,KAAM,WAAY,EAAE,AAAC,EAC1D,MAAO,CAAE,IAAK,sBAAuB,KAAM,AAAC,GAAM,CAAC,CAAC,oBAAoB,EAAE,EAAA,CAAG,CAAC,AAAC,EAC/E,MAAO,CACL,IAAK,UACL,KAAO,AAAD,GAAO,CAAC,KAAM,QAAS,aAAc,UAAW,WAAY,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,CAAC,AAC1F,CACF,EAOK,eAAe,EACpB,CAAqB,EAErB,GAAM,gBAAE,CAAc,QAAE,CAAM,CAAE,CAAG,EAEnC,GAAI,CAAC,GAAkB,CAAC,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,GACjC,MAAO,CAAE,OADyC,EAChC,EAAO,MAAO,yCAA0C,EAG5E,GAAI,CACF,IAAM,EAAe,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBAC5C,EAAW,MAAM,EAAa,OAAO,GACrC,EAAQ,EAAS,WAAW,CAAC,eAAe,CAC5C,EAAe,EAAS,WAAW,CAAC,kBAAkB,EAAI,SAC1D,EAAa,EAAS,CAAA,EAAA,EAAA,mBAAA,AAAmB,EAAC,EAAgB,GAAU,EAE1E,GAAI,CAAC,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,GACd,MAAO,CAAE,GADkB,MACT,EAAO,MAAO,CAAC,qBAAqB,EAAE,EAAA,CAAY,AAAC,EAQvE,GAAqB,UAAU,CAA3B,EACF,GAAI,CAEF,IAAM,EADU,AACD,CADC,EAAA,EAAA,OAAA,AAAO,EAAwB,yBACxB,qBAAqB,CAAC,GAE7C,GAAI,GAAQ,cAAc,SAAS,SAAU,CAC3C,IAAM,EAAW,EAAO,aAAa,CAAC,OAAO,CAAC,QAAS,GAEvD,GAAI,EAAO,KAAK,CAAE,CAChB,IAAM,EAAQ,CAAA,EAAA,EAAA,KAAA,AAAK,EAAC,EAAU,EAAE,CAAE,CAChC,UAAU,EACV,MAAO,SACP,OAAO,CACT,GACA,EAAM,EAAE,CAAC,QAAS,SAAM,GACxB,EAAM,KAAK,EACb,KAAO,CACL,GAAM,CAAC,EAAS,GAAG,EAAK,CAAG,EAAS,KAAK,CAAC,OACpC,EAAQ,CAAA,EAAA,EAAA,KAAA,AAAK,EAAC,EAAS,EAAM,CACjC,UAAU,EACV,MAAO,QACT,GACA,EAAM,EAAE,CAAC,QAAS,SAAM,GACxB,EAAM,KAAK,EACb,CAEA,MAAO,CAAE,QAAS,GAAM,KAAM,QAAY,CAAM,CAClD,CACF,CAAE,KAAM,CAER,CAIF,IAAM,EAAQ,CAAwB,CAAC,CAAA,EAAA,EAAA,QAAA,AAAQ,IAAG,CAClD,GAAI,CAAC,EACH,KADU,CACH,CACL,SAAS,EACT,MAAO,CAAC,sBAAsB,EAAE,CAAA,EAAA,EAAA,QAAQ,AAAR,IAAQ,CAAI,AAC9C,EAGF,IAAM,EAAQ,CAAA,EAAA,EAAA,KAAA,AAAK,EAAC,EAAM,GAAG,CAAE,EAAM,IAAI,CAAC,GAAa,CACrD,UAAU,EACV,MAAO,QACT,GAIA,OAHA,EAAM,EAAE,CAAC,QAAS,SAAM,GACxB,EAAM,KAAK,EADyB,CAG7B,CAAE,SAAS,EAAM,KAAM,QAAY,CAAM,CAClD,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,CANyE,QAMhE,EAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,sBACjB,CAC1C,CACF,iCA/EsB,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,mCCpBtB,IAAM,EAAqF,CACzFD,OAAQ,CAAE,IAAKC,OAAQ,KAAM,AAAC,GAAM,CAAC,EAAE,AAAC,EACxCA,MAAO,CAAE,IAAK,WAAY,KAAME,AAAC,GAAM,CAAC,EAAE,AAAC,EAC3CC,MAAO,CAAE,IAAK,WAAY,KAAM,AAAC,GAAM,CAAC,EAAE,AAAC,CAC7C,EAEO,eAAe,EACpB,CAAsB,EAEtB,GAAI,CAAC,GAAkB,CAAC,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,GACjC,MAAO,CAAEO,OADyC,EAChC,EAAO,MAAO,yCAA0CC,EAG5E,GAAI,CACF,GAAI,CAAC,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,GACd,MAAO,CAAE,OADsB,EACbV,EAAO,MAAO,qBAAsB,EAGxD,IAAM,EAAQ,CAAe,CAAC,CAAA,EAAA,EAAA,QAAA,AAAQ,IAAG,CACzC,GAAI,CAAC,EACH,KADU,CACH,CACLC,SAAS,EACT,MAAO,CAAC,sBAAsB,EAAE,CAAA,EAAA,EAAA,QAAQ,AAAR,IAAQ,CAC1C,AAD8C,EAMhD,IAAM,EAAa,CAAA,EAAA,EAAA,SAAA,AAAS,EAAC,GAEvB,EAAQ,CAAA,EAAA,EAAA,KAAA,AAAK,EAAC,EAAM,GAAG,CAAE,EAAM,IAAI,CAAC,GAAa,CACrD,UAAU,EACV,MAAO,QACT,GAIA,OAHA,EAAM,EAAE,CAAC,QAAS,SAAM,GACxB,EAAM,KAAK,EADyB,CAG7B,CAAE,SAAS,EAAM,KAAM,CAAe,CAC/C,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,SAAS,AANgE,EAMzD,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,uBACjB,CAC1C,CACF,CChDO,eAAe,EACpB,CAAoB,EAEpB,GAAI,CAAC,GAAc,OACjB,CADyB,KAClB,CAAE,SAAS,EAAO,MAAO,2BAA4B,EAG9D,GAAIJ,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAA4B,6BAEnD,OADA,MAAM,EAAQ,OAAO,CAAC,GACf,CAAE,SAAS,CAAK,CACzB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,SAAS,EAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,2BACjB,CAC1C,CACF,CCZO,eAAe,IACpB,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBAE7C,MAAO,CADU,MAAM,EAAQ,OAAO,EAAA,EACtB,kBAClB,AADoC,CAClC,KAAM,CACN,OAAO,CACT,CACF,iCFCsB,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,oECZA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,wECGA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,8CCFtB,IAAA,EAAA,EAAA,CAAA,CAAA,OAqBA,IAAM,EAAuC,CAC3C,cAAe,cACf,YAAa,YACbiB,cAAe,qBACf,OAAQ,aACR,aAAc,aACd,WAAY,eACZ,MAAO,QACP,SAAU,WACV,IAAK,MACP,EAEM,EAAyC,CAC7C,cAAe,cACf,YAAa,YACb,cAAe,cACf,OAAQ,aACR,aAAc,aACd,WAAY,UACd,EAEM,EAA2C,CAC/C,cAAe,SACf,YAAa,QACb,cAAe,UACf,OAAQ,eACR,aAAc,SACd,WAAY,MACd,EAmEA,SAAS,EAAgB,CAAiB,CAAE,CAAkB,EAC5D,OAAO,IAAI,QAAQ,AAAC,IAClB,IAAI,EACA,EAEJ,OAAQ,GACN,IAAK,cACH,EAAM,EACN,EAAO,CAAC,OAAQ,SAAS,CACzB,KACF,KAAK,SACH,EAAM,EACN,EAAO,CAAC,SAAS,CACjB,KACF,KAAK,YAEH,GAAQ,GACR,MACF,KAAK,cAWL,QATE,GAAQ,GACR,MACF,KAAK,WAAY,CACf,IAAM,EAAW,EAAA,UAAU,CAAG,CAAE,QAAS,IAAM,aAAa,CAAK,EAAI,CAAE,QAAS,GAAK,EACrF,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,OAAQ,CAAC,UAAW,OAAQ,SAAS,CAAE,EAAU,AAAC,IACzD,EAAQ,CAAC,EACX,GACA,MACF,CAKF,CAEA,GAAI,CACF,IAAM,EAAO,EAAA,UAAU,CAAG,CAAE,QAAS,IAAM,aAAa,CAAK,EAAI,CAAE,QAAS,GAAK,EACjF,CAAA,EAAA,EAAA,QAAA,AAAQ,EAAC,EAAK,EAAM,EAAM,AAAC,IACzB,EAAQ,CAAC,EACX,EACF,CAAE,KAAM,CACN,GAAQ,EACV,CACF,EACF,CAMO,eAAe,QAChB,EACJ,GAAI,CACF,IAAM,EAAe,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBAElD,EAAY,CADK,MAAM,EAAa,OAAO,EAAA,EACtB,KAAK,CAAC,IAAI,AACjC,CAAE,KAAM,CACN,MAAO,CACL,UAAW,UACX,UAAW,GACX,cAAe,GACf,MAAO,UACP,WAAY,KACZ,eAAgB,KAChB,YAAa,IACf,CACF,CAEA,IAAM,EAAQ,CAAY,CAAC,EAAU,EAAI,EACnC,EAAS,CAAc,CAAC,EAAU,EAAI,KACtC,EAAa,CAAgB,CAAC,EAAU,EAAI,KAGlD,GAAI,CAAC,EACH,MADW,AACJ,WACL,EACA,WAAW,EACX,eAAe,QACf,EACA,WAAY,KACZ,eAAgB,KAChB,YAAa,IACf,EAIF,IAAI,GAAY,EACZ,EAAgC,KACpC,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAAmB,oBAEpC,EAAO,CADC,MAAM,EAAQ,OAAO,EAAA,EAChB,IAAI,CAAC,AAAC,GAAM,EAAE,EAAE,GAAK,GACxC,EAAY,GAAM,OAAO,SAAW,YACpC,EAAiB,GAAM,gBAAkB,IAC3C,CAAE,KAAM,CACN,GAAY,CACd,CAEA,GAAI,CAAC,EACH,MAAO,GADO,QAEZ,EACA,WAAW,EACX,eAAe,QACf,aACA,iBACA,EACA,YAAa,EAAa,CAAC,QAAQ,EAAE,EAAM,MAAM,CAAC,CAAG,IACvD,EAIF,IAAM,EAAQ,AAnKhB,SAAS,AAAe,CAAiB,EACvC,IAAM,EAAO,CAAA,EAAA,EAAA,OAAA,AAAO,IAEpB,OAAQ,GACN,IAAK,cAAe,CAClB,GAAI,QAAQ,GAAG,CAAC,iBAAoB,EAChC,QAAQ,GAAG,CAAC,uBAA0B,EAAE,AACxC,OAD+C,CACvC,GAAG,CAAC,sBAAyB,EAAE,AACvC,OAD8C,CACtC,GAAG,CAAC,uBAA0B,CAHJ,CAGM,KAHC,EAGM,QACnD,IAAM,EAAW,CAAA,EAAA,EAAA,IAAA,AAAI,EAAC,EAAM,UAAW,qBACvC,QAAO,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,IAAY,MAChC,CACA,EAFyC,EAEpC,YACH,GAAI,QAAQ,GAAG,CAAC,cAAiB,CAAE,MAAO,UAC1C,OAAO,CAET,KAAK,SAAU,CACb,GAAI,QAAQ,GAAG,CAAC,cAAiB,CAAE,MAAO,UAC1C,IAAM,EAAY,CAAA,EAAA,EAAA,IAAA,AAAI,EAAC,EAAM,WAC7B,QAAO,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,IAAa,MACjC,CACA,EAF0C,EAErC,aAAc,CACjB,GAAI,QAAQ,GAAG,CAAC,cAAiB,EAC7B,QAAQ,GAAG,CAAC,cAAiB,EAAE,AAC/B,OADsC,CAC9B,GAAG,CAAC,8BAAiC,CAFd,CAEgB,KAFT,EAEgB,QAC1D,IAAM,EAAe,CAAA,EAAA,EAAA,IAAA,AAAI,EAAC,EAAM,UAAW,wBAC3C,QAAO,CAAA,EAAA,EAAA,UAAA,AAAU,EAAC,IAAgB,MACpC,CACA,EAF6C,EAExC,cAAe,CAClB,GAAI,QAAQ,GAAG,CAAC,oBAAuB,EACnC,QAAQ,GAAG,CAAC,QAAW,EAAE,AACzB,OADgC,CACxB,GAAG,CAAC,YAAe,CAFU,CAER,KAFe,EAER,QACxC,IAAM,EAAa,QAAQ,GAAG,CAAC,YAAe,CAC1C,CAAA,EAAA,EAAA,IAAA,AAAI,EAAC,QAAQ,GAAG,CAAC,YAAe,CAAE,eAClC,CAAA,EAAA,EAAA,IAAA,AAAI,EAAC,EAAM,WAAY,eAC3B,MAAO,EAAA,CAAA,EAAA,EAAA,UAAU,AAAV,EAAW,IAAc,MAClC,CACA,EAF2C,EAEtC,WAAY,CACf,GAAI,QAAQ,GAAG,CAAC,mBAAsB,CAAE,MAAO,UAC/C,IAAM,EAAU,CAAA,EAAA,EAAA,IAAI,AAAJ,EAAK,EAAM,SAC3B,MAAO,EAAA,CAAA,EAAA,EAAA,UAAU,AAAV,EAAW,IAAW,MAC/B,CACA,EAFwC,MAItC,MAAO,SACX,CACF,EAqH+B,GAE7B,GAAc,WAAW,CAArB,EAIF,MAAO,WACL,EACA,WAAW,EACX,eAAe,EACf,QACA,aACA,iBACA,YAAa,IACf,EAGF,GAAc,SAAV,EAAkB,CAGpB,IAAI,GAAgB,EAIpB,OAHI,GACF,GAAgB,MADF,AACQ,EAAgB,EAAW,EAAA,EAE5C,WACL,EACA,WAAW,gBACX,QACA,aACA,iBACA,EACA,YAAa,EAAgB,KAAO,CACtC,CACF,QAKA,AAAI,GACoB,MAAM,EAAgB,CAD9B,CACyC,GAE9C,WACL,EACA,WAAW,EACX,eAAe,QACf,aACA,iBACA,EACA,YAAa,IACf,EAKG,WACL,EACA,WAAW,EACX,eAAe,EACf,mBACA,iBACA,EACA,YAAa,CACf,CACF,CCnRA,SAAS,EACP,CAAe,CACf,CAAc,EAEd,OAAO,IAAI,QAAQ,AAAC,IAClB,GAAI,CACF,IAAM,EAAO,EAAA,UAAU,CAAG,CAAE,QAAS,IAAM,aAAa,CAAK,EAAI,CAAE,QAAS,GAAKR,EACjFF,CAAAA,EAAAA,EAAAA,QAAAA,AAAQ,EAACG,EAAS,EAAM,EAAM,CAAC,EAAO,KACpC,GAAI,EAAO,YACT,EAAQ,CAAE,WAAW,EAAOG,QAAS,IAAK,GAI5C,IAAM,EAAQ,EAAO,KAAK,CAAC,wBAC3B,EAAQ,CAAE,WAAW,EAAMA,QAAS,GAAO,CAAC,EAAEM,EAAI,IAAK,EACzD,EACF,CAAE,KAAM,CACN,EAAQ,CAAE,WAAW,EAAO,QAAS,IAAK,EAC5C,CACF,EACF,CAEO,eAAe,IAEpB,GAAM,CAAC,EAAY,EAAW,EAAM,CAAG,MAAM,QAAQ,GAAG,CAAC,CACvD,EAAW,MAAO,CAAC,YAAY,EAC/B,EAAW,KAAM,CAAC,YAAY,EAC9B,CAAC,UACC,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAO,AAAP,EAA0B,oBAC1C,OAAO,MAAM,EAAQ,OAAO,EAC9B,CAAE,KAAM,CACN,MAAO,EAAE,AACX,EACF,CAAC,GACF,EAEK,EAAU,EAAM,IAAI,CAAC,AAAC,GAAe,QAAT,EAAE,EAAE,EAChC,EAAS,EAAM,IAAI,CAAC,AAAC,GAAe,OAAT,EAAE,EAAE,EAErC,MAAO,CACL,IAAK,CACH,GAAG,CAAU,CACb,eAAgB,GAAS,gBAAkB,KAC3C,WAAY,GAAS,SAAW,qBAClC,EACA,GAAI,CACF,GAAG,CAAS,CACZ,eAAgB,GAAQ,gBAAkB,KAC1C,WAAY,GAAQ,SAAW,wBACjC,CACF,CACF,CC/DO,eAAe,EACpB,CAAiB,EAEjB,IAAM,EAAc,CAAA,EAAA,EAAA,OAAA,AAAO,EAAqB,sBAC1C,EAAU,MAAM,EAAYd,QAAQ,CAAC,UAC3C,AAAK,EACE,CAAE,CADL,IACW,CADD,CACS,IAAI,CAAE,YAAa,EAAQ,WAAW,AAAC,EADzC,IAEvB,CCXO,eAAe,EACpB,CAAiB,EAEjB,GAAI,CAAC,GAAW,OACd,CADsB,KACf,CAAE,MAAO,gBAAiB,EAGnC,GAAI,CACF,IAAM,EAAwB,CAAA,EAAA,EAAA,OAAA,AAAO,EAAwB,yBAE7D,MAAO,CAAE,QADOF,MAAM,EAAsB,OAAO,CAAC,EACnC,CACnB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,MADO,CACA,YADiB,MAAQ,EAAM,OAAO,CAAG,2BACjC,CAC1B,CACF,CCfO,eAAe,EACpB,CAAiB,CACjB,CAAiB,CACjB,CAAuB,CACvB,CAAiB,EAEjB,GAAI,CAAC,GAAW,OACd,CADsB,KACf,CAAE,MAAO,gBAAiB,EAGnC,GAAI,CACF,IAAM,EAAuB,CAAA,EAAA,EAAA,OAAA,AAAO,EAAuB,wBACrD,EAA6E,CAAC,EAQpF,YAPgB,IAAZ,GAAuB,GAAQ,OAAO,CAAG,CAAA,OACvB,IAAlB,IAA6B,EAAQ,aAAa,CAAG,CAAA,OACzC,IAAZ,IAAuB,EAAQ,OAAO,CAAG,CAAA,EAKtC,CAAE,QAHP,OAAO,IAAI,CAAC,GAAS,MAAM,CAAG,EAC1B,MAAM,EAAqB,OAAOS,CAAC,EAAW,GAC9C,MAAM,EAAqB,OAAO,CAAC,EACxB,CACnB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,MADO,CACAO,YADiB,MAAQ,EAAM,OAAO,CAAG,0BACjC,CAC1BC,CACF,CC1BO,eAAe,EACpB,CAAiB,EAEjB,GAAI,CAAC,EAAU,IAAI,GACjB,CADqB,KACd,CAAE,SAAS,EAAO,MAAO,wBAAyB,EAG3D,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAAuB,wBAE9C,OADA,MAAM,EAAQ,OAAO,CAAC,GACf,CAAE,SAAS,CAAK,CACzB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,QAAS,GAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,0BACjB,CAC1C,CACF,CCfO,eAAe,EACpB,CAAiB,EAEjB,GAAI,CAAC,EAAU,IAAI,GACjB,CADqB,KACd,CAAE,SAAS,EAAO,MAAO,wBAAyB,EAG3D,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAOpB,EAAsB,uBAE7C,OADA,MAAM,EAAQ,OAAO,CAAC,GACf,CAAE,SAAS,CAAK,CACzB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAEK,SAAS,EAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,yBACjB,CAC1C,CACF,CCdO,eAAe,EACpB,CAAiB,EAEjB,GAAI,CAAC,EAAU,IAAIJ,GACjB,CADqB,KACd,CAAE,SAAS,EAAO,MAAO,wBAAyB,EAG3D,GAAI,CAEF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBAEvC,EAAY,CADF,MAAM,EAAQ,IAAI,EAAA,EACR,IAAI,CAC5B,AAAC,GACC,EAAE,SAAS,GAAK,GACH,cAAb,EAAE,MAAM,EACKK,WAAb,EAAE,MAAM,EACK,gBAAb,EAAE,MAAM,EACK,cAAb,EAAE,MAAM,EAGZ,GAAI,CAAC,EACH,MAAO,CAAE,EADK,OACI,EAAO,MAAOO,4CAA6C,EAG/EX,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAAsB,uBACvC,EAAS,MAAM,EAAQ,OAAO,CAAC,EAAUW,EAAE,EAEjD,GAAI,CAAC,EAAO,OAAO,CACjB,CADmB,KACZ,CAAE,SAASA,EAAOK,MAAO,EAAO,MAAM,AAAC,EAEhD,MAAO,CAAE,SAAS,CAAK,CACzB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,SAAS,EAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,sBACjB,CAC1C,CACF,CCnCO,eAAe,EACpB,CAAiB,EAEjB,GAAI,CAAC,GAAW,OACd,CADsB,KACf,CAAE,MAAO,gBAAiB,EAGnC,GAAI,CACF,IAAM,EAA0B,CAAA,EAAA,EAAA,OAAA,AAAO,EAA0B,2BAEjE,MAAO,CAAE,QADO,MAAM,EAAwB,OAAO,CAAC,EACrC,CACnBd,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,MADO,CACA,YADiB,MAAQ,EAAM,OAAO,CAAG,6BACjC,CAC1B,CACF,CCVO,eAAe,EACpB,CAAyB,EAEzB,GAAM,MAAE,CAAI,MAAE,CAAI,CAAE,CAAG,EAEvB,GAAI,CAAC,GAAM,OACT,CADiB,KACV,CAAE,MAAO,kBAAmB,EAGrC,GAAI,CACF,IAAM,EAAiB,CAAA,EAAA,EAAA,OAAA,AAAO,EAAuB,wBAErD,MAAO,CAAE,WADU,MAAM,EAAe,OAAO,CAAC,MAAE,OAAM,CAAK,EACzC,CACtB,CAAE,MAAO,EAAgB,CAEvB,MAAO,CAAE,MADO,CACA,YADiB,MAAQ,EAAME,OAAO,CAAG,0BACjC,CAC1B,CACF,CCvBO,eAAe,EACpB,CAAoB,EAEpB,GAAI,CAAC,GAAc,OACjB,CADyB,KAClB,CAAE,QAAS,GAAO,MAAO,gBAAiB,EAGnD,GAAI,CACF,IAAM,EAAU,CAAA,EAAA,EAAA,OAAA,AAAO,EAA0B,2BAEjD,OADA,MAAM,EAAQ,OAAO,CAAC,GACf,CAAE,QAAS,EAAK,CACzB,CAAE,MAAOL,EAAgB,CAEvB,MAAO,CAAE,SAAS,EAAO,MADT,CACgB,YADC,MAAQ,EAAM,OAAO,CAAG,6BACjB,CAC1C,CACF,iCVwJsB,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,uECjIA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,yECjCA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,4ECJA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,wECAA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,uECDA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,uECAA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,sECCA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,qECAA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,0ECKA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA,uECNA,IAAA,CAAA,EAAA,EAAA,uBAAA,EAAA,EAAA,6CAAA"}
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/app/actions/open-ide.ts","../../../../../../../src/presentation/web/app/actions/open-shell.ts","../../../../../../../src/presentation/web/app/actions/open-folder.ts","../../../../../../../src/presentation/web/app/actions/sync-repository.ts","../../../../../../../src/presentation/web/app/actions/agent-setup-flag.ts","../../../../../../../src/presentation/web/app/actions/check-agent-auth.ts","../../../../../../../src/presentation/web/app/actions/check-tool-status.ts","../../../../../../../src/presentation/web/app/actions/get-feature-metadata.ts","../../../../../../../src/presentation/web/app/actions/archive-feature.ts","../../../../../../../src/presentation/web/app/actions/delete-feature.ts","../../../../../../../src/presentation/web/app/actions/resume-feature.ts","../../../../../../../src/presentation/web/app/actions/start-feature.ts","../../../../../../../src/presentation/web/app/actions/stop-feature.ts","../../../../../../../src/presentation/web/app/actions/unarchive-feature.ts","../../../../../../../src/presentation/web/app/actions/add-repository.ts","../../../../../../../src/presentation/web/app/actions/delete-repository.ts"],"sourcesContent":["'use server';\n\nimport { isAbsolute } from 'node:path';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { LaunchIdeUseCase } from '@shipit-ai/core/application/use-cases/ide/launch-ide.use-case';\n\ninterface OpenIdeInput {\n repositoryPath: string;\n branch?: string;\n}\n\nexport async function openIde(\n input: OpenIdeInput\n): Promise<{ success: boolean; error?: string; editor?: string; path?: string }> {\n const { repositoryPath, branch } = input;\n\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n const editor = settings.environment.defaultEditor;\n\n const useCase = resolve<LaunchIdeUseCase>('LaunchIdeUseCase');\n const result = await useCase.execute({\n editorId: editor,\n repositoryPath,\n branch,\n checkAvailability: true,\n });\n\n if (!result.ok) {\n return { success: false, error: result.message };\n }\n\n return { success: true, editor: result.editorName, path: result.worktreePath };\n}\n","'use server';\n\nimport { realpathSync } from 'node:fs';\nimport { platform } from 'node:os';\nimport { isAbsolute } from 'node:path';\nimport { spawn } from 'node:child_process';\nimport { computeWorktreePath } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { IToolInstallerService } from '@shipit-ai/core/application/ports/output/services/tool-installer.service';\n\n/**\n * Resolve the target path through realpath() so that any symlink traversal\n * happens up-front and the resulting absolute path is the authoritative\n * value used for all subsequent spawn operations. Returns null if the path\n * does not exist or cannot be resolved.\n */\nfunction resolveTargetPath(repositoryPath: string, branch?: string): string | null {\n try {\n const base = branch ? computeWorktreePath(repositoryPath, branch) : repositoryPath;\n return realpathSync(base);\n } catch {\n return null;\n }\n}\n\n/**\n * POSIX shell-escape a path for safe inclusion in a shell:true command string.\n * Wraps in single quotes and escapes embedded single quotes using the\n * standard '\\'' pattern. All tool configurations that opt into shell:true\n * use POSIX-style commands (`cd {dir} && exec <tool>`) and run on Unix only.\n */\nfunction shellEscapePosixPath(p: string): string {\n return `'${p.replace(/'/g, `'\\\\''`)}'`;\n}\n\n// Fallback commands for the \"system\" terminal when no tool metadata entry exists.\n// Uses a record lookup instead of if/else to prevent the bundler from\n// tree-shaking platform branches at build time. Turbopack evaluates\n// os.platform() during the build and dead-code-eliminates unused branches,\n// baking in the CI platform (linux) and breaking macOS/Windows installs.\nconst SYSTEM_TERMINAL_COMMANDS: Record<string, { cmd: string; args: (path: string) => string[] }> =\n {\n darwin: { cmd: 'open', args: (p) => ['-a', 'Terminal', p] },\n linux: { cmd: 'x-terminal-emulator', args: (p) => [`--working-directory=${p}`] },\n win32: {\n cmd: 'cmd.exe',\n args: (p) => ['/c', 'start', 'powershell', '-NoExit', '-Command', `Set-Location \"${p}\"`],\n },\n };\n\ninterface OpenShellInput {\n repositoryPath: string;\n branch?: string;\n}\n\nexport async function openShell(\n input: OpenShellInput\n): Promise<{ success: boolean; error?: string; path?: string; shell?: string }> {\n const { repositoryPath, branch } = input;\n\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n try {\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n const shell = settings.environment.shellPreference;\n const terminalPref = settings.environment.terminalPreference ?? 'system';\n\n // Resolve the target path through realpath() up-front. From this point\n // on, `targetPath` is the authoritative, symlink-resolved absolute path\n // used for every spawn call — never the raw user-supplied value.\n const targetPath = resolveTargetPath(repositoryPath, branch);\n if (!targetPath) {\n return { success: false, error: 'Path does not exist' };\n }\n\n // Try to find the terminal in tool metadata via DI container.\n // Using DI (not a direct import from tool-metadata) ensures that\n // TOOL_METADATA is read from the correct tools/ directory path — it is loaded once\n // in the Node.js CLI bootstrap context where import.meta.url resolves correctly.\n // Direct imports of tool-metadata break in standalone production builds.\n if (terminalPref !== 'system') {\n try {\n const service = resolve<IToolInstallerService>('IToolInstallerService');\n const config = service.getTerminalOpenConfig(terminalPref);\n\n if (config?.openDirectory.includes('{dir}')) {\n if (config.shell) {\n // For shell:true tools (claude-code, codex-cli, etc.) the tool\n // config is a POSIX shell string like `cd {dir} && exec claude`.\n // Shell-escape the path to prevent command injection: a malicious\n // path like `/tmp; rm -rf /` becomes `'/tmp; rm -rf /'` which the\n // shell treats as a single literal argument to `cd`.\n const escapedPath = shellEscapePosixPath(targetPath);\n const command = config.openDirectory.replaceAll('{dir}', escapedPath);\n const child = spawn(command, [], {\n detached: true,\n stdio: 'ignore',\n shell: true,\n });\n child.on('error', () => undefined);\n child.unref();\n } else {\n // For non-shell tools (alacritty, kitty, etc.) the config is a\n // whitespace-separated command. Split first, then substitute {dir}\n // INTO AN ARGV ELEMENT (never back into a concatenated string).\n // CodeQL recognizes the argv-form of spawn as sanitized input.\n const tokens = config.openDirectory.split(/\\s+/).filter(Boolean);\n const command = tokens[0];\n const args = tokens.slice(1).map((t) => t.replaceAll('{dir}', targetPath));\n const child = spawn(command, args, {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined);\n child.unref();\n }\n\n return { success: true, path: targetPath, shell };\n }\n } catch {\n // DI container not available — fall through to system terminal\n }\n }\n\n // Fallback to system terminal\n const entry = SYSTEM_TERMINAL_COMMANDS[platform()];\n if (!entry) {\n return {\n success: false,\n error: `Unsupported platform: ${platform()}`,\n };\n }\n\n const child = spawn(entry.cmd, entry.args(targetPath), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined); // Prevent uncaught exception on spawn failure\n child.unref();\n\n return { success: true, path: targetPath, shell };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to open shell';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { realpathSync } from 'node:fs';\nimport { platform } from 'node:os';\nimport { isAbsolute, normalize } from 'node:path';\nimport { spawn } from 'node:child_process';\n\n// Use a record lookup instead of if/else to prevent the bundler from\n// tree-shaking platform branches at build time. Turbopack evaluates\n// os.platform() during the build and dead-code-eliminates unused branches,\n// baking in the CI platform (linux) and breaking macOS/Windows installs.\nconst FOLDER_COMMANDS: Record<string, { cmd: string; args: (path: string) => string[] }> = {\n darwin: { cmd: 'open', args: (p) => [p] },\n linux: { cmd: 'xdg-open', args: (p) => [p] },\n win32: { cmd: 'explorer', args: (p) => [p] },\n};\n\nexport async function openFolder(\n repositoryPath: string\n): Promise<{ success: boolean; error?: string; path?: string }> {\n if (!repositoryPath || !isAbsolute(repositoryPath)) {\n return { success: false, error: 'repositoryPath must be an absolute path' };\n }\n\n try {\n // Resolve through realpath() up-front. All subsequent uses of the path\n // reference this symlink-resolved absolute value, not the raw user input.\n // This eliminates path-injection via symlinks and is the sanitizer that\n // CodeQL's js/path-injection analysis recognizes.\n let resolvedPath: string;\n try {\n resolvedPath = realpathSync(repositoryPath);\n } catch {\n return { success: false, error: 'Directory not found' };\n }\n\n const entry = FOLDER_COMMANDS[platform()];\n if (!entry) {\n return {\n success: false,\n error: `Unsupported platform: ${platform()}`,\n };\n }\n\n // Normalize to platform-native separators — explorer.exe on Windows\n // does not understand forward-slash paths and falls back to Documents.\n const nativePath = normalize(resolvedPath);\n\n const child = spawn(entry.cmd, entry.args(nativePath), {\n detached: true,\n stdio: 'ignore',\n });\n child.on('error', () => undefined); // Prevent uncaught exception on spawn failure\n child.unref();\n\n return { success: true, path: resolvedPath };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to open folder';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { SyncRepositoryMainUseCase } from '@shipit-ai/core/application/use-cases/repositories/sync-repository-main.use-case';\n\nexport async function syncRepository(\n repositoryId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!repositoryId?.trim()) {\n return { success: false, error: 'Repository id is required' };\n }\n\n try {\n const useCase = resolve<SyncRepositoryMainUseCase>('SyncRepositoryMainUseCase');\n await useCase.execute(repositoryId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to sync repository';\n return { success: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\n\n/**\n * Check whether onboarding has been completed.\n */\nexport async function isAgentSetupComplete(): Promise<boolean> {\n try {\n const useCase = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await useCase.execute();\n return settings.onboardingComplete;\n } catch {\n return false;\n }\n}\n","'use server';\n\nimport { existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport { execFile } from 'node:child_process';\nimport { IS_WINDOWS } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { LoadSettingsUseCase } from '@shipit-ai/core/application/use-cases/settings/load-settings.use-case';\nimport type { ListToolsUseCase } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface AgentAuthStatus {\n agentType: string;\n /** Whether the CLI tool binary is installed */\n installed: boolean;\n /** Whether credentials / auth appear valid */\n authenticated: boolean;\n /** Human-readable label for the agent */\n label: string;\n /** CLI binary name (e.g. \"claude\", \"gemini\") */\n binaryName: string | null;\n /** Shell command to install the tool (e.g. \"npm install -g @anthropic-ai/claude-code\") */\n installCommand: string | null;\n /** Instructions to authenticate if not authenticated */\n authCommand: string | null;\n}\n\nconst AGENT_LABELS: Record<string, string> = {\n 'claude-code': 'Claude Code',\n 'codex-cli': 'Codex CLI',\n 'copilot-cli': 'GitHub Copilot CLI',\n cursor: 'Cursor CLI',\n 'gemini-cli': 'Gemini CLI',\n 'rovo-dev': 'Rovo Dev CLI',\n aider: 'Aider',\n continue: 'Continue',\n dev: 'Demo',\n};\n\nconst AGENT_TOOL_MAP: Record<string, string> = {\n 'claude-code': 'claude-code',\n 'codex-cli': 'codex-cli',\n 'copilot-cli': 'copilot-cli',\n cursor: 'cursor-cli',\n 'gemini-cli': 'gemini-cli',\n 'rovo-dev': 'rovo-dev',\n};\n\nconst AGENT_BINARY_MAP: Record<string, string> = {\n 'claude-code': 'claude',\n 'codex-cli': 'codex',\n 'copilot-cli': 'copilot',\n cursor: 'cursor-agent',\n 'gemini-cli': 'gemini',\n 'rovo-dev': 'acli',\n};\n\n/**\n * Tier 1 result indicating how auth was detected.\n * - 'env-var': Explicit env var config (e.g. ANTHROPIC_API_KEY for proxy/gateway) — skip Tier 2\n * - 'file': Credential file found — run Tier 2 to verify tokens aren't expired\n * - false: No credentials found in known locations\n */\ntype Tier1Result = 'env-var' | 'file' | false;\n\n/**\n * Tier 1: Instant credential/env check (~5ms, no subprocess).\n * Distinguishes env-var auth (explicit user config, e.g. API key for a proxy)\n * from file-based auth (may be stale, needs Tier 2 verification).\n */\nfunction tier1AuthCheck(agentType: string): Tier1Result {\n const home = homedir();\n\n switch (agentType) {\n case 'claude-code': {\n if (process.env['ANTHROPIC_API_KEY']) return 'env-var';\n if (process.env['CLAUDE_CODE_USE_BEDROCK']) return 'env-var';\n if (process.env['CLAUDE_CODE_USE_VERTEX']) return 'env-var';\n if (process.env['CLAUDE_CODE_OAUTH_TOKEN']) return 'env-var';\n const credPath = join(home, '.claude', '.credentials.json');\n return existsSync(credPath) ? 'file' : false;\n }\n case 'codex-cli': {\n if (process.env['OPENAI_API_KEY']) return 'env-var';\n return false;\n }\n case 'cursor': {\n if (process.env['CURSOR_API_KEY']) return 'env-var';\n const cursorDir = join(home, '.cursor');\n return existsSync(cursorDir) ? 'file' : false;\n }\n case 'gemini-cli': {\n if (process.env['GEMINI_API_KEY']) return 'env-var';\n if (process.env['GOOGLE_API_KEY']) return 'env-var';\n if (process.env['GOOGLE_APPLICATION_CREDENTIALS']) return 'env-var';\n const accountsPath = join(home, '.gemini', 'google_accounts.json');\n return existsSync(accountsPath) ? 'file' : false;\n }\n case 'copilot-cli': {\n if (process.env['COPILOT_GITHUB_TOKEN']) return 'env-var';\n if (process.env['GH_TOKEN']) return 'env-var';\n if (process.env['GITHUB_TOKEN']) return 'env-var';\n const configPath = process.env['COPILOT_HOME']\n ? join(process.env['COPILOT_HOME'], 'config.json')\n : join(home, '.copilot', 'config.json');\n return existsSync(configPath) ? 'file' : false;\n }\n case 'rovo-dev': {\n if (process.env['ATLASSIAN_API_TOKEN']) return 'env-var';\n const acliDir = join(home, '.acli');\n return existsSync(acliDir) ? 'file' : false;\n }\n default:\n // dev, aider, continue — assume no auth needed\n return 'env-var';\n }\n}\n\n/**\n * Tier 2: Subprocess verification (~200ms).\n * Only called if tier 1 passes, to confirm tokens aren't expired.\n */\nfunction tier2AuthVerify(agentType: string, binaryName: string): Promise<boolean> {\n return new Promise((resolve) => {\n let cmd: string;\n let args: string[];\n\n switch (agentType) {\n case 'claude-code':\n cmd = binaryName;\n args = ['auth', 'status'];\n break;\n case 'cursor':\n cmd = binaryName;\n args = ['status'];\n break;\n case 'codex-cli':\n // Codex CLI has no `auth status` command — cannot verify via subprocess\n resolve(false);\n return;\n case 'copilot-cli':\n // No auth status command — trust tier 1\n resolve(true);\n return;\n case 'rovo-dev': {\n const rovoOpts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile('acli', ['rovodev', 'auth', 'status'], rovoOpts, (error) => {\n resolve(!error);\n });\n return;\n }\n default:\n // No tier 2 command available — trust tier 1\n resolve(true);\n return;\n }\n\n try {\n const opts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile(cmd, args, opts, (error) => {\n resolve(!error);\n });\n } catch {\n resolve(false);\n }\n });\n}\n\n/**\n * Check agent tool installation + auth status.\n * Uses two-tier detection: instant file/env check, then optional subprocess verify.\n */\nexport async function checkAgentAuth(): Promise<AgentAuthStatus> {\n let agentType: string;\n try {\n const loadSettings = resolve<LoadSettingsUseCase>('LoadSettingsUseCase');\n const settings = await loadSettings.execute();\n agentType = settings.agent.type;\n } catch {\n return {\n agentType: 'unknown',\n installed: false,\n authenticated: false,\n label: 'Unknown',\n binaryName: null,\n installCommand: null,\n authCommand: null,\n };\n }\n\n const label = AGENT_LABELS[agentType] ?? agentType;\n const toolId = AGENT_TOOL_MAP[agentType] ?? null;\n const binaryName = AGENT_BINARY_MAP[agentType] ?? null;\n\n // Dev/demo agents — always good\n if (!toolId) {\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName: null,\n installCommand: null,\n authCommand: null,\n };\n }\n\n // Check if tool is installed (also grab install command from metadata)\n let installed = false;\n let installCommand: string | null = null;\n try {\n const useCase = resolve<ListToolsUseCase>('ListToolsUseCase');\n const tools = await useCase.execute();\n const tool = tools.find((t) => t.id === toolId);\n installed = tool?.status.status === 'available';\n installCommand = tool?.installCommand ?? null;\n } catch {\n installed = false;\n }\n\n if (!installed) {\n return {\n agentType,\n installed: false,\n authenticated: false,\n label,\n binaryName,\n installCommand,\n authCommand: binaryName ? `Install ${label} first` : null,\n };\n }\n\n // Tier 1: instant file/env check — fast path for known credential locations\n const tier1 = tier1AuthCheck(agentType);\n\n if (tier1 === 'env-var') {\n // Explicit env var auth (e.g. ANTHROPIC_API_KEY for LiteLLM proxy).\n // Trust the user's config — skip Tier 2 subprocess check which may\n // fail against a proxy that the CLI binary doesn't know about.\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName,\n installCommand,\n authCommand: null,\n };\n }\n\n if (tier1 === 'file') {\n // Credential file found but may be stale/expired.\n // Run Tier 2 subprocess verify to confirm tokens are still valid (~200ms).\n let authenticated = true;\n if (binaryName) {\n authenticated = await tier2AuthVerify(agentType, binaryName);\n }\n return {\n agentType,\n installed: true,\n authenticated,\n label,\n binaryName,\n installCommand,\n authCommand: authenticated ? null : binaryName,\n };\n }\n\n // Tier 1 found nothing — credentials not in expected locations.\n // Fall through to Tier 2 because some auth methods (e.g. Claude Code OAuth\n // via claude.ai) store credentials outside the paths Tier 1 checks.\n if (binaryName) {\n const authenticated = await tier2AuthVerify(agentType, binaryName);\n if (authenticated) {\n return {\n agentType,\n installed: true,\n authenticated: true,\n label,\n binaryName,\n installCommand,\n authCommand: null,\n };\n }\n }\n\n // Both tiers failed — agent genuinely needs authentication\n return {\n agentType,\n installed: true,\n authenticated: false,\n label,\n binaryName,\n installCommand,\n authCommand: binaryName,\n };\n}\n","'use server';\n\nimport { execFile } from 'node:child_process';\nimport { IS_WINDOWS } from '@/lib/core-utils';\nimport { resolve } from '@/lib/server-container';\nimport type { ListToolsUseCase } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolStatusEntry {\n installed: boolean;\n version: string | null;\n /** Platform-specific install command from tool JSON metadata */\n installCommand: string | null;\n /** Documentation/website URL */\n installUrl: string | null;\n}\n\nexport interface ToolStatusResult {\n git: ToolStatusEntry;\n gh: ToolStatusEntry;\n}\n\nfunction getVersion(\n command: string,\n args: string[]\n): Promise<{ installed: boolean; version: string | null }> {\n return new Promise((resolve) => {\n try {\n const opts = IS_WINDOWS ? { timeout: 5000, windowsHide: true } : { timeout: 5000 };\n execFile(command, args, opts, (error, stdout) => {\n if (error) {\n resolve({ installed: false, version: null });\n return;\n }\n // Extract version number from output like \"git version 2.43.0\" or \"gh version 2.40.1\"\n const match = stdout.match(/(\\d+\\.\\d+(?:\\.\\d+)?)/);\n resolve({ installed: true, version: match?.[1] ?? null });\n });\n } catch {\n resolve({ installed: false, version: null });\n }\n });\n}\n\nexport async function checkToolStatus(): Promise<ToolStatusResult> {\n // Run version checks and tool metadata lookup in parallel\n const [gitVersion, ghVersion, tools] = await Promise.all([\n getVersion('git', ['--version']),\n getVersion('gh', ['--version']),\n (async () => {\n try {\n const useCase = resolve<ListToolsUseCase>('ListToolsUseCase');\n return await useCase.execute();\n } catch {\n return [];\n }\n })(),\n ]);\n\n const gitTool = tools.find((t) => t.id === 'git');\n const ghTool = tools.find((t) => t.id === 'gh');\n\n return {\n git: {\n ...gitVersion,\n installCommand: gitTool?.installCommand ?? null,\n installUrl: gitTool?.website ?? 'https://git-scm.com',\n },\n gh: {\n ...ghVersion,\n installCommand: ghTool?.installCommand ?? null,\n installUrl: ghTool?.website ?? 'https://cli.github.com',\n },\n };\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { IFeatureRepository } from '@shipit-ai/core/application/ports/output/repositories/feature-repository.interface';\n\n/**\n * Lightweight server action to fetch a single feature's name and description.\n * Used by the SSE effect to update node metadata after AI metadata generation\n * without a full graph reconcile (which can overwrite SSE-driven state).\n */\nexport async function getFeatureMetadata(\n featureId: string\n): Promise<{ name: string; description: string } | null> {\n const featureRepo = resolve<IFeatureRepository>('IFeatureRepository');\n const feature = await featureRepo.findById(featureId);\n if (!feature) return null;\n return { name: feature.name, description: feature.description };\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ArchiveFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/archive-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function archiveFeature(\n featureId: string\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const archiveFeatureUseCase = resolve<ArchiveFeatureUseCase>('ArchiveFeatureUseCase');\n const feature = await archiveFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to archive feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { DeleteFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/delete-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function deleteFeature(\n featureId: string,\n cleanup?: boolean,\n cascadeDelete?: boolean,\n closePr?: boolean\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const deleteFeatureUseCase = resolve<DeleteFeatureUseCase>('DeleteFeatureUseCase');\n const options: { cleanup?: boolean; cascadeDelete?: boolean; closePr?: boolean } = {};\n if (cleanup !== undefined) options.cleanup = cleanup;\n if (cascadeDelete !== undefined) options.cascadeDelete = cascadeDelete;\n if (closePr !== undefined) options.closePr = closePr;\n const feature =\n Object.keys(options).length > 0\n ? await deleteFeatureUseCase.execute(featureId, options)\n : await deleteFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to delete feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { ResumeFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/resume-feature.use-case';\n\nexport async function resumeFeature(\n featureId: string\n): Promise<{ resumed: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { resumed: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<ResumeFeatureUseCase>('ResumeFeatureUseCase');\n await useCase.execute(featureId);\n return { resumed: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to resume feature';\n return { resumed: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { StartFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/start-feature.use-case';\n\nexport async function startFeature(\n featureId: string\n): Promise<{ started: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { started: false, error: 'Feature id is required' };\n }\n\n try {\n const useCase = resolve<StartFeatureUseCase>('StartFeatureUseCase');\n await useCase.execute(featureId);\n return { started: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to start feature';\n return { started: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { StopAgentRunUseCase } from '@shipit-ai/core/application/use-cases/agents/stop-agent-run.use-case';\nimport type { IAgentRunRepository } from '@shipit-ai/core/application/ports/output/agents/agent-run-repository.interface';\n\nexport async function stopFeature(\n featureId: string\n): Promise<{ stopped: boolean; error?: string }> {\n if (!featureId.trim()) {\n return { stopped: false, error: 'Feature id is required' };\n }\n\n try {\n // Find the active agent run for this feature\n const runRepo = resolve<IAgentRunRepository>('IAgentRunRepository');\n const allRuns = await runRepo.list();\n const activeRun = allRuns.find(\n (r) =>\n r.featureId === featureId &&\n r.status !== 'completed' &&\n r.status !== 'failed' &&\n r.status !== 'interrupted' &&\n r.status !== 'cancelled'\n );\n\n if (!activeRun) {\n return { stopped: false, error: 'No active agent run found for this feature' };\n }\n\n const useCase = resolve<StopAgentRunUseCase>('StopAgentRunUseCase');\n const result = await useCase.execute(activeRun.id);\n\n if (!result.stopped) {\n return { stopped: false, error: result.reason };\n }\n return { stopped: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to stop agent';\n return { stopped: false, error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { UnarchiveFeatureUseCase } from '@shipit-ai/core/application/use-cases/features/unarchive-feature.use-case';\nimport type { Feature } from '@shipit-ai/core/domain/generated/output';\n\nexport async function unarchiveFeature(\n featureId: string\n): Promise<{ feature?: Feature; error?: string }> {\n if (!featureId?.trim()) {\n return { error: 'id is required' };\n }\n\n try {\n const unarchiveFeatureUseCase = resolve<UnarchiveFeatureUseCase>('UnarchiveFeatureUseCase');\n const feature = await unarchiveFeatureUseCase.execute(featureId);\n return { feature };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to unarchive feature';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { AddRepositoryUseCase } from '@shipit-ai/core/application/use-cases/repositories/add-repository.use-case';\nimport type { Repository } from '@shipit-ai/core/domain/generated/output';\n\ninterface AddRepositoryInput {\n path: string;\n name?: string;\n}\n\nexport async function addRepository(\n input: AddRepositoryInput\n): Promise<{ repository?: Repository; error?: string }> {\n const { path, name } = input;\n\n if (!path?.trim()) {\n return { error: 'path is required' };\n }\n\n try {\n const addRepoUseCase = resolve<AddRepositoryUseCase>('AddRepositoryUseCase');\n const repository = await addRepoUseCase.execute({ path, name });\n return { repository };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to add repository';\n return { error: message };\n }\n}\n","'use server';\n\nimport { resolve } from '@/lib/server-container';\nimport type { DeleteRepositoryUseCase } from '@shipit-ai/core/application/use-cases/repositories/delete-repository.use-case';\n\nexport async function deleteRepository(\n repositoryId: string\n): Promise<{ success: boolean; error?: string }> {\n if (!repositoryId?.trim()) {\n return { success: false, error: 'id is required' };\n }\n\n try {\n const useCase = resolve<DeleteRepositoryUseCase>('DeleteRepositoryUseCase');\n await useCase.execute(repositoryId);\n return { success: true };\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to delete repository';\n return { success: false, error: message };\n }\n}\n"],"names":["openIde","input","repositoryPath","branch","success","error","loadSettings","settings","execute","editor","environment","defaultEditor","useCase","result","editorId","checkAvailability","ok","message","editorName","path","worktreePath"],"mappings":"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"}