Skip to content

Releases: jesshart/croc

v0.9.0

17 Jun 16:40

Choose a tag to compare

Changed

  • croc hunt now follows crawl's mirrors: breadcrumb. A doc's
    mirrors: source (the file a crawl-generated stub shadows) is
    treated as an implicit tracked source, unioned with tracks:, so
    drift detection works on raw crawl output with no croc attack step
    and no stem resolution. This closes a gap where docs whose filename
    stem repeats across directories (always self.md / __init__.md,
    often ordinary repeats like models.py) could never be bound by
    attack's tree-wide stem index and so were invisible to hunt.
    Directory docs (self.md) mirror a directory and are skipped
    (file-mirrors only); a source that is both tracks:-bound and
    mirrors:-bound alerts once. On by default with no opt-out
    trees whose docs carry mirrors: may surface alerts they previously
    (silently) missed. The per-alert message is now
    "<doc>: bound source <path> changed". Mirror matching assumes
    crawl was run from the repo root (so the breadcrumb is repo-root-
    relative and lines up with git diff paths); anchoring subtree-
    crawled mirror paths to the repo root is a tracked follow-up.

v0.8.0

16 Jun 19:16

Choose a tag to compare

Changed

  • .croc.toml is now discovered by walking up from the doc-tree
    ROOT to the git repo root, so the repo-scoped trace/hunt config can
    live at the project root next to pyproject.toml instead of buried in
    the docs subtree. A tree-local .croc.toml at ROOT is still found
    first, so existing layouts keep working. Discovery is bounded by the
    git repo root; outside a git repo only the tree-local file is read.
  • Multiple doc trees per repo: a single .croc.toml can namespace
    per-tree config under [trees."<path>"] tables, keyed by each tree's
    path relative to the file. A per-tree table's trace/hunt/version
    override the top-level defaults for that tree; omitted fields inherit.
  • croc molt no longer touches .croc.toml. It previously stripped
    the version marker and deleted or rewrote the file; now it leaves the
    file byte-for-byte intact (yours to keep or remove) and only emits a
    NOTE that a tree-local one was left in place. The version marker is
    an inert management signal — nothing branches on its value.

Internal

  • Extracted the duplicated git_repo_root helper from attack/hunt
    into croc/gitutil.py; config is now the third caller. Removed the
    dead _molt_croc_toml strip helper.

v0.7.0

29 Apr 17:48

Choose a tag to compare

Added

  • croc bask <root> [-o OUT] [--rewrite-refs/--no-rewrite-refs] [--force] [--dry-run] [--strict-refs] — flatten a markdown tree
    into a single output directory. Every .md under root is emitted
    to OUT with its relative path encoded into the filename via __
    (dunder) joiners; non-md files are ignored. Markdown path-refs
    ([text](path.md)) in body text are rewritten to point at the
    flattened siblings by default, with anchors preserved; pass
    --no-rewrite-refs for a byte-for-byte raw export. Croc id-refs
    ([[id:X]]) are stable and pass through untouched. Output defaults
    to ./tmp/<root-name>-bask/, overridable with -o. Refs that
    escape the bask root or don't resolve to a .md in the input
    surface as SKIP-REF notes; pass --strict-refs to exit non-zero
    when any are present. Bask refuses to run when an input path
    segment already contains the __ joiner — surfaces every offender
    at once so the user renames them in one pass. Intended for one-way
    export to tools that don't traverse directories (LLM context
    loaders, embedding pipelines, dump-to-clipboard flows); there is
    no inverse operation. Honors the global --include-untracked flag.

v0.6.2

23 Apr 19:23

Choose a tag to compare

Changed

  • Lowered Python floor from 3.13 to 3.11. Nothing in the codebase
    actually needed 3.13; the only 3.12+ API in use
    (pathlib.Path.walk() in crawl.py) was swapped for a small
    os.walk adapter. tomllib in config.py pins the floor at 3.11.
    CI now runs the full test suite on 3.11, 3.12, and 3.13. No
    behavior change for existing users; new installs work on any of
    the three supported interpreters.

