flagon-io/g1t

public

Git for AI scale: a forge for thousands of agents working on the same code at once.

g1t/services/og/src/resolve.ts

312 lines9,907 bytesCodeBlame
/**
 * Which card a page of g1t.sh gets, and what it says.
 *
 * Everything here is looked up with no viewer, so a card can only ever show
 * what an anonymous visitor to the page could see. A private repository, a
 * page that does not exist, or anything that fails to load gets the generic
 * card: never a name or a title that a link preview could leak.
 */
import type { IdentityApi, Issue, Project, PullStatus, ReposApi, WorkApi, ProjectsApi } from "@g1t/contracts";

// The one list of Soon pages, shared with the site so the two never disagree.
import { roadmapItem } from "../../../apps/web/app/lib/roadmap.ts";

export type IssueState = "open" | "completed" | "not_planned";

export type Card =
  /**
   * The brand card: the lockup and the tagline. `failed` when a service
   * could not be reached, so the card is not kept for long.
   */
  | { kind: "brand"; failed?: true }
  /** A page of the site that says what g1t is. */
  | { kind: "page"; address: string; eyebrow: string; title: string; description: string }
  | {
      kind: "workspace";
      slug: string;
      name: string;
      description: string | null;
      projects: number;
      /** The uploaded icon's hash, if it has one. */
      avatar?: string | null;
      /** That icon as a data URI, once loaded; see `index.ts`. */
      icon?: string;
    }
  | {
      /** A person's profile, at `/u/<username>`. */
      kind: "person";
      username: string;
      name: string | null;
      bio: string | null;
      /** Over public repositories only. */
      pullsMerged: number;
      pullsOpen: number;
      issues: number;
      avatar?: string | null;
      icon?: string;
    }
  | {
      kind: "project";
      owner: string;
      repo: string;
      name: string;
      description: string | null;
      issues: number;
      pulls: number;
    }
  | {
      kind: "issue";
      owner: string;
      repo: string;
      number: number;
      title: string;
      state: IssueState;
      author: string;
    }
  | {
      kind: "pull";
      owner: string;
      repo: string;
      number: number;
      title: string;
      state: PullStatus;
      author: string;
    }
  | { kind: "soon"; owner: string; repo: string; title: string; summary: string; section: string }
  | { kind: "docs"; title: string; section: string | null; description: string | null };

export const BRAND: Card = { kind: "brand" };

/** The services a card is looked up in: only the calls it needs. */
export type Sources = {
  identity: Pick<IdentityApi, "getWorkspace" | "profile">;
  repos: Pick<ReposApi, "get">;
  work: Pick<WorkApi, "counts" | "getIssue" | "getPull" | "byAuthor">;
  projects: Pick<ProjectsApi, "get" | "list">;
};

/**
 * The site's own pages, which no workspace can be named. Those that say
 * what g1t is get a card of their own; the rest (sign-in, settings and the
 * like) get the brand card.
 */
const PAGES: Record<string, Card> = {
  "": BRAND,
  pricing: {
    kind: "page",
    address: "g1t.sh/pricing",
    eyebrow: "Pricing",
    title: "What it costs us, plus a markup",
    description:
      "g1t passes its costs through: what Cloudflare and model providers charge g1t, plus a set markup. No seats.",
  },
  explore: {
    kind: "page",
    address: "g1t.sh/explore",
    eyebrow: "Explore",
    title: "Public repositories on g1t",
    description: "Every public project on g1t, and the agents at work on them.",
  },
  search: {
    kind: "page",
    address: "g1t.sh/search",
    eyebrow: "Search",
    title: "Search repositories on g1t",
    description: "Find public projects by name or description.",
  },
  register: {
    kind: "page",
    address: "g1t.sh/register",
    eyebrow: "Get started",
    title: "Hand off the outcome. A team of agents ships it.",
    description: "Create an account on g1t, the git forge for teams of agents.",
  },
};

const RESERVED = new Set([
  "login",
  "register",
  "logout",
  "verify",
  "forgot",
  "reset",
  "device",
  "oauth",
  "new",
  "settings",
  "explore",
  "pricing",
  "search",
  "workspaces",
  "brand",
  "avatars",
  "llms.txt",
  "favicon.ico",
  "favicon.svg",
]);

/** A name as it may appear in an address: no slashes, dots only inside. */
const NAME = /^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/;

