magpie-vcs
Capability: contract:source-control
Kind: implementation
Vendor: Git
Runnable implementation of the source-control (VCS) capability
documented in
tools/github/source-control.md. It
extracts the abstraction the dev-loop skills assume — branch, stage,
commit, diff, log, fetch, push, working-tree reset — out of inline
git calls into one backend-dispatching CLI.
A skill (or a person) runs the abstract operation:
uv run --project tools/vcs magpie-vcs -C <upstream> diff --base main
uv run --project tools/vcs magpie-vcs -C <upstream> log --grep ISSUE-123
The active backend is detected from the working copy (or forced
with --backend / $MAGPIE_VCS), so the same command works whatever
VCS the project enables under Tools enabled → Source control.
Prerequisites
- Runtime: Python 3.11+ run via
uv; stdlib-only (no runtime dependencies). Thedevgroup pullspytest,ruff,mypy. - CLIs: Depends on the active backend — the tool shells out to the
underlying VCS binary.
gitfor the complete backend;hg/svnare detected but their bindings are not yet implemented. - Credentials / auth: None of its own; write operations (
fetch,push) inherit whatever auth the underlying VCS/remote needs. - Network: Local for read and local-write operations;
fetch/pushreach the project’s remote (e.g. GitHub) over the network.
Configuration
The active backend is detected from the working copy or forced with
--backend / $MAGPIE_VCS. Skills get the checkout path from
<project-config>/user.md (or the resolved user config) and the expected
source-control backend from <project-config>/project.md Tools enabled
entries. Backend-specific adopter knobs belong in the relevant
*-config.md file rather than in this tool.
Why
Before this tool the skills hard-coded git … inline. PR #609 added
the capability contract (source-control.md) and pointed each
git-using skill at it; this tool is the implementation of that
contract — the single place a non-Git VCS bridge plugs in, instead of
editing every skill.
The abstraction
VCSBackend is the abstract interface; each operation maps to the
What the skills require table in source-control.md:
| Operation | CLI | Read/Write |
|---|---|---|
| Detect backend | detect, backends, root |
read |
| Working-tree status | status, clean |
read |
| Current branch | branch |
read |
| Show changes | diff [--base REF] [--cached] [paths…] |
read |
| History read | log [-n N] [--grep P] [--author A] [--since S] [paths…] |
read |
| Create line of work | new-branch <name> |
write |
| Switch ref | switch <ref> |
write |
| Stage | stage <paths…> |
write |
| Commit | commit -m <msg> |
write |
| Sync from forge | fetch [remote] [ref] |
write |
| Publish | push [-u] <remote> <ref> |
write |
| Reset working copy | reset-worktree |
write |
Write operations stay gated on explicit user confirmation in the calling skill, exactly as the tracker write paths are — the tool does not add its own prompt.
Backends
| Backend | Status | Notes |
|---|---|---|
git |
complete | GitHub’s native VCS; the default binding |
hg (Mercurial) |
complete | Mercurial VCS support |
svn (Subversion) |
extension point | detected; centralized model (distributed = False) → #602 |
Detection is real for every backend (so magpie-vcs detect reports the
working copy’s VCS correctly); the non-Git/non-Hg backends raise an actionable
VCSError naming their tracking issue until the full binding lands.
Adding a backend
A VCS bridge (e.g. #602 Subversion) implements the full binding by
replacing that backend’s _UnimplementedBackend base with a concrete
VCSBackend subclass — detect(), the read operations, the write
operations — and nothing else changes: detection, dispatch, the CLI,
and every skill that calls magpie-vcs pick it up automatically.
How to use
# run the tests
uv run --project tools/vcs --group dev pytest
# in a skill / shell, against an upstream checkout
uv run --project tools/vcs magpie-vcs -C ~/code/foo detect
uv run --project tools/vcs magpie-vcs -C ~/code/foo status
Exit codes: 0 success, 1 for clean when the tree is dirty, 2
for any VCSError (unknown/unsupported backend, failed command).