@shipit-ai/cli 1.169.0 → 1.170.0-pr13.00cc956

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 (413) hide show
  1. package/apis/json-schema/ClaudeCodeProxyConfig.yaml +20 -0
  2. package/apis/json-schema/FeatureFlags.yaml +5 -0
  3. package/apis/json-schema/LiteLLMProxyConfig.yaml +17 -0
  4. package/apis/json-schema/LiteLLMProxyRoutingMode.yaml +8 -0
  5. package/apis/json-schema/Settings.yaml +3 -0
  6. package/dist/packages/core/src/application/ports/output/services/index.d.ts +1 -0
  7. package/dist/packages/core/src/application/ports/output/services/index.d.ts.map +1 -1
  8. package/dist/packages/core/src/application/ports/output/services/plugin-marketplace.interface.d.ts +46 -0
  9. package/dist/packages/core/src/application/ports/output/services/plugin-marketplace.interface.d.ts.map +1 -0
  10. package/dist/packages/core/src/application/ports/output/services/plugin-marketplace.interface.js +12 -0
  11. package/dist/packages/core/src/application/use-cases/plugins/add-marketplace.use-case.d.ts +16 -0
  12. package/dist/packages/core/src/application/use-cases/plugins/add-marketplace.use-case.d.ts.map +1 -0
  13. package/dist/packages/core/src/application/use-cases/plugins/add-marketplace.use-case.js +34 -0
  14. package/dist/packages/core/src/application/use-cases/plugins/fetch-plugin-catalog.use-case.d.ts +24 -0
  15. package/dist/packages/core/src/application/use-cases/plugins/fetch-plugin-catalog.use-case.d.ts.map +1 -0
  16. package/dist/packages/core/src/application/use-cases/plugins/fetch-plugin-catalog.use-case.js +52 -0
  17. package/dist/packages/core/src/application/use-cases/plugins/install-plugin.use-case.d.ts +17 -0
  18. package/dist/packages/core/src/application/use-cases/plugins/install-plugin.use-case.d.ts.map +1 -0
  19. package/dist/packages/core/src/application/use-cases/plugins/install-plugin.use-case.js +33 -0
  20. package/dist/packages/core/src/application/use-cases/plugins/toggle-plugin.use-case.d.ts +17 -0
  21. package/dist/packages/core/src/application/use-cases/plugins/toggle-plugin.use-case.d.ts.map +1 -0
  22. package/dist/packages/core/src/application/use-cases/plugins/toggle-plugin.use-case.js +33 -0
  23. package/dist/packages/core/src/application/use-cases/plugins/uninstall-plugin.use-case.d.ts +16 -0
  24. package/dist/packages/core/src/application/use-cases/plugins/uninstall-plugin.use-case.d.ts.map +1 -0
  25. package/dist/packages/core/src/application/use-cases/plugins/uninstall-plugin.use-case.js +33 -0
  26. package/dist/packages/core/src/domain/factories/settings-defaults.factory.d.ts.map +1 -1
  27. package/dist/packages/core/src/domain/factories/settings-defaults.factory.js +1 -0
  28. package/dist/packages/core/src/domain/generated/output.d.ts +59 -0
  29. package/dist/packages/core/src/domain/generated/output.d.ts.map +1 -1
  30. package/dist/packages/core/src/domain/generated/output.js +6 -0
  31. package/dist/packages/core/src/infrastructure/di/modules/services.module.d.ts.map +1 -1
  32. package/dist/packages/core/src/infrastructure/di/modules/services.module.js +13 -0
  33. package/dist/packages/core/src/infrastructure/di/modules/use-cases.module.d.ts.map +1 -1
  34. package/dist/packages/core/src/infrastructure/di/modules/use-cases.module.js +12 -0
  35. package/dist/packages/core/src/infrastructure/di/modules/web-tokens.module.d.ts.map +1 -1
  36. package/dist/packages/core/src/infrastructure/di/modules/web-tokens.module.js +22 -0
  37. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts +9 -0
  38. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.d.ts.map +1 -1
  39. package/dist/packages/core/src/infrastructure/persistence/sqlite/mappers/settings.mapper.js +55 -0
  40. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-litellm-proxy.d.ts +14 -0
  41. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-litellm-proxy.d.ts.map +1 -0
  42. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/054-add-litellm-proxy.js +28 -0
  43. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/055-add-litellm-proxy-agent-config.d.ts +15 -0
  44. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/055-add-litellm-proxy-agent-config.d.ts.map +1 -0
  45. package/dist/packages/core/src/infrastructure/persistence/sqlite/migrations/055-add-litellm-proxy-agent-config.js +32 -0
  46. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.d.ts.map +1 -1
  47. package/dist/packages/core/src/infrastructure/repositories/sqlite-settings.repository.js +36 -5
  48. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-provider.service.d.ts.map +1 -1
  49. package/dist/packages/core/src/infrastructure/services/agents/common/agent-executor-provider.service.js +7 -1
  50. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts +4 -1
  51. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.d.ts.map +1 -1
  52. package/dist/packages/core/src/infrastructure/services/agents/common/executors/claude-code-executor.service.js +53 -0
  53. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.d.ts.map +1 -1
  54. package/dist/packages/core/src/infrastructure/services/agents/feature-agent/feature-agent-worker.js +5 -0
  55. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/index.d.ts +4 -0
  56. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/index.d.ts.map +1 -0
  57. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/index.js +3 -0
  58. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.schema.d.ts +78 -0
  59. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.schema.d.ts.map +1 -0
  60. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.schema.js +46 -0
  61. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.service.d.ts +29 -0
  62. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.service.d.ts.map +1 -0
  63. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.service.js +147 -0
  64. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.validators.d.ts +11 -0
  65. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.validators.d.ts.map +1 -0
  66. package/dist/packages/core/src/infrastructure/services/plugin-marketplace/plugin-marketplace.validators.js +47 -0
  67. package/dist/src/presentation/web/app/actions/add-marketplace.d.ts +5 -0
  68. package/dist/src/presentation/web/app/actions/add-marketplace.d.ts.map +1 -0
  69. package/dist/src/presentation/web/app/actions/add-marketplace.js +11 -0
  70. package/dist/src/presentation/web/app/actions/fetch-plugin-catalog.d.ts +5 -0
  71. package/dist/src/presentation/web/app/actions/fetch-plugin-catalog.d.ts.map +1 -0
  72. package/dist/src/presentation/web/app/actions/fetch-plugin-catalog.js +11 -0
  73. package/dist/src/presentation/web/app/actions/install-plugin.d.ts +5 -0
  74. package/dist/src/presentation/web/app/actions/install-plugin.d.ts.map +1 -0
  75. package/dist/src/presentation/web/app/actions/install-plugin.js +11 -0
  76. package/dist/src/presentation/web/app/actions/toggle-plugin.d.ts +5 -0
  77. package/dist/src/presentation/web/app/actions/toggle-plugin.d.ts.map +1 -0
  78. package/dist/src/presentation/web/app/actions/toggle-plugin.js +11 -0
  79. package/dist/src/presentation/web/app/actions/uninstall-plugin.d.ts +5 -0
  80. package/dist/src/presentation/web/app/actions/uninstall-plugin.d.ts.map +1 -0
  81. package/dist/src/presentation/web/app/actions/uninstall-plugin.js +11 -0
  82. package/dist/src/presentation/web/app/plugins/page.d.ts +2 -0
  83. package/dist/src/presentation/web/app/plugins/page.d.ts.map +1 -0
  84. package/dist/src/presentation/web/app/plugins/page.js +23 -0
  85. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.d.ts.map +1 -1
  86. package/dist/src/presentation/web/components/common/repository-node/repository-drawer.stories.js +1 -0
  87. package/dist/src/presentation/web/components/features/plugins/plugin-card.d.ts +9 -0
  88. package/dist/src/presentation/web/components/features/plugins/plugin-card.d.ts.map +1 -0
  89. package/dist/src/presentation/web/components/features/plugins/plugin-card.js +15 -0
  90. package/dist/src/presentation/web/components/features/plugins/plugin-card.stories.d.ts +17 -0
  91. package/dist/src/presentation/web/components/features/plugins/plugin-card.stories.d.ts.map +1 -0
  92. package/dist/src/presentation/web/components/features/plugins/plugin-card.stories.js +60 -0
  93. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.d.ts +11 -0
  94. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.d.ts.map +1 -0
  95. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.js +33 -0
  96. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.stories.d.ts +18 -0
  97. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.stories.d.ts.map +1 -0
  98. package/dist/src/presentation/web/components/features/plugins/plugin-detail-drawer.stories.js +51 -0
  99. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.d.ts +6 -0
  100. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.d.ts.map +1 -0
  101. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.js +124 -0
  102. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.stories.d.ts +12 -0
  103. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.stories.d.ts.map +1 -0
  104. package/dist/src/presentation/web/components/features/plugins/plugins-page-client.stories.js +24 -0
  105. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts.map +1 -1
  106. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.js +7 -0
  107. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
  108. package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.js +2 -0
  109. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.d.ts +6 -0
  110. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.d.ts.map +1 -0
  111. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.js +69 -0
  112. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.stories.d.ts +16 -0
  113. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.stories.d.ts.map +1 -0
  114. package/dist/src/presentation/web/components/features/settings/litellm-proxy-routing-section.stories.js +64 -0
  115. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.d.ts +6 -0
  116. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.d.ts.map +1 -0
  117. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.js +73 -0
  118. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.stories.d.ts +15 -0
  119. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.stories.d.ts.map +1 -0
  120. package/dist/src/presentation/web/components/features/settings/litellm-proxy-settings-section.stories.js +29 -0
  121. package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
  122. package/dist/src/presentation/web/components/features/settings/settings-page-client.js +5 -2
  123. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
  124. package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +1 -0
  125. package/dist/src/presentation/web/components/features/skills/skills-page-client.d.ts.map +1 -1
  126. package/dist/src/presentation/web/components/features/skills/skills-page-client.js +6 -2
  127. package/dist/src/presentation/web/components/features/tools/tools-page-client.d.ts.map +1 -1
  128. package/dist/src/presentation/web/components/features/tools/tools-page-client.js +23 -4
  129. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.d.ts.map +1 -1
  130. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.js +2 -2
  131. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.d.ts.map +1 -1
  132. package/dist/src/presentation/web/components/layouts/app-sidebar/app-sidebar.stories.js +1 -0
  133. package/dist/src/presentation/web/hooks/feature-flags-context.d.ts.map +1 -1
  134. package/dist/src/presentation/web/hooks/feature-flags-context.js +1 -0
  135. package/dist/src/presentation/web/lib/feature-flags.d.ts +2 -0
  136. package/dist/src/presentation/web/lib/feature-flags.d.ts.map +1 -1
  137. package/dist/src/presentation/web/lib/feature-flags.js +6 -0
  138. package/dist/translations/ar/web.json +56 -2
  139. package/dist/translations/de/web.json +56 -2
  140. package/dist/translations/en/web.json +56 -2
  141. package/dist/translations/es/web.json +56 -2
  142. package/dist/translations/fr/web.json +56 -2
  143. package/dist/translations/he/web.json +56 -2
  144. package/dist/translations/pt/web.json +56 -2
  145. package/dist/translations/ru/web.json +56 -2
  146. package/dist/tsconfig.build.tsbuildinfo +1 -1
  147. package/package.json +1 -1
  148. package/web/.next/BUILD_ID +1 -1
  149. package/web/.next/app-path-routes-manifest.json +1 -0
  150. package/web/.next/build-manifest.json +3 -3
  151. package/web/.next/fallback-build-manifest.json +3 -3
  152. package/web/.next/prerender-manifest.json +3 -3
  153. package/web/.next/required-server-files.js +3 -3
  154. package/web/.next/required-server-files.json +3 -3
  155. package/web/.next/routes-manifest.json +6 -0
  156. package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
  157. package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
  158. package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
  159. package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
  160. package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
  161. package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
  162. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +31 -31
  163. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  164. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  165. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  166. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  167. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  168. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
  169. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  170. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  171. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  172. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  173. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  174. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  175. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  176. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  177. package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
  178. package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
  179. package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
  180. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +31 -31
  181. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  182. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  183. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
  184. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
  185. package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
  186. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
  187. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  188. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  189. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
  190. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  191. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  192. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
  193. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
  194. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
  195. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
  196. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  197. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  198. package/web/.next/server/app/_global-error.html +1 -1
  199. package/web/.next/server/app/_global-error.rsc +1 -1
  200. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  201. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  202. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  203. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  204. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  205. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
  206. package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
  207. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  208. package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
  209. package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
  210. package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
  211. package/web/.next/server/app/api/graph-data/route.js +1 -1
  212. package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
  213. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js +1 -1
  214. package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
  215. package/web/.next/server/app/api/sessions-batch/route.js +1 -1
  216. package/web/.next/server/app/api/sessions-batch/route.js.nft.json +1 -1
  217. package/web/.next/server/app/plugins/page/app-paths-manifest.json +3 -0
  218. package/web/.next/server/app/plugins/page/build-manifest.json +18 -0
  219. package/web/.next/server/app/plugins/page/next-font-manifest.json +10 -0
  220. package/web/.next/server/app/plugins/page/react-loadable-manifest.json +8 -0
  221. package/web/.next/server/app/plugins/page/server-reference-manifest.json +185 -0
  222. package/web/.next/server/app/plugins/page.js +17 -0
  223. package/web/.next/server/app/plugins/page.js.map +5 -0
  224. package/web/.next/server/app/plugins/page.js.nft.json +1 -0
  225. package/web/.next/server/app/plugins/page_client-reference-manifest.js +3 -0
  226. package/web/.next/server/app/settings/page/server-reference-manifest.json +34 -22
  227. package/web/.next/server/app/settings/page.js +1 -1
  228. package/web/.next/server/app/settings/page.js.nft.json +1 -1
  229. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  230. package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
  231. package/web/.next/server/app/skills/page.js.nft.json +1 -1
  232. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  233. package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
  234. package/web/.next/server/app/tools/page.js.nft.json +1 -1
  235. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  236. package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
  237. package/web/.next/server/app/version/page.js.nft.json +1 -1
  238. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  239. package/web/.next/server/app-paths-manifest.json +1 -0
  240. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js +1 -1
  241. package/web/.next/server/chunks/11es_next_dist_esm_build_templates_app-route_067cwst.js.map +1 -1
  242. package/web/.next/server/chunks/{[root-of-the-server]__0zu_byw._.js → [root-of-the-server]__07suer1._.js} +2 -2
  243. package/web/.next/server/chunks/{[root-of-the-server]__0u1jyv9._.js → [root-of-the-server]__0sgzo7y._.js} +2 -2
  244. package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
  245. package/web/.next/server/chunks/{[root-of-the-server]__08cpfre._.js → [root-of-the-server]__0uxlr84._.js} +2 -2
  246. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
  247. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
  248. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
  249. package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
  250. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
  251. package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
  252. package/web/.next/server/chunks/ssr/11es_next_dist_esm_build_templates_app-page_0y6lfp8.js +4 -0
  253. package/web/.next/server/chunks/ssr/11es_next_dist_esm_build_templates_app-page_0y6lfp8.js.map +1 -0
  254. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
  255. package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
  256. package/web/.next/server/chunks/ssr/{_04s_q5r._.js → 12k._sonner_dist_index_mjs_0-vmpk5._.js} +2 -2
  257. package/web/.next/server/chunks/ssr/12k._sonner_dist_index_mjs_0-vmpk5._.js.map +1 -0
  258. package/web/.next/server/chunks/ssr/{[root-of-the-server]__0rvrr1j._.js → [root-of-the-server]__0.5ojmt._.js} +2 -2
  259. package/web/.next/server/chunks/ssr/[root-of-the-server]__0.5ojmt._.js.map +1 -0
  260. package/web/.next/server/chunks/ssr/[root-of-the-server]__04h~gav._.js +3 -0
  261. package/web/.next/server/chunks/ssr/[root-of-the-server]__04h~gav._.js.map +1 -0
  262. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js +1 -1
  263. package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js.map +1 -1
  264. package/web/.next/server/chunks/ssr/[root-of-the-server]__0dec29w._.js +3 -0
  265. package/web/.next/server/chunks/ssr/[root-of-the-server]__0dec29w._.js.map +1 -0
  266. package/web/.next/server/chunks/ssr/[root-of-the-server]__0ge~xny._.js +1 -1
  267. package/web/.next/server/chunks/ssr/[root-of-the-server]__0ge~xny._.js.map +1 -1
  268. package/web/.next/server/chunks/ssr/[root-of-the-server]__0qda~yi._.js +1 -1
  269. package/web/.next/server/chunks/ssr/[root-of-the-server]__0qda~yi._.js.map +1 -1
  270. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
  271. package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js +1 -1
  272. package/web/.next/server/chunks/ssr/[root-of-the-server]__0t~u8sd._.js +1 -1
  273. package/web/.next/server/chunks/ssr/[root-of-the-server]__0t~u8sd._.js.map +1 -1
  274. package/web/.next/server/chunks/ssr/[root-of-the-server]__10tll_l._.js +1 -1
  275. package/web/.next/server/chunks/ssr/[root-of-the-server]__10tll_l._.js.map +1 -1
  276. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js +1 -1
  277. package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js.map +1 -1
  278. package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
  279. package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
  280. package/web/.next/server/chunks/ssr/{_00u~.41._.js → _03x4h9e._.js} +2 -2
  281. package/web/.next/server/chunks/ssr/_03x4h9e._.js.map +1 -0
  282. package/web/.next/server/chunks/ssr/{_0~0jkp_._.js → _05fk0a4._.js} +2 -2
  283. package/web/.next/server/chunks/ssr/_05fk0a4._.js.map +1 -0
  284. package/web/.next/server/chunks/ssr/_069y.js._.js +2 -2
  285. package/web/.next/server/chunks/ssr/_069y.js._.js.map +1 -1
  286. package/web/.next/server/chunks/ssr/_083k45~._.js +3 -0
  287. package/web/.next/server/chunks/ssr/_083k45~._.js.map +1 -0
  288. package/web/.next/server/chunks/ssr/_0__4si~._.js +1 -1
  289. package/web/.next/server/chunks/ssr/_0__4si~._.js.map +1 -1
  290. package/web/.next/server/chunks/ssr/_0_m17kl._.js +1 -1
  291. package/web/.next/server/chunks/ssr/_0_m17kl._.js.map +1 -1
  292. package/web/.next/server/chunks/ssr/_0d4miu.._.js +1 -1
  293. package/web/.next/server/chunks/ssr/_0d4miu.._.js.map +1 -1
  294. package/web/.next/server/chunks/ssr/_0e8ern9._.js +1 -1
  295. package/web/.next/server/chunks/ssr/_0e8ern9._.js.map +1 -1
  296. package/web/.next/server/chunks/ssr/_0i~-084._.js +3 -0
  297. package/web/.next/server/chunks/ssr/_0i~-084._.js.map +1 -0
  298. package/web/.next/server/chunks/ssr/{_0wor25i._.js → _0job75~._.js} +2 -2
  299. package/web/.next/server/chunks/ssr/{_0wor25i._.js.map → _0job75~._.js.map} +1 -1
  300. package/web/.next/server/chunks/ssr/_0jtr2u0._.js +3 -0
  301. package/web/.next/server/chunks/ssr/_0jtr2u0._.js.map +1 -0
  302. package/web/.next/server/chunks/ssr/_0kaec~c._.js +3 -0
  303. package/web/.next/server/chunks/ssr/_0kaec~c._.js.map +1 -0
  304. package/web/.next/server/chunks/ssr/_0o.xc6x._.js +3 -0
  305. package/web/.next/server/chunks/ssr/_0o.xc6x._.js.map +1 -0
  306. package/web/.next/server/chunks/ssr/{_0hw~zvl._.js → _0o_oaao._.js} +2 -2
  307. package/web/.next/server/chunks/ssr/_0o_oaao._.js.map +1 -0
  308. package/web/.next/server/chunks/ssr/_0p3~u8u._.js +2 -2
  309. package/web/.next/server/chunks/ssr/_0p3~u8u._.js.map +1 -1
  310. package/web/.next/server/chunks/ssr/_0r.3n~3._.js +1 -1
  311. package/web/.next/server/chunks/ssr/_0r.3n~3._.js.map +1 -1
  312. package/web/.next/server/chunks/ssr/_0rcx2-c._.js +9 -0
  313. package/web/.next/server/chunks/ssr/_0rcx2-c._.js.map +1 -0
  314. package/web/.next/server/chunks/ssr/_0t59q8r._.js +1 -1
  315. package/web/.next/server/chunks/ssr/_0t59q8r._.js.map +1 -1
  316. package/web/.next/server/chunks/ssr/_0tcccbb._.js +1 -1
  317. package/web/.next/server/chunks/ssr/_0tcccbb._.js.map +1 -1
  318. package/web/.next/server/chunks/ssr/{_0pa1dkv._.js → _0u3d8.n._.js} +2 -2
  319. package/web/.next/server/chunks/ssr/_0u3d8.n._.js.map +1 -0
  320. package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
  321. package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
  322. package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
  323. package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
  324. package/web/.next/server/chunks/ssr/{_09r54oy._.js → _0ygafoy._.js} +2 -2
  325. package/web/.next/server/chunks/ssr/{_09r54oy._.js.map → _0ygafoy._.js.map} +1 -1
  326. package/web/.next/server/chunks/ssr/_0zk-h5w._.js +1 -1
  327. package/web/.next/server/chunks/ssr/_0zk-h5w._.js.map +1 -1
  328. package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
  329. package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
  330. package/web/.next/server/chunks/ssr/{_01qdxy2._.js → _0~b~4sr._.js} +2 -2
  331. package/web/.next/server/chunks/ssr/{_01qdxy2._.js.map → _0~b~4sr._.js.map} +1 -1
  332. package/web/.next/server/chunks/ssr/_10joy2y._.js +3 -0
  333. package/web/.next/server/chunks/ssr/_10joy2y._.js.map +1 -0
  334. package/web/.next/server/chunks/ssr/_1161g9x._.js +1 -1
  335. package/web/.next/server/chunks/ssr/_1161g9x._.js.map +1 -1
  336. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_plugins_page_actions_0rdndum.js +3 -0
  337. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_plugins_page_actions_0rdndum.js.map +1 -0
  338. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js +1 -1
  339. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map +1 -1
  340. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js +1 -1
  341. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map +1 -1
  342. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +1 -1
  343. package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
  344. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
  345. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
  346. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js +1 -1
  347. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js.map +1 -1
  348. package/web/.next/server/middleware-build-manifest.js +3 -3
  349. package/web/.next/server/next-font-manifest.js +1 -1
  350. package/web/.next/server/next-font-manifest.json +3 -0
  351. package/web/.next/server/pages/500.html +1 -1
  352. package/web/.next/server/server-reference-manifest.js +1 -1
  353. package/web/.next/server/server-reference-manifest.json +187 -61
  354. package/web/.next/static/chunks/0.s8cxri-_s9l.js +1 -0
  355. package/web/.next/static/chunks/012cnd7koqv6d.js +7 -0
  356. package/web/.next/static/chunks/{0dq50gtgaj63f.js → 029s48ykt7mw9.js} +1 -1
  357. package/web/.next/static/chunks/{11vbir.u7_zf7.js → 03agfpdm4n_fn.js} +1 -1
  358. package/web/.next/static/chunks/05qti39qqsvzs.js +1 -0
  359. package/web/.next/static/chunks/{0fg~vc93spa9c.js → 07gal-~-zwagj.js} +1 -1
  360. package/web/.next/static/chunks/{0u_27fdqa2jeg.js → 0abfw8oib7e3t.js} +1 -1
  361. package/web/.next/static/chunks/{0in4l8mne5y~_.js → 0b2pi58fg3lt3.js} +1 -1
  362. package/web/.next/static/chunks/{121v1_d_dfk2k.js → 0boet02f0igne.js} +1 -1
  363. package/web/.next/static/chunks/0f80ru2bzs3v5.js +1 -0
  364. package/web/.next/static/chunks/{12axopx66pocj.js → 0ibyqd4oceukb.js} +2 -2
  365. package/web/.next/static/chunks/{0v~n9z6b639zm.js → 0jwq.mr-.ltps.js} +1 -1
  366. package/web/.next/static/chunks/0k8m.qcahm63g.js +1 -0
  367. package/web/.next/static/chunks/0kqqf5i.f1-nm.js +1 -0
  368. package/web/.next/static/chunks/0lc0x8kcu46ae.js +1 -0
  369. package/web/.next/static/chunks/{183ehj-b80a~o.js → 0nfd9bvcnbcgl.js} +1 -1
  370. package/web/.next/static/chunks/{1874_wt9rit96.js → 0o5siyl.hsy96.js} +1 -1
  371. package/web/.next/static/chunks/0s0432bko4hq9.js +1 -0
  372. package/web/.next/static/chunks/{0o33urrd3lk~u.js → 0skduwu0tu8qh.js} +1 -1
  373. package/web/.next/static/chunks/0ug478hm-8bog.js +5 -0
  374. package/web/.next/static/chunks/{0yibymrb2j05t.css → 0v7r7y~3e~oo6.css} +1 -1
  375. package/web/.next/static/chunks/{00m_fbc2z1gyi.js → 0~5~-wr7rq8b6.js} +3 -3
  376. package/web/.next/static/chunks/{09f2lesd_dd3~.js → 10gfhk-66cbtu.js} +1 -1
  377. package/web/.next/static/chunks/{0k0j7anrbg-of.js → 10lvozwidvzfo.js} +3 -3
  378. package/web/.next/static/chunks/10rtagfoabp3b.js +1 -0
  379. package/web/.next/server/chunks/ssr/[root-of-the-server]__0qxd563._.js +0 -3
  380. package/web/.next/server/chunks/ssr/[root-of-the-server]__0qxd563._.js.map +0 -1
  381. package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js.map +0 -1
  382. package/web/.next/server/chunks/ssr/_00u~.41._.js.map +0 -1
  383. package/web/.next/server/chunks/ssr/_04s_q5r._.js.map +0 -1
  384. package/web/.next/server/chunks/ssr/_0a_8rlj._.js +0 -3
  385. package/web/.next/server/chunks/ssr/_0a_8rlj._.js.map +0 -1
  386. package/web/.next/server/chunks/ssr/_0dy8.0k._.js +0 -3
  387. package/web/.next/server/chunks/ssr/_0dy8.0k._.js.map +0 -1
  388. package/web/.next/server/chunks/ssr/_0gdghcr._.js +0 -3
  389. package/web/.next/server/chunks/ssr/_0gdghcr._.js.map +0 -1
  390. package/web/.next/server/chunks/ssr/_0hw~zvl._.js.map +0 -1
  391. package/web/.next/server/chunks/ssr/_0l2~~pi._.js +0 -3
  392. package/web/.next/server/chunks/ssr/_0l2~~pi._.js.map +0 -1
  393. package/web/.next/server/chunks/ssr/_0n.magx._.js +0 -3
  394. package/web/.next/server/chunks/ssr/_0n.magx._.js.map +0 -1
  395. package/web/.next/server/chunks/ssr/_0pa1dkv._.js.map +0 -1
  396. package/web/.next/server/chunks/ssr/_0y8u4.e._.js +0 -9
  397. package/web/.next/server/chunks/ssr/_0y8u4.e._.js.map +0 -1
  398. package/web/.next/server/chunks/ssr/_0~0jkp_._.js.map +0 -1
  399. package/web/.next/static/chunks/0-ud~1jj7chzu.js +0 -7
  400. package/web/.next/static/chunks/0c0dau5pmseko.js +0 -1
  401. package/web/.next/static/chunks/0n3kuj7t_-jzp.js +0 -1
  402. package/web/.next/static/chunks/0pt-d18f7zxvv.js +0 -1
  403. package/web/.next/static/chunks/0xwh.0u-dexsl.js +0 -1
  404. package/web/.next/static/chunks/103xnw203o9k1.js +0 -1
  405. package/web/.next/static/chunks/12pd180jp8zu..js +0 -5
  406. package/web/.next/static/chunks/13fcwhkw7dle2.js +0 -1
  407. package/web/.next/static/chunks/13q1peb_t9vj8.js +0 -1
  408. /package/web/.next/server/chunks/{[root-of-the-server]__0zu_byw._.js.map → [root-of-the-server]__07suer1._.js.map} +0 -0
  409. /package/web/.next/server/chunks/{[root-of-the-server]__0u1jyv9._.js.map → [root-of-the-server]__0sgzo7y._.js.map} +0 -0
  410. /package/web/.next/server/chunks/{[root-of-the-server]__08cpfre._.js.map → [root-of-the-server]__0uxlr84._.js.map} +0 -0
  411. /package/web/.next/static/{SNdaKJ9fpre8tUMRe1jlA → GeXKcODhEHBnDRVLMaAnW}/_buildManifest.js +0 -0
  412. /package/web/.next/static/{SNdaKJ9fpre8tUMRe1jlA → GeXKcODhEHBnDRVLMaAnW}/_clientMiddlewareManifest.js +0 -0
  413. /package/web/.next/static/{SNdaKJ9fpre8tUMRe1jlA → GeXKcODhEHBnDRVLMaAnW}/_ssgManifest.js +0 -0