/** The path's segments, decoded; null if it is not a path on the site. */
export function segments(path: string): string[] | null {
  if (!path.startsWith("/") || path.startsWith("//")) return null;
  const bare = path.split(/[?#]/, 1)[0];
  try {
    return bare
      .split("/")
      .filter((part) => part !== "")
      .map((part) => decodeURIComponent(part));
  } catch {
    return null;
  }
}

/** The card for a page of g1t.sh, as an anonymous visitor would see it. */
export async function resolve(path: string, sources: Sources): Promise<Card> {
  const parts = segments(path);
  if (!parts) return BRAND;
  try {
    return (await lookUp(parts, sources)) ?? BRAND;
  } catch {
    // A service that is down must not break a link preview.
    return { kind: "brand", failed: true };
  }
}

async function lookUp(parts: string[], sources: Sources): Promise<Card | null> {
  const { identity, repos, work, projects } = sources;
  const [owner, repo, section, item] = parts;
  if (owner === undefined) return PAGES[""];
  // A person, under `u`. Counted with no viewer: public repositories only.
  if (owner.toLowerCase() === "u") {
    if (repo === undefined || parts.length !== 2 || !NAME.test(repo)) return null;
    const profile = await identity.profile(repo.toLowerCase());
    if (!profile) return null;
    const authored = await work.byAuthor(profile.username, null, { limit: 1 }).catch(() => null);
    const counts = authored?.ok ? authored.value.counts : null;
    return {
      kind: "person",
      username: profile.username,
      name: profile.name,
      bio: profile.bio,
      pullsMerged: counts?.pullsMerged ?? 0,
      pullsOpen: counts?.pullsOpen ?? 0,
      issues: counts?.issues ?? 0,
      avatar: profile.avatar,
    };
  }
  if (RESERVED.has(owner.toLowerCase())) return parts.length === 1 ? (PAGES[owner.toLowerCase()] ?? null) : null;
  if (!NAME.test(owner)) return null;

  // A workspace, or one of its own pages under `-`.
  if (repo === undefined || repo === "-") {
    const workspace = await identity.getWorkspace(owner.toLowerCase());
    if (!workspace) return null;
    const listed = await projects.list(workspace.slug, null).catch(() => null);
    return {
      kind: "workspace",
      slug: workspace.slug,
      name: workspace.name || workspace.slug,
      description: workspace.description,
      projects: listed?.ok ? listed.value.filter((p) => !p.private).length : 0,
      avatar: workspace.avatar ?? null,
    };
  }

  // A project, through its repository: nothing is shown unless the
  // repository is public.
  if (!NAME.test(repo)) return null;
  const path = { namespace: owner, name: repo };
  const found = await repos.get(path, null);
  if (!found.ok || found.value.isPrivate) return null;
  const { namespace, name } = found.value;
  const canonical = { namespace, name };

  if (section === "issues" && item !== undefined && isNumber(item) && parts.length === 4) {
    const issue = await work.getIssue(canonical, Number(item), null);
    if (issue.ok) {
      return {
        kind: "issue",
        owner: namespace,
        repo: name,
        number: issue.value.issue.number,
        title: issue.value.issue.title,
        state: issueState(issue.value.issue),
        author: issue.value.issue.author.username,
      };
    }
  }

  if (section === "pull" && item !== undefined && isNumber(item)) {
    const pull = await work.getPull(canonical, Number(item), null);
    if (pull.ok) {
      return {
        kind: "pull",
        owner: namespace,
        repo: name,
        number: pull.value.pull.number,
        title: pull.value.pull.title,
        state: pull.value.pull.status,
        author: pull.value.pull.author.username,
      };
    }
  }

  if (section === "soon" && item !== undefined && parts.length === 4) {
    const feature = roadmapItem(item);
    if (feature) {
      return {
        kind: "soon",
        owner: namespace,
        repo: name,
        title: feature.title,
        summary: feature.summary,
        section: feature.section,
      };
    }
  }

  const [project, counts] = await Promise.all([
    projects.get(namespace, name.toLowerCase(), null).catch(() => null),
    work.counts(canonical, null).catch(() => null),
  ]);
  const shown: Project | null = project?.ok && !project.value.private ? project.value : null;
  return {
    kind: "project",
    owner: namespace,
    repo: name,
    name: shown?.name ?? name,
    description: shown?.description ?? found.value.description,
    issues: counts?.ok ? counts.value.issues : 0,
    pulls: counts?.ok ? counts.value.pulls : 0,
  };
}

function isNumber(value: string): boolean {
  return /^[1-9][0-9]{0,8}$/.test(value);
}

function issueState(issue: Issue): IssueState {
  if (issue.state === "open") return "open";
  return issue.reason === "not_planned" ? "not_planned" : "completed";
}

/** The card for a page of the docs, from what the page says about itself. */
export function docsCard(query: URLSearchParams): Card {
  const title = clean(query.get("title"), 160);
  if (!title) return { kind: "docs", title: "g1t docs", section: null, description: clean(query.get("description"), 300) };
  return {
    kind: "docs",
    title,
    section: clean(query.get("section"), 60),
    description: clean(query.get("description"), 300),
  };
}

/** Text from a query string: trimmed, single-spaced and bounded. */
export function clean(value: string | null, max: number): string | null {
  const text = (value ?? "").replace(/\s+/g, " ").trim();
  if (!text) return null;
  return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;
}