Ania
Documentation

Run agents locally.
Guide them from anywhere.

Ania runs the terminal, coding worker, and supervisor on your machine while this website stores tasks, commands, events, and status for remote monitoring.

Get started

Connect your first workspace

You need Python 3.10+, Herdr, and an authenticated coding CLI such as Claude Code or Codex.

1Install the client

Run one installer on the machine that owns your workspace.

2Create a key

In the dashboard, create a User + runner key and save it when shown.

3Start a task

Run ania start from the repository you want Ania to use.

1. Install Herdr and Ania

gh api -H "Accept: application/vnd.github.raw+json" \
  repos/qywu/ania/contents/install.sh | sh

The repository is currently private, so first authenticate GitHub CLI with gh auth login. The installer uses no sudo, installs Herdr when needed, creates an isolated Ania environment under ~/.local/share/ania, and links the command into ~/.local/bin. Run the same command again to update.

2. Configure local credentials

Add these values to ~/.zshrc.secrets. The Ania API key authenticates the local client to this website. The Anthropic key stays on your machine and powers the default supervisor.

export ANIA_BASE_URL=https://ania.reasoningcats.com
export ANIA_API_KEY=ania_...
export ANTHROPIC_API_KEY=sk-ant-...
Use a User + runner key for ania start. That command registers the machine and creates a task, so it needs both scopes. A Full access key also works but grants unnecessary key-management permission.

3. Start from a workspace

cd ~/code/my-project
ania start improve-search

# Or include the initial requirements immediately:
ania start improve-search --task "Improve search relevance and verify the tests."

Ania uses the current directory, detects its Git origin when present, registers the machine, creates the task and a unique attempt, starts Herdr, launches Claude Code with Opus 5 and high thinking effort by default, and starts the background synchronization daemon. Codex defaults to GPT-5.6 Sol with high thinking effort. Choose the Solver CLI, model, and effort under Requirements → Agents; a running Solver keeps its current session and the new settings apply on its next launch or restart.

Mental model

Tasks are work; machines execute it

Task

The durable work request, including its chat, requirements, current status, and history.

Example: improve-search
Machine

The laptop, workstation, VM, or GPU host where Ania has local workspace access.

API name: runner
Attempt

One continuous interactive execution. It can work, pause, or sleep until a human explicitly stops it.

API name: run

The dashboard uses the familiar words machine and attempt. The API retains runner and run for protocol compatibility. One machine can execute many tasks over time, while renewable attempt leases prevent two machines from executing the same task concurrently.

Cross-task knowledge

Search outcomes from every attempt

The Results page searches structured attempt projections across task names, repository identities, public requirements, status summaries, sanitized Judge findings, and artifact metadata. Filter by repository or verdict, then copy the search URL or open a stable result link for its exact task, attempt, evidence, and timestamps.

Ania's Director can use state(action="search_results") to retrieve the same evidence when an earlier task may contain a useful decision, failure, benchmark, patch, or verification result. Search uses SQLite full-text indexing and returns durable citations rather than raw terminal captures. Hidden Judge rubrics and private tests are never indexed.

Search is restricted to the signed-in user's workspace. Results, repositories, runners, tasks, and stable URLs from another workspace are not visible. A Runner-only key continues to have no cross-task read access.
Shared context

Group tasks and reuse guidance by repository

When a workspace is a Git checkout, Ania uses origin when available and otherwise upstream. This keeps the repository that receives pushes and pull requests authoritative, including for fork checkouts. SSH and HTTPS remotes normalize to one stable identity, so tasks on different machines can share the same repository page. Monorepo tasks also retain their relative subdirectory.

Repository rules and skills are versioned on the website. A new attempt receives an immutable snapshot, so editing guidance never changes an attempt that is already running. Ania may propose a learned repository rule or skill, but a signed-in human must approve it on the repository page before it reaches future attempts. The task Status tab lists the origin and revision of effective requirements, repository policy, machine rules, and skills.

