CURe PR review sandboxes powered by ChunkHound and configurable LLM presets
Project description
CURe
CURe ("Code Under Review") is a CLI for running pull request reviews inside isolated sandboxes, with ChunkHound-backed code search/research and a configurable review agent on top.
It is for two audiences:
- human operators who want a repeatable way to hand PR review work to agents without letting them mutate the source checkout
- agentic sessions that need a clear, reusable bootstrap contract for fresh or partially configured environments
If you are an agent, or you want to install CURe as a reusable skill, start with SKILL.md.
Quick Links
- Why CURe
- Install And First Review
- Example Flows
- Agent And Setup Notes
- Core Commands
- Secondary Standalone Install
- Advanced / Pre-Provisioned Environments
- Minimal Config
- Jira CLI
- Tests
Why CURe
Use CURe when you want to:
- review a GitHub PR from a disposable sandbox instead of the working repo
- standardize how humans and agents start, observe, resume, and clean review runs
- give an agent a single documented path from fresh install or existing local setup to "review in progress"
CURe is different from an ad-hoc manual agent review because the project checkout stays untouched, the review state stays on disk, and the workflow is resumable instead of prompt-by-prompt improvisation.
CURe is not for:
- ad-hoc in-place repo review where the agent should work directly in the project checkout
- environments that cannot install tools or authenticate the required external systems
Install And First Review
Persistent install:
uv tool install cureview
cure setup
cure install
cure doctor --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new
cure install reuses an existing chunkhound already on PATH by default. Pass --chunkhound-source release or --chunkhound-source git-main only when you want CURe to install or replace that binary explicitly.
Ephemeral agent run path:
uvx --from cureview cure setup
uvx --from cureview cure install
uvx --from cureview cure doctor --pr-url <PR_URL> --json
uvx --from cureview cure pr <PR_URL> --if-reviewed new
Compatibility alias: uvx --from cureview cure init still enters the same setup flow.
Keep the README focused on the landing page and first success. For the full agent bootstrap contract, including local setup inspection rules and operator handoff wording, use SKILL.md.
Example Flows
Example 1: clean public package install to first review
This is the primary public path and matches the package prove-out used for the first successful public release:
uv tool install cureview
cure setup
cure install
cure doctor --pr-url https://github.com/chunkhound/chunkhound/pull/220 --json
cure pr https://github.com/chunkhound/chunkhound/pull/220 --if-reviewed new
The v0.1.2 public release prove-out verified the package-first bootstrap flow in a clean temp-home install. cure setup is now the canonical command, and cure init remains a compatibility alias to the same bootstrap logic.
Example 2: ephemeral agent bootstrap from the one-sentence kickoff
Use the canonical agent run surface when the review happens inside a disposable sandbox or agent session:
tmp_root="$(mktemp -d)"
export XDG_CONFIG_HOME="$tmp_root/config"
export XDG_STATE_HOME="$tmp_root/state"
export XDG_CACHE_HOME="$tmp_root/cache"
uvx --from cureview cure setup
uvx --from cureview cure install
uvx --from cureview cure doctor --pr-url <PR_URL> --json
uvx --from cureview cure pr <PR_URL> --if-reviewed new
If CURe is already partially configured, inspect the active local setup before creating a fresh one:
- the active `cure.toml`
- the JSON file resolved from `[chunkhound].base_config_path`
- repo-root `chunkhound.json` and `.chunkhound.json` as ask-first ChunkHound setup hints
On a TTY, cure setup acts as the setup wizard, and cure init remains a compatibility alias. The wizard can keep the current configured base config, adopt a repo-root chunkhound.json / .chunkhound.json, accept an absolute custom base-config path, or generate the default CURe-managed base config. It also detects installed codex and claude executables, persists the sticky choice through default_preset, and can offer to run cure install before returning to the original command when chunkhound is still missing on PATH.
Example 3: what a finished review produces
A normal review run leaves behind resumable session state plus a review artifact with stable headings:
<session_dir>/
meta.json
review.md
**Summary**: ...
## Business / Product Assessment
### In Scope Issues
## Technical Assessment
### In Scope Issues
Review output uses two independent lenses:
- Business / Product Assessment uses product/ticket scope.
- Technical Assessment uses implementation scope.
Agent And Setup Notes
Ensure git, curl, and ca-certificates are present before bootstrap. Install uv if it is missing.
Use cure doctor --pr-url <PR_URL> --json as the source of truth for inspect-first setup. Its repo_local_chunkhound payload plus the repo-local-chunkhound check and executor-network advisory check surface the same setup hints in machine-readable and text forms.
If repo-local ChunkHound config exists, summarize what it contains and ask the operator whether it should be reused. Do not silently adopt it in this public contract.
Commands that actually require bootstrap now fail or repair earlier instead of surfacing late config or agent-selection errors. On a TTY, cure pr, cure resume, cure followup, cure cache prime, and cure interactive can enter the same setup wizard before side effects. On non-TTY runs, those commands fail fast and point back to cure setup plus cure doctor.
On an interactive cure pr cold start with no existing CURe-managed base cache for the selected baseline, CURe may also ask whether you already have a matching ChunkHound workspace/config for that exact repo. If validation passes, CURe hot-starts the managed base cache from that workspace before running the normal top-up index. Non-TTY runs skip this prompt and build the baseline cache normally.
That indexed ChunkHound-backed path is the default and recommended public review workflow.
cure doctor --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new
cure resume <session_id|PR_URL>
Once the first run is active, continue the same indexed session with cure resume <session_id|PR_URL>.
cure pr --no-index remains available only as an advanced opt-out for custom prompt flows that intentionally skip the built-in ChunkHound-backed prompts. It is not the normal or recommended path.
Built-in CLI-provider review runs use a staged CURe-managed ChunkHound helper rather than native agent MCP wiring. CURe exports that helper through CURE_CHUNKHOUND_HELPER; the built-in prompt/proof contract is successful "$CURE_CHUNKHOUND_HELPER" search ... and "$CURE_CHUNKHOUND_HELPER" research ... execution whose captured output contains the final JSON object for that call, even if preflight/progress lines appear before it, and helper research satisfies the code_research requirement. Plain chunkhound search, chunkhound research, and chunkhound mcp shell usage are not the built-in CLI-provider contract. Historical sessions may still report legacy mcp_tool_call evidence.
Helper-backed Codex runs also export PYTHONSAFEPATH=1 so a ChunkHound daemon started while reviewing the chunkhound repo does not import the checked-out repo package by accident. If helper preflight times out, inspect the persisted helper path plus daemon lock/log/runtime metadata in session status or meta.json before retrying.
Codex and Claude executor paths need internet / network access to obtain code-under-review context. In constrained agent sandboxes, treat that as an operator-visible prerequisite and ask for help instead of pretending CURe can always self-bootstrap from zero state. When cure doctor resolves Codex or Claude, look for the executor-network advisory check instead of claiming the sandbox already proved that prerequisite.
Claude-first explicit override example:
cure doctor --llm-preset claude-cli --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new --llm-preset claude-cli
If autodetect picks the wrong CLI provider, override it explicitly with --llm-preset claude-cli or --llm-preset codex-cli.
To persist the choice for future runs, use cure set-agent claude or cure set-agent codex. cure install also repairs missing bootstrap files plus the saved local-agent choice when it can do so deterministically.
Need the full bootstrap contract for agent sessions or existing local setups? Use SKILL.md.
Core Commands
Recommended indexed review loop:
cure doctor --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new
cure resume <session_id|PR_URL>
Initialize or repair non-secret bootstrap files:
cure setup
cure init remains available as a compatibility alias to cure setup.
Start a fresh review:
cure pr <PR_URL> --if-reviewed new
Check status:
cure status <session_id|PR_URL> --json
Watch a run:
cure watch <session_id|PR_URL>
Resume a session:
cure resume <session_id|PR_URL>
Synthesize a final review:
cure zip <PR_URL>
Clean up old sessions:
cure clean closed --json
cure clean <session_id>
Show the machine-readable command catalog:
cure commands --json
Secondary Standalone Install
The public package remains the default and recommended path:
uv tool install cureview
Use the standalone GitHub Release assets only when the package path is unavailable or inconvenient. The current secondary targets are:
- Linux x86_64
- macOS x86_64
- macOS arm64
Install the latest standalone release:
curl -fsSL https://raw.githubusercontent.com/grzegorznowak/CURe/main/install-cure.sh | sh
Pin a specific standalone release:
curl -fsSL https://raw.githubusercontent.com/grzegorznowak/CURe/main/install-cure.sh | sh -s -- --version v0.1.8
The installer downloads the matching release asset into ~/.local/bin/cure. After that, the bootstrap/readiness flow is unchanged:
cure init
cure install
cure doctor --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new
If your platform is not covered by the standalone assets, fall back to the package path instead of inventing a separate bootstrap recipe.
Advanced / Pre-Provisioned Environments
Persistent human install should use the public package:
uv tool install cureview
cure init
cure install
cure doctor --pr-url <PR_URL> --json
cure pr <PR_URL> --if-reviewed new
Teams that already manage a local CURe checkout can keep using that as a secondary local-development flow:
- keep CURe in a stable local path
- refresh it with
git -C <CURE_SOURCE> pull --ff-only - install it with
uv tool install /path/to/cure - keep any project-specific wrappers or config beside that checkout
If local CURe config already exists, inspect it before overwriting it:
- check the active
cure.toml - inspect the JSON resolved from
[chunkhound].base_config_path - treat repo-root
chunkhound.jsonor.chunkhound.jsonas setup hints to discuss with the operator, not inputs to silently adopt
Prefer cure doctor --pr-url <PR_URL> --json as the readiness summary after that inspection. It now reports repo_local_chunkhound plus the repo-local-chunkhound and executor-network checks so the operator does not need to infer those details from raw files alone.
When no explicit preset or config default is selected, CURe only autodetects between claude-cli and codex-cli from the high-confidence session markers it already understands. If autodetect picks the wrong CLI provider, override it explicitly with --llm-preset claude-cli or --llm-preset codex-cli.
Those details are secondary. The primary operator contract stays use <CURE_REPO_URL> to review <PR_URL>.
Example: use https://github.com/grzegorznowak/CURe to review https://github.com/chunkhound/chunkhound/pull/220. That sentence is the kickoff contract, not a promise that every sandbox can finish setup unattended. The operator should not need to provide a local checkout path. It should not do a manual review outside CURe.
For the full bootstrap contract around fresh installs, existing local setup, and operator handoff, use SKILL.md.
Minimal Config
Default config path:
~/.config/cure/cure.toml
By default cure init also writes:
~/.config/cure/chunkhound-base.json
If you need a disposable or non-default layout, set XDG_CONFIG_HOME, XDG_STATE_HOME, and XDG_CACHE_HOME before cure init, or pass --config, --sandbox-root, and --cache-root directly to cure init.
Minimal config written by cure init:
[paths]
sandbox_root = "/absolute/path/to/sandboxes"
cache_root = "/absolute/path/to/cache"
[review_intelligence]
[[review_intelligence.sources]]
name = "github"
mode = "auto"
[[review_intelligence.sources]]
name = "jira"
mode = "when-referenced"
[chunkhound]
base_config_path = "/absolute/path/to/chunkhound-base.json"
[multipass]
# strict = fail closed on invalid grounding
# warn = record findings and continue
# off = skip grounding validation
grounding_mode = "strict"
step_workers = 4
[llm]
# One execution effort now applies to plan, step, and synth.
reasoning_effort = "high"
On interactive cure pr runs, CURe can open a /dev/tty picker for the resolved CLI provider when model or execution reasoning_effort was not explicitly configured. Press Enter keeps the displayed defaults. Built-in defaults are now explicit: claude-cli uses claude-sonnet-4-6 with effort high, and codex-cli defaults to effort high.
When strict multipass grounding fails, CURe keeps the invalid artifact on disk and writes the validation details to work/grounding_report.json inside the session. Inspect the persisted state with cure status <session_id|PR_URL> --json or cure watch <session_id|PR_URL>, then rerun the same session with cure resume <session_id> or the narrower cure resume <session_id> --from steps / cure resume <session_id> --from synth. If you want fail-open behavior for future runs, set [multipass].grounding_mode = "warn".
If an embedding key is already present in the environment, cure init adds the matching embedding block and continues. If VOYAGE_API_KEY already exists, cure init writes the Voyage embedding model into the active ChunkHound base config and continues. Otherwise, if OPENAI_API_KEY already exists, cure init writes the OpenAI embedding model into the active ChunkHound base config and continues.
If no supported key is present, the agent should stop with the exact local config path, the minimal snippet to add, the required env var name, and the rerun command instead of improvising a manual review.
The structured review_intelligence source registry now feeds prompt guidance, session metadata, and cure doctor --json capability summaries. Only mode = "required" sources are preflighted before review generation; optional sources stay lazy and surface as available, unavailable, or unknown based on the runtime facts CURe already has.
Jira CLI
Use this only when the workflow actually needs Jira context. Normal public GitHub PR review flows do not require Jira.
For tenant setup, auth, jira init, JIRA_CONFIG_FILE, common queries, and troubleshooting, use the dedicated Jira reference.
If Jira context is required in a CURe session, keep auth local, prefer ~/.netrc for api.atlassian.com or a short-lived JIRA_API_TOKEN, and point CURe at a non-default Jira CLI config with JIRA_CONFIG_FILE when needed.
Tests
Fast local check:
./selftest.sh
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file cureview-0.3.3.tar.gz.
File metadata
- Download URL: cureview-0.3.3.tar.gz
- Upload date:
- Size: 267.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eaa07881c6c55bcfc6169a682072a1155a3fc0d0822386f361e0d2b9ec009f19
|
|
| MD5 |
0608d2aec78b677922fdeacd8dfd4182
|
|
| BLAKE2b-256 |
e3574f2b14eaecc6e8957c6aad9ea5b12291305c98720f5583ecb2fc7fb2bfb4
|
Provenance
The following attestation bundles were made for cureview-0.3.3.tar.gz:
Publisher:
publish-package.yml on grzegorznowak/CURe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cureview-0.3.3.tar.gz -
Subject digest:
eaa07881c6c55bcfc6169a682072a1155a3fc0d0822386f361e0d2b9ec009f19 - Sigstore transparency entry: 1262671727
- Sigstore integration time:
-
Permalink:
grzegorznowak/CURe@41d9e44f31d324449868f2c6ebda87aca3f76a40 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/grzegorznowak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-package.yml@41d9e44f31d324449868f2c6ebda87aca3f76a40 -
Trigger Event:
push
-
Statement type:
File details
Details for the file cureview-0.3.3-py3-none-any.whl.
File metadata
- Download URL: cureview-0.3.3-py3-none-any.whl
- Upload date:
- Size: 283.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
23e946313a89d8fee7704093c8f8c114d40a56547a58bf46f8ecec190e8cac69
|
|
| MD5 |
c9919c59d50cb54e4a382cd03576cbea
|
|
| BLAKE2b-256 |
9452306fb7b54286a375bbac83f02376651569513995efebbf688561622953fe
|
Provenance
The following attestation bundles were made for cureview-0.3.3-py3-none-any.whl:
Publisher:
publish-package.yml on grzegorznowak/CURe
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
cureview-0.3.3-py3-none-any.whl -
Subject digest:
23e946313a89d8fee7704093c8f8c114d40a56547a58bf46f8ecec190e8cac69 - Sigstore transparency entry: 1262671739
- Sigstore integration time:
-
Permalink:
grzegorznowak/CURe@41d9e44f31d324449868f2c6ebda87aca3f76a40 -
Branch / Tag:
refs/tags/v0.3.3 - Owner: https://github.com/grzegorznowak
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-package.yml@41d9e44f31d324449868f2c6ebda87aca3f76a40 -
Trigger Event:
push
-
Statement type: