Reusable Python project scaffold with AI-agent tooling baked in: coding standards, shared agent memory, and an AI commit advisor — ready to clone as a starting point for new projects.
This repo uses Copier for templating — no gh
cli or manual remote-resetting needed.
Scaffold a new project (requires uv installed; uvx runs copier ephemerally):
uvx copier copy gh:giacolees/python-agent-template <new-project-dir>
cd <new-project-dir>
uv sync --all-groups
uv run pre-commit installCopier will prompt for your project name, slug, description, author, and Python
version, then generate a fully-personalised project from the template/ directory.
It also asks which optional components to include — each can be turned off:
- Agent memory system — the mem0-backed shared memory store (
memory/package,.agent-memory/, MCP server, extraction hook). - Compaction memory hooks — PreCompact session-insight extraction (requires the agent memory system).
- AI commit advisor — pre-commit hook that suggests commit messages.
- Agent rules — the binding
.agentrules/coding standards. - Release workflow — GitHub Actions workflow for automatic PyPI releases.
Keep a downstream repo up to date when this template ships new changes:
cd <existing-project-dir>
uvx copier updateCopier shows a diff of what changed and lets you resolve any conflicts — just
like a git merge.
Note
A .copier-answers.yml file is committed to each downstream repo. This is how
copier tracks the template version — do not gitignore it.
Either way, follow up with the Setup steps below, then add your
project code under src/.
src/<your_package>/— your application source code, includingconfig.py(typed settings loaded fromconfigs/).memory/— reusable agent-memory tooling (CLI + mem0-backed store) shared across projects.tests/— Pytest suite.configs/— YAML configuration (hyperparameters, thresholds, hardware targets).deployment/— Dockerfiles and Kubernetes manifests..agentrules/— coding standards binding for all agent-generated code (see Agent rules below)..agent-memory/— shared, git-tracked agent memory (see Shared agent memory below).data/— local data directory (gitignored; do not commit raw data).
uv sync --all-groups
uv run pre-commit installuv run ruff check . # lint, including naming conventions (pep8-naming)
uv run ruff format . # format
uv run mypy src memory tests # strict static type checking
uv run pytest # tests + coverageApplication settings (hardware target, example feature flags, paths) live in configs/*.yaml
and are loaded via <your_package>.config.load_config, never hardcoded in
source. See configs/default.yaml for the schema.
Rules in .agentrules/ are binding for all code, configs, and commits in
this repo — for humans and AI agents alike:
- CODING_STANDARDS.md — type hints, docstrings, no magic numbers, error handling, modularity.
- NAMING_CONVENTIONS.md — identifiers, test files, configs, deployment artifacts, branches and commits.
- COLLABORATION.md — branching, worktrees, commits, pull requests, code review, configuration & secrets, dependencies, testing, and working with AI agents.
A pre-commit hook (scripts/memory_extractor.sh) extracts durable
project knowledge from each commit's diff via the claude CLI and
appends it to .agent-memory/memories.jsonl, regenerating
.agent-memory/INDEX.md. CLAUDE.md points agents at that index so
shared knowledge is available at the start of every session. Query it
directly with:
uv run python -m memory recall "<query>"See .agentrules/COLLABORATION.md §9 for
details, including the SKIP_AGENT_MEMORY opt-out.
For a normal, non-shared session (solo exploration, debugging, a scratch branch), write live to a gitignored local store instead of waiting for a commit:
uv run python -m memory remember "<fact>" --commit pending --author <name> --localrecall always searches both the shared and local stores and merges the
results, so nothing written with --local is invisible to later recall
calls in the same checkout.
At each context compaction, a Claude Code PreCompact hook
(scripts/hooks/precompact_claude.sh) extracts up to five durable findings
from the session and stores them in the local memory store via
python -m memory remember-insights --local. Extraction is provider-neutral:
- Swap the extraction LLM with
AGENT_MEMORY_EXTRACTOR(defaultclaude; shipscodexandgeminidrivers underscripts/extractors/). Add a provider by dropping ascripts/extractors/<name>.shthat reads a prompt on stdin and prints one finding per line. - Other agent runtimes can use the same capability via the MCP server
(
.mcp.jsonregistersagent-memory, exposingremember_insightsandrecall). Wire a non-Claude runtime's compaction/session-end event toscripts/compaction_memory.sh(transcript text on stdin). - Opt out for a session with
SKIP_COMPACTION_MEMORY=1.
A pre-commit hook (scripts/commit_advisor.sh) calls the Claude Code CLI on
the staged diff before each commit. It is advisory only — it never blocks the
commit — and prints:
- Whether the change looks worth committing as-is (flags no-op/debug/ should-be-split diffs).
- A suggested commit message.
It skips silently if the claude CLI isn't installed, in CI ($CI set), or
if you set SKIP_AI_COMMIT_ADVISOR=1 for a given commit.
A workflow (.github/workflows/release.yml) watches every push to main.
When the version field in pyproject.toml changes, it tags the commit
v<version> and publishes a GitHub Release with auto-generated notes.
Validation is left to CI, which renders the template and runs the full
lint/type-check/test suite on every push to main, so the commit is
already green by the time the release runs. Pushes that don't change the
version are a no-op for this workflow.
To cut a release: bump version in pyproject.toml in a normal PR.
Merging that PR to main is what ships the release — there's no separate
manual step.