---
title: "Capabilities"
description: "How a provider declares which operations it supports, and how CI checks those claims."
canonical_url: "https://docs-oquac2tli-poetry.vercel.app/concepts/capabilities"
---
# Capabilities

> How a provider declares which operations it supports, and how CI checks those claims.

Forges don't offer the same features: Bitbucket has no releases, and Tangled has no checks. Every provider declares what it supports in `provider.capabilities`.

## Support levels

Each entry has one of four values:

<table>
<thead>
  <tr>
    <th>
      Value
    </th>
    
    <th>
      Meaning
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        true
      </code>
    </td>
    
    <td>
      Native and verified. A test exercises the operation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        'experimental'
      </code>
    </td>
    
    <td>
      Native, but not verified against a recording of the live forge, or built on an API that the forge marks unstable.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        'emulated'
      </code>
    </td>
    
    <td>
      Composed from other calls, so its behaviour can differ from a native operation.
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        false
      </code>
    </td>
    
    <td>
      Not available. Calling it rejects with <code>
        UnsupportedOperationError
      </code>
      
      .
    </td>
  </tr>
</tbody>
</table>

For example, Forgejo has no done state for notifications. Its `notifications.markDone` is `'emulated'`: it marks the notification read and unsubscribes from the thread.

## Per thread kind

Support can differ by thread kind. GitHub closes issues, pull requests and discussions, while Cursor Origin has pull requests only. Those entries are objects keyed by kind, and `can()` takes the kind as a second argument.

## Experimental providers

`capabilities.experimental` is `true` when the provider as a whole is experimental: its tests use hand-written fixtures only, or the forge's API is unstable. Gitee, Azure DevOps, Cursor Origin and pushin.eu are experimental providers.

## Version-dependent support

Some capabilities depend on the instance version. GitHub Enterprise Server supports marking notifications done from version 3.13. The provider computes capabilities without a network request, so pass `instanceVersion` if you know it, or call `refreshCapabilities()`.

## How CI enforces it

A provider can declare `true` only for an operation that a test calls. During `vitest run`, `test/setup/verbs.ts` records each verb a test calls. `pnpm test:capabilities` then runs `scripts/check-capabilities.ts`, which fails for any capability that a provider declares `true` and no test called.

Provider pages and the [capability matrix](https://docs-oquac2tli-poetry.vercel.app/reference/capability-matrix) are generated from the same declarations, and a unit test fails when they're out of date.

## Using capabilities

- Call [`provider.can()`](https://docs-oquac2tli-poetry.vercel.app/guides/capabilities) before an operation that a forge might lack.
- Use the matrix to decide which forges to support.
- Read the `limits` entry for the text limits of a forge, such as the maximum comment length.


## Sitemap

See the full [sitemap](https://docs-oquac2tli-poetry.vercel.app/sitemap.md) for all pages.
