Repositories & namespaces
The repo string format per provider, namespaces, and the normalized Repository type.
Every git provider organizes repositories differently — owners, groups, workspaces, projects.
repo-sdk reconciles this with two ideas: a repo string that addresses a single repository, and
a normalized Namespace that describes the containers repositories live in.
The repo string
Every call that targets a repository takes a repo string in the provider’s native path form. It is
passed through verbatim, so it always matches what you see in the provider’s own URLs.
| Provider | repo format |
Provider config |
|---|---|---|
| GitHub | owner/name |
— |
| GitLab | group/subgroup/project or numeric id |
— |
| Bitbucket | workspace/repo_slug |
— |
| Azure DevOps | project/repository |
organization (req.) |
| Gitea | owner/name |
— |
await client.repos.get({ repo: 'capawesome-team/repo-sdk' }); // GitHub
await client.repos.get({ repo: 'acme/backend/api' }); // GitLab subgroup
await client.repos.get({ repo: 'acme-workspace/api' }); // Bitbucket
await client.repos.get({ repo: 'Payments/checkout' }); // Azure DevOps (org set on the provider)
Namespaces
A Namespace is the normalized container a repository belongs to. Because providers use different words
for the same idea, the kind field tells you which one you’re looking at:
id?string
Provider id of the namespace.
stringslug?string
URL/path segment used in the repo string.
stringname?string
Human-readable display name.
stringkind?'user' | 'organization' | 'group' | 'workspace' | 'project'
The provider-native container type.
'user' | 'organization' | 'group' | 'workspace' | 'project'parent?string
Parent namespace slug, for nested groups.
stringavatarUrl?string
Avatar/logo URL, when the provider exposes one (not on Azure DevOps projects).
stringraw?unknown
The untouched provider payload.
unknownList them with namespaces.list / namespaces.listAll:
for await (const namespace of client.namespaces.listAll()) {
console.log(namespace.kind, namespace.slug);
}
The Repository type
repos.get and the repos.list family return the normalized Repository:
id?string
Provider id.
stringname?string
Repository name.
stringpath?string
Full path — the same string you pass as repo.
stringnamespace?string
Slug of the owning namespace.
stringdefaultBranch?string
Default branch, when available.
stringprivate?boolean
Whether the repository is private.
booleanarchived?boolean
Whether the repository is archived.
booleanurls?{ web, cloneHttp?, cloneSsh? }
Web and clone URLs. web is always present — constructed from the provider base URL when the API omits it; clone URLs when available.
{ web, cloneHttp?, cloneSsh? }raw?unknown
The untouched provider response.
unknownconst repo = await client.repos.get({ repo: 'capawesome-team/repo-sdk' });
repo.defaultBranch; // normalized
repo.urls.cloneHttp; // normalized
repo.raw; // original provider response — reach for provider-specific fields here
The raw escape hatch is present on every normalized object, so you never lose access to a
provider-specific field the normalized shape doesn’t cover.
Next: Pagination
Cursor pages and the listAll iterator.