138 lines · 5.6 KB
import { listRepos } from "../api/repos";
import { RPC, RpcError } from "./protocol";
import type { JsonObject, McpCaller } from "./protocol";
import { eventJson, eventsUri, repoHub, sessionHub, sessionSubscriber, subscriberOwner } from "./hub-do";
import { apiCtx, apiJson, scopedRepo } from "./tools/base";
import { readableEventTypes } from "./event-access";
import { MAX_FILE_BYTES, readFileAt, resolveRef } from "./tools/content";

const LISTED_REPOS = 50;
const EVENTS_IN_RESOURCE = 50;

export const RESOURCE_TEMPLATES = [
  {
    uriTemplate: "gitfor://{owner}/{repo}/{ref}/{+path}",
    name: "repo-file",
    title: "Repository file",
    description: "A file at a branch, tag or commit. URL-encode refs that contain slashes (feature%2Fx).",
  },
  {
    uriTemplate: "gitfor-events://{owner}/{repo}",
    name: "repo-events",
    title: "Repository events",
    description: "Recent push, review, CI and claim events. Subscribe to be notified when it changes.",
    mimeType: "application/json",
  },
];

type Parsed =
  | { kind: "file"; owner: string; repo: string; ref: string; path: string }
  | { kind: "events"; owner: string; repo: string };

function decode(part: string): string {
  try {
    return decodeURIComponent(part);
  } catch {
    throw new RpcError(RPC.invalidParams, "Malformed resource URI");
  }
}

export function parseResourceUri(uri: string): Parsed {