@@ -1,3 +1,3 @@
1
- module.exports=[92163,a=>{"use strict";var b=a.i(53083),c=a.i(11321),d=a.i(6168),e=a.i(41305),f=a.i(85536),g=a.i(20901),h=a.i(96436),i=a.i(44877),j=a.i(28966),k=a.i(86139),l=a.i(82912),m=a.i(69045),n=a.i(77612),o=a.i(18288),o=o,p=a.i(18948),q=a.i(82934),r=a.i(34948),s=a.i(60197),t=a.i(2);let u=(0,a.i(97624).default)("monitor",[["rect",{width:"20",height:"14",x:"2",y:"3",rx:"2",key:"48i651"}],["line",{x1:"8",x2:"16",y1:"21",y2:"21",key:"1svkeh"}],["line",{x1:"12",x2:"12",y1:"17",y2:"21",key:"vw1qmm"}]]);var v=a.i(8685),w=a.i(37545),x=a.i(24255);let y={linux:"Linux",darwin:"macOS",win32:"Windows"},z={ide:{label:"IDE",icon:u},"cli-agent":{label:"CLI Agent",icon:v.Terminal},vcs:{label:"VCS",icon:w.GitBranch},terminal:{label:"Terminal",icon:v.Terminal}};function A({status:a}){return"available"===a?(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400",children:[(0,b.jsx)(s.Check,{className:"h-3 w-3"}),"Installed"]}):"error"===a?(0,b.jsx)("span",{className:"inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700 dark:bg-red-900/30 dark:text-red-400",children:"Error"}):(0,b.jsx)("span",{className:"inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",children:"Missing"})}function B({tool:a,open:d,onClose:e,onRefresh:f,autoStart:j}){let[k,l]=(0,c.useState)(!1),[n,o]=(0,c.useState)(!1),{logs:q,status:v,startInstall:w}=function(a){let[b,d]=(0,c.useState)([]),[e,f]=(0,c.useState)("idle"),[g,h]=(0,c.useState)(null),i=(0,c.useRef)(null),j=(0,c.useCallback)(()=>{i.current&&(i.current.close(),i.current=null)},[]);return(0,c.useEffect)(()=>j,[j]),{logs:b,status:e,result:g,startInstall:(0,c.useCallback)(()=>{j(),d([]),h(null),f("streaming");let b=new EventSource(`/api/tools/${a}/install/stream`);i.current=b,b.onmessage=a=>{d(b=>[...b,a.data])},b.addEventListener("done",a=>{let b=JSON.parse(a.data);h(b),f("error"===b.status?"error":"done"),j()}),b.onerror=()=>{f("error"),j()}},[a,j])}}(a.id),C=(0,c.useRef)(null),D=(0,c.useRef)(!0),E=(0,c.useRef)(!1),F="available"===a.status.status,G="error"===a.status.status,H=F&&!!a.openDirectory,I=!F&&!G&&a.autoInstall;async function J(){o(!0);try{await fetch(`/api/tools/${a.id}/launch`,{method:"POST"})}finally{o(!1)}}(0,c.useEffect)(()=>{d&&j&&I&&"idle"===v&&!E.current&&(E.current=!0,w()),d||(E.current=!1)},[d,j,I,v,w]);let K=(0,c.useCallback)(()=>{let a=C.current;a&&(D.current=a.scrollTop+a.clientHeight>=a.scrollHeight-50)},[]);(0,c.useEffect)(()=>{D.current&&C.current&&(C.current.scrollTop=C.current.scrollHeight)},[q,v]),(0,c.useEffect)(()=>{"done"===v&&f&&f()},[v,f]);let L=(0,b.jsxs)("div",{className:"flex flex-col gap-1.5 pe-6",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[a.iconUrl?(0,b.jsx)("img",{src:a.iconUrl,alt:"",width:24,height:24,className:"shrink-0"}):(0,b.jsx)(m.Package,{className:"text-muted-foreground h-6 w-6 shrink-0"}),(0,b.jsx)("h2",{className:"text-base font-bold",children:a.name}),(0,b.jsx)(A,{status:a.status.status})]}),(0,b.jsx)("div",{className:"flex items-center gap-2",children:a.tags.map(a=>{let c=z[a]??{label:a,icon:u},d=c.icon;return(0,b.jsxs)("span",{className:"text-muted-foreground/70 inline-flex items-center gap-0.5 text-[10px]",children:[(0,b.jsx)(d,{className:"h-3 w-3"}),c.label]},a)})})]});return(0,b.jsx)(x.BaseDrawer,{open:d,onClose:e,size:"md",modal:!0,title:a.name,header:L,"data-testid":"tool-detail-drawer",children:(0,b.jsxs)("div",{className:"flex flex-1 flex-col gap-4 overflow-y-auto p-4",children:[(0,b.jsx)("p",{className:"text-muted-foreground text-sm",children:a.description}),a.author||a.platforms?(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs",children:[a.author?(0,b.jsxs)("span",{className:"text-muted-foreground",children:["by"," ",a.website?(0,b.jsx)("a",{href:a.website,target:"_blank",rel:"noopener noreferrer",className:"text-foreground hover:underline",children:a.author}):(0,b.jsx)("span",{className:"text-foreground",children:a.author})]}):null,a.platforms&&a.platforms.length>0?(0,b.jsx)("span",{className:"text-muted-foreground",children:a.platforms.map(a=>y[a]??a).join(" · ")}):null]}):null,a.installCommand?(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsx)("span",{className:"text-muted-foreground text-xs font-semibold tracking-wide uppercase",children:"Install command"}),(0,b.jsxs)("div",{className:"relative rounded-md bg-zinc-900 text-zinc-100",children:[(0,b.jsx)("pre",{className:"overflow-x-auto px-3 py-2.5 pe-16 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap",children:(0,b.jsx)("code",{children:a.installCommand})}),(0,b.jsxs)(p.Button,{variant:"ghost",size:"sm",className:"absolute top-1.5 right-1.5 h-7 cursor-pointer px-2 text-zinc-400 hover:text-zinc-100",onClick:function(){a.installCommand&&navigator.clipboard.writeText(a.installCommand).then(()=>{l(!0),setTimeout(()=>l(!1),2e3)})},"aria-label":k?"Copied!":"Copy install command",children:[k?(0,b.jsx)(s.Check,{className:"h-3.5 w-3.5 text-emerald-500"}):(0,b.jsx)(r.Copy,{className:"h-3.5 w-3.5"}),(0,b.jsx)("span",{className:"ms-1 text-[10px]",children:k?"Copied!":"Copy"})]})]})]}):null,(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[I?(0,b.jsxs)(p.Button,{size:"sm",onClick:w,disabled:"streaming"===v,"aria-label":`Install ${a.name}`,className:"cursor-pointer",children:["streaming"===v?(0,b.jsx)(g.LoaderCircle,{className:"me-1.5 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(i.Download,{className:"me-1.5 h-3.5 w-3.5"}),"streaming"===v?"Installing...":"Install"]}):null,H?(0,b.jsxs)(p.Button,{size:"sm",variant:"outline",onClick:()=>void J(),disabled:n,"aria-label":`Launch ${a.name}`,className:"cursor-pointer",children:[n?(0,b.jsx)(g.LoaderCircle,{className:"me-1.5 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(h.Rocket,{className:"me-1.5 h-3.5 w-3.5"}),"Launch"]}):null,a.documentationUrl?(0,b.jsx)(p.Button,{variant:"outline",size:"sm",className:"cursor-pointer",asChild:!0,children:(0,b.jsxs)("a",{href:a.documentationUrl,target:"_blank",rel:"noopener noreferrer",children:["Docs",(0,b.jsx)(t.ExternalLink,{className:"ms-1 h-3 w-3"})]})}):null]}),("streaming"===v||"done"===v||"error"===v)&&q.length>0?(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsx)("span",{className:"text-muted-foreground text-xs font-semibold tracking-wide uppercase",children:"Install log"}),(0,b.jsxs)("div",{ref:C,onScroll:K,className:"max-h-60 overflow-auto rounded-md bg-zinc-900 p-3 font-mono text-xs leading-relaxed text-zinc-100","data-testid":"tool-install-log",children:[q.map((a,c)=>(0,b.jsx)("div",{className:"break-all whitespace-pre-wrap",children:a},c)),"done"===v?(0,b.jsx)("div",{className:"mt-2 border-t border-zinc-700 pt-2 text-emerald-400",children:"Installation complete"}):null,"error"===v?(0,b.jsx)("div",{className:"mt-2 border-t border-zinc-700 pt-2 text-red-400",children:"Installation failed"}):null]})]}):null]})})}let C={ide:"IDE","cli-agent":"CLI Agent",vcs:"VCS",terminal:"Terminal"};function D({tool:a,onRefresh:d,className:e}){let[r,s]=(0,c.useState)(!1),[t,u]=(0,c.useState)(!1),[v,w]=(0,c.useTransition)(),x="available"===a.status.status,y="error"===a.status.status,z=x&&!!a.openDirectory;return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{"data-testid":"tool-card",onClick:function(){u(!1),s(!0)},className:(0,f.cn)("bg-card editorial-shadow group flex w-full cursor-pointer flex-col gap-4 rounded-xl p-5","transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md hover:ring-slate-300 dark:hover:ring-slate-600",e),children:[(0,b.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,b.jsx)("div",{className:"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-slate-100 p-2 ring-1 ring-slate-200/50 dark:bg-slate-800 dark:ring-slate-700/50",children:a.iconUrl?(0,b.jsx)("img",{src:a.iconUrl,alt:"",width:28,height:28,className:"h-full w-full"}):(0,b.jsx)(m.Package,{className:"text-muted-foreground h-full w-full"})}),(0,b.jsxs)("div",{className:"min-w-0",children:[(0,b.jsx)("h3",{"data-testid":"tool-card-name",className:"text-foreground truncate text-sm leading-tight font-bold tracking-tight",children:a.name}),a.author?(0,b.jsxs)("div",{className:"mt-1 flex items-center gap-1.5",children:[(0,b.jsx)("span",{"data-testid":"tool-card-vendor-label",className:"text-[9px] font-bold tracking-wider text-slate-400 uppercase",children:"Vendor"}),(0,b.jsx)("span",{"data-testid":"tool-card-vendor",className:"text-muted-foreground truncate text-xs font-medium",children:a.author})]}):a.tags.length>0?(0,b.jsxs)("div",{className:"mt-1 flex items-center gap-1.5",children:[(0,b.jsx)("span",{className:"text-[9px] font-bold tracking-wider text-slate-400 uppercase",children:"Tag"}),(0,b.jsx)("span",{"data-testid":"tool-card-tags",className:"text-muted-foreground truncate text-xs font-medium",children:a.tags.map(a=>C[a]??a).join(" · ")})]}):null]})]}),(0,b.jsxs)("div",{className:"flex shrink-0 items-center gap-2",children:[y&&"error"===a.status.status?(0,b.jsxs)("span",{className:"flex items-center gap-1 text-[10px] font-medium text-red-600 dark:text-red-400",title:a.status.errorMessage,children:[(0,b.jsx)(j.CircleX,{className:"h-3 w-3 shrink-0"}),"Error"]}):x?(0,b.jsxs)("span",{className:"flex items-center gap-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400",children:[(0,b.jsx)(l.CircleCheck,{className:"h-3 w-3"}),"Installed"]}):(0,b.jsxs)("span",{className:"text-muted-foreground flex items-center gap-1 text-[10px] font-medium",children:[(0,b.jsx)(k.Circle,{className:"h-3 w-3"}),"Not installed"]}),a.required?(0,b.jsx)(q.TooltipProvider,{children:(0,b.jsxs)(q.Tooltip,{children:[(0,b.jsx)(q.TooltipTrigger,{asChild:!0,children:(0,b.jsx)("span",{className:"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[9px] font-bold tracking-wider text-amber-700 uppercase dark:bg-amber-900/40 dark:text-amber-400",children:"Required"})}),(0,b.jsx)(q.TooltipContent,{side:"top",children:"This tool is required for ShipIT to function properly"})]})}):null]})]}),(0,b.jsx)("p",{"data-testid":"tool-card-summary",className:"text-muted-foreground -mt-2 line-clamp-2 text-xs leading-relaxed",children:a.summary}),(0,b.jsx)("div",{className:"mt-auto flex flex-col gap-1.5",children:x&&z?(0,b.jsxs)(p.Button,{variant:"default",onClick:function(b){b.stopPropagation(),w(async()=>{await fetch(`/api/tools/${a.id}/launch`,{method:"POST"})})},disabled:v,"aria-label":`Launch ${a.name}`,"data-testid":"tool-card-launch-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[v?(0,b.jsx)(g.LoaderCircle,{className:"me-1 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(h.Rocket,{className:"me-1 h-3.5 w-3.5"}),"Launch"]}):x||y?y?(0,b.jsxs)(p.Button,{variant:"outline",onClick:a=>{a.stopPropagation(),u(!1),s(!0)},"aria-label":`View error details for ${a.name}`,"data-testid":"tool-card-error-button",className:"h-9 w-full cursor-pointer rounded-lg border-red-300 text-xs font-bold tracking-wide text-red-600 transition-all duration-300 hover:-translate-y-0.5 hover:bg-red-50 hover:shadow-md dark:border-red-900 dark:text-red-400 dark:hover:bg-red-950/30",children:[(0,b.jsx)(o.default,{className:"me-1 h-3.5 w-3.5"}),"View Error"]}):(0,b.jsxs)(p.Button,{variant:"outline",onClick:a=>{a.stopPropagation(),u(!1),s(!0)},"aria-label":`View details for ${a.name}`,"data-testid":"tool-card-details-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[(0,b.jsx)(n.Info,{className:"me-1 h-3.5 w-3.5"}),"View Details"]}):(0,b.jsxs)(p.Button,{variant:"default",onClick:function(b){b.stopPropagation(),u(a.autoInstall),s(!0)},"aria-label":`Install ${a.name}`,"data-testid":"tool-card-install-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[(0,b.jsx)(i.Download,{className:"me-1 h-3.5 w-3.5"}),"Install"]})})]}),(0,b.jsx)(B,{tool:a,open:r,onClose:()=>s(!1),onRefresh:d,autoStart:t})]})}let E={all:()=>!0,ide:a=>a.tags.includes("ide"),"cli-agent":a=>a.tags.includes("cli-agent"),vcs:a=>a.tags.includes("vcs"),terminal:a=>a.tags.includes("terminal")};a.s(["ToolsPageClient",0,function({tools:a,className:g}){let[h,i]=(0,c.useState)(a),[j,k]=(0,c.useState)("all"),l=(0,c.useCallback)(async()=>{try{let a=await fetch("/api/tools");if(a.ok){let b=await a.json();i(b)}}catch{}},[]),m=h.filter(E[j]),n=h.filter(a=>"available"===a.status.status).length;return(0,b.jsxs)("div",{"data-testid":"tools-page-client",className:(0,f.cn)("space-y-8",g),children:[(0,b.jsxs)("div",{className:"space-y-1.5",children:[(0,b.jsx)("div",{className:"flex items-center gap-2",children:(0,b.jsx)("span",{className:"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase",children:"Developer Portal"})}),(0,b.jsxs)("div",{className:"flex items-baseline gap-3",children:[(0,b.jsx)("h1",{className:"text-foreground text-3xl font-black tracking-tight",children:"Tools"}),(0,b.jsxs)("span",{className:"text-muted-foreground text-sm font-medium",children:[n," of ",h.length," installed"]})]})]}),(0,b.jsxs)(e.Tabs,{value:j,onValueChange:a=>k(a),"data-testid":"tools-page-tabs",children:[(0,b.jsxs)(e.TabsList,{"data-editorial":"true",className:"bg-card editorial-shadow h-10 p-1",children:[(0,b.jsx)(e.TabsTrigger,{value:"all","data-testid":"tools-tab-all",className:"cursor-pointer px-4 text-xs font-bold",children:"All"}),(0,b.jsx)(e.TabsTrigger,{value:"ide","data-testid":"tools-tab-ide",className:"cursor-pointer px-4 text-xs font-bold",children:"IDEs"}),(0,b.jsx)(e.TabsTrigger,{value:"cli-agent","data-testid":"tools-tab-cli-agent",className:"cursor-pointer px-4 text-xs font-bold",children:"CLI Agents"}),(0,b.jsx)(e.TabsTrigger,{value:"vcs","data-testid":"tools-tab-vcs",className:"cursor-pointer px-4 text-xs font-bold",children:"Version Control"}),(0,b.jsx)(e.TabsTrigger,{value:"terminal","data-testid":"tools-tab-terminal",className:"cursor-pointer px-4 text-xs font-bold",children:"Terminals"})]}),(0,b.jsx)(e.TabsContent,{value:j,className:"mt-6",children:0===m.length?(0,b.jsxs)("div",{"data-testid":"tools-page-empty",className:"text-muted-foreground flex flex-col items-center justify-center py-16 text-center",children:[(0,b.jsx)(d.Wrench,{className:"mb-3 h-8 w-8 opacity-20"}),(0,b.jsx)("p",{className:"text-sm",children:"No tools in this category."})]}):(0,b.jsx)("div",{"data-testid":"tools-page-grid",className:"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3",children:m.map(a=>(0,b.jsx)(D,{tool:a,onRefresh:l},a.id))})})]})]})}],92163)}];
1
+ module.exports=[92163,a=>{"use strict";var b=a.i(53083),c=a.i(11321),d=a.i(6168),e=a.i(50950),f=a.i(41305),g=a.i(90920),h=a.i(18948),i=a.i(85536),j=a.i(20901),k=a.i(96436),l=a.i(44877),m=a.i(28966),n=a.i(86139),o=a.i(82912),p=a.i(69045),q=a.i(77612),r=a.i(18288),r=r,s=a.i(82934),t=a.i(34948),u=a.i(60197),v=a.i(2);let w=(0,a.i(97624).default)("monitor",[["rect",{width:"20",height:"14",x:"2",y:"3",rx:"2",key:"48i651"}],["line",{x1:"8",x2:"16",y1:"21",y2:"21",key:"1svkeh"}],["line",{x1:"12",x2:"12",y1:"17",y2:"21",key:"vw1qmm"}]]);var x=a.i(8685),y=a.i(37545),z=a.i(24255);let A={linux:"Linux",darwin:"macOS",win32:"Windows"},B={ide:{label:"IDE",icon:w},"cli-agent":{label:"CLI Agent",icon:x.Terminal},vcs:{label:"VCS",icon:y.GitBranch},terminal:{label:"Terminal",icon:x.Terminal}};function C({status:a}){return"available"===a?(0,b.jsxs)("span",{className:"inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400",children:[(0,b.jsx)(u.Check,{className:"h-3 w-3"}),"Installed"]}):"error"===a?(0,b.jsx)("span",{className:"inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700 dark:bg-red-900/30 dark:text-red-400",children:"Error"}):(0,b.jsx)("span",{className:"inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-900/30 dark:text-amber-400",children:"Missing"})}function D({tool:a,open:d,onClose:e,onRefresh:f,autoStart:g}){let[i,m]=(0,c.useState)(!1),[n,o]=(0,c.useState)(!1),{logs:q,status:r,startInstall:s}=function(a){let[b,d]=(0,c.useState)([]),[e,f]=(0,c.useState)("idle"),[g,h]=(0,c.useState)(null),i=(0,c.useRef)(null),j=(0,c.useCallback)(()=>{i.current&&(i.current.close(),i.current=null)},[]);return(0,c.useEffect)(()=>j,[j]),{logs:b,status:e,result:g,startInstall:(0,c.useCallback)(()=>{j(),d([]),h(null),f("streaming");let b=new EventSource(`/api/tools/${a}/install/stream`);i.current=b,b.onmessage=a=>{d(b=>[...b,a.data])},b.addEventListener("done",a=>{let b=JSON.parse(a.data);h(b),f("error"===b.status?"error":"done"),j()}),b.onerror=()=>{f("error"),j()}},[a,j])}}(a.id),x=(0,c.useRef)(null),y=(0,c.useRef)(!0),E=(0,c.useRef)(!1),F="available"===a.status.status,G="error"===a.status.status,H=F&&!!a.openDirectory,I=!F&&!G&&a.autoInstall;async function J(){o(!0);try{await fetch(`/api/tools/${a.id}/launch`,{method:"POST"})}finally{o(!1)}}(0,c.useEffect)(()=>{d&&g&&I&&"idle"===r&&!E.current&&(E.current=!0,s()),d||(E.current=!1)},[d,g,I,r,s]);let K=(0,c.useCallback)(()=>{let a=x.current;a&&(y.current=a.scrollTop+a.clientHeight>=a.scrollHeight-50)},[]);(0,c.useEffect)(()=>{y.current&&x.current&&(x.current.scrollTop=x.current.scrollHeight)},[q,r]),(0,c.useEffect)(()=>{"done"===r&&f&&f()},[r,f]);let L=(0,b.jsxs)("div",{className:"flex flex-col gap-1.5 pe-6",children:[(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[a.iconUrl?(0,b.jsx)("img",{src:a.iconUrl,alt:"",width:24,height:24,className:"shrink-0"}):(0,b.jsx)(p.Package,{className:"text-muted-foreground h-6 w-6 shrink-0"}),(0,b.jsx)("h2",{className:"text-base font-bold",children:a.name}),(0,b.jsx)(C,{status:a.status.status})]}),(0,b.jsx)("div",{className:"flex items-center gap-2",children:a.tags.map(a=>{let c=B[a]??{label:a,icon:w},d=c.icon;return(0,b.jsxs)("span",{className:"text-muted-foreground/70 inline-flex items-center gap-0.5 text-[10px]",children:[(0,b.jsx)(d,{className:"h-3 w-3"}),c.label]},a)})})]});return(0,b.jsx)(z.BaseDrawer,{open:d,onClose:e,size:"md",modal:!0,title:a.name,header:L,"data-testid":"tool-detail-drawer",children:(0,b.jsxs)("div",{className:"flex flex-1 flex-col gap-4 overflow-y-auto p-4",children:[(0,b.jsx)("p",{className:"text-muted-foreground text-sm",children:a.description}),a.author||a.platforms?(0,b.jsxs)("div",{className:"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs",children:[a.author?(0,b.jsxs)("span",{className:"text-muted-foreground",children:["by"," ",a.website?(0,b.jsx)("a",{href:a.website,target:"_blank",rel:"noopener noreferrer",className:"text-foreground hover:underline",children:a.author}):(0,b.jsx)("span",{className:"text-foreground",children:a.author})]}):null,a.platforms&&a.platforms.length>0?(0,b.jsx)("span",{className:"text-muted-foreground",children:a.platforms.map(a=>A[a]??a).join(" · ")}):null]}):null,a.installCommand?(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsx)("span",{className:"text-muted-foreground text-xs font-semibold tracking-wide uppercase",children:"Install command"}),(0,b.jsxs)("div",{className:"relative rounded-md bg-zinc-900 text-zinc-100",children:[(0,b.jsx)("pre",{className:"overflow-x-auto px-3 py-2.5 pe-16 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap",children:(0,b.jsx)("code",{children:a.installCommand})}),(0,b.jsxs)(h.Button,{variant:"ghost",size:"sm",className:"absolute top-1.5 right-1.5 h-7 cursor-pointer px-2 text-zinc-400 hover:text-zinc-100",onClick:function(){a.installCommand&&navigator.clipboard.writeText(a.installCommand).then(()=>{m(!0),setTimeout(()=>m(!1),2e3)})},"aria-label":i?"Copied!":"Copy install command",children:[i?(0,b.jsx)(u.Check,{className:"h-3.5 w-3.5 text-emerald-500"}):(0,b.jsx)(t.Copy,{className:"h-3.5 w-3.5"}),(0,b.jsx)("span",{className:"ms-1 text-[10px]",children:i?"Copied!":"Copy"})]})]})]}):null,(0,b.jsxs)("div",{className:"flex items-center gap-2",children:[I?(0,b.jsxs)(h.Button,{size:"sm",onClick:s,disabled:"streaming"===r,"aria-label":`Install ${a.name}`,className:"cursor-pointer",children:["streaming"===r?(0,b.jsx)(j.LoaderCircle,{className:"me-1.5 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(l.Download,{className:"me-1.5 h-3.5 w-3.5"}),"streaming"===r?"Installing...":"Install"]}):null,H?(0,b.jsxs)(h.Button,{size:"sm",variant:"outline",onClick:()=>void J(),disabled:n,"aria-label":`Launch ${a.name}`,className:"cursor-pointer",children:[n?(0,b.jsx)(j.LoaderCircle,{className:"me-1.5 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(k.Rocket,{className:"me-1.5 h-3.5 w-3.5"}),"Launch"]}):null,a.documentationUrl?(0,b.jsx)(h.Button,{variant:"outline",size:"sm",className:"cursor-pointer",asChild:!0,children:(0,b.jsxs)("a",{href:a.documentationUrl,target:"_blank",rel:"noopener noreferrer",children:["Docs",(0,b.jsx)(v.ExternalLink,{className:"ms-1 h-3 w-3"})]})}):null]}),("streaming"===r||"done"===r||"error"===r)&&q.length>0?(0,b.jsxs)("div",{className:"flex flex-col gap-1.5",children:[(0,b.jsx)("span",{className:"text-muted-foreground text-xs font-semibold tracking-wide uppercase",children:"Install log"}),(0,b.jsxs)("div",{ref:x,onScroll:K,className:"max-h-60 overflow-auto rounded-md bg-zinc-900 p-3 font-mono text-xs leading-relaxed text-zinc-100","data-testid":"tool-install-log",children:[q.map((a,c)=>(0,b.jsx)("div",{className:"break-all whitespace-pre-wrap",children:a},c)),"done"===r?(0,b.jsx)("div",{className:"mt-2 border-t border-zinc-700 pt-2 text-emerald-400",children:"Installation complete"}):null,"error"===r?(0,b.jsx)("div",{className:"mt-2 border-t border-zinc-700 pt-2 text-red-400",children:"Installation failed"}):null]})]}):null]})})}let E={ide:"IDE","cli-agent":"CLI Agent",vcs:"VCS",terminal:"Terminal"};function F({tool:a,onRefresh:d,className:e}){let[f,g]=(0,c.useState)(!1),[t,u]=(0,c.useState)(!1),[v,w]=(0,c.useTransition)(),x="available"===a.status.status,y="error"===a.status.status,z=x&&!!a.openDirectory;return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsxs)("div",{"data-testid":"tool-card",onClick:function(){u(!1),g(!0)},className:(0,i.cn)("bg-card editorial-shadow group flex w-full cursor-pointer flex-col gap-4 rounded-xl p-5","transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md hover:ring-slate-300 dark:hover:ring-slate-600",e),children:[(0,b.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,b.jsxs)("div",{className:"flex min-w-0 items-center gap-3",children:[(0,b.jsx)("div",{className:"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-slate-100 p-2 ring-1 ring-slate-200/50 dark:bg-slate-800 dark:ring-slate-700/50",children:a.iconUrl?(0,b.jsx)("img",{src:a.iconUrl,alt:"",width:28,height:28,className:"h-full w-full"}):(0,b.jsx)(p.Package,{className:"text-muted-foreground h-full w-full"})}),(0,b.jsxs)("div",{className:"min-w-0",children:[(0,b.jsx)("h3",{"data-testid":"tool-card-name",className:"text-foreground truncate text-sm leading-tight font-bold tracking-tight",children:a.name}),a.author?(0,b.jsxs)("div",{className:"mt-1 flex items-center gap-1.5",children:[(0,b.jsx)("span",{"data-testid":"tool-card-vendor-label",className:"text-[9px] font-bold tracking-wider text-slate-400 uppercase",children:"Vendor"}),(0,b.jsx)("span",{"data-testid":"tool-card-vendor",className:"text-muted-foreground truncate text-xs font-medium",children:a.author})]}):a.tags.length>0?(0,b.jsxs)("div",{className:"mt-1 flex items-center gap-1.5",children:[(0,b.jsx)("span",{className:"text-[9px] font-bold tracking-wider text-slate-400 uppercase",children:"Tag"}),(0,b.jsx)("span",{"data-testid":"tool-card-tags",className:"text-muted-foreground truncate text-xs font-medium",children:a.tags.map(a=>E[a]??a).join(" · ")})]}):null]})]}),(0,b.jsxs)("div",{className:"flex shrink-0 items-center gap-2",children:[y&&"error"===a.status.status?(0,b.jsxs)("span",{className:"flex items-center gap-1 text-[10px] font-medium text-red-600 dark:text-red-400",title:a.status.errorMessage,children:[(0,b.jsx)(m.CircleX,{className:"h-3 w-3 shrink-0"}),"Error"]}):x?(0,b.jsxs)("span",{className:"flex items-center gap-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400",children:[(0,b.jsx)(o.CircleCheck,{className:"h-3 w-3"}),"Installed"]}):(0,b.jsxs)("span",{className:"text-muted-foreground flex items-center gap-1 text-[10px] font-medium",children:[(0,b.jsx)(n.Circle,{className:"h-3 w-3"}),"Not installed"]}),a.required?(0,b.jsx)(s.TooltipProvider,{children:(0,b.jsxs)(s.Tooltip,{children:[(0,b.jsx)(s.TooltipTrigger,{asChild:!0,children:(0,b.jsx)("span",{className:"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[9px] font-bold tracking-wider text-amber-700 uppercase dark:bg-amber-900/40 dark:text-amber-400",children:"Required"})}),(0,b.jsx)(s.TooltipContent,{side:"top",children:"This tool is required for ShipIT to function properly"})]})}):null]})]}),(0,b.jsx)("p",{"data-testid":"tool-card-summary",className:"text-muted-foreground -mt-2 line-clamp-2 text-xs leading-relaxed",children:a.summary}),(0,b.jsx)("div",{className:"mt-auto flex flex-col gap-1.5",children:x&&z?(0,b.jsxs)(h.Button,{variant:"default",onClick:function(b){b.stopPropagation(),w(async()=>{await fetch(`/api/tools/${a.id}/launch`,{method:"POST"})})},disabled:v,"aria-label":`Launch ${a.name}`,"data-testid":"tool-card-launch-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[v?(0,b.jsx)(j.LoaderCircle,{className:"me-1 h-3.5 w-3.5 animate-spin"}):(0,b.jsx)(k.Rocket,{className:"me-1 h-3.5 w-3.5"}),"Launch"]}):x||y?y?(0,b.jsxs)(h.Button,{variant:"outline",onClick:a=>{a.stopPropagation(),u(!1),g(!0)},"aria-label":`View error details for ${a.name}`,"data-testid":"tool-card-error-button",className:"h-9 w-full cursor-pointer rounded-lg border-red-300 text-xs font-bold tracking-wide text-red-600 transition-all duration-300 hover:-translate-y-0.5 hover:bg-red-50 hover:shadow-md dark:border-red-900 dark:text-red-400 dark:hover:bg-red-950/30",children:[(0,b.jsx)(r.default,{className:"me-1 h-3.5 w-3.5"}),"View Error"]}):(0,b.jsxs)(h.Button,{variant:"outline",onClick:a=>{a.stopPropagation(),u(!1),g(!0)},"aria-label":`View details for ${a.name}`,"data-testid":"tool-card-details-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[(0,b.jsx)(q.Info,{className:"me-1 h-3.5 w-3.5"}),"View Details"]}):(0,b.jsxs)(h.Button,{variant:"default",onClick:function(b){b.stopPropagation(),u(a.autoInstall),g(!0)},"aria-label":`Install ${a.name}`,"data-testid":"tool-card-install-button",className:"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md",children:[(0,b.jsx)(l.Download,{className:"me-1 h-3.5 w-3.5"}),"Install"]})})]}),(0,b.jsx)(D,{tool:a,open:f,onClose:()=>g(!1),onRefresh:d,autoStart:t})]})}let G={all:()=>!0,ide:a=>a.tags.includes("ide"),"cli-agent":a=>a.tags.includes("cli-agent"),vcs:a=>a.tags.includes("vcs"),terminal:a=>a.tags.includes("terminal")};a.s(["ToolsPageClient",0,function({tools:a,className:j}){let[k,l]=(0,c.useState)(a),[m,n]=(0,c.useState)("all"),[o,p]=(0,c.useState)(""),[q,r]=(0,c.useState)(null),s=(0,c.useCallback)(async()=>{try{let a=await fetch("/api/tools");if(a.ok){let b=await a.json();l(b)}}catch{}},[]),t=(0,c.useMemo)(()=>{let a=o.toLowerCase();return k.filter(b=>{if(!G[m](b)||q&&b.status.status!==q)return!1;if(a){let c=b.name.toLowerCase().includes(a),d=b.summary.toLowerCase().includes(a);if(!c&&!d)return!1}return!0})},[k,m,o,q]),u=k.filter(a=>"available"===a.status.status).length;return(0,b.jsxs)("div",{"data-testid":"tools-page-client",className:(0,i.cn)("space-y-8",j),children:[(0,b.jsxs)("div",{className:"space-y-1.5",children:[(0,b.jsx)("div",{className:"flex items-center gap-2",children:(0,b.jsx)("span",{className:"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase",children:"Developer Portal"})}),(0,b.jsxs)("div",{className:"flex items-baseline gap-3",children:[(0,b.jsx)("h1",{className:"text-foreground text-3xl font-black tracking-tight",children:"Tools"}),(0,b.jsxs)("span",{className:"text-muted-foreground text-sm font-medium",children:[u," of ",k.length," installed"]})]})]}),(0,b.jsxs)("div",{className:"relative",children:[(0,b.jsx)(e.Search,{className:"text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2"}),(0,b.jsx)(g.Input,{placeholder:"Search tools...",value:o,onChange:a=>p(a.target.value),className:"ps-9","data-testid":"tool-search"})]}),(0,b.jsxs)(f.Tabs,{value:m,onValueChange:a=>n(a),"data-testid":"tools-page-tabs",children:[(0,b.jsxs)(f.TabsList,{"data-editorial":"true",className:"bg-card editorial-shadow h-10 p-1",children:[(0,b.jsx)(f.TabsTrigger,{value:"all","data-testid":"tools-tab-all",className:"cursor-pointer px-4 text-xs font-bold",children:"All"}),(0,b.jsx)(f.TabsTrigger,{value:"ide","data-testid":"tools-tab-ide",className:"cursor-pointer px-4 text-xs font-bold",children:"IDEs"}),(0,b.jsx)(f.TabsTrigger,{value:"cli-agent","data-testid":"tools-tab-cli-agent",className:"cursor-pointer px-4 text-xs font-bold",children:"CLI Agents"}),(0,b.jsx)(f.TabsTrigger,{value:"vcs","data-testid":"tools-tab-vcs",className:"cursor-pointer px-4 text-xs font-bold",children:"Version Control"}),(0,b.jsx)(f.TabsTrigger,{value:"terminal","data-testid":"tools-tab-terminal",className:"cursor-pointer px-4 text-xs font-bold",children:"Terminals"})]}),(0,b.jsxs)("div",{className:"mt-4 flex flex-wrap gap-2","data-testid":"tools-status-filter",children:[(0,b.jsx)(h.Button,{variant:null===q?"default":"outline",size:"sm",onClick:()=>r(null),children:"All"}),(0,b.jsx)(h.Button,{variant:"available"===q?"default":"outline",size:"sm",onClick:()=>r("available"),children:"Installed"}),(0,b.jsx)(h.Button,{variant:"missing"===q?"default":"outline",size:"sm",onClick:()=>r("missing"),children:"Not Installed"})]}),(0,b.jsx)(f.TabsContent,{value:m,className:"mt-6",children:0===t.length?(0,b.jsxs)("div",{"data-testid":"tools-page-empty",className:"text-muted-foreground flex flex-col items-center justify-center py-16 text-center",children:[(0,b.jsx)(d.Wrench,{className:"mb-3 h-8 w-8 opacity-20"}),(0,b.jsx)("p",{className:"text-sm",children:"No tools in this category."})]}):(0,b.jsx)("div",{"data-testid":"tools-page-grid",className:"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3",children:t.map(a=>(0,b.jsx)(F,{tool:a,onRefresh:s},a.id))})})]})]})}],92163)}];
2
2
 
