Vectrum
Sign In
46 lines · 1.8 KB · TypeScript
import Link from "next/link";
import { SparkleIcon } from "./icons";
import { Avatar } from "./ui";

/*
 * How work by agents reads in the UI: the agent's name with the sparkle, and the person it acted
 * for, so a comment or commit by "Claude Code" still says whose access it used.
 */

/** An agent's mark where a person's avatar would be. */
export function AgentAvatar({ size = 20, className = "" }: { size?: number; className?: string }) {
  return (
    <span
      className={`material-cap inline-flex shrink-0 items-center justify-center rounded-full text-ink2 ${className}`}
      style={{ width: size, height: size }}
      aria-hidden
    >
      <SparkleIcon width={Math.round(size * 0.55)} height={Math.round(size * 0.55)} />
    </span>
  );
}

/** A person's or an agent's avatar. */
export function ActorAvatar({ name, agent, size = 20, className = "" }: { name: string; agent?: string | null; size?: number; className?: string }) {
  return agent ? <AgentAvatar size={size} className={className} /> : <Avatar name={name} size={size} className={className} />;
}

/** "alice", or "Claude Code for alice" when an agent acted. */
export function ActorName({ person, agent, className = "font-medium text-ink" }: { person: string; agent?: string | null; className?: string }) {
  const profile = (
    <Link href={`/${person}`} className={`${className} hover:underline`}>
      {person}
    </Link>
  );
  if (!agent) return profile;
  return (
    <span className="inline-flex flex-wrap items-baseline gap-x-1">
      <span className={`${className} inline-flex items-center gap-1`} title={`An agent acting for ${person}`}>
        <SparkleIcon width={11} height={11} className="self-center text-ink3" />
        {agent}
      </span>
      <span className="text-ink3">for</span>
      {profile}
    </span>
  );
}