Skip to main content

cedit — continuous editing of vendored Markdown

Keep local adaptations of vendored Markdown alive across upstream updates: a persistent block-level overlay, re-applied by 3-way structural merge on the document's AST. Vendored a skill whose commands assume bash but your environment runs zsh? Rewrite the fences once — every later sync re-applies your rewrite over whatever upstream changed, and tells you precisely (per block, with all three versions) when upstream touched the same thing you did.

Documentation

Document What's in it
USERGUIDE.md How to drive it — a five-minute tour, a per-flag reference for all five subcommands, the conflict lifecycle worked end to end, the .cedit/ layout, a cookbook and a troubleshooting table
SPEC.md The design — the merge matrix, the normative sync algorithm, the state format, the reuse rules, and what is phase 1 vs. phase 2 vs. never
AGENTS.md Changing cedit itself — build and test commands, the architecture in one table, and the five invariants a change must not violate. CLAUDE.md exists only to pull this in, so every AI assistant reads the same file
.claude/rules/cedit-source-map.md The code, module by module — every function, dataclass field and constant, the end-to-end call graph from cli.main down to the splice, and where each invariant is actually enforced
.claude/rules/release-pipeline.md How this repo ships — the two tag shapes, the dev-build / cut / release flow end to end, who owns the version at each step, the five workflow invariants, and a failure-mode table

Using cedit? You want USERGUIDE.md. The last three are for working on it.

cedit grew out of the markdown-localization research repo, whose pinned parser and Merkle-hash diff engine are vendored — frozen — in cedit/mdcore/.

Install

pipx install cedit   # or: pip install cedit
cedit --help

That installs the cedit command and the importable package with the pinned parsing stack as real dependencies. The docs write cedit <subcommand> throughout; python3 -m cedit <subcommand> is the same entry point with the same arguments, and is what you want when cedit lives in a virtualenv you'd rather not activate.

Install cedit into an environment of its own — that's what pipx above buys you; a dedicated virtualenv does the same. mdcore/utils.make_parser appends every installed mdformat parser extension, so the set of mdformat plugins present in the environment is part of the parser identity. Dropping cedit into a shared environment that already carries other mdformat plugins can move the hashes in your .cedit/ state even though cedit's own pins are honoured — and moved hashes read as conflicts against blocks nobody touched.

Working on cedit itself

Developing cedit rather than using it? Work from a source checkout:

python3 -m venv venv
venv/bin/pip install -r requirements.txt   # the parsing stack is pinned EXACTLY — see the file
venv/bin/pip install -e .                  # optional: only to run cedit from another repo
venv/bin/python3 -m pytest                 # 27 tests, no network

Quickstart

Run from the root of the repository holding your vendored copies — a different repo than this one. State lives in .cedit/ (commit it — the base snapshots are the merge's memory).

# 1. start tracking (vendors the file if it doesn't exist yet)
cedit snapshot skills/SKILL.md --from vendor/skills/SKILL.md

# 2. adapt the file in place — e.g. rewrite bash fences for zsh — then:
cedit diff
# [edit opaque fence] #c564262de9cbba0f:0  sim=0.98
#     ctx  : 1. Discovery and healthcheck
#     base : bash "${CLAUDE_PLUGIN_ROOT}/.../ensure_local_env.sh" || exit 1
#     local: zsh "${CLAUDE_PLUGIN_ROOT}/.../ensure_local_env.sh" || exit 1

# 3. upstream evolved — merge it in (your edits re-apply, even across moves
#    and reflows; upstream changes to blocks you didn't touch flow in)
cedit sync --from vendor
# skills/SKILL.md: 1 edit(s) reapplied, 1 block(s) updated from upstream, 1 conflict(s)
# [CONFLICT opaque fence] #c564262de9cbba0f:0
#     base    : bash ".../ensure_local_env.sh" || exit 1
#     upstream: bash ".../ensure_local_env.sh" --quiet || exit 1
#     local   : zsh ".../ensure_local_env.sh" || exit 1  (kept in the working file)

# 4. a conflict means upstream changed the very block you adapted — decide:
cedit resolve skills/SKILL.md c564262de9cbba0f --show           # all three versions
cedit resolve skills/SKILL.md c564262de9cbba0f --take local    # keep the adaptation
cedit resolve skills/SKILL.md c564262de9cbba0f --take upstream # take upstream's text

cedit status
# skills/SKILL.md: 2 local edit(s), 0 unresolved conflict(s); base 92b023942934d656 ...

Exit codes: 0 clean, 1 unresolved conflicts, 2 errors. A document with open conflicts refuses to sync again until they're resolved, and the working file always keeps your text on a conflict — resolution is explicit, never a silent clobber.

Everything above in depth — every flag, every output line, the conflict lifecycle end to end, the .cedit/ layout and a troubleshooting table — is in USERGUIDE.md.

What it will not do (yet)

  • Local structural changes — inserting, deleting or moving whole blocks — are detected and rejected with a per-block report (phase 2 in the spec). Phase 1 merges replacements: prose rewrites, fence rewrites, table-cell tweaks, front-matter edits.
  • Fetching upstream. --from takes a directory (mirroring your doc paths) or a file; git submodules, subtrees or curl are your transport.

Layout

Path
cedit/__main__.py the python3 -m cedit entry point
cedit/cli.py the five subcommands: snapshot / diff / sync / status / resolve
cedit/merge3.py the 3-way merge matrix + overlay derivation
cedit/align.py block-sequence alignment (LCS over Merkle hashes, moves, fuzzy)
cedit/blocks.py block extraction, splicing, render-and-verify
cedit/state.py .cedit/ — base snapshots, manifest (+ conflicts), overlay
cedit/store.py atomic writes: temp file + rename(2), so a crash never leaves half-written state
cedit/mdcore/ vendored, frozen: pinned parser + tree_diff from markdown-localization
tests/ merge matrix + end-to-end CLI lifecycle + packaging metadata
pyproject.toml packaging metadata: the exact runtime pins, the cedit console script, explicit package discovery

Metadata

Release files for cedit 0.1.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for cedit 0.1.3
File Size Uploaded
cedit-0.1.3.tar.gz 34.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cedit 0.1.3
File Interpreter ABI Platform
cedit-0.1.3-py3-none-any.whl Python 3 none any Details

Total release size: 65.4 kB

Release files / cedit-0.1.3.tar.gz

Download URL cedit-0.1.3.tar.gz
Size 34.8 kB
Tags Source
SHA-256 checksum
How to use checksums
7f3784288129caad125243228e9772d3a47862cf2c3eeaf0fc9322664fd19f99
BLAKE2b-256 checksum
How to use checksums
f46ea554ecabfd9898890fca174c5a1f777d66ab8fc62d449553e6b0e729b80d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release files / cedit-0.1.3-py3-none-any.whl

Download URL cedit-0.1.3-py3-none-any.whl
Size 30.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
94b08080b5d64e69cf0c3e92773cd2f2ee345465dabedec07d062ca9a0a4897d
BLAKE2b-256 checksum
How to use checksums
8d8321ba53f5bfe3019059e4ace4ef5873b23e61f661e85cc732bfd7c082f113
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 5, 2026.

Transparency log

Release history Release notifications | RSS feed

0.3.6

2 release files

0.3.5

2 release files

0.3.4

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.6

2 release files

This release

0.1.3 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page