AkurAI Build
Menu

popagent

public

Latest change 59f3c89df7ac29e072aafa31e6ad04dc601a750d - Add bounded repository brief service by AkurAI Build

import { afterEach, describe, expect, test } from "bun:test";
import { mkdtemp, mkdir, rm, writeFile } from "node:fs/promises";
import { join } from "node:path";
import { tmpdir } from "node:os";
import { RepositoryBriefService } from "./repo-brief";

const repositories: string[] = [];

async function git(path: string, ...args: string[]): Promise<void> {
  const process = Bun.spawn(["git", "-C", path, ...args], { stdout: "pipe", stderr: "pipe" });
  if (await process.exited !== 0) throw new Error(await new Response(process.stderr).text());
}

async function createRepository() {
  const path = await mkdtemp(join(tmpdir(), "popagent-repo-brief-"));
  repositories.push(path);
  await mkdir(join(path, "src"));
  await Promise.all([
    writeFile(join(path, "package.json"), JSON.stringify({ scripts: { test: "bun test" } })),
    writeFile(join(path, "src", "payment.ts"), "export function processPayment() { return true; }\n"),
    writeFile(join(path, "src", "payment.test.ts"), "import { processPayment } from './payment';\n"),
  ]);
  await git(path, "init");
  await git(path, "config", "user.email", "test@example.com");
  await git(path, "config", "user.name", "Test");
  await git(path, "add", ".");
  await git(path, "commit", "-m", "fixture");
  return path;
}

afterEach(async () => {
  await Promise.all(repositories.splice(0).map((path) => rm(path, { recursive: true, force: true })));
});

describe("buildRepositoryBrief", () => {
  test("maps a request to bounded source evidence without model inference", async () => {
    const repository = await createRepository();

    const brief = await new RepositoryBriefService({ resolveRepository: async () => ({
      workspace: {} as never,
      path: repository,
    }) }).build("workspace", "Fix payment processing");

    expect(brief.repository).toEqual({ clean: true, changedFiles: [] });
    expect(brief.candidates[0]).toEqual(expect.objectContaining({ path: "src/payment.ts" }));
    expect(brief.candidates[0]?.symbols).toContainEqual({ name: "processPayment", kind: "function", line: 1 });
    expect(brief.tests).toEqual(["bun test src/payment.test.ts"]);
    expect(brief.gaps).toEqual([]);
  });

  test("reports changed paths and does not expose ignored secret files", async () => {
    const repository = await createRepository();
    await Promise.all([
      writeFile(join(repository, ".env"), "SECRET=value\n"),
      writeFile(join(repository, "src", "payment.ts"), "export function processPayment() { return false; }\n"),
    ]);

    const brief = await new RepositoryBriefService({ resolveRepository: async () => ({
      workspace: {} as never,
      path: repository,
    }) }).build("workspace", "payment");

    expect(brief.repository.clean).toBe(false);
    expect(brief.repository.changedFiles).toEqual(["src/payment.ts"]);
    expect(JSON.stringify(brief)).not.toContain("SECRET=value");
  });
});