mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
feat(settings): refine browser automation tab
This commit is contained in:
+10
@@ -8,6 +8,7 @@
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@nivo/core": "^0.99.0",
|
||||
"@nivo/sankey": "^0.99.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
@@ -28,6 +29,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^12.38.0",
|
||||
"i18next": "^25.8.13",
|
||||
"lucide-react": "^0.556.0",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
@@ -273,6 +275,8 @@
|
||||
|
||||
"@open-draft/until": ["@open-draft/until@2.1.0", "", {}, "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg=="],
|
||||
|
||||
"@phosphor-icons/react": ["@phosphor-icons/react@2.1.10", "", { "peerDependencies": { "react": ">= 16.8", "react-dom": ">= 16.8" } }, "sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA=="],
|
||||
|
||||
"@radix-ui/number": ["@radix-ui/number@1.1.1", "", {}, "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g=="],
|
||||
|
||||
"@radix-ui/primitive": ["@radix-ui/primitive@1.1.3", "", {}, "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg=="],
|
||||
@@ -735,6 +739,8 @@
|
||||
|
||||
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
|
||||
|
||||
"framer-motion": ["framer-motion@12.38.0", "", { "dependencies": { "motion-dom": "^12.38.0", "motion-utils": "^12.36.0", "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0 || ^19.0.0", "react-dom": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@emotion/is-prop-valid", "react", "react-dom"] }, "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g=="],
|
||||
|
||||
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||
|
||||
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
|
||||
@@ -877,6 +883,10 @@
|
||||
|
||||
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
|
||||
|
||||
"motion-dom": ["motion-dom@12.38.0", "", { "dependencies": { "motion-utils": "^12.36.0" } }, "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA=="],
|
||||
|
||||
"motion-utils": ["motion-utils@12.36.0", "", {}, "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg=="],
|
||||
|
||||
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||
|
||||
"msw": ["msw@2.12.4", "", { "dependencies": { "@inquirer/confirm": "^5.0.0", "@mswjs/interceptors": "^0.40.0", "@open-draft/deferred-promise": "^2.2.0", "@types/statuses": "^2.0.6", "cookie": "^1.0.2", "graphql": "^16.12.0", "headers-polyfill": "^4.0.2", "is-node-process": "^1.2.0", "outvariant": "^1.4.3", "path-to-regexp": "^6.3.0", "picocolors": "^1.1.1", "rettime": "^0.7.0", "statuses": "^2.0.2", "strict-event-emitter": "^0.5.1", "tough-cookie": "^6.0.0", "type-fest": "^5.2.0", "until-async": "^3.0.2", "yargs": "^17.7.2" }, "peerDependencies": { "typescript": ">= 4.8.x" }, "optionalPeers": ["typescript"], "bin": { "msw": "cli/index.js" } }, "sha512-rHNiVfTyKhzc0EjoXUBVGteNKBevdjOlVC6GlIRXpy+/3LHEIGRovnB5WPjcvmNODVQ1TNFnoa7wsGbd0V3epg=="],
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@nivo/core": "^0.99.0",
|
||||
"@nivo/sankey": "^0.99.0",
|
||||
"@phosphor-icons/react": "^2.1.10",
|
||||
"@radix-ui/react-alert-dialog": "^1.1.15",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-collapsible": "^1.1.12",
|
||||
@@ -42,6 +43,7 @@
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"framer-motion": "^12.38.0",
|
||||
"i18next": "^25.8.13",
|
||||
"lucide-react": "^0.556.0",
|
||||
"prism-react-renderer": "^2.4.1",
|
||||
|
||||
@@ -2433,6 +2433,8 @@ const resources = {
|
||||
'Configure Claude Browser Attach and Codex Browser Tools here, then use the guidance below to launch or verify each lane.',
|
||||
readiness: 'Readiness',
|
||||
nextStep: 'Next step',
|
||||
technicalDetails: 'Technical Details',
|
||||
diagnostics: 'Diagnostics',
|
||||
actions: {
|
||||
saveClaude: 'Save Claude settings',
|
||||
saveCodex: 'Save Codex settings',
|
||||
@@ -4846,6 +4848,8 @@ const resources = {
|
||||
'在这里配置 Claude Browser Attach 和 Codex Browser Tools,然后按下方指引启动或验证每条路径。',
|
||||
readiness: '就绪状态',
|
||||
nextStep: '下一步',
|
||||
technicalDetails: '技术细节',
|
||||
diagnostics: '诊断信息',
|
||||
actions: {
|
||||
saveClaude: '保存 Claude 设置',
|
||||
saveCodex: '保存 Codex 设置',
|
||||
@@ -7361,6 +7365,8 @@ const resources = {
|
||||
'Cấu hình Claude Browser Attach và Codex Browser Tools tại đây, rồi dùng hướng dẫn bên dưới để khởi chạy hoặc kiểm tra từng luồng.',
|
||||
readiness: 'Trạng thái sẵn sàng',
|
||||
nextStep: 'Bước tiếp theo',
|
||||
technicalDetails: 'Chi tiết kỹ thuật',
|
||||
diagnostics: 'Chẩn đoán',
|
||||
actions: {
|
||||
saveClaude: 'Lưu cấu hình Claude',
|
||||
saveCodex: 'Lưu cấu hình Codex',
|
||||
@@ -9783,6 +9789,8 @@ const resources = {
|
||||
'ここで Claude Browser Attach と Codex Browser Tools を設定し、各レーンの起動や確認は下の案内を使ってください。',
|
||||
readiness: '準備状況',
|
||||
nextStep: '次の手順',
|
||||
technicalDetails: '技術的な詳細',
|
||||
diagnostics: '診断情報',
|
||||
actions: {
|
||||
saveClaude: 'Claude 設定を保存',
|
||||
saveCodex: 'Codex 設定を保存',
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
export type ClientPlatformKey = 'darwin' | 'linux' | 'win32';
|
||||
|
||||
type NavigatorWithUserAgentData = Pick<Navigator, 'platform' | 'userAgent'> & {
|
||||
userAgentData?: {
|
||||
platform?: string | null;
|
||||
};
|
||||
};
|
||||
|
||||
function normalizeClientPlatform(value: string): ClientPlatformKey {
|
||||
const platform = value.toLowerCase();
|
||||
if (platform.includes('mac')) return 'darwin';
|
||||
if (platform.includes('win')) return 'win32';
|
||||
return 'linux';
|
||||
}
|
||||
|
||||
export function getClientPlatformKey(
|
||||
nav: NavigatorWithUserAgentData = navigator as NavigatorWithUserAgentData
|
||||
): ClientPlatformKey {
|
||||
const userAgentDataPlatform =
|
||||
typeof nav.userAgentData?.platform === 'string' ? nav.userAgentData.platform : '';
|
||||
const fallbackPlatform =
|
||||
typeof nav.platform === 'string' && nav.platform.trim() ? nav.platform : nav.userAgent;
|
||||
|
||||
return normalizeClientPlatform(userAgentDataPlatform || fallbackPlatform || '');
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,32 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getClientPlatformKey } from '@/lib/platform';
|
||||
|
||||
describe('getClientPlatformKey', () => {
|
||||
it('prefers navigator.userAgentData.platform when available', () => {
|
||||
expect(
|
||||
getClientPlatformKey({
|
||||
userAgentData: { platform: 'macOS' },
|
||||
platform: 'Win32',
|
||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
|
||||
})
|
||||
).toBe('darwin');
|
||||
});
|
||||
|
||||
it('falls back to navigator.platform when userAgentData is unavailable', () => {
|
||||
expect(
|
||||
getClientPlatformKey({
|
||||
platform: 'Win32',
|
||||
userAgent: 'Mozilla/5.0 (X11; Linux x86_64)',
|
||||
})
|
||||
).toBe('win32');
|
||||
});
|
||||
|
||||
it('falls back to user-agent parsing when platform is unavailable', () => {
|
||||
expect(
|
||||
getClientPlatformKey({
|
||||
platform: '',
|
||||
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64)',
|
||||
})
|
||||
).toBe('win32');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user