@shipit-ai/cli 1.167.0 → 1.168.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/antigravity.json +1 -1
  2. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/bash.json +1 -0
  3. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor-cli.json +1 -1
  4. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/cursor.json +1 -1
  5. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/fish.json +1 -0
  6. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/powershell.json +1 -0
  7. package/dist/packages/core/src/infrastructure/services/tool-installer/tools/zsh.json +1 -0
  8. package/dist/src/presentation/web/app/actions/get-merge-review-data.d.ts.map +1 -1
  9. package/dist/src/presentation/web/app/actions/get-merge-review-data.js +5 -1
  10. package/dist/src/presentation/web/app/actions/open-shell.d.ts.map +1 -1
  11. package/dist/src/presentation/web/app/actions/open-shell.js +5 -1
  12. package/dist/src/presentation/web/app/layout.d.ts.map +1 -1
  13. package/dist/src/presentation/web/app/layout.js +15 -2
  14. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.d.ts.map +1 -1
  15. package/dist/src/presentation/web/components/common/base-drawer/base-drawer.js +47 -10
  16. package/dist/src/presentation/web/components/common/page-header/page-header.d.ts +3 -1
  17. package/dist/src/presentation/web/components/common/page-header/page-header.d.ts.map +1 -1
  18. package/dist/src/presentation/web/components/common/page-header/page-header.js +8 -2
  19. package/dist/src/presentation/web/components/common/repository-node/repository-node.d.ts.map +1 -1
  20. package/dist/src/presentation/web/components/common/repository-node/repository-node.js +6 -1
  21. package/dist/src/presentation/web/components/common/shipit-ai-logo/shipit-ai-logo.d.ts +9 -1
  22. package/dist/src/presentation/web/components/common/shipit-ai-logo/shipit-ai-logo.d.ts.map +1 -1
  23. package/dist/src/presentation/web/components/common/shipit-ai-logo/shipit-ai-logo.js +12 -6
  24. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.d.ts.map +1 -1
  25. package/dist/src/presentation/web/components/common/sidebar-collapse-toggle/sidebar-collapse-toggle.js +5 -1
  26. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.d.ts.map +1 -1
  27. package/dist/src/presentation/web/components/common/sidebar-nav-item/sidebar-nav-item.js +15 -0
  28. package/dist/src/presentation/web/components/features/chat/ChatSheet.d.ts.map +1 -1
  29. package/dist/src/presentation/web/components/features/chat/ChatSheet.js +18 -5
  30. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.d.ts.map +1 -1
  31. package/dist/src/presentation/web/components/features/control-center/control-center-empty-state.js +1 -1
  32. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.d.ts.map +1 -1
  33. package/dist/src/presentation/web/components/features/features-canvas/features-canvas.js +5 -1
  34. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  35. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +43 -45
  36. package/dist/src/presentation/web/components/features/settings/settings-section-utils.d.ts +5 -2
  37. package/dist/src/presentation/web/components/features/settings/settings-section-utils.d.ts.map +1 -1
  38. package/dist/src/presentation/web/components/features/settings/settings-section-utils.js +8 -5
  39. package/dist/src/presentation/web/components/features/skills/category-filter.d.ts.map +1 -1
  40. package/dist/src/presentation/web/components/features/skills/category-filter.js +12 -2
  41. package/dist/src/presentation/web/components/features/skills/skill-card.d.ts.map +1 -1
  42. package/dist/src/presentation/web/components/features/skills/skill-card.js +3 -3
  43. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.d.ts.map +1 -1
  44. package/dist/src/presentation/web/components/features/skills/skill-detail-drawer.js +27 -1
  45. package/dist/src/presentation/web/components/features/skills/skill-list.js +2 -2
  46. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts.map +1 -1
  47. package/dist/src/presentation/web/components/features/skills/skills-page-client.js +2 -2
  48. package/dist/src/presentation/web/components/features/tools/tool-card.d.ts.map +1 -1
  49. package/dist/src/presentation/web/components/features/tools/tool-card.js +20 -11
  50. package/dist/src/presentation/web/components/features/tools/tool-detail-drawer.js +1 -1
  51. package/dist/src/presentation/web/components/features/tools/tools-page-client.d.ts.map +1 -1
  52. package/dist/src/presentation/web/components/features/tools/tools-page-client.js +6 -1
  53. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  54. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +39 -43
  55. package/dist/src/presentation/web/components/ui/card.d.ts.map +1 -1
  56. package/dist/src/presentation/web/components/ui/card.js +9 -1
  57. package/dist/src/presentation/web/components/ui/drawer.d.ts.map +1 -1
  58. package/dist/src/presentation/web/components/ui/drawer.js +8 -2
  59. package/dist/src/presentation/web/lib/path-sanitizers.d.ts.map +1 -1
  60. package/dist/src/presentation/web/lib/path-sanitizers.js +5 -1
  61. package/dist/tsconfig.build.tsbuildinfo +1 -1
  62. package/package.json +1 -1
  63. package/web/.next/BUILD_ID +1 -1
  64. package/web/.next/build-manifest.json +3 -3
  65. package/web/.next/fallback-build-manifest.json +3 -3
  66. package/web/.next/prerender-manifest.json +3 -3
  67. package/web/.next/required-server-files.js +2 -2
  68. package/web/.next/required-server-files.json +2 -2
  69. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/next-font-manifest.json +6 -2
  70. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  71. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js +1 -1
  72. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  73. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  74. package/web/.next/server/app/(dashboard)/@drawer/chat/page/next-font-manifest.json +6 -2
  75. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  76. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js +1 -1
  77. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  78. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  79. package/web/.next/server/app/(dashboard)/@drawer/create/page/next-font-manifest.json +6 -2
  80. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +31 -31
  81. package/web/.next/server/app/(dashboard)/@drawer/create/page.js +1 -1
  82. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  83. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  84. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/next-font-manifest.json +6 -2
  85. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  86. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js +2 -2
  87. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  88. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  89. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/next-font-manifest.json +6 -2
  90. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  91. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js +2 -2
  92. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  93. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  94. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/next-font-manifest.json +6 -2
  95. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  96. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js +1 -1
  97. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  98. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  99. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/next-font-manifest.json +6 -2
  100. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  101. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js +1 -1
  102. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  103. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  104. package/web/.next/server/app/(dashboard)/chat/page/next-font-manifest.json +6 -2
  105. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  106. package/web/.next/server/app/(dashboard)/chat/page.js +1 -1
  107. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  108. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  109. package/web/.next/server/app/(dashboard)/create/page/next-font-manifest.json +6 -2
  110. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +31 -31
  111. package/web/.next/server/app/(dashboard)/create/page.js +1 -1
  112. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  113. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  114. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/next-font-manifest.json +6 -2
  115. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  116. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js +2 -2
  117. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  118. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  119. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/next-font-manifest.json +6 -2
  120. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  121. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js +2 -2
  122. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  123. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  124. package/web/.next/server/app/(dashboard)/page/next-font-manifest.json +6 -2
  125. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  126. package/web/.next/server/app/(dashboard)/page.js +1 -1
  127. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  128. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  129. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/next-font-manifest.json +6 -2
  130. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  131. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js +1 -1
  132. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  133. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  134. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/next-font-manifest.json +6 -2
  135. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  136. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js +1 -1
  137. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  138. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  139. package/web/.next/server/app/_global-error.html +1 -1
  140. package/web/.next/server/app/_global-error.rsc +1 -1
  141. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  142. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  143. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  144. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  145. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  146. package/web/.next/server/app/_not-found/page/next-font-manifest.json +6 -2
  147. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  148. package/web/.next/server/app/_not-found/page.js +1 -1
  149. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  150. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  151. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  152. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  153. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  154. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  155. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  156. package/web/.next/server/app/settings/page/next-font-manifest.json +6 -2
  157. package/web/.next/server/app/settings/page/server-reference-manifest.json +11 -11
  158. package/web/.next/server/app/settings/page.js +1 -1
  159. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  160. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  161. package/web/.next/server/app/skills/page/next-font-manifest.json +6 -2
  162. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  163. package/web/.next/server/app/skills/page.js +1 -1
  164. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  165. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  166. package/web/.next/server/app/tools/page/next-font-manifest.json +6 -2
  167. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  168. package/web/.next/server/app/tools/page.js +1 -1
  169. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  170. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  171. package/web/.next/server/app/version/page/next-font-manifest.json +6 -2
  172. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  173. package/web/.next/server/app/version/page.js +1 -1
  174. package/web/.next/server/app/version/page.js.nft.json +1 -1
  175. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  176. package/web/.next/server/chunks/[root-of-the-server]__0_-chcy._.js.map +1 -1
  177. package/web/.next/server/chunks/[root-of-the-server]__0e9p7em._.js.map +1 -1
  178. package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
  179. package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0c0dui7._.js +3 -0
  180. package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0c0dui7._.js.map +1 -0
  181. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
  182. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
  183. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
  184. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
  185. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
  186. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
  187. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
  188. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
  189. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js +1 -1
  190. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js.map +1 -1
  191. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0uy_5rw._.js → [root-of-the-server]__0ge~xny._.js} +2 -2
  192. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0uy_5rw._.js.map → [root-of-the-server]__0ge~xny._.js.map} +1 -1
  193. package/web/.next/server/chunks/ssr/[root-of-the-server]__0jy4nha._.js +3 -0
  194. package/web/.next/server/chunks/ssr/[root-of-the-server]__0jy4nha._.js.map +1 -0
  195. package/web/.next/server/chunks/ssr/{_0e5cv3q._.js → [root-of-the-server]__0n~o-g-._.js} +2 -2
  196. package/web/.next/server/chunks/ssr/[root-of-the-server]__0n~o-g-._.js.map +1 -0
  197. package/web/.next/server/chunks/ssr/{[root-of-the-server]__02.89uf._.js → [root-of-the-server]__0qda~yi._.js} +2 -2
  198. package/web/.next/server/chunks/ssr/{[root-of-the-server]__02.89uf._.js.map → [root-of-the-server]__0qda~yi._.js.map} +1 -1
  199. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0c0xoi_._.js → [root-of-the-server]__0qxd563._.js} +2 -2
  200. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0c0xoi_._.js.map → [root-of-the-server]__0qxd563._.js.map} +1 -1
  201. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
  202. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js +1 -1
  203. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js.map +1 -1
  204. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js +1 -1
  205. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0r5zhk.._.js → [root-of-the-server]__0t~u8sd._.js} +2 -2
  206. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0r5zhk.._.js.map → [root-of-the-server]__0t~u8sd._.js.map} +1 -1
  207. package/web/.next/server/chunks/ssr/{[root-of-the-server]__04rq9lr._.js → [root-of-the-server]__10tll_l._.js} +2 -2
  208. package/web/.next/server/chunks/ssr/{[root-of-the-server]__04rq9lr._.js.map → [root-of-the-server]__10tll_l._.js.map} +1 -1
  209. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js +1 -1
  210. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js.map +1 -1
  211. package/web/.next/server/chunks/ssr/_0-09vq7._.js +1 -1
  212. package/web/.next/server/chunks/ssr/_0-09vq7._.js.map +1 -1
  213. package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
  214. package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
  215. package/web/.next/server/chunks/ssr/_069y.js._.js +2 -2
  216. package/web/.next/server/chunks/ssr/_069y.js._.js.map +1 -1
  217. package/web/.next/server/chunks/ssr/{_0mvhe_2._.js → _08_079y._.js} +2 -2
  218. package/web/.next/server/chunks/ssr/{_0mvhe_2._.js.map → _08_079y._.js.map} +1 -1
  219. package/web/.next/server/chunks/ssr/_09r54oy._.js +7 -0
  220. package/web/.next/server/chunks/ssr/_09r54oy._.js.map +1 -0
  221. package/web/.next/server/chunks/ssr/_0__4si~._.js +1 -1
  222. package/web/.next/server/chunks/ssr/_0__4si~._.js.map +1 -1
  223. package/web/.next/server/chunks/ssr/_0_m17kl._.js +1 -1
  224. package/web/.next/server/chunks/ssr/_0_m17kl._.js.map +1 -1
  225. package/web/.next/server/chunks/ssr/_0d4miu.._.js +1 -1
  226. package/web/.next/server/chunks/ssr/_0d4miu.._.js.map +1 -1
  227. package/web/.next/server/chunks/ssr/_0dy8.0k._.js +3 -0
  228. package/web/.next/server/chunks/ssr/_0dy8.0k._.js.map +1 -0
  229. package/web/.next/server/chunks/ssr/_0e8ern9._.js +1 -1
  230. package/web/.next/server/chunks/ssr/_0e8ern9._.js.map +1 -1
  231. package/web/.next/server/chunks/ssr/_0l2~~pi._.js +3 -0
  232. package/web/.next/server/chunks/ssr/_0l2~~pi._.js.map +1 -0
  233. package/web/.next/server/chunks/ssr/_0mi5qj~._.js +3 -0
  234. package/web/.next/server/chunks/ssr/_0mi5qj~._.js.map +1 -0
  235. package/web/.next/server/chunks/ssr/_0n.magx._.js +1 -1
  236. package/web/.next/server/chunks/ssr/_0n.magx._.js.map +1 -1
  237. package/web/.next/server/chunks/ssr/_0p3~u8u._.js +2 -2
  238. package/web/.next/server/chunks/ssr/_0p3~u8u._.js.map +1 -1
  239. package/web/.next/server/chunks/ssr/_0r.3n~3._.js +1 -1
  240. package/web/.next/server/chunks/ssr/_0r.3n~3._.js.map +1 -1
  241. package/web/.next/server/chunks/ssr/{_0l10ccg._.js → _0r04xhw._.js} +2 -2
  242. package/web/.next/server/chunks/ssr/{_0l10ccg._.js.map → _0r04xhw._.js.map} +1 -1
  243. package/web/.next/server/chunks/ssr/_0t59q8r._.js +1 -1
  244. package/web/.next/server/chunks/ssr/_0t59q8r._.js.map +1 -1
  245. package/web/.next/server/chunks/ssr/{_00k65h-._.js → _0txr945._.js} +2 -2
  246. package/web/.next/server/chunks/ssr/_0txr945._.js.map +1 -0
  247. package/web/.next/server/chunks/ssr/_0vjw-e_._.js +7 -0
  248. package/web/.next/server/chunks/ssr/_0vjw-e_._.js.map +1 -0
  249. package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
  250. package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
  251. package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
  252. package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
  253. package/web/.next/server/chunks/ssr/_0zk-h5w._.js +1 -1
  254. package/web/.next/server/chunks/ssr/_0zk-h5w._.js.map +1 -1
  255. package/web/.next/server/chunks/ssr/{_0hwjfpu._.js → _0~0jkp_._.js} +2 -2
  256. package/web/.next/server/chunks/ssr/_0~0jkp_._.js.map +1 -0
  257. package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
  258. package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
  259. package/web/.next/server/chunks/ssr/_1161g9x._.js +1 -1
  260. package/web/.next/server/chunks/ssr/_1161g9x._.js.map +1 -1
  261. package/web/.next/server/chunks/ssr/src_presentation_web_0y11iiz._.js +1 -1
  262. package/web/.next/server/chunks/ssr/src_presentation_web_0y11iiz._.js.map +1 -1
  263. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js +1 -1
  264. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map +1 -1
  265. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js +1 -1
  266. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map +1 -1
  267. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +1 -1
  268. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js.map +1 -1
  269. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
  270. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js.map +1 -1
  271. package/web/.next/server/chunks/ssr/src_presentation_web_components_0sk2qdt._.js +1 -1
  272. package/web/.next/server/chunks/ssr/src_presentation_web_components_0sk2qdt._.js.map +1 -1
  273. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
  274. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
  275. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js +1 -1
  276. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js.map +1 -1
  277. package/web/.next/server/middleware-build-manifest.js +3 -3
  278. package/web/.next/server/next-font-manifest.js +1 -1
  279. package/web/.next/server/next-font-manifest.json +60 -2
  280. package/web/.next/server/pages/500.html +1 -1
  281. package/web/.next/server/server-reference-manifest.js +1 -1
  282. package/web/.next/server/server-reference-manifest.json +50 -50
  283. package/web/.next/static/chunks/{05enics63g._-.js → 0-ud~1jj7chzu.js} +4 -4
  284. package/web/.next/static/chunks/01znjuvi5t9~q.js +5 -0
  285. package/web/.next/static/chunks/033sl_l5o3uo8.css +1 -0
  286. package/web/.next/static/chunks/04r9m_5p953mf.js +1 -0
  287. package/web/.next/static/chunks/{11~m1ei9bh269.js → 06nsv-_ec9ehn.js} +1 -1
  288. package/web/.next/static/chunks/{0qqe9hx_txhso.js → 078lp287u~c~b.js} +1 -1
  289. package/web/.next/static/chunks/07i3-aamszsoh.js +1 -0
  290. package/web/.next/static/chunks/{0n3u~4ytndfyd.js → 0_v4t6gzx.332.js} +1 -1
  291. package/web/.next/static/chunks/{0hti2r43x0~b7.js → 0_xww9bsde~1x.js} +1 -1
  292. package/web/.next/static/chunks/{0.8ue6wwr7ni~.js → 0cv09-g0prv4o.js} +1 -1
  293. package/web/.next/static/chunks/0ee1d3_y40g9f.js +1 -0
  294. package/web/.next/static/chunks/0hg8qgtv~kuys.js +1 -0
  295. package/web/.next/static/chunks/{11bi612fz8agh.js → 0in4l8mne5y~_.js} +1 -1
  296. package/web/.next/static/chunks/0inayq2zzadja.js +1 -0
  297. package/web/.next/static/chunks/{0t3xjndx2s1_j.css → 0j.1nx3ly591i.css} +1 -0
  298. package/web/.next/static/chunks/0o4m0k3642219.js +1 -0
  299. package/web/.next/static/chunks/0pt-d18f7zxvv.js +1 -0
  300. package/web/.next/static/chunks/0udlnp30o1kjd.js +5 -0
  301. package/web/.next/static/chunks/{13w6ziae82sjy.js → 0ygtupas8pxdi.js} +1 -1
  302. package/web/.next/static/chunks/12pd180jp8zu..js +5 -0
  303. package/web/.next/static/chunks/{028x3z97mchhz.js → 133q8d69p6cl0.js} +1 -1
  304. package/web/.next/static/chunks/13fcwhkw7dle2.js +1 -0
  305. package/web/.next/static/chunks/13q1peb_t9vj8.js +1 -0
  306. package/web/.next/static/chunks/15mks7_3venc1.js +1 -0
  307. package/web/.next/static/chunks/{0_.x~txb5da7d.js → 17c31c1biwfyi.js} +1 -1
  308. package/web/.next/static/media/1bffadaabf893a1e-s.16ipb6fqu393i.woff2 +0 -0
  309. package/web/.next/static/media/2bbe8d2671613f1f-s.067x_6k0k23tk.woff2 +0 -0
  310. package/web/.next/static/media/2c55a0e60120577a-s.0bjc5tiuqdqro.woff2 +0 -0
  311. package/web/.next/static/media/5476f68d60460930-s.0wxq9webf.ew4.woff2 +0 -0
  312. package/web/.next/static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2 +0 -0
  313. package/web/.next/static/media/9c72aa0f40e4eef8-s.0m6w47a4e5dy9.woff2 +0 -0
  314. package/web/.next/static/media/ad66f9afd8947f86-s.11u06r12fd6v_.woff2 +0 -0
  315. package/web/package.json +2 -2
  316. package/web/public/favicon.svg +10 -0
  317. package/web/public/icons/tools/antigravity.svg +1 -0
  318. package/web/public/icons/tools/bash.svg +38 -0
  319. package/web/public/icons/tools/cursor-cli.svg +12 -0
  320. package/web/public/icons/tools/cursor.svg +1 -0
  321. package/web/public/icons/tools/fish.svg +153 -0
  322. package/web/public/icons/tools/powershell.svg +29 -0
  323. package/web/public/icons/tools/zsh.svg +1 -0
  324. package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0zwb4s4._.js +0 -3
  325. package/web/.next/server/chunks/ssr/08qz_lucide-react_dist_esm_icons_0zwb4s4._.js.map +0 -1
  326. package/web/.next/server/chunks/ssr/[root-of-the-server]__0lslgap._.js +0 -7
  327. package/web/.next/server/chunks/ssr/[root-of-the-server]__0lslgap._.js.map +0 -1
  328. package/web/.next/server/chunks/ssr/_00k65h-._.js.map +0 -1
  329. package/web/.next/server/chunks/ssr/_08i-c2n._.js +0 -3
  330. package/web/.next/server/chunks/ssr/_08i-c2n._.js.map +0 -1
  331. package/web/.next/server/chunks/ssr/_0e5cv3q._.js.map +0 -1
  332. package/web/.next/server/chunks/ssr/_0hwjfpu._.js.map +0 -1
  333. package/web/.next/server/chunks/ssr/_0mo6j.n._.js +0 -3
  334. package/web/.next/server/chunks/ssr/_0mo6j.n._.js.map +0 -1
  335. package/web/.next/server/chunks/ssr/_0phryzt._.js +0 -3
  336. package/web/.next/server/chunks/ssr/_0phryzt._.js.map +0 -1
  337. package/web/.next/server/chunks/ssr/_12un22l._.js +0 -7
  338. package/web/.next/server/chunks/ssr/_12un22l._.js.map +0 -1
  339. package/web/.next/static/chunks/0-lu0b1ewsb0_.js +0 -1
  340. package/web/.next/static/chunks/01~dudieyb7wl.js +0 -5
  341. package/web/.next/static/chunks/02kpdawdtqcxm.js +0 -1
  342. package/web/.next/static/chunks/044f5piy5pt5t.js +0 -1
  343. package/web/.next/static/chunks/04~sw.nhpwy6s.css +0 -1
  344. package/web/.next/static/chunks/0_9k2ybutuphq.js +0 -1
  345. package/web/.next/static/chunks/0jo5-_q.1n69j.js +0 -1
  346. package/web/.next/static/chunks/0m5~9kij3s~81.js +0 -1
  347. package/web/.next/static/chunks/0pyz97q7eg0jz.js +0 -1
  348. package/web/.next/static/chunks/0q~uf2s33.48w.js +0 -1
  349. package/web/.next/static/chunks/0vx7ldqj8436q.js +0 -5
  350. package/web/.next/static/chunks/15m2wfd5k_7fj.js +0 -1
  351. package/web/.next/static/chunks/16.83v.xq8bn9.js +0 -1
  352. package/web/.next/static/chunks/164dnpi666fv_.js +0 -5
  353. /package/web/.next/static/{ksBer6au8b_fS1_7dCF2D → LQMB6QAutWzPQnLUZG96y}/_buildManifest.js +0 -0
  354. /package/web/.next/static/{ksBer6au8b_fS1_7dCF2D → LQMB6QAutWzPQnLUZG96y}/_clientMiddlewareManifest.js +0 -0
  355. /package/web/.next/static/{ksBer6au8b_fS1_7dCF2D → LQMB6QAutWzPQnLUZG96y}/_ssgManifest.js +0 -0
