Skip to main content

Snapshot a directory tree and diff what changed - no git required. Built for humans and agents.

Project description

tidemark

Snapshot a directory tree and diff exactly what changed - no git required.

A tidemark is the line a receding tide leaves behind, recording the level the water reached so you can see how things stood before. tidemark does the same for a directory: leave a mark, do anything, then see precisely what was added, modified, deleted, or renamed.

It scores 100/100 against The CLI Spec: structured output, schema introspection, clean stdout/stderr separation, non-interactive by default, idempotent operations, and bounded output. Excellent for humans at a terminal and for AI agents in a pipeline.

Why

"What did that command actually do to my files?" is a question without a good answer today. git needs a repo and pollutes the tree; fsdiff was archived; copy-based tools need two full copies. tidemark is a small, deterministic (BLAKE3) witness that answers it in one bounded call.

Install

cargo install tidemark
brew install rvben/tap/tidemark

Quick start

Human workflow with a labeled checkpoint:

tidemark snap before        # checkpoint the current tree
make install                # do the risky thing
tidemark diff before        # colored table of what changed

Agent / CI workflow with a portable manifest:

tidemark snap -o pre.tidemark        # write a manifest file (use - for stdout)
./run-some-tool
tidemark diff pre.tidemark @ --json  # bounded JSON delta in one call

Commands

Command Description
tidemark snap [LABEL] Snapshot the tree. LABEL stores it under .tidemark/; -o FILE writes a portable manifest (- = stdout).
tidemark diff [A] [B] Diff two refs. A ref is a label, a manifest file, or @ (current tree). tidemark diff before means before vs @.
tidemark list List stored snapshots. Also the default when no command is given.
tidemark show REF Print a manifest.
tidemark rm LABEL... --yes Delete stored snapshots.
tidemark init Create the .tidemark/ store in the current directory (idempotent).
tidemark schema Emit the clispec schema describing every command and output field.

Useful flags

  • snap: --path DIR, --ignore GLOB (repeatable), --hidden, --no-ignore, --no-content (smaller manifest, disables content diffs), --force (overwrite a label whose tree differs).
  • diff: --content (real unified line diffs for text files), --only added,modified,deleted,renamed, --exit-code.
  • Global (accepted on any command): --output json|table (defaults to JSON when piped, a table on a TTY), --json (shorthand for --output json), --quiet (suppress the stderr summary), --yes (confirm destructive ops), and the bounded-output flags --limit N, --offset N, --fields a,b for list and diff.

What counts as a change

Each entry records its BLAKE3 content hash, size, Unix mode, and symlink target. A file is modified when its content, mode, or symlink target changes. A rename is detected when a deletion and an addition share the same content hash and mode (and the pairing is unambiguous - duplicate-content files stay as plain add/delete). mtime is recorded for information but never triggers a change, so touch and rebuilds do not create false positives.

Small UTF-8 files (up to 256 KiB) also store their text inline so diff --content can show real before/after line diffs, even between two stored manifests. Pass --no-content to skip this.

Output

Snapshots of an unchanged tree produce an identical tree_digest - that is the idempotency signal. diff JSON is a flat object with summary counts and a bounded changes array; list uses the standard envelope:

{ "items": [ ... ], "total": 3, "limit": null, "offset": 0 }

Exit codes

  • Default: 0 success, 2 error.
  • With --exit-code (the diff(1) convention): 0 no changes, 1 changes found, 2 error.

Errors are written to stderr as {"error": {"kind": "...", "message": "...", "retryable": <bool>}}. Kinds: not_found, conflict, invalid_input, io (retryable), unsupported.

See AGENTS.md for the agent-focused contract.

Development

All CI steps are make targets, so the pipeline only runs make:

make check   # fmt-check + clippy (-D warnings) + tests + doctests
make score   # build release and score against clispec
make ci      # check + score

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

tidemark-0.1.1.tar.gz (41.1 kB view details)

Uploaded Source

Built Distributions

If you're not sure about the file name format, learn more about wheel file names.

