Skip to content
Hoody.com

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.

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.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope: the .hoody project layer / record cwd / tool+workflow cwd.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override selecting which on-disk .hoody install a stateless read/write resolves.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local). Rejected (400) on routes with no container dimension.
X-Hoody-RealmheaderstringNoPer-request realm selector: "global" or a 24-hex id. Rejected (400 realm_scope_unsupported) on active-only / no-realm routes.
realmquerystringNoPer-request realm selector — the in:query alias of the X-Hoody-Realm header.
Terminal window
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/auth/status
await client.agent.github.githubAuthStatus()
{
"status": "ok",
"authenticated": true,
"account": "octocat",
"host": "github.com"
}

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.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
tokenstringNoOptional PAT. When present the login validates and persists this token (no device flow); kept in env, never returned.
hoststringNoGitHub host for GitHub Enterprise (GHES); defaults to github.com. Must match the host on the subsequent poll call.
{
"host": "github.acme.internal"
}
Terminal window
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" }'
await client.agent.github.githubLogin({ host: "github.com" })
{
"device_code": "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
"user_code": "WDJB-MJHT",
"verification_uri": "https://github.com/login/device",
"interval": 5,
"expires_in": 900
}

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.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
device_codestringYesThe device_code returned by POST /github/auth/login.
hoststringNoThe GitHub host (default github.com); must match the start call.
intervalintegerNoThe poll interval (seconds) the start reply returned.
expires_inintegerNoThe device-code lifetime (seconds) the start reply returned.
{
"device_code": "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
"interval": 5,
"expires_in": 900,
"host": "github.com"
}
Terminal window
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" }'
await client.agent.github.githubLoginPoll({
device_code: "3584d83530557fdd1f46af18a1318c8f5a7d3b7a",
interval: 5,
expires_in: 900,
host: "github.com"
})
{
"key": "github.com:octocat",
"login": "octocat",
"host": "github.com"
}

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

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
Terminal window
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/repos
await client.agent.github.githubRepos()
{
"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 }
]
}

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

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
Terminal window
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/branches
await client.agent.github.githubBranches()
{
"status": "ok",
"branches": [
{ "name": "main", "sha": "a5c5b3d1c9f0e2a6b4d8c7e1f3a2b4c5d6e7f809" },
{ "name": "feature/login-flow", "sha": "b6d6c4e2d0a1f3b7c5e9d8f2a4b3c5d6e7f80901" }
]
}

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

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
Terminal window
curl https://{projectId}-{containerId}-agent-1.{server}.containers.hoody.icu/api/v1/agent/github/status
await client.agent.github.githubStatus()
{
"status": "ok",
"branch": "feature/login-flow",
"ahead": 2,
"behind": 0,
"files": [
{ "path": "src/login.ts", "state": "modified" },
{ "path": "README.md", "state": "untracked" }
]
}

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).

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
repostringNoThe 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_namestringNoCanonical "owner/name" (alternative to repo; used as-is when supplied). Requires clone_url.
clone_urlstringNoCanonical https clone URL (alternative to repo; re-validated against the active account host). Requires full_name.
dirstringNoOptional managed clone root override (clone_root); the traversal-safe parent/dest are derived under it.
shallowbooleanNoShallow clone (default true).
{
"repo": "octocat/hello-world",
"shallow": true
}
Terminal window
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 }'
await client.agent.github.githubClone({
repo: "octocat/hello-world",
shallow: true
})
{
"status": "ok",
"full_name": "octocat/hello-world",
"clone_url": "https://github.com/octocat/hello-world.git",
"dest": "/srv/clones/octocat/hello-world",
"shallow": true
}

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

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
messagestringYesThe commit message.
{
"message": "feat(login): wire up GitHub device-flow poll"
}
Terminal window
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" }'
await client.agent.github.githubCommit({
message: "feat(login): wire up GitHub device-flow poll"
})
{
"status": "ok",
"sha": "c1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8b9c0",
"branch": "feature/login-flow"
}

Runs fetchpullpush 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.

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
directionstringNoOptional: "pull" (fetch + pull) or "push" (push only). Default is the full fetchpullpush.
{
"direction": "pull"
}
Terminal window
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" }'
await client.agent.github.githubSync({ direction: "pull" })
{
"status": "ok",
"steps": [
{ "step": "fetch", "result": { "status": "ok" } },
{ "step": "pull", "result": { "status": "ok" } },
{ "step": "push", "result": { "status": "ok" } }
]
}

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

NameInTypeRequiredDescription
X-Hoody-CwdheaderstringNoPer-request working-directory scope.
X-Hoody-Config-DirheaderstringNoPer-request --config-dir override.
X-Hoody-ContainerheaderstringNoPer-request bound remote container (omitted = local).
X-Hoody-RealmheaderstringNoPer-request realm selector. Rejected (400 realm_scope_unsupported).
realmquerystringNoPer-request realm selector (in:query alias).
NameTypeRequiredDescription
titlestringYesThe PR title (required, non-empty).
bodystringNoThe PR description.
basestringNoOptional base branch (default the repo default).
{
"title": "Wire up GitHub device-flow login",
"body": "Adds the device-flow login and poll handlers, and a managed PAT path.",
"base": "main"
}
Terminal window
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" }'
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"
})
{
"status": "ok",
"number": 42,
"url": "https://github.com/octocat/hello-world/pull/42",
"html_url": "https://github.com/octocat/hello-world/pull/42"
}