@@ -1,17 +1,16 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { useState, useTransition, useRef, useEffect, useCallback } from 'react';
4
- import { Check, Bot, Terminal, GitBranch, Activity, Bell, Flag, Database, Globe, Settings2, Timer, MessageSquare, LayoutGrid, } from 'lucide-react';
4
+ import { Check, Bot, Terminal, GitBranch, Activity, Bell, Flag, Database, Timer, MessageSquare, LayoutGrid, } from 'lucide-react';
5
5
  import { toast } from 'sonner';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { cn } from '../../../lib/utils.js';
8
8
  import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../../ui/select.js';
9
9
  import { Badge } from '../../ui/badge.js';
10
10
  import { updateSettingsAction } from '../../../app/actions/update-settings.js';
11
- import { Language, TerminalType, } from '../../../../../../packages/core/src/domain/generated/output.js';
11
+ import { TerminalType, } from '../../../../../../packages/core/src/domain/generated/output.js';
12
12
  import { getEditorTypeIcon } from '../../common/editor-type-icons.js';
13
13
  import { AgentModelPicker } from '../../features/settings/AgentModelPicker/index.js';
14
- import { LanguageSettingsSection } from '../../features/settings/language-settings-section.js';
15
14
  import { CiSettingsSection } from '../../features/settings/ci-settings-section.js';
