Add git module with repo status overview (/git) and per-repo detail page (/git/[repo]) featuring a color-coded diff viewer (+ green, - red). Reads repo paths from REPO_PATHS env var, calls ops-agent git_status and git_diff commands. Status badges: clean (green), dirty (orange), behind-origin (blue). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
54 lines
1.8 KiB
TypeScript
54 lines
1.8 KiB
TypeScript
import { redirect } from 'next/navigation'
|
|
import { getCurrentUser } from '@/lib/session'
|
|
import { execAgent } from '@/lib/agent-client'
|
|
import { parseGitStatus, type RepoStatus } from '@/lib/parse-git'
|
|
import GitReposList from './_components/git-repos-list'
|
|
|
|
export const dynamic = 'force-dynamic'
|
|
|
|
function repoName(repoPath: string): string {
|
|
return repoPath.split('/').filter(Boolean).pop() ?? repoPath
|
|
}
|
|
|
|
export default async function GitPage() {
|
|
const user = await getCurrentUser()
|
|
if (!user) redirect('/login')
|
|
|
|
const repoPaths = (process.env.REPO_PATHS ?? '')
|
|
.split(',')
|
|
.map((p) => p.trim())
|
|
.filter(Boolean)
|
|
|
|
const initialRepos = await Promise.all(
|
|
repoPaths.map(async (path) => {
|
|
let status: RepoStatus | null = null
|
|
let error: string | null = null
|
|
try {
|
|
const output = await execAgent('git_status', [path])
|
|
status = parseGitStatus(output)
|
|
} catch (err) {
|
|
error = err instanceof Error ? err.message : 'failed'
|
|
}
|
|
return { path, name: repoName(path), status, error }
|
|
}),
|
|
)
|
|
|
|
return (
|
|
<div className="min-h-screen bg-background p-6">
|
|
<div className="mx-auto max-w-6xl space-y-6">
|
|
<div>
|
|
<h1 className="text-2xl font-semibold tracking-tight">Git Repositories</h1>
|
|
<p className="text-sm text-muted-foreground">Auto-refreshes every 30 seconds</p>
|
|
</div>
|
|
{repoPaths.length === 0 ? (
|
|
<div className="rounded-lg border border-border p-6 text-sm text-muted-foreground">
|
|
No repos configured. Set <code className="font-mono">REPO_PATHS</code> in your
|
|
environment (comma-separated absolute paths).
|
|
</div>
|
|
) : (
|
|
<GitReposList initialRepos={initialRepos} />
|
|
)}
|
|
</div>
|
|
</div>
|
|
)
|
|
}
|