feat(bgcode): .bgcode decoder — walker + CRC + None/DEFLATE (DD-011 phase 1) (#188) - #233
Merged
Merged
Conversation
…-011 phase 1) (#188) New package @chestnutlabs/gcode-bgcode (14th lockstep): a license-clean, in-memory decoder for Prusa binary G-code. .bgcode is a container of plain G-code, so decoding it feeds the existing parser/dialect/IR/renderer pipeline unchanged. Decode-only. Phase 1 (DD-011 §14): the file-header + block walker (spec v1), per-block CRC32 verification, sniffBgcode/openBgcode, and None + DEFLATE compression with None encoding decoded end-to-end. MeatPack (phase 2) and heatshrink (phase 3) return honest structured ContainerErrors. All failures (bad magic/version, CRC mismatch, truncation, decompression bomb) are bounded structured errors — the DEFLATE path reuses the #131-fuzzer's unhandled-rejection guard. Clean-room from the published spec (RR-003) — NO AGPL libbgcode/MeatPack code. Deps: toolpath-core + gcode-containers (crc32/ContainerError); no three/framework/fs/net (lint-enforced). A TEST-ONLY clean-room .bgcode assembler generates fixtures (no PrusaSlicer needed); real files land in phase 4 for golden-equivalence. Registration: pack-check + build-api PACKAGES, eslint boundary block + test relaxation, pack snapshot (additive), changeset (auto fixed-group). 12 tests green incl. the DEFLATE round-trip and the decoded-gcode-→-parser bridge. typeCheck/lint/test:packages/pack:check all green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sobechestnut-dev
enabled auto-merge (squash)
July 27, 2026 19:45
sobechestnut-dev
added a commit
that referenced
this pull request
Jul 27, 2026
Adds the MeatPack encoding (both variants) to the .bgcode decoder: a GCode block encoded with
MeatPack now decodes end-to-end (optionally after DEFLATE) to plain G-code.
The decoder is a faithful TS port of the MIT jamesgopsill/meatpack unpacker (© 2025 James Gopsill;
derived from the published Prusa spec), attribution preserved — NO AGPL libbgcode/OctoPrint-MeatPack
code (RR-003 §8). MeatPack packs the 15 most common g-code chars into 4-bit nibbles (first char =
low nibble); nibble 0xF escapes a full literal byte; FF FF <cmd> toggles packing/no-spaces; the
stream starts disabled (FF FF FB enables it).
Validated by HAND-COMPUTED vectors (the nibble table applied by hand as an oracle independent of the
decoder's own table): packable line, left/right/double full-width escapes, the (\n,\n)→single-newline
special case, no-spaces + disable-packing commands, invalid-command rejection — plus block-level
integration through openBgcode (None + DEFLATE × MeatPack/MeatPack-comments). Output is bounded
(bomb defense). Real PrusaSlicer meatpack files = phase-4 golden-equivalence.
Also fixes a docs-build regression: bgcode.ts's `{@link ContainerError}` (an unresolvable
cross-package typedoc link that landed in dev via #233's squash) → a code span, restoring the
API-docs warning budget to 3/3.
heatshrink compression remains phase 3.
Co-authored-by: Nathaniel Chestnut <sobechestnut-dev@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 1 of the #188 bgcode epic, implementing accepted DD-011. Does not close #188 — phases 2–6 (MeatPack, heatshrink, container-adapter integration + golden-equivalence, adversarial corpus + §7.3 review, exit) remain.
What
New package
@chestnutlabs/gcode-bgcode(14th lockstep) — a license-clean, in-memory decoder for Prusa binary G-code..bgcodeis a container of plain G-code, soopenBgcodeyields plain G-code the existing parser/dialect/IR/renderer pipeline consumes unchanged. Decode-only.Phase 1 (DD-011 §14):
sniffBgcode/openBgcode.E_BGCODE_UNSUPPORTED_*errors.ContainerError; the DEFLATE path reuses the test(e7) phase 4: coverage-guided container fuzzing (Jazzer.js, E4 §7.3) #131-fuzzer's unhandled-rejection guard.Licensing (the whole point)
Clean-room from the published spec (RR-003) — no AGPL
libbgcode/MeatPack code. Deps:toolpath-core+gcode-containers(forcrc32/ContainerError); no three/framework/fs/net (lint-enforced by a new boundary block). A TEST-ONLY clean-room.bgcodeassembler generates fixtures without PrusaSlicer; real files land in phase 4 for golden-equivalence.Verification
12 tests green — incl. the DEFLATE round-trip, multi-block concatenation + metadata/thumbnail walk-past, CRC-mismatch/truncation/bad-magic/bad-version rejection, phase-2/3 honest errors, the bomb cap, and the decoded-gcode →
parseGcodeToIRbridge.typeCheck✓,lint✓ (0 errors), CI-liketest:packages✓ (bgcode included),pack:check✓ (additive snapshot). Registration: pack-check + build-api PACKAGES, eslint block, changeset (auto fixed-group).Note on DEFLATE flavor: phase 1 uses
deflate-raw(self-consistent fixtures); the definitive Prusa flavor is confirmed against real files in phase 4.🤖 Generated with Claude Code