aiwg
Version:
Deployment tool and support utility for AI context. Copies agents, skills, commands, rules, and behaviors into the paths each AI platform reads (Claude Code, Codex, Copilot, Cursor, Warp, OpenClaw, and 6 more) so one source of truth works across 10 platfo
93 lines • 2.85 kB
JavaScript
/**
* Gitea Adapter
*
* Resolves "owner/name[@version]" shorthands against the configured Gitea host.
* Falls back to git.integrolabs.net (the default self-hosted instance).
*
* Resolution priority:
* 1. AIWG_GITEA_HOST env var
* 2. ~/.aiwg/config.yaml → defaults.giteaHost
* 3. git.integrolabs.net (hardcoded fallback)
*
* Authentication:
* - SSH clone: uses default SSH agent (recommended for teams)
* - HTTPS clone: reads token from GITEA_TOKEN env or ~/.config/gitea/token
*
* @implements #557
*/
import { existsSync } from 'fs';
import { readFile } from 'fs/promises';
import { join } from 'path';
import { homedir } from 'os';
import { GitAdapter } from './git.js';
/**
* Regex for "owner/name" or "owner/name@version" (no scheme prefix)
*/
const GITEA_SHORTHAND = /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(@[a-zA-Z0-9._/-]+)?$/;
/**
* Read Gitea token from standard file path (same as global CLAUDE.md convention)
*/
async function readGiteaToken() {
if (process.env.GITEA_TOKEN)
return process.env.GITEA_TOKEN;
const tokenPaths = [
join(homedir(), '.config', 'gitea', 'token'),
join(homedir(), '.aiwg', 'credentials', 'gitea'),
];
for (const p of tokenPaths) {
if (existsSync(p)) {
return (await readFile(p, 'utf-8')).trim();
}
}
return undefined;
}
/**
* Resolve the Gitea host
*/
function resolveGiteaHost() {
if (process.env.AIWG_GITEA_HOST)
return process.env.AIWG_GITEA_HOST;
return 'git.integrolabs.net';
}
/**
* GiteaAdapter
*
* Handles "owner/repo[@version]" shorthands for the configured Gitea host.
*/
export class GiteaAdapter extends GitAdapter {
id = 'gitea';
name = 'Gitea (shorthand)';
/**
* Matches "owner/repo" and "owner/repo@version" without a scheme prefix.
* Does not match "github:owner/repo" (handled by GitHubAdapter).
*/
canResolve(ref) {
if (ref.includes(':'))
return false; // has scheme prefix → not gitea shorthand
return GITEA_SHORTHAND.test(ref);
}
async resolve(ref) {
if (!ref.owner || !ref.name)
return null;
const host = resolveGiteaHost();
const token = await readGiteaToken();
let gitUrl;
if (token) {
// HTTPS with token
gitUrl = `https://${token}@${host}/${ref.owner}/${ref.name}.git`;
}
else {
// SSH (relies on SSH agent)
gitUrl = `git@${host}:${ref.owner}/${ref.name}.git`;
}
return {
gitUrl,
ref: ref.version,
label: `${host}/${ref.owner}/${ref.name}${ref.version ? `@${ref.version}` : ''}`,
};
}
async fetch(source, options = {}) {
return super.fetch(source, options);
}
}
//# sourceMappingURL=gitea.js.map