3
3
  //# sourceMappingURL=src_presentation_web_components_features_tools_tools-page-client_tsx_0aji.op._.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/presentation/web/hooks/use-tool-install-stream.ts","../../../../../../../src/presentation/web/components/features/tools/tool-detail-drawer.tsx","../../../../../../../src/presentation/web/components/features/tools/tool-card.tsx","../../../../../../../src/presentation/web/components/features/tools/tools-page-client.tsx","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/monitor.ts"],"sourcesContent":["'use client';\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport type { ToolInstallationStatus } from '@shipit-ai/core/domain/generated/output';\n\nexport type InstallStreamStatus = 'idle' | 'streaming' | 'done' | 'error';\n\nexport interface UseToolInstallStreamResult {\n logs: string[];\n status: InstallStreamStatus;\n result: ToolInstallationStatus | null;\n startInstall: () => void;\n}\n\nexport function useToolInstallStream(toolId: string): UseToolInstallStreamResult {\n const [logs, setLogs] = useState<string[]>([]);\n const [status, setStatus] = useState<InstallStreamStatus>('idle');\n const [result, setResult] = useState<ToolInstallationStatus | null>(null);\n const esRef = useRef<EventSource | null>(null);\n\n const cleanup = useCallback(() => {\n if (esRef.current) {\n esRef.current.close();\n esRef.current = null;\n }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => cleanup, [cleanup]);\n\n const startInstall = useCallback(() => {\n cleanup();\n setLogs([]);\n setResult(null);\n setStatus('streaming');\n\n const es = new EventSource(`/api/tools/${toolId}/install/stream`);\n esRef.current = es;\n\n es.onmessage = (event: MessageEvent) => {\n setLogs((prev) => [...prev, event.data]);\n };\n\n es.addEventListener('done', (event: MessageEvent) => {\n const installResult: ToolInstallationStatus = JSON.parse(event.data);\n setResult(installResult);\n setStatus(installResult.status === 'error' ? 'error' : 'done');\n cleanup();\n });\n\n es.onerror = () => {\n setStatus('error');\n cleanup();\n };\n }, [toolId, cleanup]);\n\n return { logs, status, result, startInstall };\n}\n","'use client';\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport {\n Copy,\n Check,\n ExternalLink,\n Download,\n Rocket,\n LoaderCircle,\n Monitor,\n Terminal,\n GitBranch,\n Package,\n} from 'lucide-react';\nimport { Button } from '@/components/ui/button';\nimport { BaseDrawer } from '@/components/common/base-drawer/base-drawer';\nimport { useToolInstallStream } from '@/hooks/use-tool-install-stream';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nconst PLATFORM_LABELS: Record<string, string> = {\n linux: 'Linux',\n darwin: 'macOS',\n win32: 'Windows',\n};\n\nexport interface ToolDetailDrawerProps {\n tool: ToolItem;\n open: boolean;\n onClose: () => void;\n onRefresh?: () => Promise<void>;\n autoStart?: boolean;\n}\n\nconst TAG_CONFIG: Record<string, { label: string; icon: typeof Monitor }> = {\n ide: { label: 'IDE', icon: Monitor },\n 'cli-agent': { label: 'CLI Agent', icon: Terminal },\n vcs: { label: 'VCS', icon: GitBranch },\n terminal: { label: 'Terminal', icon: Terminal },\n};\n\nconst AUTO_SCROLL_THRESHOLD = 50;\n\nfunction StatusBadge({ status }: { status: string }) {\n if (status === 'available') {\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400\">\n <Check className=\"h-3 w-3\" />\n Installed\n </span>\n );\n }\n if (status === 'error') {\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700 dark:bg-red-900/30 dark:text-red-400\">\n Error\n </span>\n );\n }\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-900/30 dark:text-amber-400\">\n Missing\n </span>\n );\n}\n\nexport function ToolDetailDrawer({\n tool,\n open,\n onClose,\n onRefresh,\n autoStart,\n}: ToolDetailDrawerProps) {\n const [copied, setCopied] = useState(false);\n const [isLaunching, setIsLaunching] = useState(false);\n const { logs, status, startInstall } = useToolInstallStream(tool.id);\n const logRef = useRef<HTMLDivElement>(null);\n const isAtBottomRef = useRef(true);\n const autoStartedRef = useRef(false);\n\n const isInstalled = tool.status.status === 'available';\n const isError = tool.status.status === 'error';\n const canLaunch = isInstalled && Boolean(tool.openDirectory);\n const canInstall = !isInstalled && !isError && tool.autoInstall;\n\n // Auto-start install when drawer opens with autoStart flag\n useEffect(() => {\n if (open && autoStart && canInstall && status === 'idle' && !autoStartedRef.current) {\n autoStartedRef.current = true;\n startInstall();\n }\n if (!open) {\n autoStartedRef.current = false;\n }\n }, [open, autoStart, canInstall, status, startInstall]);\n\n function handleCopy() {\n if (!tool.installCommand) return;\n void navigator.clipboard.writeText(tool.installCommand).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\n async function handleLaunch() {\n setIsLaunching(true);\n try {\n await fetch(`/api/tools/${tool.id}/launch`, { method: 'POST' });\n } finally {\n setIsLaunching(false);\n }\n }\n\n const handleScroll = useCallback(() => {\n const el = logRef.current;\n if (!el) return;\n isAtBottomRef.current =\n el.scrollTop + el.clientHeight >= el.scrollHeight - AUTO_SCROLL_THRESHOLD;\n }, []);\n\n useEffect(() => {\n if (isAtBottomRef.current && logRef.current) {\n logRef.current.scrollTop = logRef.current.scrollHeight;\n }\n }, [logs, status]);\n\n // Refresh tool status after install completes\n useEffect(() => {\n if (status === 'done' && onRefresh) {\n void onRefresh();\n }\n }, [status, onRefresh]);\n\n const header = (\n <div className=\"flex flex-col gap-1.5 pe-6\">\n <div className=\"flex items-center gap-2\">\n {tool.iconUrl ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img src={tool.iconUrl} alt=\"\" width={24} height={24} className=\"shrink-0\" />\n ) : (\n <Package className=\"text-muted-foreground h-6 w-6 shrink-0\" />\n )}\n <h2 className=\"text-base font-bold\">{tool.name}</h2>\n <StatusBadge status={tool.status.status} />\n </div>\n <div className=\"flex items-center gap-2\">\n {tool.tags.map((tag) => {\n const config = TAG_CONFIG[tag] ?? { label: tag, icon: Monitor };\n const TagIcon = config.icon;\n return (\n <span\n key={tag}\n className=\"text-muted-foreground/70 inline-flex items-center gap-0.5 text-[10px]\"\n >\n <TagIcon className=\"h-3 w-3\" />\n {config.label}\n </span>\n );\n })}\n </div>\n </div>\n );\n\n return (\n <BaseDrawer\n open={open}\n onClose={onClose}\n size=\"md\"\n modal\n title={tool.name}\n header={header}\n data-testid=\"tool-detail-drawer\"\n >\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4\">\n {/* Description */}\n <p className=\"text-muted-foreground text-sm\">{tool.description}</p>\n\n {/* Meta info row: author + platforms */}\n {tool.author || tool.platforms ? (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs\">\n {tool.author ? (\n <span className=\"text-muted-foreground\">\n by{' '}\n {tool.website ? (\n <a\n href={tool.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-foreground hover:underline\"\n >\n {tool.author}\n </a>\n ) : (\n <span className=\"text-foreground\">{tool.author}</span>\n )}\n </span>\n ) : null}\n {tool.platforms && tool.platforms.length > 0 ? (\n <span className=\"text-muted-foreground\">\n {tool.platforms.map((p) => PLATFORM_LABELS[p] ?? p).join(' · ')}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Install Command */}\n {tool.installCommand ? (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-muted-foreground text-xs font-semibold tracking-wide uppercase\">\n Install command\n </span>\n <div className=\"relative rounded-md bg-zinc-900 text-zinc-100\">\n <pre className=\"overflow-x-auto px-3 py-2.5 pe-16 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap\">\n <code>{tool.installCommand}</code>\n </pre>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-1.5 right-1.5 h-7 cursor-pointer px-2 text-zinc-400 hover:text-zinc-100\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied!' : 'Copy install command'}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" />\n )}\n <span className=\"ms-1 text-[10px]\">{copied ? 'Copied!' : 'Copy'}</span>\n </Button>\n </div>\n </div>\n ) : null}\n\n {/* Action Bar */}\n <div className=\"flex items-center gap-2\">\n {canInstall ? (\n <Button\n size=\"sm\"\n onClick={startInstall}\n disabled={status === 'streaming'}\n aria-label={`Install ${tool.name}`}\n className=\"cursor-pointer\"\n >\n {status === 'streaming' ? (\n <LoaderCircle className=\"me-1.5 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Download className=\"me-1.5 h-3.5 w-3.5\" />\n )}\n {status === 'streaming' ? 'Installing...' : 'Install'}\n </Button>\n ) : null}\n {canLaunch ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void handleLaunch()}\n disabled={isLaunching}\n aria-label={`Launch ${tool.name}`}\n className=\"cursor-pointer\"\n >\n {isLaunching ? (\n <LoaderCircle className=\"me-1.5 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Rocket className=\"me-1.5 h-3.5 w-3.5\" />\n )}\n Launch\n </Button>\n ) : null}\n {tool.documentationUrl ? (\n <Button variant=\"outline\" size=\"sm\" className=\"cursor-pointer\" asChild>\n <a href={tool.documentationUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n Docs\n <ExternalLink className=\"ms-1 h-3 w-3\" />\n </a>\n </Button>\n ) : null}\n </div>\n\n {/* Install Log */}\n {(status === 'streaming' || status === 'done' || status === 'error') && logs.length > 0 ? (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-muted-foreground text-xs font-semibold tracking-wide uppercase\">\n Install log\n </span>\n <div\n ref={logRef}\n onScroll={handleScroll}\n className=\"max-h-60 overflow-auto rounded-md bg-zinc-900 p-3 font-mono text-xs leading-relaxed text-zinc-100\"\n data-testid=\"tool-install-log\"\n >\n {logs.map((line, idx) => (\n // eslint-disable-next-line react/no-array-index-key -- logs are append-only, never reorder\n <div key={idx} className=\"break-all whitespace-pre-wrap\">\n {line}\n </div>\n ))}\n {status === 'done' ? (\n <div className=\"mt-2 border-t border-zinc-700 pt-2 text-emerald-400\">\n Installation complete\n </div>\n ) : null}\n {status === 'error' ? (\n <div className=\"mt-2 border-t border-zinc-700 pt-2 text-red-400\">\n Installation failed\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n </BaseDrawer>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport {\n LoaderCircle,\n Rocket,\n Download,\n CircleX,\n Circle,\n CircleCheck,\n Package,\n Info,\n AlertTriangle,\n} from 'lucide-react';\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\nimport { ToolDetailDrawer } from './tool-detail-drawer';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolCardProps {\n tool: ToolItem;\n onRefresh?: () => Promise<void>;\n className?: string;\n}\n\n/*\n * Tag labels for the TOOL card \"Tag\" micro-label row.\n * The tool-detail drawer keeps its own richer tag config (with icons) for its\n * detail view. This map is intentionally small — just label mapping.\n */\nconst TAG_LABELS: Record<string, string> = {\n ide: 'IDE',\n 'cli-agent': 'CLI Agent',\n vcs: 'VCS',\n terminal: 'Terminal',\n};\n\nexport function ToolCard({ tool, onRefresh, className }: ToolCardProps) {\n const [drawerOpen, setDrawerOpen] = useState(false);\n const [autoStartInstall, setAutoStartInstall] = useState(false);\n const [isPending, startTransition] = useTransition();\n\n const isInstalled = tool.status.status === 'available';\n const isError = tool.status.status === 'error';\n const canLaunch = isInstalled && Boolean(tool.openDirectory);\n\n function handleLaunch(e: React.MouseEvent) {\n e.stopPropagation();\n startTransition(async () => {\n await fetch(`/api/tools/${tool.id}/launch`, { method: 'POST' });\n });\n }\n\n function handleCardClick() {\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }\n\n function handleInstallClick(e: React.MouseEvent) {\n e.stopPropagation();\n setAutoStartInstall(tool.autoInstall);\n setDrawerOpen(true);\n }\n\n return (\n <>\n {/*\n * Tool card — editorial refresh per Stitch developer-portal pattern.\n * Layout mirrors .scratchpad/stitch/shipit-developer-portal/src/components/ToolCard.tsx:\n * - editorial-shadow ring for subtle lift\n * - icon in a ringed tile (not bare)\n * - VENDOR / ACTION micro-labels in uppercase 10px tracking-wider\n * - full-width primary action button at card footer with hover lift\n * - hover state uses ring upgrade + translate-y instead of just shadow\n * Install/launch functional logic is unchanged — only visuals.\n */}\n <div\n data-testid=\"tool-card\"\n onClick={handleCardClick}\n className={cn(\n 'bg-card editorial-shadow group flex w-full cursor-pointer flex-col gap-4 rounded-xl p-5',\n 'transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md hover:ring-slate-300 dark:hover:ring-slate-600',\n className\n )}\n >\n {/* Top row: icon tile + name/tags */}\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-slate-100 p-2 ring-1 ring-slate-200/50 dark:bg-slate-800 dark:ring-slate-700/50\">\n {tool.iconUrl ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img src={tool.iconUrl} alt=\"\" width={28} height={28} className=\"h-full w-full\" />\n ) : (\n <Package className=\"text-muted-foreground h-full w-full\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <h3\n data-testid=\"tool-card-name\"\n className=\"text-foreground truncate text-sm leading-tight font-bold tracking-tight\"\n >\n {tool.name}\n </h3>\n {/*\n * Vendor line — Stitch editorial pattern: tiny uppercase eyebrow\n * label + vendor name. Prefer tool.author (populated in every\n * tool JSON); fall back to joined tag labels only for the rare\n * case where an author is not set.\n */}\n {tool.author ? (\n <div className=\"mt-1 flex items-center gap-1.5\">\n <span\n data-testid=\"tool-card-vendor-label\"\n className=\"text-[9px] font-bold tracking-wider text-slate-400 uppercase\"\n >\n Vendor\n </span>\n <span\n data-testid=\"tool-card-vendor\"\n className=\"text-muted-foreground truncate text-xs font-medium\"\n >\n {tool.author}\n </span>\n </div>\n ) : tool.tags.length > 0 ? (\n <div className=\"mt-1 flex items-center gap-1.5\">\n <span className=\"text-[9px] font-bold tracking-wider text-slate-400 uppercase\">\n Tag\n </span>\n <span\n data-testid=\"tool-card-tags\"\n className=\"text-muted-foreground truncate text-xs font-medium\"\n >\n {tool.tags.map((tag) => TAG_LABELS[tag] ?? tag).join(' · ')}\n </span>\n </div>\n ) : null}\n </div>\n </div>\n {/* Top-right badges: status indicator + optional Required badge */}\n <div className=\"flex shrink-0 items-center gap-2\">\n {isError && tool.status.status === 'error' ? (\n <span\n className=\"flex items-center gap-1 text-[10px] font-medium text-red-600 dark:text-red-400\"\n title={tool.status.errorMessage}\n >\n <CircleX className=\"h-3 w-3 shrink-0\" />\n Error\n </span>\n ) : isInstalled ? (\n <span className=\"flex items-center gap-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400\">\n <CircleCheck className=\"h-3 w-3\" />\n Installed\n </span>\n ) : (\n <span className=\"text-muted-foreground flex items-center gap-1 text-[10px] font-medium\">\n <Circle className=\"h-3 w-3\" />\n Not installed\n </span>\n )}\n {tool.required ? (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[9px] font-bold tracking-wider text-amber-700 uppercase dark:bg-amber-900/40 dark:text-amber-400\">\n Required\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n This tool is required for ShipIT to function properly\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n\n {/* Summary */}\n <p\n data-testid=\"tool-card-summary\"\n className=\"text-muted-foreground -mt-2 line-clamp-2 text-xs leading-relaxed\"\n >\n {tool.summary}\n </p>\n\n {/* Bottom: full-width action button */}\n <div className=\"mt-auto flex flex-col gap-1.5\">\n {/*\n * Action button — full width, Stitch editorial treatment.\n * Every state renders a CTA (never an empty dashed placeholder)\n * so the card is always actionable. States:\n * - installed + launchable → primary Launch\n * - installed + not launchable (terminals/shells) → outline Details (opens drawer)\n * - not installed + healthy → primary Install\n * - error → outline Details with error icon (opens drawer to show full error)\n */}\n {isInstalled && canLaunch ? (\n <Button\n variant=\"default\"\n onClick={handleLaunch}\n disabled={isPending}\n aria-label={`Launch ${tool.name}`}\n data-testid=\"tool-card-launch-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n {isPending ? (\n <LoaderCircle className=\"me-1 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Rocket className=\"me-1 h-3.5 w-3.5\" />\n )}\n Launch\n </Button>\n ) : !isInstalled && !isError ? (\n <Button\n variant=\"default\"\n onClick={handleInstallClick}\n aria-label={`Install ${tool.name}`}\n data-testid=\"tool-card-install-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n <Download className=\"me-1 h-3.5 w-3.5\" />\n Install\n </Button>\n ) : isError ? (\n <Button\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }}\n aria-label={`View error details for ${tool.name}`}\n data-testid=\"tool-card-error-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg border-red-300 text-xs font-bold tracking-wide text-red-600 transition-all duration-300 hover:-translate-y-0.5 hover:bg-red-50 hover:shadow-md dark:border-red-900 dark:text-red-400 dark:hover:bg-red-950/30\"\n >\n <AlertTriangle className=\"me-1 h-3.5 w-3.5\" />\n View Error\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }}\n aria-label={`View details for ${tool.name}`}\n data-testid=\"tool-card-details-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n <Info className=\"me-1 h-3.5 w-3.5\" />\n View Details\n </Button>\n )}\n </div>\n </div>\n\n <ToolDetailDrawer\n tool={tool}\n open={drawerOpen}\n onClose={() => setDrawerOpen(false)}\n onRefresh={onRefresh}\n autoStart={autoStartInstall}\n />\n </>\n );\n}\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport { Wrench } from 'lucide-react';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { cn } from '@/lib/utils';\nimport { ToolCard } from './tool-card';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolsPageClientProps {\n tools: ToolItem[];\n className?: string;\n}\n\ntype TabValue = 'all' | 'ide' | 'cli-agent' | 'vcs' | 'terminal';\n\nconst TAB_FILTER: Record<TabValue, (tool: ToolItem) => boolean> = {\n all: () => true,\n ide: (tool) => tool.tags.includes('ide'),\n 'cli-agent': (tool) => tool.tags.includes('cli-agent'),\n vcs: (tool) => tool.tags.includes('vcs'),\n terminal: (tool) => tool.tags.includes('terminal'),\n};\n\nexport function ToolsPageClient({ tools: initialTools, className }: ToolsPageClientProps) {\n const [tools, setTools] = useState<ToolItem[]>(initialTools);\n const [activeTab, setActiveTab] = useState<TabValue>('all');\n\n const refreshTools = useCallback(async () => {\n try {\n const res = await fetch('/api/tools');\n if (res.ok) {\n const updated = (await res.json()) as ToolItem[];\n setTools(updated);\n }\n } catch {\n // Silently ignore refresh errors; user can re-navigate to refresh\n }\n }, []);\n\n const filtered = tools.filter(TAB_FILTER[activeTab]);\n\n const installedCount = tools.filter((t) => t.status.status === 'available').length;\n\n return (\n <div data-testid=\"tools-page-client\" className={cn('space-y-8', className)}>\n {/*\n * Editorial page header — Stitch-style typographic rhythm:\n * - tiny uppercase eyebrow label (DEVELOPER PORTAL)\n * - large bold title with tight tracking\n * - muted helper line below\n * See .scratchpad/stitch/shipit-developer-portal/src/App.tsx:161\n * for the h2 category header pattern.\n */}\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase\">\n Developer Portal\n </span>\n </div>\n <div className=\"flex items-baseline gap-3\">\n <h1 className=\"text-foreground text-3xl font-black tracking-tight\">Tools</h1>\n <span className=\"text-muted-foreground text-sm font-medium\">\n {installedCount} of {tools.length} installed\n </span>\n </div>\n </div>\n\n <Tabs\n value={activeTab}\n onValueChange={(value) => setActiveTab(value as TabValue)}\n data-testid=\"tools-page-tabs\"\n >\n {/*\n * Tabs list — Stitch editorial filter-group pattern.\n *\n * The TabsList container sits on bg-card with editorial-shadow (a lifted\n * card feel that reads against the page --color-background).\n *\n * The active-trigger styling (bg-muted + text-primary + ring lift) lives\n * in globals.css as an attribute selector on [role=\"tab\"][data-state=\"active\"]\n * instead of a conditional className here. This is the same hydration-safe\n * pattern used by SidebarNavItem's active state (globals.css selector on\n * [data-sidebar=\"menu-button\"][data-active=\"true\"]). Moving styling to CSS\n * avoids class-generation drift between the server bundle and client HMR\n * bundle during dev, which was causing a hydration mismatch on this page.\n *\n * Tab trigger classNames here are STATIC string literals so the hydrated\n * className is byte-identical between SSR and first client render.\n */}\n <TabsList data-editorial=\"true\" className=\"bg-card editorial-shadow h-10 p-1\">\n <TabsTrigger\n value=\"all\"\n data-testid=\"tools-tab-all\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n All\n </TabsTrigger>\n <TabsTrigger\n value=\"ide\"\n data-testid=\"tools-tab-ide\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n IDEs\n </TabsTrigger>\n <TabsTrigger\n value=\"cli-agent\"\n data-testid=\"tools-tab-cli-agent\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n CLI Agents\n </TabsTrigger>\n <TabsTrigger\n value=\"vcs\"\n data-testid=\"tools-tab-vcs\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n Version Control\n </TabsTrigger>\n <TabsTrigger\n value=\"terminal\"\n data-testid=\"tools-tab-terminal\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n Terminals\n </TabsTrigger>\n </TabsList>\n\n <TabsContent value={activeTab} className=\"mt-6\">\n {filtered.length === 0 ? (\n <div\n data-testid=\"tools-page-empty\"\n className=\"text-muted-foreground flex flex-col items-center justify-center py-16 text-center\"\n >\n <Wrench className=\"mb-3 h-8 w-8 opacity-20\" />\n <p className=\"text-sm\">No tools in this category.</p>\n </div>\n ) : (\n <div\n data-testid=\"tools-page-grid\"\n // Editorial density: 3 columns max so cards stay wide enough to\n // give the Stitch \"magazine\" feel. Previously xl:grid-cols-4 which\n // squeezed cards and reduced background-vs-card contrast.\n className=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\"\n >\n {filtered.map((tool) => (\n <ToolCard key={tool.id} tool={tool} onRefresh={refreshTools} />\n ))}\n </div>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '20', height: '14', x: '2', y: '3', rx: '2', key: '48i651' }],\n ['line', { x1: '8', x2: '16', y1: '21', y2: '21', key: '1svkeh' }],\n ['line', { x1: '12', x2: '12', y1: '17', y2: '21', key: 'vw1qmm' }],\n];\n\n/**\n * @component @name Monitor\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB3aWR0aD0iMjAiIGhlaWdodD0iMTQiIHg9IjIiIHk9IjMiIHJ4PSIyIiAvPgogIDxsaW5lIHgxPSI4IiB4Mj0iMTYiIHkxPSIyMSIgeTI9IjIxIiAvPgogIDxsaW5lIHgxPSIxMiIgeDI9IjEyIiB5MT0iMTciIHkyPSIyMSIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/monitor\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Monitor = createLucideIcon('monitor', __iconNode);\n\nexport default Monitor;\n"],"names":[],"mappings":"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","ignoreList":[4]}
