Skip to content

Releases: blackwell-systems/gcf-typescript

v2.4.0: Graph delta decode + verify; session + conformance hardening

Choose a tag to compare

@blackwell-systems blackwell-systems released this 13 Jul 05:25

Fixes

  • The conformance runner now hard-fails on any unhandled operation (instead of silently skipping it) and exercises session, delta, roundtrip, and pack-root fixtures end to end; the graph delta wire decode and verify path is now covered, so no operations remain allow-listed.
  • Implemented the graph delta wire decoder and verifier (decodeDelta / verifyDelta): parse a GCF profile=graph delta=true wire back into removed/added symbols and edge changes, apply them atomically to a base snapshot, recompute pack_root, and reject a wrong new_root with root_mismatch (SPEC 10.4). The ## added encoder now emits the trailing distance field (SPEC 3.4.1, Section 10.1). The shared graph-delta fixtures now run end to end: 001 (encode, gains the trailing distance), 002 (verified apply), 003 (root_mismatch rejection).
  • Session encoding correctness fix. encodeWithSession assigned per-response local IDs instead of stable session-global IDs, so the cross-call dedup references (@N # previously transmitted) pointed at the wrong symbols, and the header emitted zero-valued budget/tokens/edges. Both are fixed to match the reference; graph session output is now byte-identical across all six SDKs. This had gone undetected because the conformance runner skipped the shared graph-session fixtures (now wired).
  • Buffered graph encoder: order edges by source ID, then target ID, then edge type (SPEC 16.1), instead of emitting them in input order. Decode-invariant (edges are a set) and does not affect pack_root (which sorts edge records independently), so no content addresses change. Pinned by shared fixture graph-encode/003. Streaming edges remain in producer-arrival order.
  • Decoder: reject an orphan .field attachment (a .field whose name is neither a ^-marked column of its row nor a >-containing field name, SPEC 7.4.6.1.4) instead of silently absorbing it as an undeclared extra field. Such a stray attachment previously decoded to a record no encoder produces, silently injecting a field onto the last-parsed row (a lossless round-trip hole); now rejected per SPEC 16.5 (orphan_attachment).
  • Decoder: reject an orphan positional inline body (a pipe-delimited line with no eligible ^{} attachment-marker cell) instead of silently dropping it. The object-body parser previously skipped any unrecognized line, so a stray positional body (e.g. a second Bob|b@t.com after a row's one inline cell was filled) vanished with no error (silent data loss); now rejected per SPEC 16.5 (orphan_inline_attachment).
  • Graph streaming trailer: the edge count is now always the last counts entry, even when the stream has no edges (positional counts=2,1,0; labeled counts=…,edges:0). A zero-edge stream previously dropped it, violating the SPEC §8.4 / §8.4.1 rule that the edge count is always present and last (the invariant that keeps the positional form unambiguous). The graph trailer is decoder-ignored, so this changes producer output only.

Streaming: opt-in labeled trailer counts (SPEC §8.4.1)

  • New labeledTrailerCounts stream option on StreamEncoder. When set, the ##! summary graph streaming trailer emits counts= in the labeled form label:count per group (e.g. counts=targets:2,related:1,edges:3) instead of the default positional values-only form (counts=2,1,3). Default false is byte-identical to prior output.
  • Opt-in and non-breaking: a producer-side comprehension aid for known weak consumers. The trailer counts remain informational (decoder-ignored) in both forms; neither changes the decoded payload. Mirrors the gcf-go reference.

Conformance and docs

  • Streaming graph trailer now emits distance_N group counts in pure group-header emission order (dropping a fixed targets,related,extended prefix), matching the other SDKs and deterministic per SPEC 16.1. Byte-identical for contract-conformant (ascending-distance) input; pinned by shared fixtures streaming-v2/010011.
  • The conformance runner now executes the graph-stream-encode fixtures (streaming-encode parity, previously decode-only): fixture 004 (positional trailer) and 005 (labeled trailer).
  • README: corrected the streaming example trailer from the defunct ## _summary … sections= to the real ##! summary … counts=; README now leads with the project diagram.

Full Changelog: v2.3.0...v2.4.0

v2.3.0

Choose a tag to compare

@github-actions github-actions released this 12 Jul 17:01

Generic-profile delta + re-anchor session helper (SPEC §10a)

Delta encoding comes to the generic profile — the multi-turn compression that JSON and TOON structurally lack — plus a producer-side re-anchor helper. Byte-for-byte interoperable across all six GCF SDKs (Go, Python, TypeScript, Rust, Swift, Kotlin) against a shared conformance suite.

Generic-profile delta (§10a)

Keyed row diffs: send only what changed (## added / ## changed / ## removed) instead of re-sending the whole table each turn.

  • GenericSet + GenericDeltaPayload; genericPackRoot (content-addressed gcf-pack-root-v1)
  • diffGenericSets (producer) · encodeGenericFull / encodeGenericDelta · decodeGenericFull / decodeGenericDelta · verifyGenericDelta (atomic apply + new_root verification)
  • Opt-in and bilateral; the existing encode path is unchanged. Node-only (uses crypto).

Re-anchor session helper (§10a.8)

GenericDeltaSession — a thin stateful producer that manages the re-anchor cadence for you. Each next() returns either a compact delta or, on its cadence, a full re-anchor, updating its held base.

  • fixedN(n) (default N=15) or sizeGuard() (size-adaptive, production-recommended)
  • No new wire syntax; cadence knobs are never wire fields, so the decoder stays cadence-agnostic. A schema change forces a full.

Why it matters

Across a 50-turn comprehension study, six of seven cleanly-measured models comprehend delta as well as full-resend at a fraction of the tokens; the one model that drifts at depth is closed by the re-anchor.

Correctness

Byte-for-byte identical wire and pack roots across all six SDKs, verified by shared conformance fixtures (generic-pack-root, generic-delta, generic-delta-session). Fuzzed: the decoder never crashes on arbitrary input and arbitrary string cells survive the round-trip with the pack root preserved. MIT, zero runtime dependencies. Ships with GCF SPEC v3.3.0.

Install: npm i @blackwell-systems/gcf


Adopted by

Headlined by Chrome DevTools MCP — the #1 most-starred MCP server on GitHub (46K★), built by the Google Chrome DevTools team, which merged GCF as an experimental data format (--experimentalDataFormat=gcf) after a 4-round review.

Also running in production across the ecosystem:

  • OmniRoute (15.6K★) — AI gateway/proxy; GCF vendored into its compression engine
  • Raycast (7.5K★) — JSON→GCF converter extension in the Store
  • Speakeasyoq --format gcf for OpenAPI query output
  • NetClaw (556★) — network automation; switched from TOON to GCF
  • ctx (510★) — Claude Code tool-recommender; pip install "claude-ctx[gcf]"
  • bb — Bitbucket Cloud CLI/TUI; --format gcf
  • NeuroNest — agent-first IDE
  • Open Data Products SDK — Linux Foundation data-product toolkit
  • knowing · agent-lsp — code-intelligence + LSP-orchestration MCP servers

Using GCF in production? Open an issue to be listed.

v2.2.3

Choose a tag to compare

@github-actions github-actions released this 11 Jul 03:08

Patch release: a losslessness fix in nested-object flattening and prototype-pollution hardening in the generic decoder. No API changes; recommended for all users.

🐛 Fixes

  • Losslessness: null nested objects are no longer dropped. A nested object that was an object in some records and null at an intermediate level in others (e.g. {"meta": {"owner": null}}) was being flattened, and on decode the null reconstructed as a missing key instead of null, silently losing data. Such fields now fall back to the attachment encoding, which round-trips exactly. A top-level null still flattens (it emits - and rebuilds via the all-null rule), so compression is unaffected for that case.

🔒 Security (JS/TS only)

  • The generic decoder no longer touches Object.prototype. A __proto__ path segment in hostile GCF could pollute the prototype, and keys shadowing built-ins (toString, constructor) were misparsed. All membership checks now use Object.prototype.hasOwnProperty.call; a shared safeAssign writes a literal __proto__ as an own property; unsafe path segments are dropped and non-object intermediates guarded. Keys named toString/constructor/valueOf now round-trip correctly. (Map-based SDKs, Go/Python/Rust/Swift/Kotlin, are not affected by this class.)

✅ Tests

  • Added prototype_pollution.test.ts (nested/top-level __proto__, hostile path columns, built-in-named keys).
  • Extended the property-based round-trip fuzz to exercise the v3.2 flatten path with aligned nested objects and nulls at depth, the shape the prior scalar-only generator never produced. Verified failing on the pre-fix encoder and passing on the fix at 500k iterations.

The nested-null losslessness fix is format-level and ships in the Go/Python/Rust/Swift/Kotlin SDKs too; new shared conformance fixtures (flatten/017019) lock it in across all implementations.

Full Changelog: v2.2.2...v2.2.3

v2.2.2

Choose a tag to compare

@github-actions github-actions released this 30 Jun 12:57

Build

No API changes. Same encode/decode behavior as v2.2.1.

Full Changelog: v2.2.1...v2.2.2

v2.2.1

Choose a tag to compare

@blackwell-systems blackwell-systems released this 23 Jun 17:54

Flatten Opt-Out

  • encodeGeneric(data, { noFlatten: true }) disables nested object flattening
  • Backward compatible: encodeGeneric(data) unchanged

Bug Fixes

  • Field names containing > excluded from tabular columns (spec rule 7.4.6.1.4)
  • Field names containing > no longer eligible for flattening analysis
  • Decoder no longer treats literal > in key names as a path separator
  • Decoder accepts orphan attachments (fields excluded from column list)
  • 200K round-trips (both modes, > in keys) zero failures; 12 targeted edge case tests

Full changelog: v2.2.0...v2.2.1

Full Changelog: v2.2.0...v2.2.1

v2.2.0: Nested Object Flattening (Spec v3.2)

Choose a tag to compare

@blackwell-systems blackwell-systems released this 23 Jun 04:54

Nested Object Flattening

Encoder automatically flattens fixed-shape nested objects into > path column names. Decoder reconstructs nesting from > paths.

  • 20-48% fewer tokens on deeply nested API data
  • 100% comprehension on every frontier model
  • Zero regression on 200K random + adversarial round-trips
  • Falls back to attachment mechanism for non-flattenable cases

Install: npm install @blackwell-systems/gcf@2.2.0

Full Changelog: v2.1.2...v2.2.0

v2.1.2

Choose a tag to compare

@blackwell-systems blackwell-systems released this 18 Jun 17:42

Patch release. Fixes encoder quoting for edge cases involving bracket-colon patterns in string values. 100M fuzz iterations, zero failures.

v2.1.1

Choose a tag to compare

@blackwell-systems blackwell-systems released this 15 Jun 18:25

CommonJS support

Added CommonJS bundle (dist/cjs/index.cjs) for compatibility with CJS environments like n8n, serverless runtimes, and older Node.js projects.

The exports map now includes both import (ESM) and require (CJS) conditions. No changes needed for existing ESM consumers.

This fixes: No "exports" main defined errors when using @blackwell-systems/gcf in CommonJS projects.

v2.1.0

Choose a tag to compare

@blackwell-systems blackwell-systems released this 14 Jun 21:51

Spec v3.1 Conformance

Spec change

  • tool field in graph profile header is now optional (SHOULD be present for MCP, not required)

Bug fixes

  • Quote strings containing commas in scalar values
  • Decode v2-format indented attachments in tabular rows
  • Reject duplicate attachments on the same row
  • Reject orphan attachments on rows without ^ cells

Conformance

  • 157/157 fixtures passing
  • 23.25B+ round-trips verified across all 6 implementations, zero failures

Full spec release: gcf v3.1.0

v2.0.2: Inline Schema Encoding

Choose a tag to compare

@github-actions github-actions released this 13 Jun 06:32

v2.0.2: Inline Schema Encoding

The generic profile encoder now produces inline schema format for nested objects with 3+ scalar fields.

Breaking Changes

  • encodeGeneric output format changed (inline schemas, no attachment indentation)
  • Decoder no longer accepts v1.x indented attachment syntax
  • Comma no longer quoted in pipe-delimited contexts (only in comma-delimited inline arrays)
  • Strings starting with digits no longer quoted unless they match JSON number grammar

New Features

  • Inline object schema (^{fields}): nested objects encoded positionally
  • Shared array schemas: identical nested arrays omit field headers after first row
  • Browser-safe entry point ("browser" field in package.json): excludes Node-only packRoot/delta modules
  • 25.5% fewer tokens than TOON across 15 real-world datasets

Integrity

  • 141M lossless round-trip iterations
  • 100% comprehension accuracy on every frontier model tested
  • 156 conformance fixtures passing

Migration

- import { encodeGeneric } from '@blackwell-systems/gcf'  // works in Node
+ import { encodeGeneric } from '@blackwell-systems/gcf'  // works in Node AND browser

packRoot and encodeDelta are Node-only (require crypto). Import directly if needed:

import { packRoot } from '@blackwell-systems/gcf/dist/packroot.js'
import { encodeDelta } from '@blackwell-systems/gcf/dist/delta.js'

Full spec: https://github.com/blackwell-systems/gcf/releases/tag/v3.0.0