Add harness app: agent orchestrator with cluster deployment

- Next.js app for orchestrating coding agent benchmarks (Claude Code, Codex, OpenCode)
- Dockerfile installs git, gh CLI, and agent CLIs for headless execution
- K8s deployment with workspace volume, sealed credentials for Claude + OpenCode
- Traefik IngressRoute at harness.coreworlds.io with internal-only middleware + TLS
- CI pipeline path filter for harness builds
- Fix OpenCode runtime flags (subcommand-based headless mode)
This commit is contained in:
Julia McGhee
2026-03-21 15:26:09 +00:00
parent 9e7077cd82
commit 6dde7c8aef
46 changed files with 4675 additions and 0 deletions

View File

@@ -0,0 +1,57 @@
export type Provider =
| "github" | "gitlab"
| "anthropic" | "openai" | "openrouter" | "google" | "opencode-zen";
export const GIT_PROVIDERS: Provider[] = ["github", "gitlab"];
export const AI_PROVIDERS: Provider[] = ["anthropic", "openai", "openrouter", "google", "opencode-zen"];
export interface Credential {
id: string;
provider: Provider;
label: string;
token: string;
baseUrl?: string; // for self-hosted GitLab or custom endpoints
}
// In-memory store. Will be replaced with encrypted persistent storage.
const credentials: Map<string, Credential> = new Map();
export function getAllCredentials(): Credential[] {
return Array.from(credentials.values()).map(c => ({
...c,
token: maskToken(c.token),
}));
}
export function getCredentialsByKind(kind: "git" | "ai"): Credential[] {
const providers = kind === "git" ? GIT_PROVIDERS : AI_PROVIDERS;
return Array.from(credentials.values())
.filter(c => providers.includes(c.provider))
.map(c => ({ ...c, token: maskToken(c.token) }));
}
export function getCredential(id: string): Credential | undefined {
return credentials.get(id);
}
export function getCredentialsByProvider(provider: Provider): Credential[] {
return Array.from(credentials.values()).filter(c => c.provider === provider);
}
export function getRawCredentialsByProvider(provider: Provider): Credential[] {
return Array.from(credentials.values()).filter(c => c.provider === provider);
}
export function upsertCredential(cred: Credential): Credential {
credentials.set(cred.id, cred);
return { ...cred, token: maskToken(cred.token) };
}
export function deleteCredential(id: string): boolean {
return credentials.delete(id);
}
function maskToken(token: string): string {
if (token.length <= 8) return "••••••••";
return token.slice(0, 4) + "••••" + token.slice(-4);
}