# Agent: GitHub

**Page:** api/agent/github

[Download Raw Markdown](./api/agent/github.md)

---

{/* AUTO-GENERATED — Do not edit manually. Regenerate with: npm run docs:api:generate */}



The Agent: GitHub API exposes the daemon's GitHub tool surface: authentication (device flow or PAT), working-tree status, repo/branch listing, clone, commit, sync (fetch/pull/push), and pull-request creation. All routes are cwd-scoped (git is repo/cwd-relative) and not realm-scoped, so a per-request realm header is rejected with `400 realm_scope_unsupported`. Tokens live only in env and are never returned.


All endpoints share the same optional header/query scope parameters and the same base URL: `https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu`.


## Authentication

### `GET /api/v1/agent/github/auth/status`

Reports the GitHub authentication state (`github.auth.status`) from the account store. The token is only in env; it is never returned.

This route has no realm/container/cwd/config-dir dimension, so every per-request scope header returns `400 realm_scope_unsupported`.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope: the `.hoody` project layer / record cwd / tool+workflow cwd. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override selecting which on-disk `.hoody` install a stateless read/write resolves. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension. |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector: `"global"` or a 24-hex id. Rejected (`400 realm_scope_unsupported`) on active-only / no-realm routes. |
| `realm` | query | string | No | Per-request realm selector — the in:query alias of the `X-Hoody-Realm` header. |

#### cURL

```bash
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/auth/status
```

#### SDK

```ts
await client.agent.github.githubAuthStatus()
```

#### Response




```json
{
  "status": "ok",
  "authenticated": true,
  "account": "octocat",
  "host": "github.com"
}
```




