Skip to main content

Continuous quality gate daemon for agent-driven Python development.

Project description

pulci

Continuous quality gate daemon for agent-driven Python development.

CI License Python 3.10+ Rust

v0.0.4 — Apache-2.0 — docs/AGENTS.md

Why

When AI coding agents (Claude Code, Cursor, Codex) iterate on a Python project, they invoke ruff check, ty check, pytest over and over. Pre-commit hooks run at commit time. CI runs even later. Nothing in the existing tooling stack was designed for the loop an agent actually runs: edit → check → edit, dozens to hundreds of times per hour.

pulci is a small daemon — Rust core, Python CLI — that runs your configured quality gates continuously as files change, and exposes the aggregated state as structured JSON. Agents stop re-invoking tools; they query state.

Comparison

Tool When it runs Output format Built for
pre-commit Commit time Human terminal Humans
prek Commit time (fast) Human terminal Humans
MegaLinter CI time Reports CI/CD
pytest-watch File change Human terminal Humans
pulci Iteration time Compiler-style + JSON Agents

pulci does not replace any of these. It fills the empty quadrant.

Demo

pulci watching a project for changes

MCP server

pulci ships an MCP server for Claude Desktop, Cursor, and any MCP-compatible host.

pulci mcp info          # prints the config block to paste into your host
pulci mcp               # starts the server (stdio)
pulci mcp /path/to/project  # explicit project root

pulci mcp info output (paste into claude_desktop_config.json or .cursor/mcp.json):

{
  "mcpServers": {
    "pulci": {
      "command": "/path/to/.venv/bin/pulci",
      "args": ["mcp"]
    }
  }
}

Once configured, the host exposes the pulci_status tool — agents call it instead of invoking ruff/ty/pytest directly.

For AI agents

AI coding agents (Claude Code, Cursor, Codex) should start at docs/AGENTS.md.

The short version: run pulci start once, then call pulci status --json after each edit instead of invoking ruff/ty/pytest directly.

Install

pip install pulci
pulci --version

From source (to modify the Rust core — requires Rust stable and uv):

git clone https://github.com/grego-casparri/pulci
cd pulci
uv sync
uv run maturin develop --release
uv run pulci --version

Usage

Start the daemon (runs in foreground; press Ctrl-C to stop):

pulci start                   # watches current directory, human output
pulci start /path/to/project  # explicit root
pulci start --agent           # suppress startup messages; structured exit events

Output — compiler-style diagnostics, one per line (same in both modes):

src/foo.py:12:1: error[ruff/F401] 'os' imported but unused
1 error, 0 warnings (3 files checked, 0.4s)

Query current state (reads .pulci/state.json):

pulci status                        # human-readable table
pulci status --json                 # full JSON for agents
pulci status /path/to/project --json

Sample pulci status --json output:

{
  "schema_version": 1,
  "state_version": 7,
  "timestamp": "2026-05-16T12:00:00Z",
  "summary": { "errors": 2, "warnings": 1, "checks_run": 3, "stale": false },
  "tools": [
    {"name": "ruff", "version": "0.7.4", "source": "local-venv", "path": ".venv/bin/ruff"},
    {"name": "ty",   "version": "0.0.3", "source": "uvx-latest", "path": null}
  ],
  "diagnostics": [
    {
      "tool": "ruff",
      "file": "src/foo.py",
      "line": 12,
      "col": 1,
      "severity": "error",
      "code": "F401",
      "message": "'os' imported but unused"
    }
  ]
}

Configuration

Create pulci.toml in the project root (all fields optional):

[hooks]
ruff         = true    # ruff check on changed .py files (default: true)
ruff_format  = false   # ruff format --check; format violations as diagnostics (default: false)
ty           = true    # ty check on changed .py files (default: true)
pytest       = false   # pytest on matching test files (default: false)
timeout_secs = 120     # per-hook subprocess timeout in seconds (default: 120)

# How pytest maps source → tests. Each template substitutes {stem} for the
# source's file stem. Empty (default) keeps `tests/test_{stem}.py` only.
pytest_test_patterns = [
    "tests/test_{stem}.py",
    "test/test_{stem}.py",
]

[tools]            # optional — pin exact versions for reproducibility
ruff   = "0.7.4"   # uses uvx ruff@0.7.4 instead of auto-resolving
ty     = "0.0.3"

[watch]            # optional — paths to skip from initial scan and events
exclude = ["vendor", "fixtures"]

If pulci.toml is absent, defaults apply (ruff=true, ty=true, pytest=false, ruff_format=false, timeout 120 s). Unknown keys fail at startup (typos like clipy are rejected loudly rather than silently ignored). If [tools] is absent, pulci resolves each tool automatically: .venv/bin/<tool>$PATHuvx <tool>. Pinned versions are probed at daemon startup, so a typo or unpublished version fails fast.

pulci watches .py files only (.rs is included for internal Rust dogfooding, not a user-facing feature). Non-Python files are ignored without notice.

Benchmark