1
+ {"version":3,"sources":["../../../../../../../src/presentation/web/components/features/tools/tools-page-client.tsx","../../../../../../../src/presentation/web/hooks/use-tool-install-stream.ts","../../../../../../../src/presentation/web/components/features/tools/tool-detail-drawer.tsx","../../../../../../../src/presentation/web/components/features/tools/tool-card.tsx","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/monitor.ts"],"sourcesContent":["'use client';\n\nimport { useState, useCallback, useMemo } from 'react';\nimport { Wrench, Search } from 'lucide-react';\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\nimport { cn } from '@/lib/utils';\nimport { ToolCard } from './tool-card';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolsPageClientProps {\n tools: ToolItem[];\n className?: string;\n}\n\ntype TabValue = 'all' | 'ide' | 'cli-agent' | 'vcs' | 'terminal';\ntype StatusFilter = 'available' | 'missing' | null;\n\nconst TAB_FILTER: Record<TabValue, (tool: ToolItem) => boolean> = {\n all: () => true,\n ide: (tool) => tool.tags.includes('ide'),\n 'cli-agent': (tool) => tool.tags.includes('cli-agent'),\n vcs: (tool) => tool.tags.includes('vcs'),\n terminal: (tool) => tool.tags.includes('terminal'),\n};\n\nexport function ToolsPageClient({ tools: initialTools, className }: ToolsPageClientProps) {\n const [tools, setTools] = useState<ToolItem[]>(initialTools);\n const [activeTab, setActiveTab] = useState<TabValue>('all');\n const [searchQuery, setSearchQuery] = useState('');\n const [statusFilter, setStatusFilter] = useState<StatusFilter>(null);\n\n const refreshTools = useCallback(async () => {\n try {\n const res = await fetch('/api/tools');\n if (res.ok) {\n const updated = (await res.json()) as ToolItem[];\n setTools(updated);\n }\n } catch {\n // Silently ignore refresh errors; user can re-navigate to refresh\n }\n }, []);\n\n const filtered = useMemo(() => {\n const query = searchQuery.toLowerCase();\n return tools.filter((tool) => {\n if (!TAB_FILTER[activeTab](tool)) return false;\n if (statusFilter && tool.status.status !== statusFilter) return false;\n if (query) {\n const matchesName = tool.name.toLowerCase().includes(query);\n const matchesSummary = tool.summary.toLowerCase().includes(query);\n if (!matchesName && !matchesSummary) return false;\n }\n return true;\n });\n }, [tools, activeTab, searchQuery, statusFilter]);\n\n const installedCount = tools.filter((t) => t.status.status === 'available').length;\n\n return (\n <div data-testid=\"tools-page-client\" className={cn('space-y-8', className)}>\n {/*\n * Editorial page header — Stitch-style typographic rhythm:\n * - tiny uppercase eyebrow label (DEVELOPER PORTAL)\n * - large bold title with tight tracking\n * - muted helper line below\n * See .scratchpad/stitch/shipit-developer-portal/src/App.tsx:161\n * for the h2 category header pattern.\n */}\n <div className=\"space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase\">\n Developer Portal\n </span>\n </div>\n <div className=\"flex items-baseline gap-3\">\n <h1 className=\"text-foreground text-3xl font-black tracking-tight\">Tools</h1>\n <span className=\"text-muted-foreground text-sm font-medium\">\n {installedCount} of {tools.length} installed\n </span>\n </div>\n </div>\n\n {/* Search */}\n <div className=\"relative\">\n <Search className=\"text-muted-foreground absolute top-1/2 left-3 size-4 -translate-y-1/2\" />\n <Input\n placeholder=\"Search tools...\"\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"ps-9\"\n data-testid=\"tool-search\"\n />\n </div>\n\n <Tabs\n value={activeTab}\n onValueChange={(value) => setActiveTab(value as TabValue)}\n data-testid=\"tools-page-tabs\"\n >\n {/*\n * Tabs list — Stitch editorial filter-group pattern.\n *\n * The TabsList container sits on bg-card with editorial-shadow (a lifted\n * card feel that reads against the page --color-background).\n *\n * The active-trigger styling (bg-muted + text-primary + ring lift) lives\n * in globals.css as an attribute selector on [role=\"tab\"][data-state=\"active\"]\n * instead of a conditional className here. This is the same hydration-safe\n * pattern used by SidebarNavItem's active state (globals.css selector on\n * [data-sidebar=\"menu-button\"][data-active=\"true\"]). Moving styling to CSS\n * avoids class-generation drift between the server bundle and client HMR\n * bundle during dev, which was causing a hydration mismatch on this page.\n *\n * Tab trigger classNames here are STATIC string literals so the hydrated\n * className is byte-identical between SSR and first client render.\n */}\n <TabsList data-editorial=\"true\" className=\"bg-card editorial-shadow h-10 p-1\">\n <TabsTrigger\n value=\"all\"\n data-testid=\"tools-tab-all\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n All\n </TabsTrigger>\n <TabsTrigger\n value=\"ide\"\n data-testid=\"tools-tab-ide\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n IDEs\n </TabsTrigger>\n <TabsTrigger\n value=\"cli-agent\"\n data-testid=\"tools-tab-cli-agent\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n CLI Agents\n </TabsTrigger>\n <TabsTrigger\n value=\"vcs\"\n data-testid=\"tools-tab-vcs\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n Version Control\n </TabsTrigger>\n <TabsTrigger\n value=\"terminal\"\n data-testid=\"tools-tab-terminal\"\n className=\"cursor-pointer px-4 text-xs font-bold\"\n >\n Terminals\n </TabsTrigger>\n </TabsList>\n\n {/* Status filter pills */}\n <div className=\"mt-4 flex flex-wrap gap-2\" data-testid=\"tools-status-filter\">\n <Button\n variant={statusFilter === null ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setStatusFilter(null)}\n >\n All\n </Button>\n <Button\n variant={statusFilter === 'available' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setStatusFilter('available')}\n >\n Installed\n </Button>\n <Button\n variant={statusFilter === 'missing' ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => setStatusFilter('missing')}\n >\n Not Installed\n </Button>\n </div>\n\n <TabsContent value={activeTab} className=\"mt-6\">\n {filtered.length === 0 ? (\n <div\n data-testid=\"tools-page-empty\"\n className=\"text-muted-foreground flex flex-col items-center justify-center py-16 text-center\"\n >\n <Wrench className=\"mb-3 h-8 w-8 opacity-20\" />\n <p className=\"text-sm\">No tools in this category.</p>\n </div>\n ) : (\n <div\n data-testid=\"tools-page-grid\"\n // Editorial density: 3 columns max so cards stay wide enough to\n // give the Stitch \"magazine\" feel. Previously xl:grid-cols-4 which\n // squeezed cards and reduced background-vs-card contrast.\n className=\"grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3\"\n >\n {filtered.map((tool) => (\n <ToolCard key={tool.id} tool={tool} onRefresh={refreshTools} />\n ))}\n </div>\n )}\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useRef, useCallback, useEffect } from 'react';\nimport type { ToolInstallationStatus } from '@shipit-ai/core/domain/generated/output';\n\nexport type InstallStreamStatus = 'idle' | 'streaming' | 'done' | 'error';\n\nexport interface UseToolInstallStreamResult {\n logs: string[];\n status: InstallStreamStatus;\n result: ToolInstallationStatus | null;\n startInstall: () => void;\n}\n\nexport function useToolInstallStream(toolId: string): UseToolInstallStreamResult {\n const [logs, setLogs] = useState<string[]>([]);\n const [status, setStatus] = useState<InstallStreamStatus>('idle');\n const [result, setResult] = useState<ToolInstallationStatus | null>(null);\n const esRef = useRef<EventSource | null>(null);\n\n const cleanup = useCallback(() => {\n if (esRef.current) {\n esRef.current.close();\n esRef.current = null;\n }\n }, []);\n\n // Cleanup on unmount\n useEffect(() => cleanup, [cleanup]);\n\n const startInstall = useCallback(() => {\n cleanup();\n setLogs([]);\n setResult(null);\n setStatus('streaming');\n\n const es = new EventSource(`/api/tools/${toolId}/install/stream`);\n esRef.current = es;\n\n es.onmessage = (event: MessageEvent) => {\n setLogs((prev) => [...prev, event.data]);\n };\n\n es.addEventListener('done', (event: MessageEvent) => {\n const installResult: ToolInstallationStatus = JSON.parse(event.data);\n setResult(installResult);\n setStatus(installResult.status === 'error' ? 'error' : 'done');\n cleanup();\n });\n\n es.onerror = () => {\n setStatus('error');\n cleanup();\n };\n }, [toolId, cleanup]);\n\n return { logs, status, result, startInstall };\n}\n","'use client';\n\nimport { useState, useRef, useEffect, useCallback } from 'react';\nimport {\n Copy,\n Check,\n ExternalLink,\n Download,\n Rocket,\n LoaderCircle,\n Monitor,\n Terminal,\n GitBranch,\n Package,\n} from 'lucide-react';\nimport { Button } from '@/components/ui/button';\nimport { BaseDrawer } from '@/components/common/base-drawer/base-drawer';\nimport { useToolInstallStream } from '@/hooks/use-tool-install-stream';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nconst PLATFORM_LABELS: Record<string, string> = {\n linux: 'Linux',\n darwin: 'macOS',\n win32: 'Windows',\n};\n\nexport interface ToolDetailDrawerProps {\n tool: ToolItem;\n open: boolean;\n onClose: () => void;\n onRefresh?: () => Promise<void>;\n autoStart?: boolean;\n}\n\nconst TAG_CONFIG: Record<string, { label: string; icon: typeof Monitor }> = {\n ide: { label: 'IDE', icon: Monitor },\n 'cli-agent': { label: 'CLI Agent', icon: Terminal },\n vcs: { label: 'VCS', icon: GitBranch },\n terminal: { label: 'Terminal', icon: Terminal },\n};\n\nconst AUTO_SCROLL_THRESHOLD = 50;\n\nfunction StatusBadge({ status }: { status: string }) {\n if (status === 'available') {\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-emerald-100 px-2 py-0.5 text-xs font-medium text-emerald-700 dark:bg-emerald-900/30 dark:text-emerald-400\">\n <Check className=\"h-3 w-3\" />\n Installed\n </span>\n );\n }\n if (status === 'error') {\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-red-100 px-2 py-0.5 text-xs font-medium text-red-700 dark:bg-red-900/30 dark:text-red-400\">\n Error\n </span>\n );\n }\n return (\n <span className=\"inline-flex items-center gap-1 rounded-full bg-amber-100 px-2 py-0.5 text-xs font-medium text-amber-700 dark:bg-amber-900/30 dark:text-amber-400\">\n Missing\n </span>\n );\n}\n\nexport function ToolDetailDrawer({\n tool,\n open,\n onClose,\n onRefresh,\n autoStart,\n}: ToolDetailDrawerProps) {\n const [copied, setCopied] = useState(false);\n const [isLaunching, setIsLaunching] = useState(false);\n const { logs, status, startInstall } = useToolInstallStream(tool.id);\n const logRef = useRef<HTMLDivElement>(null);\n const isAtBottomRef = useRef(true);\n const autoStartedRef = useRef(false);\n\n const isInstalled = tool.status.status === 'available';\n const isError = tool.status.status === 'error';\n const canLaunch = isInstalled && Boolean(tool.openDirectory);\n const canInstall = !isInstalled && !isError && tool.autoInstall;\n\n // Auto-start install when drawer opens with autoStart flag\n useEffect(() => {\n if (open && autoStart && canInstall && status === 'idle' && !autoStartedRef.current) {\n autoStartedRef.current = true;\n startInstall();\n }\n if (!open) {\n autoStartedRef.current = false;\n }\n }, [open, autoStart, canInstall, status, startInstall]);\n\n function handleCopy() {\n if (!tool.installCommand) return;\n void navigator.clipboard.writeText(tool.installCommand).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }\n\n async function handleLaunch() {\n setIsLaunching(true);\n try {\n await fetch(`/api/tools/${tool.id}/launch`, { method: 'POST' });\n } finally {\n setIsLaunching(false);\n }\n }\n\n const handleScroll = useCallback(() => {\n const el = logRef.current;\n if (!el) return;\n isAtBottomRef.current =\n el.scrollTop + el.clientHeight >= el.scrollHeight - AUTO_SCROLL_THRESHOLD;\n }, []);\n\n useEffect(() => {\n if (isAtBottomRef.current && logRef.current) {\n logRef.current.scrollTop = logRef.current.scrollHeight;\n }\n }, [logs, status]);\n\n // Refresh tool status after install completes\n useEffect(() => {\n if (status === 'done' && onRefresh) {\n void onRefresh();\n }\n }, [status, onRefresh]);\n\n const header = (\n <div className=\"flex flex-col gap-1.5 pe-6\">\n <div className=\"flex items-center gap-2\">\n {tool.iconUrl ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img src={tool.iconUrl} alt=\"\" width={24} height={24} className=\"shrink-0\" />\n ) : (\n <Package className=\"text-muted-foreground h-6 w-6 shrink-0\" />\n )}\n <h2 className=\"text-base font-bold\">{tool.name}</h2>\n <StatusBadge status={tool.status.status} />\n </div>\n <div className=\"flex items-center gap-2\">\n {tool.tags.map((tag) => {\n const config = TAG_CONFIG[tag] ?? { label: tag, icon: Monitor };\n const TagIcon = config.icon;\n return (\n <span\n key={tag}\n className=\"text-muted-foreground/70 inline-flex items-center gap-0.5 text-[10px]\"\n >\n <TagIcon className=\"h-3 w-3\" />\n {config.label}\n </span>\n );\n })}\n </div>\n </div>\n );\n\n return (\n <BaseDrawer\n open={open}\n onClose={onClose}\n size=\"md\"\n modal\n title={tool.name}\n header={header}\n data-testid=\"tool-detail-drawer\"\n >\n <div className=\"flex flex-1 flex-col gap-4 overflow-y-auto p-4\">\n {/* Description */}\n <p className=\"text-muted-foreground text-sm\">{tool.description}</p>\n\n {/* Meta info row: author + platforms */}\n {tool.author || tool.platforms ? (\n <div className=\"flex flex-wrap items-center gap-x-4 gap-y-1 text-xs\">\n {tool.author ? (\n <span className=\"text-muted-foreground\">\n by{' '}\n {tool.website ? (\n <a\n href={tool.website}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-foreground hover:underline\"\n >\n {tool.author}\n </a>\n ) : (\n <span className=\"text-foreground\">{tool.author}</span>\n )}\n </span>\n ) : null}\n {tool.platforms && tool.platforms.length > 0 ? (\n <span className=\"text-muted-foreground\">\n {tool.platforms.map((p) => PLATFORM_LABELS[p] ?? p).join(' · ')}\n </span>\n ) : null}\n </div>\n ) : null}\n\n {/* Install Command */}\n {tool.installCommand ? (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-muted-foreground text-xs font-semibold tracking-wide uppercase\">\n Install command\n </span>\n <div className=\"relative rounded-md bg-zinc-900 text-zinc-100\">\n <pre className=\"overflow-x-auto px-3 py-2.5 pe-16 font-mono text-xs leading-relaxed break-all whitespace-pre-wrap\">\n <code>{tool.installCommand}</code>\n </pre>\n <Button\n variant=\"ghost\"\n size=\"sm\"\n className=\"absolute top-1.5 right-1.5 h-7 cursor-pointer px-2 text-zinc-400 hover:text-zinc-100\"\n onClick={handleCopy}\n aria-label={copied ? 'Copied!' : 'Copy install command'}\n >\n {copied ? (\n <Check className=\"h-3.5 w-3.5 text-emerald-500\" />\n ) : (\n <Copy className=\"h-3.5 w-3.5\" />\n )}\n <span className=\"ms-1 text-[10px]\">{copied ? 'Copied!' : 'Copy'}</span>\n </Button>\n </div>\n </div>\n ) : null}\n\n {/* Action Bar */}\n <div className=\"flex items-center gap-2\">\n {canInstall ? (\n <Button\n size=\"sm\"\n onClick={startInstall}\n disabled={status === 'streaming'}\n aria-label={`Install ${tool.name}`}\n className=\"cursor-pointer\"\n >\n {status === 'streaming' ? (\n <LoaderCircle className=\"me-1.5 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Download className=\"me-1.5 h-3.5 w-3.5\" />\n )}\n {status === 'streaming' ? 'Installing...' : 'Install'}\n </Button>\n ) : null}\n {canLaunch ? (\n <Button\n size=\"sm\"\n variant=\"outline\"\n onClick={() => void handleLaunch()}\n disabled={isLaunching}\n aria-label={`Launch ${tool.name}`}\n className=\"cursor-pointer\"\n >\n {isLaunching ? (\n <LoaderCircle className=\"me-1.5 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Rocket className=\"me-1.5 h-3.5 w-3.5\" />\n )}\n Launch\n </Button>\n ) : null}\n {tool.documentationUrl ? (\n <Button variant=\"outline\" size=\"sm\" className=\"cursor-pointer\" asChild>\n <a href={tool.documentationUrl} target=\"_blank\" rel=\"noopener noreferrer\">\n Docs\n <ExternalLink className=\"ms-1 h-3 w-3\" />\n </a>\n </Button>\n ) : null}\n </div>\n\n {/* Install Log */}\n {(status === 'streaming' || status === 'done' || status === 'error') && logs.length > 0 ? (\n <div className=\"flex flex-col gap-1.5\">\n <span className=\"text-muted-foreground text-xs font-semibold tracking-wide uppercase\">\n Install log\n </span>\n <div\n ref={logRef}\n onScroll={handleScroll}\n className=\"max-h-60 overflow-auto rounded-md bg-zinc-900 p-3 font-mono text-xs leading-relaxed text-zinc-100\"\n data-testid=\"tool-install-log\"\n >\n {logs.map((line, idx) => (\n // eslint-disable-next-line react/no-array-index-key -- logs are append-only, never reorder\n <div key={idx} className=\"break-all whitespace-pre-wrap\">\n {line}\n </div>\n ))}\n {status === 'done' ? (\n <div className=\"mt-2 border-t border-zinc-700 pt-2 text-emerald-400\">\n Installation complete\n </div>\n ) : null}\n {status === 'error' ? (\n <div className=\"mt-2 border-t border-zinc-700 pt-2 text-red-400\">\n Installation failed\n </div>\n ) : null}\n </div>\n </div>\n ) : null}\n </div>\n </BaseDrawer>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport {\n LoaderCircle,\n Rocket,\n Download,\n CircleX,\n Circle,\n CircleCheck,\n Package,\n Info,\n AlertTriangle,\n} from 'lucide-react';\nimport { Button } from '@/components/ui/button';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';\nimport { cn } from '@/lib/utils';\nimport { ToolDetailDrawer } from './tool-detail-drawer';\nimport type { ToolItem } from '@shipit-ai/core/application/use-cases/tools/list-tools.use-case';\n\nexport interface ToolCardProps {\n tool: ToolItem;\n onRefresh?: () => Promise<void>;\n className?: string;\n}\n\n/*\n * Tag labels for the TOOL card \"Tag\" micro-label row.\n * The tool-detail drawer keeps its own richer tag config (with icons) for its\n * detail view. This map is intentionally small — just label mapping.\n */\nconst TAG_LABELS: Record<string, string> = {\n ide: 'IDE',\n 'cli-agent': 'CLI Agent',\n vcs: 'VCS',\n terminal: 'Terminal',\n};\n\nexport function ToolCard({ tool, onRefresh, className }: ToolCardProps) {\n const [drawerOpen, setDrawerOpen] = useState(false);\n const [autoStartInstall, setAutoStartInstall] = useState(false);\n const [isPending, startTransition] = useTransition();\n\n const isInstalled = tool.status.status === 'available';\n const isError = tool.status.status === 'error';\n const canLaunch = isInstalled && Boolean(tool.openDirectory);\n\n function handleLaunch(e: React.MouseEvent) {\n e.stopPropagation();\n startTransition(async () => {\n await fetch(`/api/tools/${tool.id}/launch`, { method: 'POST' });\n });\n }\n\n function handleCardClick() {\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }\n\n function handleInstallClick(e: React.MouseEvent) {\n e.stopPropagation();\n setAutoStartInstall(tool.autoInstall);\n setDrawerOpen(true);\n }\n\n return (\n <>\n {/*\n * Tool card — editorial refresh per Stitch developer-portal pattern.\n * Layout mirrors .scratchpad/stitch/shipit-developer-portal/src/components/ToolCard.tsx:\n * - editorial-shadow ring for subtle lift\n * - icon in a ringed tile (not bare)\n * - VENDOR / ACTION micro-labels in uppercase 10px tracking-wider\n * - full-width primary action button at card footer with hover lift\n * - hover state uses ring upgrade + translate-y instead of just shadow\n * Install/launch functional logic is unchanged — only visuals.\n */}\n <div\n data-testid=\"tool-card\"\n onClick={handleCardClick}\n className={cn(\n 'bg-card editorial-shadow group flex w-full cursor-pointer flex-col gap-4 rounded-xl p-5',\n 'transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md hover:ring-slate-300 dark:hover:ring-slate-600',\n className\n )}\n >\n {/* Top row: icon tile + name/tags */}\n <div className=\"flex items-start justify-between gap-3\">\n <div className=\"flex min-w-0 items-center gap-3\">\n <div className=\"flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-slate-100 p-2 ring-1 ring-slate-200/50 dark:bg-slate-800 dark:ring-slate-700/50\">\n {tool.iconUrl ? (\n /* eslint-disable-next-line @next/next/no-img-element */\n <img src={tool.iconUrl} alt=\"\" width={28} height={28} className=\"h-full w-full\" />\n ) : (\n <Package className=\"text-muted-foreground h-full w-full\" />\n )}\n </div>\n <div className=\"min-w-0\">\n <h3\n data-testid=\"tool-card-name\"\n className=\"text-foreground truncate text-sm leading-tight font-bold tracking-tight\"\n >\n {tool.name}\n </h3>\n {/*\n * Vendor line — Stitch editorial pattern: tiny uppercase eyebrow\n * label + vendor name. Prefer tool.author (populated in every\n * tool JSON); fall back to joined tag labels only for the rare\n * case where an author is not set.\n */}\n {tool.author ? (\n <div className=\"mt-1 flex items-center gap-1.5\">\n <span\n data-testid=\"tool-card-vendor-label\"\n className=\"text-[9px] font-bold tracking-wider text-slate-400 uppercase\"\n >\n Vendor\n </span>\n <span\n data-testid=\"tool-card-vendor\"\n className=\"text-muted-foreground truncate text-xs font-medium\"\n >\n {tool.author}\n </span>\n </div>\n ) : tool.tags.length > 0 ? (\n <div className=\"mt-1 flex items-center gap-1.5\">\n <span className=\"text-[9px] font-bold tracking-wider text-slate-400 uppercase\">\n Tag\n </span>\n <span\n data-testid=\"tool-card-tags\"\n className=\"text-muted-foreground truncate text-xs font-medium\"\n >\n {tool.tags.map((tag) => TAG_LABELS[tag] ?? tag).join(' · ')}\n </span>\n </div>\n ) : null}\n </div>\n </div>\n {/* Top-right badges: status indicator + optional Required badge */}\n <div className=\"flex shrink-0 items-center gap-2\">\n {isError && tool.status.status === 'error' ? (\n <span\n className=\"flex items-center gap-1 text-[10px] font-medium text-red-600 dark:text-red-400\"\n title={tool.status.errorMessage}\n >\n <CircleX className=\"h-3 w-3 shrink-0\" />\n Error\n </span>\n ) : isInstalled ? (\n <span className=\"flex items-center gap-1 text-[10px] font-medium text-emerald-600 dark:text-emerald-400\">\n <CircleCheck className=\"h-3 w-3\" />\n Installed\n </span>\n ) : (\n <span className=\"text-muted-foreground flex items-center gap-1 text-[10px] font-medium\">\n <Circle className=\"h-3 w-3\" />\n Not installed\n </span>\n )}\n {tool.required ? (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"shrink-0 rounded-full bg-amber-100 px-2 py-0.5 text-[9px] font-bold tracking-wider text-amber-700 uppercase dark:bg-amber-900/40 dark:text-amber-400\">\n Required\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"top\">\n This tool is required for ShipIT to function properly\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n ) : null}\n </div>\n </div>\n\n {/* Summary */}\n <p\n data-testid=\"tool-card-summary\"\n className=\"text-muted-foreground -mt-2 line-clamp-2 text-xs leading-relaxed\"\n >\n {tool.summary}\n </p>\n\n {/* Bottom: full-width action button */}\n <div className=\"mt-auto flex flex-col gap-1.5\">\n {/*\n * Action button — full width, Stitch editorial treatment.\n * Every state renders a CTA (never an empty dashed placeholder)\n * so the card is always actionable. States:\n * - installed + launchable → primary Launch\n * - installed + not launchable (terminals/shells) → outline Details (opens drawer)\n * - not installed + healthy → primary Install\n * - error → outline Details with error icon (opens drawer to show full error)\n */}\n {isInstalled && canLaunch ? (\n <Button\n variant=\"default\"\n onClick={handleLaunch}\n disabled={isPending}\n aria-label={`Launch ${tool.name}`}\n data-testid=\"tool-card-launch-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n {isPending ? (\n <LoaderCircle className=\"me-1 h-3.5 w-3.5 animate-spin\" />\n ) : (\n <Rocket className=\"me-1 h-3.5 w-3.5\" />\n )}\n Launch\n </Button>\n ) : !isInstalled && !isError ? (\n <Button\n variant=\"default\"\n onClick={handleInstallClick}\n aria-label={`Install ${tool.name}`}\n data-testid=\"tool-card-install-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n <Download className=\"me-1 h-3.5 w-3.5\" />\n Install\n </Button>\n ) : isError ? (\n <Button\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }}\n aria-label={`View error details for ${tool.name}`}\n data-testid=\"tool-card-error-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg border-red-300 text-xs font-bold tracking-wide text-red-600 transition-all duration-300 hover:-translate-y-0.5 hover:bg-red-50 hover:shadow-md dark:border-red-900 dark:text-red-400 dark:hover:bg-red-950/30\"\n >\n <AlertTriangle className=\"me-1 h-3.5 w-3.5\" />\n View Error\n </Button>\n ) : (\n <Button\n variant=\"outline\"\n onClick={(e) => {\n e.stopPropagation();\n setAutoStartInstall(false);\n setDrawerOpen(true);\n }}\n aria-label={`View details for ${tool.name}`}\n data-testid=\"tool-card-details-button\"\n className=\"h-9 w-full cursor-pointer rounded-lg text-xs font-bold tracking-wide transition-all duration-300 hover:-translate-y-0.5 hover:shadow-md\"\n >\n <Info className=\"me-1 h-3.5 w-3.5\" />\n View Details\n </Button>\n )}\n </div>\n </div>\n\n <ToolDetailDrawer\n tool={tool}\n open={drawerOpen}\n onClose={() => setDrawerOpen(false)}\n onRefresh={onRefresh}\n autoStart={autoStartInstall}\n />\n </>\n );\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '20', height: '14', x: '2', y: '3', rx: '2', key: '48i651' }],\n ['line', { x1: '8', x2: '16', y1: '21', y2: '21', key: '1svkeh' }],\n ['line', { x1: '12', x2: '12', y1: '17', y2: '21', key: 'vw1qmm' }],\n];\n\n/**\n * @component @name Monitor\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview ![img](data:image/svg+xml;base64,PHN2ZyAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogIHdpZHRoPSIyNCIKICBoZWlnaHQ9IjI0IgogIHZpZXdCb3g9IjAgMCAyNCAyNCIKICBmaWxsPSJub25lIgogIHN0cm9rZT0iIzAwMCIgc3R5bGU9ImJhY2tncm91bmQtY29sb3I6ICNmZmY7IGJvcmRlci1yYWRpdXM6IDJweCIKICBzdHJva2Utd2lkdGg9IjIiCiAgc3Ryb2tlLWxpbmVjYXA9InJvdW5kIgogIHN0cm9rZS1saW5lam9pbj0icm91bmQiCj4KICA8cmVjdCB3aWR0aD0iMjAiIGhlaWdodD0iMTQiIHg9IjIiIHk9IjMiIHJ4PSIyIiAvPgogIDxsaW5lIHgxPSI4IiB4Mj0iMTYiIHkxPSIyMSIgeTI9IjIxIiAvPgogIDxsaW5lIHgxPSIxMiIgeDI9IjEyIiB5MT0iMTciIHkyPSIyMSIgLz4KPC9zdmc+Cg==) - https://lucide.dev/icons/monitor\n * @see https://lucide.dev/guide/packages/lucide-react - Documentation\n *\n * @param {Object} props - Lucide icons props and any valid SVG attribute\n * @returns {JSX.Element} JSX Element\n *\n */\nconst Monitor = createLucideIcon('monitor', __iconNode);\n\nexport default Monitor;\n"],"names":[],"mappings":"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","ignoreList":[4]}
@@ -7,9 +7,9 @@ globalThis.__BUILD_MANIFEST = {
7
7
  "static/chunks/03~yq9q893hmn.js"
8
8
  ],