Machine rules are configured locally with ania machine-rules --set-file FILE. Their contents never leave the runner; the website receives only whether they are configured and a content revision. Skills use the explicit scopes task, repository, and machine.

Local security policy and checked-in repository instructions such as AGENTS.md remain authoritative. The machine reports remote identity, branch, commit, dirty state, relative subdirectory, and the workspace's absolute path, which the task page shows as the working directory. Source files, Git credentials, repository contents, and machine-rule contents stay on the machine.
Conversation

Chat is the primary task interface

Each task opens on its Chat tab. Messages support Markdown headings, lists, links, code blocks, tables, and images. Use Attach image to upload a PNG, JPEG, GIF, or WebP image up to 5 MB; the image is stored with the task and inserted into the message as Markdown.

When Ania verifies the requested work, it reports the outcome and puts the Director to sleep. The current attempt and Herdr terminals remain available, while the read-only Monitor continues watching. Any follow-up chat message forces the Director to wake in that same attempt; use Stop only when you want to end the attempt and close its terminals.

After the machine confirms the task is stopped, Delete task becomes available in the task header. It permanently removes the task's attempts, chat, commands, events, attached images, artifact metadata, and terminal-session records from Ania. It never deletes the repository workspace or its files.

Requirements have their own tab. Attempts, commands, events, and low-level identifiers live under History so they remain available for audit and troubleshooting without crowding normal interaction.

Status monitoring

An asynchronous Monitor watches; the Director acts

By default, a tool-free Claude Sonnet 5 Monitor runs with low thinking effort and checks changed Herdr terminal output about every 30 seconds. It receives a bounded capture from the Primary Solver and every task-owned Helper window; the independent Judge is excluded. Its provider request runs in a background lane, so it never blocks chat wakeups or the Director. Its current phase, summary, Solver state, model, timestamp, and escalation status appear in the live activity card at the top of Chat.

The Monitor has no tools and cannot type into any terminal. It detects frozen screens, cosmetically changing retry/poll patterns, and repeated summaries with no new concrete outcome. A suspected silent failure wakes the Director, which independently checks process state, durable logs, exit codes, and expected artifacts before intervening. Configure separate frozen-screen, repeated-pattern, semantic-no-progress, and similarity thresholds under Requirements → Agents. Provider credentials remain local, and raw captures are not uploaded.

Plan and independent evaluation

A live goal graph directs work; a second coding agent judges outcomes

Every task has a durable goal DAG. Parent links organize goals and subgoals into an outline, while dependency links determine which branches are ready and which are blocked. The Plan tab offers both outline and graph views, shows parallel-ready branches, and attaches execution todos, Herdr panes, external jobs, evidence, and Judge state to each goal.

The Director can refine this plan while work runs: it may add required discovered subgoals, change grouping or dependency links, and create or update execution todos. It cannot weaken existing requirements, make a required goal optional, delete a required outcome, introduce a cycle, or mark its own work passed. Every mutation is revision-checked and retained in append-only plan history. Long-running jobs can therefore wait in one branch while other non-conflicting ready branches proceed.

Every task has a Judge; it cannot be disabled. The Director invokes the Judge independently for each required goal, then invokes it once more without a goal for final integration. Completion requires fresh passing verdicts for every required goal and final integration. Completing every todo is useful execution evidence, but never passes a goal by itself.

The Judge runs as a separate Claude Code process by default, with Codex available as an alternative, asynchronously in its own Herdr terminal. It receives only the shared requirements plus the selected goal for a goal evaluation, or the shared requirements plus every goal for final integration. It inspects and tests a disposable snapshot containing the Solver's tracked, dirty, and untracked files; its probes cannot modify the Solver workspace. Open Terminal and switch among Solver, Judge, and Shell when direct inspection is useful.

Under Plan (the successor to Goals & requirements), an owner can manage goal structure, dependencies, public requirements, todos, and goal-specific hidden Judge material. Shared requirements, agent configuration, and final-integration Judge material live under Settings & requirements. The normal task API, command queue, Director, Solver, and Monitor receive only private evaluation revisions and fingerprints. When the Director invokes a Judge, the runner fetches only that invocation's private specification just in time, creates the files only in the disposable snapshot, and removes them after the verdict. Private paths and literal content are redacted from durable results.

