feat(aircoding): AirCoding V2 baseline — deterministic multi-agent architecture
Forked from OpenCode v1.17.4 with multi-agent system: - 5 agents: aircoding, scheduler, worker, architect, reviewer - Deterministic DAG scheduling engine (coordinator_tick) - Tool whitelists as hard enforcement - AirCoding validation plugin - System prompt injection for routing - V1 requirements: C4 docs, ADR, AGENTS.md, debug-log.md - Design documents in docs/
This commit is contained in:
65
packages/core/test/repository.test.ts
Normal file
65
packages/core/test/repository.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import path from "path"
|
||||
import { pathToFileURL } from "url"
|
||||
import { Repository } from "@opencode-ai/core/repository"
|
||||
|
||||
describe("Repository", () => {
|
||||
test("parses github shorthand and builds an explicit-root cache path", () => {
|
||||
const reference = Repository.parseRemote("owner/repo")
|
||||
|
||||
expect(reference).toMatchObject({
|
||||
host: "github.com",
|
||||
path: "owner/repo",
|
||||
segments: ["owner", "repo"],
|
||||
owner: "owner",
|
||||
repo: "repo",
|
||||
remote: "https://github.com/owner/repo.git",
|
||||
label: "owner/repo",
|
||||
})
|
||||
expect(Repository.cachePath("/cache", reference)).toBe(path.join("/cache", "github.com", "owner", "repo"))
|
||||
expect(Repository.cacheIdentity(reference)).toBe("github.com/owner/repo")
|
||||
})
|
||||
|
||||
test("parses host path and scp remote references", () => {
|
||||
expect(Repository.parseRemote("gitlab.com/group/repo")).toMatchObject({
|
||||
host: "gitlab.com",
|
||||
path: "group/repo",
|
||||
remote: "https://gitlab.com/group/repo.git",
|
||||
label: "gitlab.com/group/repo",
|
||||
})
|
||||
expect(Repository.parseRemote("git@github.com:owner/repo.git")).toMatchObject({
|
||||
host: "github.com",
|
||||
path: "owner/repo",
|
||||
remote: "git@github.com:owner/repo.git",
|
||||
label: "owner/repo",
|
||||
})
|
||||
})
|
||||
|
||||
test("keeps local file repositories distinct from remote repositories", () => {
|
||||
const localPath = path.resolve("repo.git")
|
||||
const reference = Repository.parse(pathToFileURL(localPath).href)
|
||||
|
||||
expect(reference).toMatchObject({ host: "file", protocol: "file:", label: localPath })
|
||||
expect(reference && Repository.isFile(reference)).toBe(true)
|
||||
expect(reference && Repository.isRemote(reference)).toBe(false)
|
||||
expect(() => Repository.parseRemote(pathToFileURL(localPath).href)).toThrow(
|
||||
Repository.UnsupportedLocalRepositoryError,
|
||||
)
|
||||
})
|
||||
|
||||
test("rejects unsafe remote references and branches with typed errors", () => {
|
||||
expect(() => Repository.parseRemote("not-a-repo")).toThrow(Repository.InvalidReferenceError)
|
||||
expect(() => Repository.parseRemote("git@github.com:../../../etc/passwd")).toThrow(Repository.InvalidReferenceError)
|
||||
expect(() => Repository.validateBranch("feature/docs.v1")).not.toThrow()
|
||||
expect(() => Repository.validateBranch("-bad")).toThrow(Repository.InvalidBranchError)
|
||||
expect(() => Repository.validateBranch("bad..branch")).toThrow(Repository.InvalidBranchError)
|
||||
expect(() => Repository.validateBranch("bad branch")).toThrow(Repository.InvalidBranchError)
|
||||
})
|
||||
|
||||
test("compares cache identity independent of input spelling", () => {
|
||||
const shorthand = Repository.parseRemote("owner/repo")
|
||||
|
||||
expect(Repository.same(shorthand, Repository.parseRemote("https://github.com/owner/repo.git"))).toBe(true)
|
||||
expect(Repository.same(shorthand, Repository.parseRemote("github.com/owner/repo"))).toBe(true)
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user