Skip to content

diegomarino/gh-delta

v0.12.1MIT

Decision guide for observing GitHub PR and issue deltas with gh-delta.

Changelog

All notable changes to this package will be documented here.

This project follows semantic versioning.

Unreleased

Features

  • Add opt-in one-line per-delta templates to detector ticks and cursor reads, with local file sources and optional raw-byte SHA-256 verification (#95). Planned for the next minor release.

0.12.1 (2026-10-18)

Bug Fixes

  • plugin: add Cursor marketplace metadata and logo (#125) (660778a)
  • skill: clarify how scheduled --once runs resolve, fail and stay quiet (#126) (a6141c7)

0.12.0 (2026-10-18)

Features

  • cli: autodetect --repo for reset like a run does (#122) (11d14c8)
  • plugin: add Agent Plugins 1.0 and Cursor manifests sharing skills/ (4ff83d7)
  • quickstart: add a one-shot --once mode for schedulers (9124295)

Bug Fixes

  • polling: fall back when the token cannot read team reviewers (116abd5)
  • polling: recalibrate GitHub clock offset on every broad tick (#118) (5dbc42f)
  • quickstart: probe repository read access in the readiness check (#121) (b674734)

Documentation

  • describe the team-reviewers-unavailable warning (b3c1444)
  • install: mention Agent Plugins and Cursor install targets (75a3e69)
  • skill: document one-shot scheduled runs and cloud-agent setup (c50388e)

0.11.0 (2026-10-08)

Features

  • skill: add an isolated session monitoring quickstart (#112) (9af262f)

Bug Fixes

  • polling: calibrate GitHub time and avoid pre-start notifications (#111) (af0d0c2)
  • quickstart: reject false non-boolean settings (#117) (27a5989)

0.10.1 (2026-10-02)

Bug Fixes

  • docs: restore navigable documentation and skill references (#109) (d5e24f0)

0.10.0 (2026-10-02)

Features

  • watch: observe strict issue and mixed lists without a broad fetch (#107) (419bbf1)

0.9.0 (2026-10-02)

Features

  • output: add one-line per-delta templates (#100) (021e74b)
  • output: support NDJSON detector ticks without end records (#98) (c6aece5)
  • watch: add atomic desired-set synchronization (#102) (e5a214f)
  • watch: add strict targeted PR watching beyond ten entries (#99) (5368277)
  • watch: preserve local labels on emitted deltas (#96) (1baa75c)

Bug Fixes

  • watch: reject non-enumerable own label entries (#104) (ae8144a)
  • watch: retain validated rate-limit accounting on later strict-batch failure (#105) (0c8a5c4)

0.8.1 (2026-09-26)

Bug Fixes

Code Refactoring

  • cli: split orchestration into internal modules (#88) (2cd2613)

0.8.0 (2026-09-26)

⚠ BREAKING CHANGES

  • runtime: Node.js versions below 22 are no longer supported. CI tests Node 22 and Node 24, with shared quality checks and coverage on Node 24.

Features

  • runtime: require Node 22 and streamline CI (#85) (1b87309)

Bug Fixes

  • skill: check CLI availability before monitoring (#87) (6f5bc55)

0.7.1 (2026-09-26)

Bug Fixes

  • skill: update operating guide for schema v2 (#83) (ce0ff8e)

0.7.0 (2026-09-25)

⚠ BREAKING CHANGES

  • watch: watch entry JSON files may now carry an optional ignoredTerminalAt field. Existing entries remain valid unmodified; any tool reading watch entry files with a strict/exact-key expectation must be updated to tolerate this new optional key.
  • compact,text: compact/ndjson delta records now include seq and firstObserved when the underlying delta carries them (previously silently dropped); a strict consumer validating against an exact key set must account for the two new optional fields.
  • fingerprint: delta ids for checks rows that previously tied on name/kind/status/conclusion (distinguishable only by detailsUrl) will differ from prior 0.x output. This is a one-time churn for those rows only; existing contract-baseline fixtures were unaffected (no duplicate-tuple check rows in the recorded fixtures), so no baseline regeneration was needed.
  • compact,ndjson: --format compact and --format ndjson now emit detectedAt instead of at in the report/end envelope.
  • contract: report.schemaVersion and outpost payload schemaVersion are now 2. This is the schema-v2 epic's cumulative v1 -> v2 contract change, closing out what R1-R6 and F1-F4 built incrementally:
    • Snapshot items and delta from/to are {fingerprint, context, meta}, not one flat object; comparableFingerprint's 14-key drop-list and the ADDITIVE_COMPARED_FIELDS upgrade-compat list are gone -- every fingerprint key now participates in comparison and the delta id.
    • Fingerprint field names/casing changed throughout: ci/reviews/head/ base/review/ciChecks/reviewSummary/threadDigest/threadStates/ commentNodes/comments/commentsOverflow are replaced by checks/reviews/headSha/baseRef/reviewDecision/conversationComments/ reviewComments, with lowercase enums; there are no more opaque digests.
    • The report is always the repos/results[] envelope (no single-repo bare shape, no top-level multi-repo errors array); filteredDeltas and warnings are always present; the timestamp field is detectedAt.
    • delta.title/author/url/headRefName are replaced by delta.context; delta.line and hideInternalDetails' public/private delta view are removed; delta.summary and delta.changed are always present.
    • Outpost payloads no longer duplicate delta fields at the root or emit eventId; delta fields live under delta, dedupe uses delta.id, and Standard Webhooks headers replace X-GhDelta-Signature.
    • A pre-schema-v2 (or otherwise invalid) snapshot or durable log is never migrated: it is a permanent error naming gh-delta reset.
  • classes: a push with no other change now emits only classes: ["head-changed"], not ["head-changed", "updated"]. Any consumer relying on the forced pairing (or on --ignore-classes updated to avoid double-counting a push) must switch to matching head-changed directly. context.title on the missing lifecycle is now the real last-known title rather than always null.
  • examples: this example receiver only understands the v2 outpost payload and Standard Webhooks signing; it no longer verifies X-GhDelta-Signature or reads v1's root-level delta fields.
  • outpost: the outpost HTTP payload no longer duplicates delta fields at its root and no longer emits eventId; delta fields live under the new delta key, and dedupe must use delta.id. The X-GhDelta-Signature header is removed in favor of Standard Webhooks headers (webhook-id/webhook-timestamp/webhook-signature); receivers verifying the old header must migrate.
  • schema: schema/json.json, compact.json, and ndjson.json now express the delta shape as $defs.delta + $ref instead of three inlined copies; consumers resolving these schemas must support $ref.
  • schema: schema/json.json, compact.json, and ndjson.json no longer describe the old single/multi-repo split or the legacy delta field names; they describe the always-enveloped report and the context/changed/summary-always-on delta.
  • cli: delta.title/author/url/headRefName are replaced by delta.context; delta.line is removed; delta.summary and delta.changed are now always present (previously opt-in/PR-only); delta.from/to are now compact/ndjson-optional (--full) rather than always omitted. The report drops the single-repo bare shape and the multi-repo top-level errors array in favor of an always-present repos/results[] envelope with per-repo errors; filteredDeltas/warnings are always present; the report timestamp field is renamed from at to detectedAt.
  • cli: commentAuthorsIgnored is replaced by authorsIgnored, which also suppresses review-changed (via reviews[].author) and review-comments-added (via a pre-publish, double-opt-in-gated --enrich thread-replies call) when every attributable author is listed in --ignore-authors. review-changed is never suppressed when reviewDecision itself moved, even if a changed review row happens to belong to an ignored author -- that transition may not be explained by the changed row. Without --enrich thread-replies, or when every incremented thread is brand new (no prior baseline to diff replies against), a review-comments-added delta now fails open with an explicit warning instead of silently passing through unchecked. This is the one documented exception to opt-in enrichment quota being spent only after snapshot publication; see --help for --ignore-authors/--enrich.
  • contract: DELTA_CLASSES gains review-comments-added and review-comments-removed; DELTA_DETAIL_FIELDS_BY_CLASS renames the new-comments/comments-removed detail field from comments to conversationComments, adds reviewComments for the two new classes, and replaces comments with conversationComments/reviewComments in updated's field list.
  • detect: new-comments/comments-removed now fire only on conversationComments; a reply in an existing review thread instead fires the new review-comments-added/review-comments-removed classes, driven by the reviewComments compared field. Exports threadReplyIncrements, a pure per-thread reply-count-delta helper shared by --enrich thread-replies and the --ignore-authors pre-publish filter pass.
  • fingerprint: prFingerprint/issueFingerprint no longer carry the aggregate comments field. PR fingerprints add reviewComments alongside the existing conversationComments; issue fingerprints keep conversationComments only. delta.id changes for any PR/issue whose comment counts differ from a prior snapshot taken before this change.
  • gh: normalizePr/normalizeIssue no longer emit the aggregate comments field. PRs now emit conversationComments and reviewComments (= totalCommentsCount - conversationComments, clamped at 0) as independent values; issues keep conversationComments only.
  • fingerprint: checks[] rows may gain runId/jobId fields, which enter the content-addressed delta.id (R2 put checks[] directly in the hashed identity), so ids for PRs with parseable Actions check URLs change from prior schema-v2 snapshots.
  • deltalog: appendDeltaLog now requires non-empty repo/monitorId options, and every log record gains repo/monitorId fields. A durable log written before this change -- v1/v2 manifest, or pre-manifest raw NDJSON -- is rejected with an error naming gh-delta reset. There is no migration.
  • snapshot: a snapshot missing meta, or whose meta.schemaVersion is not 2, is rejected with an error naming gh-delta reset as the recovery path. There is no migration from an older or meta-less snapshot.
  • gh: lib/gh.mjs's fetchPRs, fetchIssues, fetchPRsByNumber, and fetchEnrichment now return { rows, rateLimit } instead of a bare array; lib/enrich.mjs's enrichEmittedDeltas now returns { warnings, rateLimit } instead of a bare warnings array. Any code importing these directly must destructure the new shape.
  • fingerprint: fingerprint field names and enum casing change again (schema v2, following R1); every delta.id changes accordingly. Consumers reading ci/reviews/head/base/review/ciChecks/reviewSummary/threadDigest/ threadStates/commentNodes or uppercase enum values must update to checks/reviews/headSha/baseRef/reviewDecision and lowercase enums.
  • cli: --detail/--summaries/agent-compact output, status items, and outpost payloads now read the three-section snapshot item shape (see the companion snapshot-split commit); a delta's from/to in every report format now carry fingerprint/context/meta instead of one flat object.
  • snapshot: snapshot items and delta from/to are now { fingerprint, context, meta } instead of one flat object. Delta ids change for every entity that carries a fingerprint field previously dropped before hashing (ciChecks, reviewSummary, ciDetails, reviewDetails, commentNodes, conversationComments, threadDigest, threadStates): these now participate in the content-addressed id. Persisted v1 snapshots are not compatible with this version; consumers reading raw snapshot files must update to the three-section shape.

Features

  • cli: add gh-delta reset; snapshot writes now carry full schema-v2 meta (9bb865b)
  • cli: authorsIgnored covers conversation, reviews, and thread replies (0dfaad5)
  • cli: unify delta and report shape for schema v2 (R3) (e638a9c)
  • compact,ndjson: unify at -> detectedAt with the JSON report (83a3b8f)
  • contract: bump schema version to 2, close the v1 compat surface (994ca97)
  • contract: register review-comments-added/-removed classes (5245366)
  • deltalog: version-3-only manifest, log records carry repo/monitorId (0bee0a9)
  • detect: review-comments-added/-removed classes; new-comments is conversation-only (7996313)
  • enrich: add thread-replies enrichment kind (2a538a9)
  • fingerprint: drop digests, unify names/enums across checks/reviews/threads (bd91971)
  • fingerprint: parse runId/jobId from Actions check URLs, add summary.failedChecks (afb0089)
  • fingerprint: reviewComments joins conversationComments as compared fields (5e74f81)
  • gh,cli: item context (id/author/createdAt/url) and --enrich body (b7ae6e7)
  • gh,cli: item context (id/author/createdAt/url) and --enrich body (F2) (a579c5b)
  • gh: add fetchThreadReplies, one aliased per-thread GraphQL call (3e2f18b)
  • gh: instrument every GraphQL query with rateLimit cost tracking (8115288)
  • gh: split PR conversation and review comment counts (15f7ee6)
  • outpost: reshape delta payload and switch to Standard Webhooks signing (b48b808)
  • schema: regenerate json/compact/ndjson schemas for the v2 delta/report shape (163a73b)
  • snapshot: make snapshot meta mandatory (schema v2) (55e17e6)
  • snapshot: split snapshot items into fingerprint/context/meta (a4fb6f4)
  • watch: persist ignored terminal transitions to close the sticky-filter hole (7207a8f)

Bug Fixes

  • classes: decouple head-changed from updated, carry real missing-cycle titles, add firstObserved (db842b9)
  • cli: read the schema-v2 three-section item shape everywhere (33095d7)
  • cli: repair the cli.mjs/wait.mjs detector-tick error paths (f2f32a5)
  • cli: require full author coverage before suppressing review-comments-added (f9cacdd)
  • compact,text: propagate seq/firstObserved to agent formats, show title/author in status text (dbd7a66)
  • contract-fields: derive REGISTRY_ENTRY_FIELDS from real registerMonitor output (a002b22)
  • contract: correct stale AGENT_COMPACT_*/AGENT_NDJSON_END_FIELDS (3b8bda3)
  • contract: cover every field catalog with real-output drift detection (60551fd)
  • deltalog: resetDeltaLog recovers dataFile from an invalid-but-parseable manifest (758afa9)
  • diff: align checksDiff with diffSummaries on duplicate check names, exclude recentComments rotation from updated (3fd8ac1)
  • diff: checksDiff opaque fallback only fires on a real change (bf478b3)
  • examples,tools: repair broken examples and contract-violating generated output (W7B) (06d77cc)
  • examples: fix v2 field mapping in programmatic-embed example (b0a15cb)
  • examples: read coordinator logFile from results[], not top-level (fa9eacc)
  • fingerprint: give buildChecks a unique sort tiebreaker (97b683f)
  • gh-delta init reads init baseline/stateFile from v2 results[0] (25c7873)
  • gh: anchor fetchThreadReplies against the observed thread state (d21ba5c)
  • outpost: normalize a raw detectDeltas() delta before building its payload (5a526fb)
  • post-epic cleanup lane A — release blocker, wait bug, at→detectedAt (W7A) (b5321a1)
  • read v2 results[0].baseline in the live playground e2e, widen the sweep (eae7b3c)
  • resolve confirmed Codex review findings from the schema-v2 epic (code) (24ccaca)
  • schema: share one $defs.delta across json/compact/ndjson via $ref (a6080d7)
  • test: make schema-coverage's compact/ndjson checks self-policing (836b86e)
  • test: render and validate multi-repo output in every agent format (cc10b08)
  • test: stop writing real detector ticks into the developer's registry (6e14af5)
  • tools/examples: enrich deltas before the fixture strip step (4b76954)
  • wait: make --from-log --until-summary actually match (f51092b)
  • wait: repoint state-file lookups at results[].stateFile (a07ea00)
  • wait: report the highest-severity error, not the last one collected (21bffa2)
  • watch: clean up entries by terminal state, not delta class (9b302f7)
  • watch: clean up entries by terminal state, not delta class (d3f3ed3), closes #57
  • watch: derive marker suppression from real filter output, not flags (a6d0fe0)
  • watch: fail the tick on a concurrent watch-entry replacement (5444769)
  • watch: hold the entry lock through mark AND publish, not just the mark (95497b4)
  • watch: move unsafe lock helpers off the published API surface (3462db6)
  • watch: persist ignoredTerminalAt before publication, not after (68fe707)
  • watch: recognize an already-terminal from.state as cleanup-eligible (c3b357a)
  • watch: require a surviving terminal class before cleaning up a watch entry (2d2396f)
  • watch: size the entry lock lease from --lock-stale-ms, not --gh-timeout-ms (12d46aa)
  • watch: size the entry lock lease from a fixed constant, not --lock-stale-ms (66833be)
  • watch: treat a terminal first observation as cleanup-eligible (894ff3c)
  • watch: use from.state !== to.state for transitions, not terminal-priorState (c5da9be)

Documentation

  • add missing --enrich/--full and gh-delta reset coverage (gaps, no v2 doc home) (c4dd79f)
  • args: stop describing repo-casing normalization via the removed eventId (0ad352f)
  • bring prose in line with schema v2 (W7C) (3aa02f9)
  • contract,help: rewrite contract.md for schema v2 (520b22b)
  • contract: fix stale manifest/log docs and internal v2 contradictions (8c53b70)
  • contract: fix the from/to bare-fingerprint self-contradiction (e6e88d7)
  • examples: add a review-comments-added example delta, regenerate SVGs (428598e)
  • examples: fix stale v1 references in examples and generator docs (9f27dd0)
  • examples: migrate outpost-ntfy-receiver to Standard Webhooks and the v2 payload (87b49c3)
  • examples: update fixtures and cast generator to the v2 item shape (a69a2d2)
  • examples: update fixtures and demo runner to the v2 fingerprint shape (abb782d)
  • examples: update fixtures and the GitHub Actions example for schema v2 (35de99f)
  • fingerprint: fix stale drop-list comments left over from schema v2 (0af8758)
  • fix dead outpost-v1 anchors, stale --summaries usage, new-comments scope (7755f13)
  • fix reset --entities omission, dead v1 anchor, import comment, enrich cost (d80e62e)
  • fix v1-era field names, --summaries no-op, and add gh-delta reset recovery (b0e3243)
  • help,text-output: document thread-replies, review-comments-*, and the pre-publish quota exception (4dbeac4)
  • help: document the v2 delta/report shape and the new --full flag (014fffc)
  • help: document the v2 outpost payload shape and dedupe rule (981a5ad)
  • lib: fix stale schema-v2 comments and prose (4836b21)
  • record F1's measured reviewThreads.comments query cost (8/8, not 7/8) (17ab7a3)
  • resolve confirmed Codex review findings (docs) (6d44056)
  • runbook: cover --watch-dir monitors in the reset recovery flow (fcd38d7)
  • runbook: fix outpost v2 payload/dedupe, summaries no-op, class table gaps (62b5d2e)
  • watch-loop-prompt: drop obsolete head-changed/updated pairing advice (4d24717)

0.6.1 (2026-09-23)

Documentation

  • examples: point --state-dir at XDG state, not the caller's cwd (#55) (a89f2ef)

0.6.0 (2026-09-21)

Features

  • add actionable details and ignored comment authors (#37) (79960d0)
  • add agent-oriented output formats (#44) (eeffae3)
  • add bounded wait command (#45) (c293a0e)
  • add durable delta log replay (#34) (d3fbf31)
  • add economical watch directory fetching (#40) (38c1f7d)
  • add local watch directory selection (#39) (38ab15a)
  • add opt-in GraphQL rate limit floor (#42) (be672d1)
  • add post-detection attention filters (#33) (0fcb81a)
  • add setup and diagnostics commands (86fd2b8)
  • add setup and diagnostics commands (a292409)
  • add status and stale detection (#46) (a824559)
  • aggregate detector passes across repositories (#43) (4ee57dc)
  • compact retained delta logs (#35) (5189104)
  • detect head changes and review-thread identity (#32) (c35aaeb)
  • distribute gh-delta for agents (#47) (bd69a0e)
  • enrich emitted deltas on demand (#41) (99eb38a)
  • guard the snapshot with a deadline-based file lock (#31) (69328ca)
  • scope monitor identity by worktree (#36) (c423feb)
  • sign outpost deliveries with HMAC (#38) (2513dfd)
  • wave 0 foundations — shared duration parser and the two regression nets (#28) (1554ca2)

Bug Fixes

  • ci: verify extension release URL (9de0a22)
  • dedupe outpost deliveries by delta id, not event id (#29) (dd39da4)
  • docs: align schema preview command (31e882d)
  • dx: harden doctor and init safeguards (bfe8d78)
  • examples: harden agent integration recipes (18ee2c9)

Documentation

  • add agent-first examples and recipes (228c113)
  • add agent-first examples and recipes (53b4396)
  • add common PR loop demo (#51) (7e9fcf8)
  • keep scenario lifecycle with its launcher (#53) (bb90356)
  • restore generated output visuals (1cd6649)
  • restore generated output visuals (ab14a63)
  • scope agent scenarios by session id (#54) (3df6c57)
  • turn gh-delta skill into an operating guide (#52) (fd13968)

0.5.0 (2026-08-05)

Features

  • add seven neutral delta classes for agent feedback signals (49eba4f)
  • explain the new classes in details, text output, and help (e3fe9be)
  • extend neutral GitHub signals from the #23 audit (a679688)
  • fetch base ref, labels, assignees, and review requests (730ce69)

Bug Fixes

  • suppress additive-field detail rows on upgrade ticks (518331f)

Documentation

  • catch operator docs up with the new classes and audit notes (0fc4c0c)
  • document the new classes and compared fingerprint fields (8af1b84)
  • rate-limit budget, unresolvable-reviewer placeholder, GHES opt-in stance (3b4e029)
  • showcase review-requests-changed in the example artifacts (f5bb320)

0.4.0 (2026-07-28)

Features

  • add --baseline-emit-state flag for pre-existing open items (b903d4b)
  • add mergeStateStatus enum to the delta summary (1cfecdb)
  • add opt-in baseline-state delta class to the detector (6288815)
  • derive --repo from the git remote when omitted (#18) (c992b9e)
  • mergeStateStatus in delta summary + opt-in baseline-state emission (7502787)
  • observe mergeStateStatus in the PR fingerprint boundary (6fb3bbe)

Bug Fixes

  • compare mergeStateStatus so merge-state transitions are not swallowed (bf0d36b)

0.3.1 (2026-07-12)

Bug Fixes

  • pass gh GraphQL variables as raw string fields (2a0be9b)
  • terminal-safe text output and clearer gh-delta list behavior (056aebd)

Documentation

  • complete delta-class coverage and scheduler provenance (3ee690f)
  • correct contract and architecture reference gaps (066f80c)
  • document the release process and fix the package inventory (25ff347)
  • fix research anchors, add refresh policy and a docs index (ca4f673)
  • use present-tense npm install framing (69a13b0)

0.3.0 (2026-07-10)

Features

  • add optional --summaries semantic layer for PR deltas (#14) (c1e7aa1)
  • cli: gh-delta list — read-only inventory of every local monitor (#11) (0f757da)
  • name the exact checks and reviews behind ci-changed/review-changed details (#12) (d948d3e)

0.2.0 (2026-07-08)

Features

  • add content-addressed id to every delta (#5) (917ba42)
  • carry PR head branch (headRefName) on deltas (#7) (1e5e536)

0.1.1 (2026-07-08)

Bug Fixes

  • add operator suggestions for draft-ready and reopened deltas (#1) (8ae8f5d)

0.1.0 - 2026-07-08

  • Initial gh-delta detector CLI.
  • Classified first-observed closed/merged items as first-seen so a cold start against a repo with history does not report them as newly created.
  • Validated snapshot meta.horizon and legacy updatedAt as ISO dates, failing with exit 2 before fetching instead of computing a bogus incremental window.
  • Added one-shot JSON and text output through the single gh-delta CLI.
  • Added stable --monitor-id identity and monitor-scoped derived snapshot paths.
  • Added deterministic PR and issue delta classification.
  • Added GraphQL review-thread enrichment for open PR unresolved-thread signals.
  • Added optional at-most-once outpost delivery.
  • Added research-only docs for future entity and selector design.
  • Added Node test suite, linting, formatting, coverage reporting, and package dry-run checks.
  • Added schemaVersion: 1 to every JSON report (success and error) so consumers can pin the report shape at runtime.
  • Made the outpost eventId order-independent by sorting classes before joining.
  • Hardened docs/contract.md: class applicability table, closed-set / non-empty / forward-compat guarantees, from/to opacity policy and nullability, error-report shape, and snapshot semantics.
  • Hardened snapshot validation so malformed state files fail before GitHub fetches.
  • Changed derived snapshot filenames to collision-free encoded identity segments.
  • Added reappeared delta classification for objects returning after missing fetches.
  • Closed the accidental package root import surface; documented subpaths remain public.
  • Clarified outpost as best-effort delivery and separated semantic eventId from delivery attempts.
  • Fixed CLI help drift, duplicate --format handling, package README image contents, and live e2e documentation.