16
15
  import { StageTimeoutsSettingsSection } from '../../features/settings/stage-timeouts-settings-section.js';
17
16
  import { InteractiveAgentSettingsSection } from '../../features/settings/interactive-agent-settings-section.js';
@@ -30,7 +29,6 @@ const DEFAULT_SHELL_OPTIONS = [
30
29
  { id: 'fish', name: 'Fish', available: true },
31
30
  ];
32
31
  const SECTIONS = [
33
- { id: 'language', labelKey: 'settings.sections.language', icon: Globe },
34
32
  { id: 'agent', labelKey: 'settings.sections.agent', icon: Bot },
35
33
  { id: 'environment', labelKey: 'settings.sections.environment', icon: Terminal },
36
34
  { id: 'workflow', labelKey: 'settings.sections.workflow', icon: GitBranch },
@@ -191,13 +189,13 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
191
189
  void el.offsetHeight;
192
190
  el.style.animation = 'section-flash 1s ease-out';
193
191
  }, []);
194
- return (_jsxs("div", { "data-testid": "settings-page-client", className: "max-w-5xl", children: [_jsx("div", { className: "bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 grid grid-cols-1 gap-x-5 pt-6 pb-4 backdrop-blur lg:grid-cols-[1fr_280px]", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Settings2, { className: "text-muted-foreground h-4 w-4" }), _jsx("h1", { className: "text-sm font-bold tracking-tight", children: t('settings.title') }), _jsxs("span", { className: "relative h-4 w-16", children: [_jsx("span", { className: cn('text-muted-foreground absolute inset-0 flex items-center text-xs transition-opacity duration-300', showSaving ? 'opacity-100' : 'opacity-0'), children: t('settings.saving') }), _jsxs("span", { className: cn('absolute inset-0 flex items-center gap-1 text-xs text-green-600 transition-opacity duration-300', showSaved && !showSaving ? 'opacity-100' : 'opacity-0'), children: [_jsx(Check, { className: "h-3 w-3" }), t('settings.saved')] })] }), _jsx("nav", { className: "ml-auto flex items-center gap-0.5", children: SECTIONS.map((s) => {
195
- const SectionIcon = s.icon;
196
- const isActive = activeSection === s.id;
197
- return (_jsxs("button", { type: "button", onClick: () => scrollToSection(s.id), className: cn('flex cursor-pointer items-center gap-1 rounded-md px-1.5 py-1 text-[11px] transition-all', isActive
198
- ? 'bg-accent text-foreground font-medium'
199
- : 'text-muted-foreground/60 hover:text-foreground hover:bg-accent/50'), children: [_jsx(SectionIcon, { className: "h-3 w-3" }), _jsx("span", { className: "hidden sm:inline", children: t(s.labelKey) })] }, s.id));
200
- }) })] }) }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsx("div", { id: "section-language", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: _jsx(LanguageSettingsSection, { language: settings.user?.preferredLanguage ?? Language.English }) }), _jsxs("div", { id: "section-agent", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(SettingsSection, { icon: Bot, title: t('settings.agent.sectionTitle'), description: t('settings.agent.sectionDescription'), testId: "agent-settings-section", children: _jsx(SettingsRow, { label: t('settings.agent.agentAndModel'), description: t('settings.agent.agentAndModelDescription'), htmlFor: "agent-model-picker", children: _jsx(AgentModelPicker, { initialAgentType: agentType, initialModel: settings.models.default, mode: "settings", onAgentModelChange: (newAgent) => setAgentType(newAgent), className: "w-55" }) }) }), _jsx(SectionHint, { links: [
192
+ return (_jsxs("div", { "data-testid": "settings-page-client", className: "max-w-5xl px-8 pt-8", children: [_jsxs("div", { className: "bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 pb-4 backdrop-blur", children: [_jsxs("div", { className: "mb-4 space-y-1.5", children: [_jsx("span", { className: "text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase", children: "Developer Portal" }), _jsxs("div", { className: "flex items-baseline gap-3", children: [_jsx("h1", { className: "text-foreground text-3xl font-black tracking-tight", children: t('settings.title') }), _jsxs("span", { className: "relative h-4 w-16", children: [_jsx("span", { className: cn('text-muted-foreground absolute inset-0 flex items-center text-xs transition-opacity duration-300', showSaving ? 'opacity-100' : 'opacity-0'), children: t('settings.saving') }), _jsxs("span", { className: cn('absolute inset-0 flex items-center gap-1 text-xs text-green-600 transition-opacity duration-300', showSaved && !showSaving ? 'opacity-100' : 'opacity-0'), children: [_jsx(Check, { className: "h-3 w-3" }), t('settings.saved')] })] })] })] }), _jsx("nav", { className: "bg-card editorial-shadow flex flex-wrap items-center gap-0.5 rounded-lg p-1", children: SECTIONS.map((s) => {
193
+ const SectionIcon = s.icon;
194
+ const isActive = activeSection === s.id;
195
+ return (_jsxs("button", { type: "button", onClick: () => scrollToSection(s.id), className: cn('flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-bold transition-all', isActive
196
+ ? 'bg-muted text-primary shadow-sm ring-1 ring-slate-200/70 dark:ring-slate-700/50'
197
+ : 'text-muted-foreground hover:text-foreground hover:bg-accent/50'), children: [_jsx(SectionIcon, { className: "h-3 w-3" }), _jsx("span", { className: "hidden sm:inline", children: t(s.labelKey) })] }, s.id));
198
+ }) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs("div", { id: "section-agent", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(SettingsSection, { icon: Bot, title: t('settings.agent.sectionTitle'), description: t('settings.agent.sectionDescription'), testId: "agent-settings-section", children: _jsx(SettingsRow, { label: t('settings.agent.agentAndModel'), description: t('settings.agent.agentAndModelDescription'), tooltip: "Changing the agent switches which AI CLI tool runs your features. Each agent has different capabilities, speed, and cost tradeoffs.", htmlFor: "agent-model-picker", children: _jsx(AgentModelPicker, { initialAgentType: agentType, initialModel: settings.models.default, mode: "settings", onAgentModelChange: (newAgent) => setAgentType(newAgent), className: "w-55" }) }) }), _jsx(SectionHint, { links: [
201
199
  {
202
200
  label: t('settings.agent.links.agentSystem'),
203
201
  href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/agent-system.md',
@@ -210,7 +208,7 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
210
208
  label: t('settings.agent.links.configurationGuide'),
211
209
  href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',
212
210
  },
213
- ], children: t('settings.agent.hint') })] }), _jsxs("div", { id: "section-environment", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Terminal, title: t('settings.environment.sectionTitle'), description: t('settings.environment.sectionDescription'), testId: "environment-settings-section", children: [_jsx(SettingsRow, { label: t('settings.environment.defaultEditor'), description: t('settings.environment.defaultEditorDescription'), htmlFor: "default-editor", children: _jsxs(Select, { value: editor, onValueChange: (v) => {
211
+ ], children: t('settings.agent.hint') })] }), _jsxs("div", { id: "section-environment", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Terminal, title: t('settings.environment.sectionTitle'), description: t('settings.environment.sectionDescription'), testId: "environment-settings-section", children: [_jsx(SettingsRow, { label: t('settings.environment.defaultEditor'), description: t('settings.environment.defaultEditorDescription'), tooltip: "The editor that opens when you click 'Launch' on a tool card or when ShipIT needs to open a file for review.", htmlFor: "default-editor", children: _jsxs(Select, { value: editor, onValueChange: (v) => {
214
212
  setEditor(v);
215
213
  save({
216
214
  environment: {
@@ -224,7 +222,7 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
224
222
  return (_jsx(SelectItem, { value: opt.id, disabled: !opt.available, children: _jsxs("span", { className: "flex items-center gap-2 text-xs", children: [_jsx(Icon, { className: "h-4 w-4 shrink-0" }), opt.name, _jsx(Badge, { variant: "outline", className: cn('ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal', opt.available
225
223
  ? 'border-emerald-500/30 text-emerald-500'
226
224
  : 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id));
227
- }) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.shell'), description: t('settings.environment.shellDescription'), htmlFor: "shell-preference", children: _jsxs(Select, { value: shell, onValueChange: (v) => {
225
+ }) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.shell'), description: t('settings.environment.shellDescription'), tooltip: "Controls which shell runs generated scripts like install commands and git operations. Match this to your daily driver shell.", htmlFor: "shell-preference", children: _jsxs(Select, { value: shell, onValueChange: (v) => {
228
226
  setShell(v);
229
227
  save({
230
228
  environment: {
@@ -235,7 +233,7 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
235
233
  });
236
234
  }, children: [_jsx(SelectTrigger, { id: "shell-preference", "data-testid": "shell-select", className: "w-64 cursor-pointer text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: shellOptions.map((opt) => (_jsx(SelectItem, { value: opt.id, disabled: !opt.available, children: _jsxs("span", { className: "flex items-center gap-2 text-xs", children: [opt.name, _jsx(Badge, { variant: "outline", className: cn('ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal', opt.available
237
235
  ? 'border-emerald-500/30 text-emerald-500'
238
- : 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id))) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.terminal'), description: t('settings.environment.terminalDescription'), htmlFor: "terminal-preference", children: _jsxs(Select, { value: terminal, onValueChange: (v) => {
236
+ : 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id))) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.terminal'), description: t('settings.environment.terminalDescription'), tooltip: "The terminal emulator launched when opening shell sessions from the web UI. Only affects web-launched terminals, not CLI usage.", htmlFor: "terminal-preference", children: _jsxs(Select, { value: terminal, onValueChange: (v) => {
239
237
  setTerminal(v);
240
238
  save({
241
239
  environment: {
@@ -251,19 +249,19 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
251
249
  label: t('settings.environment.links.configurationGuide'),
252
250
  href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',
253
251
  },
254
- ], children: t('settings.environment.hint') })] }), _jsxs("div", { id: "section-workflow", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: GitBranch, title: t('settings.workflow.title'), description: t('settings.workflow.sectionDescription'), testId: "workflow-settings-section", children: [_jsx(SwitchRow, { label: t('settings.workflow.defaultFastMode'), description: t('settings.workflow.defaultFastModeDescription'), id: "default-fast-mode", testId: "switch-default-fast-mode", checked: defaultFastMode, onChange: (v) => {
252
+ ], children: t('settings.environment.hint') })] }), _jsxs("div", { id: "section-workflow", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: GitBranch, title: t('settings.workflow.title'), description: t('settings.workflow.sectionDescription'), testId: "workflow-settings-section", children: [_jsx(SwitchRow, { label: t('settings.workflow.defaultFastMode'), description: t('settings.workflow.defaultFastModeDescription'), tooltip: "When enabled, new features skip the PRD and Plan phases and go straight to implementation. Useful for quick fixes, risky for complex features.", id: "default-fast-mode", testId: "switch-default-fast-mode", checked: defaultFastMode, onChange: (v) => {
255
253
  setDefaultFastMode(v);
256
254
  save(buildWorkflowPayload({ defaultFastMode: v }));
257
- } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.approve') }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePrd'), description: t('settings.workflow.autoApprovePrdDescription'), id: "allow-prd", testId: "switch-allow-prd", checked: allowPrd, onChange: (v) => {
255
+ } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.approve') }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePrd'), description: t('settings.workflow.autoApprovePrdDescription'), tooltip: "Automatically approves the requirements document without pausing for your review. Saves time but you lose the chance to refine requirements before planning.", id: "allow-prd", testId: "switch-allow-prd", checked: allowPrd, onChange: (v) => {
258
256
  setAllowPrd(v);
259
257
  save(buildWorkflowPayload({ allowPrd: v }));
260
- } }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePlan'), description: t('settings.workflow.autoApprovePlanDescription'), id: "allow-plan", testId: "switch-allow-plan", checked: allowPlan, onChange: (v) => {
258
+ } }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePlan'), description: t('settings.workflow.autoApprovePlanDescription'), tooltip: "Automatically approves the implementation plan. The agent proceeds to coding without waiting for your plan review.", id: "allow-plan", testId: "switch-allow-plan", checked: allowPlan, onChange: (v) => {
261
259
  setAllowPlan(v);
262
260
  save(buildWorkflowPayload({ allowPlan: v }));
263
- } }), _jsx(SwitchRow, { label: t('settings.workflow.autoApproveMerge'), description: t('settings.workflow.autoApproveMergeDescription'), id: "allow-merge", testId: "switch-allow-merge", checked: allowMerge, onChange: (v) => {
261
+ } }), _jsx(SwitchRow, { label: t('settings.workflow.autoApproveMerge'), description: t('settings.workflow.autoApproveMergeDescription'), tooltip: "Automatically merges the PR after implementation without requiring your final review. Use with caution on production branches.", id: "allow-merge", testId: "switch-allow-merge", checked: allowMerge, onChange: (v) => {
264
262
  setAllowMerge(v);
265
263
  save(buildWorkflowPayload({ allowMerge: v }));
266
- } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.evidence') }), _jsx(SwitchRow, { label: t('settings.workflow.collectEvidence'), description: t('settings.workflow.collectEvidenceDescription'), id: "enable-evidence", testId: "switch-enable-evidence", checked: enableEvidence, onChange: (v) => {
264
+ } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.evidence') }), _jsx(SwitchRow, { label: t('settings.workflow.collectEvidence'), description: t('settings.workflow.collectEvidenceDescription'), tooltip: "Captures screenshots and test outputs during implementation as proof of work. Useful for audit trails and PR documentation.", id: "enable-evidence", testId: "switch-enable-evidence", checked: enableEvidence, onChange: (v) => {
267
265
  setEnableEvidence(v);
268
266
  if (!v) {
269
267
  setCommitEvidence(false);
@@ -272,13 +270,13 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
272
270
  else {
273
271
  save(buildWorkflowPayload({ enableEvidence: v }));
274
272
  }
275
- } }), _jsx(SwitchRow, { label: t('settings.workflow.addEvidenceToPr'), description: t('settings.workflow.addEvidenceToPrDescription'), id: "commit-evidence", testId: "switch-commit-evidence", checked: commitEvidence, disabled: !enableEvidence || !openPr, onChange: (v) => {
273
+ } }), _jsx(SwitchRow, { label: t('settings.workflow.addEvidenceToPr'), description: t('settings.workflow.addEvidenceToPrDescription'), tooltip: "Attaches collected evidence artifacts (screenshots, logs) directly to the pull request description.", id: "commit-evidence", testId: "switch-commit-evidence", checked: commitEvidence, disabled: !enableEvidence || !openPr, onChange: (v) => {
276
274
  setCommitEvidence(v);
277
275
  save(buildWorkflowPayload({ commitEvidence: v }));
278
- } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.git') }), _jsx(SwitchRow, { label: t('settings.workflow.pushOnComplete'), description: t('settings.workflow.pushOnCompleteDescription'), id: "push-on-complete", testId: "switch-push-on-complete", checked: pushOnComplete, onChange: (v) => {
276
+ } }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.git') }), _jsx(SwitchRow, { label: t('settings.workflow.pushOnComplete'), description: t('settings.workflow.pushOnCompleteDescription'), tooltip: "Automatically pushes the implementation branch to the remote repository when the agent finishes coding.", id: "push-on-complete", testId: "switch-push-on-complete", checked: pushOnComplete, onChange: (v) => {
279
277
  setPushOnComplete(v);
280
278
  save(buildWorkflowPayload({ pushOnComplete: v }));
281
- } }), _jsx(SwitchRow, { label: t('settings.workflow.openPrOnComplete'), description: t('settings.workflow.openPrOnCompleteDescription'), id: "open-pr", testId: "switch-open-pr", checked: openPr, onChange: (v) => {
279
+ } }), _jsx(SwitchRow, { label: t('settings.workflow.openPrOnComplete'), description: t('settings.workflow.openPrOnCompleteDescription'), tooltip: "Creates a pull request automatically after pushing. Combined with push-on-complete, this fully automates the delivery pipeline.", id: "open-pr", testId: "switch-open-pr", checked: openPr, onChange: (v) => {
282
280
  setOpenPr(v);
283
281
  if (!v) {
284
282
  setCommitEvidence(false);
@@ -287,13 +285,13 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
287
285
  else {
288
286
  save(buildWorkflowPayload({ openPr: v }));
289
287
  }
290
- } }), _jsx(SwitchRow, { label: t('settings.workflow.watchCiAfterPush'), description: t('settings.workflow.watchCiAfterPushDescription'), id: "ci-watch-enabled", testId: "switch-ci-watch-enabled", checked: ciWatchEnabled, onChange: (v) => {
288
+ } }), _jsx(SwitchRow, { label: t('settings.workflow.watchCiAfterPush'), description: t('settings.workflow.watchCiAfterPushDescription'), tooltip: "Monitors CI/CD pipeline status after pushing and can attempt fixes if tests fail. Disable if you prefer to handle CI failures manually.", id: "ci-watch-enabled", testId: "switch-ci-watch-enabled", checked: ciWatchEnabled, onChange: (v) => {
291
289
  setCiWatchEnabled(v);
292
290
  save(buildWorkflowPayload({ ciWatchEnabled: v }));
293
- } }), _jsx(SubsectionLabel, { children: "Archive" }), _jsx(SwitchRow, { label: "Auto-archive completed", description: "Automatically archive features after they reach the completed state", id: "auto-archive-enabled", testId: "switch-auto-archive-enabled", checked: autoArchiveEnabled, onChange: (v) => {
291
+ } }), _jsx(SubsectionLabel, { children: "Archive" }), _jsx(SwitchRow, { label: "Auto-archive completed", description: "Automatically archive features after they reach the completed state", tooltip: "Automatically archives features from the control center canvas after they reach the completed state, keeping the board clean.", id: "auto-archive-enabled", testId: "switch-auto-archive-enabled", checked: autoArchiveEnabled, onChange: (v) => {
294
292
  setAutoArchiveEnabled(v);
295
293
  save(buildWorkflowPayload({ autoArchiveEnabled: v }));
296
- } }), _jsx(SettingsRow, { label: "Archive delay", description: "Minutes to wait after completion before archiving (1\u20131440)", htmlFor: "auto-archive-delay", children: _jsx(NumberStepper, { id: "auto-archive-delay", testId: "input-auto-archive-delay", value: autoArchiveDelay, placeholder: "10", min: 1, max: 1440, suffix: "min", onChange: (v) => {
294
+ } }), _jsx(SettingsRow, { label: "Archive delay", description: "Minutes to wait after completion before archiving (1\u20131440)", tooltip: "How long to wait after a feature completes before archiving it. Gives you time to review results before the feature moves off the board.", htmlFor: "auto-archive-delay", children: _jsx(NumberStepper, { id: "auto-archive-delay", testId: "input-auto-archive-delay", value: autoArchiveDelay, placeholder: "10", min: 1, max: 1440, suffix: "min", onChange: (v) => {
297
295
  setAutoArchiveDelay(v);
298
296
  }, onBlur: () => {
299
297
  if (!autoArchiveEnabled)
@@ -320,50 +318,50 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
320
318
  label: t('settings.ci.links.ciSecurityGates'),
321
319
  href: 'https://github.com/jrmatherly/shipit/blob/main/specs/003-cicd-security-gates/spec.md',
322
320
  },
323
- ], children: t('settings.ci.hint') })] }), _jsxs("div", { id: "section-stage-timeouts", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(StageTimeoutsSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.stageTimeouts.hint') })] }), _jsxs("div", { id: "section-notifications", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Bell, title: t('settings.notifications.title'), description: t('settings.notifications.sectionDescription'), testId: "notification-settings-section", children: [_jsx(SubsectionLabel, { children: t('settings.notifications.channels') }), _jsx(SwitchRow, { label: t('settings.notifications.inAppLabel'), description: t('settings.notifications.inAppDescription'), id: "notif-in-app", testId: "switch-in-app", checked: inApp, onChange: (v) => {
321
+ ], children: t('settings.ci.hint') })] }), _jsxs("div", { id: "section-stage-timeouts", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(StageTimeoutsSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.stageTimeouts.hint') })] }), _jsxs("div", { id: "section-notifications", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Bell, title: t('settings.notifications.title'), description: t('settings.notifications.sectionDescription'), testId: "notification-settings-section", children: [_jsx(SubsectionLabel, { children: t('settings.notifications.channels') }), _jsx(SwitchRow, { label: t('settings.notifications.inAppLabel'), description: t('settings.notifications.inAppDescription'), tooltip: "Master toggle for in-app toast notifications. When disabled, no event toasts will appear regardless of individual event settings below.", id: "notif-in-app", testId: "switch-in-app", checked: inApp, onChange: (v) => {
324
322
  setInApp(v);
325
323
  save(buildNotificationPayload({ inApp: v }));
326
- } }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.agentEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentStarted'), id: "notif-event-agentStarted", testId: "switch-event-agentStarted", checked: events.agentStarted, onChange: (v) => {
324
+ } }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.agentEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentStarted'), tooltip: "Controls whether you receive an in-app toast notification when an agent begins working on a feature.", id: "notif-event-agentStarted", testId: "switch-event-agentStarted", checked: events.agentStarted, onChange: (v) => {
327
325
  const newEvents = { ...events, agentStarted: v };
328
326
  setEvents(newEvents);
329
327
  save(buildNotificationPayload({ events: newEvents }));
330
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.phaseCompleted'), id: "notif-event-phaseCompleted", testId: "switch-event-phaseCompleted", checked: events.phaseCompleted, onChange: (v) => {
328
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.phaseCompleted'), tooltip: "Controls whether you receive an in-app toast notification when an agent completes a workflow phase (e.g., requirements, planning, implementation).", id: "notif-event-phaseCompleted", testId: "switch-event-phaseCompleted", checked: events.phaseCompleted, onChange: (v) => {
331
329
  const newEvents = { ...events, phaseCompleted: v };
332
330
  setEvents(newEvents);
333
331
  save(buildNotificationPayload({ events: newEvents }));
334
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.waitingApproval'), id: "notif-event-waitingApproval", testId: "switch-event-waitingApproval", checked: events.waitingApproval, onChange: (v) => {
332
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.waitingApproval'), tooltip: "Controls whether you receive an in-app toast notification when a feature is paused and waiting for your approval to continue.", id: "notif-event-waitingApproval", testId: "switch-event-waitingApproval", checked: events.waitingApproval, onChange: (v) => {
335
333
  const newEvents = { ...events, waitingApproval: v };
336
334
  setEvents(newEvents);
337
335
  save(buildNotificationPayload({ events: newEvents }));
338
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentCompleted'), id: "notif-event-agentCompleted", testId: "switch-event-agentCompleted", checked: events.agentCompleted, onChange: (v) => {
336
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentCompleted'), tooltip: "Controls whether you receive an in-app toast notification when an agent finishes all work on a feature successfully.", id: "notif-event-agentCompleted", testId: "switch-event-agentCompleted", checked: events.agentCompleted, onChange: (v) => {
339
337
  const newEvents = { ...events, agentCompleted: v };
340
338
  setEvents(newEvents);
341
339
  save(buildNotificationPayload({ events: newEvents }));
342
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentFailed'), id: "notif-event-agentFailed", testId: "switch-event-agentFailed", checked: events.agentFailed, onChange: (v) => {
340
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentFailed'), tooltip: "Controls whether you receive an in-app toast notification when an agent encounters an error and stops working on a feature.", id: "notif-event-agentFailed", testId: "switch-event-agentFailed", checked: events.agentFailed, onChange: (v) => {
343
341
  const newEvents = { ...events, agentFailed: v };
344
342
  setEvents(newEvents);
345
343
  save(buildNotificationPayload({ events: newEvents }));
346
- } }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.pullRequestEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.prMerged'), id: "notif-event-prMerged", testId: "switch-event-prMerged", checked: events.prMerged, onChange: (v) => {
344
+ } }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.pullRequestEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.prMerged'), tooltip: "Controls whether you receive an in-app toast notification when a feature's pull request is merged into the target branch.", id: "notif-event-prMerged", testId: "switch-event-prMerged", checked: events.prMerged, onChange: (v) => {
347
345
  const newEvents = { ...events, prMerged: v };
348
346
  setEvents(newEvents);
349
347
  save(buildNotificationPayload({ events: newEvents }));
350
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prClosed'), id: "notif-event-prClosed", testId: "switch-event-prClosed", checked: events.prClosed, onChange: (v) => {
348
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prClosed'), tooltip: "Controls whether you receive an in-app toast notification when a feature's pull request is closed without merging.", id: "notif-event-prClosed", testId: "switch-event-prClosed", checked: events.prClosed, onChange: (v) => {
351
349
  const newEvents = { ...events, prClosed: v };
352
350
  setEvents(newEvents);
353
351
  save(buildNotificationPayload({ events: newEvents }));
354
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksPassed'), id: "notif-event-prChecksPassed", testId: "switch-event-prChecksPassed", checked: events.prChecksPassed, onChange: (v) => {
352
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksPassed'), tooltip: "Controls whether you receive an in-app toast notification when all CI checks pass on a feature's pull request.", id: "notif-event-prChecksPassed", testId: "switch-event-prChecksPassed", checked: events.prChecksPassed, onChange: (v) => {
355
353
  const newEvents = { ...events, prChecksPassed: v };
356
354
  setEvents(newEvents);
357
355
  save(buildNotificationPayload({ events: newEvents }));
358
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksFailed'), id: "notif-event-prChecksFailed", testId: "switch-event-prChecksFailed", checked: events.prChecksFailed, onChange: (v) => {
356
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksFailed'), tooltip: "Controls whether you receive an in-app toast notification when CI checks fail on a feature's pull request.", id: "notif-event-prChecksFailed", testId: "switch-event-prChecksFailed", checked: events.prChecksFailed, onChange: (v) => {
359
357
  const newEvents = { ...events, prChecksFailed: v };
360
358
  setEvents(newEvents);
361
359
  save(buildNotificationPayload({ events: newEvents }));
362
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prBlocked'), id: "notif-event-prBlocked", testId: "switch-event-prBlocked", checked: events.prBlocked, onChange: (v) => {
360
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.prBlocked'), tooltip: "Controls whether you receive an in-app toast notification when a pull request is blocked by merge conflicts or branch protection rules.", id: "notif-event-prBlocked", testId: "switch-event-prBlocked", checked: events.prBlocked, onChange: (v) => {
363
361
  const newEvents = { ...events, prBlocked: v };
364
362
  setEvents(newEvents);
365
363
  save(buildNotificationPayload({ events: newEvents }));
366
- } }), _jsx(SwitchRow, { label: t('settings.notifications.events.mergeReviewReady'), id: "notif-event-mergeReviewReady", testId: "switch-event-mergeReviewReady", checked: events.mergeReviewReady, onChange: (v) => {
364
+ } }), _jsx(SwitchRow, { label: t('settings.notifications.events.mergeReviewReady'), tooltip: "Controls whether you receive an in-app toast notification when a feature's PR passes all checks and is ready for your merge review.", id: "notif-event-mergeReviewReady", testId: "switch-event-mergeReviewReady", checked: events.mergeReviewReady, onChange: (v) => {
367
365
  const newEvents = { ...events, mergeReviewReady: v };
368
366
  setEvents(newEvents);
369
367
  save(buildNotificationPayload({ events: newEvents }));
@@ -372,35 +370,35 @@ export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availab
372
370
  label: t('settings.notifications.links.notificationSystem'),
373
371
  href: 'https://github.com/jrmatherly/shipit/blob/main/specs/021-agent-notifications/spec.yaml',
374
372
  },
375
- ], children: t('settings.notifications.hint') })] }), _jsxs("div", { id: "section-feature-flags", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Flag, title: t('settings.featureFlags.title'), description: t('settings.featureFlags.sectionDescription'), badge: t('settings.featureFlags.badge'), testId: "feature-flags-settings-section", children: [_jsx(SwitchRow, { label: t('settings.featureFlags.skills'), description: t('settings.featureFlags.skillsDescription'), id: "flag-skills", testId: "switch-flag-skills", checked: flags.skills, onChange: (v) => {
373
+ ], children: t('settings.notifications.hint') })] }), _jsxs("div", { id: "section-feature-flags", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Flag, title: t('settings.featureFlags.title'), description: t('settings.featureFlags.sectionDescription'), badge: t('settings.featureFlags.badge'), testId: "feature-flags-settings-section", children: [_jsx(SwitchRow, { label: t('settings.featureFlags.skills'), description: t('settings.featureFlags.skillsDescription'), tooltip: "Enables the Skills page in the sidebar for browsing and managing Claude Code skills.", id: "flag-skills", testId: "switch-flag-skills", checked: flags.skills, onChange: (v) => {
376
374
  const newFlags = { ...flags, skills: v };
377
375
  setFlags(newFlags);
378
376
  save({ featureFlags: newFlags });
379
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.deployments'), description: t('settings.featureFlags.deploymentsDescription'), id: "flag-envDeploy", testId: "switch-flag-envDeploy", checked: flags.envDeploy, onChange: (v) => {
377
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.deployments'), description: t('settings.featureFlags.deploymentsDescription'), tooltip: "Enables experimental deployment features for environment management.", id: "flag-envDeploy", testId: "switch-flag-envDeploy", checked: flags.envDeploy, onChange: (v) => {
380
378
  const newFlags = { ...flags, envDeploy: v };
381
379
  setFlags(newFlags);
382
380
  save({ featureFlags: newFlags });
383
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.debug'), description: t('settings.featureFlags.debugDescription'), id: "flag-debug", testId: "switch-flag-debug", checked: flags.debug, onChange: (v) => {
381
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.debug'), description: t('settings.featureFlags.debugDescription'), tooltip: "Shows additional debugging information in the UI for troubleshooting.", id: "flag-debug", testId: "switch-flag-debug", checked: flags.debug, onChange: (v) => {
384
382
  const newFlags = { ...flags, debug: v };
385
383
  setFlags(newFlags);
386
384
  save({ featureFlags: newFlags });
387
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.githubImport'), description: t('settings.featureFlags.githubImportDescription'), id: "flag-githubImport", testId: "switch-flag-githubImport", checked: flags.githubImport, onChange: (v) => {
385
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.githubImport'), description: t('settings.featureFlags.githubImportDescription'), tooltip: "Enables importing repositories directly from GitHub.", id: "flag-githubImport", testId: "switch-flag-githubImport", checked: flags.githubImport, onChange: (v) => {
388
386
  const newFlags = { ...flags, githubImport: v };
389
387
  setFlags(newFlags);
390
388
  save({ featureFlags: newFlags });
391
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.adoptBranch'), description: t('settings.featureFlags.adoptBranchDescription'), id: "flag-adoptBranch", testId: "switch-flag-adoptBranch", checked: flags.adoptBranch, onChange: (v) => {
389
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.adoptBranch'), description: t('settings.featureFlags.adoptBranchDescription'), tooltip: "Enables adopting existing git branches as ShipIT features.", id: "flag-adoptBranch", testId: "switch-flag-adoptBranch", checked: flags.adoptBranch, onChange: (v) => {
392
390
  const newFlags = { ...flags, adoptBranch: v };
393
391
  setFlags(newFlags);
394
392
  save({ featureFlags: newFlags });
395
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.gitRebaseSync'), description: t('settings.featureFlags.gitRebaseSyncDescription'), id: "flag-gitRebaseSync", testId: "switch-flag-gitRebaseSync", checked: flags.gitRebaseSync, onChange: (v) => {
393
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.gitRebaseSync'), description: t('settings.featureFlags.gitRebaseSyncDescription'), tooltip: "Uses git rebase instead of merge when syncing feature branches with the upstream branch.", id: "flag-gitRebaseSync", testId: "switch-flag-gitRebaseSync", checked: flags.gitRebaseSync, onChange: (v) => {
396
394
  const newFlags = { ...flags, gitRebaseSync: v };
397
395
  setFlags(newFlags);
398
396
  save({ featureFlags: newFlags });
399
- } }), _jsx(SwitchRow, { label: t('settings.featureFlags.reactFileManager'), description: t('settings.featureFlags.reactFileManagerDescription'), id: "flag-reactFileManager", testId: "switch-flag-reactFileManager", checked: flags.reactFileManager, onChange: (v) => {
397
+ } }), _jsx(SwitchRow, { label: t('settings.featureFlags.reactFileManager'), description: t('settings.featureFlags.reactFileManagerDescription'), tooltip: "Replaces the native file picker dialog with a React-based file browser for selecting project folders.", id: "flag-reactFileManager", testId: "switch-flag-reactFileManager", checked: flags.reactFileManager, onChange: (v) => {
400
398
  const newFlags = { ...flags, reactFileManager: v };
401
399
  setFlags(newFlags);
402
400
  save({ featureFlags: newFlags });
403
- } })] }), _jsx(SectionHint, { children: t('settings.featureFlags.hint') })] }), _jsxs("div", { id: "section-interactive-agent", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(InteractiveAgentSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.interactiveAgent.hint') })] }), _jsxs("div", { id: "section-fab-layout", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(FabLayoutSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.fabLayout.hint') })] }), _jsxs("div", { id: "section-database", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Database, title: t('settings.database.title'), description: t('settings.database.sectionDescription'), testId: "database-settings-section", children: [_jsx(SettingsRow, { label: t('settings.database.location'), description: t('settings.database.locationDescription'), children: _jsx("span", { className: "text-muted-foreground max-w-50 truncate font-mono text-xs", "data-testid": "shipit-ai-home-path", children: shipitAiHome }) }), _jsx(SettingsRow, { label: t('settings.database.size'), children: _jsx("span", { className: "text-muted-foreground text-xs", "data-testid": "db-file-size", children: dbFileSize }) })] }), _jsx(SectionHint, { links: [
401
+ } })] }), _jsx(SectionHint, { children: t('settings.featureFlags.hint') })] }), _jsxs("div", { id: "section-interactive-agent", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(InteractiveAgentSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.interactiveAgent.hint') })] }), _jsxs("div", { id: "section-fab-layout", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(FabLayoutSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.fabLayout.hint') })] }), _jsxs("div", { id: "section-database", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Database, title: t('settings.database.title'), description: t('settings.database.sectionDescription'), testId: "database-settings-section", children: [_jsx(SettingsRow, { label: t('settings.database.location'), description: t('settings.database.locationDescription'), tooltip: "The directory where ShipIT stores its SQLite database, logs, and configuration files. Change this via the SHIPIT_AI_HOME environment variable.", children: _jsx("span", { className: "text-muted-foreground max-w-50 truncate font-mono text-xs", "data-testid": "shipit-ai-home-path", children: shipitAiHome }) }), _jsx(SettingsRow, { label: t('settings.database.size'), tooltip: "Current size of the SQLite database file on disk. Large databases may slow down startup; consider archiving old features if this grows significantly.", children: _jsx("span", { className: "text-muted-foreground text-xs", "data-testid": "db-file-size", children: dbFileSize }) })] }), _jsx(SectionHint, { links: [
404
402
  {
405
403
  label: t('settings.database.links.settingsService'),
406
404
  href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/settings-service.md',
@@ -1,10 +1,12 @@
1
- export declare function SettingsRow({ label, description, htmlFor, children, }: {
1
+ export declare function SettingsRow({ label, description, htmlFor, tooltip, children, }: {
2
2
  label: string;
3
3
  description?: string;
4
4
  htmlFor?: string;
5
+ /** Explicit tooltip text. Falls back to `description` if not provided. */
6
+ tooltip?: string;
5
7
  children: React.ReactNode;
6
8
  }): import("react/jsx-runtime").JSX.Element;
7
- export declare function SwitchRow({ label, description, id, testId, checked, onChange, disabled, }: {
9
+ export declare function SwitchRow({ label, description, id, testId, checked, onChange, disabled, tooltip, }: {
8
10
  label: string;
9
11
  description?: string;
10
12
  id: string;
@@ -12,6 +14,7 @@ export declare function SwitchRow({ label, description, id, testId, checked, onC
12
14
  checked: boolean;
13
15
  onChange: (value: boolean) => void;
14
16
  disabled?: boolean;
17
+ tooltip?: string;
15
18
  }): import("react/jsx-runtime").JSX.Element;
16
19
  export declare function SettingsSection({ icon: Icon, title, description, badge, testId, children, }: {
17
20
  icon: React.ComponentType<{
@@ -1 +1 @@
1
- {"version":3,"file":"settings-section-utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx"],"names":[],"mappings":"AAUA,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,OAAO,EACP,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAcA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,WAAW,EACX,EAAE,EACF,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,2CAaA;AAID,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAkBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EACX,GAAO,EACP,GAAG,EACH,IAAQ,EACR,MAAM,GACP,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CA4DA;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAQ1E;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C,2CAsBA"}
1
+ {"version":3,"file":"settings-section-utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx"],"names":[],"mappings":"AAWA,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CA6BA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,WAAW,EACX,EAAE,EACF,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,2CAaA;AAID,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CAkBA;AAED,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EACX,GAAO,EACP,GAAG,EACH,IAAQ,EACR,MAAM,GACP,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CA4DA;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAQ1E;AAED,wBAAgB,WAAW,CAAC,EAC1B,QAAQ,EACR,KAAK,GACN,EAAE;IACD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC3C,2CAsBA"}
@@ -1,16 +1,19 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Minus, Plus, ExternalLink } from 'lucide-react';
3
+ import { Minus, Plus, ExternalLink, Info } from 'lucide-react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { cn } from '../../../lib/utils.js';
6
6
  import { Label } from '../../ui/label.js';
7
7
  import { Switch } from '../../ui/switch.js';
8
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip.js';
8
9
  /* ── Reusable row components ── */
9
- export function SettingsRow({ label, description, htmlFor, children, }) {
10
- return (_jsxs("div", { className: "flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0", children: [_jsxs("div", { className: "min-w-0", children: [_jsx(Label, { htmlFor: htmlFor, className: "cursor-pointer text-sm font-normal whitespace-nowrap", children: label }), description ? (_jsx("p", { className: "text-muted-foreground text-[11px] leading-tight", children: description })) : null] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: children })] }));
10
+ export function SettingsRow({ label, description, htmlFor, tooltip, children, }) {
11
+ // Show the Info icon when there's either an explicit tooltip or a description to surface
12
+ const tooltipText = tooltip ?? description;
13
+ return (_jsxs("div", { className: "flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Label, { htmlFor: htmlFor, className: "cursor-pointer text-sm font-normal whitespace-nowrap", children: label }), tooltipText ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Info, { className: "text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors" }) }), _jsx(TooltipContent, { side: "top", className: "max-w-72 text-xs leading-relaxed", children: tooltipText })] })) : null] }), description ? (_jsx("p", { className: "text-muted-foreground text-[11px] leading-tight", children: description })) : null] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: children })] }));
11
14
  }
12
- export function SwitchRow({ label, description, id, testId, checked, onChange, disabled, }) {
13
- return (_jsx(SettingsRow, { label: label, description: description, htmlFor: id, children: _jsx(Switch, { id: id, "data-testid": testId, checked: checked, onCheckedChange: onChange, disabled: disabled, className: cn('cursor-pointer', disabled && 'cursor-not-allowed opacity-50') }) }));
15
+ export function SwitchRow({ label, description, id, testId, checked, onChange, disabled, tooltip, }) {
16
+ return (_jsx(SettingsRow, { label: label, description: description, htmlFor: id, tooltip: tooltip, children: _jsx(Switch, { id: id, "data-testid": testId, checked: checked, onCheckedChange: onChange, disabled: disabled, className: cn('cursor-pointer', disabled && 'cursor-not-allowed opacity-50') }) }));
14
17
  }
15
18
  /* ── Section card wrapper ── */
16
19
  export function SettingsSection({ icon: Icon, title, description, badge, testId, children, }) {
@@ -1 +1 @@
1
- {"version":3,"file":"category-filter.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/category-filter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAUlD,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;CACxC;AAED,wBAAgB,cAAc,CAAC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,mBAAmB,2CAkB/F"}
1
+ {"version":3,"file":"category-filter.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/category-filter.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAUlD,MAAM,WAAW,mBAAmB;IAClC,cAAc,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,gBAAgB,EAAE,CAAC,QAAQ,EAAE,aAAa,GAAG,IAAI,KAAK,IAAI,CAAC;IAC3D,MAAM,CAAC,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;CACxC;AAOD,wBAAgB,cAAc,CAAC,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,EAAE,EAAE,mBAAmB,2CA8B/F"}
@@ -1,5 +1,5 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
- import { Button } from '../../ui/button.js';
2
+ import { cn } from '../../../lib/utils.js';
3
3
  const CATEGORIES = [
4
4
  { label: 'All', value: null },
5
5
  { label: 'Workflow', value: 'Workflow' },
@@ -7,6 +7,16 @@ const CATEGORIES = [
7
7
  { label: 'Analysis', value: 'Analysis' },
8
8
  { label: 'Reference', value: 'Reference' },
9
9
  ];
10
+ /*
11
+ * Category filter — editorial tab treatment matching the Tools page.
12
+ * Uses bg-card container with editorial-shadow, active pill with bg-muted +
13
+ * text-primary + ring lift, inactive pills with muted text and hover affordance.
14
+ */
10
15
  export function CategoryFilter({ activeCategory, onCategoryChange, counts }) {
11
- return (_jsx("div", { className: "flex flex-wrap gap-2", role: "group", "aria-label": "Filter by category", children: CATEGORIES.map(({ label, value }) => (_jsxs(Button, { variant: activeCategory === value ? 'default' : 'outline', size: "sm", onClick: () => onCategoryChange(value), children: [label, counts && value ? (_jsxs("span", { className: "ms-1 text-xs opacity-70", children: ["(", counts[value], ")"] })) : null] }, label))) }));
16
+ return (_jsx("div", { className: "bg-card editorial-shadow inline-flex flex-wrap items-center gap-1 rounded-lg p-1", role: "group", "aria-label": "Filter by category", children: CATEGORIES.map(({ label, value }) => {
17
+ const isActive = activeCategory === value;
18
+ return (_jsxs("button", { type: "button", onClick: () => onCategoryChange(value), className: cn('cursor-pointer rounded-md px-3 py-1.5 text-xs font-bold transition-all', isActive
19
+ ? 'bg-muted text-primary shadow-sm ring-1 ring-slate-200/70 dark:ring-slate-700/50'
20
+ : 'text-muted-foreground hover:text-foreground'), children: [label, counts != null && value != null ? (_jsxs("span", { className: "ms-1 opacity-70", children: ["(", counts[value], ")"] })) : null] }, label));
21
+ }) }));
12
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skill-card.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,cAAc,2CAqC5D"}
1
+ {"version":3,"file":"skill-card.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-card.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;CACtC;AAED,wBAAgB,SAAS,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,cAAc,2CA0C5D"}
@@ -1,12 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Card, CardContent, CardHeader, CardTitle } from '../../ui/card.js';
2
+ import { Card } from '../../ui/card.js';
3
3
  import { Badge } from '../../ui/badge.js';
4
4
  import { FolderOpen } from 'lucide-react';
5
5
  export function SkillCard({ skill, onSelect }) {
6
- return (_jsxs(Card, { className: "hover:border-primary/50 cursor-pointer transition-colors", role: "button", tabIndex: 0, onClick: () => onSelect(skill), onKeyDown: (e) => {
6
+ return (_jsxs(Card, { className: "cursor-pointer p-5 transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md hover:ring-slate-300 dark:hover:ring-slate-600", role: "button", tabIndex: 0, onClick: () => onSelect(skill), onKeyDown: (e) => {
7
7
  if (e.key === 'Enter' || e.key === ' ') {
8
8
  e.preventDefault();
9
9
  onSelect(skill);
10
10
  }
11
- }, "data-testid": `skill-card-${skill.name}`, children: [_jsxs(CardHeader, { className: "pb-3", children: [_jsx(CardTitle, { className: "text-base", children: skill.displayName }), _jsx("p", { className: "text-muted-foreground font-mono text-xs", children: skill.name })] }), _jsxs(CardContent, { className: "space-y-3", children: [_jsx("p", { className: "text-muted-foreground line-clamp-2 text-sm", children: skill.description }), _jsxs("div", { className: "flex flex-wrap items-center gap-1.5", children: [_jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', children: skill.source === 'project' ? 'Project' : 'Global' }), skill.context ? _jsx(Badge, { variant: "outline", children: skill.context }) : null, skill.allowedTools ? _jsx(Badge, { variant: "outline", children: "Tools" }) : null, skill.resources.length > 0 ? (_jsxs("span", { className: "text-muted-foreground inline-flex items-center gap-1 text-xs", children: [_jsx(FolderOpen, { className: "size-3" }), skill.resources.length, " ", skill.resources.length === 1 ? 'resource' : 'resources'] })) : null] })] })] }));
11
+ }, "data-testid": `skill-card-${skill.name}`, children: [_jsx("h3", { className: "text-foreground text-sm leading-tight font-bold tracking-tight", children: skill.displayName }), _jsx("p", { className: "text-muted-foreground mt-1 font-mono text-xs", children: skill.name }), _jsx("p", { className: "text-muted-foreground mt-3 line-clamp-2 text-xs leading-relaxed", children: skill.description }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-1.5", children: [_jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', children: skill.source === 'project' ? 'Project' : 'Global' }), skill.context ? _jsx(Badge, { variant: "outline", children: skill.context }) : null, skill.allowedTools ? _jsx(Badge, { variant: "outline", children: "Tools" }) : null, skill.resources.length > 0 ? (_jsxs("span", { className: "text-muted-foreground inline-flex items-center gap-1 text-xs", children: [_jsx(FolderOpen, { className: "size-3" }), skill.resources.length, " ", skill.resources.length === 1 ? 'resource' : 'resources'] })) : null] })] }));
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skill-detail-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-detail-drawer.tsx"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,sBAAsB,2CA+E3E"}
1
+ {"version":3,"file":"skill-detail-drawer.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skill-detail-drawer.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AA0D9C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,sBAAsB,2CAiH3E"}
@@ -1,10 +1,36 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import Markdown from 'react-markdown';
4
+ import remarkGfm from 'remark-gfm';
3
5
  import { BaseDrawer } from '../../common/base-drawer/index.js';
4
6
  import { DrawerTitle, DrawerDescription } from '../../ui/drawer.js';
5
7
  import { Badge } from '../../ui/badge.js';
6
8
  import { Separator } from '../../ui/separator.js';
9
+ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip.js';
7
10
  import { FolderOpen } from 'lucide-react';
11
+ /*
12
+ * Markdown component overrides for skill body rendering.
13
+ * Styled to match the editorial palette and fit within the drawer's
14
+ * constrained width. Uses the same pattern as tech-decisions-review.
15
+ */
16
+ const mdComponents = {
17
+ h1: ({ children }) => (_jsx("h1", { className: "text-foreground mt-6 mb-3 text-lg font-bold tracking-tight first:mt-0", children: children })),
18
+ h2: ({ children }) => (_jsx("h2", { className: "text-foreground mt-5 mb-2 text-base font-bold tracking-tight", children: children })),
19
+ h3: ({ children }) => _jsx("h3", { className: "text-foreground mt-4 mb-2 text-sm font-bold", children: children }),
20
+ p: ({ children }) => (_jsx("p", { className: "text-muted-foreground mb-3 text-sm leading-relaxed last:mb-0", children: children })),
21
+ strong: ({ children }) => _jsx("strong", { className: "text-foreground font-semibold", children: children }),
22
+ em: ({ children }) => _jsx("em", { className: "italic", children: children }),
23
+ code: ({ children, className }) => className ? (_jsx("code", { className: `${className} text-xs`, children: children })) : (_jsx("code", { className: "bg-muted text-foreground rounded-md px-1.5 py-0.5 font-mono text-xs", children: children })),
24
+ pre: ({ children }) => (_jsx("pre", { className: "bg-muted my-3 overflow-x-auto rounded-lg border p-3 text-xs", children: children })),
25
+ ul: ({ children }) => (_jsx("ul", { className: "text-muted-foreground mb-3 list-disc space-y-1 ps-5 text-sm", children: children })),
26
+ ol: ({ children }) => (_jsx("ol", { className: "text-muted-foreground mb-3 list-decimal space-y-1 ps-5 text-sm", children: children })),
27
+ li: ({ children }) => _jsx("li", { className: "leading-relaxed", children: children }),
28
+ hr: () => _jsx(Separator, { className: "my-4" }),
29
+ a: ({ href, children }) => (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", className: "text-primary hover:text-primary/80 underline underline-offset-2", children: children })),
30
+ blockquote: ({ children }) => (_jsx("blockquote", { className: "border-primary/30 text-muted-foreground my-3 border-l-2 pl-4 italic", children: children })),
31
+ };
8
32
  export function SkillDetailDrawer({ skill, onClose }) {
9
- return (_jsx(BaseDrawer, { open: skill !== null, onClose: onClose, size: "sm", modal: true, "data-testid": "skill-detail-drawer", header: skill ? (_jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: skill.displayName }), _jsx(DrawerDescription, { children: skill.name })] })) : undefined, children: skill ? (_jsxs("div", { className: "px-4 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: skill.description }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-1.5", children: [_jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', children: skill.source === 'project' ? 'Project' : 'Global' }), _jsx(Badge, { variant: "outline", children: skill.category }), skill.context ? _jsx(Badge, { variant: "outline", children: skill.context }) : null] }), skill.allowedTools ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Allowed Tools" }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: skill.allowedTools })] })] })) : null, skill.resources.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Resources" }), _jsx("ul", { className: "mt-2 space-y-1.5", children: skill.resources.map((resource) => (_jsxs("li", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(FolderOpen, { className: "size-3.5 shrink-0" }), _jsxs("span", { children: [resource.name, "/ \u2014 ", resource.fileCount, ' ', resource.fileCount === 1 ? 'file' : 'files'] })] }, resource.name))) })] })] })) : null, skill.body ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsx("pre", { className: "text-muted-foreground text-sm leading-relaxed whitespace-pre-wrap", children: skill.body })] })) : null] })) : null }));
33
+ return (_jsx(BaseDrawer, { open: skill !== null, onClose: onClose, size: "sm", modal: true, "data-testid": "skill-detail-drawer", header: skill ? (_jsxs(_Fragment, { children: [_jsx(DrawerTitle, { children: skill.displayName }), _jsx(DrawerDescription, { children: skill.name })] })) : undefined, children: skill ? (_jsxs("div", { className: "min-h-0 flex-1 overflow-y-auto px-4 pb-4", children: [_jsx("p", { className: "text-muted-foreground text-sm", children: skill.description }), _jsxs("div", { className: "mt-4 flex flex-wrap items-center gap-1.5", children: [_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Badge, { variant: skill.source === 'project' ? 'secondary' : 'outline', className: "cursor-default", children: skill.source === 'project' ? 'Project' : 'Global' }) }), _jsx(TooltipContent, { side: "bottom", children: skill.source === 'project'
34
+ ? 'Installed in this project\u2019s .claude/skills/ directory'
35
+ : 'Installed globally in your user profile' })] }), _jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Badge, { variant: "outline", className: "cursor-default", children: skill.category }) }), _jsx(TooltipContent, { side: "bottom", children: "Skill category \\u2014 used for filtering on the Skills page" })] }), skill.context ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Badge, { variant: "outline", className: "cursor-default", children: skill.context }) }), _jsx(TooltipContent, { side: "bottom", children: "Context restriction \\u2014 this skill only activates in this context" })] })) : null] }), skill.allowedTools ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Allowed Tools" }), _jsx("p", { className: "text-muted-foreground mt-1 text-sm", children: skill.allowedTools })] })] })) : null, skill.resources.length > 0 ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-semibold", children: "Resources" }), _jsx("ul", { className: "mt-2 space-y-1.5", children: skill.resources.map((resource) => (_jsxs("li", { className: "text-muted-foreground flex items-center gap-2 text-sm", children: [_jsx(FolderOpen, { className: "size-3.5 shrink-0" }), _jsxs("span", { children: [resource.name, "/ \u2014 ", resource.fileCount, ' ', resource.fileCount === 1 ? 'file' : 'files'] })] }, resource.name))) })] })] })) : null, skill.body ? (_jsxs(_Fragment, { children: [_jsx(Separator, { className: "my-4" }), _jsx("div", { className: "prose-sm", children: _jsx(Markdown, { remarkPlugins: [remarkGfm], components: mdComponents, children: skill.body }) })] })) : null] })) : null }));
10
36
  }
@@ -12,10 +12,10 @@ function groupByCategory(skills) {
12
12
  }
13
13
  export function SkillList({ skills, onSkillSelect }) {
14
14
  const groups = groupByCategory(skills);
15
- return (_jsx("div", { className: "space-y-8", children: CATEGORY_ORDER.map((category) => {
15
+ return (_jsx("div", { className: "space-y-12", children: CATEGORY_ORDER.map((category) => {
16
16
  const categorySkills = groups.get(category);
17
17
  if (!categorySkills || categorySkills.length === 0)
18
18
  return null;
19
- return (_jsxs("section", { children: [_jsxs("h2", { className: "mb-4 text-lg font-semibold", children: [category, ' ', _jsxs("span", { className: "text-muted-foreground text-sm font-normal", children: ["(", categorySkills.length, ")"] })] }), _jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3", children: categorySkills.map((skill) => (_jsx(SkillCard, { skill: skill, onSelect: onSkillSelect }, skill.name))) })] }, category));
19
+ return (_jsxs("section", { children: [_jsxs("h2", { className: "text-foreground mb-6 text-xl font-bold tracking-tight", children: [category, ' ', _jsxs("span", { className: "text-muted-foreground text-sm font-normal", children: ["(", categorySkills.length, ")"] })] }), _jsx("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3", children: categorySkills.map((skill) => (_jsx(SkillCard, { skill: skill, onSelect: onSkillSelect }, skill.name))) })] }, category));
20
20
  }) }));
21
21
  }
@@ -1 +1 @@
1
- {"version":3,"file":"skills-page-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skills-page-client.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAeD,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CAiFjE"}
1
+ {"version":3,"file":"skills-page-client.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/skills/skills-page-client.tsx"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAiB,SAAS,EAAE,MAAM,cAAc,CAAC;AAE7D,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,SAAS,EAAE,CAAC;CACrB;AAeD,wBAAgB,gBAAgB,CAAC,EAAE,MAAM,EAAE,EAAE,qBAAqB,2CAyFjE"}
@@ -46,7 +46,7 @@ export function SkillsPageClient({ skills }) {
46
46
  };
47
47
  // No skills installed at all
48
48
  if (skills.length === 0) {
49
- return (_jsxs("div", { className: "flex flex-col gap-6 p-6", children: [_jsx(PageHeader, { title: "Skills", description: "Claude Code skills installed in this project" }), _jsx(EmptyState, { icon: _jsx(Puzzle, { className: "size-10" }), title: "No skills found", description: "No Claude Code skills are installed. Add skills to .claude/skills/ to get started." })] }));
49
+ return (_jsxs("div", { className: "flex flex-col gap-8 p-8", children: [_jsx(PageHeader, { eyebrow: "Developer Portal", title: "Skills", description: "Claude Code skills installed in this project" }), _jsx(EmptyState, { icon: _jsx(Puzzle, { className: "size-10" }), title: "No skills found", description: "No Claude Code skills are installed. Add skills to .claude/skills/ to get started." })] }));
50
50
  }
51
- return (_jsxs("div", { className: "flex flex-col gap-6 p-6", children: [_jsx(PageHeader, { title: "Skills", description: "Claude Code skills installed in this project" }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search skills...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "ps-9" })] }), _jsx(CategoryFilter, { activeCategory: activeCategory, onCategoryChange: setActiveCategory, counts: categoryCounts }), filteredSkills.length > 0 ? (_jsx(SkillList, { skills: filteredSkills, onSkillSelect: setSelectedSkill })) : (_jsx(EmptyState, { icon: _jsx(Search, { className: "size-10" }), title: "No matching skills", description: "No skills match your current search and filter criteria.", action: _jsx(Button, { variant: "outline", onClick: clearFilters, children: "Clear filters" }) })), _jsx(SkillDetailDrawer, { skill: selectedSkill, onClose: () => setSelectedSkill(null) })] }));
51
+ return (_jsxs("div", { className: "flex flex-col gap-8 p-8", children: [_jsx(PageHeader, { eyebrow: "Developer Portal", title: "Skills", description: "Claude Code skills installed in this project" }), _jsxs("div", { className: "relative", children: [_jsx(Search, { className: "text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2" }), _jsx(Input, { placeholder: "Search skills...", value: searchQuery, onChange: (e) => setSearchQuery(e.target.value), className: "ps-9" })] }), _jsx(CategoryFilter, { activeCategory: activeCategory, onCategoryChange: setActiveCategory, counts: categoryCounts }), filteredSkills.length > 0 ? (_jsx(SkillList, { skills: filteredSkills, onSkillSelect: setSelectedSkill })) : (_jsx(EmptyState, { icon: _jsx(Search, { className: "size-10" }), title: "No matching skills", description: "No skills match your current search and filter criteria.", action: _jsx(Button, { variant: "outline", onClick: clearFilters, children: "Clear filters" }) })), _jsx(SkillDetailDrawer, { skill: selectedSkill, onClose: () => setSelectedSkill(null) })] }));
52
52
  }
@@ -1 +1 @@
1
- {"version":3,"file":"tool-card.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/tools/tool-card.tsx"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AASD,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,aAAa,2CAkKrE"}
1
+ {"version":3,"file":"tool-card.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/tools/tool-card.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAEhG,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAChC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAcD,wBAAgB,QAAQ,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,EAAE,aAAa,2CAqOrE"}