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
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
0.10.0 (2026-10-02)
Features
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
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
Bug Fixes
0.7.1 (2026-09-26)
Bug Fixes
0.7.0 (2026-09-25)
⚠ BREAKING CHANGES
- watch: watch entry JSON files may now carry an optional
ignoredTerminalAtfield. 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
detectedAtinstead ofatin 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 usesdelta.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.
- Snapshot items and delta from/to are
- 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 updatedto avoid double-counting a push) must switch to matchinghead-changeddirectly.context.titleon 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 newdeltakey, and dedupe must usedelta.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
errorsarray in favor of an always-presentrepos/results[]envelope with per-repo errors;filteredDeltas/warningsare always present; the report timestamp field is renamed fromattodetectedAt. - 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 resetas 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'sfrom/toin every report format now carryfingerprint/context/metainstead 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
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
0.1.0 - 2026-07-08
- Initial
gh-deltadetector CLI. - Classified first-observed closed/merged items as
first-seenso a cold start against a repo with history does not report them as newly created. - Validated snapshot
meta.horizonand legacyupdatedAtas 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-deltaCLI. - Added stable
--monitor-ididentity 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: 1to every JSON report (success and error) so consumers can pin the report shape at runtime. - Made the outpost
eventIdorder-independent by sortingclassesbefore joining. - Hardened
docs/contract.md: class applicability table, closed-set / non-empty / forward-compat guarantees,from/toopacity 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
reappeareddelta 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
eventIdfrom delivery attempts. - Fixed CLI help drift, duplicate
--formathandling, package README image contents, and live e2e documentation.