feat(graph): demo-ready materializer + per-pod Team memory action

Materializer (live.ts) — cut demo-pod from 110 -> 22 nodes:
- cap to 8 recent collisions; collapse repeats by memorySignature
- collapse interventions to one (most recent) per collision
- filter junk 'files' (URLs, env vars, browser/app names, scratch/test) to
  real source paths only
- prune test-artifact engineers (a/b/verify/codex-check/-testrepo) + any node
  orphaned by that
- collisions referenced by accepted outcomes bypass the cap so the learned_from
  money path never drops; risk-paths metric counts distinct signatures

UI: per-pod 'Team memory' action on each PodCard's menu (replaces the header
button that always opened pods[0]).

Verified against live demo-pod data (joins connect); typechecks clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
sb-iam
2026-06-27 21:35:14 -07:00
parent 412d3f7df6
commit 2006096cda
3 changed files with 117 additions and 21 deletions
+1 -4
View File
@@ -268,10 +268,6 @@ export default function App() {
<ShieldCheckIcon data-icon="inline-start" />
Privacy-limited
</Badge>
<Button variant="outline" onClick={() => setGraphPodId(pods[0]?.id ?? 'demo-pod')}>
<BrainCircuitIcon data-icon="inline-start" />
Team memory
</Button>
<Button variant="outline" onClick={() => void refresh()} disabled={loading}>
<RefreshCwIcon data-icon="inline-start" />
Refresh
@@ -342,6 +338,7 @@ export default function App() {
onRemoveMember={handleRemoveMember}
onUpdate={handleUpdate}
onDelete={handleDelete}
onOpenGraph={setGraphPodId}
/>
))}
</div>
+14 -1
View File
@@ -1,5 +1,12 @@
import { useState } from 'react';
import { MoreHorizontalIcon, PlusIcon, Trash2Icon, UserRoundIcon, VideoIcon } from 'lucide-react';
import {
BrainCircuitIcon,
MoreHorizontalIcon,
PlusIcon,
Trash2Icon,
UserRoundIcon,
VideoIcon,
} from 'lucide-react';
import type { Pod, PodInput } from '@podman/shared';
import { Avatar, AvatarBadge, AvatarFallback, AvatarGroup } from '@/components/ui/avatar';
import { Badge } from '@/components/ui/badge';
@@ -42,6 +49,7 @@ export function PodCard({
onRemoveMember: _onRemoveMember,
onUpdate,
onDelete,
onOpenGraph,
}: {
pod: Pod;
busy: boolean;
@@ -52,6 +60,7 @@ export function PodCard({
onRemoveMember: (id: string, name: string) => void;
onUpdate: (id: string, patch: PodInput) => void;
onDelete: (id: string) => void;
onOpenGraph: (id: string) => void;
}) {
const [newMember, setNewMember] = useState('');
const [editing, setEditing] = useState(false);
@@ -100,6 +109,10 @@ export function PodCard({
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuGroup>
<DropdownMenuItem onSelect={() => onOpenGraph(pod.id)}>
<BrainCircuitIcon />
Team memory
</DropdownMenuItem>
<DropdownMenuItem onSelect={() => setEditing(true)}>Edit pod</DropdownMenuItem>
<DropdownMenuItem
variant="destructive"