Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to `diffs-rs` are recorded here. The forked crates in
`crates/` keep their own changelogs.

## 0.1.1 - unreleased

- docs: new README, docs moved under docs/.

## 0.1.0 - 2026-10-27

First release.

- `diffs` viewer for Git patches (file or stdin), two files, or two Git commits.
- Split and unified layouts, wrapping, dark and light themes, and a changed-file sidebar.
- Syntax colors from complete old and new sources for file and commit comparisons, with
incremental context expansion.
- Literal search, source-line selection, save of original bytes, and clipboard copy on macOS.
- `diffs_rs::engine::Engine` for embedding the viewer in a Ratatui application.
43 changes: 43 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Contributing

Bug reports and pull requests are welcome at
[plannotator/diffs-rs](https://github.com/plannotator/diffs-rs).

## Build and test

The tests need Rust 1.88 or newer, Git 2.50 or newer, Python 3.11 or newer, `shasum`, and a
Unix PTY. Many of them run the real `diffs` binary against files, pipes, keys, and signals.

```sh
cargo fmt --check
cargo clippy --locked --all-targets -- -D warnings
cargo clippy --locked --all-targets --all-features -- -D warnings
cargo test --release --locked -- --test-threads=1
```

CI runs the same commands on Linux and macOS, plus a `cargo check` with Rust 1.88.

The embedded-host checks need the example binary:

```sh
cargo build --release --locked --example embedded_viewer
NATIVE_DIFF_HOST_BINARY="$PWD/target/release/examples/embedded_viewer" \
cargo test --release --locked --test process engine_host_contract -- --ignored --test-threads=1
```

Build instrumented features (`--all-features`) in a separate target directory so they do not
replace the normal binary.

## Repository layout

- `src/`: the library (`diffs_rs`) and the `diffs` binary.
- `crates/`: forks of syntect, fancy-regex, and two-face. Record any change to a fork in its
`PATCHES.md`.
- `tests/`, `fixtures/`: unit, process, and rendering tests and their inputs.
- `tools/`: Python scripts for the large-patch measurements in
[docs/measurements](docs/measurements/README.md). They are not needed for normal development.
- `docs/`: user guides, design notes, and the measurement and development records.

## Commits

Use lowercase conventional commit subjects, for example `fix: keep the cursor on resize`.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 3 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "diffs-rs"
version = "0.1.0"
version = "0.1.1"
edition = "2024"
rust-version = "1.88"
description = "Fast terminal diff viewer and embeddable Rust diff engine"
Expand All @@ -9,8 +9,6 @@ repository = "https://github.com/plannotator/diffs-rs"
readme = "README.md"
keywords = ["diff", "patch", "terminal", "tui", "ratatui"]
categories = ["command-line-utilities", "development-tools", "text-processing"]
# Publishing stays off until the forks in crates/ are published first and the
# repository is public. See RELEASE_READINESS.md for the publish order.
# Ship only what the library and binary need to build, plus the docs a reader
# of the crate needs. Tests, fixtures, tools, reports and the forked crates in
# crates/ (published separately) stay out of this package.
Expand All @@ -22,7 +20,8 @@ include = [
"/Cargo.toml",
"/Cargo.lock",
"/README.md",
"/EMBEDDING.md",
"/CHANGELOG.md",
"/docs/embedding.md",
"/LICENSE",
"/NOTICE.md",
]
Expand Down
543 changes: 126 additions & 417 deletions README.md

Large diffs are not rendered by default.

Binary file added assets/screenshot.webp
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion crates/diffs-fancy-regex/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ include = [
"/AUTHORS",
"/LICENSE",
]
# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order.

[package.metadata.diffs-rs.upstream]
crate = "fancy-regex"
Expand Down
1 change: 0 additions & 1 deletion crates/diffs-syntect/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ include = [
"/CHANGELOG.md",
"/LICENSE.txt",
]
# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order.

[package.metadata.diffs-rs.upstream]
crate = "syntect"
Expand Down
3 changes: 2 additions & 1 deletion crates/diffs-syntect/PATCHES.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ The optional `regex-census` feature additionally exposes a borrowed snapshot in
`src/parsing/regex_census.rs`. It inspects initialized static cells only, records
owner identities, and does not load grammars, compile regexes, or clone owners.
It is disabled in ordinary application builds. The application-level scope and
real-grammar controls are in `REGEX_CENSUS_PLAN.md` and `tests/regex_census.rs`.
real-grammar controls are in `docs/measurements/REGEX_CENSUS_PLAN.md` and `tests/regex_census.rs`
in the diffs-rs repository.

The optional `owner-census` feature adds `src/parsing/owner_census.rs` for the
Fancy Regex backend. It deduplicates initialized outer cells before visiting
Expand Down
1 change: 0 additions & 1 deletion crates/diffs-two-face/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ include = [
"/LICENSE-APACHE",
"/LICENSE-MIT",
]
# Not published yet. RELEASE_READINESS.md in diffs-rs gives the publish order.

[package.metadata.diffs-rs.upstream]
crate = "two-face"
Expand Down
30 changes: 30 additions & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Documentation

## Guides

- [embedding.md](embedding.md): embed the diff engine in a Ratatui application.
- [release.md](release.md): publish the crates.
- [measurements/](measurements/README.md): large-patch timing and memory results, and how they
were measured.

## Design

[design/](design/) has the specifications the viewer was built against:

- [SPEC.md](design/SPEC.md): product behavior, controls, and presentation.
- [LARGE_DIFFS.md](design/LARGE_DIFFS.md): the large-patch workload and its targets.
- [EXACT_SOURCE_CONTEXT_SPEC.md](design/EXACT_SOURCE_CONTEXT_SPEC.md): full-source coloring and
context expansion.
- [INPUT_SCENARIO_ANALYSIS.md](design/INPUT_SCENARIO_ANALYSIS.md): input sources, including
proposed GitHub pull request support.
- [SIDEBAR_SPEC.md](design/SIDEBAR_SPEC.md): the changed-file sidebar.
- [ACCEPTANCE.md](design/ACCEPTANCE.md): the acceptance checklist.

Some of these describe features that are not implemented yet.

## History

[history/](history/README.md) keeps the dated plans, reports, and reviews from development
before the first release, including the full development log in
[CURRENT_STATE.md](history/CURRENT_STATE.md). They record what was measured or decided at
the time and are not current instructions.
14 changes: 7 additions & 7 deletions ACCEPTANCE.md → docs/design/ACCEPTANCE.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Acceptance checklist

Status: 31 real-process checks pass as of 2026-09-11. The five-patch interior/latency/memory batch is complete; no full milestone is complete.
The [rendering contracts](tests/process/README.md) define the new independent terminal checks and their limits.
The [large-diff progress report](docs/history/LARGE_DIFF_PROGRESS.md) records the current source checks and remaining acceptance work.
The [implementation report](docs/history/IMPLEMENTATION_STATUS.md) records the tested subset, limitations, and open visual acceptance.
The [rendering contracts](../../tests/process/README.md) define the new independent terminal checks and their limits.
The [large-diff progress report](../history/LARGE_DIFF_PROGRESS.md) records the current source checks and remaining acceptance work.
The [implementation report](../history/IMPLEMENTATION_STATUS.md) records the tested subset, limitations, and open visual acceptance.
The [large-diff specification](LARGE_DIFFS.md) replaces provisional scale-fixture selection with the five exact cached DiffsHub inputs and defines the next batch.
The [five-patch results](docs/history/FIVE_PATCH_RESULTS.md) records its independent interior checks and current-build measurements.
The [five-patch results](../history/FIVE_PATCH_RESULTS.md) records its independent interior checks and current-build measurements.
The [spec](SPEC.md) owns behavior and defaults. This file owns evidence and milestone completion.

## The evidence rules
Expand Down Expand Up @@ -110,6 +110,6 @@ The original implementation passed ten development checks. Later work brought th
All five large patches pass the complete supplied-source digest comparison. The new rendering contracts cover explicit small-screen expectations.
The full milestone cells remain open because their requirements include additional evidence.
The existing Pierre browser reference and user-supplied Ghostty screenshot do not establish complete visual acceptance.
Geometry-cache eviction and sparse Unicode boundaries now pass independent process checks. The [responsiveness batch](docs/history/RESPONSIVENESS.md) records the scope.
Deep old/new syntax, continued fallback, and hunk/theme isolation pass independent process checks. The [syntax replay batch](docs/history/SYNTAX_REPLAY.md) records the limits.
The five-patch batch now covers 205 independent interior PTY states per patch, five latency repetitions per patch, and three memory tours per patch. All interior oracles and corruption controls pass. Pierre has one styled distant-seek maximum above the strict 200 ms guard. Ghostty alone meets the current memory envelope; Pierre, Node, Bun, and Linux exceed their applicable RSS limits. Actual Ghostty pixel behavior, display timing, and full milestone acceptance remain open. See [FIVE_PATCH_RESULTS.md](docs/history/FIVE_PATCH_RESULTS.md).
Geometry-cache eviction and sparse Unicode boundaries now pass independent process checks. The [responsiveness batch](../history/RESPONSIVENESS.md) records the scope.
Deep old/new syntax, continued fallback, and hunk/theme isolation pass independent process checks. The [syntax replay batch](../history/SYNTAX_REPLAY.md) records the limits.
The five-patch batch now covers 205 independent interior PTY states per patch, five latency repetitions per patch, and three memory tours per patch. All interior oracles and corruption controls pass. Pierre has one styled distant-seek maximum above the strict 200 ms guard. Ghostty alone meets the current memory envelope; Pierre, Node, Bun, and Linux exceed their applicable RSS limits. Actual Ghostty pixel behavior, display timing, and full milestone acceptance remain open. See [FIVE_PATCH_RESULTS.md](../history/FIVE_PATCH_RESULTS.md).
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Exact-source coloring and expandable context

Date: 2026-09-22.
Status: feature specification, with [storage/reference groundwork](SOURCE_STORAGE_REPORT.md) and [local source inputs](LOCAL_SOURCE_INPUT_REPORT.md) implemented.
The [complete-context coloring checkpoint](FULL_SOURCE_COLOR_REPORT.md) implements the coloring stage.
The [context expansion checkpoint](CONTEXT_EXPANSION_REPORT.md) implements incremental local expansion. Integrated resource and physical-terminal qualification remain open.
Status: feature specification, with [storage/reference groundwork](../history/SOURCE_STORAGE_REPORT.md) and [local source inputs](../history/LOCAL_SOURCE_INPUT_REPORT.md) implemented.
The [complete-context coloring checkpoint](../history/FULL_SOURCE_COLOR_REPORT.md) implements the coloring stage.
The [context expansion checkpoint](../history/CONTEXT_EXPANSION_REPORT.md) implements incremental local expansion. Integrated resource and physical-terminal qualification remain open.

This specification refines the input, syntax, and context proposals in [SPEC.md](SPEC.md).
The [input scenario analysis](INPUT_SCENARIO_ANALYSIS.md) defines the broader source modes, GitHub requirements, and delivery priorities.
Expand Down Expand Up @@ -59,7 +59,7 @@ The patch parser, line pairing, inline emphasis, and canonical patch export rema
New context must not become fake additions, deletions, or extra original patch records.
The implementation must not increase every stored patch record to hold optional full-file metadata.

The existing [sidebar report](SIDEBAR_REPORT.md) owns current correctness evidence.
The existing [sidebar report](../history/SIDEBAR_REPORT.md) owns current correctness evidence.
Existing measurements do not describe this proposed feature or a future executable.

## 3. Inputs and exact version identity
Expand Down Expand Up @@ -504,7 +504,7 @@ Public evidence cannot qualify private authentication or enterprise hosts. Recor

Each stage preserves its ordinary executable and source identity before the next stage changes runtime behavior.
Historical evidence and prepared measurement binaries stay unchanged.
The compatibility-only store/reference refactor is complete, as recorded in the [storage checkpoint](SOURCE_STORAGE_REPORT.md).
The compatibility-only store/reference refactor is complete, as recorded in the [storage checkpoint](../history/SOURCE_STORAGE_REPORT.md).
The local-source checkpoint adds snapshots, disk indexes, local identities, exact correspondence, and both local commands.
The expansion checkpoint preserves the typed identity mapping before it adds range expansion and terminal controls.
Its concrete review type represents complete local comparisons only. Partial/unknown remote coverage states remain part of the remote adapter checkpoint.
Expand Down
File renamed without changes.
8 changes: 4 additions & 4 deletions LARGE_DIFFS.md → docs/design/LARGE_DIFFS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Large-diff foundation: implementation specification

Date: 2026-09-10. Status: implementation started, not performance-accepted. See the [progress report](docs/history/LARGE_DIFF_PROGRESS.md).
Date: 2026-09-10. Status: implementation started, not performance-accepted. See the [progress report](../history/LARGE_DIFF_PROGRESS.md).

## 1. Decision and scope

Expand All @@ -16,7 +16,7 @@ DiffGrid remains untouched. No maintainer contact, publishing, global installati
## 2. Exact workload

The pinned [DiffsHub route source](https://github.com/pierrecomputer/pierre/blob/0a7a733078f093577cd21ca65d2508806a22238a/apps/diffshub/app/api/diff/route.ts) contains five cached patch mappings.
All five downloaded bodies now have SHA-256 identities in [corpus.json](fixtures/diffshub/corpus.json).
All five downloaded bodies now have SHA-256 identities in [corpus.json](../../fixtures/diffshub/corpus.json).
The CDN bytes define the workload. A current PR response or a newly generated Git diff cannot silently replace them.

| Required input | Bytes | Physical lines | File records | Hunks |
Expand Down Expand Up @@ -95,7 +95,7 @@ Steady RSS is the maximum during the settled portion of a third fixed memory tou
Disk spool size, source/index allocations, cache payloads, and OS memory measurements remain separate fields.
Kernel filesystem cache outside process RSS is not described as free memory or included in an allocator-only claim.
After warm-up, retained state must plateau within its explicit budgets. A tour cannot retain another document-sized structure.
Each tour visits the fixed file quantiles and structural extremes defined in [scenario.json](fixtures/diffshub/scenario.json).
Each tour visits the fixed file quantiles and structural extremes defined in [scenario.json](../../fixtures/diffshub/scenario.json).
It is not an exhaustive display of all 20 million lines. The separate full-content check covers every supplied source segment.

Failure leaves a target unmet. It does not justify silently changing the corpus, excluding expensive files, or weakening visual settings.
Expand Down Expand Up @@ -267,7 +267,7 @@ No dashboard or multi-candidate benchmark framework is required. Missing GUI acc
| E | Release evidence and visual corrections | All five required cases meet targets, with actual Ghostty appearance/movement signoff recorded separately. |

Step A includes pinned source digests, structural anchors, and an original parse/index diagnostic.
The [content-grid protocol](MEASUREMENT.md) adds a resolved input trace and a runner for the preserved interactive baseline.
The [content-grid protocol](../measurements/MEASUREMENT.md) adds a resolved input trace and a runner for the preserved interactive baseline.
Its scope excludes style completion, normalized full-metadata coverage, long-line tours, and steady-memory acceptance. Those requirements remain pending.
Step B now includes the private spool, progressive file publication, compact source records, and compressed display ranges.
Full source checks and selected corpus terminal checks pass. A shared block index still needs implementation or an evidence-based design review.
Expand Down
2 changes: 1 addition & 1 deletion SIDEBAR_SPEC.md → docs/design/SIDEBAR_SPEC.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changed-file sidebar: implementation specification

Date: 2026-09-22.
Status: implemented. The [implementation report](SIDEBAR_REPORT.md) records checks and limits.
Status: implemented. The [implementation report](../history/SIDEBAR_REPORT.md) records checks and limits.

The user approved the feature boundary and the exact directory hierarchy.
The controls and dimensions below define the first implementation.
Expand Down
6 changes: 3 additions & 3 deletions SPEC.md → docs/design/SPEC.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Native diff viewer: product spec v0.1

Status: proposed behavior, not a description of an existing implementation.
Implementation progress is recorded separately in [IMPLEMENTATION_STATUS.md](docs/history/IMPLEMENTATION_STATUS.md).
Implementation progress is recorded separately in [IMPLEMENTATION_STATUS.md](../history/IMPLEMENTATION_STATUS.md).
The [large-diff implementation specification](LARGE_DIFFS.md) now owns the next batch, exact scale corpus, and proposed performance targets.
Date: 2026-09-10.
Scope: a read-only Rust terminal viewer. The name and proposed defaults remain open to user review.
Expand Down Expand Up @@ -101,7 +101,7 @@ Both layouts use the same source identities and inline-change spans. A layout sw
- Syntax colors remain visible over change backgrounds. Whole changed lines do not become solid red or green text.
- Inline emphasis covers changed spans, not the entire replacement line.
- Inline comparison separates punctuation from words and preserves complete graphemes. Unchanged separators do not receive emphasis.
- Identifiers retain word-level emphasis. The [inline policy](docs/history/INLINE_HIGHLIGHTING.md) defines boundaries and covered checks.
- Identifiers retain word-level emphasis. The [inline policy](../history/INLINE_HIGHLIGHTING.md) defines boundaries and covered checks.
- A small gutter marker identifies the active source line without covering its inline highlights.
- No blinking decoration, scrolling animation, or automatic movement accompanies background highlighting.

Expand Down Expand Up @@ -312,7 +312,7 @@ An input or allocation failure produces an explicit incomplete-result state. It
- The small correctness corpus and generated single-hunk/long-line cases diagnose specific failures. They cannot replace a failing showcase.
- A separate 1 GiB generated workload is outside the next batch.

The [corpus manifest](fixtures/diffshub/corpus.json) pins downloaded bytes and records structural inventory.
The [corpus manifest](../../fixtures/diffshub/corpus.json) pins downloaded bytes and records structural inventory.
Full source-blob correspondence and viewer measurements remain pending. Live PR refs do not replace the pinned CDN bodies.
Pierre's performance claims are not our results or pass thresholds. This product work makes no clean-room independence claim.

Expand Down
Loading
Loading