The Judge returns a structured pass/fail verdict with checks, failures, limitations, the evaluated commit, and public/private requirement and workspace fingerprints. Editing an acceptance requirement invalidates its verdict plus final integration; a workspace change makes earlier snapshot verdicts stale at completion time. Goal progress and sanitized findings appear above Chat.

This is an agent-visibility boundary, not an operating-system secrecy boundary. An administrator with access to the server database, runner account, or live Judge terminal can inspect private evaluation material.
Collaboration

Share a direct link to live work

Tasks, attempts, machines, and major task tabs have stable dashboard URLs. Use Copy link or Copy section in the dashboard, or copy the browser address directly. A recipient must still sign in with an allowed Google account; sharing a URL never makes task data, uploaded images, or terminal access public. API-key secrets are never included in a link.

Interactive access

One task workspace, multiple visible Herdr windows

Each task reports its Herdr session, task workspace, named windows, nested panes, occupants, and lifecycle states in the Herdr session card. One protected Primary Solver owns implementation and integration. When bounded, non-conflicting help is useful, the Director creates named Helper shell, Claude Code, or Codex windows instead of asking the Primary Solver to use opaque background Task/Monitor jobs. Work needing overlapping ownership, its own branch or PR, or an independent lifecycle belongs in another task.

  • Open Open Solver or Open Helper on any reported pane to see its exact live screen and interact with it. Window and pane IDs are shown explicitly for troubleshooting.
  • Primary Solver remains the authoritative Claude Code or Codex pane; it cannot be closed through Helper-window controls.
  • Helper windows have one scoped purpose and do not compete with the Primary Solver.
  • Judge is the independent evaluator in its disposable snapshot, not a Helper.
  • Shell creates a separate temporary Bash/Zsh tab rooted in the task workspace and removes it when the web view closes.
  • The server receives only sanitized topology and lifecycle metadata. It does not receive terminal text, commands, process arguments, or workspace contents.
  • A valid Google browser session is required. Browser and runner derive an ephemeral P-256 shared key and exchange AES-GCM encrypted frames; Ania only relays ciphertext.
  • Only one web terminal may be active per runner. Closing it releases the controller without stopping the task or its agents.
Every opened pane has the runner user's local permissions. Keystrokes affect live processes, so treat the web terminal like direct local access.
Source code

The client is the Ania repository

The local client and agent harness are open source at github.com/qywu/ania. The website is monitoring and control; all terminal execution remains in the client.

Command line

Useful client commands

CommandPurpose
ania start NAMECreate and start a remotely monitored task in the current directory.
ania startRegister and run the machine daemon; bootstrap a first task only when none exists.
ania remote-status NAMERead the server-side desired and observed state.
ania status NAMEShow detailed local supervisor state.
ania peek NAMERead recent worker terminal output without attaching.
ania attach NAMEAttach to the live Herdr terminal.
ania say NAME "..."Ask a question or update requirements from the local CLI.
ania chat NAME --followFollow the human/agent conversation.
ania skills [NAME] [--task TASK]Inspect effective machine, repository-snapshot, and task skills with revisions.
ania promote-skill TASK SKILLPropose a learned skill for human-approved repository sharing.
ania machine-rules [--set-file FILE|--clear]Inspect or replace local administrator-owned machine rules.
ania pause|resume|stop NAMEChange local supervision state.
ania runner --onceForce one remote synchronization cycle.
Authentication

Choose the narrowest API-key scope

Send an API key in the HTTP Authorization: Bearer … header. Keys are shown once, stored only as hashes, and can be rotated or revoked from the dashboard. Every Google identity has a private Ania workspace; keys created while signed in belong only to that workspace.