```json
{
  "code": "realm_scope_unsupported",
  "message": "realm scope not supported on this route"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC, which has no realm dimension to scope. | Omit the realm header on this route, or open a session to scope by realm. |




```json
{
  "code": "forbidden",
  "message": "request must arrive through the Hoody proxy"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy (`hoody agent …`), not by connecting to the container directly. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded; the gateway throttled the request before dispatch. | Honor the `Retry-After` header and retry; reduce the request rate. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor `Retry-After` and retry. |




### `POST /api/v1/agent/github/auth/login`

Begins a GitHub login. With no body `token`, this starts a device flow and returns the non-secret `{device_code, user_code, verification_uri, interval, expires_in}`; the user authorizes that URL out of band, then `POST /github/auth/login/poll` completes the login. With a body `token` (a PAT), this validates and persists the token directly (no device flow), returning the linked `{login, host}`. For GitHub Enterprise (GHES), set body `host` (default `github.com`) on both the device-flow start and the PAT-add.


SECURITY: the token lives only in env / the validate call and is never returned.


#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `token` | string | No | Optional PAT. When present the login validates and persists this token (no device flow); kept in env, never returned. |
| `host` | string | No | GitHub host for GitHub Enterprise (GHES); defaults to `github.com`. Must match the host on the subsequent poll call. |

```json
{
  "host": "github.acme.internal"
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/auth/login \
  -H "Content-Type: application/json" \
  -d '{ "host": "github.com" }'
```

#### SDK

```ts
await client.agent.github.githubLogin({ host: "github.com" })
```

#### Response




```json
{
  "device_code": "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
  "user_code": "WDJB-MJHT",
  "verification_uri": "https://github.com/login/device",
  "interval": 5,
  "expires_in": 900
}
```




```json
{
  "code": "realm_scope_unsupported",
  "message": "realm scope not supported on this route"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route, or open a session to scope by realm. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | Forbidden — the request was refused by the server's admin gate. | Run the daemon with socket auth (`--auth-token-path`) and no separate admin capability so its own gate allows HTTP requests forwarded from the gateway. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy, not by connecting to the container directly. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap (`MaxBodyBytes`). The gateway rejects an oversized body at the edge before the handler reads it. | Reduce the request body below the configured limit (default 8 MiB); split a large payload into smaller requests. |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry; reduce the request rate. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request (too busy, or a per-client stream concurrency cap was hit). | Honor `Retry-After` and retry. |




### `POST /api/v1/agent/github/auth/login/poll`

Polls an in-flight GitHub device-flow login. Forward the `{device_code, interval, expires_in}` the start reply returned; the call blocks until the user authorizes (or the flow expires/cancels), then validates and persists the resulting token.


Required to complete a device-flow login over HTTP. SECURITY: the token lives only in env and is never returned; only the linked `{login, host}` is echoed.


#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `device_code` | string | Yes | The `device_code` returned by `POST /github/auth/login`. |
| `host` | string | No | The GitHub host (default `github.com`); must match the start call. |
| `interval` | integer | No | The poll interval (seconds) the start reply returned. |
| `expires_in` | integer | No | The device-code lifetime (seconds) the start reply returned. |

```json
{
  "device_code": "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
  "interval": 5,
  "expires_in": 900,
  "host": "github.com"
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/auth/login/poll \
  -H "Content-Type: application/json" \
  -d '{ "device_code": "3584d83530557fdd1f46af18a1318c8f5a7d3b7a", "interval": 5, "expires_in": 900, "host": "github.com" }'
```

#### SDK

```ts
await client.agent.github.githubLoginPoll({
  device_code: "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
  interval: 5,
  expires_in: 900,
  host: "github.com"
})
```

#### Response




```json
{
  "key": "github.com:octocat",
  "login": "octocat",
  "host": "github.com"
}
```




```json
{
  "code": "bad_request",
  "message": "invalid request"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | The request was refused by the server's admin gate. | Run the daemon with socket auth and no separate admin capability. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap. | Reduce the request body below the limit (default 8 MiB). |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




## Repository and branch reads

### `GET /api/v1/agent/github/repos`

Lists known/configured repos (`github.repo.list`). Returns the daemon reply verbatim (`{status, repos, account}`); not paginated.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### cURL

```bash
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/repos
```

#### SDK

```ts
await client.agent.github.githubRepos()
```

#### Response




```json
{
  "status": "ok",
  "account": "octocat",
  "repos": [
    { "full_name": "octocat/hello-world", "clone_url": "https://github.com/octocat/hello-world.git", "private": false },
    { "full_name": "octocat/spoon-knife", "clone_url": "https://github.com/octocat/spoon-knife.git", "private": true }
  ]
}
```




```json
{
  "code": "realm_scope_unsupported",
  "message": "realm scope not supported on this route"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a cwd-scoped RPC. | Omit the realm header on this route. |




```json
{
  "code": "forbidden",
  "message": "request must arrive through the Hoody proxy"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




### `GET /api/v1/agent/github/branches`

Lists branches for the requesting cwd's repo (`github.branch.list`). Returns `{status, branches}` verbatim; not paginated.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### cURL

```bash
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/branches
```

#### SDK

```ts
await client.agent.github.githubBranches()
```

#### Response




```json
{
  "status": "ok",
  "branches": [
    { "name": "main", "sha": "a5c5b3d1c9f0e2a6b4d8c7e1f3a2b4c5d6e7f809" },
    { "name": "feature/login-flow", "sha": "b6d6c4e2d0a1f3b7c5e9d8f2a4b3c5d6e7f80901" }
  ]
}
```




```json
{
  "code": "realm_scope_unsupported",
  "message": "realm scope not supported on this route"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a cwd-scoped RPC. | Omit the realm header on this route. |




```json
{
  "code": "forbidden",
  "message": "request must arrive through the Hoody proxy"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




### `GET /api/v1/agent/github/status`

Returns the git working-tree status (`github.status`) for the requesting cwd.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### cURL

```bash
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/status
```

#### SDK

```ts
await client.agent.github.githubStatus()
```

#### Response




```json
{
  "status": "ok",
  "branch": "feature/login-flow",
  "ahead": 2,
  "behind": 0,
  "files": [
    { "path": "src/login.ts", "state": "modified" },
    { "path": "README.md", "state": "untracked" }
  ]
}
```




```json
{
  "code": "realm_scope_unsupported",
  "message": "realm scope not supported on this route"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a cwd-scoped RPC. | Omit the realm header on this route. |




```json
{
  "code": "forbidden",
  "message": "request must arrive through the Hoody proxy"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




## Mutating endpoints


The endpoints in this section are destructive. They mutate the working tree, the local clone, or the remote repository.


### `POST /api/v1/agent/github/clone`

Clones a GitHub repository. The service translates `repo` (owner/name OR an https github URL) into the server-authoritative `{full_name, clone_url}`: the clone runs against the active account host (a URL whose host does not match is rejected), and the destination is derived traversal-safe under the managed clone root (`dir` overrides it).

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `repo` | string | No | The repository to clone: `"owner/name"` or an https github URL. Translated to `full_name` + `clone_url` against the active account host. Supply this OR the canonical `full_name` + `clone_url`; if both, the canonical fields win. |
| `full_name` | string | No | Canonical `"owner/name"` (alternative to `repo`; used as-is when supplied). Requires `clone_url`. |
| `clone_url` | string | No | Canonical https clone URL (alternative to `repo`; re-validated against the active account host). Requires `full_name`. |
| `dir` | string | No | Optional managed clone root override (`clone_root`); the traversal-safe parent/dest are derived under it. |
| `shallow` | boolean | No | Shallow clone (default `true`). |

```json
{
  "repo": "octocat/hello-world",
  "shallow": true
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/clone \
  -H "Content-Type: application/json" \
  -d '{ "repo": "octocat/hello-world", "shallow": true }'
```

#### SDK

```ts
await client.agent.github.githubClone({
  repo: "octocat/hello-world",
  shallow: true
})
```

#### Response




```json
{
  "status": "ok",
  "full_name": "octocat/hello-world",
  "clone_url": "https://github.com/octocat/hello-world.git",
  "dest": "/srv/clones/octocat/hello-world",
  "shallow": true
}
```




```json
{
  "code": "bad_request",
  "message": "invalid request"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters (for example, neither `repo` nor `full_name` + `clone_url` was supplied, or a `clone_url` host did not match the active account). | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | The request was refused by the server's admin gate. | Run the daemon with socket auth and no separate admin capability. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap. | Reduce the request body below the limit (default 8 MiB). |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




### `POST /api/v1/agent/github/commit`

Stages all changes and commits in the requesting cwd's repo. Destructive.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `message` | string | Yes | The commit message. |

```json
{
  "message": "feat(login): wire up GitHub device-flow poll"
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/commit \
  -H "Content-Type: application/json" \
  -d '{ "message": "feat(login): wire up GitHub device-flow poll" }'
```

#### SDK

```ts
await client.agent.github.githubCommit({
  message: "feat(login): wire up GitHub device-flow poll"
})
```

#### Response




```json
{
  "status": "ok",
  "sha": "c1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0",
  "branch": "feature/login-flow"
}
```




```json
{
  "code": "bad_request",
  "message": "invalid request"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters. | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | The request was refused by the server's admin gate. | Run the daemon with socket auth and no separate admin capability. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap. | Reduce the request body below the limit (default 8 MiB). |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




### `POST /api/v1/agent/github/sync`

Runs `fetch` → `pull` → `push` as one logical sync, stopping at the first non-ok step so a later push never runs against a half-synced tree. The body `direction` lets a caller pull-only (`fetch` + `pull`) or push-only; default is the full sync. This is body-only — there is no `?direction` alias.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `direction` | string | No | Optional: `"pull"` (`fetch` + `pull`) or `"push"` (push only). Default is the full `fetch` → `pull` → `push`. |

```json
{
  "direction": "pull"
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/sync \
  -H "Content-Type: application/json" \
  -d '{ "direction": "pull" }'
```

#### SDK

```ts
await client.agent.github.githubSync({ direction: "pull" })
```

#### Response




```json
{
  "status": "ok",
  "steps": [
    { "step": "fetch", "result": { "status": "ok" } },
    { "step": "pull", "result": { "status": "ok" } },
    { "step": "push", "result": { "status": "ok" } }
  ]
}
```




```json
{
  "code": "bad_request",
  "message": "invalid request"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters (for example, an unrecognized `direction`). | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | The request was refused by the server's admin gate. | Run the daemon with socket auth and no separate admin capability. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap. | Reduce the request body below the limit (default 8 MiB). |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "sync_step_failed",
  "message": "sync step failed",
  "details": {
    "failed_step": "push",
    "steps": [
      { "step": "fetch", "result": { "status": "ok" } },
      { "step": "pull", "result": { "status": "ok" } },
      { "step": "push", "result": { "status": "error", "message": "updates were rejected (non-fast-forward)" } }
    ]
  }
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `sync_step_failed` | Sync step failed | A downstream git/gh step (`fetch`/`pull`/`push`) failed after the sync was accepted; the steps that ran plus the failing one are returned under `details`. | Resolve the underlying git state (conflict / transport / auth) and retry the sync. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |




### `POST /api/v1/agent/github/pr`

Opens a pull request for the requesting cwd's repo. Destructive.

#### Parameters

| Name | In | Type | Required | Description |
|------|-----|------|----------|-------------|
| `X-Hoody-Cwd` | header | string | No | Per-request working-directory scope. |
| `X-Hoody-Config-Dir` | header | string | No | Per-request `--config-dir` override. |
| `X-Hoody-Container` | header | string | No | Per-request bound remote container (omitted = local). |
| `X-Hoody-Realm` | header | string | No | Per-request realm selector. Rejected (`400 realm_scope_unsupported`). |
| `realm` | query | string | No | Per-request realm selector (in:query alias). |

#### Request Body

| Name | Type | Required | Description |
|------|------|----------|-------------|
| `title` | string | Yes | The PR title (required, non-empty). |
| `body` | string | No | The PR description. |
| `base` | string | No | Optional base branch (default the repo default). |

```json
{
  "title": "Wire up GitHub device-flow login",
  "body": "Adds the device-flow login and poll handlers, and a managed PAT path.",
  "base": "main"
}
```

#### cURL

```bash
curl -X POST https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/pr \
  -H "Content-Type: application/json" \
  -d '{ "title": "Wire up GitHub device-flow login", "body": "Adds the device-flow login and poll handlers, and a managed PAT path.", "base": "main" }'
```

#### SDK

```ts
await client.agent.github.githubPullRequest({
  title: "Wire up GitHub device-flow login",
  body: "Adds the device-flow login and poll handlers, and a managed PAT path.",
  base: "main"
})
```

#### Response




```json
{
  "status": "ok",
  "number": 42,
  "url": "https://github.com/octocat/hello-world/pull/42",
  "html_url": "https://github.com/octocat/hello-world/pull/42"
}
```




```json
{
  "code": "bad_request",
  "message": "invalid request"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `bad_request` | Bad request | The request was malformed or carried invalid parameters (for example, an empty `title`). | Correct the request body or query parameters. |
| `realm_scope_unsupported` | Realm scope unsupported | A per-request realm header was supplied to a global-no-realm RPC. | Omit the realm header on this route. |




```json
{
  "code": "admin_unauthorized",
  "message": "memory administration requires a valid admin token"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `admin_unauthorized` | Rejected by the daemon's own admin gate | The request was refused by the server's admin gate. | Run the daemon with socket auth and no separate admin capability. |
| `forbidden` | Forbidden (not via the Hoody proxy) | The request did not reach the service through the public endpoint. | Reach the agent through hoody-proxy. |




```json
{
  "code": "not_found",
  "message": "resource not found"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `not_found` | Not found | The requested resource does not exist. | Verify the path and identifier. |




```json
{
  "code": "payload_too_large",
  "message": "request body exceeds the configured size limit"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `payload_too_large` | Payload too large | The request body exceeds the configured size cap. | Reduce the request body below the limit (default 8 MiB). |




```json
{
  "code": "rate_limited",
  "message": "request rate limit exceeded"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `rate_limited` | Too many requests | The per-client request rate limit was exceeded. | Honor `Retry-After` and retry. |




```json
{
  "code": "internal_error",
  "message": "internal server error"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `internal_error` | Internal error | An unexpected error occurred while handling the request. | Retry; if persistent, inspect the daemon logs. |




```json
{
  "code": "service_unavailable",
  "message": "service unavailable"
}
```

| Error Code | Title | Description | Resolution |
|------------|-------|-------------|------------|
| `service_unavailable` | Service unavailable | The daemon could not service the request. | Honor `Retry-After` and retry. |