9
9
  "lowPriorityFiles": [
10
- "static/SNdaKJ9fpre8tUMRe1jlA/_buildManifest.js",
11
- "static/SNdaKJ9fpre8tUMRe1jlA/_ssgManifest.js",
12
- "static/SNdaKJ9fpre8tUMRe1jlA/_clientMiddlewareManifest.js"
10
+ "static/GeXKcODhEHBnDRVLMaAnW/_buildManifest.js",
11
+ "static/GeXKcODhEHBnDRVLMaAnW/_ssgManifest.js",
12
+ "static/GeXKcODhEHBnDRVLMaAnW/_clientMiddlewareManifest.js"
13
13
  ],
14
14
  "rootMainFiles": [
15
15
  "static/chunks/16~vw9ce~pa0c.js",
@@ -1 +1 @@
1
- self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/adopt/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/chat/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/create/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/repository/[repositoryId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/chat/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/create/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/feature/[featureId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/feature/[featureId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/repository/[repositoryId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/repository/[repositoryId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/_not-found/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/settings/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/skills/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/tools/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/version/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
1
+ self.__NEXT_FONT_MANIFEST="{\n \"app\": {\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/adopt/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/chat/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/create/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/feature/[featureId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/@drawer/repository/[repositoryId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/chat/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/create/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/feature/[featureId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/feature/[featureId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/repository/[repositoryId]/[tab]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/(dashboard)/repository/[repositoryId]/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/_not-found/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/plugins/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/settings/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/skills/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/tools/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ],\n \"[project]/src/presentation/web/app/version/page\": [\n \"static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2\"\n ]\n },\n \"appUsingSizeAdjust\": true,\n \"pages\": {},\n \"pagesUsingSizeAdjust\": false\n}"
@@ -45,6 +45,9 @@
45
45
  "[project]/src/presentation/web/app/_not-found/page": [
46
46
  "static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2"
47
47
  ],
48
+ "[project]/src/presentation/web/app/plugins/page": [
49
+ "static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2"
50
+ ],
48
51
  "[project]/src/presentation/web/app/settings/page": [
49
52
  "static/media/83afe278b6a6bb3c-s.p.0q-301v4kxxnr.woff2"
50
53
  ],
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/16~vw9ce~pa0c.js"/><script src="/_next/static/chunks/0xrbak95onw-v.js" async=""></script><script src="/_next/static/chunks/09_oo_kc.j.df.js" async=""></script><script src="/_next/static/chunks/17op3~2jku4g7.js" async=""></script><script src="/_next/static/chunks/0rfd5i_uq~-36.js" async=""></script><script src="/_next/static/chunks/turbopack-0wsav6to5abtk.js" async=""></script><script src="/_next/static/chunks/0ia0v054b4ci_.js" async=""></script><script src="/_next/static/chunks/0rcp01fimyysj.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/16~vw9ce~pa0c.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[10206,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n3:I[20397,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n4:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"ViewportBoundary\"]\na:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"MetadataBoundary\"]\nc:I[98295,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"SNdaKJ9fpre8tUMRe1jlA\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/16~vw9ce~pa0c.js"/><script src="/_next/static/chunks/0xrbak95onw-v.js" async=""></script><script src="/_next/static/chunks/09_oo_kc.j.df.js" async=""></script><script src="/_next/static/chunks/17op3~2jku4g7.js" async=""></script><script src="/_next/static/chunks/0rfd5i_uq~-36.js" async=""></script><script src="/_next/static/chunks/turbopack-0wsav6to5abtk.js" async=""></script><script src="/_next/static/chunks/0ia0v054b4ci_.js" async=""></script><script src="/_next/static/chunks/0rcp01fimyysj.js" async=""></script><meta name="next-size-adjust" content=""/><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/03~yq9q893hmn.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/16~vw9ce~pa0c.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[10206,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n3:I[20397,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n4:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"ViewportBoundary\"]\na:I[91336,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"MetadataBoundary\"]\nc:I[98295,[\"/_next/static/chunks/0ia0v054b4ci_.js\",\"/_next/static/chunks/0rcp01fimyysj.js\"],\"default\"]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],[\"$\",\"meta\",null,{\"name\":\"next-size-adjust\",\"content\":\"\"}]]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"GeXKcODhEHBnDRVLMaAnW\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>