tidemark-0.1.1-py3-none-win_amd64.whl (1.1 MB view details)

Uploaded Python 3Windows x86-64

tidemark-0.1.1-py3-none-manylinux_2_28_x86_64.whl (1.3 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ x86-64

tidemark-0.1.1-py3-none-manylinux_2_28_aarch64.whl (1.1 MB view details)

Uploaded Python 3manylinux: glibc 2.28+ ARM64

tidemark-0.1.1-py3-none-macosx_11_0_arm64.whl (1.1 MB view details)

Uploaded Python 3macOS 11.0+ ARM64

tidemark-0.1.1-py3-none-macosx_10_12_x86_64.whl (1.2 MB view details)

Uploaded Python 3macOS 10.12+ x86-64

File details

Details for the file tidemark-0.1.1.tar.gz.

File metadata

  • Download URL: tidemark-0.1.1.tar.gz
  • Upload date:
  • Size: 41.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for tidemark-0.1.1.tar.gz
Algorithm Hash digest
SHA256 de1bff98e578b78d261a790b080790bd05312f1a050468e013173caa7b4491c6
MD5 ed708f3ea0957b5fd8e62522db1445c5
BLAKE2b-256 82269059a327d9bd08b0377fe17f346be29f5c4bf3c203859d7c405b5420c168

See more details on using hashes here.

File details

Details for the file tidemark-0.1.1-py3-none-win_amd64.whl.

File metadata

  • Download URL: tidemark-0.1.1-py3-none-win_amd64.whl
  • Upload date:
  • Size: 1.1 MB
  • Tags: Python 3, Windows x86-64
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.3

File hashes

Hashes for tidemark-0.1.1-py3-none-win_amd64.whl
Algorithm Hash digest
SHA256 9948b4ed7959e538e9c5a1391b24fe6f6ab306e16d271c686ae1beb19a70555f
MD5 aff9ad87d0837d192035729c8db78e73
BLAKE2b-256 0bbb295f24b10caabfed18a7b3985b71e0392dd0c047c475e29cf0e03a915ff9

See more details on using hashes here.

File details

Details for the file tidemark-0.1.1-py3-none-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tidemark-0.1.1-py3-none-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 435ae6b7ecd64b9bb778031376073f6aa1099837582885c62c433577dcb8505a
MD5 bfb7bd36c5eed9481d2afb0cf573f491
BLAKE2b-256 165490e0c5270b49862c0851ec743084c2baf8fd93837888bb727ac8cd3ef5cb

See more details on using hashes here.

File details

Details for the file tidemark-0.1.1-py3-none-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for tidemark-0.1.1-py3-none-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 1fb3dace8066b3f2ecdaea952e75ce84756a6f988235cf04115eddfcab034be2
MD5 d37760add01d27a71829ca0bf99b9ae9
BLAKE2b-256 89dac44d360fdbbe1eb48c4db34ad5ff79e20ee7de9967d6f96ecf05fd4a9b1d

See more details on using hashes here.

File details

Details for the file tidemark-0.1.1-py3-none-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tidemark-0.1.1-py3-none-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 658a378fcba8a2c63d20c31e6e9a80fd0a7179911c67c464ef8709cc575c8d16
MD5 a5f3e62b04d4437c8942a6a66d26e1a1
BLAKE2b-256 d90265dcd3dda6c17f08be5a158b045172270f364c94289a3dcd8366b2229f69

See more details on using hashes here.

File details

Details for the file tidemark-0.1.1-py3-none-macosx_10_12_x86_64.whl.

File metadata

File hashes

Hashes for tidemark-0.1.1-py3-none-macosx_10_12_x86_64.whl
Algorithm Hash digest
SHA256 789fbabfeea5ab6ad38629c9b9f21493061d6f49db6573f386dc2b5eb80097d8
MD5 383f5fa55768f6813ad255d3711dea57
BLAKE2b-256 12b0dae7fc8da82d2195f0273eb1ad7763ef21bdcf0c0e7d6fccf4f4a69b149b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page