Contributing

August 16, 2026 · View on GitHub

Thanks for considering a contribution to dsh-checkpoint-diff. This project is small on purpose — a focused read-only diff view over dsh-checkpoint-rewind checkpoints — so a few conventions keep it maintainable.

Ground rules

  • Read-only by design, with one explicit exception — rollback. The plugin must never write to snapshot storage, git, or sessions, and never fork sessions. The single write path is user-invoked rollback (/rollback / POST /api/rollback / panel Restore row): it restores snapshot file contents into the session workspace — overwrite only, never deletes, workspace-root confined, .git/.dsh refused, read-only git primitives (no git restore). Every new write-like behavior must first extend that exception explicitly in AGENTS.md/SECURITY.md; anything else belongs in the producer (rewind) instead.
  • Pure functions where possible. Timeline extraction, addressing, and output formatting live in lib/checkpoints.mjs as pure functions; the diff engine in lib/diff/engine.mjs is dependency-free; rollback planning lives in lib/rollback.mjs as pure functions plus low-level fs helpers. Keep it that way.
  • Security boundaries are load-bearing. Refs are validated (git 40/64-hex, copy UUID) and relative paths reject .. and absolute paths before any filesystem or git access; restore targets additionally refuse .git/.dsh segments and symlink escapes. Tests must cover the degradation paths (missing records, pruned snapshots, missing objects, mixed providers) and the rollback refusal paths (traversal, protected paths, absent files, method gates).

Development setup

pnpm install                 # zod, esbuild, jsdom + react for tests
pnpm test                    # unit tests (node --test, in-process isolation)
pnpm test:integration        # headless integration vs. real dsh-checkpoint-rewind
pnpm build:client            # rebuild the browser bundle -> lib/client.js

The integration suite assembles the real rewind plugin against the local harness deployment ($DSH_HOME/profiles/node_modules, rc.5) because dsh-checkpoint-rewind is not published to npm and rc.5 packages are not on the registry either. scripts/link-profile-deps.mjs junctions those packages into this repo's node_modules; run pnpm test:integration on a machine with the harness installed (or with DSH_HOME pointed at one). The unit suite has no such dependency and runs anywhere.

Sandbox notes (Windows): node --test child-process spawning and esbuild's binary service may be blocked under restricted sandbox modes — unit tests use --test-isolation=none, and building the client bundle may require full-access once.

Structure

  • index.mjs — host plugin entry (config, domain acquisition, /diff and /rollback incl. --project, API route)
  • lib/ — host logic: constants, domain (zod spec), workspace, checkpoints (timeline/format), project (cross-session merge/lineage), labels (snapshot intent naming), service (DiffService + HTTP handler), rollback (restore planning + fs helpers), diff/engine|git|copy
  • src/client/ — browser half: index (slot registration), store, api, tree (collapsible directory tree), DiffTrigger, DiffPanel (incl. restore row), style (theme tokens)
  • scripts/build-client.mjs (esbuild), link-profile-deps.mjs (test deps)
  • test/ — unit tests, jsdom panel smoke tests, integration/diff-headless.mjs
  • docs/ — design documents (timeline-design.md: cross-session timelines, implemented in 0.2.0)

Pull request checklist

  • pnpm test passes
  • pnpm test:integration passes (or is documented as environment-limited)
  • pnpm build:client and the built bundle was committed if client code changed
  • CHANGELOG updated (Added / Fixed sections)
  • New behavior covered by a test; degradation paths included

License

By contributing you agree that your contributions are licensed under the Apache-2.0 terms of this repository.