Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions frontend/src/apis/github.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,20 @@ export const githubApis = {
return await apiClient.get('/git/repositories')
},

async searchRepositories(query: string): Promise<GitRepoInfo[]> {
// Add timeout=30 parameter to be compatible with backend interface
return await apiClient.get(`/git/repositories/search?q=${encodeURIComponent(query)}&timeout=30`);
// Unified search API: supports optional precise search via fullmatch and configurable timeout
async searchRepositories(
query: string,
opts?: { fullmatch?: boolean; timeout?: number }
): Promise<GitRepoInfo[]> {
const timeout = opts?.timeout ?? 30
const params = new URLSearchParams({
q: query,
timeout: String(timeout),
})
if (opts?.fullmatch) {
params.append('fullmatch', '1')
}
return await apiClient.get(`/git/repositories/search?${params.toString()}`)
},

async getBranches(repo: GitRepoInfo): Promise<GitBranchesResponse> {
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import { Button } from 'antd'
import { paths } from '@/config/paths'
import { useTranslation } from '@/hooks/useTranslation'
import LanguageSwitcher from '@/components/LanguageSwitcher'
import { ThemeToggle } from '@/features/theme/ThemeToggle'
import { getToken } from '@/apis/user'
import { ThemeToggle } from '@/features/theme/ThemeToggle'
import { GithubStarButton } from '@/features/layout/GithubStarButton'

export default function Home() {
const router = useRouter()
Expand All @@ -29,6 +30,7 @@ export default function Home() {
<main className="flex smart-h-screen flex-col items-center justify-center p-8 bg-base relative box-border">
{/* Language Switcher */}
<div className="absolute top-4 right-4 flex items-center gap-3">
<GithubStarButton />
<ThemeToggle />
<LanguageSwitcher />
</div>
Expand Down
7 changes: 2 additions & 5 deletions frontend/src/app/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ import BotList from '@/features/settings/components/BotList'
import TeamList from '@/features/settings/components/TeamList'
import { UserProvider, useUser } from '@/features/common/UserContext'
import { useTranslation } from '@/hooks/useTranslation'
import { ThemeToggle } from '@/features/theme/ThemeToggle'
import { DocsButton } from '@/features/layout/DocsButton'
import { GithubStarButton } from '@/features/layout/GithubStarButton'

function DashboardContent() {
const router = useRouter()
Expand Down Expand Up @@ -78,9 +77,7 @@ function DashboardContent() {
activePage="dashboard"
showLogo={true}
>
{/* User Avatar Menu */}
<DocsButton />
<ThemeToggle />
<GithubStarButton />
<UserMenu />
</TopNavigation>

Expand Down
6 changes: 2 additions & 4 deletions frontend/src/app/tasks/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import TeamShareHandler from '@/features/tasks/components/TeamShareHandler'
import OidcTokenHandler from '@/features/login/components/OidcTokenHandler'
import '@/app/tasks/tasks.css'
import '@/features/common/scrollbar.css'
import { ThemeToggle } from '@/features/theme/ThemeToggle'
import { DocsButton } from '@/features/layout/DocsButton'
import { GithubStarButton } from '@/features/layout/GithubStarButton'
import { Team } from '@/types/api'
export default function TasksPage() {
// Team state from service
Expand Down Expand Up @@ -69,8 +68,7 @@ export default function TasksPage() {
showLogo={false}
onMobileSidebarToggle={() => setIsMobileSidebarOpen(true)}
>
<DocsButton />
<ThemeToggle />
<GithubStarButton />
<UserMenu />
</TopNavigation>
{/* Chat area */}
Expand Down
2 changes: 0 additions & 2 deletions frontend/src/features/common/UserContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ export const UserProvider = ({ children }: { children: ReactNode }) => {

const fetchUser = async () => {
setIsLoading(true)
console.log('UserContext: Starting to fetch user information')

try {
const isAuth = userApis.isAuthenticated()
console.log('UserContext: Authentication status check:', isAuth)

if (!isAuth) {
console.log('UserContext: User not authenticated, clearing user state and redirecting to login')
Expand Down
104 changes: 104 additions & 0 deletions frontend/src/features/layout/GithubStarButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// SPDX-FileCopyrightText: 2025 Weibo, Inc.
//
// SPDX-License-Identifier: Apache-2.0

'use client'

import { useEffect, useState } from 'react'

const REPO_API = 'https://api.github.com/repos/wecode-ai/Wegent'
const REPO_URL = 'https://github.com/wecode-ai/Wegent'

export function GithubStarButton({ className = '' }: { className?: string }) {
const [stars, setStars] = useState<number | null>(null)
const [isLoading, setIsLoading] = useState(true)

useEffect(() => {
let isMounted = true

const fetchStars = async () => {
try {
const response = await fetch(REPO_API, {
headers: {
Accept: 'application/vnd.github+json',
},
})

if (!response.ok) {
throw new Error(`GitHub API responded with ${response.status}`)
}

const data = await response.json()

if (isMounted && typeof data?.stargazers_count === 'number') {
setStars(data.stargazers_count)
}
} catch (error) {
console.error('Failed to fetch GitHub stars', error)
if (isMounted) {
setStars(null)
}
} finally {
if (isMounted) {
setIsLoading(false)
}
}
}

void fetchStars()

return () => {
isMounted = false
}
}, [])

const mergedClassName = `
px-3 py-1.5 rounded-full border border-transparent
flex items-center gap-2 text-base font-semibold text-text-primary
hover:border-border transition-colors duration-200
${className}
`.trim()

const handleClick = () => {
window.open(REPO_URL, '_blank', 'noopener,noreferrer')
}

const formatStarCount = (value: number | null): string => {
if (value === null) {
return '—'
}
if (value < 1000) {
return "🌟"+value.toString()
}
const thousands = value / 1000
const decimals = value >= 100000 ? 0 : 1
const base = Number(thousands.toFixed(decimals))
return `${base}k`
}

const displayValue = isLoading ? '...' : formatStarCount(stars)

return (
<button
type="button"
onClick={handleClick}
className={mergedClassName}
aria-label="Star Wegent on GitHub"
>
<svg
stroke="currentColor"
fill="currentColor"
viewBox="0 0 15 15"
className="h-5 w-5"
aria-hidden="true"
>
<path
fillRule="evenodd"
clipRule="evenodd"
d="M7.49933 0.25C3.49635 0.25 0.25 3.49593 0.25 7.50024C0.25 10.703 2.32715 13.4206 5.2081 14.3797C5.57084 14.446 5.70302 14.2222 5.70302 14.0299C5.70302 13.8576 5.69679 13.4019 5.69323 12.797C3.67661 13.235 3.25112 11.825 3.25112 11.825C2.92132 10.9874 2.44599 10.7644 2.44599 10.7644C1.78773 10.3149 2.49584 10.3238 2.49584 10.3238C3.22353 10.375 3.60629 11.0711 3.60629 11.0711C4.25298 12.1788 5.30335 11.8588 5.71638 11.6732C5.78225 11.205 5.96962 10.8854 6.17658 10.7043C4.56675 10.5209 2.87415 9.89918 2.87415 7.12104C2.87415 6.32925 3.15677 5.68257 3.62053 5.17563C3.54576 4.99226 3.29697 4.25521 3.69174 3.25691C3.69174 3.25691 4.30015 3.06196 5.68522 3.99973C6.26337 3.83906 6.8838 3.75895 7.50022 3.75583C8.1162 3.75895 8.73619 3.83906 9.31523 3.99973C10.6994 3.06196 11.3069 3.25691 11.3069 3.25691C11.7026 4.25521 11.4538 4.99226 11.3795 5.17563C11.8441 5.68257 12.1245 6.32925 12.1245 7.12104C12.1245 9.9063 10.4292 10.5192 8.81452 10.6985C9.07444 10.9224 9.30633 11.3648 9.30633 12.0413C9.30633 13.0102 9.29742 13.7922 9.29742 14.0299C9.29742 14.2239 9.42828 14.4496 9.79591 14.3788C12.6746 13.4179 14.75 10.7025 14.75 7.50024C14.75 3.49593 11.5036 0.25 7.49933 0.25Z"
/>
</svg>
<span>{displayValue}</span>
</button>
)
}
9 changes: 8 additions & 1 deletion frontend/src/features/layout/UserMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { Button } from 'antd'

import { useUser } from '@/features/common/UserContext'
import { useTranslation } from '@/hooks/useTranslation'
import { DocsButton } from '@/features/layout/DocsButton'
import { ThemeToggle } from '@/features/theme/ThemeToggle'

type UserMenuProps = {
className?: string
Expand All @@ -22,13 +24,18 @@ export default function UserMenu({ className = '' }: UserMenuProps) {
return (
<div className={className}>
<Menu as="div" className="relative">
<Menu.Button className="px-3 py-1 bg-muted border border-border rounded-full flex items-center justify-center text-sm font-medium text-text-primary hover:bg-border/40 transition-colors duration-200">
<Menu.Button className="px-4 py-1.5 bg-muted border border-border rounded-full flex items-center justify-center text-base font-semibold text-text-primary hover:bg-border/40 transition-colors duration-200">
{userDisplayName}
</Menu.Button>
<Menu.Items
className="absolute top-full right-0 mt-2 min-w-[120px] rounded-lg border border-border bg-surface py-1 z-30 focus:outline-none"
style={{ boxShadow: 'var(--shadow-popover)' }}
>
<div className="flex flex-col gap-2 px-2 pb-1.5">
<DocsButton className="w-full justify-center" />
<ThemeToggle className="w-full justify-center" />
</div>
<div className="my-1 h-px bg-border/60" />
<Menu.Item>
{({ active }) => (
<Button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,13 @@ const McpConfigImportModal: React.FC<McpConfigImportModalProps> = ({
"remote-server": {
"url": "http://127.0.0.1:9099/sse"
},
"search-mcp": {
"weibo-search-mcp": {
"transport": "streamable_http"
},
"EcoMCP-server": {
"url": "http://example.com:9999/sse",
"disabled": false,
"alwaysAllow": []
}
}
}`}
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/features/settings/components/TeamEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ export default function TeamEdit(props: TeamEditProps) {
}, [editingTeamId, initialTeam])


// Each Mode's "description" and "boundary", including text and assets (i18n)
// Each Mode's "description" and "boundary", including text and images (i18n)
const MODE_INFO = useMemo(() => {
// i18n keys
const titleKey = `team_model.${mode}`;
Expand Down
9 changes: 5 additions & 4 deletions frontend/src/features/tasks/components/BranchSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ export default function BranchSelector({

// Fetch branch list
useEffect(() => {
handleBranchChange(null)
if (!selectedRepo) {
setBranches([])
setError(null)
setLoading(false)

return
}
let ignore = false
Expand Down Expand Up @@ -93,9 +95,8 @@ export default function BranchSelector({
const defaultBranch = branches.find(b => b.default)
if (defaultBranch) {
handleBranchChange(defaultBranch)
} else if (branches.length > 0) {
// Fallback to first branch if no default branch found
handleBranchChange(branches[0])
} else {
handleBranchChange(null)
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down Expand Up @@ -155,7 +156,7 @@ export default function BranchSelector({
popupMatchSelectWidth={false}
styles={{ popup: { root: { maxWidth: 200 } } }}
classNames={{ popup: { root: "repository-selector-dropdown custom-scrollbar" } }}
disabled={disabled || showLoading || showError || showNoBranch}
disabled={disabled || showError || showNoBranch}
loading={showLoading}
optionFilterProp="value"
filterOption={(input, option) => {
Expand Down
Loading