This release is a pre-release and may not be stable for production use.
Curupira
Curupira (by Caipora Labs) is the product name. The PyPI project, primary console script, and Python import are curupira. The short command curu is the same entry point.
Curupira runs automations on your machine. It takes a GitHub issue or pull request, or a local cron occurrence, and hands it to a coding-agent CLI you already have.
Each automation in the settings TOML watches one source (issues, pull requests,
or a cron schedule) and carries its own prompt. All automations share one discovery,
scheduling, and execution pipeline: run drains currently available tasks, while
run --watch polls every automation continuously.
Requirements
- A supported platform wheel from PyPI (the CLI is a Rust binary; Python 3.11+ is used for packaging and optional official trigger extras)
ghinstalled and authenticated (gh auth login) when using GitHub automations- Only the CLIs used by the configured profiles need to be installed:
claude,codex, the Cursor CLI (agent),gemini, GitHub Copilot CLI (copilot),kilo,opencode,pi, orqwen
Installation
Install the Rust CLI from npm or PyPI. Both ship the same executable and use
~/.curupira/ for configuration and state. The npm install does not need Python.
npm install -g @caipora-labs/curupira
# or, without a global install:
npx @caipora-labs/curupira --help
# Python
uv tool install curupira
pip install curupira
Official triggers (curupira-plugins) and curupira-sdk are optional. Install them when
you need forge task sources:
pip install 'curupira[extensions]' # installs curupira-plugins (+ curupira-sdk)
pip install 'curupira[github]' # same package; forge-named extras are aliases
To pin a specific version, use uv tool install "curupira==X.Y.Z".
The project is caipora-labs/curupira.
curupira --version and the short alias curu --version report the installed version.
Task-source extensions (except built-in cron) are separate processes; coding agents are
built into the Rust CLI. See
Process extensions.
Documentation
See the full guide in Portuguese for installation, automation configuration, providers, and operational commands. Newcomers can start with the automations reference (triggers, minimal TOML examples, first-run commands, and common errors).
Configuration
The default settings file is ~/.curupira/settings.toml. Download the example
configuration directly to that location, then adjust repositories, paths, queries, and
prompts:
mkdir -p ~/.curupira
curl -fsSL https://raw.githubusercontent.com/caipora-labs/curupira/main/packages/curupira-core/curupira.example.toml \
-o ~/.curupira/settings.toml
The ~/.curupira directory is created automatically when the default file is first
loaded. Pass --config path/to/settings.toml to use a different file; relative workspace,
state, and automation paths are resolved from that file's directory.
[settings]
max_active_tasks = 1
workspace_dir = "~/.curupira/workspaces"
state_db_path = "~/.curupira/state.sqlite3"
log_level = "INFO"
# Optional OTLP/HTTP trace endpoint; omit it to disable telemetry.
# otlp_endpoint = "http://localhost:4318/v1/traces"
[settings.polling]
poll_interval_seconds = 30
batch_size = 100
cron_poll_interval_seconds = 1
[repositories.api]
remote = "https://github.com/acme/api.git"
# setup_script = "scripts/bootstrap.sh"
[agents.defaults]
profile = "opencode-default"
timezone = "UTC"
[agents.profiles.opencode-default]
provider = "opencode"
[automations.resolve-ready-issues]
trigger_type = "plugins-py/github-issues"
repository = "api"
repo = "acme/api"
labels = ["agent-ready"]
linked_pull_request = false
prompt = "Resolve issue ${issue_number}: ${issue_title}\n\n${issue_body}"
Automations
For a newcomer-oriented map of every built-in trigger (minimal TOML, placeholders, and first-run commands), see the automations reference.
[automations.<name>] is a keyed map; the map key is the automation ID and is carried
into every task identity. repository selects a [repositories.<alias>] checkout with a
full Git remote URL (and optional path / setup_script). trigger_type selects the
source:
"plugins-py/github-issues"/"plugins-py/github-pull-requests"— discover matching GitHub issues and pull requests; see the GitHub task source guide"plugins-py/github-project-items"— discover issues and pull requests in a GitHub Project board column (needs theread:projectscope)"cron"— produces occurrences fromscheduleinstead of querying a forge
Every automation requires repository and prompt. GitHub triggers also require
forge repo identity; cron requires schedule. Optional profile selects a named CLI profile;
otherwise the default profile applies. Relative paths resolve from the TOML directory.
Different repository aliases cannot share one workspace path. Automations keep file order,
and one-shot selection follows that order.
Providers and native options
Curupira supports these coding-agent CLIs, selected with provider in a profile:
- Claude Code (
claude) - Codex (
codex) - Cursor (
cursor) - Kilo CLI (
kilo) - Gemini CLI (
gemini) - GitHub Copilot CLI (
copilot) - OpenCode (
opencode) - pi (
pi) - Qwen Code (
qwen)
How model, effort, agent, and permission options map to each CLI's native
arguments is documented on the
Providers page.
Prompts and placeholders
Placeholders use ${name} syntax. The host provides ${repository} and
${automation}. Every other name is a key from the trigger result, substituted
as a string. A missing name is left unchanged. For dynamic prompts, Jinja syntax
({{ name }}, {% if %}, {% for %}) works next to ${name}; the keys of the
GitHub triggers are listed in the
GitHub task source guide.
Cron prompts receive only the host variables.
Discovery, concurrency, and cron semantics
GitHub discovery compiles typed filters into Search queries and runs them through GraphQL
with a token from gh auth token; see the
GitHub task source guide for filters,
deduplication, scopes, and prompt fields. Polls fetch up to batch_size items (default 100,
up to 1000). When a full cycle finds nothing, the shared poller waits
poll_interval_seconds (default 30s); consecutive empty cycles double the wait up to
5 minutes, and any discovery resets it. Each automation deduplicates its own items, so
two automations may process the same forge item with different prompts.
Other task sources can be added as trigger plugins registered under the
curupira.triggers entry-point group; see the
plugins guide.
max_active_tasks bounds concurrently running coding agents (default 1). By default,
each task runs in a new worktree beside its base checkout, so tasks for the same repository
can run concurrently without sharing edits. The worktree branch is created from the
fetched remote default branch and is not pushed. Set checkout = "main" to use the
shared checkout instead (this means the shared checkout, not a branch named main, and
restores the previous exclusive behavior). path continues to select the base checkout.
With checkout = "main", the agent runs on the shared checkout exactly as it is: Curupira does not fetch, pull, or switch branches there.
Checkouts are created on demand with git clone <remote> under
workspace_dir/<repository-alias> (or the alias path).
An optional setup_script on the repository alias is a repository-relative executable
path (no absolute paths or ..). It runs directly, with the checkout root as its working
directory, only when the base checkout has just been cloned. It does not run for an
existing checkout or in the task worktree. Use checkout = "main" when the agent must run
where setup wrote files. A nonzero setup exit prevents the agent from starting; the newly
cloned checkout is removed, while an existing checkout is preserved. validate checks the
path syntax but does not require the script to exist. run --dry-run does not fetch, clone,
create a worktree, or run setup.
Each cron automation coalesces overdue ticks into a single pending occurrence; the same
automation never runs concurrently with itself. schedule is a five-field cron
expression, timezone is IANA (defaulting to agents.defaults.timezone), and
start_date/end_date form an optional inclusive window interpreted in that timezone.
Without start_date, the window starts when the automation is first recorded.
OpenTelemetry
Set settings.otlp_endpoint to an OTLP/HTTP trace endpoint (for example,
http://localhost:4318/v1/traces) to export one span for each dispatched issue, pull
request, or cron occurrence. Each span includes the repository, type, identifier, and
result (success or failure); failures also include error.message. The endpoint must
accept OTLP over HTTP/protobuf. If the field is omitted, no telemetry is exported.
State files
Running sessions and cron schedule state live in state_db_path (default
~/.curupira/state.sqlite3). The per-user dispatch lock is stored in
~/.curupira/dispatch.lock, and the dedicated log directory is
~/.curupira/logs. Only one run or tui process can dispatch at a time; a second
process exits with an error rather than running tasks in parallel. Session records are
removed when the agent process ends; run and run --watch resume saved sessions after
a restart. If the file exists but is not a compatible database, the application exits with
an error instead of deleting it — delete or move the file yourself to start fresh.
Log file
The run and run --watch commands append records to
~/.curupira/logs/curupira.log; restarting the process does not erase existing
content. Each task records its start and completion time, repository, type, and
identifier. If a task fails, the record includes the error. Set
[settings].log_level (or pass --log-level) to DEBUG for more internal detail.
Uncaught crashes write separate reports under ~/.curupira/logs/crashes/.
Usage
Validate configuration without calling external CLIs or writing state:
curupira validate
Drain currently available tasks through the shared scheduler:
curupira run
curupira run --size 5
Preview one selected task without reserving, persisting, cloning, or executing:
curupira run --dry-run
Poll all automations with the shared bounded scheduler until interrupted:
curupira run --watch
Run the same continuous scheduler inside an interactive Textual dashboard:
curupira tui
The short alias curu accepts the same subcommands (curu validate, curu run,
curu run --watch, curu tui).
validate exits 0 when the configuration is valid and 2 on configuration errors.
run, run --watch, and tui exit 1 when any executed task failed, otherwise 0.
run --dry-run never reserves or persists cron occurrences and does not perform checkout,
worktree, or setup operations.
run --watch runs every CLI non-interactively so concurrent workers never contend for the
terminal UI. tui is the interactive alternative. Editing the configuration file while
either is running hot-reloads settings after in-flight tasks finish. Transient gh
failures are retried with backoff; authentication, configuration, output-format, and
agent-task failures are not retried automatically.
Public interface
Curupira is CLI-first. The only supported programmatic surface is
curupira.__version__; all other modules are internal implementation details that
may change without notice.
Development and validation
uv sync --dev
uv run --no-sync prek install
uv run --no-sync pytest
uv run --no-sync ruff check .
uv run --no-sync ruff format --check .
uv run --no-sync pyrefly check
uv build
uv run --no-sync twine check dist/*
uv sync installs the pure-Python package. uv run --no-sync prek install registers
Git pre-commit hooks; Ruff and Pyrefly run through uv so they use the locked project
environment. uv build produces a py3-none-any wheel and sdist with no compiler
toolchain required.
To inspect branch coverage locally, run uv run --no-sync pytest --cov --cov-report=term-missing;
the configured minimum is 85%.
See CONTRIBUTING.md for environment setup and the exact verification commands, and CHANGELOG.md for release notes.
License
MIT — see LICENSE.
Metadata
Release files for curupira 0.3.0.dev4
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| curupira-0.3.0.dev4.tar.gz | 83.1 kB | With provenance | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| curupira-0.3.0.dev4-py3-none-win_arm64.whl | Python 3 | none | Windows ARM64 | Details |
| curupira-0.3.0.dev4-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| curupira-0.3.0.dev4-py3-none-musllinux_1_2_x86_64.whl | Python 3 | none | Linux musl 1.2+ x86-64 | Details |
| curupira-0.3.0.dev4-py3-none-musllinux_1_2_aarch64.whl | Python 3 | none | Linux musl 1.2+ ARM64 | Details |
| curupira-0.3.0.dev4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl | Python 3 | none | Linux glibc 2.17+ x86-64 | Details |
| curupira-0.3.0.dev4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl | Python 3 | none | Linux glibc 2.17+ ARM64 | Details |
| curupira-0.3.0.dev4-py3-none-macosx_11_0_arm64.whl | Python 3 | none | macOS 11.0+ ARM64 | Details |
| curupira-0.3.0.dev4-py3-none-macosx_10_12_x86_64.whl | Python 3 | none | macOS 10.12+ x86-64 | Details |
Total release size: 50.2 MB
Release files / curupira-0.3.0.dev4.tar.gz
| Download URL | curupira-0.3.0.dev4.tar.gz |
|---|---|
| Size | 83.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
357b8324fddc3cf88a550b7245ee47a4e9bd3b4539ed9ebbbbbe589573c3c1c6
|
|
BLAKE2b-256 checksum How to use checksums |
b810fbea509933be4d8c0f98c57c239aaca58c52fe5b102a7312ca2d9126231b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-win_arm64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-win_arm64.whl |
|---|---|
| Size | 5.3 MB |
| Tags | Python 3 Windows ARM64 |
|
SHA-256 checksum How to use checksums |
2b741f1b8b390f0ec3b7758e3e0bb6761da635fb0c902c89a5a3a2e5eaf20475
|
|
BLAKE2b-256 checksum How to use checksums |
51d6a354caf7d2d56e7416127222a46b78cb0b72307f8b9ac4152373a752d8fa
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-win_amd64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-win_amd64.whl |
|---|---|
| Size | 5.8 MB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
3ca9e0e36fe7719694b1cf782a85d53303ae4ec223ce481bc04c2b3d8632f22c
|
|
BLAKE2b-256 checksum How to use checksums |
4ec252dbb2efbb1384015d162070b0fa2aa53130ffb14b3977a8ebc74bdef3ec
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-musllinux_1_2_x86_64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-musllinux_1_2_x86_64.whl |
|---|---|
| Size | 7.0 MB |
| Tags | Linux musl 1.2+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
0926f3e41317e630cb50447bd11f77659a636fd3596f1c95e6002a9c18a81f44
|
|
BLAKE2b-256 checksum How to use checksums |
5c9a9577e9d12047e8de6c16dcd60b41c754c2fc5b87fd86eaed244527d5cace
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-musllinux_1_2_aarch64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-musllinux_1_2_aarch64.whl |
|---|---|
| Size | 6.6 MB |
| Tags | Linux musl 1.2+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
5392425c895d5942e162066b819dd5b37e9524c59eae266ec068ca570c661e4e
|
|
BLAKE2b-256 checksum How to use checksums |
30e2f33aaef162bbac75d70baa2cd0a784d439065dc51c4098b9e935330695da
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl |
|---|---|
| Size | 6.7 MB |
| Tags | Linux glibc 2.17+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
8ce185d5dae604665260d636cf4717937c2f62d5440559b14672e6593380c979
|
|
BLAKE2b-256 checksum How to use checksums |
2afc0acaceba7d45c41ae3fc5191eba6ee6eafc64c7a4ea60a8e51ea8adac95d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl |
|---|---|
| Size | 6.6 MB |
| Tags | Linux glibc 2.17+ ARM64 Python 3 |
|
SHA-256 checksum How to use checksums |
b875b21c76868624068bf1f58e955a6948198bf2ae1fb6177081f7f5f579019b
|
|
BLAKE2b-256 checksum How to use checksums |
6455eebb848180544568c1a6ffb87d4455f366c53e816121dbd4c9cce39fff7b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-macosx_11_0_arm64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-macosx_11_0_arm64.whl |
|---|---|
| Size | 6.0 MB |
| Tags | Python 3 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
f63b73a3f6364a7ba64aec2d8b8347ece8e52dd373f82eb77adc176fdb35c4ec
|
|
BLAKE2b-256 checksum How to use checksums |
97b1ce1daeef834922760efd649fa90946eaf388a555a2e226b0b6b05794b495
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logRelease files / curupira-0.3.0.dev4-py3-none-macosx_10_12_x86_64.whl
| Download URL | curupira-0.3.0.dev4-py3-none-macosx_10_12_x86_64.whl |
|---|---|
| Size | 6.2 MB |
| Tags | Python 3 macOS 10.12+ x86-64 |
|
SHA-256 checksum How to use checksums |
abe651f80d40ceced69aad863ff28e702ec92998d10ee2ec4a5f189979fec170
|
|
BLAKE2b-256 checksum How to use checksums |
d733c96f4009f4ff972eeff51652e8ca7e05d3edafea8e700bcf35932a4400f7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logSecurity for curupira 0.3.0.dev4
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 9 files in this release have been uploaded with provenance metadata.
Attestation for curupira-0.3.0.dev4.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 18, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.