"use client"; import { useEffect, useState } from "react"; import { Save, Plus, Trash2 } from "lucide-react"; import { Input } from "@multica/ui/components/ui/input"; import { Button } from "@multica/ui/components/ui/button"; import { Card, CardContent } from "@multica/ui/components/ui/card"; import { toast } from "sonner"; import { useQuery, useQueryClient } from "@tanstack/react-query"; import { useAuthStore } from "@multica/core/auth"; import { useWorkspaceId } from "@multica/core/hooks"; import { useCurrentWorkspace } from "@multica/core/paths"; import { memberListOptions, workspaceKeys } from "@multica/core/workspace/queries"; import { api } from "@multica/core/api"; import type { Workspace, WorkspaceRepo } from "@multica/core/types"; export function RepositoriesTab() { const user = useAuthStore((s) => s.user); const workspace = useCurrentWorkspace(); const wsId = useWorkspaceId(); const qc = useQueryClient(); const { data: members = [] } = useQuery(memberListOptions(wsId)); const [repos, setRepos] = useState(workspace?.repos ?? []); const [saving, setSaving] = useState(false); const currentMember = members.find((m) => m.user_id === user?.id) ?? null; const canManageWorkspace = currentMember?.role === "owner" || currentMember?.role === "admin"; useEffect(() => { setRepos(workspace?.repos ?? []); }, [workspace]); const handleSave = async () => { if (!workspace) return; setSaving(true); try { const updated = await api.updateWorkspace(workspace.id, { repos }); qc.setQueryData(workspaceKeys.list(), (old: Workspace[] | undefined) => old?.map((ws) => (ws.id === updated.id ? updated : ws)), ); toast.success("Repositories saved"); } catch (e) { toast.error(e instanceof Error ? e.message : "Failed to save repositories"); } finally { setSaving(false); } }; const handleAddRepo = () => { setRepos([...repos, { url: "", description: "" }]); }; const handleRemoveRepo = (index: number) => { setRepos(repos.filter((_, i) => i !== index)); }; const handleRepoChange = (index: number, field: keyof WorkspaceRepo, value: string) => { setRepos(repos.map((r, i) => (i === index ? { ...r, [field]: value } : r))); }; if (!workspace) return null; return (

Repositories

Git repositories associated with this workspace. Agents use these to clone and work on code.

{repos.map((repo, index) => (
handleRepoChange(index, "url", e.target.value)} disabled={!canManageWorkspace} placeholder="https://git.example.com/org/repo.git" className="text-sm" /> handleRepoChange(index, "description", e.target.value)} disabled={!canManageWorkspace} placeholder="Description (e.g. Go backend + Next.js frontend)" className="text-sm" />
{canManageWorkspace && ( )}
))} {canManageWorkspace && (
)} {!canManageWorkspace && (

Only admins and owners can manage repositories.

)}
); }