A benchmark script is included to compare pulci against manual tool invocation and prek across N iterations:

uv run python benchmarks/bench_modes.py --iterations 50

Metrics: mean/p50/p95 latency per iteration, total wall time, estimated output tokens per iteration. pulci's compact state.json is a fixed-schema file; manual tool output grows linearly with the number of violations.

State file contract

.pulci/state.json is the primary contract between pulci and consumers. Schema version is 1 and will be bumped on breaking changes.

Contributing

See CONTRIBUTING.md.

License

Apache-2.0

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pulci-0.0.4.tar.gz (56.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

pulci-0.0.4-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl (1.3 MB view details)

Uploaded CPython 3.14macOS 10.12+ universal2 (ARM64, x86-64)macOS 10.12+ x86-64macOS 11.0+ ARM64

pulci-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (741.9 kB view details)

Uploaded CPython 3.13manylinux: glibc 2.17+ x86-64

pulci-0.0.4-cp312-cp312-win_amd64.whl (669.2 kB view details)

Uploaded CPython 3.12Windows x86-64

pulci-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl (1.3 MB view details)

Uploaded CPython 3.12musllinux: musl 1.2+ x86-64

pulci-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (742.4 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.17+ x86-64

pulci-0.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (742.6 kB view details)

Uploaded CPython 3.11manylinux: glibc 2.17+ x86-64

pulci-0.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (742.7 kB view details)

Uploaded CPython 3.10manylinux: glibc 2.17+ x86-64

File details

Details for the file pulci-0.0.4.tar.gz.

File metadata

  • Download URL: pulci-0.0.4.tar.gz
  • Upload date:
  • Size: 56.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pulci-0.0.4.tar.gz
Algorithm Hash digest
SHA256 521a6f5e550f94632fccd9f14d3e215d7d02f79f39d70b7a19cd515780d1164b
MD5 9943209f18a6bcb9e2801ca58aeb6888
BLAKE2b-256 c768a6d39a718604beae9f3677b27411895d3a1fed471f5f6c89c888ecd9ae45

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4.tar.gz:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl
Algorithm Hash digest
SHA256 3b2f6de5b9ea862ddc4aaf2d7179dbc685155ce80d085b7ef1de9014f345d7cc
MD5 3664120e77f488b3f1529c7e85a5bb21
BLAKE2b-256 ae3671222bd88ac807605876b3f0e868f28edf4961478bbdd25b7f4b8760d17f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp314-cp314-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 28e4274e576654934c8b5917327ee82f49d777fc673cbabf6375ce8e69cec6c1
MD5 29b5df26eddc096502c201aa8a704144
BLAKE2b-256 b8d7d08a249c868a1e136dd0f907243a7aed2a2edbfa74c75f70c9419e850af7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp312-cp312-win_amd64.whl.

File metadata

  • Download URL: pulci-0.0.4-cp312-cp312-win_amd64.whl
  • Upload date:
  • Size: 669.2 kB
  • Tags: CPython 3.12, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for pulci-0.0.4-cp312-cp312-win_amd64.whl
Algorithm Hash digest
SHA256 d3344be855c6cab4214c71aa958a56f345611267a14d7e404ee3cece59745b92
MD5 86a561fd6da6fc785cf91652ddfbd28e
BLAKE2b-256 8bee253440e34b630f2141f2cf2d5f90a4f44a392e22ab7aaa7c5aacdf971496

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp312-cp312-win_amd64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl
Algorithm Hash digest
SHA256 1d81c30e0793e510f0da0867ca9edad60accfbdb074efa8b6df07cecafc6dc73
MD5 a51b7ddc455d186387a9f9e8135b817e
BLAKE2b-256 2db694a6b1d0a61527f2f15011bdd7377ef4e3f0bb3b8aefaad0b2c9f862e6da

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp312-cp312-musllinux_1_2_x86_64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 7b475837ca29efab5c6e219741c54003de25d1d93af14fe59ba353287f68002e
MD5 01b555eb1bced1953acd981a904be469
BLAKE2b-256 bdfb3677e6bbd0eadcb8c8e0dc485c65406d605093618eb339b065c929ddc141

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 65bc89ab49e2cb8785d30ff4d108aba0a26d2fd73fd30ff5fb014ff919dce1de
MD5 0355e2df03c7fac6212a4036a0953111
BLAKE2b-256 55c1cefe4fc0de02399cf994a853e4c751ee558ea72deafff8f2472c4b6e28c3

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pulci-0.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.

File metadata

File hashes

Hashes for pulci-0.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
Algorithm Hash digest
SHA256 fcfd0310e895b7d28e7748ff0d2e2c27b78e4bb77124dad128677a35e30f6e2f
MD5 dc3808e21db4150697d14fc3789a42c2
BLAKE2b-256 ccebcde7effc8e6ed8c35390a14dff77279826c0b4e85e8edfbc8a27e1ad380b

See more details on using hashes here.

Provenance

The following attestation bundles were made for pulci-0.0.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl:

Publisher: release.yml on grego-casparri/pulci

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page