Key typeUse it forAccess within your workspace
RunnerA dedicated, pre-provisioned runner daemonRegister one runner, heartbeat, receive commands, and upload events
API userScripts and integrationsRead and control your tasks and view your runners
User + runnerThe normal ania start workflowBoth task and runner APIs
Full accessTrusted workspace administration onlyAll APIs in your workspace, including creating, rotating, and revoking its keys
Treat a User + runner or Full access key like a password: it can read and control all data in its owner's Ania workspace. It cannot access another user's workspace or read local workspace files unless a runner explicitly uploads an allowed artifact.
HTTP API

Automate Ania with REST

All application endpoints are versioned under /api/v1. Use JSON request bodies and bearer authentication. See the interactive OpenAPI reference for generated schemas.

List tasks

curl "$ANIA_BASE_URL/api/v1/tasks" \
  -H "Authorization: Bearer $ANIA_API_KEY"

Search structured results

curl --get "$ANIA_BASE_URL/api/v1/search" \
  -H "Authorization: Bearer $ANIA_API_KEY" \
  --data-urlencode "q=Qwen3 parity router replay" \
  --data-urlencode "verdict=passed" \
  --data-urlencode "limit=10"

Create a task assigned to a registered runner

curl -X POST "$ANIA_BASE_URL/api/v1/tasks" \
  -H "Authorization: Bearer $ANIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "improve-search",
    "runner_id": "runner_...",
    "requirements": "Improve search relevance and run the tests.",
    "start": true
  }'

Send a message or change state

# Valid action types:
# start, pause, resume, stop, send_message, update_requirements, configure_agents
curl -X POST "$ANIA_BASE_URL/api/v1/tasks/$TASK_ID/actions" \
  -H "Authorization: Bearer $ANIA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"type":"send_message","payload":{"message":"Please run the full test suite."}}'

Delete a stopped task

The runner must have reported the task as stopped; a pending Stop request is rejected to avoid orphaning a live worker.

curl -X DELETE "$ANIA_BASE_URL/api/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $ANIA_API_KEY"

Endpoint summary

Method and pathScopePurpose
GET/healthPublicService health and version
GET/runnersUserList registered execution machines
POST/tasksUserCreate a task and optionally start its first run
GET/tasksUserList task projections
GET/tasks/{task_id}UserRead desired state, observed state, requirements, and status
GET/searchUserFull-text search structured results with repository, task, runner, status, verdict, and time filters
GET/results/{result_id}UserRead one stable attempt result and its evidence links
GET/tasks/{task_id}/resultsUserList structured results for every attempt of one task
DELETE/tasks/{task_id}UserPurge a runner-confirmed stopped task and its retained history; never delete workspace files
GET/PUT/tasks/{task_id}/evaluation-specUserRead or update the private, independently revisioned Judge rubric and test files
GET/POST/tasks/{task_id}/goalsUserList or create independently judged task goals
PUT/DELETE/tasks/{task_id}/goals/{goal_id}UserRevise, regroup, link dependencies, reorder, or remove a goal
POST/tasks/{task_id}/goals/{goal_id}/todosUserCreate an execution todo linked to a goal
PUT/DELETE/tasks/{task_id}/goals/{goal_id}/todos/{todo_id}UserUpdate ownership, state, evidence, or remove a todo
GET/tasks/{task_id}/plan-eventsUserRead append-only goal and todo mutation history
GET/PUT/tasks/{task_id}/goals/{goal_id}/evaluation-specUserRead or update that goal's hidden Judge rubric and private tests
GET/tasks/{task_id}/goals/{goal_id}/evaluationsUserRead the goal's durable Judge verdict history
GET/runners/{runner_id}/tasks/{task_id}/evaluation-contextBound runnerFetch the assigned task's private Judge context just before evaluation
GET/POST/runners/{runner_id}/tasks/{task_id}/plan[-actions]Bound runnerRead or safely refine the assigned task's goal DAG and todos
GET/repositoriesUserList normalized Git repositories and task/checkout counts
GET/repositories/{repository_id}UserRead repository tasks, safe checkout metadata, rules, and skills
PUT/repositories/{repository_id}/rulesUserUpdate versioned shared repository rules
POST/PUT/DELETE/repositories/{repository_id}/skills…UserManage versioned repository skills
POST/runners/{runner_id}/tasks/{task_id}/repository-proposalsBound runnerPropose a repository rule or skill without publishing it
POST/repositories/{repository_id}/proposals/{proposal_id}/decisionUserApprove or reject a runner proposal for future attempts
POST/tasks/{task_id}/actionsUserStart, pause, resume, stop, message, update requirements, or configure task agents
GET/tasks/{task_id}/runsUserList attempts for a task
GET/runs/{run_id}UserRead one execution attempt
POST/runs/{run_id}/actionsUserTarget an action at a specific active run
GET/tasks/{task_id}/eventsUserRead the durable event timeline; accepts limit
GET/tasks/{task_id}/commandsUserRead command and acknowledgement history
GET/tasks/{task_id}/chatUserRead human/agent messages
POST/tasks/{task_id}/chat-imagesUserUpload a validated task-chat image up to 5 MB
GET/chat-images/{image_id}UserRead an authenticated task-chat image
GET/tasks/{task_id}/artifactsUserList explicitly uploaded artifact metadata
GET/POST/DELETE/api-keys…AdminList, create, rotate, and revoke API keys
Runner protocol

