A small spell for building Juju charms - an AI-powered charm development agent
Project description
Cantrip
A small spell for building Juju charms
⚠ Experimental, pre-1.0 software — run inside a VM only.
Cantrip is early, exploratory work. Interfaces, on-disk layouts, slash commands, tool surfaces, and defaults will change without notice, and there is no API or behavioural stability guarantee until 1.0. Treat it accordingly.
Cantrip is an autonomous agent: it executes shell commands, edits files, packs and deploys charms, and talks to Juju controllers and Kubernetes substrates on your behalf. Steps have been taken to keep it well-behaved — sandboxed tool execution, an allow-listed command surface, confirmation prompts for risky actions, scoped file access — but you should only run Cantrip inside a disposable virtual machine or dedicated test environment, never against production systems, personal home directories, or controllers you cannot afford to lose. Use a fresh VM, point it at a throwaway Juju model, and assume any mistake the agent makes can affect the entire machine it runs on.
Cantrip is an AI-powered autonomous agent that builds production-quality Juju charms independently. Describe your workload, and Cantrip researches it, designs the charm, writes the code, deploys it, tests it, and debugs it — with you confirming key decisions and providing domain expertise.
Quick start
- Just use Cantrip:
uv tool install juju-cantrip - Contribute to Cantrip: clone this repo and run
uv sync --dev
> build a charm for Redis
Researching Redis operational requirements...
✓ Design proposed — 4 integrations, 3 actions, backup/restore support
Waiting for your confirmation...
> looks good, go ahead
Planning tasks...
├─ ✓ Write integration tests (Jubilant)
├─ ✓ Scaffold charm with ops framework
├─ ✓ Implement charm code (red/green iteration)
├─ ✓ Pack and deploy to dev model
├─ ✓ Run acceptance tests (actions, relations, config)
├─ ✓ Wire COS observability
├─ ● Operational readiness assessment...
└─ Generate demo and docs
Status: active | 3 subagents working
Features
- Autonomous: Two concurrent loops — you steer, the agent drives. Subagents handle research, build, deploy, test, and debug tasks in parallel
- Research-driven: Analyses workloads via web search, Charmhub, and documentation before proposing a design with companion charms
- Test-first: Integration tests written before charm code; acceptance tests exercise every action, relation, config option, and endpoint
- Observable: COS integration baked in — traces, metrics, logs, and dashboards via ops-tracing, Prometheus, Loki, and Grafana; multi-controller COS auto-detected
- Improvement mode: Audit existing charms, modernise deprecated APIs, add tests, fill observability gaps, check operational readiness
- Day-2 aware: Researches backup/restore, scaling, HA, upgrades, and security hardening after initial build
- Quickpack: Ultra-fast local charm packing — 20-100x faster than
charmcraft pack, skipping LXD, linting, and analysis. Optional Rust backend with ~50 ms startup for tight build-test loops - Charm linting: Standalone
charmlinttool with 40+ deterministic rules across 12 categories. Optional Rust backend completes a full lint in under 30 ms - Durable memory: Persistent lessons across sessions and charms — user corrections are auto-captured as rules, hard-won workarounds become lessons with SHA-256 citations that self-quarantine when the source drifts. Manage with
/memory,/remember,/forget - MCP-extensible: Plug in third-party tools via the Model Context Protocol — stdio or HTTP servers, OAuth 2.1, token storage, mid-task elicitation, and marketplace discovery
- Ecosystem showcase: Juju, Charmcraft, Rockcraft, Ops, Jubilant, Concierge, Scenario, Showboat
Install to use Cantrip
# Install the CLI
uv tool install juju-cantrip
# Set your API key
export GEMINI_API_KEY='your-key-here'
# Run
cantrip
See docs/docs/howto-provider.html for
other provider setups (and how to make the env var persistent),
docs/docs/reference-cli.html#env-vars
for the full table of environment variables Cantrip reads, and
docs/docs/howto-interface.html
for choosing between the TUI, Web UI, CLI REPL, and print mode.
Contributor checkout
# Clone the repository
git clone https://github.com/tonyandrewmeyer/cantrip
cd cantrip
# Install dev dependencies
uv sync --dev
# Set your API key (see install section above, or howto-provider.html for other providers)
export GEMINI_API_KEY='your-key-here'
# Run
uv run cantrip
Usage
# Start the TUI in current directory
cantrip
# Start with a specific charm path
cantrip /path/to/my-charm
# Use the Web UI instead
cantrip --web
# Improve an existing charm (audit, fix, redeploy)
cantrip --improve /path/to/existing-charm
# Use Claude instead of Gemini
cantrip --provider claude
# Use a local inference snap (no API key needed)
cantrip --provider inference-snap --snap gemma3
# CLI mode (no TUI)
cantrip --no-tui
# Choose a colour theme
cantrip --theme ubuntu
# Export a session transcript
cantrip export-transcript /path/to/my-charm --format html --page-size 50
In the chat itself, slash commands let you drive persistent memory and inspect configured MCP servers without leaving the conversation:
/memory # list every remembered lesson
/remember lesson -- uv-lock-stale -- Run `uv lock` before charmcraft pack.
/forget uv-lock-stale
/mcp # list configured MCP servers and their status
/mcp tools charmhub # list tools a particular server exposes
/mcp marketplace # browse server catalogues you've subscribed to
See docs/docs/howto-memory.html and
docs/docs/howto-mcp.html for full
workflows.
Skills authored for the vendor-neutral ecosystem (Claude Code,
gh skill install, Cursor, Codex, Gemini CLI, Windsurf) work with
Cantrip unchanged — drop a standard SKILL.md into
~/.claude/skills/, ~/.config/agents/skills/, or
~/.config/cantrip/skills/, or install via GitHub CLI:
gh skill install microsoft/skills/harness-migration # project-scope, into <charm>/.agents/skills/
cantrip skill export NAME PATH writes any discovered skill back
out in the same format, sanitising charm paths and secrets. See
docs/docs/howto-skills.html.
Development
# Install dev dependencies
uv sync --dev
# Format, lint, and test
make all # format + lint + unit tests
# Or individually:
make format # ruff format
make lint # ruff check + ty type checker
make unit # pytest unit tests
make coverage # unit tests with coverage report
Documentation
- PLAN.md — Architecture decisions and design philosophy
- AGENT.md — Agent architecture (two-loop design, subagents, work queue)
- UI.md — Shared UI design (TUI + Web), event bus, layout, shortcuts
- ROADMAP.md — Implementation phases (active work); ROADMAP_ARCHIVE.md for completed phases
- CHANGELOG.md — Notable changes
Licence
Apache 2.0
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 juju_cantrip-0.2.3.tar.gz.
File metadata
- Download URL: juju_cantrip-0.2.3.tar.gz
- Upload date:
- Size: 8.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6b907e89b1562acc608561e8d385184f502618383670c74cb5e4c0a4b3efd0a3
|
|
| MD5 |
b99ac45fc5a6a86f135a1d40aa1732ab
|
|
| BLAKE2b-256 |
8a72a2ca8d2f970ce1eaa813f72a9ec61d377a69a42049365ffaa2bedba4ea37
|
Provenance
The following attestation bundles were made for juju_cantrip-0.2.3.tar.gz:
Publisher:
publish.yaml on tonyandrewmeyer/cantrip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juju_cantrip-0.2.3.tar.gz -
Subject digest:
6b907e89b1562acc608561e8d385184f502618383670c74cb5e4c0a4b3efd0a3 - Sigstore transparency entry: 1523873237
- Sigstore integration time:
-
Permalink:
tonyandrewmeyer/cantrip@9ddbd7bac6b10efc641e7f4857f3d43a7c4132c5 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/tonyandrewmeyer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@9ddbd7bac6b10efc641e7f4857f3d43a7c4132c5 -
Trigger Event:
push
-
Statement type:
File details
Details for the file juju_cantrip-0.2.3-py3-none-any.whl.
File metadata
- Download URL: juju_cantrip-0.2.3-py3-none-any.whl
- Upload date:
- Size: 1.4 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
254e6daeb8e26a2822b107bd4f16bd246b615ff66a4a322924f9b9864805663e
|
|
| MD5 |
09387ae6f4891ebfee46f52952339919
|
|
| BLAKE2b-256 |
f78b07ef2dcec403419634003782b3f16dede4e5d7597464c43a9f5413ebeb65
|
Provenance
The following attestation bundles were made for juju_cantrip-0.2.3-py3-none-any.whl:
Publisher:
publish.yaml on tonyandrewmeyer/cantrip
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
juju_cantrip-0.2.3-py3-none-any.whl -
Subject digest:
254e6daeb8e26a2822b107bd4f16bd246b615ff66a4a322924f9b9864805663e - Sigstore transparency entry: 1523873298
- Sigstore integration time:
-
Permalink:
tonyandrewmeyer/cantrip@9ddbd7bac6b10efc641e7f4857f3d43a7c4132c5 -
Branch / Tag:
refs/tags/v0.2.3 - Owner: https://github.com/tonyandrewmeyer
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@9ddbd7bac6b10efc641e7f4857f3d43a7c4132c5 -
Trigger Event:
push
-
Statement type: