@shipit-ai/cli 1.168.0 → 1.169.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts +3 -3
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.js +23 -102
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts +2 -3
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/agent-settings-section.stories.js +18 -22
- package/dist/src/presentation/web/components/features/settings/ci-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/ci-settings-section.js +14 -5
- package/dist/src/presentation/web/components/features/settings/database-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/database-settings-section.js +14 -4
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.d.ts +9 -3
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.js +75 -65
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/environment-settings-section.stories.js +20 -18
- package/dist/src/presentation/web/components/features/settings/fab-layout-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/fab-layout-settings-section.js +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts +3 -3
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.js +48 -50
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/feature-flags-settings-section.stories.js +25 -25
- package/dist/src/presentation/web/components/features/settings/interactive-agent-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/interactive-agent-settings-section.js +3 -3
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.d.ts +3 -3
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.js +64 -47
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/notification-settings-section.stories.js +32 -24
- package/dist/src/presentation/web/components/features/settings/settings-page-client.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.js +27 -378
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts +2 -0
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js +13 -0
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.d.ts +8 -8
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.js +3 -6
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.js +7 -7
- package/dist/src/presentation/web/components/features/settings/stage-timeouts-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/stage-timeouts-settings-section.js +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.d.ts +3 -3
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.js +118 -165
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.d.ts.map +1 -1
- package/dist/src/presentation/web/components/features/settings/workflow-settings-section.stories.js +26 -64
- package/dist/src/presentation/web/components/ui/tooltip.d.ts.map +1 -1
- package/dist/src/presentation/web/components/ui/tooltip.js +3 -3
- package/dist/translations/ar/web.json +1 -0
- package/dist/translations/de/web.json +1 -0
- package/dist/translations/en/web.json +1 -0
- package/dist/translations/es/web.json +1 -0
- package/dist/translations/fr/web.json +1 -0
- package/dist/translations/he/web.json +1 -0
- package/dist/translations/pt/web.json +1 -0
- package/dist/translations/ru/web.json +1 -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/settings/page/server-reference-manifest.json +11 -11
- 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/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]__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]__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]__0qxd563._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0qxd563._.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]__0rvrr1j._.js +1 -1
- package/web/.next/server/chunks/ssr/[root-of-the-server]__0rvrr1j._.js.map +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/{_08_079y._.js → _01qdxy2._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_08_079y._.js.map → _01qdxy2._.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/_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/_0a_8rlj._.js +3 -0
- package/web/.next/server/chunks/ssr/{_0mi5qj~._.js.map → _0a_8rlj._.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/_0n.magx._.js +1 -1
- package/web/.next/server/chunks/ssr/_0n.magx._.js.map +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/{_0txr945._.js → _0pa1dkv._.js} +2 -2
- package/web/.next/server/chunks/ssr/_0pa1dkv._.js.map +1 -0
- 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/_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/{_0r04xhw._.js → _0wor25i._.js} +2 -2
- package/web/.next/server/chunks/ssr/{_0r04xhw._.js.map → _0wor25i._.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/_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_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 +50 -50
- package/web/.next/static/chunks/{01znjuvi5t9~q.js → 00m_fbc2z1gyi.js} +3 -3
- package/web/.next/static/chunks/{0ygtupas8pxdi.js → 09f2lesd_dd3~.js} +1 -1
- package/web/.next/static/chunks/0c0dau5pmseko.js +1 -0
- package/web/.next/static/chunks/{078lp287u~c~b.js → 0dq50gtgaj63f.js} +1 -1
- package/web/.next/static/chunks/{06nsv-_ec9ehn.js → 0k0j7anrbg-of.js} +1 -1
- package/web/.next/static/chunks/{17c31c1biwfyi.js → 0o33urrd3lk~u.js} +1 -1
- package/web/.next/static/chunks/0u_27fdqa2jeg.js +1 -0
- package/web/.next/static/chunks/0xwh.0u-dexsl.js +1 -0
- package/web/.next/static/chunks/0yibymrb2j05t.css +1 -0
- package/web/.next/static/chunks/103xnw203o9k1.js +1 -0
- package/web/.next/static/chunks/{0cv09-g0prv4o.js → 11vbir.u7_zf7.js} +1 -1
- package/web/.next/static/chunks/{133q8d69p6cl0.js → 121v1_d_dfk2k.js} +1 -1
- package/web/.next/static/chunks/{0_xww9bsde~1x.js → 12axopx66pocj.js} +1 -1
- package/web/.next/static/chunks/{0hg8qgtv~kuys.js → 183ehj-b80a~o.js} +1 -1
- package/web/.next/static/chunks/{0_v4t6gzx.332.js → 1874_wt9rit96.js} +1 -1
- package/web/.next/server/chunks/ssr/_0mi5qj~._.js +0 -3
- package/web/.next/server/chunks/ssr/_0txr945._.js.map +0 -1
- package/web/.next/static/chunks/033sl_l5o3uo8.css +0 -1
- package/web/.next/static/chunks/04r9m_5p953mf.js +0 -1
- package/web/.next/static/chunks/07i3-aamszsoh.js +0 -1
- package/web/.next/static/chunks/0ee1d3_y40g9f.js +0 -1
- package/web/.next/static/chunks/15mks7_3venc1.js +0 -1
- /package/web/.next/static/{LQMB6QAutWzPQnLUZG96y → SNdaKJ9fpre8tUMRe1jlA}/_buildManifest.js +0 -0
- /package/web/.next/static/{LQMB6QAutWzPQnLUZG96y → SNdaKJ9fpre8tUMRe1jlA}/_clientMiddlewareManifest.js +0 -0
- /package/web/.next/static/{LQMB6QAutWzPQnLUZG96y → SNdaKJ9fpre8tUMRe1jlA}/_ssgManifest.js +0 -0
|
@@ -1,33 +1,19 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useState,
|
|
4
|
-
import {
|
|
5
|
-
import { toast } from 'sonner';
|
|
3
|
+
import { useState, useEffect } from 'react';
|
|
4
|
+
import { Bot, Terminal, GitBranch, Activity, Bell, Flag, Database, Timer, MessageSquare, LayoutGrid, LayoutList, } from 'lucide-react';
|
|
6
5
|
import { useTranslation } from 'react-i18next';
|
|
7
6
|
import { cn } from '../../../lib/utils.js';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import { SettingsSection, SettingsRow, SwitchRow, NumberStepper, SubsectionLabel, SectionHint, } from '../../features/settings/settings-section-utils.js';
|
|
19
|
-
const DEFAULT_EDITOR_OPTIONS = [
|
|
20
|
-
{ id: 'vscode', name: 'VS Code', available: true },
|
|
21
|
-
{ id: 'cursor', name: 'Cursor', available: true },
|
|
22
|
-
{ id: 'windsurf', name: 'Windsurf', available: true },
|
|
23
|
-
{ id: 'zed', name: 'Zed', available: true },
|
|
24
|
-
{ id: 'antigravity', name: 'Antigravity', available: true },
|
|
25
|
-
];
|
|
26
|
-
const DEFAULT_SHELL_OPTIONS = [
|
|
27
|
-
{ id: 'bash', name: 'Bash', available: true },
|
|
28
|
-
{ id: 'zsh', name: 'Zsh', available: true },
|
|
29
|
-
{ id: 'fish', name: 'Fish', available: true },
|
|
30
|
-
];
|
|
7
|
+
import { AgentSettingsSection } from './agent-settings-section.js';
|
|
8
|
+
import { EnvironmentSettingsSection } from './environment-settings-section.js';
|
|
9
|
+
import { WorkflowSettingsSection } from './workflow-settings-section.js';
|
|
10
|
+
import { CiSettingsSection } from './ci-settings-section.js';
|
|
11
|
+
import { StageTimeoutsSettingsSection } from './stage-timeouts-settings-section.js';
|
|
12
|
+
import { NotificationSettingsSection } from './notification-settings-section.js';
|
|
13
|
+
import { FeatureFlagsSettingsSection } from './feature-flags-settings-section.js';
|
|
14
|
+
import { InteractiveAgentSettingsSection } from './interactive-agent-settings-section.js';
|
|
15
|
+
import { FabLayoutSettingsSection } from './fab-layout-settings-section.js';
|
|
16
|
+
import { DatabaseSettingsSection } from './database-settings-section.js';
|
|
31
17
|
const SECTIONS = [
|
|
32
18
|
{ id: 'agent', labelKey: 'settings.sections.agent', icon: Bot },
|
|
33
19
|
{ id: 'environment', labelKey: 'settings.sections.environment', icon: Terminal },
|
|
@@ -40,372 +26,35 @@ const SECTIONS = [
|
|
|
40
26
|
{ id: 'fab-layout', labelKey: 'settings.sections.layout', icon: LayoutGrid },
|
|
41
27
|
{ id: 'database', labelKey: 'settings.sections.database', icon: Database },
|
|
42
28
|
];
|
|
43
|
-
|
|
44
|
-
const { t } = useTranslation('web');
|
|
45
|
-
const [isPending, startTransition] = useTransition();
|
|
46
|
-
const [showSaving, setShowSaving] = useState(false);
|
|
47
|
-
const [showSaved, setShowSaved] = useState(false);
|
|
48
|
-
const minTimerRef = useRef(null);
|
|
49
|
-
const pendingDoneRef = useRef(false);
|
|
50
|
-
// Show "Saving..." with a minimum display time of 600ms
|
|
51
|
-
useEffect(() => {
|
|
52
|
-
if (isPending && !showSaving) {
|
|
53
|
-
setShowSaving(true);
|
|
54
|
-
pendingDoneRef.current = false;
|
|
55
|
-
minTimerRef.current = setTimeout(() => {
|
|
56
|
-
minTimerRef.current = null;
|
|
57
|
-
if (pendingDoneRef.current) {
|
|
58
|
-
setShowSaving(false);
|
|
59
|
-
setShowSaved(true);
|
|
60
|
-
setTimeout(() => setShowSaved(false), 2000);
|
|
61
|
-
}
|
|
62
|
-
}, 350);
|
|
63
|
-
}
|
|
64
|
-
if (!isPending && showSaving) {
|
|
65
|
-
pendingDoneRef.current = true;
|
|
66
|
-
// If min timer already elapsed, transition now
|
|
67
|
-
if (!minTimerRef.current) {
|
|
68
|
-
setShowSaving(false);
|
|
69
|
-
setShowSaved(true);
|
|
70
|
-
setTimeout(() => setShowSaved(false), 2000);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
}, [isPending, showSaving]);
|
|
74
|
-
const save = useCallback((payload) => {
|
|
75
|
-
startTransition(async () => {
|
|
76
|
-
const result = await updateSettingsAction(payload);
|
|
77
|
-
if (!result.success) {
|
|
78
|
-
toast.error(result.error ?? t('settings.failedToSave'));
|
|
79
|
-
}
|
|
80
|
-
});
|
|
81
|
-
}, [startTransition, t]);
|
|
82
|
-
return { showSaving, showSaved, save };
|
|
83
|
-
}
|
|
84
|
-
/* ── Main component ── */
|
|
29
|
+
const TABS = [{ id: 'all', labelKey: 'settings.sections.all', icon: LayoutList }, ...SECTIONS];
|
|
85
30
|
export function SettingsPageClient({ settings, shipitAiHome, dbFileSize, availableTerminals, availableEditors, availableShells, }) {
|
|
86
31
|
const { t } = useTranslation('web');
|
|
87
|
-
const
|
|
88
|
-
const
|
|
89
|
-
|
|
90
|
-
envDeploy: false,
|
|
91
|
-
debug: false,
|
|
92
|
-
githubImport: false,
|
|
93
|
-
adoptBranch: false,
|
|
94
|
-
gitRebaseSync: false,
|
|
95
|
-
reactFileManager: false,
|
|
96
|
-
};
|
|
97
|
-
// Agent state
|
|
98
|
-
const [agentType, setAgentType] = useState(settings.agent.type);
|
|
99
|
-
// Environment state
|
|
100
|
-
const [editor, setEditor] = useState(settings.environment.defaultEditor);
|
|
101
|
-
const [shell, setShell] = useState(settings.environment.shellPreference);
|
|
102
|
-
const [terminal, setTerminal] = useState(settings.environment.terminalPreference ?? TerminalType.System);
|
|
103
|
-
const terminalOptions = availableTerminals ?? [
|
|
104
|
-
{
|
|
105
|
-
id: TerminalType.System,
|
|
106
|
-
name: t('settings.environment.systemTerminal'),
|
|
107
|
-
available: true,
|
|
108
|
-
},
|
|
109
|
-
];
|
|
110
|
-
const editorOptions = availableEditors ?? DEFAULT_EDITOR_OPTIONS;
|
|
111
|
-
const shellOptions = availableShells ?? DEFAULT_SHELL_OPTIONS;
|
|
112
|
-
// Workflow state
|
|
113
|
-
const [openPr, setOpenPr] = useState(settings.workflow.openPrOnImplementationComplete);
|
|
114
|
-
const [pushOnComplete, setPushOnComplete] = useState(settings.workflow.approvalGateDefaults.pushOnImplementationComplete);
|
|
115
|
-
const [allowPrd, setAllowPrd] = useState(settings.workflow.approvalGateDefaults.allowPrd);
|
|
116
|
-
const [allowPlan, setAllowPlan] = useState(settings.workflow.approvalGateDefaults.allowPlan);
|
|
117
|
-
const [allowMerge, setAllowMerge] = useState(settings.workflow.approvalGateDefaults.allowMerge);
|
|
118
|
-
const [enableEvidence, setEnableEvidence] = useState(settings.workflow.enableEvidence);
|
|
119
|
-
const [commitEvidence, setCommitEvidence] = useState(settings.workflow.commitEvidence);
|
|
120
|
-
const [ciWatchEnabled, setCiWatchEnabled] = useState(settings.workflow.ciWatchEnabled !== false);
|
|
121
|
-
const [defaultFastMode, setDefaultFastMode] = useState(settings.workflow.defaultFastMode !== false);
|
|
122
|
-
// Auto-archive state
|
|
123
|
-
const [autoArchiveEnabled, setAutoArchiveEnabled] = useState((settings.workflow.autoArchiveDelayMinutes ?? 10) > 0);
|
|
124
|
-
const [autoArchiveDelay, setAutoArchiveDelay] = useState(String(settings.workflow.autoArchiveDelayMinutes ?? 10));
|
|
125
|
-
// Notification state
|
|
126
|
-
const [inApp, setInApp] = useState(settings.notifications.inApp.enabled);
|
|
127
|
-
const [events, setEvents] = useState({ ...settings.notifications.events });
|
|
128
|
-
// Feature flags state
|
|
129
|
-
const [flags, setFlags] = useState({ ...featureFlags });
|
|
130
|
-
// Workflow helpers
|
|
131
|
-
function buildWorkflowPayload(overrides = {}) {
|
|
132
|
-
const archiveEnabled = overrides.autoArchiveEnabled ?? autoArchiveEnabled;
|
|
133
|
-
const archiveDelay = parseInt(overrides.autoArchiveDelay ?? autoArchiveDelay, 10);
|
|
134
|
-
return {
|
|
135
|
-
workflow: {
|
|
136
|
-
openPrOnImplementationComplete: overrides.openPr ?? openPr,
|
|
137
|
-
approvalGateDefaults: {
|
|
138
|
-
pushOnImplementationComplete: overrides.pushOnComplete ?? pushOnComplete,
|
|
139
|
-
allowPrd: overrides.allowPrd ?? allowPrd,
|
|
140
|
-
allowPlan: overrides.allowPlan ?? allowPlan,
|
|
141
|
-
allowMerge: overrides.allowMerge ?? allowMerge,
|
|
142
|
-
},
|
|
143
|
-
enableEvidence: overrides.enableEvidence ?? enableEvidence,
|
|
144
|
-
commitEvidence: overrides.commitEvidence ?? commitEvidence,
|
|
145
|
-
ciWatchEnabled: overrides.ciWatchEnabled ?? ciWatchEnabled,
|
|
146
|
-
defaultFastMode: overrides.defaultFastMode ?? defaultFastMode,
|
|
147
|
-
autoArchiveDelayMinutes: archiveEnabled
|
|
148
|
-
? Number.isNaN(archiveDelay) || archiveDelay < 1
|
|
149
|
-
? 10
|
|
150
|
-
: archiveDelay
|
|
151
|
-
: 0,
|
|
152
|
-
},
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
// Notification helpers
|
|
156
|
-
function buildNotificationPayload(overrides = {}) {
|
|
157
|
-
return {
|
|
158
|
-
notifications: {
|
|
159
|
-
inApp: { enabled: overrides.inApp ?? inApp },
|
|
160
|
-
events: overrides.events ?? events,
|
|
161
|
-
},
|
|
162
|
-
};
|
|
163
|
-
}
|
|
164
|
-
const [activeSection, setActiveSection] = useState('agent');
|
|
165
|
-
// Track which section is in view via IntersectionObserver
|
|
32
|
+
const [activeTab, setActiveTab] = useState('all');
|
|
33
|
+
const [visibleSection, setVisibleSection] = useState('agent');
|
|
34
|
+
// Track which section is in view via IntersectionObserver (only on "All" tab)
|
|
166
35
|
useEffect(() => {
|
|
36
|
+
if (activeTab !== 'all')
|
|
37
|
+
return;
|
|
167
38
|
const els = SECTIONS.map((s) => document.getElementById(`section-${s.id}`)).filter(Boolean);
|
|
168
39
|
if (els.length === 0)
|
|
169
40
|
return;
|
|
170
41
|
const observer = new IntersectionObserver((entries) => {
|
|
171
42
|
for (const entry of entries) {
|
|
172
43
|
if (entry.isIntersecting) {
|
|
173
|
-
|
|
44
|
+
setVisibleSection(entry.target.id.replace('section-', ''));
|
|
174
45
|
}
|
|
175
46
|
}
|
|
176
47
|
}, { rootMargin: '-65px 0px -60% 0px', threshold: 0 });
|
|
177
48
|
for (const el of els)
|
|
178
49
|
observer.observe(el);
|
|
179
50
|
return () => observer.disconnect();
|
|
180
|
-
}, []);
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
// Flash highlight
|
|
187
|
-
el.style.animation = 'none';
|
|
188
|
-
// Force reflow
|
|
189
|
-
void el.offsetHeight;
|
|
190
|
-
el.style.animation = 'section-flash 1s ease-out';
|
|
191
|
-
}, []);
|
|
192
|
-
return (_jsxs("div", { "data-testid": "settings-page-client", className: "max-w-5xl px-8 pt-8", children: [_jsxs("div", { className: "bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 pb-4 backdrop-blur", children: [_jsxs("div", { className: "mb-4 space-y-1.5", children: [_jsx("span", { className: "text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase", children: "Developer Portal" }), _jsxs("div", { className: "flex items-baseline gap-3", children: [_jsx("h1", { className: "text-foreground text-3xl font-black tracking-tight", children: t('settings.title') }), _jsxs("span", { className: "relative h-4 w-16", children: [_jsx("span", { className: cn('text-muted-foreground absolute inset-0 flex items-center text-xs transition-opacity duration-300', showSaving ? 'opacity-100' : 'opacity-0'), children: t('settings.saving') }), _jsxs("span", { className: cn('absolute inset-0 flex items-center gap-1 text-xs text-green-600 transition-opacity duration-300', showSaved && !showSaving ? 'opacity-100' : 'opacity-0'), children: [_jsx(Check, { className: "h-3 w-3" }), t('settings.saved')] })] })] })] }), _jsx("nav", { className: "bg-card editorial-shadow flex flex-wrap items-center gap-0.5 rounded-lg p-1", children: SECTIONS.map((s) => {
|
|
193
|
-
const SectionIcon = s.icon;
|
|
194
|
-
const isActive = activeSection === s.id;
|
|
195
|
-
return (_jsxs("button", { type: "button", onClick: () => scrollToSection(s.id), className: cn('flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-bold transition-all', isActive
|
|
51
|
+
}, [activeTab]);
|
|
52
|
+
return (_jsxs("div", { "data-testid": "settings-page-client", className: "max-w-5xl px-8 pt-8", children: [_jsxs("div", { className: "bg-background/95 supports-backdrop-filter:bg-background/80 sticky top-0 z-10 pb-4 backdrop-blur", children: [_jsxs("div", { className: "mb-4 space-y-1.5", children: [_jsx("span", { className: "text-[10px] font-bold tracking-[0.2em] text-slate-400 uppercase", children: "Developer Portal" }), _jsx("div", { className: "flex items-baseline gap-3", children: _jsx("h1", { className: "text-foreground text-3xl font-black tracking-tight", children: t('settings.title') }) })] }), _jsx("nav", { className: "bg-card editorial-shadow flex flex-wrap items-center gap-0.5 rounded-lg p-1", children: TABS.map((tab) => {
|
|
53
|
+
const TabIcon = tab.icon;
|
|
54
|
+
const isActive = activeTab === tab.id ||
|
|
55
|
+
(activeTab === 'all' && tab.id !== 'all' && visibleSection === tab.id);
|
|
56
|
+
return (_jsxs("button", { type: "button", onClick: () => setActiveTab(tab.id), className: cn('flex cursor-pointer items-center gap-1 rounded-md px-2 py-1.5 text-[11px] font-bold transition-all', isActive
|
|
196
57
|
? 'bg-muted text-primary shadow-sm ring-1 ring-slate-200/70 dark:ring-slate-700/50'
|
|
197
|
-
: 'text-muted-foreground hover:text-foreground hover:bg-accent/50'), children: [_jsx(
|
|
198
|
-
}) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [
|
|
199
|
-
{
|
|
200
|
-
label: t('settings.agent.links.agentSystem'),
|
|
201
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/agent-system.md',
|
|
202
|
-
},
|
|
203
|
-
{
|
|
204
|
-
label: t('settings.agent.links.addingAgents'),
|
|
205
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/adding-agents.md',
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
label: t('settings.agent.links.configurationGuide'),
|
|
209
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',
|
|
210
|
-
},
|
|
211
|
-
], children: t('settings.agent.hint') })] }), _jsxs("div", { id: "section-environment", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Terminal, title: t('settings.environment.sectionTitle'), description: t('settings.environment.sectionDescription'), testId: "environment-settings-section", children: [_jsx(SettingsRow, { label: t('settings.environment.defaultEditor'), description: t('settings.environment.defaultEditorDescription'), tooltip: "The editor that opens when you click 'Launch' on a tool card or when ShipIT needs to open a file for review.", htmlFor: "default-editor", children: _jsxs(Select, { value: editor, onValueChange: (v) => {
|
|
212
|
-
setEditor(v);
|
|
213
|
-
save({
|
|
214
|
-
environment: {
|
|
215
|
-
defaultEditor: v,
|
|
216
|
-
shellPreference: shell,
|
|
217
|
-
terminalPreference: terminal,
|
|
218
|
-
},
|
|
219
|
-
});
|
|
220
|
-
}, children: [_jsx(SelectTrigger, { id: "default-editor", "data-testid": "editor-select", className: "w-64 cursor-pointer text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: editorOptions.map((opt) => {
|
|
221
|
-
const Icon = getEditorTypeIcon(opt.id);
|
|
222
|
-
return (_jsx(SelectItem, { value: opt.id, disabled: !opt.available, children: _jsxs("span", { className: "flex items-center gap-2 text-xs", children: [_jsx(Icon, { className: "h-4 w-4 shrink-0" }), opt.name, _jsx(Badge, { variant: "outline", className: cn('ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal', opt.available
|
|
223
|
-
? 'border-emerald-500/30 text-emerald-500'
|
|
224
|
-
: 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id));
|
|
225
|
-
}) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.shell'), description: t('settings.environment.shellDescription'), tooltip: "Controls which shell runs generated scripts like install commands and git operations. Match this to your daily driver shell.", htmlFor: "shell-preference", children: _jsxs(Select, { value: shell, onValueChange: (v) => {
|
|
226
|
-
setShell(v);
|
|
227
|
-
save({
|
|
228
|
-
environment: {
|
|
229
|
-
defaultEditor: editor,
|
|
230
|
-
shellPreference: v,
|
|
231
|
-
terminalPreference: terminal,
|
|
232
|
-
},
|
|
233
|
-
});
|
|
234
|
-
}, children: [_jsx(SelectTrigger, { id: "shell-preference", "data-testid": "shell-select", className: "w-64 cursor-pointer text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: shellOptions.map((opt) => (_jsx(SelectItem, { value: opt.id, disabled: !opt.available, children: _jsxs("span", { className: "flex items-center gap-2 text-xs", children: [opt.name, _jsx(Badge, { variant: "outline", className: cn('ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal', opt.available
|
|
235
|
-
? 'border-emerald-500/30 text-emerald-500'
|
|
236
|
-
: 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id))) })] }) }), _jsx(SettingsRow, { label: t('settings.environment.terminal'), description: t('settings.environment.terminalDescription'), tooltip: "The terminal emulator launched when opening shell sessions from the web UI. Only affects web-launched terminals, not CLI usage.", htmlFor: "terminal-preference", children: _jsxs(Select, { value: terminal, onValueChange: (v) => {
|
|
237
|
-
setTerminal(v);
|
|
238
|
-
save({
|
|
239
|
-
environment: {
|
|
240
|
-
defaultEditor: editor,
|
|
241
|
-
shellPreference: shell,
|
|
242
|
-
terminalPreference: v,
|
|
243
|
-
},
|
|
244
|
-
});
|
|
245
|
-
}, children: [_jsx(SelectTrigger, { id: "terminal-preference", "data-testid": "terminal-select", className: "w-64 cursor-pointer text-xs", children: _jsx(SelectValue, {}) }), _jsx(SelectContent, { children: terminalOptions.map((opt) => (_jsx(SelectItem, { value: opt.id, disabled: !opt.available, children: _jsxs("span", { className: "flex items-center gap-2 text-xs", children: [opt.name, _jsx(Badge, { variant: "outline", className: cn('ml-auto px-1.5 py-0 text-[10px] leading-4 font-normal', opt.available
|
|
246
|
-
? 'border-emerald-500/30 text-emerald-500'
|
|
247
|
-
: 'border-muted-foreground/30 text-muted-foreground'), children: opt.available ? 'Installed' : 'Not Installed' })] }) }, opt.id))) })] }) })] }), _jsx(SectionHint, { links: [
|
|
248
|
-
{
|
|
249
|
-
label: t('settings.environment.links.configurationGuide'),
|
|
250
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/guides/configuration.md',
|
|
251
|
-
},
|
|
252
|
-
], children: t('settings.environment.hint') })] }), _jsxs("div", { id: "section-workflow", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: GitBranch, title: t('settings.workflow.title'), description: t('settings.workflow.sectionDescription'), testId: "workflow-settings-section", children: [_jsx(SwitchRow, { label: t('settings.workflow.defaultFastMode'), description: t('settings.workflow.defaultFastModeDescription'), tooltip: "When enabled, new features skip the PRD and Plan phases and go straight to implementation. Useful for quick fixes, risky for complex features.", id: "default-fast-mode", testId: "switch-default-fast-mode", checked: defaultFastMode, onChange: (v) => {
|
|
253
|
-
setDefaultFastMode(v);
|
|
254
|
-
save(buildWorkflowPayload({ defaultFastMode: v }));
|
|
255
|
-
} }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.approve') }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePrd'), description: t('settings.workflow.autoApprovePrdDescription'), tooltip: "Automatically approves the requirements document without pausing for your review. Saves time but you lose the chance to refine requirements before planning.", id: "allow-prd", testId: "switch-allow-prd", checked: allowPrd, onChange: (v) => {
|
|
256
|
-
setAllowPrd(v);
|
|
257
|
-
save(buildWorkflowPayload({ allowPrd: v }));
|
|
258
|
-
} }), _jsx(SwitchRow, { label: t('settings.workflow.autoApprovePlan'), description: t('settings.workflow.autoApprovePlanDescription'), tooltip: "Automatically approves the implementation plan. The agent proceeds to coding without waiting for your plan review.", id: "allow-plan", testId: "switch-allow-plan", checked: allowPlan, onChange: (v) => {
|
|
259
|
-
setAllowPlan(v);
|
|
260
|
-
save(buildWorkflowPayload({ allowPlan: v }));
|
|
261
|
-
} }), _jsx(SwitchRow, { label: t('settings.workflow.autoApproveMerge'), description: t('settings.workflow.autoApproveMergeDescription'), tooltip: "Automatically merges the PR after implementation without requiring your final review. Use with caution on production branches.", id: "allow-merge", testId: "switch-allow-merge", checked: allowMerge, onChange: (v) => {
|
|
262
|
-
setAllowMerge(v);
|
|
263
|
-
save(buildWorkflowPayload({ allowMerge: v }));
|
|
264
|
-
} }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.evidence') }), _jsx(SwitchRow, { label: t('settings.workflow.collectEvidence'), description: t('settings.workflow.collectEvidenceDescription'), tooltip: "Captures screenshots and test outputs during implementation as proof of work. Useful for audit trails and PR documentation.", id: "enable-evidence", testId: "switch-enable-evidence", checked: enableEvidence, onChange: (v) => {
|
|
265
|
-
setEnableEvidence(v);
|
|
266
|
-
if (!v) {
|
|
267
|
-
setCommitEvidence(false);
|
|
268
|
-
save(buildWorkflowPayload({ enableEvidence: v, commitEvidence: false }));
|
|
269
|
-
}
|
|
270
|
-
else {
|
|
271
|
-
save(buildWorkflowPayload({ enableEvidence: v }));
|
|
272
|
-
}
|
|
273
|
-
} }), _jsx(SwitchRow, { label: t('settings.workflow.addEvidenceToPr'), description: t('settings.workflow.addEvidenceToPrDescription'), tooltip: "Attaches collected evidence artifacts (screenshots, logs) directly to the pull request description.", id: "commit-evidence", testId: "switch-commit-evidence", checked: commitEvidence, disabled: !enableEvidence || !openPr, onChange: (v) => {
|
|
274
|
-
setCommitEvidence(v);
|
|
275
|
-
save(buildWorkflowPayload({ commitEvidence: v }));
|
|
276
|
-
} }), _jsx(SubsectionLabel, { children: t('settings.workflow.subsections.git') }), _jsx(SwitchRow, { label: t('settings.workflow.pushOnComplete'), description: t('settings.workflow.pushOnCompleteDescription'), tooltip: "Automatically pushes the implementation branch to the remote repository when the agent finishes coding.", id: "push-on-complete", testId: "switch-push-on-complete", checked: pushOnComplete, onChange: (v) => {
|
|
277
|
-
setPushOnComplete(v);
|
|
278
|
-
save(buildWorkflowPayload({ pushOnComplete: v }));
|
|
279
|
-
} }), _jsx(SwitchRow, { label: t('settings.workflow.openPrOnComplete'), description: t('settings.workflow.openPrOnCompleteDescription'), tooltip: "Creates a pull request automatically after pushing. Combined with push-on-complete, this fully automates the delivery pipeline.", id: "open-pr", testId: "switch-open-pr", checked: openPr, onChange: (v) => {
|
|
280
|
-
setOpenPr(v);
|
|
281
|
-
if (!v) {
|
|
282
|
-
setCommitEvidence(false);
|
|
283
|
-
save(buildWorkflowPayload({ openPr: v, commitEvidence: false }));
|
|
284
|
-
}
|
|
285
|
-
else {
|
|
286
|
-
save(buildWorkflowPayload({ openPr: v }));
|
|
287
|
-
}
|
|
288
|
-
} }), _jsx(SwitchRow, { label: t('settings.workflow.watchCiAfterPush'), description: t('settings.workflow.watchCiAfterPushDescription'), tooltip: "Monitors CI/CD pipeline status after pushing and can attempt fixes if tests fail. Disable if you prefer to handle CI failures manually.", id: "ci-watch-enabled", testId: "switch-ci-watch-enabled", checked: ciWatchEnabled, onChange: (v) => {
|
|
289
|
-
setCiWatchEnabled(v);
|
|
290
|
-
save(buildWorkflowPayload({ ciWatchEnabled: v }));
|
|
291
|
-
} }), _jsx(SubsectionLabel, { children: "Archive" }), _jsx(SwitchRow, { label: "Auto-archive completed", description: "Automatically archive features after they reach the completed state", tooltip: "Automatically archives features from the control center canvas after they reach the completed state, keeping the board clean.", id: "auto-archive-enabled", testId: "switch-auto-archive-enabled", checked: autoArchiveEnabled, onChange: (v) => {
|
|
292
|
-
setAutoArchiveEnabled(v);
|
|
293
|
-
save(buildWorkflowPayload({ autoArchiveEnabled: v }));
|
|
294
|
-
} }), _jsx(SettingsRow, { label: "Archive delay", description: "Minutes to wait after completion before archiving (1\u20131440)", tooltip: "How long to wait after a feature completes before archiving it. Gives you time to review results before the feature moves off the board.", htmlFor: "auto-archive-delay", children: _jsx(NumberStepper, { id: "auto-archive-delay", testId: "input-auto-archive-delay", value: autoArchiveDelay, placeholder: "10", min: 1, max: 1440, suffix: "min", onChange: (v) => {
|
|
295
|
-
setAutoArchiveDelay(v);
|
|
296
|
-
}, onBlur: () => {
|
|
297
|
-
if (!autoArchiveEnabled)
|
|
298
|
-
return;
|
|
299
|
-
const n = parseInt(autoArchiveDelay, 10);
|
|
300
|
-
const clamped = Number.isNaN(n) ? 10 : Math.min(1440, Math.max(1, n));
|
|
301
|
-
setAutoArchiveDelay(String(clamped));
|
|
302
|
-
save(buildWorkflowPayload({ autoArchiveDelay: String(clamped) }));
|
|
303
|
-
} }) })] }), _jsx(SectionHint, { links: [
|
|
304
|
-
{
|
|
305
|
-
label: t('settings.workflow.links.approvalGates'),
|
|
306
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/specs/016-hitl-approval-gates/spec.yaml',
|
|
307
|
-
},
|
|
308
|
-
{
|
|
309
|
-
label: t('settings.workflow.links.pushAndPrFlags'),
|
|
310
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/specs/037-feature-pr-push-flags/spec.yaml',
|
|
311
|
-
},
|
|
312
|
-
], children: t('settings.workflow.hint') })] }), _jsxs("div", { id: "section-ci", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(CiSettingsSection, { settings: settings }), _jsx(SectionHint, { links: [
|
|
313
|
-
{
|
|
314
|
-
label: t('settings.ci.links.cicdPipeline'),
|
|
315
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/development/cicd.md',
|
|
316
|
-
},
|
|
317
|
-
{
|
|
318
|
-
label: t('settings.ci.links.ciSecurityGates'),
|
|
319
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/specs/003-cicd-security-gates/spec.md',
|
|
320
|
-
},
|
|
321
|
-
], children: t('settings.ci.hint') })] }), _jsxs("div", { id: "section-stage-timeouts", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(StageTimeoutsSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.stageTimeouts.hint') })] }), _jsxs("div", { id: "section-notifications", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Bell, title: t('settings.notifications.title'), description: t('settings.notifications.sectionDescription'), testId: "notification-settings-section", children: [_jsx(SubsectionLabel, { children: t('settings.notifications.channels') }), _jsx(SwitchRow, { label: t('settings.notifications.inAppLabel'), description: t('settings.notifications.inAppDescription'), tooltip: "Master toggle for in-app toast notifications. When disabled, no event toasts will appear regardless of individual event settings below.", id: "notif-in-app", testId: "switch-in-app", checked: inApp, onChange: (v) => {
|
|
322
|
-
setInApp(v);
|
|
323
|
-
save(buildNotificationPayload({ inApp: v }));
|
|
324
|
-
} }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.agentEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentStarted'), tooltip: "Controls whether you receive an in-app toast notification when an agent begins working on a feature.", id: "notif-event-agentStarted", testId: "switch-event-agentStarted", checked: events.agentStarted, onChange: (v) => {
|
|
325
|
-
const newEvents = { ...events, agentStarted: v };
|
|
326
|
-
setEvents(newEvents);
|
|
327
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
328
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.phaseCompleted'), tooltip: "Controls whether you receive an in-app toast notification when an agent completes a workflow phase (e.g., requirements, planning, implementation).", id: "notif-event-phaseCompleted", testId: "switch-event-phaseCompleted", checked: events.phaseCompleted, onChange: (v) => {
|
|
329
|
-
const newEvents = { ...events, phaseCompleted: v };
|
|
330
|
-
setEvents(newEvents);
|
|
331
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
332
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.waitingApproval'), tooltip: "Controls whether you receive an in-app toast notification when a feature is paused and waiting for your approval to continue.", id: "notif-event-waitingApproval", testId: "switch-event-waitingApproval", checked: events.waitingApproval, onChange: (v) => {
|
|
333
|
-
const newEvents = { ...events, waitingApproval: v };
|
|
334
|
-
setEvents(newEvents);
|
|
335
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
336
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentCompleted'), tooltip: "Controls whether you receive an in-app toast notification when an agent finishes all work on a feature successfully.", id: "notif-event-agentCompleted", testId: "switch-event-agentCompleted", checked: events.agentCompleted, onChange: (v) => {
|
|
337
|
-
const newEvents = { ...events, agentCompleted: v };
|
|
338
|
-
setEvents(newEvents);
|
|
339
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
340
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.agentFailed'), tooltip: "Controls whether you receive an in-app toast notification when an agent encounters an error and stops working on a feature.", id: "notif-event-agentFailed", testId: "switch-event-agentFailed", checked: events.agentFailed, onChange: (v) => {
|
|
341
|
-
const newEvents = { ...events, agentFailed: v };
|
|
342
|
-
setEvents(newEvents);
|
|
343
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
344
|
-
} }), _jsx(SubsectionLabel, { children: t('settings.notifications.subsections.pullRequestEvents') }), _jsx(SwitchRow, { label: t('settings.notifications.events.prMerged'), tooltip: "Controls whether you receive an in-app toast notification when a feature's pull request is merged into the target branch.", id: "notif-event-prMerged", testId: "switch-event-prMerged", checked: events.prMerged, onChange: (v) => {
|
|
345
|
-
const newEvents = { ...events, prMerged: v };
|
|
346
|
-
setEvents(newEvents);
|
|
347
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
348
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.prClosed'), tooltip: "Controls whether you receive an in-app toast notification when a feature's pull request is closed without merging.", id: "notif-event-prClosed", testId: "switch-event-prClosed", checked: events.prClosed, onChange: (v) => {
|
|
349
|
-
const newEvents = { ...events, prClosed: v };
|
|
350
|
-
setEvents(newEvents);
|
|
351
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
352
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksPassed'), tooltip: "Controls whether you receive an in-app toast notification when all CI checks pass on a feature's pull request.", id: "notif-event-prChecksPassed", testId: "switch-event-prChecksPassed", checked: events.prChecksPassed, onChange: (v) => {
|
|
353
|
-
const newEvents = { ...events, prChecksPassed: v };
|
|
354
|
-
setEvents(newEvents);
|
|
355
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
356
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.prChecksFailed'), tooltip: "Controls whether you receive an in-app toast notification when CI checks fail on a feature's pull request.", id: "notif-event-prChecksFailed", testId: "switch-event-prChecksFailed", checked: events.prChecksFailed, onChange: (v) => {
|
|
357
|
-
const newEvents = { ...events, prChecksFailed: v };
|
|
358
|
-
setEvents(newEvents);
|
|
359
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
360
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.prBlocked'), tooltip: "Controls whether you receive an in-app toast notification when a pull request is blocked by merge conflicts or branch protection rules.", id: "notif-event-prBlocked", testId: "switch-event-prBlocked", checked: events.prBlocked, onChange: (v) => {
|
|
361
|
-
const newEvents = { ...events, prBlocked: v };
|
|
362
|
-
setEvents(newEvents);
|
|
363
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
364
|
-
} }), _jsx(SwitchRow, { label: t('settings.notifications.events.mergeReviewReady'), tooltip: "Controls whether you receive an in-app toast notification when a feature's PR passes all checks and is ready for your merge review.", id: "notif-event-mergeReviewReady", testId: "switch-event-mergeReviewReady", checked: events.mergeReviewReady, onChange: (v) => {
|
|
365
|
-
const newEvents = { ...events, mergeReviewReady: v };
|
|
366
|
-
setEvents(newEvents);
|
|
367
|
-
save(buildNotificationPayload({ events: newEvents }));
|
|
368
|
-
} })] }), _jsx(SectionHint, { links: [
|
|
369
|
-
{
|
|
370
|
-
label: t('settings.notifications.links.notificationSystem'),
|
|
371
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/specs/021-agent-notifications/spec.yaml',
|
|
372
|
-
},
|
|
373
|
-
], children: t('settings.notifications.hint') })] }), _jsxs("div", { id: "section-feature-flags", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Flag, title: t('settings.featureFlags.title'), description: t('settings.featureFlags.sectionDescription'), badge: t('settings.featureFlags.badge'), testId: "feature-flags-settings-section", children: [_jsx(SwitchRow, { label: t('settings.featureFlags.skills'), description: t('settings.featureFlags.skillsDescription'), tooltip: "Enables the Skills page in the sidebar for browsing and managing Claude Code skills.", id: "flag-skills", testId: "switch-flag-skills", checked: flags.skills, onChange: (v) => {
|
|
374
|
-
const newFlags = { ...flags, skills: v };
|
|
375
|
-
setFlags(newFlags);
|
|
376
|
-
save({ featureFlags: newFlags });
|
|
377
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.deployments'), description: t('settings.featureFlags.deploymentsDescription'), tooltip: "Enables experimental deployment features for environment management.", id: "flag-envDeploy", testId: "switch-flag-envDeploy", checked: flags.envDeploy, onChange: (v) => {
|
|
378
|
-
const newFlags = { ...flags, envDeploy: v };
|
|
379
|
-
setFlags(newFlags);
|
|
380
|
-
save({ featureFlags: newFlags });
|
|
381
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.debug'), description: t('settings.featureFlags.debugDescription'), tooltip: "Shows additional debugging information in the UI for troubleshooting.", id: "flag-debug", testId: "switch-flag-debug", checked: flags.debug, onChange: (v) => {
|
|
382
|
-
const newFlags = { ...flags, debug: v };
|
|
383
|
-
setFlags(newFlags);
|
|
384
|
-
save({ featureFlags: newFlags });
|
|
385
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.githubImport'), description: t('settings.featureFlags.githubImportDescription'), tooltip: "Enables importing repositories directly from GitHub.", id: "flag-githubImport", testId: "switch-flag-githubImport", checked: flags.githubImport, onChange: (v) => {
|
|
386
|
-
const newFlags = { ...flags, githubImport: v };
|
|
387
|
-
setFlags(newFlags);
|
|
388
|
-
save({ featureFlags: newFlags });
|
|
389
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.adoptBranch'), description: t('settings.featureFlags.adoptBranchDescription'), tooltip: "Enables adopting existing git branches as ShipIT features.", id: "flag-adoptBranch", testId: "switch-flag-adoptBranch", checked: flags.adoptBranch, onChange: (v) => {
|
|
390
|
-
const newFlags = { ...flags, adoptBranch: v };
|
|
391
|
-
setFlags(newFlags);
|
|
392
|
-
save({ featureFlags: newFlags });
|
|
393
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.gitRebaseSync'), description: t('settings.featureFlags.gitRebaseSyncDescription'), tooltip: "Uses git rebase instead of merge when syncing feature branches with the upstream branch.", id: "flag-gitRebaseSync", testId: "switch-flag-gitRebaseSync", checked: flags.gitRebaseSync, onChange: (v) => {
|
|
394
|
-
const newFlags = { ...flags, gitRebaseSync: v };
|
|
395
|
-
setFlags(newFlags);
|
|
396
|
-
save({ featureFlags: newFlags });
|
|
397
|
-
} }), _jsx(SwitchRow, { label: t('settings.featureFlags.reactFileManager'), description: t('settings.featureFlags.reactFileManagerDescription'), tooltip: "Replaces the native file picker dialog with a React-based file browser for selecting project folders.", id: "flag-reactFileManager", testId: "switch-flag-reactFileManager", checked: flags.reactFileManager, onChange: (v) => {
|
|
398
|
-
const newFlags = { ...flags, reactFileManager: v };
|
|
399
|
-
setFlags(newFlags);
|
|
400
|
-
save({ featureFlags: newFlags });
|
|
401
|
-
} })] }), _jsx(SectionHint, { children: t('settings.featureFlags.hint') })] }), _jsxs("div", { id: "section-interactive-agent", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(InteractiveAgentSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.interactiveAgent.hint') })] }), _jsxs("div", { id: "section-fab-layout", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsx(FabLayoutSettingsSection, { settings: settings }), _jsx(SectionHint, { children: t('settings.fabLayout.hint') })] }), _jsxs("div", { id: "section-database", className: "grid scroll-mt-18 grid-cols-1 gap-x-5 rounded-lg lg:grid-cols-[1fr_280px]", children: [_jsxs(SettingsSection, { icon: Database, title: t('settings.database.title'), description: t('settings.database.sectionDescription'), testId: "database-settings-section", children: [_jsx(SettingsRow, { label: t('settings.database.location'), description: t('settings.database.locationDescription'), tooltip: "The directory where ShipIT stores its SQLite database, logs, and configuration files. Change this via the SHIPIT_AI_HOME environment variable.", children: _jsx("span", { className: "text-muted-foreground max-w-50 truncate font-mono text-xs", "data-testid": "shipit-ai-home-path", children: shipitAiHome }) }), _jsx(SettingsRow, { label: t('settings.database.size'), tooltip: "Current size of the SQLite database file on disk. Large databases may slow down startup; consider archiving old features if this grows significantly.", children: _jsx("span", { className: "text-muted-foreground text-xs", "data-testid": "db-file-size", children: dbFileSize }) })] }), _jsx(SectionHint, { links: [
|
|
402
|
-
{
|
|
403
|
-
label: t('settings.database.links.settingsService'),
|
|
404
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/docs/architecture/settings-service.md',
|
|
405
|
-
},
|
|
406
|
-
{
|
|
407
|
-
label: t('settings.database.links.settingsSpec'),
|
|
408
|
-
href: 'https://github.com/jrmatherly/shipit/blob/main/specs/005-global-settings-service/spec.md',
|
|
409
|
-
},
|
|
410
|
-
], children: t('settings.database.hint') })] })] })] }));
|
|
58
|
+
: 'text-muted-foreground hover:text-foreground hover:bg-accent/50'), children: [_jsx(TabIcon, { className: "h-3 w-3" }), _jsx("span", { className: "hidden sm:inline", children: t(tab.labelKey) })] }, tab.id));
|
|
59
|
+
}) })] }), _jsxs("div", { className: "flex flex-col gap-3", children: [(activeTab === 'all' || activeTab === 'agent') && (_jsx("div", { id: "section-agent", className: "scroll-mt-18 rounded-lg", children: _jsx(AgentSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'environment') && (_jsx("div", { id: "section-environment", className: "scroll-mt-18 rounded-lg", children: _jsx(EnvironmentSettingsSection, { settings: settings, availableEditors: availableEditors, availableShells: availableShells, availableTerminals: availableTerminals }) })), (activeTab === 'all' || activeTab === 'workflow') && (_jsx("div", { id: "section-workflow", className: "scroll-mt-18 rounded-lg", children: _jsx(WorkflowSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'ci') && (_jsx("div", { id: "section-ci", className: "scroll-mt-18 rounded-lg", children: _jsx(CiSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'stage-timeouts') && (_jsx("div", { id: "section-stage-timeouts", className: "scroll-mt-18 rounded-lg", children: _jsx(StageTimeoutsSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'notifications') && (_jsx("div", { id: "section-notifications", className: "scroll-mt-18 rounded-lg", children: _jsx(NotificationSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'feature-flags') && (_jsx("div", { id: "section-feature-flags", className: "scroll-mt-18 rounded-lg", children: _jsx(FeatureFlagsSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'interactive-agent') && (_jsx("div", { id: "section-interactive-agent", className: "scroll-mt-18 rounded-lg", children: _jsx(InteractiveAgentSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'fab-layout') && (_jsx("div", { id: "section-fab-layout", className: "scroll-mt-18 rounded-lg", children: _jsx(FabLayoutSettingsSection, { settings: settings }) })), (activeTab === 'all' || activeTab === 'database') && (_jsx("div", { id: "section-database", className: "scroll-mt-18 rounded-lg", children: _jsx(DatabaseSettingsSection, { shipitAiHome: shipitAiHome, dbFileSize: dbFileSize }) }))] })] }));
|
|
411
60
|
}
|
package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts
CHANGED
|
@@ -14,4 +14,6 @@ export declare const Default: Story;
|
|
|
14
14
|
export declare const AllSections: Story;
|
|
15
15
|
export declare const EvidenceEnabled: Story;
|
|
16
16
|
export declare const CustomTimeouts: Story;
|
|
17
|
+
/** Shows the settings page with only the Workflow tab active (simulated via play function). */
|
|
18
|
+
export declare const SingleTabView: Story;
|
|
17
19
|
//# sourceMappingURL=settings-page-client.stories.d.ts.map
|
package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-page-client.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-page-client.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAM5D,QAAA,MAAM,IAAI;;;;;;;CAOiC,CAAC;AAE5C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAqBzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAa7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAsB5B,CAAC"}
|
|
1
|
+
{"version":3,"file":"settings-page-client.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-page-client.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAM5D,QAAA,MAAM,IAAI;;;;;;;CAOiC,CAAC;AAE5C,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,KAqBzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAa7B,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAsB5B,CAAC;AAEF,+FAA+F;AAC/F,eAAO,MAAM,aAAa,EAAE,KAW3B,CAAC"}
|
package/dist/src/presentation/web/components/features/settings/settings-page-client.stories.js
CHANGED
|
@@ -77,3 +77,16 @@ export const CustomTimeouts = {
|
|
|
77
77
|
dbFileSize: '2.4 MB',
|
|
78
78
|
},
|
|
79
79
|
};
|
|
80
|
+
/** Shows the settings page with only the Workflow tab active (simulated via play function). */
|
|
81
|
+
export const SingleTabView = {
|
|
82
|
+
args: {
|
|
83
|
+
settings: defaultSettings,
|
|
84
|
+
shipitAiHome: '/home/user/.shipit-ai',
|
|
85
|
+
dbFileSize: '2.4 MB',
|
|
86
|
+
},
|
|
87
|
+
play: async ({ canvasElement }) => {
|
|
88
|
+
const tabs = canvasElement.querySelectorAll('nav button');
|
|
89
|
+
const wfTab = Array.from(tabs).find((btn) => btn.textContent?.includes('Workflow'));
|
|
90
|
+
wfTab?.click();
|
|
91
|
+
},
|
|
92
|
+
};
|
|
@@ -16,7 +16,7 @@ export declare function SwitchRow({ label, description, id, testId, checked, onC
|
|
|
16
16
|
disabled?: boolean;
|
|
17
17
|
tooltip?: string;
|
|
18
18
|
}): import("react/jsx-runtime").JSX.Element;
|
|
19
|
-
export declare function SettingsSection({ icon: Icon, title, description, badge, testId, children, }: {
|
|
19
|
+
export declare function SettingsSection({ icon: Icon, title, description, badge, testId, tooltip, tooltipLinks, children, }: {
|
|
20
20
|
icon: React.ComponentType<{
|
|
21
21
|
className?: string;
|
|
22
22
|
}>;
|
|
@@ -24,6 +24,13 @@ export declare function SettingsSection({ icon: Icon, title, description, badge,
|
|
|
24
24
|
description: string;
|
|
25
25
|
badge?: string;
|
|
26
26
|
testId: string;
|
|
27
|
+
/** Section-level tooltip describing the purpose of this settings group. */
|
|
28
|
+
tooltip?: string;
|
|
29
|
+
/** Documentation links rendered below the tooltip text. */
|
|
30
|
+
tooltipLinks?: {
|
|
31
|
+
label: string;
|
|
32
|
+
href: string;
|
|
33
|
+
}[];
|
|
27
34
|
children: React.ReactNode;
|
|
28
35
|
}): import("react/jsx-runtime").JSX.Element;
|
|
29
36
|
export declare function NumberStepper({ id, testId, value, onChange, onBlur, placeholder, min, max, step, suffix, }: {
|
|
@@ -41,11 +48,4 @@ export declare function NumberStepper({ id, testId, value, onChange, onBlur, pla
|
|
|
41
48
|
export declare function SubsectionLabel({ children }: {
|
|
42
49
|
children: React.ReactNode;
|
|
43
50
|
}): import("react/jsx-runtime").JSX.Element;
|
|
44
|
-
export declare function SectionHint({ children, links, }: {
|
|
45
|
-
children: React.ReactNode;
|
|
46
|
-
links?: {
|
|
47
|
-
label: string;
|
|
48
|
-
href: string;
|
|
49
|
-
}[];
|
|
50
|
-
}): import("react/jsx-runtime").JSX.Element;
|
|
51
51
|
//# sourceMappingURL=settings-section-utils.d.ts.map
|
package/dist/src/presentation/web/components/features/settings/settings-section-utils.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-section-utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx"],"names":[],"mappings":"AAWA,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CA6BA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,WAAW,EACX,EAAE,EACF,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,2CAaA;AAID,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,
|
|
1
|
+
{"version":3,"file":"settings-section-utils.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.tsx"],"names":[],"mappings":"AAWA,wBAAgB,WAAW,CAAC,EAC1B,KAAK,EACL,WAAW,EACX,OAAO,EACP,OAAO,EACP,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CA6BA;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAK,EACL,WAAW,EACX,EAAE,EACF,MAAM,EACN,OAAO,EACP,QAAQ,EACR,QAAQ,EACR,OAAO,GACR,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB,2CAaA;AAID,wBAAgB,eAAe,CAAC,EAC9B,IAAI,EAAE,IAAI,EACV,KAAK,EACL,WAAW,EACX,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAY,EACZ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,2EAA2E;IAC3E,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2DAA2D;IAC3D,YAAY,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;CAC3B,2CA4CA;AAED,wBAAgB,aAAa,CAAC,EAC5B,EAAE,EACF,MAAM,EACN,KAAK,EACL,QAAQ,EACR,MAAM,EACN,WAAW,EACX,GAAO,EACP,GAAG,EACH,IAAQ,EACR,MAAM,GACP,EAAE;IACD,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,2CA4DA;AAED,wBAAgB,eAAe,CAAC,EAAE,QAAQ,EAAE,EAAE;IAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,2CAQ1E"}
|
|
@@ -10,14 +10,14 @@ import { Tooltip, TooltipContent, TooltipTrigger } from '../../ui/tooltip.js';
|
|
|
10
10
|
export function SettingsRow({ label, description, htmlFor, tooltip, children, }) {
|
|
11
11
|
// Show the Info icon when there's either an explicit tooltip or a description to surface
|
|
12
12
|
const tooltipText = tooltip ?? description;
|
|
13
|
-
return (_jsxs("div", { className: "flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Label, { htmlFor: htmlFor, className: "cursor-pointer text-sm font-normal whitespace-nowrap", children: label }), tooltipText ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Info, { className: "text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors" }) }), _jsx(TooltipContent, { side: "top", className: "max-w-
|
|
13
|
+
return (_jsxs("div", { className: "flex items-center justify-between gap-4 border-b py-2.5 last:border-b-0", children: [_jsxs("div", { className: "min-w-0", children: [_jsxs("span", { className: "flex items-center gap-1.5", children: [_jsx(Label, { htmlFor: htmlFor, className: "cursor-pointer text-sm font-normal whitespace-nowrap", children: label }), tooltipText ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Info, { className: "text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors" }) }), _jsx(TooltipContent, { side: "top", className: "max-w-64 text-[11px] leading-relaxed", children: _jsx("span", { className: "text-muted-foreground", children: tooltipText }) })] })) : null] }), description ? (_jsx("p", { className: "text-muted-foreground text-[11px] leading-tight", children: description })) : null] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", children: children })] }));
|
|
14
14
|
}
|
|
15
15
|
export function SwitchRow({ label, description, id, testId, checked, onChange, disabled, tooltip, }) {
|
|
16
16
|
return (_jsx(SettingsRow, { label: label, description: description, htmlFor: id, tooltip: tooltip, children: _jsx(Switch, { id: id, "data-testid": testId, checked: checked, onCheckedChange: onChange, disabled: disabled, className: cn('cursor-pointer', disabled && 'cursor-not-allowed opacity-50') }) }));
|
|
17
17
|
}
|
|
18
18
|
/* ── Section card wrapper ── */
|
|
19
|
-
export function SettingsSection({ icon: Icon, title, description, badge, testId, children, }) {
|
|
20
|
-
return (_jsxs("div", { className: "bg-background rounded-lg border", "data-testid": testId, children: [_jsxs("div", { className: "bg-muted/30 border-b px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("h2", { className: "text-sm font-semibold", children: title }), badge ? (_jsx("span", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[9px] font-medium tracking-wider uppercase", children: badge })) : null] }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-[11px]", children: description })] }), _jsx("div", { className: "px-4", children: children })] }));
|
|
19
|
+
export function SettingsSection({ icon: Icon, title, description, badge, testId, tooltip, tooltipLinks, children, }) {
|
|
20
|
+
return (_jsxs("div", { className: "bg-background rounded-lg border", "data-testid": testId, children: [_jsxs("div", { className: "bg-muted/30 border-b px-4 py-3", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Icon, { className: "text-muted-foreground h-3.5 w-3.5" }), _jsx("h2", { className: "text-sm font-semibold", children: title }), tooltip ? (_jsxs(Tooltip, { children: [_jsx(TooltipTrigger, { asChild: true, children: _jsx(Info, { className: "text-muted-foreground/40 hover:text-muted-foreground h-3.5 w-3.5 shrink-0 cursor-help transition-colors" }) }), _jsxs(TooltipContent, { side: "bottom", className: "max-w-72 text-[11px] leading-relaxed", children: [_jsx("p", { className: "text-muted-foreground", children: tooltip }), tooltipLinks != null && tooltipLinks.length > 0 ? (_jsx("div", { className: "border-border/50 mt-1.5 flex flex-col gap-0.5 border-t pt-1.5", children: tooltipLinks.map((link) => (_jsxs("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1.5 text-[10px] tracking-wide transition-colors", children: [_jsx(ExternalLink, { className: "h-2.5 w-2.5 shrink-0 opacity-50" }), link.label] }, link.href))) })) : null] })] })) : null, badge ? (_jsx("span", { className: "bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-[9px] font-medium tracking-wider uppercase", children: badge })) : null] }), _jsx("p", { className: "text-muted-foreground mt-0.5 text-[11px]", children: description })] }), _jsx("div", { className: "px-4", children: children })] }));
|
|
21
21
|
}
|
|
22
22
|
export function NumberStepper({ id, testId, value, onChange, onBlur, placeholder, min = 1, max, step = 1, suffix, }) {
|
|
23
23
|
const { t } = useTranslation('web');
|
|
@@ -44,6 +44,3 @@ export function NumberStepper({ id, testId, value, onChange, onBlur, placeholder
|
|
|
44
44
|
export function SubsectionLabel({ children }) {
|
|
45
45
|
return (_jsx("div", { className: "border-b pt-3 pb-1", children: _jsx("span", { className: "text-muted-foreground text-[10px] font-semibold tracking-wider uppercase", children: children }) }));
|
|
46
46
|
}
|
|
47
|
-
export function SectionHint({ children, links, }) {
|
|
48
|
-
return (_jsxs("div", { className: "hidden pt-2 lg:block", children: [_jsx("p", { className: "text-muted-foreground/70 text-[11px] leading-relaxed", children: children }), links != null && links.length > 0 ? (_jsx("div", { className: "mt-2 flex flex-col gap-1", children: links.map((link) => (_jsxs("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", className: "text-muted-foreground hover:text-foreground inline-flex items-center gap-1 text-[10px] transition-colors", children: [_jsx(ExternalLink, { className: "h-2.5 w-2.5" }), link.label] }, link.href))) })) : null] }));
|
|
49
|
-
}
|
package/dist/src/presentation/web/components/features/settings/settings-section-utils.stories.d.ts
CHANGED
|
@@ -19,5 +19,5 @@ export declare const SwitchRows: Story;
|
|
|
19
19
|
export declare const SectionWithSwitches: Story;
|
|
20
20
|
export declare const NumberSteppers: Story;
|
|
21
21
|
export declare const SubsectionLabelExample: Story;
|
|
22
|
-
export declare const
|
|
22
|
+
export declare const SectionWithTooltip: Story;
|
|
23
23
|
//# sourceMappingURL=settings-section-utils.stories.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-section-utils.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"settings-section-utils.stories.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/features/settings/settings-section-utils.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAW5D;;;GAGG;AAEH,iBAAS,eAAe,4CAoBvB;AAgGD,QAAA,MAAM,IAAI;;;;;;;CAO8B,CAAC;AAEzC,eAAe,IAAI,CAAC;AACpB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,mBAAmB,EAAE,KAAU,CAAC;AAE7C,eAAO,MAAM,UAAU,EAAE,KAExB,CAAC;AAEF,eAAO,MAAM,mBAAmB,EAAE,KAEjC,CAAC;AAEF,eAAO,MAAM,cAAc,EAAE,KAE5B,CAAC;AAEF,eAAO,MAAM,sBAAsB,EAAE,KASpC,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAEhC,CAAC"}
|