Install on any of:

  • Python 3.11 (default on Ubuntu 24.04, Debian 12 backports)
  • Python 3.12
  • Python 3.13

All 370 tests pass on all three interpreters locally; CI matrix
enforces that going forward.

v0.6.1

23 Apr 18:11

Choose a tag to compare

Fixed

  • Parser: documentation-about-syntax no longer parses as usage.
    [[id:X]] and [text](path.md) inside fenced code blocks
    (``` or ~~~), inline code (any matched backtick run), or
    backslash-escaped brackets/parens (`[`, `]`, `(`, `)`) are
    now treated as literal text by every ref-handling site — `check`,
    `init --adopt` (including the auto-filled `links:` and the MIGRATE-
    gate), `molt`, `rename-id`, and `refs`. Docs that teach croc's
    syntax no longer materialize spurious `to: X` frontmatter entries,
    trip `E-DANGLING` / `E-LIFETIME` / `E-IDENTITY`, or get their
    syntax examples rewritten on molt. A ref written as documentation
    survives the full adopt → molt round-trip byte-for-byte.

Release-process fix

Prior releases from v0.4.0 through v0.6.0 all have the literal
string "vX.Y.Z" as their GitHub Release body because the tag was
annotated with -m vX.Y.Z and gh release create --notes-from-tag
copies the tag annotation verbatim. The Makefile and README release
recipes now document the correct form: git tag -a vX.Y.Z -F notes.md
so the annotation carries real content.

v0.6.0

23 Apr 15:46

Choose a tag to compare

v0.6.0

v0.5.0

22 Apr 20:17

Choose a tag to compare

v0.5.0

v0.4.0

22 Apr 19:11

Choose a tag to compare

v0.4.0

v0.3.0

20 Apr 15:34

Choose a tag to compare

Added

  • croc crawl <src> — scaffold a plain-markdown doc tree from a source directory. One .md stub per file, one self.md per directory. Output carries only a mirrors: breadcrumb in frontmatter (no id / title / kind / links), making crawl output shape-compatible with the post-molt state — the adopt/molt cycle round-trips cleanly through crawl-produced files. Pass --adopt to fold in init --adopt and get a croc check-clean tree in one step.

    Default discovery mirrors every file git tracks (dot-dirs and __pycache__ are always pruned). Narrow by extension with --file-types .py --file-types .ts (repeat the flag for multiples; pass all for no filter). Honors .gitignore automatically when run inside a git repo. Re-running without --force skips existing files — idempotent.

    Subsumes the docure experiment; croc can now produce a starting tree in addition to managing one.

Fixed

  • .gitignore anchoring. The thoughts/ and docs/plans/ rules were unanchored, which meant they matched any directory of those names anywhere in the tree — silently hiding bundled example fixtures like examples/thoughts/ and examples/thoughts-from-code/thoughts/ from new commits. Both rules now carry leading slashes so they only apply at the repo root.

See CHANGELOG.md for the full history.

v0.2.0

18 Apr 01:23

Choose a tag to compare

Added

  • --strict-refs flag on init and molt. Exits non-zero when any SKIP / SKIP-REF / SKIP-MOLT-REF notes were emitted. Useful in CI / pre-commit where unresolvable refs should gate success. Default behavior unchanged: a plain init --adopt still exits 0 even with skips, preserving the adoption-must-land policy.

Changed

  • Summary line separates writes from skip notes. Previously init OK (164 actions) blurred 161 writes with 3 skip notes; now it reads init OK (161 actions, 3 skipped refs). Same change applied to molt and to dry-run summaries.

  • Skip notes re-echoed on stderr after the summary. An adopt run on a large tree was burying SKIP-REF lines under hundreds of AUGMENTs; by the time the summary printed, the skips had scrolled off-screen. They now re-appear in a bold-yellow stderr block as the last thing the user sees. Inline skip lines are also colored yellow so they stop blending into successful actions.

See CHANGELOG.md for the full history.