@shipit-ai/cli 1.173.2 → 1.174.1
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.
- package/dist/packages/core/src/infrastructure/services/mcp-server-browser/mcp-server-browser.service.js +46 -1
- package/dist/packages/core/src/infrastructure/services/tool-installer/tools/codex-cli.json +1 -1
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-connect-instructions.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-connect-instructions.js +1 -3
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-card.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-card.js +2 -8
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-detail-drawer.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-detail-drawer.js +5 -4
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-icon.d.ts +45 -0
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-icon.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-server-icon.js +138 -0
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-servers-page-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/mcp-servers/mcp-servers-page-client.js +7 -6
- package/dist/src/presentation/web/components/features/mcp-servers/vendor-brand-icons.d.ts +29 -0
- package/dist/src/presentation/web/components/features/mcp-servers/vendor-brand-icons.d.ts.map +1 -0
- package/dist/src/presentation/web/components/features/mcp-servers/vendor-brand-icons.js +25 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/web/.next/BUILD_ID +1 -1
- package/web/.next/build-manifest.json +3 -3
- package/web/.next/fallback-build-manifest.json +3 -3
- package/web/.next/prerender-manifest.json +3 -3
- package/web/.next/required-server-files.js +2 -2
- package/web/.next/required-server-files.json +2 -2
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page/server-reference-manifest.json +29 -29
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/adopt/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/@drawer/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/chat/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/chat/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/chat/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +31 -31
- package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +37 -37
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +27 -27
- package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/[tab]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +28 -28
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
- package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/_global-error.html +1 -1
- package/web/.next/server/app/_global-error.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/web/.next/server/app/_not-found/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/_not-found/page.js.nft.json +1 -1
- package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/api/attachments/preview/route.js.nft.json +1 -1
- package/web/.next/server/app/api/dialog/pick-files/route.js.nft.json +1 -1
- package/web/.next/server/app/api/evidence/route.js.nft.json +1 -1
- package/web/.next/server/app/api/graph-data/route.js.nft.json +1 -1
- package/web/.next/server/app/api/interactive/chat/[featureId]/messages/route.js.nft.json +1 -1
- package/web/.next/server/app/mcp-servers/page/server-reference-manifest.json +13 -13
- package/web/.next/server/app/mcp-servers/page.js.nft.json +1 -1
- package/web/.next/server/app/mcp-servers/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/plugins/page/server-reference-manifest.json +15 -15
- package/web/.next/server/app/plugins/page.js.nft.json +1 -1
- package/web/.next/server/app/plugins/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/settings/page/server-reference-manifest.json +12 -12
- package/web/.next/server/app/settings/page.js.nft.json +1 -1
- package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/skills/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/skills/page.js.nft.json +1 -1
- package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/tools/page/server-reference-manifest.json +11 -11
- package/web/.next/server/app/tools/page.js.nft.json +1 -1
- package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
- package/web/.next/server/app/version/page/server-reference-manifest.json +6 -6
- package/web/.next/server/app/version/page.js.nft.json +1 -1
- package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
- package/web/.next/server/chunks/[root-of-the-server]__0tb~wwk._.js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_create-drawer-client_tsx_0g70fc5._.js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js +2 -2
- package/web/.next/server/chunks/ssr/0j.8_web_components_common_control-center-drawer_feature-drawer-client_tsx_104cna.._.js.map +1 -1
- package/web/.next/server/chunks/ssr/0j.8_web_components_features_mcp-servers_mcp-servers-page-client_tsx_0dda8ih._.js +2 -2
- package/web/.next/server/chunks/ssr/0j.8_web_components_features_mcp-servers_mcp-servers-page-client_tsx_0dda8ih._.js.map +1 -1
- package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js +1 -1
- package/web/.next/server/chunks/ssr/0ukq_presentation_web_components_features_settings_settings-page-client_tsx_0j1uius._.js.map +1 -1
- package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js +1 -1
- package/web/.next/server/chunks/ssr/11y9_components_common_control-center-drawer_repository-drawer-client_tsx_09z.znp._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0.5ojmt._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0.5ojmt._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__05_qc0n._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0ge~xny._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0ge~xny._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0mwao26._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0mwao26._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0qda~yi._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0qda~yi._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0rv1gci._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0tq2syh._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0t~u8sd._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0t~u8sd._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__10tll_l._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__10tll_l._.js.map +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__12j29w-._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0~d-l61._.js → _019y939._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_0~d-l61._.js.map → _019y939._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/{_09b301s._.js → _01jtwj3._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_09b301s._.js.map → _01jtwj3._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_01sesw0._.js +1 -1
- package/web/.next/server/chunks/ssr/_01sesw0._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_069y.js._.js +2 -2
- package/web/.next/server/chunks/ssr/_069y.js._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_1031n_-._.js → _083k45~._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_1031n_-._.js.map → _083k45~._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_0__4si~._.js +1 -1
- package/web/.next/server/chunks/ssr/_0__4si~._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0_m17kl._.js +1 -1
- package/web/.next/server/chunks/ssr/_0_m17kl._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0d4miu.._.js +1 -1
- package/web/.next/server/chunks/ssr/_0d4miu.._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0e8ern9._.js +1 -1
- package/web/.next/server/chunks/ssr/_0e8ern9._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0fswe4r._.js +1 -1
- package/web/.next/server/chunks/ssr/_0p3~u8u._.js +2 -2
- package/web/.next/server/chunks/ssr/_0p3~u8u._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_0u09c2.._.js → _0pwlot2._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_0u09c2.._.js.map → _0pwlot2._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_0r.3n~3._.js +1 -1
- package/web/.next/server/chunks/ssr/_0r.3n~3._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0t59q8r._.js +1 -1
- package/web/.next/server/chunks/ssr/_0t59q8r._.js.map +1 -1
- package/web/.next/server/chunks/ssr/{_096x3u~._.js → _0vq0c0x._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_096x3u~._.js.map → _0vq0c0x._.js.map} +1 -1
- package/web/.next/server/chunks/ssr/_0vyfc4b._.js +1 -1
- package/web/.next/server/chunks/ssr/_0vyfc4b._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0w-_hww._.js +1 -1
- package/web/.next/server/chunks/ssr/_0w-_hww._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0zk-h5w._.js +1 -1
- package/web/.next/server/chunks/ssr/_0zk-h5w._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0~7lwu_._.js +1 -1
- package/web/.next/server/chunks/ssr/_0~7lwu_._.js.map +1 -1
- package/web/.next/server/chunks/ssr/_0~g5-.e._.js +3 -0
- package/web/.next/server/chunks/ssr/_0~g5-.e._.js.map +1 -0
- package/web/.next/server/chunks/ssr/_1161g9x._.js +1 -1
- package/web/.next/server/chunks/ssr/_1161g9x._.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_mcp-servers_page_actions_0d.r4q..js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_mcp-servers_page_actions_0d.r4q..js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_plugins_page_actions_0rdndum.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_plugins_page_actions_0rdndum.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_05m2q~u.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_0.6zk.t.js.map +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_approve-feature_ts_0pjb_re._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_app_actions_open-ide_ts_0w2wqvu._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js +1 -1
- package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_0l3oxx9._.js.map +1 -1
- package/web/.next/server/middleware-build-manifest.js +3 -3
- package/web/.next/server/pages/500.html +1 -1
- package/web/.next/server/server-reference-manifest.js +1 -1
- package/web/.next/server/server-reference-manifest.json +57 -57
- package/web/.next/static/chunks/0-sn8_v5.1tfa.js +1 -0
- package/web/.next/static/chunks/{10p0lo4adb2~5.js → 0.3drm0s7ymfs.js} +1 -1
- package/web/.next/static/chunks/{0t~1ohqb2m7ma.js → 02zfrf7ikyp29.js} +1 -1
- package/web/.next/static/chunks/{050mn~oci41h6.js → 03hqf_4_4qwm3.js} +3 -3
- package/web/.next/static/chunks/{0xee.1sl6c~24.js → 06mib0h4gcgk5.js} +1 -1
- package/web/.next/static/chunks/{0ul697ie_gsw9.js → 0_9e92fdo3l-q.js} +1 -1
- package/web/.next/static/chunks/0a~-dbzk6tkpw.css +1 -0
- package/web/.next/static/chunks/0e_8lon2juca..js +8 -0
- package/web/.next/static/chunks/{159n33nvplqug.js → 0egftcm_dm9y9.js} +1 -1
- package/web/.next/static/chunks/{06_a861w0tkp6.js → 0fr8fr~b7xh6n.js} +1 -1
- package/web/.next/static/chunks/{0~9hrc9~63dvr.js → 0n_1ni2m~6utg.js} +1 -1
- package/web/.next/static/chunks/{08w-qt8wfe5u..js → 0q1wkqn0g7-pm.js} +1 -1
- package/web/.next/static/chunks/{0mekjif_lg0-r.js → 0vi.ovr0j.l39.js} +1 -1
- package/web/.next/static/chunks/0wd.i4f822qoa.js +1 -0
- package/web/.next/static/chunks/{07kpqi8hle98h.js → 0xebtxnu~n6~7.js} +1 -1
- package/web/.next/static/chunks/{0pb77veci.7gd.js → 0y_.-wq2.g0em.js} +1 -1
- package/web/.next/static/chunks/{10j-adknfho63.js → 10rtagfoabp3b.js} +1 -1
- package/web/.next/static/chunks/18alqn4hhlmew.js +1 -0
- package/web/public/icons/tools/openai.svg +1 -0
- package/web/.next/server/chunks/ssr/_0vm01xk._.js +0 -3
- package/web/.next/server/chunks/ssr/_0vm01xk._.js.map +0 -1
- package/web/.next/static/chunks/0h2nh2s2b3ma2.css +0 -1
- package/web/.next/static/chunks/0inayq2zzadja.js +0 -1
- package/web/.next/static/chunks/0whqmoyf3zd67.js +0 -1
- package/web/.next/static/chunks/14ixmk5pm1-rc.js +0 -8
- package/web/.next/static/chunks/167z9~gq-q~oy.js +0 -1
- /package/web/.next/static/{q4u94V1z_KGlqS1uxSgT2 → 0k1x5A5Hmt_Py4vQ0o-XR}/_buildManifest.js +0 -0
- /package/web/.next/static/{q4u94V1z_KGlqS1uxSgT2 → 0k1x5A5Hmt_Py4vQ0o-XR}/_clientMiddlewareManifest.js +0 -0
- /package/web/.next/static/{q4u94V1z_KGlqS1uxSgT2 → 0k1x5A5Hmt_Py4vQ0o-XR}/_ssgManifest.js +0 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../../../../src/presentation/web/components/features/settings/settings-page-client.tsx","../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx","../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.tsx","../../../../../../../src/presentation/web/app/actions/data%3A86d2da%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/features/settings/environment-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/workflow-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/ci-settings-section.tsx","../../../../../../../node_modules/.pnpm/%40radix-ui%2Breact-slider%401.3.6_%40types%2Breact-dom%4019.2.3_%40types%2Breact%4019.2.14__%40types%2Breact_c6a3fae91eb6750caf661d179680cb4a/node_modules/%40radix-ui/react-slider/dist/index.mjs","../../../../../../../src/presentation/web/components/ui/slider.tsx","../../../../../../../src/presentation/web/components/features/settings/timeout-slider.tsx","../../../../../../../src/presentation/web/components/features/settings/stage-timeouts-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/notification-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/feature-flags-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/interactive-agent-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/fab-layout-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/database-settings-section.tsx","../../../../../../../src/presentation/web/app/actions/data%3A97b8ec%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/features/settings/litellm-proxy-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/litellm-proxy-routing-section.tsx","../../../../../../../src/presentation/web/components/common/editor-type-icons.tsx","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/route.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/database.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/layout-grid.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/layout-list.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/flag.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/bell.ts","../../../../../../../node_modules/.pnpm/%40radix-ui%2Breact-slider%401.3.6_%40types%2Breact-dom%4019.2.3_%40types%2Breact%4019.2.14__%40types%2Breact_c6a3fae91eb6750caf661d179680cb4a/node_modules/%40radix-ui/react-slider/src/slider.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect } from 'react';\nimport {\n Bot,\n Terminal,\n GitBranch,\n Activity,\n Bell,\n Flag,\n Database,\n Timer,\n MessageSquare,\n LayoutGrid,\n LayoutList,\n Server,\n} from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport { AgentSettingsSection } from './agent-settings-section';\nimport { EnvironmentSettingsSection } from './environment-settings-section';\nimport { WorkflowSettingsSection } from './workflow-settings-section';\nimport { CiSettingsSection } from './ci-settings-section';\nimport { StageTimeoutsSettingsSection } from './stage-timeouts-settings-section';\nimport { NotificationSettingsSection } from './notification-settings-section';\nimport { FeatureFlagsSettingsSection } from './feature-flags-settings-section';\nimport { InteractiveAgentSettingsSection } from './interactive-agent-settings-section';\nimport { FabLayoutSettingsSection } from './fab-layout-settings-section';\nimport { DatabaseSettingsSection } from './database-settings-section';\nimport { LiteLLMProxySettingsSection } from './litellm-proxy-settings-section';\nimport { LiteLLMProxyRoutingSection } from './litellm-proxy-routing-section';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport type { AvailableTerminal } from '@/app/actions/get-available-terminals';\nimport type { AvailableEditor } from '@/app/actions/get-available-editors';\nimport type { AvailableShell } from '@/app/actions/get-available-shells';\n\nconst SECTIONS = [\n { id: 'agent', labelKey: 'settings.sections.agent', icon: Bot },\n { id: 'environment', labelKey: 'settings.sections.environment', icon: Terminal },\n { id: 'workflow', labelKey: 'settings.sections.workflow', icon: GitBranch },\n { id: 'ci', labelKey: 'settings.sections.ci', icon: Activity },\n { id: 'stage-timeouts', labelKey: 'settings.sections.timeouts', icon: Timer },\n { id: 'notifications', labelKey: 'settings.sections.notifications', icon: Bell },\n { id: 'feature-flags', labelKey: 'settings.sections.flags', icon: Flag },\n { id: 'interactive-agent', labelKey: 'settings.sections.chat', icon: MessageSquare },\n { id: 'fab-layout', labelKey: 'settings.sections.layout', icon: LayoutGrid },\n { id: 'database', labelKey: 'settings.sections.database', icon: Database },\n { id: 'litellm-proxy', labelKey: 'settings.sections.proxy', icon: Server },\n] as const;\n\nconst TABS = [{ id: 'all', labelKey: 'settings.sections.all', icon: LayoutList }, ...SECTIONS];\n\nexport interface SettingsPageClientProps {\n settings: Settings;\n shipitAiHome: string;\n dbFileSize: string;\n availableTerminals?: AvailableTerminal[];\n availableEditors?: AvailableEditor[];\n availableShells?: AvailableShell[];\n}\n\nexport function SettingsPageClient({\n settings,\n shipitAiHome,\n dbFileSize,\n availableTerminals,\n availableEditors,\n availableShells,\n}: SettingsPageClientProps) {\n const { t } = useTranslation('web');\n const [activeTab, setActiveTab] = useState<string>('all');\n const [visibleSection, setVisibleSection] = useState<string>('agent');\n\n // Track which section is in view via IntersectionObserver (only on \"All\" tab)\n useEffect(() => {\n if (activeTab !== 'all') return;\n\n const els = SECTIONS.map((s) => document.getElementById(`section-${s.id}`)).filter(\n Boolean\n ) as HTMLElement[];\n if (els.length === 0) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setVisibleSection(entry.target.id.replace('section-', ''));\n }\n }\n },\n { rootMargin: '-65px 0px -60% 0px', threshold: 0 }\n );\n\n for (const el of els) observer.observe(el);\n return () => observer.disconnect();\n }, [activeTab]);\n\n return (\n <div data-testid=\"settings-page-client\" className=\"max-w-5xl px-8 pt-8\">\n {/* Sticky header -- editorial title + tab nav */}\n <div className=\"bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 pb-4 backdrop-blur\">\n {/* Title row with editorial treatment */}\n <div className=\"mb-4 space-y-1.5\">\n <span className=\"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase\">\n Developer Portal\n </span>\n <div className=\"flex items-baseline gap-3\">\n <h1 className=\"text-foreground text-3xl font-black tracking-tight\">\n {t('settings.title')}\n </h1>\n </div>\n </div>\n {/* Tab navigation -- editorial tab treatment */}\n <nav className=\"bg-card editorial-shadow flex flex-wrap items-center gap-0.5 rounded-lg p-1\">\n {TABS.map((tab) => {\n const TabIcon = tab.icon;\n const isActive =\n activeTab === tab.id ||\n (activeTab === 'all' && tab.id !== 'all' && visibleSection === tab.id);\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-bold transition-all',\n isActive\n ? 'bg-muted text-primary shadow-sm ring-1 ring-slate-200/70 dark:ring-slate-700/50'\n : 'text-muted-foreground hover:text-foreground hover:bg-accent/50'\n )}\n >\n <TabIcon className=\"h-3 w-3\" />\n <span className=\"hidden sm:inline\">{t(tab.labelKey)}</span>\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n {/* -- Agent -- */}\n {(activeTab === 'all' || activeTab === 'agent') && (\n <div id=\"section-agent\" className=\"scroll-mt-18 rounded-lg\">\n <AgentSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Environment -- */}\n {(activeTab === 'all' || activeTab === 'environment') && (\n <div id=\"section-environment\" className=\"scroll-mt-18 rounded-lg\">\n <EnvironmentSettingsSection\n settings={settings}\n availableEditors={availableEditors}\n availableShells={availableShells}\n availableTerminals={availableTerminals}\n />\n </div>\n )}\n\n {/* -- Workflow -- */}\n {(activeTab === 'all' || activeTab === 'workflow') && (\n <div id=\"section-workflow\" className=\"scroll-mt-18 rounded-lg\">\n <WorkflowSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- CI -- */}\n {(activeTab === 'all' || activeTab === 'ci') && (\n <div id=\"section-ci\" className=\"scroll-mt-18 rounded-lg\">\n <CiSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Stage Timeouts -- */}\n {(activeTab === 'all' || activeTab === 'stage-timeouts') && (\n <div id=\"section-stage-timeouts\" className=\"scroll-mt-18 rounded-lg\">\n <StageTimeoutsSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Notifications -- */}\n {(activeTab === 'all' || activeTab === 'notifications') && (\n <div id=\"section-notifications\" className=\"scroll-mt-18 rounded-lg\">\n <NotificationSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Feature Flags -- */}\n {(activeTab === 'all' || activeTab === 'feature-flags') && (\n <div id=\"section-feature-flags\" className=\"scroll-mt-18 rounded-lg\">\n <FeatureFlagsSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Interactive Agent -- */}\n {(activeTab === 'all' || activeTab === 'interactive-agent') && (\n <div id=\"section-interactive-agent\" className=\"scroll-mt-18 rounded-lg\">\n <InteractiveAgentSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- FAB Layout -- */}\n {(activeTab === 'all' || activeTab === 'fab-layout') && (\n <div id=\"section-fab-layout\" className=\"scroll-mt-18 rounded-lg\">\n <FabLayoutSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Database -- */}\n {(activeTab === 'all' || activeTab === 'database') && (\n <div id=\"section-database\" className=\"scroll-mt-18 rounded-lg\">\n <DatabaseSettingsSection shipitAiHome={shipitAiHome} dbFileSize={dbFileSize} />\n </div>\n )}\n\n {/* -- LiteLLM Proxy -- */}\n {(activeTab === 'all' || activeTab === 'litellm-proxy') && (\n <div id=\"section-litellm-proxy\" className=\"scroll-mt-18 rounded-lg\">\n <LiteLLMProxySettingsSection settings={settings} />\n {settings.litellmProxy?.baseUrl ? (\n <LiteLLMProxyRoutingSection settings={settings} />\n ) : null}\n </div>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { Minus, Plus, ExternalLink, Info } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport { Label } from '@/components/ui/label';\nimport { Switch } from '@/components/ui/switch';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\n/* ── Reusable row components ── */\n\nexport function SettingsRow({\n label,\n description,\n htmlFor,\n tooltip,\n children,\n}: {\n label: string;\n description?: string;\n htmlFor?: string;\n /** Explicit tooltip text. Falls back to `description` if not provided. */\n tooltip?: string;\n children: React.ReactNode;\n}) {\n // Show the Info icon when there's either an explicit tooltip or a description to surface\n const tooltipText = tooltip ?? description;\n\n return (\n <div className=\"flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0\">\n <div className=\"min-w-0\">\n <span className=\"flex items-center gap-1.5\">\n <Label htmlFor={htmlFor} className=\"cursor-pointer text-sm font-normal whitespace-nowrap\">\n {label}\n </Label>\n {tooltipText ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Info className=\"text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors\" />\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-[11px] leading-relaxed\">\n <span className=\"text-muted-foreground\">{tooltipText}</span>\n </TooltipContent>\n </Tooltip>\n ) : null}\n </span>\n {description ? (\n <p className=\"text-muted-foreground text-[11px] leading-tight\">{description}</p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">{children}</div>\n </div>\n );\n}\n\nexport function SwitchRow({\n label,\n description,\n id,\n testId,\n checked,\n onChange,\n disabled,\n tooltip,\n}: {\n label: string;\n description?: string;\n id: string;\n testId: string;\n checked: boolean;\n onChange: (value: boolean) => void;\n disabled?: boolean;\n tooltip?: string;\n}) {\n return (\n <SettingsRow label={label} description={description} htmlFor={id} tooltip={tooltip}>\n <Switch\n id={id}\n data-testid={testId}\n checked={checked}\n onCheckedChange={onChange}\n disabled={disabled}\n className={cn('cursor-pointer', disabled && 'cursor-not-allowed opacity-50')}\n />\n </SettingsRow>\n );\n}\n\n/* ── Section card wrapper ── */\n\nexport function SettingsSection({\n icon: Icon,\n title,\n description,\n badge,\n testId,\n tooltip,\n tooltipLinks,\n children,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n title: string;\n description: string;\n badge?: string;\n testId: string;\n /** Section-level tooltip describing the purpose of this settings group. */\n tooltip?: string;\n /** Documentation links rendered below the tooltip text. */\n tooltipLinks?: { label: string; href: string }[];\n children: React.ReactNode;\n}) {\n return (\n <div className=\"bg-background rounded-lg border\" data-testid={testId}>\n <div className=\"bg-muted/30 border-b px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <Icon className=\"text-muted-foreground h-3.5 w-3.5\" />\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n {tooltip ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Info className=\"text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors\" />\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"max-w-72 text-[11px] leading-relaxed\">\n <p className=\"text-muted-foreground\">{tooltip}</p>\n {tooltipLinks != null && tooltipLinks.length > 0 ? (\n <div className=\"border-border/50 mt-1.5 flex flex-col gap-0.5 border-t pt-1.5\">\n {tooltipLinks.map((link) => (\n <a\n key={link.href}\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5 text-[10px] tracking-wide transition-colors\"\n >\n <ExternalLink className=\"h-2.5 w-2.5 shrink-0 opacity-50\" />\n {link.label}\n </a>\n ))}\n </div>\n ) : null}\n </TooltipContent>\n </Tooltip>\n ) : null}\n {badge ? (\n <span className=\"bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[9px] font-medium tracking-wider uppercase\">\n {badge}\n </span>\n ) : null}\n </div>\n <p className=\"text-muted-foreground mt-0.5 text-[11px]\">{description}</p>\n </div>\n <div className=\"px-4\">{children}</div>\n </div>\n );\n}\n\nexport function NumberStepper({\n id,\n testId,\n value,\n onChange,\n onBlur,\n placeholder,\n min = 1,\n max,\n step = 1,\n suffix,\n}: {\n id: string;\n testId: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n placeholder: string;\n min?: number;\n max?: number;\n step?: number;\n suffix?: string;\n}) {\n const { t } = useTranslation('web');\n const numValue = value === '' ? undefined : parseInt(value, 10);\n\n const decrement = () => {\n const current = numValue ?? parseInt(placeholder, 10);\n const next = Math.max(min, current - step);\n onChange(String(next));\n };\n\n const increment = () => {\n const current = numValue ?? parseInt(placeholder, 10);\n const next = max != null ? Math.min(max, current + step) : current + step;\n onChange(String(next));\n };\n\n return (\n <div className=\"flex items-center gap-1.5\">\n <div className=\"flex items-center overflow-hidden rounded-md border\">\n <button\n type=\"button\"\n onClick={() => {\n decrement();\n }}\n onMouseUp={onBlur}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-8 w-7 cursor-pointer items-center justify-center border-r transition-colors\"\n aria-label={t('common.decrease')}\n >\n <Minus className=\"h-3 w-3\" />\n </button>\n <input\n id={id}\n data-testid={testId}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={value}\n placeholder={placeholder}\n onChange={(e) => {\n const v = e.target.value.replace(/[^0-9]/g, '');\n onChange(v);\n }}\n onBlur={onBlur}\n className=\"h-8 w-14 bg-transparent text-center text-xs outline-none\"\n />\n <button\n type=\"button\"\n onClick={() => {\n increment();\n }}\n onMouseUp={onBlur}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-8 w-7 cursor-pointer items-center justify-center border-l transition-colors\"\n aria-label={t('common.increase')}\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n {suffix ? <span className=\"text-muted-foreground text-[11px]\">{suffix}</span> : null}\n </div>\n );\n}\n\nexport function SubsectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"border-b pt-3 pb-1\">\n <span className=\"text-muted-foreground text-[10px] font-semibold tracking-wider uppercase\">\n {children}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Bot } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport type { Settings, AgentType } from '@shipit-ai/core/domain/generated/output';\nimport { AgentModelPicker } from '@/components/features/settings/AgentModelPicker';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\n\nexport interface AgentSettingsSectionProps {\n settings: Settings;\n}\n\nexport function AgentSettingsSection({ settings }: AgentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [agentType, setAgentType] = useState(settings.agent.type);\n\n return (\n <SettingsSection\n icon={Bot}\n title={t('settings.agent.sectionTitle')}\n description={t('settings.agent.sectionDescription')}\n testId=\"agent-settings-section\"\n tooltip={t('settings.agent.hint')}\n tooltipLinks={[\n {\n label: t('settings.agent.links.agentSystem'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/agent-system.md',\n },\n {\n label: t('settings.agent.links.addingAgents'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/adding-agents.md',\n },\n {\n label: t('settings.agent.links.configurationGuide'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.agent.agentAndModel')}\n description={t('settings.agent.agentAndModelDescription')}\n tooltip=\"Changing the agent switches which AI CLI tool runs your features. Each agent has different capabilities, speed, and cost tradeoffs.\"\n htmlFor=\"agent-model-picker\"\n >\n <AgentModelPicker\n initialAgentType={agentType}\n initialModel={settings.models.default}\n mode=\"settings\"\n onAgentModelChange={(newAgent) => setAgentType(newAgent as AgentType)}\n className=\"w-55\"\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"403b2511a107b82251b07c35158ea444b6edbbeb0f\":{\"name\":\"updateSettingsAction\"}},\"src/presentation/web/app/actions/update-settings.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"403b2511a107b82251b07c35158ea444b6edbbeb0f\",callServer,void 0,findSourceMapURL,\"updateSettingsAction\");export{$$RSC_SERVER_ACTION_0 as updateSettingsAction};","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Terminal } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\nimport { Badge } from '@/components/ui/badge';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { type EditorType, TerminalType } from '@shipit-ai/core/domain/generated/output';\nimport { getEditorTypeIcon } from '@/components/common/editor-type-icons';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport type { AvailableTerminal } from '@/app/actions/get-available-terminals';\nimport type { AvailableEditor } from '@/app/actions/get-available-editors';\nimport type { AvailableShell } from '@/app/actions/get-available-shells';\n\nexport const DEFAULT_EDITOR_OPTIONS: AvailableEditor[] = [\n { id: 'vscode', name: 'VS Code', available: true },\n { id: 'cursor', name: 'Cursor', available: true },\n { id: 'windsurf', name: 'Windsurf', available: true },\n { id: 'zed', name: 'Zed', available: true },\n { id: 'antigravity', name: 'Antigravity', available: true },\n];\n\nexport const DEFAULT_SHELL_OPTIONS: AvailableShell[] = [\n { id: 'bash', name: 'Bash', available: true },\n { id: 'zsh', name: 'Zsh', available: true },\n { id: 'fish', name: 'Fish', available: true },\n];\n\nexport interface EnvironmentSettingsSectionProps {\n settings: Settings;\n availableEditors?: AvailableEditor[];\n availableShells?: AvailableShell[];\n availableTerminals?: AvailableTerminal[];\n}\n\nexport function EnvironmentSettingsSection({\n settings,\n availableEditors,\n availableShells,\n availableTerminals,\n}: EnvironmentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [editor, setEditor] = useState(settings.environment.defaultEditor);\n const [shell, setShell] = useState(settings.environment.shellPreference);\n const [terminal, setTerminal] = useState(\n settings.environment.terminalPreference ?? TerminalType.System\n );\n\n const terminalOptions = availableTerminals ?? [\n {\n id: TerminalType.System,\n name: t('settings.environment.systemTerminal'),\n available: true as const,\n },\n ];\n\n const editorOptions = availableEditors ?? DEFAULT_EDITOR_OPTIONS;\n const shellOptions = availableShells ?? DEFAULT_SHELL_OPTIONS;\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Terminal}\n title={t('settings.environment.sectionTitle')}\n description={t('settings.environment.sectionDescription')}\n testId=\"environment-settings-section\"\n tooltip={t('settings.environment.hint')}\n tooltipLinks={[\n {\n label: t('settings.environment.links.configurationGuide'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.environment.defaultEditor')}\n description={t('settings.environment.defaultEditorDescription')}\n tooltip=\"The editor that opens when you click 'Launch' on a tool card or when ShipIT needs to open a file for review.\"\n htmlFor=\"default-editor\"\n >\n <Select\n value={editor}\n onValueChange={(v) => {\n setEditor(v as EditorType);\n save({\n environment: {\n defaultEditor: v as EditorType,\n shellPreference: shell,\n terminalPreference: terminal,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"default-editor\"\n data-testid=\"editor-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {editorOptions.map((opt) => {\n const Icon = getEditorTypeIcon(opt.id as EditorType);\n return (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n <Icon className=\"h-4 w-4 shrink-0\" />\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n );\n })}\n </SelectContent>\n </Select>\n </SettingsRow>\n <SettingsRow\n label={t('settings.environment.shell')}\n description={t('settings.environment.shellDescription')}\n tooltip=\"Controls which shell runs generated scripts like install commands and git operations. Match this to your daily driver shell.\"\n htmlFor=\"shell-preference\"\n >\n <Select\n value={shell}\n onValueChange={(v) => {\n setShell(v);\n save({\n environment: {\n defaultEditor: editor,\n shellPreference: v,\n terminalPreference: terminal,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"shell-preference\"\n data-testid=\"shell-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {shellOptions.map((opt) => (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </SettingsRow>\n <SettingsRow\n label={t('settings.environment.terminal')}\n description={t('settings.environment.terminalDescription')}\n tooltip=\"The terminal emulator launched when opening shell sessions from the web UI. Only affects web-launched terminals, not CLI usage.\"\n htmlFor=\"terminal-preference\"\n >\n <Select\n value={terminal}\n onValueChange={(v) => {\n setTerminal(v as TerminalType);\n save({\n environment: {\n defaultEditor: editor,\n shellPreference: shell,\n terminalPreference: v as TerminalType,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"terminal-preference\"\n data-testid=\"terminal-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {terminalOptions.map((opt) => (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { GitBranch } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport {\n SettingsSection,\n SettingsRow,\n SwitchRow,\n NumberStepper,\n SubsectionLabel,\n} from './settings-section-utils';\n\nexport interface WorkflowSettingsSectionProps {\n settings: Settings;\n}\n\nfunction buildWorkflowPayload(\n state: {\n openPr: boolean;\n pushOnComplete: boolean;\n allowPrd: boolean;\n allowPlan: boolean;\n allowMerge: boolean;\n enableEvidence: boolean;\n commitEvidence: boolean;\n ciWatchEnabled: boolean;\n defaultFastMode: boolean;\n autoArchiveEnabled: boolean;\n autoArchiveDelay: string;\n },\n overrides: {\n openPr?: boolean;\n pushOnComplete?: boolean;\n allowPrd?: boolean;\n allowPlan?: boolean;\n allowMerge?: boolean;\n enableEvidence?: boolean;\n commitEvidence?: boolean;\n ciWatchEnabled?: boolean;\n defaultFastMode?: boolean;\n autoArchiveEnabled?: boolean;\n autoArchiveDelay?: string;\n } = {}\n) {\n const archiveEnabled = overrides.autoArchiveEnabled ?? state.autoArchiveEnabled;\n const archiveDelay = parseInt(overrides.autoArchiveDelay ?? state.autoArchiveDelay, 10);\n return {\n workflow: {\n openPrOnImplementationComplete: overrides.openPr ?? state.openPr,\n approvalGateDefaults: {\n pushOnImplementationComplete: overrides.pushOnComplete ?? state.pushOnComplete,\n allowPrd: overrides.allowPrd ?? state.allowPrd,\n allowPlan: overrides.allowPlan ?? state.allowPlan,\n allowMerge: overrides.allowMerge ?? state.allowMerge,\n },\n enableEvidence: overrides.enableEvidence ?? state.enableEvidence,\n commitEvidence: overrides.commitEvidence ?? state.commitEvidence,\n ciWatchEnabled: overrides.ciWatchEnabled ?? state.ciWatchEnabled,\n defaultFastMode: overrides.defaultFastMode ?? state.defaultFastMode,\n autoArchiveDelayMinutes: archiveEnabled\n ? Number.isNaN(archiveDelay) || archiveDelay < 1\n ? 10\n : archiveDelay\n : 0,\n },\n };\n}\n\nexport function WorkflowSettingsSection({ settings }: WorkflowSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [openPr, setOpenPr] = useState(settings.workflow.openPrOnImplementationComplete);\n const [pushOnComplete, setPushOnComplete] = useState(\n settings.workflow.approvalGateDefaults.pushOnImplementationComplete\n );\n const [allowPrd, setAllowPrd] = useState(settings.workflow.approvalGateDefaults.allowPrd);\n const [allowPlan, setAllowPlan] = useState(settings.workflow.approvalGateDefaults.allowPlan);\n const [allowMerge, setAllowMerge] = useState(settings.workflow.approvalGateDefaults.allowMerge);\n const [enableEvidence, setEnableEvidence] = useState(settings.workflow.enableEvidence);\n const [commitEvidence, setCommitEvidence] = useState(settings.workflow.commitEvidence);\n const [ciWatchEnabled, setCiWatchEnabled] = useState(settings.workflow.ciWatchEnabled !== false);\n const [defaultFastMode, setDefaultFastMode] = useState(\n settings.workflow.defaultFastMode !== false\n );\n const [autoArchiveEnabled, setAutoArchiveEnabled] = useState(\n (settings.workflow.autoArchiveDelayMinutes ?? 10) > 0\n );\n const [autoArchiveDelay, setAutoArchiveDelay] = useState(\n String(settings.workflow.autoArchiveDelayMinutes ?? 10)\n );\n\n function getState() {\n return {\n openPr,\n pushOnComplete,\n allowPrd,\n allowPlan,\n allowMerge,\n enableEvidence,\n commitEvidence,\n ciWatchEnabled,\n defaultFastMode,\n autoArchiveEnabled,\n autoArchiveDelay,\n };\n }\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={GitBranch}\n title={t('settings.workflow.title')}\n description={t('settings.workflow.sectionDescription')}\n testId=\"workflow-settings-section\"\n tooltip={t('settings.workflow.hint')}\n tooltipLinks={[\n {\n label: t('settings.workflow.links.approvalGates'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/016-hitl-approval-gates/spec.yaml',\n },\n {\n label: t('settings.workflow.links.pushAndPrFlags'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/037-feature-pr-push-flags/spec.yaml',\n },\n ]}\n >\n <SwitchRow\n label={t('settings.workflow.defaultFastMode')}\n description={t('settings.workflow.defaultFastModeDescription')}\n tooltip=\"When enabled, new features skip the PRD and Plan phases and go straight to implementation. Useful for quick fixes, risky for complex features.\"\n id=\"default-fast-mode\"\n testId=\"switch-default-fast-mode\"\n checked={defaultFastMode}\n onChange={(v) => {\n setDefaultFastMode(v);\n save(buildWorkflowPayload(getState(), { defaultFastMode: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.approve')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.autoApprovePrd')}\n description={t('settings.workflow.autoApprovePrdDescription')}\n tooltip=\"Automatically approves the requirements document without pausing for your review. Saves time but you lose the chance to refine requirements before planning.\"\n id=\"allow-prd\"\n testId=\"switch-allow-prd\"\n checked={allowPrd}\n onChange={(v) => {\n setAllowPrd(v);\n save(buildWorkflowPayload(getState(), { allowPrd: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.autoApprovePlan')}\n description={t('settings.workflow.autoApprovePlanDescription')}\n tooltip=\"Automatically approves the implementation plan. The agent proceeds to coding without waiting for your plan review.\"\n id=\"allow-plan\"\n testId=\"switch-allow-plan\"\n checked={allowPlan}\n onChange={(v) => {\n setAllowPlan(v);\n save(buildWorkflowPayload(getState(), { allowPlan: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.autoApproveMerge')}\n description={t('settings.workflow.autoApproveMergeDescription')}\n tooltip=\"Automatically merges the PR after implementation without requiring your final review. Use with caution on production branches.\"\n id=\"allow-merge\"\n testId=\"switch-allow-merge\"\n checked={allowMerge}\n onChange={(v) => {\n setAllowMerge(v);\n save(buildWorkflowPayload(getState(), { allowMerge: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.evidence')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.collectEvidence')}\n description={t('settings.workflow.collectEvidenceDescription')}\n tooltip=\"Captures screenshots and test outputs during implementation as proof of work. Useful for audit trails and PR documentation.\"\n id=\"enable-evidence\"\n testId=\"switch-enable-evidence\"\n checked={enableEvidence}\n onChange={(v) => {\n setEnableEvidence(v);\n if (!v) {\n setCommitEvidence(false);\n save(buildWorkflowPayload(getState(), { enableEvidence: v, commitEvidence: false }));\n } else {\n save(buildWorkflowPayload(getState(), { enableEvidence: v }));\n }\n }}\n />\n <SwitchRow\n label={t('settings.workflow.addEvidenceToPr')}\n description={t('settings.workflow.addEvidenceToPrDescription')}\n tooltip=\"Attaches collected evidence artifacts (screenshots, logs) directly to the pull request description.\"\n id=\"commit-evidence\"\n testId=\"switch-commit-evidence\"\n checked={commitEvidence}\n disabled={!enableEvidence || !openPr}\n onChange={(v) => {\n setCommitEvidence(v);\n save(buildWorkflowPayload(getState(), { commitEvidence: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.git')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.pushOnComplete')}\n description={t('settings.workflow.pushOnCompleteDescription')}\n tooltip=\"Automatically pushes the implementation branch to the remote repository when the agent finishes coding.\"\n id=\"push-on-complete\"\n testId=\"switch-push-on-complete\"\n checked={pushOnComplete}\n onChange={(v) => {\n setPushOnComplete(v);\n save(buildWorkflowPayload(getState(), { pushOnComplete: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.openPrOnComplete')}\n description={t('settings.workflow.openPrOnCompleteDescription')}\n tooltip=\"Creates a pull request automatically after pushing. Combined with push-on-complete, this fully automates the delivery pipeline.\"\n id=\"open-pr\"\n testId=\"switch-open-pr\"\n checked={openPr}\n onChange={(v) => {\n setOpenPr(v);\n if (!v) {\n setCommitEvidence(false);\n save(buildWorkflowPayload(getState(), { openPr: v, commitEvidence: false }));\n } else {\n save(buildWorkflowPayload(getState(), { openPr: v }));\n }\n }}\n />\n <SwitchRow\n label={t('settings.workflow.watchCiAfterPush')}\n description={t('settings.workflow.watchCiAfterPushDescription')}\n tooltip=\"Monitors CI/CD pipeline status after pushing and can attempt fixes if tests fail. Disable if you prefer to handle CI failures manually.\"\n id=\"ci-watch-enabled\"\n testId=\"switch-ci-watch-enabled\"\n checked={ciWatchEnabled}\n onChange={(v) => {\n setCiWatchEnabled(v);\n save(buildWorkflowPayload(getState(), { ciWatchEnabled: v }));\n }}\n />\n <SubsectionLabel>Archive</SubsectionLabel>\n <SwitchRow\n label=\"Auto-archive completed\"\n description=\"Automatically archive features after they reach the completed state\"\n tooltip=\"Automatically archives features from the control center canvas after they reach the completed state, keeping the board clean.\"\n id=\"auto-archive-enabled\"\n testId=\"switch-auto-archive-enabled\"\n checked={autoArchiveEnabled}\n onChange={(v) => {\n setAutoArchiveEnabled(v);\n save(buildWorkflowPayload(getState(), { autoArchiveEnabled: v }));\n }}\n />\n <SettingsRow\n label=\"Archive delay\"\n description=\"Minutes to wait after completion before archiving (1-1440)\"\n tooltip=\"How long to wait after a feature completes before archiving it. Gives you time to review results before the feature moves off the board.\"\n htmlFor=\"auto-archive-delay\"\n >\n <NumberStepper\n id=\"auto-archive-delay\"\n testId=\"input-auto-archive-delay\"\n value={autoArchiveDelay}\n placeholder=\"10\"\n min={1}\n max={1440}\n suffix=\"min\"\n onChange={(v) => {\n setAutoArchiveDelay(v);\n }}\n onBlur={() => {\n if (!autoArchiveEnabled) return;\n const n = parseInt(autoArchiveDelay, 10);\n const clamped = Number.isNaN(n) ? 10 : Math.min(1440, Math.max(1, n));\n setAutoArchiveDelay(String(clamped));\n save(buildWorkflowPayload(getState(), { autoArchiveDelay: String(clamped) }));\n }}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Activity } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SwitchRow, NumberStepper } from './settings-section-utils';\n\nexport interface CiSettingsSectionProps {\n settings: Settings;\n}\n\nfunction parseOptionalInt(value: string): number | undefined {\n if (value === '') return undefined;\n const n = parseInt(value, 10);\n return Number.isNaN(n) || n <= 0 ? undefined : n;\n}\n\nexport function CiSettingsSection({ settings }: CiSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [ciMaxFix, setCiMaxFix] = useState(\n settings.workflow.ciMaxFixAttempts != null ? String(settings.workflow.ciMaxFixAttempts) : ''\n );\n const [ciTimeout, setCiTimeout] = useState(\n settings.workflow.ciWatchTimeoutMs != null\n ? String(Math.round(settings.workflow.ciWatchTimeoutMs / 1000))\n : ''\n );\n const [ciLogMax, setCiLogMax] = useState(\n settings.workflow.ciLogMaxChars != null ? String(settings.workflow.ciLogMaxChars) : ''\n );\n const [ciPollInterval, setCiPollInterval] = useState(\n settings.workflow.ciWatchPollIntervalSeconds != null\n ? String(settings.workflow.ciWatchPollIntervalSeconds)\n : ''\n );\n const [hideCiStatus, setHideCiStatus] = useState(settings.workflow.hideCiStatus !== false);\n\n const originalCiMaxFix =\n settings.workflow.ciMaxFixAttempts != null ? String(settings.workflow.ciMaxFixAttempts) : '';\n const originalCiTimeout =\n settings.workflow.ciWatchTimeoutMs != null\n ? String(Math.round(settings.workflow.ciWatchTimeoutMs / 1000))\n : '';\n const originalCiLogMax =\n settings.workflow.ciLogMaxChars != null ? String(settings.workflow.ciLogMaxChars) : '';\n const originalCiPollInterval =\n settings.workflow.ciWatchPollIntervalSeconds != null\n ? String(settings.workflow.ciWatchPollIntervalSeconds)\n : '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(overrides: {\n ciMaxFix?: string;\n ciTimeout?: string;\n ciLogMax?: string;\n ciPollInterval?: string;\n hideCiStatus?: boolean;\n }) {\n const timeoutSeconds = parseOptionalInt(overrides.ciTimeout ?? ciTimeout);\n return {\n workflow: {\n ciMaxFixAttempts: parseOptionalInt(overrides.ciMaxFix ?? ciMaxFix),\n ciWatchTimeoutMs: timeoutSeconds != null ? timeoutSeconds * 1000 : undefined,\n ciLogMaxChars: parseOptionalInt(overrides.ciLogMax ?? ciLogMax),\n ciWatchPollIntervalSeconds: parseOptionalInt(overrides.ciPollInterval ?? ciPollInterval),\n hideCiStatus: overrides.hideCiStatus ?? hideCiStatus,\n },\n };\n }\n\n return (\n <SettingsSection\n icon={Activity}\n title={t('settings.ci.title')}\n description={t('settings.ci.description')}\n testId=\"ci-settings-section\"\n tooltip={t('settings.ci.hint')}\n tooltipLinks={[\n {\n label: t('settings.ci.links.cicdPipeline'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/cicd.md',\n },\n {\n label: t('settings.ci.links.ciSecurityGates'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/003-cicd-security-gates/spec.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.ci.maxFixAttempts')}\n description={t('settings.ci.maxFixAttemptsDescription')}\n tooltip=\"How many times the agent will attempt to fix failing CI checks before giving up. Higher values increase the chance of auto-resolution but consume more agent time and API calls.\"\n htmlFor=\"ci-max-fix\"\n >\n <NumberStepper\n id=\"ci-max-fix\"\n testId=\"ci-max-fix-input\"\n placeholder=\"3\"\n value={ciMaxFix}\n onChange={setCiMaxFix}\n onBlur={() => {\n if (ciMaxFix !== originalCiMaxFix) save(buildPayload({ ciMaxFix }));\n }}\n min={1}\n max={10}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.watchTimeout')}\n description={t('settings.ci.watchTimeoutDescription')}\n tooltip=\"Maximum time the agent will wait for CI to finish. If CI hasn't completed within this window, the agent stops watching. Increase for repos with slow CI pipelines.\"\n htmlFor=\"ci-timeout\"\n >\n <NumberStepper\n id=\"ci-timeout\"\n testId=\"ci-timeout-input\"\n placeholder=\"300\"\n value={ciTimeout}\n onChange={setCiTimeout}\n onBlur={() => {\n if (ciTimeout !== originalCiTimeout) save(buildPayload({ ciTimeout }));\n }}\n min={30}\n step={30}\n suffix=\"sec\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.maxLogSize')}\n description={t('settings.ci.maxLogSizeDescription')}\n tooltip=\"CI logs beyond this character limit are truncated before being sent to the agent for analysis. Keeps agent context focused and avoids excessive token usage.\"\n htmlFor=\"ci-log-max\"\n >\n <NumberStepper\n id=\"ci-log-max\"\n testId=\"ci-log-max-input\"\n placeholder=\"50000\"\n value={ciLogMax}\n onChange={setCiLogMax}\n onBlur={() => {\n if (ciLogMax !== originalCiLogMax) save(buildPayload({ ciLogMax }));\n }}\n min={1000}\n step={5000}\n suffix=\"chars\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.pollInterval')}\n description={t('settings.ci.pollIntervalDescription')}\n tooltip=\"How frequently the agent checks GitHub for CI status updates. Lower values give faster feedback but increase API call volume.\"\n htmlFor=\"ci-poll-interval\"\n >\n <NumberStepper\n id=\"ci-poll-interval\"\n testId=\"ci-poll-interval-input\"\n placeholder=\"30\"\n value={ciPollInterval}\n onChange={setCiPollInterval}\n onBlur={() => {\n if (ciPollInterval !== originalCiPollInterval) save(buildPayload({ ciPollInterval }));\n }}\n min={5}\n step={5}\n suffix=\"sec\"\n />\n </SettingsRow>\n <SwitchRow\n label={t('settings.ci.hideCiStatus')}\n description={t('settings.ci.hideCiStatusDescription')}\n tooltip=\"When enabled, CI status indicators are hidden from the feature drawer and merge review panels. Useful if you monitor CI through GitHub directly.\"\n id=\"hide-ci-status\"\n testId=\"switch-hide-ci-status\"\n checked={hideCiStatus}\n onChange={(v) => {\n setHideCiStatus(v);\n save(buildPayload({ hideCiStatus: v }));\n }}\n />\n </SettingsSection>\n );\n}\n","\"use client\";\n\n// src/slider.tsx\nimport * as React from \"react\";\nimport { clamp } from \"@radix-ui/number\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { usePrevious } from \"@radix-ui/react-use-previous\";\nimport { useSize } from \"@radix-ui/react-use-size\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { createCollection } from \"@radix-ui/react-collection\";\nimport { jsx, jsxs } from \"react/jsx-runtime\";\nvar PAGE_KEYS = [\"PageUp\", \"PageDown\"];\nvar ARROW_KEYS = [\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"];\nvar BACK_KEYS = {\n \"from-left\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowLeft\"],\n \"from-right\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowRight\"],\n \"from-bottom\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowLeft\"],\n \"from-top\": [\"Home\", \"PageDown\", \"ArrowUp\", \"ArrowLeft\"]\n};\nvar SLIDER_NAME = \"Slider\";\nvar [Collection, useCollection, createCollectionScope] = createCollection(SLIDER_NAME);\nvar [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [\n createCollectionScope\n]);\nvar [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);\nvar Slider = React.forwardRef(\n (props, forwardedRef) => {\n const {\n name,\n min = 0,\n max = 100,\n step = 1,\n orientation = \"horizontal\",\n disabled = false,\n minStepsBetweenThumbs = 0,\n defaultValue = [min],\n value,\n onValueChange = () => {\n },\n onValueCommit = () => {\n },\n inverted = false,\n form,\n ...sliderProps\n } = props;\n const thumbRefs = React.useRef(/* @__PURE__ */ new Set());\n const valueIndexToChangeRef = React.useRef(0);\n const isHorizontal = orientation === \"horizontal\";\n const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;\n const [values = [], setValues] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange: (value2) => {\n const thumbs = [...thumbRefs.current];\n thumbs[valueIndexToChangeRef.current]?.focus();\n onValueChange(value2);\n }\n });\n const valuesBeforeSlideStartRef = React.useRef(values);\n function handleSlideStart(value2) {\n const closestIndex = getClosestValueIndex(values, value2);\n updateValues(value2, closestIndex);\n }\n function handleSlideMove(value2) {\n updateValues(value2, valueIndexToChangeRef.current);\n }\n function handleSlideEnd() {\n const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];\n const nextValue = values[valueIndexToChangeRef.current];\n const hasChanged = nextValue !== prevValue;\n if (hasChanged) onValueCommit(values);\n }\n function updateValues(value2, atIndex, { commit } = { commit: false }) {\n const decimalCount = getDecimalCount(step);\n const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount);\n const nextValue = clamp(snapToStep, [min, max]);\n setValues((prevValues = []) => {\n const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);\n if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {\n valueIndexToChangeRef.current = nextValues.indexOf(nextValue);\n const hasChanged = String(nextValues) !== String(prevValues);\n if (hasChanged && commit) onValueCommit(nextValues);\n return hasChanged ? nextValues : prevValues;\n } else {\n return prevValues;\n }\n });\n }\n return /* @__PURE__ */ jsx(\n SliderProvider,\n {\n scope: props.__scopeSlider,\n name,\n disabled,\n min,\n max,\n valueIndexToChangeRef,\n thumbs: thumbRefs.current,\n values,\n orientation,\n form,\n children: /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(\n SliderOrientation,\n {\n \"aria-disabled\": disabled,\n \"data-disabled\": disabled ? \"\" : void 0,\n ...sliderProps,\n ref: forwardedRef,\n onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {\n if (!disabled) valuesBeforeSlideStartRef.current = values;\n }),\n min,\n max,\n inverted,\n onSlideStart: disabled ? void 0 : handleSlideStart,\n onSlideMove: disabled ? void 0 : handleSlideMove,\n onSlideEnd: disabled ? void 0 : handleSlideEnd,\n onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }),\n onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }),\n onStepKeyDown: ({ event, direction: stepDirection }) => {\n if (!disabled) {\n const isPageKey = PAGE_KEYS.includes(event.key);\n const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key);\n const multiplier = isSkipKey ? 10 : 1;\n const atIndex = valueIndexToChangeRef.current;\n const value2 = values[atIndex];\n const stepInDirection = step * multiplier * stepDirection;\n updateValues(value2 + stepInDirection, atIndex, { commit: true });\n }\n }\n }\n ) }) })\n }\n );\n }\n);\nSlider.displayName = SLIDER_NAME;\nvar [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {\n startEdge: \"left\",\n endEdge: \"right\",\n size: \"width\",\n direction: 1\n});\nvar SliderHorizontal = React.forwardRef(\n (props, forwardedRef) => {\n const {\n min,\n max,\n dir,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const [slider, setSlider] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));\n const rectRef = React.useRef(void 0);\n const direction = useDirection(dir);\n const isDirectionLTR = direction === \"ltr\";\n const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;\n function getValueFromPointer(pointerPosition) {\n const rect = rectRef.current || slider.getBoundingClientRect();\n const input = [0, rect.width];\n const output = isSlidingFromLeft ? [min, max] : [max, min];\n const value = linearScale(input, output);\n rectRef.current = rect;\n return value(pointerPosition - rect.left);\n }\n return /* @__PURE__ */ jsx(\n SliderOrientationProvider,\n {\n scope: props.__scopeSlider,\n startEdge: isSlidingFromLeft ? \"left\" : \"right\",\n endEdge: isSlidingFromLeft ? \"right\" : \"left\",\n direction: isSlidingFromLeft ? 1 : -1,\n size: \"width\",\n children: /* @__PURE__ */ jsx(\n SliderImpl,\n {\n dir: direction,\n \"data-orientation\": \"horizontal\",\n ...sliderProps,\n ref: composedRefs,\n style: {\n ...sliderProps.style,\n [\"--radix-slider-thumb-transform\"]: \"translateX(-50%)\"\n },\n onSlideStart: (event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideStart?.(value);\n },\n onSlideMove: (event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideMove?.(value);\n },\n onSlideEnd: () => {\n rectRef.current = void 0;\n onSlideEnd?.();\n },\n onStepKeyDown: (event) => {\n const slideDirection = isSlidingFromLeft ? \"from-left\" : \"from-right\";\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }\n }\n )\n }\n );\n }\n);\nvar SliderVertical = React.forwardRef(\n (props, forwardedRef) => {\n const {\n min,\n max,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const sliderRef = React.useRef(null);\n const ref = useComposedRefs(forwardedRef, sliderRef);\n const rectRef = React.useRef(void 0);\n const isSlidingFromBottom = !inverted;\n function getValueFromPointer(pointerPosition) {\n const rect = rectRef.current || sliderRef.current.getBoundingClientRect();\n const input = [0, rect.height];\n const output = isSlidingFromBottom ? [max, min] : [min, max];\n const value = linearScale(input, output);\n rectRef.current = rect;\n return value(pointerPosition - rect.top);\n }\n return /* @__PURE__ */ jsx(\n SliderOrientationProvider,\n {\n scope: props.__scopeSlider,\n startEdge: isSlidingFromBottom ? \"bottom\" : \"top\",\n endEdge: isSlidingFromBottom ? \"top\" : \"bottom\",\n size: \"height\",\n direction: isSlidingFromBottom ? 1 : -1,\n children: /* @__PURE__ */ jsx(\n SliderImpl,\n {\n \"data-orientation\": \"vertical\",\n ...sliderProps,\n ref,\n style: {\n ...sliderProps.style,\n [\"--radix-slider-thumb-transform\"]: \"translateY(50%)\"\n },\n onSlideStart: (event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideStart?.(value);\n },\n onSlideMove: (event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideMove?.(value);\n },\n onSlideEnd: () => {\n rectRef.current = void 0;\n onSlideEnd?.();\n },\n onStepKeyDown: (event) => {\n const slideDirection = isSlidingFromBottom ? \"from-bottom\" : \"from-top\";\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }\n }\n )\n }\n );\n }\n);\nvar SliderImpl = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeSlider,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onHomeKeyDown,\n onEndKeyDown,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const context = useSliderContext(SLIDER_NAME, __scopeSlider);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n ...sliderProps,\n ref: forwardedRef,\n onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === \"Home\") {\n onHomeKeyDown(event);\n event.preventDefault();\n } else if (event.key === \"End\") {\n onEndKeyDown(event);\n event.preventDefault();\n } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {\n onStepKeyDown(event);\n event.preventDefault();\n }\n }),\n onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {\n const target = event.target;\n target.setPointerCapture(event.pointerId);\n event.preventDefault();\n if (context.thumbs.has(target)) {\n target.focus();\n } else {\n onSlideStart(event);\n }\n }),\n onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {\n const target = event.target;\n if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);\n }),\n onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {\n const target = event.target;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n onSlideEnd(event);\n }\n })\n }\n );\n }\n);\nvar TRACK_NAME = \"SliderTrack\";\nvar SliderTrack = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, ...trackProps } = props;\n const context = useSliderContext(TRACK_NAME, __scopeSlider);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n \"data-disabled\": context.disabled ? \"\" : void 0,\n \"data-orientation\": context.orientation,\n ...trackProps,\n ref: forwardedRef\n }\n );\n }\n);\nSliderTrack.displayName = TRACK_NAME;\nvar RANGE_NAME = \"SliderRange\";\nvar SliderRange = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, ...rangeProps } = props;\n const context = useSliderContext(RANGE_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const valuesCount = context.values.length;\n const percentages = context.values.map(\n (value) => convertValueToPercentage(value, context.min, context.max)\n );\n const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;\n const offsetEnd = 100 - Math.max(...percentages);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n \"data-orientation\": context.orientation,\n \"data-disabled\": context.disabled ? \"\" : void 0,\n ...rangeProps,\n ref: composedRefs,\n style: {\n ...props.style,\n [orientation.startEdge]: offsetStart + \"%\",\n [orientation.endEdge]: offsetEnd + \"%\"\n }\n }\n );\n }\n);\nSliderRange.displayName = RANGE_NAME;\nvar THUMB_NAME = \"SliderThumb\";\nvar SliderThumb = React.forwardRef(\n (props, forwardedRef) => {\n const getItems = useCollection(props.__scopeSlider);\n const [thumb, setThumb] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const index = React.useMemo(\n () => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,\n [getItems, thumb]\n );\n return /* @__PURE__ */ jsx(SliderThumbImpl, { ...props, ref: composedRefs, index });\n }\n);\nvar SliderThumbImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, index, name, ...thumbProps } = props;\n const context = useSliderContext(THUMB_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);\n const [thumb, setThumb] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const isFormControl = thumb ? context.form || !!thumb.closest(\"form\") : true;\n const size = useSize(thumb);\n const value = context.values[index];\n const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);\n const label = getLabel(index, context.values.length);\n const orientationSize = size?.[orientation.size];\n const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;\n React.useEffect(() => {\n if (thumb) {\n context.thumbs.add(thumb);\n return () => {\n context.thumbs.delete(thumb);\n };\n }\n }, [thumb, context.thumbs]);\n return /* @__PURE__ */ jsxs(\n \"span\",\n {\n style: {\n transform: \"var(--radix-slider-thumb-transform)\",\n position: \"absolute\",\n [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`\n },\n children: [\n /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(\n Primitive.span,\n {\n role: \"slider\",\n \"aria-label\": props[\"aria-label\"] || label,\n \"aria-valuemin\": context.min,\n \"aria-valuenow\": value,\n \"aria-valuemax\": context.max,\n \"aria-orientation\": context.orientation,\n \"data-orientation\": context.orientation,\n \"data-disabled\": context.disabled ? \"\" : void 0,\n tabIndex: context.disabled ? void 0 : 0,\n ...thumbProps,\n ref: composedRefs,\n style: value === void 0 ? { display: \"none\" } : props.style,\n onFocus: composeEventHandlers(props.onFocus, () => {\n context.valueIndexToChangeRef.current = index;\n })\n }\n ) }),\n isFormControl && /* @__PURE__ */ jsx(\n SliderBubbleInput,\n {\n name: name ?? (context.name ? context.name + (context.values.length > 1 ? \"[]\" : \"\") : void 0),\n form: context.form,\n value\n },\n index\n )\n ]\n }\n );\n }\n);\nSliderThumb.displayName = THUMB_NAME;\nvar BUBBLE_INPUT_NAME = \"RadioBubbleInput\";\nvar SliderBubbleInput = React.forwardRef(\n ({ __scopeSlider, value, ...props }, forwardedRef) => {\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(ref, forwardedRef);\n const prevValue = usePrevious(value);\n React.useEffect(() => {\n const input = ref.current;\n if (!input) return;\n const inputProto = window.HTMLInputElement.prototype;\n const descriptor = Object.getOwnPropertyDescriptor(inputProto, \"value\");\n const setValue = descriptor.set;\n if (prevValue !== value && setValue) {\n const event = new Event(\"input\", { bubbles: true });\n setValue.call(input, value);\n input.dispatchEvent(event);\n }\n }, [prevValue, value]);\n return /* @__PURE__ */ jsx(\n Primitive.input,\n {\n style: { display: \"none\" },\n ...props,\n ref: composedRefs,\n defaultValue: value\n }\n );\n }\n);\nSliderBubbleInput.displayName = BUBBLE_INPUT_NAME;\nfunction getNextSortedValues(prevValues = [], nextValue, atIndex) {\n const nextValues = [...prevValues];\n nextValues[atIndex] = nextValue;\n return nextValues.sort((a, b) => a - b);\n}\nfunction convertValueToPercentage(value, min, max) {\n const maxSteps = max - min;\n const percentPerStep = 100 / maxSteps;\n const percentage = percentPerStep * (value - min);\n return clamp(percentage, [0, 100]);\n}\nfunction getLabel(index, totalValues) {\n if (totalValues > 2) {\n return `Value ${index + 1} of ${totalValues}`;\n } else if (totalValues === 2) {\n return [\"Minimum\", \"Maximum\"][index];\n } else {\n return void 0;\n }\n}\nfunction getClosestValueIndex(values, nextValue) {\n if (values.length === 1) return 0;\n const distances = values.map((value) => Math.abs(value - nextValue));\n const closestDistance = Math.min(...distances);\n return distances.indexOf(closestDistance);\n}\nfunction getThumbInBoundsOffset(width, left, direction) {\n const halfWidth = width / 2;\n const halfPercent = 50;\n const offset = linearScale([0, halfPercent], [0, halfWidth]);\n return (halfWidth - offset(left) * direction) * direction;\n}\nfunction getStepsBetweenValues(values) {\n return values.slice(0, -1).map((value, index) => values[index + 1] - value);\n}\nfunction hasMinStepsBetweenValues(values, minStepsBetweenValues) {\n if (minStepsBetweenValues > 0) {\n const stepsBetweenValues = getStepsBetweenValues(values);\n const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);\n return actualMinStepsBetweenValues >= minStepsBetweenValues;\n }\n return true;\n}\nfunction linearScale(input, output) {\n return (value) => {\n if (input[0] === input[1] || output[0] === output[1]) return output[0];\n const ratio = (output[1] - output[0]) / (input[1] - input[0]);\n return output[0] + ratio * (value - input[0]);\n };\n}\nfunction getDecimalCount(value) {\n return (String(value).split(\".\")[1] || \"\").length;\n}\nfunction roundValue(value, decimalCount) {\n const rounder = Math.pow(10, decimalCount);\n return Math.round(value * rounder) / rounder;\n}\nvar Root = Slider;\nvar Track = SliderTrack;\nvar Range = SliderRange;\nvar Thumb = SliderThumb;\nexport {\n Range,\n Root,\n Slider,\n SliderRange,\n SliderThumb,\n SliderTrack,\n Thumb,\n Track,\n createSliderScope\n};\n//# sourceMappingURL=index.mjs.map\n","'use client';\n\nimport * as React from 'react';\nimport { Slider as SliderPrimitive } from 'radix-ui';\n\nimport { cn } from '@/lib/utils';\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: React.ComponentProps<typeof SliderPrimitive.Root>) {\n const _values = React.useMemo(\n () => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),\n [value, defaultValue, min, max]\n );\n\n return (\n <SliderPrimitive.Root\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n className={cn(\n 'relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className={cn(\n 'bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5'\n )}\n >\n <SliderPrimitive.Range\n data-slot=\"slider-range\"\n className={cn(\n 'bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full'\n )}\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Root>\n );\n}\n\nexport { Slider };\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport { Slider } from '@/components/ui/slider';\n\n/** Fixed duration presets in seconds — slider snaps to these values */\nconst PRESETS = [\n 60, // 1m\n 120, // 2m\n 300, // 5m\n 600, // 10m\n 900, // 15m\n 1800, // 30m\n 2700, // 45m\n 3600, // 1h\n 7200, // 2h\n 10800, // 3h\n 14400, // 4h\n 21600, // 6h\n 28800, // 8h\n 43200, // 12h\n 86400, // 24h\n];\n\nconst SLIDER_MAX = PRESETS.length - 1;\n\n/** Find the closest preset index for a given seconds value */\nfunction secondsToIndex(seconds: number): number {\n let closest = 0;\n let minDiff = Math.abs(seconds - PRESETS[0]);\n for (let i = 1; i < PRESETS.length; i++) {\n const diff = Math.abs(seconds - PRESETS[i]);\n if (diff < minDiff) {\n minDiff = diff;\n closest = i;\n }\n }\n return closest;\n}\n\nexport interface TimeoutSliderProps {\n id: string;\n testId: string;\n /** Current value in seconds (as a string for form compatibility) */\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n defaultSeconds?: number;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.round((totalSeconds % 3600) / 60);\n\n if (hours === 0) return `${minutes}m`;\n if (minutes === 0) return `${hours}h`;\n return `${hours}h ${minutes}m`;\n}\n\nexport function TimeoutSlider({\n id,\n testId,\n value,\n onChange,\n onBlur,\n defaultSeconds = 1800,\n}: TimeoutSliderProps) {\n const numValue = value === '' ? defaultSeconds : parseInt(value, 10);\n const seconds = numValue || defaultSeconds;\n\n // Local index state prevents snap-back during drag — updates immediately\n // without waiting for the parent to re-render with the new value.\n const [localIndex, setLocalIndex] = useState(() => secondsToIndex(seconds));\n\n // Sync from props only when the resolved index actually differs\n // (e.g. external reset or server push). Avoids overwriting during drag.\n const propsIndex = secondsToIndex(seconds);\n if (propsIndex !== localIndex && PRESETS[localIndex] !== seconds) {\n setLocalIndex(propsIndex);\n }\n\n const handleChange = useCallback(\n ([i]: number[]) => {\n setLocalIndex(i);\n onChange(String(PRESETS[i]));\n },\n [onChange]\n );\n\n return (\n <div className=\"flex w-55 items-center gap-2\">\n <Slider\n id={id}\n data-testid={testId}\n min={0}\n max={SLIDER_MAX}\n step={1}\n value={[localIndex]}\n onValueChange={handleChange}\n onValueCommit={() => onBlur()}\n className=\"min-w-0 flex-1\"\n />\n <span className=\"text-muted-foreground shrink-0 text-end text-xs tabular-nums\">\n {formatDuration(PRESETS[localIndex])}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Timer } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { TimeoutSlider } from '@/components/features/settings/timeout-slider';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SubsectionLabel } from './settings-section-utils';\n\nexport interface StageTimeoutsSettingsSectionProps {\n settings: Settings;\n}\n\nexport function parseOptionalInt(value: string): number | undefined {\n if (value === '') return undefined;\n const n = parseInt(value, 10);\n return Number.isNaN(n) || n <= 0 ? undefined : n;\n}\n\nexport function secondsToMs(val: string | undefined): number | undefined {\n if (val === undefined) return undefined;\n const n = parseOptionalInt(val);\n return n != null ? n * 1000 : undefined;\n}\n\nexport function StageTimeoutsSettingsSection({ settings }: StageTimeoutsSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const stageTimeoutsConfig = settings.workflow.stageTimeouts;\n const analyzeRepoConfig = settings.workflow.analyzeRepoTimeouts;\n\n const [analyzeTimeout, setAnalyzeTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.analyzeMs ?? 1_800_000) / 1000))\n );\n const [requirementsTimeout, setRequirementsTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.requirementsMs ?? 1_800_000) / 1000))\n );\n const [researchTimeout, setResearchTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.researchMs ?? 1_800_000) / 1000))\n );\n const [planTimeout, setPlanTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.planMs ?? 1_800_000) / 1000))\n );\n const [implementTimeout, setImplementTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.implementMs ?? 1_800_000) / 1000))\n );\n const [mergeTimeout, setMergeTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.mergeMs ?? 1_800_000) / 1000))\n );\n const [analyzeRepoTimeout, setAnalyzeRepoTimeout] = useState(\n String(Math.round((analyzeRepoConfig?.analyzeMs ?? 600_000) / 1000))\n );\n\n const originalAnalyzeTimeout =\n stageTimeoutsConfig?.analyzeMs != null\n ? String(Math.round(stageTimeoutsConfig.analyzeMs / 1000))\n : '';\n const originalRequirementsTimeout =\n stageTimeoutsConfig?.requirementsMs != null\n ? String(Math.round(stageTimeoutsConfig.requirementsMs / 1000))\n : '';\n const originalResearchTimeout =\n stageTimeoutsConfig?.researchMs != null\n ? String(Math.round(stageTimeoutsConfig.researchMs / 1000))\n : '';\n const originalPlanTimeout =\n stageTimeoutsConfig?.planMs != null\n ? String(Math.round(stageTimeoutsConfig.planMs / 1000))\n : '';\n const originalImplementTimeout =\n stageTimeoutsConfig?.implementMs != null\n ? String(Math.round(stageTimeoutsConfig.implementMs / 1000))\n : '';\n const originalMergeTimeout =\n stageTimeoutsConfig?.mergeMs != null\n ? String(Math.round(stageTimeoutsConfig.mergeMs / 1000))\n : '';\n const originalAnalyzeRepoTimeout =\n analyzeRepoConfig?.analyzeMs != null\n ? String(Math.round(analyzeRepoConfig.analyzeMs / 1000))\n : '';\n\n function buildPayload(overrides: {\n analyzeTimeout?: string;\n requirementsTimeout?: string;\n researchTimeout?: string;\n planTimeout?: string;\n implementTimeout?: string;\n mergeTimeout?: string;\n analyzeRepoTimeout?: string;\n }) {\n return {\n workflow: {\n stageTimeouts: {\n analyzeMs: secondsToMs(overrides.analyzeTimeout ?? analyzeTimeout),\n requirementsMs: secondsToMs(overrides.requirementsTimeout ?? requirementsTimeout),\n researchMs: secondsToMs(overrides.researchTimeout ?? researchTimeout),\n planMs: secondsToMs(overrides.planTimeout ?? planTimeout),\n implementMs: secondsToMs(overrides.implementTimeout ?? implementTimeout),\n mergeMs: secondsToMs(overrides.mergeTimeout ?? mergeTimeout),\n },\n analyzeRepoTimeouts: {\n analyzeMs: secondsToMs(overrides.analyzeRepoTimeout ?? analyzeRepoTimeout),\n },\n },\n };\n }\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Timer}\n title={t('settings.stageTimeouts.title')}\n description={t('settings.stageTimeouts.description')}\n testId=\"stage-timeouts-settings-section\"\n tooltip={t('settings.stageTimeouts.hint')}\n >\n <SubsectionLabel>{t('settings.stageTimeouts.subsections.featureAgent')}</SubsectionLabel>\n <SettingsRow\n label={t('settings.stageTimeouts.analyze')}\n description={t('settings.stageTimeouts.analyzeDescription')}\n htmlFor=\"timeout-analyze\"\n >\n <TimeoutSlider\n id=\"timeout-analyze\"\n testId=\"timeout-analyze-input\"\n value={analyzeTimeout}\n onChange={setAnalyzeTimeout}\n onBlur={() => {\n if (analyzeTimeout !== originalAnalyzeTimeout) save(buildPayload({ analyzeTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.requirements')}\n description={t('settings.stageTimeouts.requirementsDescription')}\n htmlFor=\"timeout-requirements\"\n >\n <TimeoutSlider\n id=\"timeout-requirements\"\n testId=\"timeout-requirements-input\"\n value={requirementsTimeout}\n onChange={setRequirementsTimeout}\n onBlur={() => {\n if (requirementsTimeout !== originalRequirementsTimeout)\n save(buildPayload({ requirementsTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.research')}\n description={t('settings.stageTimeouts.researchDescription')}\n htmlFor=\"timeout-research\"\n >\n <TimeoutSlider\n id=\"timeout-research\"\n testId=\"timeout-research-input\"\n value={researchTimeout}\n onChange={setResearchTimeout}\n onBlur={() => {\n if (researchTimeout !== originalResearchTimeout)\n save(buildPayload({ researchTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.plan')}\n description={t('settings.stageTimeouts.planDescription')}\n htmlFor=\"timeout-plan\"\n >\n <TimeoutSlider\n id=\"timeout-plan\"\n testId=\"timeout-plan-input\"\n value={planTimeout}\n onChange={setPlanTimeout}\n onBlur={() => {\n if (planTimeout !== originalPlanTimeout) save(buildPayload({ planTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.implement')}\n description={t('settings.stageTimeouts.implementDescription')}\n htmlFor=\"timeout-implement\"\n >\n <TimeoutSlider\n id=\"timeout-implement\"\n testId=\"timeout-implement-input\"\n value={implementTimeout}\n onChange={setImplementTimeout}\n onBlur={() => {\n if (implementTimeout !== originalImplementTimeout)\n save(buildPayload({ implementTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.merge')}\n description={t('settings.stageTimeouts.mergeDescription')}\n htmlFor=\"timeout-merge\"\n >\n <TimeoutSlider\n id=\"timeout-merge\"\n testId=\"timeout-merge-input\"\n value={mergeTimeout}\n onChange={setMergeTimeout}\n onBlur={() => {\n if (mergeTimeout !== originalMergeTimeout) save(buildPayload({ mergeTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SubsectionLabel>{t('settings.stageTimeouts.subsections.analyzeRepoAgent')}</SubsectionLabel>\n <SettingsRow\n label={t('settings.stageTimeouts.analyze')}\n description={t('settings.stageTimeouts.analyzeDescription')}\n htmlFor=\"timeout-analyze-repo\"\n >\n <TimeoutSlider\n id=\"timeout-analyze-repo\"\n testId=\"timeout-analyze-repo-input\"\n value={analyzeRepoTimeout}\n onChange={setAnalyzeRepoTimeout}\n onBlur={() => {\n if (analyzeRepoTimeout !== originalAnalyzeRepoTimeout)\n save(buildPayload({ analyzeRepoTimeout }));\n }}\n defaultSeconds={600}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Bell } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, NotificationPreferences } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow, SubsectionLabel } from './settings-section-utils';\n\nexport interface NotificationSettingsSectionProps {\n settings: Settings;\n}\n\nexport function NotificationSettingsSection({ settings }: NotificationSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [inApp, setInApp] = useState(settings.notifications.inApp.enabled);\n const [events, setEvents] = useState({ ...settings.notifications.events });\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildNotificationPayload(\n overrides: {\n inApp?: boolean;\n events?: NotificationPreferences['events'];\n } = {}\n ) {\n return {\n notifications: {\n inApp: { enabled: overrides.inApp ?? inApp },\n events: overrides.events ?? events,\n },\n };\n }\n\n return (\n <SettingsSection\n icon={Bell}\n title={t('settings.notifications.title')}\n description={t('settings.notifications.sectionDescription')}\n testId=\"notification-settings-section\"\n tooltip={t('settings.notifications.hint')}\n tooltipLinks={[\n {\n label: t('settings.notifications.links.notificationSystem'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/021-agent-notifications/spec.yaml',\n },\n ]}\n >\n <SubsectionLabel>{t('settings.notifications.channels')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.inAppLabel')}\n description={t('settings.notifications.inAppDescription')}\n tooltip=\"Master toggle for in-app toast notifications. When disabled, no event toasts will appear regardless of individual event settings below.\"\n id=\"notif-in-app\"\n testId=\"switch-in-app\"\n checked={inApp}\n onChange={(v) => {\n setInApp(v);\n save(buildNotificationPayload({ inApp: v }));\n }}\n />\n\n <SubsectionLabel>{t('settings.notifications.subsections.agentEvents')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.events.agentStarted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent begins working on a feature.\"\n id=\"notif-event-agentStarted\"\n testId=\"switch-event-agentStarted\"\n checked={events.agentStarted}\n onChange={(v) => {\n const newEvents = { ...events, agentStarted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.phaseCompleted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent completes a workflow phase (e.g., requirements, planning, implementation).\"\n id=\"notif-event-phaseCompleted\"\n testId=\"switch-event-phaseCompleted\"\n checked={events.phaseCompleted}\n onChange={(v) => {\n const newEvents = { ...events, phaseCompleted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.waitingApproval')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature is paused and waiting for your approval to continue.\"\n id=\"notif-event-waitingApproval\"\n testId=\"switch-event-waitingApproval\"\n checked={events.waitingApproval}\n onChange={(v) => {\n const newEvents = { ...events, waitingApproval: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.agentCompleted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent finishes all work on a feature successfully.\"\n id=\"notif-event-agentCompleted\"\n testId=\"switch-event-agentCompleted\"\n checked={events.agentCompleted}\n onChange={(v) => {\n const newEvents = { ...events, agentCompleted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.agentFailed')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent encounters an error and stops working on a feature.\"\n id=\"notif-event-agentFailed\"\n testId=\"switch-event-agentFailed\"\n checked={events.agentFailed}\n onChange={(v) => {\n const newEvents = { ...events, agentFailed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n\n <SubsectionLabel>{t('settings.notifications.subsections.pullRequestEvents')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.events.prMerged')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's pull request is merged into the target branch.\"\n id=\"notif-event-prMerged\"\n testId=\"switch-event-prMerged\"\n checked={events.prMerged}\n onChange={(v) => {\n const newEvents = { ...events, prMerged: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prClosed')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's pull request is closed without merging.\"\n id=\"notif-event-prClosed\"\n testId=\"switch-event-prClosed\"\n checked={events.prClosed}\n onChange={(v) => {\n const newEvents = { ...events, prClosed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prChecksPassed')}\n tooltip=\"Controls whether you receive an in-app toast notification when all CI checks pass on a feature's pull request.\"\n id=\"notif-event-prChecksPassed\"\n testId=\"switch-event-prChecksPassed\"\n checked={events.prChecksPassed}\n onChange={(v) => {\n const newEvents = { ...events, prChecksPassed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prChecksFailed')}\n tooltip=\"Controls whether you receive an in-app toast notification when CI checks fail on a feature's pull request.\"\n id=\"notif-event-prChecksFailed\"\n testId=\"switch-event-prChecksFailed\"\n checked={events.prChecksFailed}\n onChange={(v) => {\n const newEvents = { ...events, prChecksFailed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prBlocked')}\n tooltip=\"Controls whether you receive an in-app toast notification when a pull request is blocked by merge conflicts or branch protection rules.\"\n id=\"notif-event-prBlocked\"\n testId=\"switch-event-prBlocked\"\n checked={events.prBlocked}\n onChange={(v) => {\n const newEvents = { ...events, prBlocked: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.mergeReviewReady')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's PR passes all checks and is ready for your merge review.\"\n id=\"notif-event-mergeReviewReady\"\n testId=\"switch-event-mergeReviewReady\"\n checked={events.mergeReviewReady}\n onChange={(v) => {\n const newEvents = { ...events, mergeReviewReady: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Flag } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, FeatureFlags } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow } from './settings-section-utils';\n\nexport interface FeatureFlagsSettingsSectionProps {\n settings: Settings;\n}\n\nexport function FeatureFlagsSettingsSection({ settings }: FeatureFlagsSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const featureFlags = settings.featureFlags ?? {\n skills: false,\n envDeploy: false,\n debug: false,\n githubImport: false,\n adoptBranch: false,\n gitRebaseSync: false,\n reactFileManager: false,\n plugins: false,\n mcpServers: false,\n };\n\n const [flags, setFlags] = useState<FeatureFlags>({ ...featureFlags });\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Flag}\n title={t('settings.featureFlags.title')}\n description={t('settings.featureFlags.sectionDescription')}\n badge={t('settings.featureFlags.badge')}\n testId=\"feature-flags-settings-section\"\n tooltip={t('settings.featureFlags.hint')}\n >\n <SwitchRow\n label={t('settings.featureFlags.skills')}\n description={t('settings.featureFlags.skillsDescription')}\n tooltip=\"Enables the Skills page in the sidebar for browsing and managing Claude Code skills.\"\n id=\"flag-skills\"\n testId=\"switch-flag-skills\"\n checked={flags.skills}\n onChange={(v) => {\n const newFlags = { ...flags, skills: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.deployments')}\n description={t('settings.featureFlags.deploymentsDescription')}\n tooltip=\"Enables experimental deployment features for environment management.\"\n id=\"flag-envDeploy\"\n testId=\"switch-flag-envDeploy\"\n checked={flags.envDeploy}\n onChange={(v) => {\n const newFlags = { ...flags, envDeploy: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.debug')}\n description={t('settings.featureFlags.debugDescription')}\n tooltip=\"Shows additional debugging information in the UI for troubleshooting.\"\n id=\"flag-debug\"\n testId=\"switch-flag-debug\"\n checked={flags.debug}\n onChange={(v) => {\n const newFlags = { ...flags, debug: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.githubImport')}\n description={t('settings.featureFlags.githubImportDescription')}\n tooltip=\"Enables importing repositories directly from GitHub.\"\n id=\"flag-githubImport\"\n testId=\"switch-flag-githubImport\"\n checked={flags.githubImport}\n onChange={(v) => {\n const newFlags = { ...flags, githubImport: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.adoptBranch')}\n description={t('settings.featureFlags.adoptBranchDescription')}\n tooltip=\"Enables adopting existing git branches as ShipIT features.\"\n id=\"flag-adoptBranch\"\n testId=\"switch-flag-adoptBranch\"\n checked={flags.adoptBranch}\n onChange={(v) => {\n const newFlags = { ...flags, adoptBranch: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.gitRebaseSync')}\n description={t('settings.featureFlags.gitRebaseSyncDescription')}\n tooltip=\"Uses git rebase instead of merge when syncing feature branches with the upstream branch.\"\n id=\"flag-gitRebaseSync\"\n testId=\"switch-flag-gitRebaseSync\"\n checked={flags.gitRebaseSync}\n onChange={(v) => {\n const newFlags = { ...flags, gitRebaseSync: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.reactFileManager')}\n description={t('settings.featureFlags.reactFileManagerDescription')}\n tooltip=\"Replaces the native file picker dialog with a React-based file browser for selecting project folders.\"\n id=\"flag-reactFileManager\"\n testId=\"switch-flag-reactFileManager\"\n checked={flags.reactFileManager}\n onChange={(v) => {\n const newFlags = { ...flags, reactFileManager: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.plugins')}\n description={\n settings.litellmProxy?.baseUrl\n ? t('settings.featureFlags.pluginsDescription')\n : `${t('settings.featureFlags.pluginsDescription')} — ${t('plugins.noProxy')}`\n }\n tooltip=\"Enables the Plugins page for browsing and managing Claude Code plugins from a LiteLLM marketplace. Requires a LiteLLM proxy URL to be configured.\"\n id=\"flag-plugins\"\n testId=\"switch-flag-plugins\"\n checked={flags.plugins}\n disabled={!settings.litellmProxy?.baseUrl}\n onChange={(v) => {\n const newFlags = { ...flags, plugins: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.mcpServers')}\n description={\n settings.litellmProxy?.baseUrl\n ? t('settings.featureFlags.mcpServersDescription')\n : `${t('settings.featureFlags.mcpServersDescription')} — ${t('mcpServers.noProxy')}`\n }\n tooltip=\"Enables the MCP Servers page for viewing MCP servers deployed on your LiteLLM proxy. Requires a LiteLLM proxy URL to be configured.\"\n id=\"flag-mcp-servers\"\n testId=\"switch-flag-mcp-servers\"\n checked={flags.mcpServers}\n disabled={!settings.litellmProxy?.baseUrl}\n onChange={(v) => {\n const newFlags = { ...flags, mcpServers: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { MessageSquare } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, InteractiveAgentConfig } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SwitchRow, NumberStepper } from './settings-section-utils';\n\nexport interface InteractiveAgentSettingsSectionProps {\n settings: Settings;\n}\n\nexport function InteractiveAgentSettingsSection({\n settings,\n}: InteractiveAgentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const interactiveAgentConfig: InteractiveAgentConfig = settings.interactiveAgent ?? {\n enabled: true,\n autoTimeoutMinutes: 15,\n maxConcurrentSessions: 3,\n };\n\n const [interactiveEnabled, setInteractiveEnabled] = useState(interactiveAgentConfig.enabled);\n const [interactiveTimeout, setInteractiveTimeout] = useState(\n String(interactiveAgentConfig.autoTimeoutMinutes)\n );\n const [interactiveSessions, setInteractiveSessions] = useState(\n String(interactiveAgentConfig.maxConcurrentSessions)\n );\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={MessageSquare}\n title={t('settings.interactiveAgent.title')}\n description={t('settings.interactiveAgent.description')}\n testId=\"interactive-agent-settings-section\"\n tooltip={t('settings.interactiveAgent.hint')}\n >\n <SwitchRow\n label={t('settings.interactiveAgent.enableChatTab')}\n description={t('settings.interactiveAgent.enableChatTabDescription')}\n tooltip=\"Shows or hides the Chat tab on feature detail pages. When enabled, you can have interactive conversations with the agent about a specific feature.\"\n id=\"interactive-agent-enabled\"\n testId=\"switch-interactive-agent-enabled\"\n checked={interactiveEnabled}\n onChange={(v) => {\n setInteractiveEnabled(v);\n save({\n interactiveAgent: {\n enabled: v,\n autoTimeoutMinutes: parseInt(interactiveTimeout, 10) || 15,\n maxConcurrentSessions: parseInt(interactiveSessions, 10) || 3,\n },\n });\n }}\n />\n <SettingsRow\n label={t('settings.interactiveAgent.autoTimeout')}\n description={t('settings.interactiveAgent.autoTimeoutDescription')}\n tooltip=\"Minutes of inactivity before a chat agent session is automatically terminated. Prevents idle agent processes from consuming resources indefinitely.\"\n htmlFor=\"interactive-agent-timeout\"\n >\n <NumberStepper\n id=\"interactive-agent-timeout\"\n testId=\"input-interactive-agent-timeout\"\n value={interactiveTimeout}\n placeholder=\"15\"\n min={1}\n max={120}\n suffix=\"min\"\n onChange={setInteractiveTimeout}\n onBlur={() => {\n const n = parseInt(interactiveTimeout, 10);\n const clamped = Number.isNaN(n) ? 15 : Math.min(120, Math.max(1, n));\n const clampedStr = String(clamped);\n setInteractiveTimeout(clampedStr);\n save({\n interactiveAgent: {\n enabled: interactiveEnabled,\n autoTimeoutMinutes: clamped,\n maxConcurrentSessions: parseInt(interactiveSessions, 10) || 3,\n },\n });\n }}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.interactiveAgent.maxConcurrentSessions')}\n description={t('settings.interactiveAgent.maxConcurrentSessionsDescription')}\n tooltip=\"Maximum number of interactive agent sessions that can run simultaneously. Each session spawns a separate agent process, so higher values use more CPU and memory.\"\n htmlFor=\"interactive-agent-sessions\"\n >\n <NumberStepper\n id=\"interactive-agent-sessions\"\n testId=\"input-interactive-agent-sessions\"\n value={interactiveSessions}\n placeholder=\"3\"\n min={1}\n max={10}\n onChange={setInteractiveSessions}\n onBlur={() => {\n const n = parseInt(interactiveSessions, 10);\n const clamped = Number.isNaN(n) ? 3 : Math.min(10, Math.max(1, n));\n const clampedStr = String(clamped);\n setInteractiveSessions(clampedStr);\n save({\n interactiveAgent: {\n enabled: interactiveEnabled,\n autoTimeoutMinutes: parseInt(interactiveTimeout, 10) || 15,\n maxConcurrentSessions: clamped,\n },\n });\n }}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { LayoutGrid } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, FabLayoutConfig } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow } from './settings-section-utils';\n\nexport interface FabLayoutSettingsSectionProps {\n settings: Settings;\n}\n\nexport function FabLayoutSettingsSection({ settings }: FabLayoutSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const fabLayoutConfig: FabLayoutConfig = settings.fabLayout ?? { swapPosition: false };\n const [fabSwapPosition, setFabSwapPosition] = useState(fabLayoutConfig.swapPosition);\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={LayoutGrid}\n title={t('settings.fabLayout.title')}\n description={t('settings.fabLayout.description')}\n testId=\"fab-layout-settings-section\"\n tooltip={t('settings.fabLayout.hint')}\n >\n <SwitchRow\n label={t('settings.fabLayout.swapPosition')}\n description={t('settings.fabLayout.swapPositionDescription')}\n tooltip=\"Swaps the Create button (bottom-right) and Chat button (bottom-left) positions on the control center canvas.\"\n id=\"fab-swap-position\"\n testId=\"switch-fab-swap-position\"\n checked={fabSwapPosition}\n onChange={(v) => {\n setFabSwapPosition(v);\n save({ fabLayout: { swapPosition: v } });\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { Database } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\n\nexport interface DatabaseSettingsSectionProps {\n shipitAiHome: string;\n dbFileSize: string;\n}\n\nexport function DatabaseSettingsSection({\n shipitAiHome,\n dbFileSize,\n}: DatabaseSettingsSectionProps) {\n const { t } = useTranslation('web');\n\n return (\n <SettingsSection\n icon={Database}\n title={t('settings.database.title')}\n description={t('settings.database.sectionDescription')}\n testId=\"database-settings-section\"\n tooltip={t('settings.database.hint')}\n tooltipLinks={[\n {\n label: t('settings.database.links.settingsService'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/settings-service.md',\n },\n {\n label: t('settings.database.links.settingsSpec'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/005-global-settings-service/spec.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.database.location')}\n description={t('settings.database.locationDescription')}\n tooltip=\"The directory where ShipIT stores its SQLite database, logs, and configuration files. Change this via the SHIPIT_AI_HOME environment variable.\"\n >\n <span\n className=\"text-muted-foreground max-w-50 truncate font-mono text-xs\"\n data-testid=\"shipit-ai-home-path\"\n >\n {shipitAiHome}\n </span>\n </SettingsRow>\n <SettingsRow\n label={t('settings.database.size')}\n tooltip=\"Current size of the SQLite database file on disk. Large databases may slow down startup; consider archiving old features if this grows significantly.\"\n >\n <span className=\"text-muted-foreground text-xs\" data-testid=\"db-file-size\">\n {dbFileSize}\n </span>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40fd64c4bf0dcdef52a9cf199b2f48110acd18fd8b\":{\"name\":\"addMarketplaceAction\"}},\"src/presentation/web/app/actions/add-marketplace.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40fd64c4bf0dcdef52a9cf199b2f48110acd18fd8b\",callServer,void 0,findSourceMapURL,\"addMarketplaceAction\");export{$$RSC_SERVER_ACTION_0 as addMarketplaceAction};","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Server, CheckCircle2, XCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { addMarketplaceAction } from '@/app/actions/add-marketplace';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\n\nexport interface LiteLLMProxySettingsSectionProps {\n settings: Settings;\n}\n\nexport function LiteLLMProxySettingsSection({ settings }: LiteLLMProxySettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [baseUrl, setBaseUrl] = useState(settings.litellmProxy?.baseUrl ?? '');\n const [apiKey, setApiKey] = useState(settings.litellmProxy?.apiKey ?? '');\n const [testStatus, setTestStatus] = useState<'idle' | 'success' | 'failed'>('idle');\n const [isTesting, setIsTesting] = useState(false);\n\n const originalBaseUrl = settings.litellmProxy?.baseUrl ?? '';\n const originalApiKey = settings.litellmProxy?.apiKey ?? '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(overrides?: { baseUrl?: string; apiKey?: string }) {\n const url = overrides?.baseUrl ?? baseUrl;\n return {\n litellmProxy: {\n baseUrl: url,\n apiKey: overrides?.apiKey ?? apiKey,\n marketplaceEnabled: !!url,\n },\n };\n }\n\n async function handleTestConnection() {\n if (!baseUrl) return;\n setIsTesting(true);\n setTestStatus('idle');\n try {\n const marketplaceUrl = `${baseUrl.replace(/\\/+$/, '')}/claude-code/marketplace.json`;\n const result = await addMarketplaceAction(marketplaceUrl);\n setTestStatus(result.success ? 'success' : 'failed');\n if (result.success) {\n toast.success(t('settings.litellmProxy.testSuccess'));\n } else {\n toast.error(t('settings.litellmProxy.testFailed'));\n }\n } catch {\n setTestStatus('failed');\n toast.error(t('settings.litellmProxy.testFailed'));\n } finally {\n setIsTesting(false);\n }\n }\n\n return (\n <SettingsSection\n icon={Server}\n title={t('settings.litellmProxy.title')}\n description={t('settings.litellmProxy.description')}\n testId=\"litellm-proxy-settings-section\"\n tooltip={t('settings.litellmProxy.hint')}\n >\n <SettingsRow\n label={t('settings.litellmProxy.baseUrl')}\n description={t('settings.litellmProxy.baseUrlDescription')}\n tooltip=\"The base URL of your LiteLLM proxy server. This is used to fetch the plugin marketplace catalog and route model requests.\"\n htmlFor=\"litellm-proxy-url\"\n >\n <Input\n id=\"litellm-proxy-url\"\n data-testid=\"litellm-proxy-url-input\"\n type=\"text\"\n placeholder=\"http://localhost:4000\"\n value={baseUrl}\n onChange={(e) => {\n setBaseUrl(e.target.value);\n setTestStatus('idle');\n }}\n onBlur={() => {\n if (baseUrl !== originalBaseUrl) save(buildPayload({ baseUrl }));\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.litellmProxy.apiKey')}\n description={t('settings.litellmProxy.apiKeyDescription')}\n tooltip=\"A virtual API key for authenticating with the LiteLLM proxy. Stored locally alongside other agent credentials.\"\n htmlFor=\"litellm-api-key\"\n >\n <Input\n id=\"litellm-api-key\"\n data-testid=\"litellm-api-key-input\"\n type=\"password\"\n placeholder=\"sk-...\"\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n onBlur={() => {\n if (apiKey !== originalApiKey) save(buildPayload({ apiKey }));\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.litellmProxy.testConnection')}\n tooltip=\"Attempt to connect to the proxy and fetch the marketplace catalog to verify the configuration is correct.\"\n >\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n data-testid=\"litellm-test-connection-btn\"\n disabled={!baseUrl || isTesting}\n onClick={handleTestConnection}\n className=\"cursor-pointer text-xs\"\n >\n {isTesting ? t('settings.saving') : t('settings.litellmProxy.testConnection')}\n </Button>\n {testStatus === 'success' && (\n <CheckCircle2 className=\"h-4 w-4 text-emerald-500\" data-testid=\"litellm-test-success\" />\n )}\n {testStatus === 'failed' && (\n <XCircle className=\"text-destructive h-4 w-4\" data-testid=\"litellm-test-failed\" />\n )}\n </div>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Route } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { LiteLLMProxyRoutingMode } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\n\nexport interface LiteLLMProxyRoutingSectionProps {\n settings: Settings;\n}\n\n/** Agent types that support env-var-based proxy routing (Tier 1) */\nconst TIER1_AGENTS = new Set(['claude-code', 'gemini-cli', 'codex-cli']);\n/** Agent types that need documentation-only panels (Tier 2) */\nconst TIER2_AGENTS = new Set(['cursor', 'copilot-cli']);\n\n/** Get the per-agent proxy config key for building payloads */\nfunction agentConfigKey(agentType: string): string | null {\n switch (agentType) {\n case 'claude-code':\n return 'claudeCode';\n case 'gemini-cli':\n return 'geminiCli';\n case 'codex-cli':\n return 'codexCli';\n default:\n return null;\n }\n}\n\n/** Get the current routing mode for the active agent */\nfunction getRoutingMode(settings: Settings): string {\n const agentType = settings.agent.type as string;\n switch (agentType) {\n case 'claude-code':\n return settings.litellmProxy?.claudeCode?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n case 'gemini-cli':\n return settings.litellmProxy?.geminiCli?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n case 'codex-cli':\n return settings.litellmProxy?.codexCli?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n default:\n return LiteLLMProxyRoutingMode.direct;\n }\n}\n\n/** Whether this agent supports passthrough mode */\nfunction supportsPassthrough(agentType: string): boolean {\n return agentType === 'claude-code';\n}\n\nexport function LiteLLMProxyRoutingSection({ settings }: LiteLLMProxyRoutingSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n const agentType = settings.agent.type as string;\n\n const cc = settings.litellmProxy?.claudeCode;\n const [routingMode, setRoutingMode] = useState<string>(getRoutingMode(settings));\n const [customHeaders, setCustomHeaders] = useState(cc?.customHeaders ?? '');\n const [sonnetModel, setSonnetModel] = useState(cc?.sonnetModel ?? '');\n const [haikuModel, setHaikuModel] = useState(cc?.haikuModel ?? '');\n const [opusModel, setOpusModel] = useState(cc?.opusModel ?? '');\n\n const originalCustomHeaders = cc?.customHeaders ?? '';\n const originalSonnetModel = cc?.sonnetModel ?? '';\n const originalHaikuModel = cc?.haikuModel ?? '';\n const originalOpusModel = cc?.opusModel ?? '';\n\n const showProxyFields = routingMode !== LiteLLMProxyRoutingMode.direct;\n const isTier1 = TIER1_AGENTS.has(agentType);\n const isTier2 = TIER2_AGENTS.has(agentType);\n const proxyUrl = settings.litellmProxy?.baseUrl ?? '';\n const proxyApiKey = settings.litellmProxy?.apiKey ?? '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(\n overrides?: Partial<{\n routingMode: string;\n customHeaders: string;\n sonnetModel: string;\n haikuModel: string;\n opusModel: string;\n }>\n ) {\n const key = agentConfigKey(agentType);\n if (!key) return {};\n\n if (agentType === 'claude-code') {\n return {\n litellmProxy: {\n claudeCode: {\n routingMode: overrides?.routingMode ?? routingMode,\n customHeaders: overrides?.customHeaders ?? customHeaders,\n sonnetModel: overrides?.sonnetModel ?? sonnetModel,\n haikuModel: overrides?.haikuModel ?? haikuModel,\n opusModel: overrides?.opusModel ?? opusModel,\n },\n },\n };\n }\n\n // Gemini CLI and Codex CLI: only routingMode\n return {\n litellmProxy: {\n [key]: {\n routingMode: overrides?.routingMode ?? routingMode,\n },\n },\n };\n }\n\n function handleModeChange(value: string) {\n setRoutingMode(value);\n save(buildPayload({ routingMode: value }));\n }\n\n // Unsupported agent type\n if (!isTier1 && !isTier2) {\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow label=\"\" description={t('settings.litellmProxy.routing.notSupported')}>\n <span />\n </SettingsRow>\n </SettingsSection>\n );\n }\n\n // Tier 2: Documentation-only panels\n if (isTier2) {\n const isCursor = agentType === 'cursor';\n const displayUrl = proxyUrl\n ? isCursor\n ? `${proxyUrl.replace(/\\/+$/, '')}/cursor`\n : proxyUrl\n : '';\n\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow\n label={\n isCursor\n ? t('settings.litellmProxy.routing.cursorInstructions')\n : t('settings.litellmProxy.routing.copilotInstructions')\n }\n description={\n isCursor\n ? t('settings.litellmProxy.routing.cursorDescription')\n : t('settings.litellmProxy.routing.copilotDescription')\n }\n >\n <div className=\"w-64 space-y-2\">\n <code className=\"bg-muted block rounded px-2 py-1 text-xs break-all\">{displayUrl}</code>\n {isCursor && proxyApiKey ? (\n <code className=\"bg-muted block rounded px-2 py-1 text-xs break-all\">\n {proxyApiKey}\n </code>\n ) : null}\n </div>\n </SettingsRow>\n </SettingsSection>\n );\n }\n\n // Tier 1: Env-var-based proxy routing (Claude Code, Gemini CLI, Codex CLI)\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow\n label={t('settings.litellmProxy.routing.mode')}\n description={t('settings.litellmProxy.routing.modeDescription')}\n htmlFor=\"litellm-routing-mode\"\n >\n <Select value={routingMode} onValueChange={handleModeChange}>\n <SelectTrigger\n id=\"litellm-routing-mode\"\n data-testid=\"litellm-routing-mode-select\"\n className=\"w-48 text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={LiteLLMProxyRoutingMode.direct}>\n {t('settings.litellmProxy.routing.modeDirect')}\n </SelectItem>\n <SelectItem value={LiteLLMProxyRoutingMode.proxy}>\n {t('settings.litellmProxy.routing.modeProxy')}\n </SelectItem>\n {supportsPassthrough(agentType) && (\n <SelectItem value={LiteLLMProxyRoutingMode.passthrough}>\n {t('settings.litellmProxy.routing.modePassthrough')}\n </SelectItem>\n )}\n </SelectContent>\n </Select>\n </SettingsRow>\n\n {routingMode === LiteLLMProxyRoutingMode.passthrough && (\n <SettingsRow label=\"\" description={t('settings.litellmProxy.routing.passthroughHelp')}>\n <span />\n </SettingsRow>\n )}\n\n {showProxyFields && agentType === 'claude-code' ? (\n <>\n <SettingsRow\n label={t('settings.litellmProxy.routing.customHeaders')}\n description={t('settings.litellmProxy.routing.customHeadersDescription')}\n htmlFor=\"litellm-custom-headers\"\n >\n <Textarea\n id=\"litellm-custom-headers\"\n data-testid=\"litellm-custom-headers-input\"\n placeholder={'x-litellm-customer-id: my-user\\nx-litellm-tags: project:acme'}\n value={customHeaders}\n onChange={(e) => setCustomHeaders(e.target.value)}\n onBlur={() => {\n if (customHeaders !== originalCustomHeaders) {\n save(buildPayload({ customHeaders }));\n }\n }}\n rows={3}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.sonnetModel')}\n description={t('settings.litellmProxy.routing.modelOverrideDescription')}\n htmlFor=\"litellm-sonnet-model\"\n >\n <Input\n id=\"litellm-sonnet-model\"\n data-testid=\"litellm-sonnet-model-input\"\n type=\"text\"\n placeholder=\"claude-sonnet-4-6\"\n value={sonnetModel}\n onChange={(e) => setSonnetModel(e.target.value)}\n onBlur={() => {\n if (sonnetModel !== originalSonnetModel) {\n save(buildPayload({ sonnetModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.haikuModel')}\n htmlFor=\"litellm-haiku-model\"\n >\n <Input\n id=\"litellm-haiku-model\"\n data-testid=\"litellm-haiku-model-input\"\n type=\"text\"\n placeholder=\"claude-haiku-4-5\"\n value={haikuModel}\n onChange={(e) => setHaikuModel(e.target.value)}\n onBlur={() => {\n if (haikuModel !== originalHaikuModel) {\n save(buildPayload({ haikuModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.opusModel')}\n htmlFor=\"litellm-opus-model\"\n >\n <Input\n id=\"litellm-opus-model\"\n data-testid=\"litellm-opus-model-input\"\n type=\"text\"\n placeholder=\"claude-opus-4-6\"\n value={opusModel}\n onChange={(e) => setOpusModel(e.target.value)}\n onBlur={() => {\n if (opusModel !== originalOpusModel) {\n save(buildPayload({ opusModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n </>\n ) : null}\n </SettingsSection>\n );\n}\n","import type { ComponentType, SVGProps } from 'react';\nimport Image from 'next/image';\nimport { Code, Rocket } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ntype IconProps = SVGProps<SVGSVGElement> & { className?: string };\n\n/** Fallback icon for unknown editor types. */\nfunction DefaultEditorIcon(props: IconProps) {\n return <Code className={cn('h-4 w-4', props.className)} {...(props as object)} />;\n}\n\nfunction VsCodeIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/vscode.svg\"\n alt=\"VS Code\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nVsCodeIcon.displayName = 'VsCodeIcon';\n\nfunction CursorEditorIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/agents/cursor.jpeg\"\n alt=\"Cursor\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nCursorEditorIcon.displayName = 'CursorEditorIcon';\n\nfunction WindsurfIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/windsurf.svg\"\n alt=\"Windsurf\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nWindsurfIcon.displayName = 'WindsurfIcon';\n\nfunction ZedIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/zed.svg\"\n alt=\"Zed\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nZedIcon.displayName = 'ZedIcon';\n\nfunction AntigravityIcon({ className, ...props }: IconProps) {\n return <Rocket className={cn('h-4 w-4', className)} {...(props as object)} />;\n}\nAntigravityIcon.displayName = 'AntigravityIcon';\n\nconst editorTypeIconMap: Record<string, ComponentType<IconProps>> = {\n vscode: VsCodeIcon,\n cursor: CursorEditorIcon,\n windsurf: WindsurfIcon,\n zed: ZedIcon,\n antigravity: AntigravityIcon,\n};\n\n/** Resolve an editor type string to its corresponding icon component. */\nexport function getEditorTypeIcon(editorType?: string): ComponentType<IconProps> {\n if (editorType && editorType in editorTypeIconMap) {\n return editorTypeIconMap[editorType];\n }\n return DefaultEditorIcon;\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '6', cy: '19', r: '3', key: '1kj8tv' }],\n ['path', { d: 'M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15', key: '1d8sl' }],\n ['circle', { cx: '18', cy: '5', r: '3', key: 'gq8acd' }],\n];\n\n/**\n * @component @name Route\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/route\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 Route = createLucideIcon('route', __iconNode);\n\nexport default Route;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['ellipse', { cx: '12', cy: '5', rx: '9', ry: '3', key: 'msslwz' }],\n ['path', { d: 'M3 5V19A9 3 0 0 0 21 19V5', key: '1wlel7' }],\n ['path', { d: 'M3 12A9 3 0 0 0 21 12', key: 'mv7ke4' }],\n];\n\n/**\n * @component @name Database\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/database\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 Database = createLucideIcon('database', __iconNode);\n\nexport default Database;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '7', height: '7', x: '3', y: '3', rx: '1', key: '1g98yp' }],\n ['rect', { width: '7', height: '7', x: '14', y: '3', rx: '1', key: '6d4xhi' }],\n ['rect', { width: '7', height: '7', x: '14', y: '14', rx: '1', key: 'nxv5o0' }],\n ['rect', { width: '7', height: '7', x: '3', y: '14', rx: '1', key: '1bb6yr' }],\n];\n\n/**\n * @component @name LayoutGrid\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layout-grid\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 LayoutGrid = createLucideIcon('layout-grid', __iconNode);\n\nexport default LayoutGrid;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '7', height: '7', x: '3', y: '3', rx: '1', key: '1g98yp' }],\n ['rect', { width: '7', height: '7', x: '3', y: '14', rx: '1', key: '1bb6yr' }],\n ['path', { d: 'M14 4h7', key: '3xa0d5' }],\n ['path', { d: 'M14 9h7', key: '1icrd9' }],\n ['path', { d: 'M14 15h7', key: '1mj8o2' }],\n ['path', { d: 'M14 20h7', key: '11slyb' }],\n];\n\n/**\n * @component @name LayoutList\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layout-list\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 LayoutList = createLucideIcon('layout-list', __iconNode);\n\nexport default LayoutList;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528',\n key: '1jaruq',\n },\n ],\n];\n\n/**\n * @component @name Flag\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/flag\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 Flag = createLucideIcon('flag', __iconNode);\n\nexport default Flag;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M10.268 21a2 2 0 0 0 3.464 0', key: 'vwvbt9' }],\n [\n 'path',\n {\n d: 'M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326',\n key: '11g9vi',\n },\n ],\n];\n\n/**\n * @component @name Bell\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/bell\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 Bell = createLucideIcon('bell', __iconNode);\n\nexport default Bell;\n","import * as React from 'react';\nimport { clamp } from '@radix-ui/number';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\nimport { usePrevious } from '@radix-ui/react-use-previous';\nimport { useSize } from '@radix-ui/react-use-size';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { createCollection } from '@radix-ui/react-collection';\n\nimport type { Scope } from '@radix-ui/react-context';\n\ntype Direction = 'ltr' | 'rtl';\n\nconst PAGE_KEYS = ['PageUp', 'PageDown'];\nconst ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\ntype SlideDirection = 'from-left' | 'from-right' | 'from-bottom' | 'from-top';\nconst BACK_KEYS: Record<SlideDirection, string[]> = {\n 'from-left': ['Home', 'PageDown', 'ArrowDown', 'ArrowLeft'],\n 'from-right': ['Home', 'PageDown', 'ArrowDown', 'ArrowRight'],\n 'from-bottom': ['Home', 'PageDown', 'ArrowDown', 'ArrowLeft'],\n 'from-top': ['Home', 'PageDown', 'ArrowUp', 'ArrowLeft'],\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Slider\n * -----------------------------------------------------------------------------------------------*/\n\nconst SLIDER_NAME = 'Slider';\n\nconst [Collection, useCollection, createCollectionScope] =\n createCollection<SliderThumbElement>(SLIDER_NAME);\n\ntype ScopedProps<P> = P & { __scopeSlider?: Scope };\nconst [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [\n createCollectionScope,\n]);\n\ntype SliderContextValue = {\n name: string | undefined;\n disabled: boolean | undefined;\n min: number;\n max: number;\n values: number[];\n valueIndexToChangeRef: React.MutableRefObject<number>;\n thumbs: Set<SliderThumbElement>;\n orientation: SliderProps['orientation'];\n form: string | undefined;\n};\n\nconst [SliderProvider, useSliderContext] = createSliderContext<SliderContextValue>(SLIDER_NAME);\n\ntype SliderElement = SliderHorizontalElement | SliderVerticalElement;\ninterface SliderProps\n extends Omit<\n SliderHorizontalProps | SliderVerticalProps,\n keyof SliderOrientationPrivateProps | 'defaultValue'\n > {\n name?: string;\n disabled?: boolean;\n orientation?: React.AriaAttributes['aria-orientation'];\n dir?: Direction;\n min?: number;\n max?: number;\n step?: number;\n minStepsBetweenThumbs?: number;\n value?: number[];\n defaultValue?: number[];\n onValueChange?(value: number[]): void;\n onValueCommit?(value: number[]): void;\n inverted?: boolean;\n form?: string;\n}\n\nconst Slider = React.forwardRef<SliderElement, SliderProps>(\n (props: ScopedProps<SliderProps>, forwardedRef) => {\n const {\n name,\n min = 0,\n max = 100,\n step = 1,\n orientation = 'horizontal',\n disabled = false,\n minStepsBetweenThumbs = 0,\n defaultValue = [min],\n value,\n onValueChange = () => {},\n onValueCommit = () => {},\n inverted = false,\n form,\n ...sliderProps\n } = props;\n const thumbRefs = React.useRef<SliderContextValue['thumbs']>(new Set());\n const valueIndexToChangeRef = React.useRef<number>(0);\n const isHorizontal = orientation === 'horizontal';\n const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;\n\n const [values = [], setValues] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange: (value) => {\n const thumbs = [...thumbRefs.current];\n thumbs[valueIndexToChangeRef.current]?.focus();\n onValueChange(value);\n },\n });\n const valuesBeforeSlideStartRef = React.useRef(values);\n\n function handleSlideStart(value: number) {\n const closestIndex = getClosestValueIndex(values, value);\n updateValues(value, closestIndex);\n }\n\n function handleSlideMove(value: number) {\n updateValues(value, valueIndexToChangeRef.current);\n }\n\n function handleSlideEnd() {\n const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];\n const nextValue = values[valueIndexToChangeRef.current];\n const hasChanged = nextValue !== prevValue;\n if (hasChanged) onValueCommit(values);\n }\n\n function updateValues(value: number, atIndex: number, { commit } = { commit: false }) {\n const decimalCount = getDecimalCount(step);\n const snapToStep = roundValue(Math.round((value - min) / step) * step + min, decimalCount);\n const nextValue = clamp(snapToStep, [min, max]);\n\n setValues((prevValues = []) => {\n const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);\n if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {\n valueIndexToChangeRef.current = nextValues.indexOf(nextValue);\n const hasChanged = String(nextValues) !== String(prevValues);\n if (hasChanged && commit) onValueCommit(nextValues);\n return hasChanged ? nextValues : prevValues;\n } else {\n return prevValues;\n }\n });\n }\n\n return (\n <SliderProvider\n scope={props.__scopeSlider}\n name={name}\n disabled={disabled}\n min={min}\n max={max}\n valueIndexToChangeRef={valueIndexToChangeRef}\n thumbs={thumbRefs.current}\n values={values}\n orientation={orientation}\n form={form}\n >\n <Collection.Provider scope={props.__scopeSlider}>\n <Collection.Slot scope={props.__scopeSlider}>\n <SliderOrientation\n aria-disabled={disabled}\n data-disabled={disabled ? '' : undefined}\n {...sliderProps}\n ref={forwardedRef}\n onPointerDown={composeEventHandlers(sliderProps.onPointerDown, () => {\n if (!disabled) valuesBeforeSlideStartRef.current = values;\n })}\n min={min}\n max={max}\n inverted={inverted}\n onSlideStart={disabled ? undefined : handleSlideStart}\n onSlideMove={disabled ? undefined : handleSlideMove}\n onSlideEnd={disabled ? undefined : handleSlideEnd}\n onHomeKeyDown={() => !disabled && updateValues(min, 0, { commit: true })}\n onEndKeyDown={() =>\n !disabled && updateValues(max, values.length - 1, { commit: true })\n }\n onStepKeyDown={({ event, direction: stepDirection }) => {\n if (!disabled) {\n const isPageKey = PAGE_KEYS.includes(event.key);\n const isSkipKey = isPageKey || (event.shiftKey && ARROW_KEYS.includes(event.key));\n const multiplier = isSkipKey ? 10 : 1;\n const atIndex = valueIndexToChangeRef.current;\n const value = values[atIndex]!;\n const stepInDirection = step * multiplier * stepDirection;\n updateValues(value + stepInDirection, atIndex, { commit: true });\n }\n }}\n />\n </Collection.Slot>\n </Collection.Provider>\n </SliderProvider>\n );\n }\n);\n\nSlider.displayName = SLIDER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderHorizontal\n * -----------------------------------------------------------------------------------------------*/\n\ntype Side = 'top' | 'right' | 'bottom' | 'left';\n\nconst [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext<{\n startEdge: Side;\n endEdge: Side;\n size: keyof NonNullable<ReturnType<typeof useSize>>;\n direction: number;\n}>(SLIDER_NAME, {\n startEdge: 'left',\n endEdge: 'right',\n size: 'width',\n direction: 1,\n});\n\ntype SliderOrientationPrivateProps = {\n min: number;\n max: number;\n inverted: boolean;\n onSlideStart?(value: number): void;\n onSlideMove?(value: number): void;\n onSlideEnd?(): void;\n onHomeKeyDown(event: React.KeyboardEvent): void;\n onEndKeyDown(event: React.KeyboardEvent): void;\n onStepKeyDown(step: { event: React.KeyboardEvent; direction: number }): void;\n};\ninterface SliderOrientationProps\n extends Omit<SliderImplProps, keyof SliderImplPrivateProps>,\n SliderOrientationPrivateProps {}\n\ntype SliderHorizontalElement = SliderImplElement;\ninterface SliderHorizontalProps extends SliderOrientationProps {\n dir?: Direction;\n}\n\nconst SliderHorizontal = React.forwardRef<SliderHorizontalElement, SliderHorizontalProps>(\n (props: ScopedProps<SliderHorizontalProps>, forwardedRef) => {\n const {\n min,\n max,\n dir,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const [slider, setSlider] = React.useState<SliderImplElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));\n const rectRef = React.useRef<DOMRect>(undefined);\n const direction = useDirection(dir);\n const isDirectionLTR = direction === 'ltr';\n const isSlidingFromLeft = (isDirectionLTR && !inverted) || (!isDirectionLTR && inverted);\n\n function getValueFromPointer(pointerPosition: number) {\n const rect = rectRef.current || slider!.getBoundingClientRect();\n const input: [number, number] = [0, rect.width];\n const output: [number, number] = isSlidingFromLeft ? [min, max] : [max, min];\n const value = linearScale(input, output);\n\n rectRef.current = rect;\n return value(pointerPosition - rect.left);\n }\n\n return (\n <SliderOrientationProvider\n scope={props.__scopeSlider}\n startEdge={isSlidingFromLeft ? 'left' : 'right'}\n endEdge={isSlidingFromLeft ? 'right' : 'left'}\n direction={isSlidingFromLeft ? 1 : -1}\n size=\"width\"\n >\n <SliderImpl\n dir={direction}\n data-orientation=\"horizontal\"\n {...sliderProps}\n ref={composedRefs}\n style={{\n ...sliderProps.style,\n ['--radix-slider-thumb-transform' as any]: 'translateX(-50%)',\n }}\n onSlideStart={(event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideStart?.(value);\n }}\n onSlideMove={(event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideMove?.(value);\n }}\n onSlideEnd={() => {\n rectRef.current = undefined;\n onSlideEnd?.();\n }}\n onStepKeyDown={(event) => {\n const slideDirection = isSlidingFromLeft ? 'from-left' : 'from-right';\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }}\n />\n </SliderOrientationProvider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderVertical\n * -----------------------------------------------------------------------------------------------*/\n\ntype SliderVerticalElement = SliderImplElement;\ninterface SliderVerticalProps extends SliderOrientationProps {}\n\nconst SliderVertical = React.forwardRef<SliderVerticalElement, SliderVerticalProps>(\n (props: ScopedProps<SliderVerticalProps>, forwardedRef) => {\n const {\n min,\n max,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const sliderRef = React.useRef<SliderImplElement>(null);\n const ref = useComposedRefs(forwardedRef, sliderRef);\n const rectRef = React.useRef<DOMRect>(undefined);\n const isSlidingFromBottom = !inverted;\n\n function getValueFromPointer(pointerPosition: number) {\n const rect = rectRef.current || sliderRef.current!.getBoundingClientRect();\n const input: [number, number] = [0, rect.height];\n const output: [number, number] = isSlidingFromBottom ? [max, min] : [min, max];\n const value = linearScale(input, output);\n\n rectRef.current = rect;\n return value(pointerPosition - rect.top);\n }\n\n return (\n <SliderOrientationProvider\n scope={props.__scopeSlider}\n startEdge={isSlidingFromBottom ? 'bottom' : 'top'}\n endEdge={isSlidingFromBottom ? 'top' : 'bottom'}\n size=\"height\"\n direction={isSlidingFromBottom ? 1 : -1}\n >\n <SliderImpl\n data-orientation=\"vertical\"\n {...sliderProps}\n ref={ref}\n style={{\n ...sliderProps.style,\n ['--radix-slider-thumb-transform' as any]: 'translateY(50%)',\n }}\n onSlideStart={(event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideStart?.(value);\n }}\n onSlideMove={(event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideMove?.(value);\n }}\n onSlideEnd={() => {\n rectRef.current = undefined;\n onSlideEnd?.();\n }}\n onStepKeyDown={(event) => {\n const slideDirection = isSlidingFromBottom ? 'from-bottom' : 'from-top';\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }}\n />\n </SliderOrientationProvider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderImpl\n * -----------------------------------------------------------------------------------------------*/\n\ntype SliderImplElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ntype SliderImplPrivateProps = {\n onSlideStart(event: React.PointerEvent): void;\n onSlideMove(event: React.PointerEvent): void;\n onSlideEnd(event: React.PointerEvent): void;\n onHomeKeyDown(event: React.KeyboardEvent): void;\n onEndKeyDown(event: React.KeyboardEvent): void;\n onStepKeyDown(event: React.KeyboardEvent): void;\n};\ninterface SliderImplProps extends PrimitiveDivProps, SliderImplPrivateProps {}\n\nconst SliderImpl = React.forwardRef<SliderImplElement, SliderImplProps>(\n (props: ScopedProps<SliderImplProps>, forwardedRef) => {\n const {\n __scopeSlider,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onHomeKeyDown,\n onEndKeyDown,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const context = useSliderContext(SLIDER_NAME, __scopeSlider);\n\n return (\n <Primitive.span\n {...sliderProps}\n ref={forwardedRef}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Home') {\n onHomeKeyDown(event);\n // Prevent scrolling to page start\n event.preventDefault();\n } else if (event.key === 'End') {\n onEndKeyDown(event);\n // Prevent scrolling to page end\n event.preventDefault();\n } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {\n onStepKeyDown(event);\n // Prevent scrolling for directional key presses\n event.preventDefault();\n }\n })}\n onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {\n const target = event.target as HTMLElement;\n target.setPointerCapture(event.pointerId);\n // Prevent browser focus behaviour because we focus a thumb manually when values change.\n event.preventDefault();\n // Touch devices have a delay before focusing so won't focus if touch immediately moves\n // away from target (sliding). We want thumb to focus regardless.\n if (context.thumbs.has(target)) {\n target.focus();\n } else {\n onSlideStart(event);\n }\n })}\n onPointerMove={composeEventHandlers(props.onPointerMove, (event) => {\n const target = event.target as HTMLElement;\n if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);\n })}\n onPointerUp={composeEventHandlers(props.onPointerUp, (event) => {\n const target = event.target as HTMLElement;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n onSlideEnd(event);\n }\n })}\n />\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderTrack\n * -----------------------------------------------------------------------------------------------*/\n\nconst TRACK_NAME = 'SliderTrack';\n\ntype SliderTrackElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface SliderTrackProps extends PrimitiveSpanProps {}\n\nconst SliderTrack = React.forwardRef<SliderTrackElement, SliderTrackProps>(\n (props: ScopedProps<SliderTrackProps>, forwardedRef) => {\n const { __scopeSlider, ...trackProps } = props;\n const context = useSliderContext(TRACK_NAME, __scopeSlider);\n return (\n <Primitive.span\n data-disabled={context.disabled ? '' : undefined}\n data-orientation={context.orientation}\n {...trackProps}\n ref={forwardedRef}\n />\n );\n }\n);\n\nSliderTrack.displayName = TRACK_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderRange\n * -----------------------------------------------------------------------------------------------*/\n\nconst RANGE_NAME = 'SliderRange';\n\ntype SliderRangeElement = React.ComponentRef<typeof Primitive.span>;\ninterface SliderRangeProps extends PrimitiveSpanProps {}\n\nconst SliderRange = React.forwardRef<SliderRangeElement, SliderRangeProps>(\n (props: ScopedProps<SliderRangeProps>, forwardedRef) => {\n const { __scopeSlider, ...rangeProps } = props;\n const context = useSliderContext(RANGE_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);\n const ref = React.useRef<HTMLSpanElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const valuesCount = context.values.length;\n const percentages = context.values.map((value) =>\n convertValueToPercentage(value, context.min, context.max)\n );\n const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;\n const offsetEnd = 100 - Math.max(...percentages);\n\n return (\n <Primitive.span\n data-orientation={context.orientation}\n data-disabled={context.disabled ? '' : undefined}\n {...rangeProps}\n ref={composedRefs}\n style={{\n ...props.style,\n [orientation.startEdge]: offsetStart + '%',\n [orientation.endEdge]: offsetEnd + '%',\n }}\n />\n );\n }\n);\n\nSliderRange.displayName = RANGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderThumb\n * -----------------------------------------------------------------------------------------------*/\n\nconst THUMB_NAME = 'SliderThumb';\n\ntype SliderThumbElement = SliderThumbImplElement;\ninterface SliderThumbProps extends Omit<SliderThumbImplProps, 'index'> {}\n\nconst SliderThumb = React.forwardRef<SliderThumbElement, SliderThumbProps>(\n (props: ScopedProps<SliderThumbProps>, forwardedRef) => {\n const getItems = useCollection(props.__scopeSlider);\n const [thumb, setThumb] = React.useState<SliderThumbImplElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const index = React.useMemo(\n () => (thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1),\n [getItems, thumb]\n );\n return <SliderThumbImpl {...props} ref={composedRefs} index={index} />;\n }\n);\n\ntype SliderThumbImplElement = React.ComponentRef<typeof Primitive.span>;\ninterface SliderThumbImplProps extends PrimitiveSpanProps {\n index: number;\n name?: string;\n}\n\nconst SliderThumbImpl = React.forwardRef<SliderThumbImplElement, SliderThumbImplProps>(\n (props: ScopedProps<SliderThumbImplProps>, forwardedRef) => {\n const { __scopeSlider, index, name, ...thumbProps } = props;\n const context = useSliderContext(THUMB_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);\n const [thumb, setThumb] = React.useState<HTMLSpanElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n // We set this to true by default so that events bubble to forms without JS (SSR)\n const isFormControl = thumb ? context.form || !!thumb.closest('form') : true;\n const size = useSize(thumb);\n // We cast because index could be `-1` which would return undefined\n const value = context.values[index] as number | undefined;\n const percent =\n value === undefined ? 0 : convertValueToPercentage(value, context.min, context.max);\n const label = getLabel(index, context.values.length);\n const orientationSize = size?.[orientation.size];\n const thumbInBoundsOffset = orientationSize\n ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction)\n : 0;\n\n React.useEffect(() => {\n if (thumb) {\n context.thumbs.add(thumb);\n return () => {\n context.thumbs.delete(thumb);\n };\n }\n }, [thumb, context.thumbs]);\n\n return (\n <span\n style={{\n transform: 'var(--radix-slider-thumb-transform)',\n position: 'absolute',\n [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`,\n }}\n >\n <Collection.ItemSlot scope={props.__scopeSlider}>\n <Primitive.span\n role=\"slider\"\n aria-label={props['aria-label'] || label}\n aria-valuemin={context.min}\n aria-valuenow={value}\n aria-valuemax={context.max}\n aria-orientation={context.orientation}\n data-orientation={context.orientation}\n data-disabled={context.disabled ? '' : undefined}\n tabIndex={context.disabled ? undefined : 0}\n {...thumbProps}\n ref={composedRefs}\n /**\n * There will be no value on initial render while we work out the index so we hide thumbs\n * without a value, otherwise SSR will render them in the wrong position before they\n * snap into the correct position during hydration which would be visually jarring for\n * slower connections.\n */\n style={value === undefined ? { display: 'none' } : props.style}\n onFocus={composeEventHandlers(props.onFocus, () => {\n context.valueIndexToChangeRef.current = index;\n })}\n />\n </Collection.ItemSlot>\n\n {isFormControl && (\n <SliderBubbleInput\n key={index}\n name={\n name ??\n (context.name ? context.name + (context.values.length > 1 ? '[]' : '') : undefined)\n }\n form={context.form}\n value={value}\n />\n )}\n </span>\n );\n }\n);\n\nSliderThumb.displayName = THUMB_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderBubbleInput\n * -----------------------------------------------------------------------------------------------*/\n\nconst BUBBLE_INPUT_NAME = 'RadioBubbleInput';\n\ntype InputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;\ninterface SliderBubbleInputProps extends InputProps {}\n\nconst SliderBubbleInput = React.forwardRef<HTMLInputElement, SliderBubbleInputProps>(\n ({ __scopeSlider, value, ...props }: ScopedProps<SliderBubbleInputProps>, forwardedRef) => {\n const ref = React.useRef<HTMLInputElement>(null);\n const composedRefs = useComposedRefs(ref, forwardedRef);\n const prevValue = usePrevious(value);\n\n // Bubble value change to parents (e.g form change event)\n React.useEffect(() => {\n const input = ref.current;\n if (!input) return;\n\n const inputProto = window.HTMLInputElement.prototype;\n const descriptor = Object.getOwnPropertyDescriptor(inputProto, 'value') as PropertyDescriptor;\n const setValue = descriptor.set;\n if (prevValue !== value && setValue) {\n const event = new Event('input', { bubbles: true });\n setValue.call(input, value);\n input.dispatchEvent(event);\n }\n }, [prevValue, value]);\n\n /**\n * We purposefully do not use `type=\"hidden\"` here otherwise forms that\n * wrap it will not be able to access its value via the FormData API.\n *\n * We purposefully do not add the `value` attribute here to allow the value\n * to be set programmatically and bubble to any parent form `onChange` event.\n * Adding the `value` will cause React to consider the programmatic\n * dispatch a duplicate and it will get swallowed.\n */\n return (\n <Primitive.input\n style={{ display: 'none' }}\n {...props}\n ref={composedRefs}\n defaultValue={value}\n />\n );\n }\n);\n\nSliderBubbleInput.displayName = BUBBLE_INPUT_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction getNextSortedValues(prevValues: number[] = [], nextValue: number, atIndex: number) {\n const nextValues = [...prevValues];\n nextValues[atIndex] = nextValue;\n return nextValues.sort((a, b) => a - b);\n}\n\nfunction convertValueToPercentage(value: number, min: number, max: number) {\n const maxSteps = max - min;\n const percentPerStep = 100 / maxSteps;\n const percentage = percentPerStep * (value - min);\n return clamp(percentage, [0, 100]);\n}\n\n/**\n * Returns a label for each thumb when there are two or more thumbs\n */\nfunction getLabel(index: number, totalValues: number) {\n if (totalValues > 2) {\n return `Value ${index + 1} of ${totalValues}`;\n } else if (totalValues === 2) {\n return ['Minimum', 'Maximum'][index];\n } else {\n return undefined;\n }\n}\n\n/**\n * Given a `values` array and a `nextValue`, determine which value in\n * the array is closest to `nextValue` and return its index.\n *\n * @example\n * // returns 1\n * getClosestValueIndex([10, 30], 25);\n */\nfunction getClosestValueIndex(values: number[], nextValue: number) {\n if (values.length === 1) return 0;\n const distances = values.map((value) => Math.abs(value - nextValue));\n const closestDistance = Math.min(...distances);\n return distances.indexOf(closestDistance);\n}\n\n/**\n * Offsets the thumb centre point while sliding to ensure it remains\n * within the bounds of the slider when reaching the edges\n */\nfunction getThumbInBoundsOffset(width: number, left: number, direction: number) {\n const halfWidth = width / 2;\n const halfPercent = 50;\n const offset = linearScale([0, halfPercent], [0, halfWidth]);\n return (halfWidth - offset(left) * direction) * direction;\n}\n\n/**\n * Gets an array of steps between each value.\n *\n * @example\n * // returns [1, 9]\n * getStepsBetweenValues([10, 11, 20]);\n */\nfunction getStepsBetweenValues(values: number[]) {\n return values.slice(0, -1).map((value, index) => values[index + 1]! - value);\n}\n\n/**\n * Verifies the minimum steps between all values is greater than or equal\n * to the expected minimum steps.\n *\n * @example\n * // returns false\n * hasMinStepsBetweenValues([1,2,3], 2);\n *\n * @example\n * // returns true\n * hasMinStepsBetweenValues([1,2,3], 1);\n */\nfunction hasMinStepsBetweenValues(values: number[], minStepsBetweenValues: number) {\n if (minStepsBetweenValues > 0) {\n const stepsBetweenValues = getStepsBetweenValues(values);\n const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);\n return actualMinStepsBetweenValues >= minStepsBetweenValues;\n }\n return true;\n}\n\n// https://github.com/tmcw-up-for-adoption/simple-linear-scale/blob/master/index.js\nfunction linearScale(input: readonly [number, number], output: readonly [number, number]) {\n return (value: number) => {\n if (input[0] === input[1] || output[0] === output[1]) return output[0];\n const ratio = (output[1] - output[0]) / (input[1] - input[0]);\n return output[0] + ratio * (value - input[0]);\n };\n}\n\nfunction getDecimalCount(value: number) {\n return (String(value).split('.')[1] || '').length;\n}\n\nfunction roundValue(value: number, decimalCount: number) {\n const rounder = Math.pow(10, decimalCount);\n return Math.round(value * rounder) / rounder;\n}\n\nconst Root = Slider;\nconst Track = SliderTrack;\nconst Range = SliderRange;\nconst Thumb = SliderThumb;\n\nexport {\n createSliderScope,\n //\n Slider,\n SliderTrack,\n SliderRange,\n SliderThumb,\n //\n Root,\n Track,\n Range,\n Thumb,\n};\nexport type { SliderProps, SliderTrackProps, SliderRangeProps, SliderThumbProps };\n"],"names":["__iconNode","d"],"mappings":"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","ignoreList":[7,20,21,22,23,24,25,26]}
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/presentation/web/components/features/settings/settings-page-client.tsx","../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx","../../../../../../../src/presentation/web/components/features/settings/agent-settings-section.tsx","../../../../../../../src/presentation/web/app/actions/data%3A83f3e0%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/features/settings/environment-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/workflow-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/ci-settings-section.tsx","../../../../../../../node_modules/.pnpm/%40radix-ui%2Breact-slider%401.3.6_%40types%2Breact-dom%4019.2.3_%40types%2Breact%4019.2.14__%40types%2Breact_c6a3fae91eb6750caf661d179680cb4a/node_modules/%40radix-ui/react-slider/dist/index.mjs","../../../../../../../src/presentation/web/components/ui/slider.tsx","../../../../../../../src/presentation/web/components/features/settings/timeout-slider.tsx","../../../../../../../src/presentation/web/components/features/settings/stage-timeouts-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/notification-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/feature-flags-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/interactive-agent-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/fab-layout-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/database-settings-section.tsx","../../../../../../../src/presentation/web/app/actions/data%3A0db943%20%3Ctext/javascript%3E","../../../../../../../src/presentation/web/components/features/settings/litellm-proxy-settings-section.tsx","../../../../../../../src/presentation/web/components/features/settings/litellm-proxy-routing-section.tsx","../../../../../../../src/presentation/web/components/common/editor-type-icons.tsx","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/route.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/database.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/layout-grid.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/layout-list.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/flag.ts","../../../../../../../node_modules/.pnpm/lucide-react%401.7.0_react%4019.2.4/node_modules/lucide-react/src/icons/bell.ts","../../../../../../../node_modules/.pnpm/%40radix-ui%2Breact-slider%401.3.6_%40types%2Breact-dom%4019.2.3_%40types%2Breact%4019.2.14__%40types%2Breact_c6a3fae91eb6750caf661d179680cb4a/node_modules/%40radix-ui/react-slider/src/slider.tsx"],"sourcesContent":["'use client';\n\nimport { useState, useEffect } from 'react';\nimport {\n Bot,\n Terminal,\n GitBranch,\n Activity,\n Bell,\n Flag,\n Database,\n Timer,\n MessageSquare,\n LayoutGrid,\n LayoutList,\n Server,\n} from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport { AgentSettingsSection } from './agent-settings-section';\nimport { EnvironmentSettingsSection } from './environment-settings-section';\nimport { WorkflowSettingsSection } from './workflow-settings-section';\nimport { CiSettingsSection } from './ci-settings-section';\nimport { StageTimeoutsSettingsSection } from './stage-timeouts-settings-section';\nimport { NotificationSettingsSection } from './notification-settings-section';\nimport { FeatureFlagsSettingsSection } from './feature-flags-settings-section';\nimport { InteractiveAgentSettingsSection } from './interactive-agent-settings-section';\nimport { FabLayoutSettingsSection } from './fab-layout-settings-section';\nimport { DatabaseSettingsSection } from './database-settings-section';\nimport { LiteLLMProxySettingsSection } from './litellm-proxy-settings-section';\nimport { LiteLLMProxyRoutingSection } from './litellm-proxy-routing-section';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport type { AvailableTerminal } from '@/app/actions/get-available-terminals';\nimport type { AvailableEditor } from '@/app/actions/get-available-editors';\nimport type { AvailableShell } from '@/app/actions/get-available-shells';\n\nconst SECTIONS = [\n { id: 'agent', labelKey: 'settings.sections.agent', icon: Bot },\n { id: 'environment', labelKey: 'settings.sections.environment', icon: Terminal },\n { id: 'workflow', labelKey: 'settings.sections.workflow', icon: GitBranch },\n { id: 'ci', labelKey: 'settings.sections.ci', icon: Activity },\n { id: 'stage-timeouts', labelKey: 'settings.sections.timeouts', icon: Timer },\n { id: 'notifications', labelKey: 'settings.sections.notifications', icon: Bell },\n { id: 'feature-flags', labelKey: 'settings.sections.flags', icon: Flag },\n { id: 'interactive-agent', labelKey: 'settings.sections.chat', icon: MessageSquare },\n { id: 'fab-layout', labelKey: 'settings.sections.layout', icon: LayoutGrid },\n { id: 'database', labelKey: 'settings.sections.database', icon: Database },\n { id: 'litellm-proxy', labelKey: 'settings.sections.proxy', icon: Server },\n] as const;\n\nconst TABS = [{ id: 'all', labelKey: 'settings.sections.all', icon: LayoutList }, ...SECTIONS];\n\nexport interface SettingsPageClientProps {\n settings: Settings;\n shipitAiHome: string;\n dbFileSize: string;\n availableTerminals?: AvailableTerminal[];\n availableEditors?: AvailableEditor[];\n availableShells?: AvailableShell[];\n}\n\nexport function SettingsPageClient({\n settings,\n shipitAiHome,\n dbFileSize,\n availableTerminals,\n availableEditors,\n availableShells,\n}: SettingsPageClientProps) {\n const { t } = useTranslation('web');\n const [activeTab, setActiveTab] = useState<string>('all');\n const [visibleSection, setVisibleSection] = useState<string>('agent');\n\n // Track which section is in view via IntersectionObserver (only on \"All\" tab)\n useEffect(() => {\n if (activeTab !== 'all') return;\n\n const els = SECTIONS.map((s) => document.getElementById(`section-${s.id}`)).filter(\n Boolean\n ) as HTMLElement[];\n if (els.length === 0) return;\n\n const observer = new IntersectionObserver(\n (entries) => {\n for (const entry of entries) {\n if (entry.isIntersecting) {\n setVisibleSection(entry.target.id.replace('section-', ''));\n }\n }\n },\n { rootMargin: '-65px 0px -60% 0px', threshold: 0 }\n );\n\n for (const el of els) observer.observe(el);\n return () => observer.disconnect();\n }, [activeTab]);\n\n return (\n <div data-testid=\"settings-page-client\" className=\"max-w-5xl px-8 pt-8\">\n {/* Sticky header -- editorial title + tab nav */}\n <div className=\"bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 pb-4 backdrop-blur\">\n {/* Title row with editorial treatment */}\n <div className=\"mb-4 space-y-1.5\">\n <span className=\"text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase\">\n Developer Portal\n </span>\n <div className=\"flex items-baseline gap-3\">\n <h1 className=\"text-foreground text-3xl font-black tracking-tight\">\n {t('settings.title')}\n </h1>\n </div>\n </div>\n {/* Tab navigation -- editorial tab treatment */}\n <nav className=\"bg-card editorial-shadow flex flex-wrap items-center gap-0.5 rounded-lg p-1\">\n {TABS.map((tab) => {\n const TabIcon = tab.icon;\n const isActive =\n activeTab === tab.id ||\n (activeTab === 'all' && tab.id !== 'all' && visibleSection === tab.id);\n return (\n <button\n key={tab.id}\n type=\"button\"\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n 'flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-bold transition-all',\n isActive\n ? 'bg-muted text-primary shadow-sm ring-1 ring-slate-200/70 dark:ring-slate-700/50'\n : 'text-muted-foreground hover:text-foreground hover:bg-accent/50'\n )}\n >\n <TabIcon className=\"h-3 w-3\" />\n <span className=\"hidden sm:inline\">{t(tab.labelKey)}</span>\n </button>\n );\n })}\n </nav>\n </div>\n\n <div className=\"flex flex-col gap-3\">\n {/* -- Agent -- */}\n {(activeTab === 'all' || activeTab === 'agent') && (\n <div id=\"section-agent\" className=\"scroll-mt-18 rounded-lg\">\n <AgentSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Environment -- */}\n {(activeTab === 'all' || activeTab === 'environment') && (\n <div id=\"section-environment\" className=\"scroll-mt-18 rounded-lg\">\n <EnvironmentSettingsSection\n settings={settings}\n availableEditors={availableEditors}\n availableShells={availableShells}\n availableTerminals={availableTerminals}\n />\n </div>\n )}\n\n {/* -- Workflow -- */}\n {(activeTab === 'all' || activeTab === 'workflow') && (\n <div id=\"section-workflow\" className=\"scroll-mt-18 rounded-lg\">\n <WorkflowSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- CI -- */}\n {(activeTab === 'all' || activeTab === 'ci') && (\n <div id=\"section-ci\" className=\"scroll-mt-18 rounded-lg\">\n <CiSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Stage Timeouts -- */}\n {(activeTab === 'all' || activeTab === 'stage-timeouts') && (\n <div id=\"section-stage-timeouts\" className=\"scroll-mt-18 rounded-lg\">\n <StageTimeoutsSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Notifications -- */}\n {(activeTab === 'all' || activeTab === 'notifications') && (\n <div id=\"section-notifications\" className=\"scroll-mt-18 rounded-lg\">\n <NotificationSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Feature Flags -- */}\n {(activeTab === 'all' || activeTab === 'feature-flags') && (\n <div id=\"section-feature-flags\" className=\"scroll-mt-18 rounded-lg\">\n <FeatureFlagsSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Interactive Agent -- */}\n {(activeTab === 'all' || activeTab === 'interactive-agent') && (\n <div id=\"section-interactive-agent\" className=\"scroll-mt-18 rounded-lg\">\n <InteractiveAgentSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- FAB Layout -- */}\n {(activeTab === 'all' || activeTab === 'fab-layout') && (\n <div id=\"section-fab-layout\" className=\"scroll-mt-18 rounded-lg\">\n <FabLayoutSettingsSection settings={settings} />\n </div>\n )}\n\n {/* -- Database -- */}\n {(activeTab === 'all' || activeTab === 'database') && (\n <div id=\"section-database\" className=\"scroll-mt-18 rounded-lg\">\n <DatabaseSettingsSection shipitAiHome={shipitAiHome} dbFileSize={dbFileSize} />\n </div>\n )}\n\n {/* -- LiteLLM Proxy -- */}\n {(activeTab === 'all' || activeTab === 'litellm-proxy') && (\n <div id=\"section-litellm-proxy\" className=\"scroll-mt-18 rounded-lg\">\n <LiteLLMProxySettingsSection settings={settings} />\n {settings.litellmProxy?.baseUrl ? (\n <LiteLLMProxyRoutingSection settings={settings} />\n ) : null}\n </div>\n )}\n </div>\n </div>\n );\n}\n","'use client';\n\nimport { Minus, Plus, ExternalLink, Info } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport { Label } from '@/components/ui/label';\nimport { Switch } from '@/components/ui/switch';\nimport { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';\n\n/* ── Reusable row components ── */\n\nexport function SettingsRow({\n label,\n description,\n htmlFor,\n tooltip,\n children,\n}: {\n label: string;\n description?: string;\n htmlFor?: string;\n /** Explicit tooltip text. Falls back to `description` if not provided. */\n tooltip?: string;\n children: React.ReactNode;\n}) {\n // Show the Info icon when there's either an explicit tooltip or a description to surface\n const tooltipText = tooltip ?? description;\n\n return (\n <div className=\"flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0\">\n <div className=\"min-w-0\">\n <span className=\"flex items-center gap-1.5\">\n <Label htmlFor={htmlFor} className=\"cursor-pointer text-sm font-normal whitespace-nowrap\">\n {label}\n </Label>\n {tooltipText ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Info className=\"text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors\" />\n </TooltipTrigger>\n <TooltipContent side=\"top\" className=\"max-w-64 text-[11px] leading-relaxed\">\n <span className=\"text-muted-foreground\">{tooltipText}</span>\n </TooltipContent>\n </Tooltip>\n ) : null}\n </span>\n {description ? (\n <p className=\"text-muted-foreground text-[11px] leading-tight\">{description}</p>\n ) : null}\n </div>\n <div className=\"flex shrink-0 items-center gap-2\">{children}</div>\n </div>\n );\n}\n\nexport function SwitchRow({\n label,\n description,\n id,\n testId,\n checked,\n onChange,\n disabled,\n tooltip,\n}: {\n label: string;\n description?: string;\n id: string;\n testId: string;\n checked: boolean;\n onChange: (value: boolean) => void;\n disabled?: boolean;\n tooltip?: string;\n}) {\n return (\n <SettingsRow label={label} description={description} htmlFor={id} tooltip={tooltip}>\n <Switch\n id={id}\n data-testid={testId}\n checked={checked}\n onCheckedChange={onChange}\n disabled={disabled}\n className={cn('cursor-pointer', disabled && 'cursor-not-allowed opacity-50')}\n />\n </SettingsRow>\n );\n}\n\n/* ── Section card wrapper ── */\n\nexport function SettingsSection({\n icon: Icon,\n title,\n description,\n badge,\n testId,\n tooltip,\n tooltipLinks,\n children,\n}: {\n icon: React.ComponentType<{ className?: string }>;\n title: string;\n description: string;\n badge?: string;\n testId: string;\n /** Section-level tooltip describing the purpose of this settings group. */\n tooltip?: string;\n /** Documentation links rendered below the tooltip text. */\n tooltipLinks?: { label: string; href: string }[];\n children: React.ReactNode;\n}) {\n return (\n <div className=\"bg-background rounded-lg border\" data-testid={testId}>\n <div className=\"bg-muted/30 border-b px-4 py-3\">\n <div className=\"flex items-center gap-2\">\n <Icon className=\"text-muted-foreground h-3.5 w-3.5\" />\n <h2 className=\"text-sm font-semibold\">{title}</h2>\n {tooltip ? (\n <Tooltip>\n <TooltipTrigger asChild>\n <Info className=\"text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors\" />\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" className=\"max-w-72 text-[11px] leading-relaxed\">\n <p className=\"text-muted-foreground\">{tooltip}</p>\n {tooltipLinks != null && tooltipLinks.length > 0 ? (\n <div className=\"border-border/50 mt-1.5 flex flex-col gap-0.5 border-t pt-1.5\">\n {tooltipLinks.map((link) => (\n <a\n key={link.href}\n href={link.href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5 text-[10px] tracking-wide transition-colors\"\n >\n <ExternalLink className=\"h-2.5 w-2.5 shrink-0 opacity-50\" />\n {link.label}\n </a>\n ))}\n </div>\n ) : null}\n </TooltipContent>\n </Tooltip>\n ) : null}\n {badge ? (\n <span className=\"bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[9px] font-medium tracking-wider uppercase\">\n {badge}\n </span>\n ) : null}\n </div>\n <p className=\"text-muted-foreground mt-0.5 text-[11px]\">{description}</p>\n </div>\n <div className=\"px-4\">{children}</div>\n </div>\n );\n}\n\nexport function NumberStepper({\n id,\n testId,\n value,\n onChange,\n onBlur,\n placeholder,\n min = 1,\n max,\n step = 1,\n suffix,\n}: {\n id: string;\n testId: string;\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n placeholder: string;\n min?: number;\n max?: number;\n step?: number;\n suffix?: string;\n}) {\n const { t } = useTranslation('web');\n const numValue = value === '' ? undefined : parseInt(value, 10);\n\n const decrement = () => {\n const current = numValue ?? parseInt(placeholder, 10);\n const next = Math.max(min, current - step);\n onChange(String(next));\n };\n\n const increment = () => {\n const current = numValue ?? parseInt(placeholder, 10);\n const next = max != null ? Math.min(max, current + step) : current + step;\n onChange(String(next));\n };\n\n return (\n <div className=\"flex items-center gap-1.5\">\n <div className=\"flex items-center overflow-hidden rounded-md border\">\n <button\n type=\"button\"\n onClick={() => {\n decrement();\n }}\n onMouseUp={onBlur}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-8 w-7 cursor-pointer items-center justify-center border-r transition-colors\"\n aria-label={t('common.decrease')}\n >\n <Minus className=\"h-3 w-3\" />\n </button>\n <input\n id={id}\n data-testid={testId}\n type=\"text\"\n inputMode=\"numeric\"\n pattern=\"[0-9]*\"\n value={value}\n placeholder={placeholder}\n onChange={(e) => {\n const v = e.target.value.replace(/[^0-9]/g, '');\n onChange(v);\n }}\n onBlur={onBlur}\n className=\"h-8 w-14 bg-transparent text-center text-xs outline-none\"\n />\n <button\n type=\"button\"\n onClick={() => {\n increment();\n }}\n onMouseUp={onBlur}\n className=\"text-muted-foreground hover:bg-muted hover:text-foreground flex h-8 w-7 cursor-pointer items-center justify-center border-l transition-colors\"\n aria-label={t('common.increase')}\n >\n <Plus className=\"h-3 w-3\" />\n </button>\n </div>\n {suffix ? <span className=\"text-muted-foreground text-[11px]\">{suffix}</span> : null}\n </div>\n );\n}\n\nexport function SubsectionLabel({ children }: { children: React.ReactNode }) {\n return (\n <div className=\"border-b pt-3 pb-1\">\n <span className=\"text-muted-foreground text-[10px] font-semibold tracking-wider uppercase\">\n {children}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useState } from 'react';\nimport { Bot } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport type { Settings, AgentType } from '@shipit-ai/core/domain/generated/output';\nimport { AgentModelPicker } from '@/components/features/settings/AgentModelPicker';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\n\nexport interface AgentSettingsSectionProps {\n settings: Settings;\n}\n\nexport function AgentSettingsSection({ settings }: AgentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [agentType, setAgentType] = useState(settings.agent.type);\n\n return (\n <SettingsSection\n icon={Bot}\n title={t('settings.agent.sectionTitle')}\n description={t('settings.agent.sectionDescription')}\n testId=\"agent-settings-section\"\n tooltip={t('settings.agent.hint')}\n tooltipLinks={[\n {\n label: t('settings.agent.links.agentSystem'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/agent-system.md',\n },\n {\n label: t('settings.agent.links.addingAgents'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/adding-agents.md',\n },\n {\n label: t('settings.agent.links.configurationGuide'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.agent.agentAndModel')}\n description={t('settings.agent.agentAndModelDescription')}\n tooltip=\"Changing the agent switches which AI CLI tool runs your features. Each agent has different capabilities, speed, and cost tradeoffs.\"\n htmlFor=\"agent-model-picker\"\n >\n <AgentModelPicker\n initialAgentType={agentType}\n initialModel={settings.models.default}\n mode=\"settings\"\n onAgentModelChange={(newAgent) => setAgentType(newAgent as AgentType)}\n className=\"w-55\"\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"40285521bc7bb097a5f552c11d2e05bd4a34911967\":{\"name\":\"updateSettingsAction\"}},\"src/presentation/web/app/actions/update-settings.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"40285521bc7bb097a5f552c11d2e05bd4a34911967\",callServer,void 0,findSourceMapURL,\"updateSettingsAction\");export{$$RSC_SERVER_ACTION_0 as updateSettingsAction};","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Terminal } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { cn } from '@/lib/utils';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\nimport { Badge } from '@/components/ui/badge';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { type EditorType, TerminalType } from '@shipit-ai/core/domain/generated/output';\nimport { getEditorTypeIcon } from '@/components/common/editor-type-icons';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport type { AvailableTerminal } from '@/app/actions/get-available-terminals';\nimport type { AvailableEditor } from '@/app/actions/get-available-editors';\nimport type { AvailableShell } from '@/app/actions/get-available-shells';\n\nexport const DEFAULT_EDITOR_OPTIONS: AvailableEditor[] = [\n { id: 'vscode', name: 'VS Code', available: true },\n { id: 'cursor', name: 'Cursor', available: true },\n { id: 'windsurf', name: 'Windsurf', available: true },\n { id: 'zed', name: 'Zed', available: true },\n { id: 'antigravity', name: 'Antigravity', available: true },\n];\n\nexport const DEFAULT_SHELL_OPTIONS: AvailableShell[] = [\n { id: 'bash', name: 'Bash', available: true },\n { id: 'zsh', name: 'Zsh', available: true },\n { id: 'fish', name: 'Fish', available: true },\n];\n\nexport interface EnvironmentSettingsSectionProps {\n settings: Settings;\n availableEditors?: AvailableEditor[];\n availableShells?: AvailableShell[];\n availableTerminals?: AvailableTerminal[];\n}\n\nexport function EnvironmentSettingsSection({\n settings,\n availableEditors,\n availableShells,\n availableTerminals,\n}: EnvironmentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [editor, setEditor] = useState(settings.environment.defaultEditor);\n const [shell, setShell] = useState(settings.environment.shellPreference);\n const [terminal, setTerminal] = useState(\n settings.environment.terminalPreference ?? TerminalType.System\n );\n\n const terminalOptions = availableTerminals ?? [\n {\n id: TerminalType.System,\n name: t('settings.environment.systemTerminal'),\n available: true as const,\n },\n ];\n\n const editorOptions = availableEditors ?? DEFAULT_EDITOR_OPTIONS;\n const shellOptions = availableShells ?? DEFAULT_SHELL_OPTIONS;\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Terminal}\n title={t('settings.environment.sectionTitle')}\n description={t('settings.environment.sectionDescription')}\n testId=\"environment-settings-section\"\n tooltip={t('settings.environment.hint')}\n tooltipLinks={[\n {\n label: t('settings.environment.links.configurationGuide'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.environment.defaultEditor')}\n description={t('settings.environment.defaultEditorDescription')}\n tooltip=\"The editor that opens when you click 'Launch' on a tool card or when ShipIT needs to open a file for review.\"\n htmlFor=\"default-editor\"\n >\n <Select\n value={editor}\n onValueChange={(v) => {\n setEditor(v as EditorType);\n save({\n environment: {\n defaultEditor: v as EditorType,\n shellPreference: shell,\n terminalPreference: terminal,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"default-editor\"\n data-testid=\"editor-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {editorOptions.map((opt) => {\n const Icon = getEditorTypeIcon(opt.id as EditorType);\n return (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n <Icon className=\"h-4 w-4 shrink-0\" />\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n );\n })}\n </SelectContent>\n </Select>\n </SettingsRow>\n <SettingsRow\n label={t('settings.environment.shell')}\n description={t('settings.environment.shellDescription')}\n tooltip=\"Controls which shell runs generated scripts like install commands and git operations. Match this to your daily driver shell.\"\n htmlFor=\"shell-preference\"\n >\n <Select\n value={shell}\n onValueChange={(v) => {\n setShell(v);\n save({\n environment: {\n defaultEditor: editor,\n shellPreference: v,\n terminalPreference: terminal,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"shell-preference\"\n data-testid=\"shell-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {shellOptions.map((opt) => (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </SettingsRow>\n <SettingsRow\n label={t('settings.environment.terminal')}\n description={t('settings.environment.terminalDescription')}\n tooltip=\"The terminal emulator launched when opening shell sessions from the web UI. Only affects web-launched terminals, not CLI usage.\"\n htmlFor=\"terminal-preference\"\n >\n <Select\n value={terminal}\n onValueChange={(v) => {\n setTerminal(v as TerminalType);\n save({\n environment: {\n defaultEditor: editor,\n shellPreference: shell,\n terminalPreference: v as TerminalType,\n },\n });\n }}\n >\n <SelectTrigger\n id=\"terminal-preference\"\n data-testid=\"terminal-select\"\n className=\"w-64 cursor-pointer text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {terminalOptions.map((opt) => (\n <SelectItem key={opt.id} value={opt.id} disabled={!opt.available}>\n <span className=\"flex items-center gap-2 text-xs\">\n {opt.name}\n <Badge\n variant=\"outline\"\n className={cn(\n 'ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal',\n opt.available\n ? 'border-emerald-500/30 text-emerald-500'\n : 'border-muted-foreground/30 text-muted-foreground'\n )}\n >\n {opt.available ? 'Installed' : 'Not Installed'}\n </Badge>\n </span>\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { GitBranch } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport {\n SettingsSection,\n SettingsRow,\n SwitchRow,\n NumberStepper,\n SubsectionLabel,\n} from './settings-section-utils';\n\nexport interface WorkflowSettingsSectionProps {\n settings: Settings;\n}\n\nfunction buildWorkflowPayload(\n state: {\n openPr: boolean;\n pushOnComplete: boolean;\n allowPrd: boolean;\n allowPlan: boolean;\n allowMerge: boolean;\n enableEvidence: boolean;\n commitEvidence: boolean;\n ciWatchEnabled: boolean;\n defaultFastMode: boolean;\n autoArchiveEnabled: boolean;\n autoArchiveDelay: string;\n },\n overrides: {\n openPr?: boolean;\n pushOnComplete?: boolean;\n allowPrd?: boolean;\n allowPlan?: boolean;\n allowMerge?: boolean;\n enableEvidence?: boolean;\n commitEvidence?: boolean;\n ciWatchEnabled?: boolean;\n defaultFastMode?: boolean;\n autoArchiveEnabled?: boolean;\n autoArchiveDelay?: string;\n } = {}\n) {\n const archiveEnabled = overrides.autoArchiveEnabled ?? state.autoArchiveEnabled;\n const archiveDelay = parseInt(overrides.autoArchiveDelay ?? state.autoArchiveDelay, 10);\n return {\n workflow: {\n openPrOnImplementationComplete: overrides.openPr ?? state.openPr,\n approvalGateDefaults: {\n pushOnImplementationComplete: overrides.pushOnComplete ?? state.pushOnComplete,\n allowPrd: overrides.allowPrd ?? state.allowPrd,\n allowPlan: overrides.allowPlan ?? state.allowPlan,\n allowMerge: overrides.allowMerge ?? state.allowMerge,\n },\n enableEvidence: overrides.enableEvidence ?? state.enableEvidence,\n commitEvidence: overrides.commitEvidence ?? state.commitEvidence,\n ciWatchEnabled: overrides.ciWatchEnabled ?? state.ciWatchEnabled,\n defaultFastMode: overrides.defaultFastMode ?? state.defaultFastMode,\n autoArchiveDelayMinutes: archiveEnabled\n ? Number.isNaN(archiveDelay) || archiveDelay < 1\n ? 10\n : archiveDelay\n : 0,\n },\n };\n}\n\nexport function WorkflowSettingsSection({ settings }: WorkflowSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [openPr, setOpenPr] = useState(settings.workflow.openPrOnImplementationComplete);\n const [pushOnComplete, setPushOnComplete] = useState(\n settings.workflow.approvalGateDefaults.pushOnImplementationComplete\n );\n const [allowPrd, setAllowPrd] = useState(settings.workflow.approvalGateDefaults.allowPrd);\n const [allowPlan, setAllowPlan] = useState(settings.workflow.approvalGateDefaults.allowPlan);\n const [allowMerge, setAllowMerge] = useState(settings.workflow.approvalGateDefaults.allowMerge);\n const [enableEvidence, setEnableEvidence] = useState(settings.workflow.enableEvidence);\n const [commitEvidence, setCommitEvidence] = useState(settings.workflow.commitEvidence);\n const [ciWatchEnabled, setCiWatchEnabled] = useState(settings.workflow.ciWatchEnabled !== false);\n const [defaultFastMode, setDefaultFastMode] = useState(\n settings.workflow.defaultFastMode !== false\n );\n const [autoArchiveEnabled, setAutoArchiveEnabled] = useState(\n (settings.workflow.autoArchiveDelayMinutes ?? 10) > 0\n );\n const [autoArchiveDelay, setAutoArchiveDelay] = useState(\n String(settings.workflow.autoArchiveDelayMinutes ?? 10)\n );\n\n function getState() {\n return {\n openPr,\n pushOnComplete,\n allowPrd,\n allowPlan,\n allowMerge,\n enableEvidence,\n commitEvidence,\n ciWatchEnabled,\n defaultFastMode,\n autoArchiveEnabled,\n autoArchiveDelay,\n };\n }\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={GitBranch}\n title={t('settings.workflow.title')}\n description={t('settings.workflow.sectionDescription')}\n testId=\"workflow-settings-section\"\n tooltip={t('settings.workflow.hint')}\n tooltipLinks={[\n {\n label: t('settings.workflow.links.approvalGates'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/016-hitl-approval-gates/spec.yaml',\n },\n {\n label: t('settings.workflow.links.pushAndPrFlags'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/037-feature-pr-push-flags/spec.yaml',\n },\n ]}\n >\n <SwitchRow\n label={t('settings.workflow.defaultFastMode')}\n description={t('settings.workflow.defaultFastModeDescription')}\n tooltip=\"When enabled, new features skip the PRD and Plan phases and go straight to implementation. Useful for quick fixes, risky for complex features.\"\n id=\"default-fast-mode\"\n testId=\"switch-default-fast-mode\"\n checked={defaultFastMode}\n onChange={(v) => {\n setDefaultFastMode(v);\n save(buildWorkflowPayload(getState(), { defaultFastMode: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.approve')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.autoApprovePrd')}\n description={t('settings.workflow.autoApprovePrdDescription')}\n tooltip=\"Automatically approves the requirements document without pausing for your review. Saves time but you lose the chance to refine requirements before planning.\"\n id=\"allow-prd\"\n testId=\"switch-allow-prd\"\n checked={allowPrd}\n onChange={(v) => {\n setAllowPrd(v);\n save(buildWorkflowPayload(getState(), { allowPrd: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.autoApprovePlan')}\n description={t('settings.workflow.autoApprovePlanDescription')}\n tooltip=\"Automatically approves the implementation plan. The agent proceeds to coding without waiting for your plan review.\"\n id=\"allow-plan\"\n testId=\"switch-allow-plan\"\n checked={allowPlan}\n onChange={(v) => {\n setAllowPlan(v);\n save(buildWorkflowPayload(getState(), { allowPlan: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.autoApproveMerge')}\n description={t('settings.workflow.autoApproveMergeDescription')}\n tooltip=\"Automatically merges the PR after implementation without requiring your final review. Use with caution on production branches.\"\n id=\"allow-merge\"\n testId=\"switch-allow-merge\"\n checked={allowMerge}\n onChange={(v) => {\n setAllowMerge(v);\n save(buildWorkflowPayload(getState(), { allowMerge: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.evidence')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.collectEvidence')}\n description={t('settings.workflow.collectEvidenceDescription')}\n tooltip=\"Captures screenshots and test outputs during implementation as proof of work. Useful for audit trails and PR documentation.\"\n id=\"enable-evidence\"\n testId=\"switch-enable-evidence\"\n checked={enableEvidence}\n onChange={(v) => {\n setEnableEvidence(v);\n if (!v) {\n setCommitEvidence(false);\n save(buildWorkflowPayload(getState(), { enableEvidence: v, commitEvidence: false }));\n } else {\n save(buildWorkflowPayload(getState(), { enableEvidence: v }));\n }\n }}\n />\n <SwitchRow\n label={t('settings.workflow.addEvidenceToPr')}\n description={t('settings.workflow.addEvidenceToPrDescription')}\n tooltip=\"Attaches collected evidence artifacts (screenshots, logs) directly to the pull request description.\"\n id=\"commit-evidence\"\n testId=\"switch-commit-evidence\"\n checked={commitEvidence}\n disabled={!enableEvidence || !openPr}\n onChange={(v) => {\n setCommitEvidence(v);\n save(buildWorkflowPayload(getState(), { commitEvidence: v }));\n }}\n />\n <SubsectionLabel>{t('settings.workflow.subsections.git')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.workflow.pushOnComplete')}\n description={t('settings.workflow.pushOnCompleteDescription')}\n tooltip=\"Automatically pushes the implementation branch to the remote repository when the agent finishes coding.\"\n id=\"push-on-complete\"\n testId=\"switch-push-on-complete\"\n checked={pushOnComplete}\n onChange={(v) => {\n setPushOnComplete(v);\n save(buildWorkflowPayload(getState(), { pushOnComplete: v }));\n }}\n />\n <SwitchRow\n label={t('settings.workflow.openPrOnComplete')}\n description={t('settings.workflow.openPrOnCompleteDescription')}\n tooltip=\"Creates a pull request automatically after pushing. Combined with push-on-complete, this fully automates the delivery pipeline.\"\n id=\"open-pr\"\n testId=\"switch-open-pr\"\n checked={openPr}\n onChange={(v) => {\n setOpenPr(v);\n if (!v) {\n setCommitEvidence(false);\n save(buildWorkflowPayload(getState(), { openPr: v, commitEvidence: false }));\n } else {\n save(buildWorkflowPayload(getState(), { openPr: v }));\n }\n }}\n />\n <SwitchRow\n label={t('settings.workflow.watchCiAfterPush')}\n description={t('settings.workflow.watchCiAfterPushDescription')}\n tooltip=\"Monitors CI/CD pipeline status after pushing and can attempt fixes if tests fail. Disable if you prefer to handle CI failures manually.\"\n id=\"ci-watch-enabled\"\n testId=\"switch-ci-watch-enabled\"\n checked={ciWatchEnabled}\n onChange={(v) => {\n setCiWatchEnabled(v);\n save(buildWorkflowPayload(getState(), { ciWatchEnabled: v }));\n }}\n />\n <SubsectionLabel>Archive</SubsectionLabel>\n <SwitchRow\n label=\"Auto-archive completed\"\n description=\"Automatically archive features after they reach the completed state\"\n tooltip=\"Automatically archives features from the control center canvas after they reach the completed state, keeping the board clean.\"\n id=\"auto-archive-enabled\"\n testId=\"switch-auto-archive-enabled\"\n checked={autoArchiveEnabled}\n onChange={(v) => {\n setAutoArchiveEnabled(v);\n save(buildWorkflowPayload(getState(), { autoArchiveEnabled: v }));\n }}\n />\n <SettingsRow\n label=\"Archive delay\"\n description=\"Minutes to wait after completion before archiving (1-1440)\"\n tooltip=\"How long to wait after a feature completes before archiving it. Gives you time to review results before the feature moves off the board.\"\n htmlFor=\"auto-archive-delay\"\n >\n <NumberStepper\n id=\"auto-archive-delay\"\n testId=\"input-auto-archive-delay\"\n value={autoArchiveDelay}\n placeholder=\"10\"\n min={1}\n max={1440}\n suffix=\"min\"\n onChange={(v) => {\n setAutoArchiveDelay(v);\n }}\n onBlur={() => {\n if (!autoArchiveEnabled) return;\n const n = parseInt(autoArchiveDelay, 10);\n const clamped = Number.isNaN(n) ? 10 : Math.min(1440, Math.max(1, n));\n setAutoArchiveDelay(String(clamped));\n save(buildWorkflowPayload(getState(), { autoArchiveDelay: String(clamped) }));\n }}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Activity } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SwitchRow, NumberStepper } from './settings-section-utils';\n\nexport interface CiSettingsSectionProps {\n settings: Settings;\n}\n\nfunction parseOptionalInt(value: string): number | undefined {\n if (value === '') return undefined;\n const n = parseInt(value, 10);\n return Number.isNaN(n) || n <= 0 ? undefined : n;\n}\n\nexport function CiSettingsSection({ settings }: CiSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [ciMaxFix, setCiMaxFix] = useState(\n settings.workflow.ciMaxFixAttempts != null ? String(settings.workflow.ciMaxFixAttempts) : ''\n );\n const [ciTimeout, setCiTimeout] = useState(\n settings.workflow.ciWatchTimeoutMs != null\n ? String(Math.round(settings.workflow.ciWatchTimeoutMs / 1000))\n : ''\n );\n const [ciLogMax, setCiLogMax] = useState(\n settings.workflow.ciLogMaxChars != null ? String(settings.workflow.ciLogMaxChars) : ''\n );\n const [ciPollInterval, setCiPollInterval] = useState(\n settings.workflow.ciWatchPollIntervalSeconds != null\n ? String(settings.workflow.ciWatchPollIntervalSeconds)\n : ''\n );\n const [hideCiStatus, setHideCiStatus] = useState(settings.workflow.hideCiStatus !== false);\n\n const originalCiMaxFix =\n settings.workflow.ciMaxFixAttempts != null ? String(settings.workflow.ciMaxFixAttempts) : '';\n const originalCiTimeout =\n settings.workflow.ciWatchTimeoutMs != null\n ? String(Math.round(settings.workflow.ciWatchTimeoutMs / 1000))\n : '';\n const originalCiLogMax =\n settings.workflow.ciLogMaxChars != null ? String(settings.workflow.ciLogMaxChars) : '';\n const originalCiPollInterval =\n settings.workflow.ciWatchPollIntervalSeconds != null\n ? String(settings.workflow.ciWatchPollIntervalSeconds)\n : '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(overrides: {\n ciMaxFix?: string;\n ciTimeout?: string;\n ciLogMax?: string;\n ciPollInterval?: string;\n hideCiStatus?: boolean;\n }) {\n const timeoutSeconds = parseOptionalInt(overrides.ciTimeout ?? ciTimeout);\n return {\n workflow: {\n ciMaxFixAttempts: parseOptionalInt(overrides.ciMaxFix ?? ciMaxFix),\n ciWatchTimeoutMs: timeoutSeconds != null ? timeoutSeconds * 1000 : undefined,\n ciLogMaxChars: parseOptionalInt(overrides.ciLogMax ?? ciLogMax),\n ciWatchPollIntervalSeconds: parseOptionalInt(overrides.ciPollInterval ?? ciPollInterval),\n hideCiStatus: overrides.hideCiStatus ?? hideCiStatus,\n },\n };\n }\n\n return (\n <SettingsSection\n icon={Activity}\n title={t('settings.ci.title')}\n description={t('settings.ci.description')}\n testId=\"ci-settings-section\"\n tooltip={t('settings.ci.hint')}\n tooltipLinks={[\n {\n label: t('settings.ci.links.cicdPipeline'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/cicd.md',\n },\n {\n label: t('settings.ci.links.ciSecurityGates'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/003-cicd-security-gates/spec.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.ci.maxFixAttempts')}\n description={t('settings.ci.maxFixAttemptsDescription')}\n tooltip=\"How many times the agent will attempt to fix failing CI checks before giving up. Higher values increase the chance of auto-resolution but consume more agent time and API calls.\"\n htmlFor=\"ci-max-fix\"\n >\n <NumberStepper\n id=\"ci-max-fix\"\n testId=\"ci-max-fix-input\"\n placeholder=\"3\"\n value={ciMaxFix}\n onChange={setCiMaxFix}\n onBlur={() => {\n if (ciMaxFix !== originalCiMaxFix) save(buildPayload({ ciMaxFix }));\n }}\n min={1}\n max={10}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.watchTimeout')}\n description={t('settings.ci.watchTimeoutDescription')}\n tooltip=\"Maximum time the agent will wait for CI to finish. If CI hasn't completed within this window, the agent stops watching. Increase for repos with slow CI pipelines.\"\n htmlFor=\"ci-timeout\"\n >\n <NumberStepper\n id=\"ci-timeout\"\n testId=\"ci-timeout-input\"\n placeholder=\"300\"\n value={ciTimeout}\n onChange={setCiTimeout}\n onBlur={() => {\n if (ciTimeout !== originalCiTimeout) save(buildPayload({ ciTimeout }));\n }}\n min={30}\n step={30}\n suffix=\"sec\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.maxLogSize')}\n description={t('settings.ci.maxLogSizeDescription')}\n tooltip=\"CI logs beyond this character limit are truncated before being sent to the agent for analysis. Keeps agent context focused and avoids excessive token usage.\"\n htmlFor=\"ci-log-max\"\n >\n <NumberStepper\n id=\"ci-log-max\"\n testId=\"ci-log-max-input\"\n placeholder=\"50000\"\n value={ciLogMax}\n onChange={setCiLogMax}\n onBlur={() => {\n if (ciLogMax !== originalCiLogMax) save(buildPayload({ ciLogMax }));\n }}\n min={1000}\n step={5000}\n suffix=\"chars\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.ci.pollInterval')}\n description={t('settings.ci.pollIntervalDescription')}\n tooltip=\"How frequently the agent checks GitHub for CI status updates. Lower values give faster feedback but increase API call volume.\"\n htmlFor=\"ci-poll-interval\"\n >\n <NumberStepper\n id=\"ci-poll-interval\"\n testId=\"ci-poll-interval-input\"\n placeholder=\"30\"\n value={ciPollInterval}\n onChange={setCiPollInterval}\n onBlur={() => {\n if (ciPollInterval !== originalCiPollInterval) save(buildPayload({ ciPollInterval }));\n }}\n min={5}\n step={5}\n suffix=\"sec\"\n />\n </SettingsRow>\n <SwitchRow\n label={t('settings.ci.hideCiStatus')}\n description={t('settings.ci.hideCiStatusDescription')}\n tooltip=\"When enabled, CI status indicators are hidden from the feature drawer and merge review panels. Useful if you monitor CI through GitHub directly.\"\n id=\"hide-ci-status\"\n testId=\"switch-hide-ci-status\"\n checked={hideCiStatus}\n onChange={(v) => {\n setHideCiStatus(v);\n save(buildPayload({ hideCiStatus: v }));\n }}\n />\n </SettingsSection>\n );\n}\n","\"use client\";\n\n// src/slider.tsx\nimport * as React from \"react\";\nimport { clamp } from \"@radix-ui/number\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { useDirection } from \"@radix-ui/react-direction\";\nimport { usePrevious } from \"@radix-ui/react-use-previous\";\nimport { useSize } from \"@radix-ui/react-use-size\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { createCollection } from \"@radix-ui/react-collection\";\nimport { jsx, jsxs } from \"react/jsx-runtime\";\nvar PAGE_KEYS = [\"PageUp\", \"PageDown\"];\nvar ARROW_KEYS = [\"ArrowUp\", \"ArrowDown\", \"ArrowLeft\", \"ArrowRight\"];\nvar BACK_KEYS = {\n \"from-left\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowLeft\"],\n \"from-right\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowRight\"],\n \"from-bottom\": [\"Home\", \"PageDown\", \"ArrowDown\", \"ArrowLeft\"],\n \"from-top\": [\"Home\", \"PageDown\", \"ArrowUp\", \"ArrowLeft\"]\n};\nvar SLIDER_NAME = \"Slider\";\nvar [Collection, useCollection, createCollectionScope] = createCollection(SLIDER_NAME);\nvar [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [\n createCollectionScope\n]);\nvar [SliderProvider, useSliderContext] = createSliderContext(SLIDER_NAME);\nvar Slider = React.forwardRef(\n (props, forwardedRef) => {\n const {\n name,\n min = 0,\n max = 100,\n step = 1,\n orientation = \"horizontal\",\n disabled = false,\n minStepsBetweenThumbs = 0,\n defaultValue = [min],\n value,\n onValueChange = () => {\n },\n onValueCommit = () => {\n },\n inverted = false,\n form,\n ...sliderProps\n } = props;\n const thumbRefs = React.useRef(/* @__PURE__ */ new Set());\n const valueIndexToChangeRef = React.useRef(0);\n const isHorizontal = orientation === \"horizontal\";\n const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;\n const [values = [], setValues] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange: (value2) => {\n const thumbs = [...thumbRefs.current];\n thumbs[valueIndexToChangeRef.current]?.focus();\n onValueChange(value2);\n }\n });\n const valuesBeforeSlideStartRef = React.useRef(values);\n function handleSlideStart(value2) {\n const closestIndex = getClosestValueIndex(values, value2);\n updateValues(value2, closestIndex);\n }\n function handleSlideMove(value2) {\n updateValues(value2, valueIndexToChangeRef.current);\n }\n function handleSlideEnd() {\n const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];\n const nextValue = values[valueIndexToChangeRef.current];\n const hasChanged = nextValue !== prevValue;\n if (hasChanged) onValueCommit(values);\n }\n function updateValues(value2, atIndex, { commit } = { commit: false }) {\n const decimalCount = getDecimalCount(step);\n const snapToStep = roundValue(Math.round((value2 - min) / step) * step + min, decimalCount);\n const nextValue = clamp(snapToStep, [min, max]);\n setValues((prevValues = []) => {\n const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);\n if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {\n valueIndexToChangeRef.current = nextValues.indexOf(nextValue);\n const hasChanged = String(nextValues) !== String(prevValues);\n if (hasChanged && commit) onValueCommit(nextValues);\n return hasChanged ? nextValues : prevValues;\n } else {\n return prevValues;\n }\n });\n }\n return /* @__PURE__ */ jsx(\n SliderProvider,\n {\n scope: props.__scopeSlider,\n name,\n disabled,\n min,\n max,\n valueIndexToChangeRef,\n thumbs: thumbRefs.current,\n values,\n orientation,\n form,\n children: /* @__PURE__ */ jsx(Collection.Provider, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(Collection.Slot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(\n SliderOrientation,\n {\n \"aria-disabled\": disabled,\n \"data-disabled\": disabled ? \"\" : void 0,\n ...sliderProps,\n ref: forwardedRef,\n onPointerDown: composeEventHandlers(sliderProps.onPointerDown, () => {\n if (!disabled) valuesBeforeSlideStartRef.current = values;\n }),\n min,\n max,\n inverted,\n onSlideStart: disabled ? void 0 : handleSlideStart,\n onSlideMove: disabled ? void 0 : handleSlideMove,\n onSlideEnd: disabled ? void 0 : handleSlideEnd,\n onHomeKeyDown: () => !disabled && updateValues(min, 0, { commit: true }),\n onEndKeyDown: () => !disabled && updateValues(max, values.length - 1, { commit: true }),\n onStepKeyDown: ({ event, direction: stepDirection }) => {\n if (!disabled) {\n const isPageKey = PAGE_KEYS.includes(event.key);\n const isSkipKey = isPageKey || event.shiftKey && ARROW_KEYS.includes(event.key);\n const multiplier = isSkipKey ? 10 : 1;\n const atIndex = valueIndexToChangeRef.current;\n const value2 = values[atIndex];\n const stepInDirection = step * multiplier * stepDirection;\n updateValues(value2 + stepInDirection, atIndex, { commit: true });\n }\n }\n }\n ) }) })\n }\n );\n }\n);\nSlider.displayName = SLIDER_NAME;\nvar [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext(SLIDER_NAME, {\n startEdge: \"left\",\n endEdge: \"right\",\n size: \"width\",\n direction: 1\n});\nvar SliderHorizontal = React.forwardRef(\n (props, forwardedRef) => {\n const {\n min,\n max,\n dir,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const [slider, setSlider] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));\n const rectRef = React.useRef(void 0);\n const direction = useDirection(dir);\n const isDirectionLTR = direction === \"ltr\";\n const isSlidingFromLeft = isDirectionLTR && !inverted || !isDirectionLTR && inverted;\n function getValueFromPointer(pointerPosition) {\n const rect = rectRef.current || slider.getBoundingClientRect();\n const input = [0, rect.width];\n const output = isSlidingFromLeft ? [min, max] : [max, min];\n const value = linearScale(input, output);\n rectRef.current = rect;\n return value(pointerPosition - rect.left);\n }\n return /* @__PURE__ */ jsx(\n SliderOrientationProvider,\n {\n scope: props.__scopeSlider,\n startEdge: isSlidingFromLeft ? \"left\" : \"right\",\n endEdge: isSlidingFromLeft ? \"right\" : \"left\",\n direction: isSlidingFromLeft ? 1 : -1,\n size: \"width\",\n children: /* @__PURE__ */ jsx(\n SliderImpl,\n {\n dir: direction,\n \"data-orientation\": \"horizontal\",\n ...sliderProps,\n ref: composedRefs,\n style: {\n ...sliderProps.style,\n [\"--radix-slider-thumb-transform\"]: \"translateX(-50%)\"\n },\n onSlideStart: (event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideStart?.(value);\n },\n onSlideMove: (event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideMove?.(value);\n },\n onSlideEnd: () => {\n rectRef.current = void 0;\n onSlideEnd?.();\n },\n onStepKeyDown: (event) => {\n const slideDirection = isSlidingFromLeft ? \"from-left\" : \"from-right\";\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }\n }\n )\n }\n );\n }\n);\nvar SliderVertical = React.forwardRef(\n (props, forwardedRef) => {\n const {\n min,\n max,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const sliderRef = React.useRef(null);\n const ref = useComposedRefs(forwardedRef, sliderRef);\n const rectRef = React.useRef(void 0);\n const isSlidingFromBottom = !inverted;\n function getValueFromPointer(pointerPosition) {\n const rect = rectRef.current || sliderRef.current.getBoundingClientRect();\n const input = [0, rect.height];\n const output = isSlidingFromBottom ? [max, min] : [min, max];\n const value = linearScale(input, output);\n rectRef.current = rect;\n return value(pointerPosition - rect.top);\n }\n return /* @__PURE__ */ jsx(\n SliderOrientationProvider,\n {\n scope: props.__scopeSlider,\n startEdge: isSlidingFromBottom ? \"bottom\" : \"top\",\n endEdge: isSlidingFromBottom ? \"top\" : \"bottom\",\n size: \"height\",\n direction: isSlidingFromBottom ? 1 : -1,\n children: /* @__PURE__ */ jsx(\n SliderImpl,\n {\n \"data-orientation\": \"vertical\",\n ...sliderProps,\n ref,\n style: {\n ...sliderProps.style,\n [\"--radix-slider-thumb-transform\"]: \"translateY(50%)\"\n },\n onSlideStart: (event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideStart?.(value);\n },\n onSlideMove: (event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideMove?.(value);\n },\n onSlideEnd: () => {\n rectRef.current = void 0;\n onSlideEnd?.();\n },\n onStepKeyDown: (event) => {\n const slideDirection = isSlidingFromBottom ? \"from-bottom\" : \"from-top\";\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }\n }\n )\n }\n );\n }\n);\nvar SliderImpl = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopeSlider,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onHomeKeyDown,\n onEndKeyDown,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const context = useSliderContext(SLIDER_NAME, __scopeSlider);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n ...sliderProps,\n ref: forwardedRef,\n onKeyDown: composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === \"Home\") {\n onHomeKeyDown(event);\n event.preventDefault();\n } else if (event.key === \"End\") {\n onEndKeyDown(event);\n event.preventDefault();\n } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {\n onStepKeyDown(event);\n event.preventDefault();\n }\n }),\n onPointerDown: composeEventHandlers(props.onPointerDown, (event) => {\n const target = event.target;\n target.setPointerCapture(event.pointerId);\n event.preventDefault();\n if (context.thumbs.has(target)) {\n target.focus();\n } else {\n onSlideStart(event);\n }\n }),\n onPointerMove: composeEventHandlers(props.onPointerMove, (event) => {\n const target = event.target;\n if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);\n }),\n onPointerUp: composeEventHandlers(props.onPointerUp, (event) => {\n const target = event.target;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n onSlideEnd(event);\n }\n })\n }\n );\n }\n);\nvar TRACK_NAME = \"SliderTrack\";\nvar SliderTrack = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, ...trackProps } = props;\n const context = useSliderContext(TRACK_NAME, __scopeSlider);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n \"data-disabled\": context.disabled ? \"\" : void 0,\n \"data-orientation\": context.orientation,\n ...trackProps,\n ref: forwardedRef\n }\n );\n }\n);\nSliderTrack.displayName = TRACK_NAME;\nvar RANGE_NAME = \"SliderRange\";\nvar SliderRange = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, ...rangeProps } = props;\n const context = useSliderContext(RANGE_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const valuesCount = context.values.length;\n const percentages = context.values.map(\n (value) => convertValueToPercentage(value, context.min, context.max)\n );\n const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;\n const offsetEnd = 100 - Math.max(...percentages);\n return /* @__PURE__ */ jsx(\n Primitive.span,\n {\n \"data-orientation\": context.orientation,\n \"data-disabled\": context.disabled ? \"\" : void 0,\n ...rangeProps,\n ref: composedRefs,\n style: {\n ...props.style,\n [orientation.startEdge]: offsetStart + \"%\",\n [orientation.endEdge]: offsetEnd + \"%\"\n }\n }\n );\n }\n);\nSliderRange.displayName = RANGE_NAME;\nvar THUMB_NAME = \"SliderThumb\";\nvar SliderThumb = React.forwardRef(\n (props, forwardedRef) => {\n const getItems = useCollection(props.__scopeSlider);\n const [thumb, setThumb] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const index = React.useMemo(\n () => thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1,\n [getItems, thumb]\n );\n return /* @__PURE__ */ jsx(SliderThumbImpl, { ...props, ref: composedRefs, index });\n }\n);\nvar SliderThumbImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeSlider, index, name, ...thumbProps } = props;\n const context = useSliderContext(THUMB_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);\n const [thumb, setThumb] = React.useState(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const isFormControl = thumb ? context.form || !!thumb.closest(\"form\") : true;\n const size = useSize(thumb);\n const value = context.values[index];\n const percent = value === void 0 ? 0 : convertValueToPercentage(value, context.min, context.max);\n const label = getLabel(index, context.values.length);\n const orientationSize = size?.[orientation.size];\n const thumbInBoundsOffset = orientationSize ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction) : 0;\n React.useEffect(() => {\n if (thumb) {\n context.thumbs.add(thumb);\n return () => {\n context.thumbs.delete(thumb);\n };\n }\n }, [thumb, context.thumbs]);\n return /* @__PURE__ */ jsxs(\n \"span\",\n {\n style: {\n transform: \"var(--radix-slider-thumb-transform)\",\n position: \"absolute\",\n [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`\n },\n children: [\n /* @__PURE__ */ jsx(Collection.ItemSlot, { scope: props.__scopeSlider, children: /* @__PURE__ */ jsx(\n Primitive.span,\n {\n role: \"slider\",\n \"aria-label\": props[\"aria-label\"] || label,\n \"aria-valuemin\": context.min,\n \"aria-valuenow\": value,\n \"aria-valuemax\": context.max,\n \"aria-orientation\": context.orientation,\n \"data-orientation\": context.orientation,\n \"data-disabled\": context.disabled ? \"\" : void 0,\n tabIndex: context.disabled ? void 0 : 0,\n ...thumbProps,\n ref: composedRefs,\n style: value === void 0 ? { display: \"none\" } : props.style,\n onFocus: composeEventHandlers(props.onFocus, () => {\n context.valueIndexToChangeRef.current = index;\n })\n }\n ) }),\n isFormControl && /* @__PURE__ */ jsx(\n SliderBubbleInput,\n {\n name: name ?? (context.name ? context.name + (context.values.length > 1 ? \"[]\" : \"\") : void 0),\n form: context.form,\n value\n },\n index\n )\n ]\n }\n );\n }\n);\nSliderThumb.displayName = THUMB_NAME;\nvar BUBBLE_INPUT_NAME = \"RadioBubbleInput\";\nvar SliderBubbleInput = React.forwardRef(\n ({ __scopeSlider, value, ...props }, forwardedRef) => {\n const ref = React.useRef(null);\n const composedRefs = useComposedRefs(ref, forwardedRef);\n const prevValue = usePrevious(value);\n React.useEffect(() => {\n const input = ref.current;\n if (!input) return;\n const inputProto = window.HTMLInputElement.prototype;\n const descriptor = Object.getOwnPropertyDescriptor(inputProto, \"value\");\n const setValue = descriptor.set;\n if (prevValue !== value && setValue) {\n const event = new Event(\"input\", { bubbles: true });\n setValue.call(input, value);\n input.dispatchEvent(event);\n }\n }, [prevValue, value]);\n return /* @__PURE__ */ jsx(\n Primitive.input,\n {\n style: { display: \"none\" },\n ...props,\n ref: composedRefs,\n defaultValue: value\n }\n );\n }\n);\nSliderBubbleInput.displayName = BUBBLE_INPUT_NAME;\nfunction getNextSortedValues(prevValues = [], nextValue, atIndex) {\n const nextValues = [...prevValues];\n nextValues[atIndex] = nextValue;\n return nextValues.sort((a, b) => a - b);\n}\nfunction convertValueToPercentage(value, min, max) {\n const maxSteps = max - min;\n const percentPerStep = 100 / maxSteps;\n const percentage = percentPerStep * (value - min);\n return clamp(percentage, [0, 100]);\n}\nfunction getLabel(index, totalValues) {\n if (totalValues > 2) {\n return `Value ${index + 1} of ${totalValues}`;\n } else if (totalValues === 2) {\n return [\"Minimum\", \"Maximum\"][index];\n } else {\n return void 0;\n }\n}\nfunction getClosestValueIndex(values, nextValue) {\n if (values.length === 1) return 0;\n const distances = values.map((value) => Math.abs(value - nextValue));\n const closestDistance = Math.min(...distances);\n return distances.indexOf(closestDistance);\n}\nfunction getThumbInBoundsOffset(width, left, direction) {\n const halfWidth = width / 2;\n const halfPercent = 50;\n const offset = linearScale([0, halfPercent], [0, halfWidth]);\n return (halfWidth - offset(left) * direction) * direction;\n}\nfunction getStepsBetweenValues(values) {\n return values.slice(0, -1).map((value, index) => values[index + 1] - value);\n}\nfunction hasMinStepsBetweenValues(values, minStepsBetweenValues) {\n if (minStepsBetweenValues > 0) {\n const stepsBetweenValues = getStepsBetweenValues(values);\n const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);\n return actualMinStepsBetweenValues >= minStepsBetweenValues;\n }\n return true;\n}\nfunction linearScale(input, output) {\n return (value) => {\n if (input[0] === input[1] || output[0] === output[1]) return output[0];\n const ratio = (output[1] - output[0]) / (input[1] - input[0]);\n return output[0] + ratio * (value - input[0]);\n };\n}\nfunction getDecimalCount(value) {\n return (String(value).split(\".\")[1] || \"\").length;\n}\nfunction roundValue(value, decimalCount) {\n const rounder = Math.pow(10, decimalCount);\n return Math.round(value * rounder) / rounder;\n}\nvar Root = Slider;\nvar Track = SliderTrack;\nvar Range = SliderRange;\nvar Thumb = SliderThumb;\nexport {\n Range,\n Root,\n Slider,\n SliderRange,\n SliderThumb,\n SliderTrack,\n Thumb,\n Track,\n createSliderScope\n};\n//# sourceMappingURL=index.mjs.map\n","'use client';\n\nimport * as React from 'react';\nimport { Slider as SliderPrimitive } from 'radix-ui';\n\nimport { cn } from '@/lib/utils';\n\nfunction Slider({\n className,\n defaultValue,\n value,\n min = 0,\n max = 100,\n ...props\n}: React.ComponentProps<typeof SliderPrimitive.Root>) {\n const _values = React.useMemo(\n () => (Array.isArray(value) ? value : Array.isArray(defaultValue) ? defaultValue : [min, max]),\n [value, defaultValue, min, max]\n );\n\n return (\n <SliderPrimitive.Root\n data-slot=\"slider\"\n defaultValue={defaultValue}\n value={value}\n min={min}\n max={max}\n className={cn(\n 'relative flex w-full touch-none items-center select-none data-[disabled]:opacity-50 data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col',\n className\n )}\n {...props}\n >\n <SliderPrimitive.Track\n data-slot=\"slider-track\"\n className={cn(\n 'bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=horizontal]:w-full data-[orientation=vertical]:h-full data-[orientation=vertical]:w-1.5'\n )}\n >\n <SliderPrimitive.Range\n data-slot=\"slider-range\"\n className={cn(\n 'bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full'\n )}\n />\n </SliderPrimitive.Track>\n {Array.from({ length: _values.length }, (_, index) => (\n <SliderPrimitive.Thumb\n data-slot=\"slider-thumb\"\n key={index}\n className=\"border-primary ring-ring/50 block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 focus-visible:outline-hidden disabled:pointer-events-none disabled:opacity-50\"\n />\n ))}\n </SliderPrimitive.Root>\n );\n}\n\nexport { Slider };\n","'use client';\n\nimport { useState, useCallback } from 'react';\nimport { Slider } from '@/components/ui/slider';\n\n/** Fixed duration presets in seconds — slider snaps to these values */\nconst PRESETS = [\n 60, // 1m\n 120, // 2m\n 300, // 5m\n 600, // 10m\n 900, // 15m\n 1800, // 30m\n 2700, // 45m\n 3600, // 1h\n 7200, // 2h\n 10800, // 3h\n 14400, // 4h\n 21600, // 6h\n 28800, // 8h\n 43200, // 12h\n 86400, // 24h\n];\n\nconst SLIDER_MAX = PRESETS.length - 1;\n\n/** Find the closest preset index for a given seconds value */\nfunction secondsToIndex(seconds: number): number {\n let closest = 0;\n let minDiff = Math.abs(seconds - PRESETS[0]);\n for (let i = 1; i < PRESETS.length; i++) {\n const diff = Math.abs(seconds - PRESETS[i]);\n if (diff < minDiff) {\n minDiff = diff;\n closest = i;\n }\n }\n return closest;\n}\n\nexport interface TimeoutSliderProps {\n id: string;\n testId: string;\n /** Current value in seconds (as a string for form compatibility) */\n value: string;\n onChange: (value: string) => void;\n onBlur: () => void;\n defaultSeconds?: number;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n const hours = Math.floor(totalSeconds / 3600);\n const minutes = Math.round((totalSeconds % 3600) / 60);\n\n if (hours === 0) return `${minutes}m`;\n if (minutes === 0) return `${hours}h`;\n return `${hours}h ${minutes}m`;\n}\n\nexport function TimeoutSlider({\n id,\n testId,\n value,\n onChange,\n onBlur,\n defaultSeconds = 1800,\n}: TimeoutSliderProps) {\n const numValue = value === '' ? defaultSeconds : parseInt(value, 10);\n const seconds = numValue || defaultSeconds;\n\n // Local index state prevents snap-back during drag — updates immediately\n // without waiting for the parent to re-render with the new value.\n const [localIndex, setLocalIndex] = useState(() => secondsToIndex(seconds));\n\n // Sync from props only when the resolved index actually differs\n // (e.g. external reset or server push). Avoids overwriting during drag.\n const propsIndex = secondsToIndex(seconds);\n if (propsIndex !== localIndex && PRESETS[localIndex] !== seconds) {\n setLocalIndex(propsIndex);\n }\n\n const handleChange = useCallback(\n ([i]: number[]) => {\n setLocalIndex(i);\n onChange(String(PRESETS[i]));\n },\n [onChange]\n );\n\n return (\n <div className=\"flex w-55 items-center gap-2\">\n <Slider\n id={id}\n data-testid={testId}\n min={0}\n max={SLIDER_MAX}\n step={1}\n value={[localIndex]}\n onValueChange={handleChange}\n onValueCommit={() => onBlur()}\n className=\"min-w-0 flex-1\"\n />\n <span className=\"text-muted-foreground shrink-0 text-end text-xs tabular-nums\">\n {formatDuration(PRESETS[localIndex])}\n </span>\n </div>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Timer } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { TimeoutSlider } from '@/components/features/settings/timeout-slider';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SubsectionLabel } from './settings-section-utils';\n\nexport interface StageTimeoutsSettingsSectionProps {\n settings: Settings;\n}\n\nexport function parseOptionalInt(value: string): number | undefined {\n if (value === '') return undefined;\n const n = parseInt(value, 10);\n return Number.isNaN(n) || n <= 0 ? undefined : n;\n}\n\nexport function secondsToMs(val: string | undefined): number | undefined {\n if (val === undefined) return undefined;\n const n = parseOptionalInt(val);\n return n != null ? n * 1000 : undefined;\n}\n\nexport function StageTimeoutsSettingsSection({ settings }: StageTimeoutsSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const stageTimeoutsConfig = settings.workflow.stageTimeouts;\n const analyzeRepoConfig = settings.workflow.analyzeRepoTimeouts;\n\n const [analyzeTimeout, setAnalyzeTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.analyzeMs ?? 1_800_000) / 1000))\n );\n const [requirementsTimeout, setRequirementsTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.requirementsMs ?? 1_800_000) / 1000))\n );\n const [researchTimeout, setResearchTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.researchMs ?? 1_800_000) / 1000))\n );\n const [planTimeout, setPlanTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.planMs ?? 1_800_000) / 1000))\n );\n const [implementTimeout, setImplementTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.implementMs ?? 1_800_000) / 1000))\n );\n const [mergeTimeout, setMergeTimeout] = useState(\n String(Math.round((stageTimeoutsConfig?.mergeMs ?? 1_800_000) / 1000))\n );\n const [analyzeRepoTimeout, setAnalyzeRepoTimeout] = useState(\n String(Math.round((analyzeRepoConfig?.analyzeMs ?? 600_000) / 1000))\n );\n\n const originalAnalyzeTimeout =\n stageTimeoutsConfig?.analyzeMs != null\n ? String(Math.round(stageTimeoutsConfig.analyzeMs / 1000))\n : '';\n const originalRequirementsTimeout =\n stageTimeoutsConfig?.requirementsMs != null\n ? String(Math.round(stageTimeoutsConfig.requirementsMs / 1000))\n : '';\n const originalResearchTimeout =\n stageTimeoutsConfig?.researchMs != null\n ? String(Math.round(stageTimeoutsConfig.researchMs / 1000))\n : '';\n const originalPlanTimeout =\n stageTimeoutsConfig?.planMs != null\n ? String(Math.round(stageTimeoutsConfig.planMs / 1000))\n : '';\n const originalImplementTimeout =\n stageTimeoutsConfig?.implementMs != null\n ? String(Math.round(stageTimeoutsConfig.implementMs / 1000))\n : '';\n const originalMergeTimeout =\n stageTimeoutsConfig?.mergeMs != null\n ? String(Math.round(stageTimeoutsConfig.mergeMs / 1000))\n : '';\n const originalAnalyzeRepoTimeout =\n analyzeRepoConfig?.analyzeMs != null\n ? String(Math.round(analyzeRepoConfig.analyzeMs / 1000))\n : '';\n\n function buildPayload(overrides: {\n analyzeTimeout?: string;\n requirementsTimeout?: string;\n researchTimeout?: string;\n planTimeout?: string;\n implementTimeout?: string;\n mergeTimeout?: string;\n analyzeRepoTimeout?: string;\n }) {\n return {\n workflow: {\n stageTimeouts: {\n analyzeMs: secondsToMs(overrides.analyzeTimeout ?? analyzeTimeout),\n requirementsMs: secondsToMs(overrides.requirementsTimeout ?? requirementsTimeout),\n researchMs: secondsToMs(overrides.researchTimeout ?? researchTimeout),\n planMs: secondsToMs(overrides.planTimeout ?? planTimeout),\n implementMs: secondsToMs(overrides.implementTimeout ?? implementTimeout),\n mergeMs: secondsToMs(overrides.mergeTimeout ?? mergeTimeout),\n },\n analyzeRepoTimeouts: {\n analyzeMs: secondsToMs(overrides.analyzeRepoTimeout ?? analyzeRepoTimeout),\n },\n },\n };\n }\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Timer}\n title={t('settings.stageTimeouts.title')}\n description={t('settings.stageTimeouts.description')}\n testId=\"stage-timeouts-settings-section\"\n tooltip={t('settings.stageTimeouts.hint')}\n >\n <SubsectionLabel>{t('settings.stageTimeouts.subsections.featureAgent')}</SubsectionLabel>\n <SettingsRow\n label={t('settings.stageTimeouts.analyze')}\n description={t('settings.stageTimeouts.analyzeDescription')}\n htmlFor=\"timeout-analyze\"\n >\n <TimeoutSlider\n id=\"timeout-analyze\"\n testId=\"timeout-analyze-input\"\n value={analyzeTimeout}\n onChange={setAnalyzeTimeout}\n onBlur={() => {\n if (analyzeTimeout !== originalAnalyzeTimeout) save(buildPayload({ analyzeTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.requirements')}\n description={t('settings.stageTimeouts.requirementsDescription')}\n htmlFor=\"timeout-requirements\"\n >\n <TimeoutSlider\n id=\"timeout-requirements\"\n testId=\"timeout-requirements-input\"\n value={requirementsTimeout}\n onChange={setRequirementsTimeout}\n onBlur={() => {\n if (requirementsTimeout !== originalRequirementsTimeout)\n save(buildPayload({ requirementsTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.research')}\n description={t('settings.stageTimeouts.researchDescription')}\n htmlFor=\"timeout-research\"\n >\n <TimeoutSlider\n id=\"timeout-research\"\n testId=\"timeout-research-input\"\n value={researchTimeout}\n onChange={setResearchTimeout}\n onBlur={() => {\n if (researchTimeout !== originalResearchTimeout)\n save(buildPayload({ researchTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.plan')}\n description={t('settings.stageTimeouts.planDescription')}\n htmlFor=\"timeout-plan\"\n >\n <TimeoutSlider\n id=\"timeout-plan\"\n testId=\"timeout-plan-input\"\n value={planTimeout}\n onChange={setPlanTimeout}\n onBlur={() => {\n if (planTimeout !== originalPlanTimeout) save(buildPayload({ planTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.implement')}\n description={t('settings.stageTimeouts.implementDescription')}\n htmlFor=\"timeout-implement\"\n >\n <TimeoutSlider\n id=\"timeout-implement\"\n testId=\"timeout-implement-input\"\n value={implementTimeout}\n onChange={setImplementTimeout}\n onBlur={() => {\n if (implementTimeout !== originalImplementTimeout)\n save(buildPayload({ implementTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.stageTimeouts.merge')}\n description={t('settings.stageTimeouts.mergeDescription')}\n htmlFor=\"timeout-merge\"\n >\n <TimeoutSlider\n id=\"timeout-merge\"\n testId=\"timeout-merge-input\"\n value={mergeTimeout}\n onChange={setMergeTimeout}\n onBlur={() => {\n if (mergeTimeout !== originalMergeTimeout) save(buildPayload({ mergeTimeout }));\n }}\n defaultSeconds={1800}\n />\n </SettingsRow>\n <SubsectionLabel>{t('settings.stageTimeouts.subsections.analyzeRepoAgent')}</SubsectionLabel>\n <SettingsRow\n label={t('settings.stageTimeouts.analyze')}\n description={t('settings.stageTimeouts.analyzeDescription')}\n htmlFor=\"timeout-analyze-repo\"\n >\n <TimeoutSlider\n id=\"timeout-analyze-repo\"\n testId=\"timeout-analyze-repo-input\"\n value={analyzeRepoTimeout}\n onChange={setAnalyzeRepoTimeout}\n onBlur={() => {\n if (analyzeRepoTimeout !== originalAnalyzeRepoTimeout)\n save(buildPayload({ analyzeRepoTimeout }));\n }}\n defaultSeconds={600}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Bell } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, NotificationPreferences } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow, SubsectionLabel } from './settings-section-utils';\n\nexport interface NotificationSettingsSectionProps {\n settings: Settings;\n}\n\nexport function NotificationSettingsSection({ settings }: NotificationSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [inApp, setInApp] = useState(settings.notifications.inApp.enabled);\n const [events, setEvents] = useState({ ...settings.notifications.events });\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildNotificationPayload(\n overrides: {\n inApp?: boolean;\n events?: NotificationPreferences['events'];\n } = {}\n ) {\n return {\n notifications: {\n inApp: { enabled: overrides.inApp ?? inApp },\n events: overrides.events ?? events,\n },\n };\n }\n\n return (\n <SettingsSection\n icon={Bell}\n title={t('settings.notifications.title')}\n description={t('settings.notifications.sectionDescription')}\n testId=\"notification-settings-section\"\n tooltip={t('settings.notifications.hint')}\n tooltipLinks={[\n {\n label: t('settings.notifications.links.notificationSystem'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/021-agent-notifications/spec.yaml',\n },\n ]}\n >\n <SubsectionLabel>{t('settings.notifications.channels')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.inAppLabel')}\n description={t('settings.notifications.inAppDescription')}\n tooltip=\"Master toggle for in-app toast notifications. When disabled, no event toasts will appear regardless of individual event settings below.\"\n id=\"notif-in-app\"\n testId=\"switch-in-app\"\n checked={inApp}\n onChange={(v) => {\n setInApp(v);\n save(buildNotificationPayload({ inApp: v }));\n }}\n />\n\n <SubsectionLabel>{t('settings.notifications.subsections.agentEvents')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.events.agentStarted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent begins working on a feature.\"\n id=\"notif-event-agentStarted\"\n testId=\"switch-event-agentStarted\"\n checked={events.agentStarted}\n onChange={(v) => {\n const newEvents = { ...events, agentStarted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.phaseCompleted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent completes a workflow phase (e.g., requirements, planning, implementation).\"\n id=\"notif-event-phaseCompleted\"\n testId=\"switch-event-phaseCompleted\"\n checked={events.phaseCompleted}\n onChange={(v) => {\n const newEvents = { ...events, phaseCompleted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.waitingApproval')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature is paused and waiting for your approval to continue.\"\n id=\"notif-event-waitingApproval\"\n testId=\"switch-event-waitingApproval\"\n checked={events.waitingApproval}\n onChange={(v) => {\n const newEvents = { ...events, waitingApproval: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.agentCompleted')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent finishes all work on a feature successfully.\"\n id=\"notif-event-agentCompleted\"\n testId=\"switch-event-agentCompleted\"\n checked={events.agentCompleted}\n onChange={(v) => {\n const newEvents = { ...events, agentCompleted: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.agentFailed')}\n tooltip=\"Controls whether you receive an in-app toast notification when an agent encounters an error and stops working on a feature.\"\n id=\"notif-event-agentFailed\"\n testId=\"switch-event-agentFailed\"\n checked={events.agentFailed}\n onChange={(v) => {\n const newEvents = { ...events, agentFailed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n\n <SubsectionLabel>{t('settings.notifications.subsections.pullRequestEvents')}</SubsectionLabel>\n <SwitchRow\n label={t('settings.notifications.events.prMerged')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's pull request is merged into the target branch.\"\n id=\"notif-event-prMerged\"\n testId=\"switch-event-prMerged\"\n checked={events.prMerged}\n onChange={(v) => {\n const newEvents = { ...events, prMerged: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prClosed')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's pull request is closed without merging.\"\n id=\"notif-event-prClosed\"\n testId=\"switch-event-prClosed\"\n checked={events.prClosed}\n onChange={(v) => {\n const newEvents = { ...events, prClosed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prChecksPassed')}\n tooltip=\"Controls whether you receive an in-app toast notification when all CI checks pass on a feature's pull request.\"\n id=\"notif-event-prChecksPassed\"\n testId=\"switch-event-prChecksPassed\"\n checked={events.prChecksPassed}\n onChange={(v) => {\n const newEvents = { ...events, prChecksPassed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prChecksFailed')}\n tooltip=\"Controls whether you receive an in-app toast notification when CI checks fail on a feature's pull request.\"\n id=\"notif-event-prChecksFailed\"\n testId=\"switch-event-prChecksFailed\"\n checked={events.prChecksFailed}\n onChange={(v) => {\n const newEvents = { ...events, prChecksFailed: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.prBlocked')}\n tooltip=\"Controls whether you receive an in-app toast notification when a pull request is blocked by merge conflicts or branch protection rules.\"\n id=\"notif-event-prBlocked\"\n testId=\"switch-event-prBlocked\"\n checked={events.prBlocked}\n onChange={(v) => {\n const newEvents = { ...events, prBlocked: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n <SwitchRow\n label={t('settings.notifications.events.mergeReviewReady')}\n tooltip=\"Controls whether you receive an in-app toast notification when a feature's PR passes all checks and is ready for your merge review.\"\n id=\"notif-event-mergeReviewReady\"\n testId=\"switch-event-mergeReviewReady\"\n checked={events.mergeReviewReady}\n onChange={(v) => {\n const newEvents = { ...events, mergeReviewReady: v };\n setEvents(newEvents);\n save(buildNotificationPayload({ events: newEvents }));\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Flag } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, FeatureFlags } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow } from './settings-section-utils';\n\nexport interface FeatureFlagsSettingsSectionProps {\n settings: Settings;\n}\n\nexport function FeatureFlagsSettingsSection({ settings }: FeatureFlagsSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const featureFlags = settings.featureFlags ?? {\n skills: false,\n envDeploy: false,\n debug: false,\n githubImport: false,\n adoptBranch: false,\n gitRebaseSync: false,\n reactFileManager: false,\n plugins: false,\n mcpServers: false,\n };\n\n const [flags, setFlags] = useState<FeatureFlags>({ ...featureFlags });\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={Flag}\n title={t('settings.featureFlags.title')}\n description={t('settings.featureFlags.sectionDescription')}\n badge={t('settings.featureFlags.badge')}\n testId=\"feature-flags-settings-section\"\n tooltip={t('settings.featureFlags.hint')}\n >\n <SwitchRow\n label={t('settings.featureFlags.skills')}\n description={t('settings.featureFlags.skillsDescription')}\n tooltip=\"Enables the Skills page in the sidebar for browsing and managing Claude Code skills.\"\n id=\"flag-skills\"\n testId=\"switch-flag-skills\"\n checked={flags.skills}\n onChange={(v) => {\n const newFlags = { ...flags, skills: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.deployments')}\n description={t('settings.featureFlags.deploymentsDescription')}\n tooltip=\"Enables experimental deployment features for environment management.\"\n id=\"flag-envDeploy\"\n testId=\"switch-flag-envDeploy\"\n checked={flags.envDeploy}\n onChange={(v) => {\n const newFlags = { ...flags, envDeploy: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.debug')}\n description={t('settings.featureFlags.debugDescription')}\n tooltip=\"Shows additional debugging information in the UI for troubleshooting.\"\n id=\"flag-debug\"\n testId=\"switch-flag-debug\"\n checked={flags.debug}\n onChange={(v) => {\n const newFlags = { ...flags, debug: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.githubImport')}\n description={t('settings.featureFlags.githubImportDescription')}\n tooltip=\"Enables importing repositories directly from GitHub.\"\n id=\"flag-githubImport\"\n testId=\"switch-flag-githubImport\"\n checked={flags.githubImport}\n onChange={(v) => {\n const newFlags = { ...flags, githubImport: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.adoptBranch')}\n description={t('settings.featureFlags.adoptBranchDescription')}\n tooltip=\"Enables adopting existing git branches as ShipIT features.\"\n id=\"flag-adoptBranch\"\n testId=\"switch-flag-adoptBranch\"\n checked={flags.adoptBranch}\n onChange={(v) => {\n const newFlags = { ...flags, adoptBranch: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.gitRebaseSync')}\n description={t('settings.featureFlags.gitRebaseSyncDescription')}\n tooltip=\"Uses git rebase instead of merge when syncing feature branches with the upstream branch.\"\n id=\"flag-gitRebaseSync\"\n testId=\"switch-flag-gitRebaseSync\"\n checked={flags.gitRebaseSync}\n onChange={(v) => {\n const newFlags = { ...flags, gitRebaseSync: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.reactFileManager')}\n description={t('settings.featureFlags.reactFileManagerDescription')}\n tooltip=\"Replaces the native file picker dialog with a React-based file browser for selecting project folders.\"\n id=\"flag-reactFileManager\"\n testId=\"switch-flag-reactFileManager\"\n checked={flags.reactFileManager}\n onChange={(v) => {\n const newFlags = { ...flags, reactFileManager: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.plugins')}\n description={\n settings.litellmProxy?.baseUrl\n ? t('settings.featureFlags.pluginsDescription')\n : `${t('settings.featureFlags.pluginsDescription')} — ${t('plugins.noProxy')}`\n }\n tooltip=\"Enables the Plugins page for browsing and managing Claude Code plugins from a LiteLLM marketplace. Requires a LiteLLM proxy URL to be configured.\"\n id=\"flag-plugins\"\n testId=\"switch-flag-plugins\"\n checked={flags.plugins}\n disabled={!settings.litellmProxy?.baseUrl}\n onChange={(v) => {\n const newFlags = { ...flags, plugins: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n <SwitchRow\n label={t('settings.featureFlags.mcpServers')}\n description={\n settings.litellmProxy?.baseUrl\n ? t('settings.featureFlags.mcpServersDescription')\n : `${t('settings.featureFlags.mcpServersDescription')} — ${t('mcpServers.noProxy')}`\n }\n tooltip=\"Enables the MCP Servers page for viewing MCP servers deployed on your LiteLLM proxy. Requires a LiteLLM proxy URL to be configured.\"\n id=\"flag-mcp-servers\"\n testId=\"switch-flag-mcp-servers\"\n checked={flags.mcpServers}\n disabled={!settings.litellmProxy?.baseUrl}\n onChange={(v) => {\n const newFlags = { ...flags, mcpServers: v };\n setFlags(newFlags);\n save({ featureFlags: newFlags });\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { MessageSquare } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, InteractiveAgentConfig } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow, SwitchRow, NumberStepper } from './settings-section-utils';\n\nexport interface InteractiveAgentSettingsSectionProps {\n settings: Settings;\n}\n\nexport function InteractiveAgentSettingsSection({\n settings,\n}: InteractiveAgentSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const interactiveAgentConfig: InteractiveAgentConfig = settings.interactiveAgent ?? {\n enabled: true,\n autoTimeoutMinutes: 15,\n maxConcurrentSessions: 3,\n };\n\n const [interactiveEnabled, setInteractiveEnabled] = useState(interactiveAgentConfig.enabled);\n const [interactiveTimeout, setInteractiveTimeout] = useState(\n String(interactiveAgentConfig.autoTimeoutMinutes)\n );\n const [interactiveSessions, setInteractiveSessions] = useState(\n String(interactiveAgentConfig.maxConcurrentSessions)\n );\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={MessageSquare}\n title={t('settings.interactiveAgent.title')}\n description={t('settings.interactiveAgent.description')}\n testId=\"interactive-agent-settings-section\"\n tooltip={t('settings.interactiveAgent.hint')}\n >\n <SwitchRow\n label={t('settings.interactiveAgent.enableChatTab')}\n description={t('settings.interactiveAgent.enableChatTabDescription')}\n tooltip=\"Shows or hides the Chat tab on feature detail pages. When enabled, you can have interactive conversations with the agent about a specific feature.\"\n id=\"interactive-agent-enabled\"\n testId=\"switch-interactive-agent-enabled\"\n checked={interactiveEnabled}\n onChange={(v) => {\n setInteractiveEnabled(v);\n save({\n interactiveAgent: {\n enabled: v,\n autoTimeoutMinutes: parseInt(interactiveTimeout, 10) || 15,\n maxConcurrentSessions: parseInt(interactiveSessions, 10) || 3,\n },\n });\n }}\n />\n <SettingsRow\n label={t('settings.interactiveAgent.autoTimeout')}\n description={t('settings.interactiveAgent.autoTimeoutDescription')}\n tooltip=\"Minutes of inactivity before a chat agent session is automatically terminated. Prevents idle agent processes from consuming resources indefinitely.\"\n htmlFor=\"interactive-agent-timeout\"\n >\n <NumberStepper\n id=\"interactive-agent-timeout\"\n testId=\"input-interactive-agent-timeout\"\n value={interactiveTimeout}\n placeholder=\"15\"\n min={1}\n max={120}\n suffix=\"min\"\n onChange={setInteractiveTimeout}\n onBlur={() => {\n const n = parseInt(interactiveTimeout, 10);\n const clamped = Number.isNaN(n) ? 15 : Math.min(120, Math.max(1, n));\n const clampedStr = String(clamped);\n setInteractiveTimeout(clampedStr);\n save({\n interactiveAgent: {\n enabled: interactiveEnabled,\n autoTimeoutMinutes: clamped,\n maxConcurrentSessions: parseInt(interactiveSessions, 10) || 3,\n },\n });\n }}\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.interactiveAgent.maxConcurrentSessions')}\n description={t('settings.interactiveAgent.maxConcurrentSessionsDescription')}\n tooltip=\"Maximum number of interactive agent sessions that can run simultaneously. Each session spawns a separate agent process, so higher values use more CPU and memory.\"\n htmlFor=\"interactive-agent-sessions\"\n >\n <NumberStepper\n id=\"interactive-agent-sessions\"\n testId=\"input-interactive-agent-sessions\"\n value={interactiveSessions}\n placeholder=\"3\"\n min={1}\n max={10}\n onChange={setInteractiveSessions}\n onBlur={() => {\n const n = parseInt(interactiveSessions, 10);\n const clamped = Number.isNaN(n) ? 3 : Math.min(10, Math.max(1, n));\n const clampedStr = String(clamped);\n setInteractiveSessions(clampedStr);\n save({\n interactiveAgent: {\n enabled: interactiveEnabled,\n autoTimeoutMinutes: parseInt(interactiveTimeout, 10) || 15,\n maxConcurrentSessions: clamped,\n },\n });\n }}\n />\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { LayoutGrid } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings, FabLayoutConfig } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SwitchRow } from './settings-section-utils';\n\nexport interface FabLayoutSettingsSectionProps {\n settings: Settings;\n}\n\nexport function FabLayoutSettingsSection({ settings }: FabLayoutSettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const fabLayoutConfig: FabLayoutConfig = settings.fabLayout ?? { swapPosition: false };\n const [fabSwapPosition, setFabSwapPosition] = useState(fabLayoutConfig.swapPosition);\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n return (\n <SettingsSection\n icon={LayoutGrid}\n title={t('settings.fabLayout.title')}\n description={t('settings.fabLayout.description')}\n testId=\"fab-layout-settings-section\"\n tooltip={t('settings.fabLayout.hint')}\n >\n <SwitchRow\n label={t('settings.fabLayout.swapPosition')}\n description={t('settings.fabLayout.swapPositionDescription')}\n tooltip=\"Swaps the Create button (bottom-right) and Chat button (bottom-left) positions on the control center canvas.\"\n id=\"fab-swap-position\"\n testId=\"switch-fab-swap-position\"\n checked={fabSwapPosition}\n onChange={(v) => {\n setFabSwapPosition(v);\n save({ fabLayout: { swapPosition: v } });\n }}\n />\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { Database } from 'lucide-react';\nimport { useTranslation } from 'react-i18next';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\n\nexport interface DatabaseSettingsSectionProps {\n shipitAiHome: string;\n dbFileSize: string;\n}\n\nexport function DatabaseSettingsSection({\n shipitAiHome,\n dbFileSize,\n}: DatabaseSettingsSectionProps) {\n const { t } = useTranslation('web');\n\n return (\n <SettingsSection\n icon={Database}\n title={t('settings.database.title')}\n description={t('settings.database.sectionDescription')}\n testId=\"database-settings-section\"\n tooltip={t('settings.database.hint')}\n tooltipLinks={[\n {\n label: t('settings.database.links.settingsService'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/settings-service.md',\n },\n {\n label: t('settings.database.links.settingsSpec'),\n href: 'https://github.com/jrmatherly/shipit/blob/main/specs/005-global-settings-service/spec.md',\n },\n ]}\n >\n <SettingsRow\n label={t('settings.database.location')}\n description={t('settings.database.locationDescription')}\n tooltip=\"The directory where ShipIT stores its SQLite database, logs, and configuration files. Change this via the SHIPIT_AI_HOME environment variable.\"\n >\n <span\n className=\"text-muted-foreground max-w-50 truncate font-mono text-xs\"\n data-testid=\"shipit-ai-home-path\"\n >\n {shipitAiHome}\n </span>\n </SettingsRow>\n <SettingsRow\n label={t('settings.database.size')}\n tooltip=\"Current size of the SQLite database file on disk. Large databases may slow down startup; consider archiving old features if this grows significantly.\"\n >\n <span className=\"text-muted-foreground text-xs\" data-testid=\"db-file-size\">\n {dbFileSize}\n </span>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","/* __next_internal_action_entry_do_not_use__ [{\"402fc2a2ac18768b2bbec9b50455d3aa3b4c5523f8\":{\"name\":\"addMarketplaceAction\"}},\"src/presentation/web/app/actions/add-marketplace.ts\",\"\"] */\"use turbopack no side effects\";import{createServerReference,callServer,findSourceMapURL}from\"private-next-rsc-action-client-wrapper\";const $$RSC_SERVER_ACTION_0=/*#__PURE__*/createServerReference(\"402fc2a2ac18768b2bbec9b50455d3aa3b4c5523f8\",callServer,void 0,findSourceMapURL,\"addMarketplaceAction\");export{$$RSC_SERVER_ACTION_0 as addMarketplaceAction};","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Server, CheckCircle2, XCircle } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport { addMarketplaceAction } from '@/app/actions/add-marketplace';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport { Input } from '@/components/ui/input';\nimport { Button } from '@/components/ui/button';\n\nexport interface LiteLLMProxySettingsSectionProps {\n settings: Settings;\n}\n\nexport function LiteLLMProxySettingsSection({ settings }: LiteLLMProxySettingsSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n\n const [baseUrl, setBaseUrl] = useState(settings.litellmProxy?.baseUrl ?? '');\n const [apiKey, setApiKey] = useState(settings.litellmProxy?.apiKey ?? '');\n const [testStatus, setTestStatus] = useState<'idle' | 'success' | 'failed'>('idle');\n const [isTesting, setIsTesting] = useState(false);\n\n const originalBaseUrl = settings.litellmProxy?.baseUrl ?? '';\n const originalApiKey = settings.litellmProxy?.apiKey ?? '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(overrides?: { baseUrl?: string; apiKey?: string }) {\n const url = overrides?.baseUrl ?? baseUrl;\n return {\n litellmProxy: {\n baseUrl: url,\n apiKey: overrides?.apiKey ?? apiKey,\n marketplaceEnabled: !!url,\n },\n };\n }\n\n async function handleTestConnection() {\n if (!baseUrl) return;\n setIsTesting(true);\n setTestStatus('idle');\n try {\n const marketplaceUrl = `${baseUrl.replace(/\\/+$/, '')}/claude-code/marketplace.json`;\n const result = await addMarketplaceAction(marketplaceUrl);\n setTestStatus(result.success ? 'success' : 'failed');\n if (result.success) {\n toast.success(t('settings.litellmProxy.testSuccess'));\n } else {\n toast.error(t('settings.litellmProxy.testFailed'));\n }\n } catch {\n setTestStatus('failed');\n toast.error(t('settings.litellmProxy.testFailed'));\n } finally {\n setIsTesting(false);\n }\n }\n\n return (\n <SettingsSection\n icon={Server}\n title={t('settings.litellmProxy.title')}\n description={t('settings.litellmProxy.description')}\n testId=\"litellm-proxy-settings-section\"\n tooltip={t('settings.litellmProxy.hint')}\n >\n <SettingsRow\n label={t('settings.litellmProxy.baseUrl')}\n description={t('settings.litellmProxy.baseUrlDescription')}\n tooltip=\"The base URL of your LiteLLM proxy server. This is used to fetch the plugin marketplace catalog and route model requests.\"\n htmlFor=\"litellm-proxy-url\"\n >\n <Input\n id=\"litellm-proxy-url\"\n data-testid=\"litellm-proxy-url-input\"\n type=\"text\"\n placeholder=\"http://localhost:4000\"\n value={baseUrl}\n onChange={(e) => {\n setBaseUrl(e.target.value);\n setTestStatus('idle');\n }}\n onBlur={() => {\n if (baseUrl !== originalBaseUrl) save(buildPayload({ baseUrl }));\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.litellmProxy.apiKey')}\n description={t('settings.litellmProxy.apiKeyDescription')}\n tooltip=\"A virtual API key for authenticating with the LiteLLM proxy. Stored locally alongside other agent credentials.\"\n htmlFor=\"litellm-api-key\"\n >\n <Input\n id=\"litellm-api-key\"\n data-testid=\"litellm-api-key-input\"\n type=\"password\"\n placeholder=\"sk-...\"\n value={apiKey}\n onChange={(e) => setApiKey(e.target.value)}\n onBlur={() => {\n if (apiKey !== originalApiKey) save(buildPayload({ apiKey }));\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n <SettingsRow\n label={t('settings.litellmProxy.testConnection')}\n tooltip=\"Attempt to connect to the proxy and fetch the marketplace catalog to verify the configuration is correct.\"\n >\n <div className=\"flex items-center gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n data-testid=\"litellm-test-connection-btn\"\n disabled={!baseUrl || isTesting}\n onClick={handleTestConnection}\n className=\"cursor-pointer text-xs\"\n >\n {isTesting ? t('settings.saving') : t('settings.litellmProxy.testConnection')}\n </Button>\n {testStatus === 'success' && (\n <CheckCircle2 className=\"h-4 w-4 text-emerald-500\" data-testid=\"litellm-test-success\" />\n )}\n {testStatus === 'failed' && (\n <XCircle className=\"text-destructive h-4 w-4\" data-testid=\"litellm-test-failed\" />\n )}\n </div>\n </SettingsRow>\n </SettingsSection>\n );\n}\n","'use client';\n\nimport { useState, useTransition } from 'react';\nimport { Route } from 'lucide-react';\nimport { toast } from 'sonner';\nimport { useTranslation } from 'react-i18next';\nimport { updateSettingsAction } from '@/app/actions/update-settings';\nimport type { Settings } from '@shipit-ai/core/domain/generated/output';\nimport { LiteLLMProxyRoutingMode } from '@shipit-ai/core/domain/generated/output';\nimport { SettingsSection, SettingsRow } from './settings-section-utils';\nimport { Input } from '@/components/ui/input';\nimport { Textarea } from '@/components/ui/textarea';\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@/components/ui/select';\n\nexport interface LiteLLMProxyRoutingSectionProps {\n settings: Settings;\n}\n\n/** Agent types that support env-var-based proxy routing (Tier 1) */\nconst TIER1_AGENTS = new Set(['claude-code', 'gemini-cli', 'codex-cli']);\n/** Agent types that need documentation-only panels (Tier 2) */\nconst TIER2_AGENTS = new Set(['cursor', 'copilot-cli']);\n\n/** Get the per-agent proxy config key for building payloads */\nfunction agentConfigKey(agentType: string): string | null {\n switch (agentType) {\n case 'claude-code':\n return 'claudeCode';\n case 'gemini-cli':\n return 'geminiCli';\n case 'codex-cli':\n return 'codexCli';\n default:\n return null;\n }\n}\n\n/** Get the current routing mode for the active agent */\nfunction getRoutingMode(settings: Settings): string {\n const agentType = settings.agent.type as string;\n switch (agentType) {\n case 'claude-code':\n return settings.litellmProxy?.claudeCode?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n case 'gemini-cli':\n return settings.litellmProxy?.geminiCli?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n case 'codex-cli':\n return settings.litellmProxy?.codexCli?.routingMode ?? LiteLLMProxyRoutingMode.direct;\n default:\n return LiteLLMProxyRoutingMode.direct;\n }\n}\n\n/** Whether this agent supports passthrough mode */\nfunction supportsPassthrough(agentType: string): boolean {\n return agentType === 'claude-code';\n}\n\nexport function LiteLLMProxyRoutingSection({ settings }: LiteLLMProxyRoutingSectionProps) {\n const { t } = useTranslation('web');\n const [, startTransition] = useTransition();\n const agentType = settings.agent.type as string;\n\n const cc = settings.litellmProxy?.claudeCode;\n const [routingMode, setRoutingMode] = useState<string>(getRoutingMode(settings));\n const [customHeaders, setCustomHeaders] = useState(cc?.customHeaders ?? '');\n const [sonnetModel, setSonnetModel] = useState(cc?.sonnetModel ?? '');\n const [haikuModel, setHaikuModel] = useState(cc?.haikuModel ?? '');\n const [opusModel, setOpusModel] = useState(cc?.opusModel ?? '');\n\n const originalCustomHeaders = cc?.customHeaders ?? '';\n const originalSonnetModel = cc?.sonnetModel ?? '';\n const originalHaikuModel = cc?.haikuModel ?? '';\n const originalOpusModel = cc?.opusModel ?? '';\n\n const showProxyFields = routingMode !== LiteLLMProxyRoutingMode.direct;\n const isTier1 = TIER1_AGENTS.has(agentType);\n const isTier2 = TIER2_AGENTS.has(agentType);\n const proxyUrl = settings.litellmProxy?.baseUrl ?? '';\n const proxyApiKey = settings.litellmProxy?.apiKey ?? '';\n\n function save(payload: Record<string, unknown>) {\n startTransition(async () => {\n const result = await updateSettingsAction(payload);\n if (!result.success) {\n toast.error(result.error ?? t('settings.failedToSave'));\n }\n });\n }\n\n function buildPayload(\n overrides?: Partial<{\n routingMode: string;\n customHeaders: string;\n sonnetModel: string;\n haikuModel: string;\n opusModel: string;\n }>\n ) {\n const key = agentConfigKey(agentType);\n if (!key) return {};\n\n if (agentType === 'claude-code') {\n return {\n litellmProxy: {\n claudeCode: {\n routingMode: overrides?.routingMode ?? routingMode,\n customHeaders: overrides?.customHeaders ?? customHeaders,\n sonnetModel: overrides?.sonnetModel ?? sonnetModel,\n haikuModel: overrides?.haikuModel ?? haikuModel,\n opusModel: overrides?.opusModel ?? opusModel,\n },\n },\n };\n }\n\n // Gemini CLI and Codex CLI: only routingMode\n return {\n litellmProxy: {\n [key]: {\n routingMode: overrides?.routingMode ?? routingMode,\n },\n },\n };\n }\n\n function handleModeChange(value: string) {\n setRoutingMode(value);\n save(buildPayload({ routingMode: value }));\n }\n\n // Unsupported agent type\n if (!isTier1 && !isTier2) {\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow label=\"\" description={t('settings.litellmProxy.routing.notSupported')}>\n <span />\n </SettingsRow>\n </SettingsSection>\n );\n }\n\n // Tier 2: Documentation-only panels\n if (isTier2) {\n const isCursor = agentType === 'cursor';\n const displayUrl = proxyUrl\n ? isCursor\n ? `${proxyUrl.replace(/\\/+$/, '')}/cursor`\n : proxyUrl\n : '';\n\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow\n label={\n isCursor\n ? t('settings.litellmProxy.routing.cursorInstructions')\n : t('settings.litellmProxy.routing.copilotInstructions')\n }\n description={\n isCursor\n ? t('settings.litellmProxy.routing.cursorDescription')\n : t('settings.litellmProxy.routing.copilotDescription')\n }\n >\n <div className=\"w-64 space-y-2\">\n <code className=\"bg-muted block rounded px-2 py-1 text-xs break-all\">{displayUrl}</code>\n {isCursor && proxyApiKey ? (\n <code className=\"bg-muted block rounded px-2 py-1 text-xs break-all\">\n {proxyApiKey}\n </code>\n ) : null}\n </div>\n </SettingsRow>\n </SettingsSection>\n );\n }\n\n // Tier 1: Env-var-based proxy routing (Claude Code, Gemini CLI, Codex CLI)\n return (\n <SettingsSection\n icon={Route}\n title={t('settings.litellmProxy.routing.title')}\n description={t('settings.litellmProxy.routing.description')}\n testId=\"litellm-proxy-routing-section\"\n tooltip={t('settings.litellmProxy.routing.hint')}\n >\n <SettingsRow\n label={t('settings.litellmProxy.routing.mode')}\n description={t('settings.litellmProxy.routing.modeDescription')}\n htmlFor=\"litellm-routing-mode\"\n >\n <Select value={routingMode} onValueChange={handleModeChange}>\n <SelectTrigger\n id=\"litellm-routing-mode\"\n data-testid=\"litellm-routing-mode-select\"\n className=\"w-48 text-xs\"\n >\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={LiteLLMProxyRoutingMode.direct}>\n {t('settings.litellmProxy.routing.modeDirect')}\n </SelectItem>\n <SelectItem value={LiteLLMProxyRoutingMode.proxy}>\n {t('settings.litellmProxy.routing.modeProxy')}\n </SelectItem>\n {supportsPassthrough(agentType) && (\n <SelectItem value={LiteLLMProxyRoutingMode.passthrough}>\n {t('settings.litellmProxy.routing.modePassthrough')}\n </SelectItem>\n )}\n </SelectContent>\n </Select>\n </SettingsRow>\n\n {routingMode === LiteLLMProxyRoutingMode.passthrough && (\n <SettingsRow label=\"\" description={t('settings.litellmProxy.routing.passthroughHelp')}>\n <span />\n </SettingsRow>\n )}\n\n {showProxyFields && agentType === 'claude-code' ? (\n <>\n <SettingsRow\n label={t('settings.litellmProxy.routing.customHeaders')}\n description={t('settings.litellmProxy.routing.customHeadersDescription')}\n htmlFor=\"litellm-custom-headers\"\n >\n <Textarea\n id=\"litellm-custom-headers\"\n data-testid=\"litellm-custom-headers-input\"\n placeholder={'x-litellm-customer-id: my-user\\nx-litellm-tags: project:acme'}\n value={customHeaders}\n onChange={(e) => setCustomHeaders(e.target.value)}\n onBlur={() => {\n if (customHeaders !== originalCustomHeaders) {\n save(buildPayload({ customHeaders }));\n }\n }}\n rows={3}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.sonnetModel')}\n description={t('settings.litellmProxy.routing.modelOverrideDescription')}\n htmlFor=\"litellm-sonnet-model\"\n >\n <Input\n id=\"litellm-sonnet-model\"\n data-testid=\"litellm-sonnet-model-input\"\n type=\"text\"\n placeholder=\"claude-sonnet-4-6\"\n value={sonnetModel}\n onChange={(e) => setSonnetModel(e.target.value)}\n onBlur={() => {\n if (sonnetModel !== originalSonnetModel) {\n save(buildPayload({ sonnetModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.haikuModel')}\n htmlFor=\"litellm-haiku-model\"\n >\n <Input\n id=\"litellm-haiku-model\"\n data-testid=\"litellm-haiku-model-input\"\n type=\"text\"\n placeholder=\"claude-haiku-4-5\"\n value={haikuModel}\n onChange={(e) => setHaikuModel(e.target.value)}\n onBlur={() => {\n if (haikuModel !== originalHaikuModel) {\n save(buildPayload({ haikuModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n\n <SettingsRow\n label={t('settings.litellmProxy.routing.opusModel')}\n htmlFor=\"litellm-opus-model\"\n >\n <Input\n id=\"litellm-opus-model\"\n data-testid=\"litellm-opus-model-input\"\n type=\"text\"\n placeholder=\"claude-opus-4-6\"\n value={opusModel}\n onChange={(e) => setOpusModel(e.target.value)}\n onBlur={() => {\n if (opusModel !== originalOpusModel) {\n save(buildPayload({ opusModel }));\n }\n }}\n className=\"w-64 text-xs\"\n />\n </SettingsRow>\n </>\n ) : null}\n </SettingsSection>\n );\n}\n","import type { ComponentType, SVGProps } from 'react';\nimport Image from 'next/image';\nimport { Code, Rocket } from 'lucide-react';\nimport { cn } from '@/lib/utils';\n\ntype IconProps = SVGProps<SVGSVGElement> & { className?: string };\n\n/** Fallback icon for unknown editor types. */\nfunction DefaultEditorIcon(props: IconProps) {\n return <Code className={cn('h-4 w-4', props.className)} {...(props as object)} />;\n}\n\nfunction VsCodeIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/vscode.svg\"\n alt=\"VS Code\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nVsCodeIcon.displayName = 'VsCodeIcon';\n\nfunction CursorEditorIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/agents/cursor.jpeg\"\n alt=\"Cursor\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nCursorEditorIcon.displayName = 'CursorEditorIcon';\n\nfunction WindsurfIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/windsurf.svg\"\n alt=\"Windsurf\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nWindsurfIcon.displayName = 'WindsurfIcon';\n\nfunction ZedIcon({ className }: IconProps) {\n return (\n <Image\n src=\"/icons/editors/zed.svg\"\n alt=\"Zed\"\n width={24}\n height={24}\n className={cn('rounded-sm object-contain', className)}\n />\n );\n}\nZedIcon.displayName = 'ZedIcon';\n\nfunction AntigravityIcon({ className, ...props }: IconProps) {\n return <Rocket className={cn('h-4 w-4', className)} {...(props as object)} />;\n}\nAntigravityIcon.displayName = 'AntigravityIcon';\n\nconst editorTypeIconMap: Record<string, ComponentType<IconProps>> = {\n vscode: VsCodeIcon,\n cursor: CursorEditorIcon,\n windsurf: WindsurfIcon,\n zed: ZedIcon,\n antigravity: AntigravityIcon,\n};\n\n/** Resolve an editor type string to its corresponding icon component. */\nexport function getEditorTypeIcon(editorType?: string): ComponentType<IconProps> {\n if (editorType && editorType in editorTypeIconMap) {\n return editorTypeIconMap[editorType];\n }\n return DefaultEditorIcon;\n}\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['circle', { cx: '6', cy: '19', r: '3', key: '1kj8tv' }],\n ['path', { d: 'M9 19h8.5a3.5 3.5 0 0 0 0-7h-11a3.5 3.5 0 0 1 0-7H15', key: '1d8sl' }],\n ['circle', { cx: '18', cy: '5', r: '3', key: 'gq8acd' }],\n];\n\n/**\n * @component @name Route\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/route\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 Route = createLucideIcon('route', __iconNode);\n\nexport default Route;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['ellipse', { cx: '12', cy: '5', rx: '9', ry: '3', key: 'msslwz' }],\n ['path', { d: 'M3 5V19A9 3 0 0 0 21 19V5', key: '1wlel7' }],\n ['path', { d: 'M3 12A9 3 0 0 0 21 12', key: 'mv7ke4' }],\n];\n\n/**\n * @component @name Database\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/database\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 Database = createLucideIcon('database', __iconNode);\n\nexport default Database;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '7', height: '7', x: '3', y: '3', rx: '1', key: '1g98yp' }],\n ['rect', { width: '7', height: '7', x: '14', y: '3', rx: '1', key: '6d4xhi' }],\n ['rect', { width: '7', height: '7', x: '14', y: '14', rx: '1', key: 'nxv5o0' }],\n ['rect', { width: '7', height: '7', x: '3', y: '14', rx: '1', key: '1bb6yr' }],\n];\n\n/**\n * @component @name LayoutGrid\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layout-grid\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 LayoutGrid = createLucideIcon('layout-grid', __iconNode);\n\nexport default LayoutGrid;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['rect', { width: '7', height: '7', x: '3', y: '3', rx: '1', key: '1g98yp' }],\n ['rect', { width: '7', height: '7', x: '3', y: '14', rx: '1', key: '1bb6yr' }],\n ['path', { d: 'M14 4h7', key: '3xa0d5' }],\n ['path', { d: 'M14 9h7', key: '1icrd9' }],\n ['path', { d: 'M14 15h7', key: '1mj8o2' }],\n ['path', { d: 'M14 20h7', key: '11slyb' }],\n];\n\n/**\n * @component @name LayoutList\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/layout-list\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 LayoutList = createLucideIcon('layout-list', __iconNode);\n\nexport default LayoutList;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n [\n 'path',\n {\n d: 'M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528',\n key: '1jaruq',\n },\n ],\n];\n\n/**\n * @component @name Flag\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/flag\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 Flag = createLucideIcon('flag', __iconNode);\n\nexport default Flag;\n","import createLucideIcon from '../createLucideIcon';\nimport { IconNode } from '../types';\n\nexport const __iconNode: IconNode = [\n ['path', { d: 'M10.268 21a2 2 0 0 0 3.464 0', key: 'vwvbt9' }],\n [\n 'path',\n {\n d: 'M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326',\n key: '11g9vi',\n },\n ],\n];\n\n/**\n * @component @name Bell\n * @description Lucide SVG icon component, renders SVG Element with children.\n *\n * @preview  - https://lucide.dev/icons/bell\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 Bell = createLucideIcon('bell', __iconNode);\n\nexport default Bell;\n","import * as React from 'react';\nimport { clamp } from '@radix-ui/number';\nimport { composeEventHandlers } from '@radix-ui/primitive';\nimport { useComposedRefs } from '@radix-ui/react-compose-refs';\nimport { createContextScope } from '@radix-ui/react-context';\nimport { useControllableState } from '@radix-ui/react-use-controllable-state';\nimport { useDirection } from '@radix-ui/react-direction';\nimport { usePrevious } from '@radix-ui/react-use-previous';\nimport { useSize } from '@radix-ui/react-use-size';\nimport { Primitive } from '@radix-ui/react-primitive';\nimport { createCollection } from '@radix-ui/react-collection';\n\nimport type { Scope } from '@radix-ui/react-context';\n\ntype Direction = 'ltr' | 'rtl';\n\nconst PAGE_KEYS = ['PageUp', 'PageDown'];\nconst ARROW_KEYS = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight'];\n\ntype SlideDirection = 'from-left' | 'from-right' | 'from-bottom' | 'from-top';\nconst BACK_KEYS: Record<SlideDirection, string[]> = {\n 'from-left': ['Home', 'PageDown', 'ArrowDown', 'ArrowLeft'],\n 'from-right': ['Home', 'PageDown', 'ArrowDown', 'ArrowRight'],\n 'from-bottom': ['Home', 'PageDown', 'ArrowDown', 'ArrowLeft'],\n 'from-top': ['Home', 'PageDown', 'ArrowUp', 'ArrowLeft'],\n};\n\n/* -------------------------------------------------------------------------------------------------\n * Slider\n * -----------------------------------------------------------------------------------------------*/\n\nconst SLIDER_NAME = 'Slider';\n\nconst [Collection, useCollection, createCollectionScope] =\n createCollection<SliderThumbElement>(SLIDER_NAME);\n\ntype ScopedProps<P> = P & { __scopeSlider?: Scope };\nconst [createSliderContext, createSliderScope] = createContextScope(SLIDER_NAME, [\n createCollectionScope,\n]);\n\ntype SliderContextValue = {\n name: string | undefined;\n disabled: boolean | undefined;\n min: number;\n max: number;\n values: number[];\n valueIndexToChangeRef: React.MutableRefObject<number>;\n thumbs: Set<SliderThumbElement>;\n orientation: SliderProps['orientation'];\n form: string | undefined;\n};\n\nconst [SliderProvider, useSliderContext] = createSliderContext<SliderContextValue>(SLIDER_NAME);\n\ntype SliderElement = SliderHorizontalElement | SliderVerticalElement;\ninterface SliderProps\n extends Omit<\n SliderHorizontalProps | SliderVerticalProps,\n keyof SliderOrientationPrivateProps | 'defaultValue'\n > {\n name?: string;\n disabled?: boolean;\n orientation?: React.AriaAttributes['aria-orientation'];\n dir?: Direction;\n min?: number;\n max?: number;\n step?: number;\n minStepsBetweenThumbs?: number;\n value?: number[];\n defaultValue?: number[];\n onValueChange?(value: number[]): void;\n onValueCommit?(value: number[]): void;\n inverted?: boolean;\n form?: string;\n}\n\nconst Slider = React.forwardRef<SliderElement, SliderProps>(\n (props: ScopedProps<SliderProps>, forwardedRef) => {\n const {\n name,\n min = 0,\n max = 100,\n step = 1,\n orientation = 'horizontal',\n disabled = false,\n minStepsBetweenThumbs = 0,\n defaultValue = [min],\n value,\n onValueChange = () => {},\n onValueCommit = () => {},\n inverted = false,\n form,\n ...sliderProps\n } = props;\n const thumbRefs = React.useRef<SliderContextValue['thumbs']>(new Set());\n const valueIndexToChangeRef = React.useRef<number>(0);\n const isHorizontal = orientation === 'horizontal';\n const SliderOrientation = isHorizontal ? SliderHorizontal : SliderVertical;\n\n const [values = [], setValues] = useControllableState({\n prop: value,\n defaultProp: defaultValue,\n onChange: (value) => {\n const thumbs = [...thumbRefs.current];\n thumbs[valueIndexToChangeRef.current]?.focus();\n onValueChange(value);\n },\n });\n const valuesBeforeSlideStartRef = React.useRef(values);\n\n function handleSlideStart(value: number) {\n const closestIndex = getClosestValueIndex(values, value);\n updateValues(value, closestIndex);\n }\n\n function handleSlideMove(value: number) {\n updateValues(value, valueIndexToChangeRef.current);\n }\n\n function handleSlideEnd() {\n const prevValue = valuesBeforeSlideStartRef.current[valueIndexToChangeRef.current];\n const nextValue = values[valueIndexToChangeRef.current];\n const hasChanged = nextValue !== prevValue;\n if (hasChanged) onValueCommit(values);\n }\n\n function updateValues(value: number, atIndex: number, { commit } = { commit: false }) {\n const decimalCount = getDecimalCount(step);\n const snapToStep = roundValue(Math.round((value - min) / step) * step + min, decimalCount);\n const nextValue = clamp(snapToStep, [min, max]);\n\n setValues((prevValues = []) => {\n const nextValues = getNextSortedValues(prevValues, nextValue, atIndex);\n if (hasMinStepsBetweenValues(nextValues, minStepsBetweenThumbs * step)) {\n valueIndexToChangeRef.current = nextValues.indexOf(nextValue);\n const hasChanged = String(nextValues) !== String(prevValues);\n if (hasChanged && commit) onValueCommit(nextValues);\n return hasChanged ? nextValues : prevValues;\n } else {\n return prevValues;\n }\n });\n }\n\n return (\n <SliderProvider\n scope={props.__scopeSlider}\n name={name}\n disabled={disabled}\n min={min}\n max={max}\n valueIndexToChangeRef={valueIndexToChangeRef}\n thumbs={thumbRefs.current}\n values={values}\n orientation={orientation}\n form={form}\n >\n <Collection.Provider scope={props.__scopeSlider}>\n <Collection.Slot scope={props.__scopeSlider}>\n <SliderOrientation\n aria-disabled={disabled}\n data-disabled={disabled ? '' : undefined}\n {...sliderProps}\n ref={forwardedRef}\n onPointerDown={composeEventHandlers(sliderProps.onPointerDown, () => {\n if (!disabled) valuesBeforeSlideStartRef.current = values;\n })}\n min={min}\n max={max}\n inverted={inverted}\n onSlideStart={disabled ? undefined : handleSlideStart}\n onSlideMove={disabled ? undefined : handleSlideMove}\n onSlideEnd={disabled ? undefined : handleSlideEnd}\n onHomeKeyDown={() => !disabled && updateValues(min, 0, { commit: true })}\n onEndKeyDown={() =>\n !disabled && updateValues(max, values.length - 1, { commit: true })\n }\n onStepKeyDown={({ event, direction: stepDirection }) => {\n if (!disabled) {\n const isPageKey = PAGE_KEYS.includes(event.key);\n const isSkipKey = isPageKey || (event.shiftKey && ARROW_KEYS.includes(event.key));\n const multiplier = isSkipKey ? 10 : 1;\n const atIndex = valueIndexToChangeRef.current;\n const value = values[atIndex]!;\n const stepInDirection = step * multiplier * stepDirection;\n updateValues(value + stepInDirection, atIndex, { commit: true });\n }\n }}\n />\n </Collection.Slot>\n </Collection.Provider>\n </SliderProvider>\n );\n }\n);\n\nSlider.displayName = SLIDER_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderHorizontal\n * -----------------------------------------------------------------------------------------------*/\n\ntype Side = 'top' | 'right' | 'bottom' | 'left';\n\nconst [SliderOrientationProvider, useSliderOrientationContext] = createSliderContext<{\n startEdge: Side;\n endEdge: Side;\n size: keyof NonNullable<ReturnType<typeof useSize>>;\n direction: number;\n}>(SLIDER_NAME, {\n startEdge: 'left',\n endEdge: 'right',\n size: 'width',\n direction: 1,\n});\n\ntype SliderOrientationPrivateProps = {\n min: number;\n max: number;\n inverted: boolean;\n onSlideStart?(value: number): void;\n onSlideMove?(value: number): void;\n onSlideEnd?(): void;\n onHomeKeyDown(event: React.KeyboardEvent): void;\n onEndKeyDown(event: React.KeyboardEvent): void;\n onStepKeyDown(step: { event: React.KeyboardEvent; direction: number }): void;\n};\ninterface SliderOrientationProps\n extends Omit<SliderImplProps, keyof SliderImplPrivateProps>,\n SliderOrientationPrivateProps {}\n\ntype SliderHorizontalElement = SliderImplElement;\ninterface SliderHorizontalProps extends SliderOrientationProps {\n dir?: Direction;\n}\n\nconst SliderHorizontal = React.forwardRef<SliderHorizontalElement, SliderHorizontalProps>(\n (props: ScopedProps<SliderHorizontalProps>, forwardedRef) => {\n const {\n min,\n max,\n dir,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const [slider, setSlider] = React.useState<SliderImplElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setSlider(node));\n const rectRef = React.useRef<DOMRect>(undefined);\n const direction = useDirection(dir);\n const isDirectionLTR = direction === 'ltr';\n const isSlidingFromLeft = (isDirectionLTR && !inverted) || (!isDirectionLTR && inverted);\n\n function getValueFromPointer(pointerPosition: number) {\n const rect = rectRef.current || slider!.getBoundingClientRect();\n const input: [number, number] = [0, rect.width];\n const output: [number, number] = isSlidingFromLeft ? [min, max] : [max, min];\n const value = linearScale(input, output);\n\n rectRef.current = rect;\n return value(pointerPosition - rect.left);\n }\n\n return (\n <SliderOrientationProvider\n scope={props.__scopeSlider}\n startEdge={isSlidingFromLeft ? 'left' : 'right'}\n endEdge={isSlidingFromLeft ? 'right' : 'left'}\n direction={isSlidingFromLeft ? 1 : -1}\n size=\"width\"\n >\n <SliderImpl\n dir={direction}\n data-orientation=\"horizontal\"\n {...sliderProps}\n ref={composedRefs}\n style={{\n ...sliderProps.style,\n ['--radix-slider-thumb-transform' as any]: 'translateX(-50%)',\n }}\n onSlideStart={(event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideStart?.(value);\n }}\n onSlideMove={(event) => {\n const value = getValueFromPointer(event.clientX);\n onSlideMove?.(value);\n }}\n onSlideEnd={() => {\n rectRef.current = undefined;\n onSlideEnd?.();\n }}\n onStepKeyDown={(event) => {\n const slideDirection = isSlidingFromLeft ? 'from-left' : 'from-right';\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }}\n />\n </SliderOrientationProvider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderVertical\n * -----------------------------------------------------------------------------------------------*/\n\ntype SliderVerticalElement = SliderImplElement;\ninterface SliderVerticalProps extends SliderOrientationProps {}\n\nconst SliderVertical = React.forwardRef<SliderVerticalElement, SliderVerticalProps>(\n (props: ScopedProps<SliderVerticalProps>, forwardedRef) => {\n const {\n min,\n max,\n inverted,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const sliderRef = React.useRef<SliderImplElement>(null);\n const ref = useComposedRefs(forwardedRef, sliderRef);\n const rectRef = React.useRef<DOMRect>(undefined);\n const isSlidingFromBottom = !inverted;\n\n function getValueFromPointer(pointerPosition: number) {\n const rect = rectRef.current || sliderRef.current!.getBoundingClientRect();\n const input: [number, number] = [0, rect.height];\n const output: [number, number] = isSlidingFromBottom ? [max, min] : [min, max];\n const value = linearScale(input, output);\n\n rectRef.current = rect;\n return value(pointerPosition - rect.top);\n }\n\n return (\n <SliderOrientationProvider\n scope={props.__scopeSlider}\n startEdge={isSlidingFromBottom ? 'bottom' : 'top'}\n endEdge={isSlidingFromBottom ? 'top' : 'bottom'}\n size=\"height\"\n direction={isSlidingFromBottom ? 1 : -1}\n >\n <SliderImpl\n data-orientation=\"vertical\"\n {...sliderProps}\n ref={ref}\n style={{\n ...sliderProps.style,\n ['--radix-slider-thumb-transform' as any]: 'translateY(50%)',\n }}\n onSlideStart={(event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideStart?.(value);\n }}\n onSlideMove={(event) => {\n const value = getValueFromPointer(event.clientY);\n onSlideMove?.(value);\n }}\n onSlideEnd={() => {\n rectRef.current = undefined;\n onSlideEnd?.();\n }}\n onStepKeyDown={(event) => {\n const slideDirection = isSlidingFromBottom ? 'from-bottom' : 'from-top';\n const isBackKey = BACK_KEYS[slideDirection].includes(event.key);\n onStepKeyDown?.({ event, direction: isBackKey ? -1 : 1 });\n }}\n />\n </SliderOrientationProvider>\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderImpl\n * -----------------------------------------------------------------------------------------------*/\n\ntype SliderImplElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveDivProps = React.ComponentPropsWithoutRef<typeof Primitive.div>;\ntype SliderImplPrivateProps = {\n onSlideStart(event: React.PointerEvent): void;\n onSlideMove(event: React.PointerEvent): void;\n onSlideEnd(event: React.PointerEvent): void;\n onHomeKeyDown(event: React.KeyboardEvent): void;\n onEndKeyDown(event: React.KeyboardEvent): void;\n onStepKeyDown(event: React.KeyboardEvent): void;\n};\ninterface SliderImplProps extends PrimitiveDivProps, SliderImplPrivateProps {}\n\nconst SliderImpl = React.forwardRef<SliderImplElement, SliderImplProps>(\n (props: ScopedProps<SliderImplProps>, forwardedRef) => {\n const {\n __scopeSlider,\n onSlideStart,\n onSlideMove,\n onSlideEnd,\n onHomeKeyDown,\n onEndKeyDown,\n onStepKeyDown,\n ...sliderProps\n } = props;\n const context = useSliderContext(SLIDER_NAME, __scopeSlider);\n\n return (\n <Primitive.span\n {...sliderProps}\n ref={forwardedRef}\n onKeyDown={composeEventHandlers(props.onKeyDown, (event) => {\n if (event.key === 'Home') {\n onHomeKeyDown(event);\n // Prevent scrolling to page start\n event.preventDefault();\n } else if (event.key === 'End') {\n onEndKeyDown(event);\n // Prevent scrolling to page end\n event.preventDefault();\n } else if (PAGE_KEYS.concat(ARROW_KEYS).includes(event.key)) {\n onStepKeyDown(event);\n // Prevent scrolling for directional key presses\n event.preventDefault();\n }\n })}\n onPointerDown={composeEventHandlers(props.onPointerDown, (event) => {\n const target = event.target as HTMLElement;\n target.setPointerCapture(event.pointerId);\n // Prevent browser focus behaviour because we focus a thumb manually when values change.\n event.preventDefault();\n // Touch devices have a delay before focusing so won't focus if touch immediately moves\n // away from target (sliding). We want thumb to focus regardless.\n if (context.thumbs.has(target)) {\n target.focus();\n } else {\n onSlideStart(event);\n }\n })}\n onPointerMove={composeEventHandlers(props.onPointerMove, (event) => {\n const target = event.target as HTMLElement;\n if (target.hasPointerCapture(event.pointerId)) onSlideMove(event);\n })}\n onPointerUp={composeEventHandlers(props.onPointerUp, (event) => {\n const target = event.target as HTMLElement;\n if (target.hasPointerCapture(event.pointerId)) {\n target.releasePointerCapture(event.pointerId);\n onSlideEnd(event);\n }\n })}\n />\n );\n }\n);\n\n/* -------------------------------------------------------------------------------------------------\n * SliderTrack\n * -----------------------------------------------------------------------------------------------*/\n\nconst TRACK_NAME = 'SliderTrack';\n\ntype SliderTrackElement = React.ComponentRef<typeof Primitive.span>;\ntype PrimitiveSpanProps = React.ComponentPropsWithoutRef<typeof Primitive.span>;\ninterface SliderTrackProps extends PrimitiveSpanProps {}\n\nconst SliderTrack = React.forwardRef<SliderTrackElement, SliderTrackProps>(\n (props: ScopedProps<SliderTrackProps>, forwardedRef) => {\n const { __scopeSlider, ...trackProps } = props;\n const context = useSliderContext(TRACK_NAME, __scopeSlider);\n return (\n <Primitive.span\n data-disabled={context.disabled ? '' : undefined}\n data-orientation={context.orientation}\n {...trackProps}\n ref={forwardedRef}\n />\n );\n }\n);\n\nSliderTrack.displayName = TRACK_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderRange\n * -----------------------------------------------------------------------------------------------*/\n\nconst RANGE_NAME = 'SliderRange';\n\ntype SliderRangeElement = React.ComponentRef<typeof Primitive.span>;\ninterface SliderRangeProps extends PrimitiveSpanProps {}\n\nconst SliderRange = React.forwardRef<SliderRangeElement, SliderRangeProps>(\n (props: ScopedProps<SliderRangeProps>, forwardedRef) => {\n const { __scopeSlider, ...rangeProps } = props;\n const context = useSliderContext(RANGE_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(RANGE_NAME, __scopeSlider);\n const ref = React.useRef<HTMLSpanElement>(null);\n const composedRefs = useComposedRefs(forwardedRef, ref);\n const valuesCount = context.values.length;\n const percentages = context.values.map((value) =>\n convertValueToPercentage(value, context.min, context.max)\n );\n const offsetStart = valuesCount > 1 ? Math.min(...percentages) : 0;\n const offsetEnd = 100 - Math.max(...percentages);\n\n return (\n <Primitive.span\n data-orientation={context.orientation}\n data-disabled={context.disabled ? '' : undefined}\n {...rangeProps}\n ref={composedRefs}\n style={{\n ...props.style,\n [orientation.startEdge]: offsetStart + '%',\n [orientation.endEdge]: offsetEnd + '%',\n }}\n />\n );\n }\n);\n\nSliderRange.displayName = RANGE_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderThumb\n * -----------------------------------------------------------------------------------------------*/\n\nconst THUMB_NAME = 'SliderThumb';\n\ntype SliderThumbElement = SliderThumbImplElement;\ninterface SliderThumbProps extends Omit<SliderThumbImplProps, 'index'> {}\n\nconst SliderThumb = React.forwardRef<SliderThumbElement, SliderThumbProps>(\n (props: ScopedProps<SliderThumbProps>, forwardedRef) => {\n const getItems = useCollection(props.__scopeSlider);\n const [thumb, setThumb] = React.useState<SliderThumbImplElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n const index = React.useMemo(\n () => (thumb ? getItems().findIndex((item) => item.ref.current === thumb) : -1),\n [getItems, thumb]\n );\n return <SliderThumbImpl {...props} ref={composedRefs} index={index} />;\n }\n);\n\ntype SliderThumbImplElement = React.ComponentRef<typeof Primitive.span>;\ninterface SliderThumbImplProps extends PrimitiveSpanProps {\n index: number;\n name?: string;\n}\n\nconst SliderThumbImpl = React.forwardRef<SliderThumbImplElement, SliderThumbImplProps>(\n (props: ScopedProps<SliderThumbImplProps>, forwardedRef) => {\n const { __scopeSlider, index, name, ...thumbProps } = props;\n const context = useSliderContext(THUMB_NAME, __scopeSlider);\n const orientation = useSliderOrientationContext(THUMB_NAME, __scopeSlider);\n const [thumb, setThumb] = React.useState<HTMLSpanElement | null>(null);\n const composedRefs = useComposedRefs(forwardedRef, (node) => setThumb(node));\n // We set this to true by default so that events bubble to forms without JS (SSR)\n const isFormControl = thumb ? context.form || !!thumb.closest('form') : true;\n const size = useSize(thumb);\n // We cast because index could be `-1` which would return undefined\n const value = context.values[index] as number | undefined;\n const percent =\n value === undefined ? 0 : convertValueToPercentage(value, context.min, context.max);\n const label = getLabel(index, context.values.length);\n const orientationSize = size?.[orientation.size];\n const thumbInBoundsOffset = orientationSize\n ? getThumbInBoundsOffset(orientationSize, percent, orientation.direction)\n : 0;\n\n React.useEffect(() => {\n if (thumb) {\n context.thumbs.add(thumb);\n return () => {\n context.thumbs.delete(thumb);\n };\n }\n }, [thumb, context.thumbs]);\n\n return (\n <span\n style={{\n transform: 'var(--radix-slider-thumb-transform)',\n position: 'absolute',\n [orientation.startEdge]: `calc(${percent}% + ${thumbInBoundsOffset}px)`,\n }}\n >\n <Collection.ItemSlot scope={props.__scopeSlider}>\n <Primitive.span\n role=\"slider\"\n aria-label={props['aria-label'] || label}\n aria-valuemin={context.min}\n aria-valuenow={value}\n aria-valuemax={context.max}\n aria-orientation={context.orientation}\n data-orientation={context.orientation}\n data-disabled={context.disabled ? '' : undefined}\n tabIndex={context.disabled ? undefined : 0}\n {...thumbProps}\n ref={composedRefs}\n /**\n * There will be no value on initial render while we work out the index so we hide thumbs\n * without a value, otherwise SSR will render them in the wrong position before they\n * snap into the correct position during hydration which would be visually jarring for\n * slower connections.\n */\n style={value === undefined ? { display: 'none' } : props.style}\n onFocus={composeEventHandlers(props.onFocus, () => {\n context.valueIndexToChangeRef.current = index;\n })}\n />\n </Collection.ItemSlot>\n\n {isFormControl && (\n <SliderBubbleInput\n key={index}\n name={\n name ??\n (context.name ? context.name + (context.values.length > 1 ? '[]' : '') : undefined)\n }\n form={context.form}\n value={value}\n />\n )}\n </span>\n );\n }\n);\n\nSliderThumb.displayName = THUMB_NAME;\n\n/* -------------------------------------------------------------------------------------------------\n * SliderBubbleInput\n * -----------------------------------------------------------------------------------------------*/\n\nconst BUBBLE_INPUT_NAME = 'RadioBubbleInput';\n\ntype InputProps = React.ComponentPropsWithoutRef<typeof Primitive.input>;\ninterface SliderBubbleInputProps extends InputProps {}\n\nconst SliderBubbleInput = React.forwardRef<HTMLInputElement, SliderBubbleInputProps>(\n ({ __scopeSlider, value, ...props }: ScopedProps<SliderBubbleInputProps>, forwardedRef) => {\n const ref = React.useRef<HTMLInputElement>(null);\n const composedRefs = useComposedRefs(ref, forwardedRef);\n const prevValue = usePrevious(value);\n\n // Bubble value change to parents (e.g form change event)\n React.useEffect(() => {\n const input = ref.current;\n if (!input) return;\n\n const inputProto = window.HTMLInputElement.prototype;\n const descriptor = Object.getOwnPropertyDescriptor(inputProto, 'value') as PropertyDescriptor;\n const setValue = descriptor.set;\n if (prevValue !== value && setValue) {\n const event = new Event('input', { bubbles: true });\n setValue.call(input, value);\n input.dispatchEvent(event);\n }\n }, [prevValue, value]);\n\n /**\n * We purposefully do not use `type=\"hidden\"` here otherwise forms that\n * wrap it will not be able to access its value via the FormData API.\n *\n * We purposefully do not add the `value` attribute here to allow the value\n * to be set programmatically and bubble to any parent form `onChange` event.\n * Adding the `value` will cause React to consider the programmatic\n * dispatch a duplicate and it will get swallowed.\n */\n return (\n <Primitive.input\n style={{ display: 'none' }}\n {...props}\n ref={composedRefs}\n defaultValue={value}\n />\n );\n }\n);\n\nSliderBubbleInput.displayName = BUBBLE_INPUT_NAME;\n\n/* -----------------------------------------------------------------------------------------------*/\n\nfunction getNextSortedValues(prevValues: number[] = [], nextValue: number, atIndex: number) {\n const nextValues = [...prevValues];\n nextValues[atIndex] = nextValue;\n return nextValues.sort((a, b) => a - b);\n}\n\nfunction convertValueToPercentage(value: number, min: number, max: number) {\n const maxSteps = max - min;\n const percentPerStep = 100 / maxSteps;\n const percentage = percentPerStep * (value - min);\n return clamp(percentage, [0, 100]);\n}\n\n/**\n * Returns a label for each thumb when there are two or more thumbs\n */\nfunction getLabel(index: number, totalValues: number) {\n if (totalValues > 2) {\n return `Value ${index + 1} of ${totalValues}`;\n } else if (totalValues === 2) {\n return ['Minimum', 'Maximum'][index];\n } else {\n return undefined;\n }\n}\n\n/**\n * Given a `values` array and a `nextValue`, determine which value in\n * the array is closest to `nextValue` and return its index.\n *\n * @example\n * // returns 1\n * getClosestValueIndex([10, 30], 25);\n */\nfunction getClosestValueIndex(values: number[], nextValue: number) {\n if (values.length === 1) return 0;\n const distances = values.map((value) => Math.abs(value - nextValue));\n const closestDistance = Math.min(...distances);\n return distances.indexOf(closestDistance);\n}\n\n/**\n * Offsets the thumb centre point while sliding to ensure it remains\n * within the bounds of the slider when reaching the edges\n */\nfunction getThumbInBoundsOffset(width: number, left: number, direction: number) {\n const halfWidth = width / 2;\n const halfPercent = 50;\n const offset = linearScale([0, halfPercent], [0, halfWidth]);\n return (halfWidth - offset(left) * direction) * direction;\n}\n\n/**\n * Gets an array of steps between each value.\n *\n * @example\n * // returns [1, 9]\n * getStepsBetweenValues([10, 11, 20]);\n */\nfunction getStepsBetweenValues(values: number[]) {\n return values.slice(0, -1).map((value, index) => values[index + 1]! - value);\n}\n\n/**\n * Verifies the minimum steps between all values is greater than or equal\n * to the expected minimum steps.\n *\n * @example\n * // returns false\n * hasMinStepsBetweenValues([1,2,3], 2);\n *\n * @example\n * // returns true\n * hasMinStepsBetweenValues([1,2,3], 1);\n */\nfunction hasMinStepsBetweenValues(values: number[], minStepsBetweenValues: number) {\n if (minStepsBetweenValues > 0) {\n const stepsBetweenValues = getStepsBetweenValues(values);\n const actualMinStepsBetweenValues = Math.min(...stepsBetweenValues);\n return actualMinStepsBetweenValues >= minStepsBetweenValues;\n }\n return true;\n}\n\n// https://github.com/tmcw-up-for-adoption/simple-linear-scale/blob/master/index.js\nfunction linearScale(input: readonly [number, number], output: readonly [number, number]) {\n return (value: number) => {\n if (input[0] === input[1] || output[0] === output[1]) return output[0];\n const ratio = (output[1] - output[0]) / (input[1] - input[0]);\n return output[0] + ratio * (value - input[0]);\n };\n}\n\nfunction getDecimalCount(value: number) {\n return (String(value).split('.')[1] || '').length;\n}\n\nfunction roundValue(value: number, decimalCount: number) {\n const rounder = Math.pow(10, decimalCount);\n return Math.round(value * rounder) / rounder;\n}\n\nconst Root = Slider;\nconst Track = SliderTrack;\nconst Range = SliderRange;\nconst Thumb = SliderThumb;\n\nexport {\n createSliderScope,\n //\n Slider,\n SliderTrack,\n SliderRange,\n SliderThumb,\n //\n Root,\n Track,\n Range,\n Thumb,\n};\nexport type { SliderProps, SliderTrackProps, SliderRangeProps, SliderThumbProps };\n"],"names":["__iconNode","d"],"mappings":"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","ignoreList":[7,20,21,22,23,24,25,26]}
|