Skip to content

Repositories

After this page you can give an agent a repository to work in, know exactly what authority that requires and who has to provide it, and know what your integration must store to keep working when an administrator changes their mind.

A session’s workspace comes from its source, set at creation and immutable afterwards. There are three shapes:

source Workspace
omitted An empty workspace. Useful for tasks that write from scratch.
{ "kind": "public", "url": "https://…", "label": "…" } A public HTTPS clone. No authorization needed, http:// is rejected, and the URL may not embed credentials.
{ "kind": "github", "grantId": "…", "baseBranch": "…" } A repository the organization has granted to your installation. baseBranch is optional and defaults to the repository’s default branch.

PATCH cannot change it. A different repository, or a different base branch, is a different session — which is the honest model, because the agent’s work is relative to what it started from.

Read back, a GitHub source reports what was actually pinned:

{
"source": {
"kind": "github",
"grantId": "b41d0e2a-1f7c-4d3e-9a10-8c5b2f0d7e64",
"label": "acme/invoices",
"private": true,
"baseBranch": "main",
"baseOid": "3d5c1f9e8a7b6c5d4e3f2a1b0c9d8e7f6a5b4c3d"
}
}

baseOid is the point. The base commit is resolved and recorded when the session is created, so main moving underneath you does not silently change what the agent was working from. Every later question — what did it change, what should be published, is this diff still reviewable — is answered against that pin.

A repository grant is a durable authorization created by a human administrator of the customer’s organization. It binds one repository to one app installation, and it names what may be done with it:

operations Meaning
["CHECKOUT"] The agent may read the repository into a workspace.
["CHECKOUT", "PUBLISH"] It may also push a branch and open a pull request.

Those are the only two shapes. There is no publish-without-checkout grant, and there is no way to widen a grant in place: a grant is immutable. Its lifecycle is two states.

active ──▶ revoked

Changing what an installation may do means creating a new grant and revoking the old one, which produces a new grantId. Three consequences shape how you store one:

  • Revocation is invisible as a field. A revoked grant is simply not returned anymore. There is no status to interpret; presence in a list is the status.
  • One active grant per installation and repository. You cannot hold two competing authorizations for the same repository at once.
  • A grant backing a session cannot be deleted out from under it. The reference is protected in storage, so an existing session keeps a coherent record of the authority it was created with.

A grant resource is small on purpose:

{
"id": "b41d0e2a-1f7c-4d3e-9a10-8c5b2f0d7e64",
"repository": { "fullName": "acme/invoices", "defaultBranch": "main", "private": true },
"operations": ["CHECKOUT", "PUBLISH"]
}

There is no endpoint that authorizes a repository, and this is deliberate rather than unfinished. Handing an agent write access to a private codebase is a decision a person with administrator rights makes, in a session they can see, on a surface they trust — not something a backend integration can arrange for them with a bearer token.

The flow your product plans for is therefore:

  1. An administrator connects their GitHub identity in the WAMP Cloud web app.
  2. They grant the specific repositories your installation may use, and choose whether publishing is included.
  3. Your backend reads the result and stores the grantId against whichever of your own records the work belongs to.

Plan for step 2 producing nothing: a customer who authorizes no repository can still use sessions with no source or with a public clone. Design the empty case as a normal state of your onboarding, not an error.

Reading grants back — and the honest caveat

Section titled “Reading grants back — and the honest caveat”

The model has two read operations, and together they are how a stored grantId stays healthy over time:

  • Discovery — list the grants currently active for the calling installation. Since revoked grants are absent, this doubles as a liveness check.
  • Replacement lookup — given a grantId you already hold, get the grant that now replaces it, or null if there is none. This is how a grantId stored on your tenant record heals after an administrator re-grants the repository, without you asking them to paste anything again.

What still works meanwhile is the discovery document. GET /v1/capabilities reports whether the calling installation holds any grant at all:

{
"capabilities": {
"repositories": {
"sources": [
{ "kind": "public_https", "available": true },
{
"kind": "github_repository_grant",
"available": true,
"discovery": "/v1/repository-grants"
}
]
}
}
}

available on github_repository_grant is true only when at least one grant is active for your installation, which is enough to decide whether to offer a repository-backed session in your own UI. It is false for a human-delegated credential, because grants are installation-scoped and there is nothing coherent to report for a person.

Terminal window
SESSION_ID=$(uuidgen | tr 'A-Z' 'a-z')
curl -sS -X PUT "$WAMP_API/v1/sessions/$SESSION_ID" \
-H "Authorization: Bearer $WAMP_TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"title": "T-142 · Invoice export",
"task": "Fix the CSV export rounding bug and add a regression test.",
"model": "<model-id-from-/v1/capabilities>",
"source": {
"kind": "github",
"grantId": "b41d0e2a-1f7c-4d3e-9a10-8c5b2f0d7e64",
"baseBranch": "main"
}
}'

The grant is checked for CHECKOUT at creation, against the live authorization rather than a cached copy. A grant that has been revoked, or that no longer matches the repository it was issued for, is 403 cloud_repository_grant_required at this call — before you have submitted any work.

The checkout itself happens later, when a turn causes a sandbox to be provisioned. You do not choose a path, a clone depth, or a remote name; those are not part of the contract.

Before publishing anything you read the review:

Terminal window
curl -sS "$WAMP_API/v1/sessions/$SESSION_ID/repository/review" \
-H "Authorization: Bearer $WAMP_TOKEN"
{ "review": { "revision": "5c1e…64 hex chars…", "files": [] } }

Two things to take from it:

  • revision is a 64-character hex digest of the working tree — a content revision, not a git commit id. It is the “I reviewed exactly this” token, and publishing requires you to pass it back. If the tree changes after you read it, the revision changes with it.
  • files describes the changed files. The contract leaves each entry open, so render what you recognize and do not assume a fixed set of keys.

Publishing that revision is Publications.

What you may assume, and what you must handle

Section titled “What you may assume, and what you must handle”

Assume. A session’s source and base commit never change. A grant never changes; only its presence does. A grant in use by a session stays referenceable. CHECKOUT is implied by any grant you can see; PUBLISH is not.

Handle. 403 cloud_repository_grant_required when authorization was revoked or narrowed between two of your calls — including between creating a session and publishing from it. A stored grantId that no longer appears anywhere, which means asking the administrator to grant again. Customers with no repository at all. And the read-path caveat above: your code should degrade to “ask a human”, not to a stuck queue.