import { env, waitUntil } from "cloudflare:workers";
import { kvPut } from "./cache";
import { sha256Hex } from "../crypto";
import { withStore } from "../git/store";
import type { GitStore } from "../git/store";
import { branchSha, listRefs } from "../git/refs";
import { loadRepoById } from "../repos";
import { toBrief } from "~/lib/code-intel";
import type { CommitBrief } from "~/lib/code-intel";
import type { CommitSummary } from "~/lib/types";
const PAGE_SIZE = 30;
const WALK_BUDGET_PER_REQUEST = 300;
const PREFETCH_COMMITS = 100;
/** Extra budgets spent after the response is sent, so deep walks finish without the client polling. */
const BACKGROUND_BUDGETS = 10;
const MAX_PATH_MATCHES = 1000;
const MAX_INLINE_KEY_PATH = 200;
/** KV keys are capped at 512 bytes, so long paths are hashed. */
export async function pathKey(path: string): Promise<string> {
return path.length <= MAX_INLINE_KEY_PATH ? path : `h:${await sha256Hex(path)}`;
}
async function pathSha(store: GitStore, commit: CommitSummary, path: string): Promise<string | null> {
const entry = await store.entryAtPath(commit.treeSha, path);
return entry?.sha ?? null;
}
type PathLogState = { matches: CommitBrief[]; cursor: string | null; cursorPathSha: string | null };
export type PathHistoryPage = { commits: CommitBrief[]; hasMore: boolean; capped: boolean };
/**
* First-parent history of commits that changed `path`. The walk resumes from a KV-stored cursor so
* each request reads at most WALK_BUDGET_PER_REQUEST commits, however deep the requested page.
*/
export async function pathHistory(
store: GitStore,
headSha: string,