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:
57
apps/harness/src/lib/credentials.ts
Normal file
57
apps/harness/src/lib/credentials.ts
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user