Runner endpoints are normally client-managed

The Ania daemon prefers an outbound WebSocket at /api/v1/runners/{runner_id}/ws. It sends heartbeats and ordered event batches and receives structured commands. If WebSocket connectivity fails, it falls back to authenticated REST long polling.

Method and pathPurpose
POST/runners/registerRegister identity, name, version, capabilities, and capacity
POST/runners/{id}/heartbeatReport health, capacity, and active leases
GET/runners/{id}/commands?wait=25Long-poll pending commands
POST/runners/{id}/commands/{command_id}Acknowledge accepted, rejected, superseded, or completed status
POST/runners/{id}/eventsCommit an ordered event batch
WS/runners/{id}/wsLow-latency commands and web-terminal offers
GET/runners/{id}/terminal-sessionsREST fallback for pending terminal offers
WS/terminal-sessions/{id}/runnerRelay encrypted Herdr terminal frames

Runner keys bind to the first runner ID they register. Delivery is at least once: commands and events carry stable IDs, and both sides deduplicate them.

Privacy

Execution and secrets stay local

  • The server stores users, task definitions, normalized repository metadata, repository rules and skills, desired state, commands, events, chat, explicitly attached chat images, status projections, runner heartbeats, API-key metadata, and web-terminal audit metadata in SQLite.
  • Deleting a stopped task removes its server-side content and history. A content-free task ID, runner ID, and deletion timestamp remain as a protocol tombstone so a runner can safely retry a final event whose acknowledgement was lost.
  • The runner owns Herdr processes, terminal state, local verification, provider credentials, and its durable outbox.
  • The workspace owns source files, build outputs, shell tools, and secrets. The server cannot browse the repository; an authenticated web shell is created only inside the selected task workspace and its contents remain end-to-end encrypted.
  • Raw terminal captures and workspace files are not uploaded by default. Opt-in web-terminal contents are encrypted between browser and runner and are not persisted. Chat images require an explicit upload from the authenticated user; other artifacts require an explicit upload policy.
  • Set ANIA_ALLOWED_WORKSPACE_ROOTS to a comma-separated allowlist to restrict directories a runner may use.
Troubleshooting

Common checks

SymptomCheck
HTTP 401The key is missing, invalid, rotated, or revoked. Open a fresh shell after editing your secrets file.
HTTP 403The key lacks the required scope or a runner key is bound to a different runner ID.
Runner is offlineRun ania runner --once, then inspect local logs and network access to this HTTPS origin.
ania start cannot create a taskUse a User + runner key; a Runner-only key cannot call the task API.
Supervisor model errorConfirm ANTHROPIC_API_KEY is available in a fresh shell. Coding CLI authentication is separate.
Workspace rejectedEnsure the current directory is inside one of ANIA_ALLOWED_WORKSPACE_ROOTS.