Oleksandr ShyshatskyiandClaude Opus 5 2b3772664a Close six gates that passed while checking nothing
Every one of these reported success on a condition it could not fail, which is
worse than having no gate at all -- this repo has been bitten by it three times
already (test-abi.sh, lint-danger, the old skip protocol) and the harness
docstrings cite those as the reason it exists.

run_pytest scored a run that collected NOTHING as a pass. pytest exits 5 and
writes tests="0"; passed = total - failures - skipped then gave 0/0/0 and the
gate went green, with proc.returncode never read. Renaming test/integration/,
breaking a conftest import or adding a collect_ignore would have stopped all 54
tests while make test and both CI jobs stayed green. Reproduced before fixing.

check_no_bashisms passed when shellcheck examined no files: with no targets it
writes usage to stderr and exits 1, leaving the SC3xxx filter empty.
check_shell_syntax has an empty-target guard; this one did not. Moving payload/
would have retired the ash-compatibility check in silence. Its exit code is now
checked too, so a usage or file error cannot read as "no findings".

case-install.sh's "a service owns Klipper startup" grepped for the string
start.sh anywhere under init.d/ -- and S70klipper and S60web both name it in
their header COMMENTS, so deleting the line that actually runs it still passed.
Now requires a non-comment line.

case-install.sh scored the genuine FlashForge binary at firmwareExe as ok
("no UI replacement requested"). patch.sh installs the wrapper unconditionally
and HelixScreen is the only UI, so that outcome means the install did not take
-- and it silently switched off four further assertions plus the whole boot-3
UI block, making "the install produced nothing" a passing run.

case-mcu-bringup.sh printed SKIP and exit 0 when the interpreter was not
executable, which Replica.run_case scores as a passing gate: the import test,
the resolution check, the bring-up run, the ttyS7 coverage and the
LD_LIBRARY_PATH control were all skipped and reported clean. seed-prog.sh
already hard-fails on a MISSING interpreter, so this window is a broken
replica, not an absent feature. It fails now.

verify.sh's ship-boundary check uses relative finds, so from any cwd but the
repo root host.md5 is empty, the join matches nothing, and it reported
"package carries nothing from bin/, test/ or docker/" having compared nothing
-- the only check keeping config.env off a USB stick.

Full suite with every gate tightened: 12 passed, 0 failed, 0 skipped. Nothing
was hiding behind them.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-24 19:48:45 +03:00
2026-08-24 12:24:37 +03:00

creator5-custom-firmware

Custom firmware for the FlashForge Creator 5 and Creator 5 Pro.

It installs the way a normal FlashForge update does: copy one file to a USB stick, plug it in, power the printer on. No jailbreak, no soldering, no opening the case, no ssh needed to get started — the printer's own updater does the work.

Unofficial and unaffiliated with FlashForge. It voids your warranty and you are responsible for your machine. Nothing here has been installed on a printer yet — see Status before you flash anything.


What you get

Mainsail in your browser The full Klipper web interface at http://<printer-ip>/ — upload gcode, watch the print, tune on the fly. Moonraker comes with it, so anything that speaks the Klipper API works.
A shell on your printer ssh as root. Dropbear is already running on stock firmware; this simply gives you a password you know. Official releases have one baked in at build time; a package you build yourself without setting ROOT_PW_HASH picks a random password and writes it to anvil-password.txt on your USB stick.
Real toolchanger Klipper A current Klipper with proper tool-change support, replacing the 0.12-era tree FlashForge ships.
A current Moonraker Replacing the 2022 build FlashForge ships, which is too old for today's Mainsail — with it, the camera panel never appears at all.
A modern touchscreen UI HelixScreen replaces the stock interface on the printer's own screen.
Nothing you cannot undo Flashing the stock FlashForge package restores every file the mod replaced, and the printer behaves as it did before.

The stock boot process and the stock recovery path are left in place. The mod's whole integration point is one file — firmwareExe, the stock application — and nothing in rcS or app_startup.sh is patched, so FlashForge's own updater is still what installs and still what reverts. Flashing the stock package restores everything the mod replaced: firmwareExe, start.sh, the Klipper tree, printer.base.cfg and shadow. What it does not do is scrub the disk — the payload under /usr/data/anvil, the ff-*.cfg in /usr/data/config/ and the install log stay behind, inert, because nothing references them any more. make test-recovery asserts exactly that, on a replica of the machine.

What you give up

That one file is FlashForge's whole application, so anything that lived inside it rather than in a separate service goes with it:

  • The FlashForge network API on :8898, and with it FlashPrint, Orca's FlashForge profile and the mobile app. Moonraker's API takes over, which is what Mainsail, OrcaSlicer's Klipper/Moonraker upload and Fluidd speak. Slice for the toolchanger and send it there instead.

The camera is not on that list, though the app did serve it: mjpg-streamer is already on the printer, unused, and this firmware simply starts it. The stream shows up in Mainsail as usual.

Flashing the stock package brings the API back.


Which file do I need

Creator 5 and Creator 5 Pro are not interchangeable. Each package is built for one model and the printer refuses a package meant for the other, so pick the file whose name matches your machine:

Your printer The file
Creator 5 Creator5-anvil-<date>.tgz
Creator 5 Pro Creator5Pro-anvil-<date>.tgz

Not sure which you have? On the printer: Settings → About.


How to flash

  1. Format a USB stick as FAT32. Not exFAT, not NTFS.
  2. Copy the file for your model to the root of the stick. Not in a folder. Leave the name exactly as it is — the printer looks for that pattern.
  3. Power the printer off.
  4. Plug the stick in and power the printer on. It finds the package by itself, shows the update screen and installs. This takes a few minutes.
  5. Wait for it to reboot on its own, then pull the stick.

Afterwards, http://<printer-ip>/ gets you Mainsail. The install log is on the printer at /usr/data/anvil-install.log.

Two things to do first

One file per model, one flash — but do these before you start, because they are the cheap version of every problem people hit:

  • Check the model. A Creator5Pro- package will not install on a Creator 5 and vice versa; the printer refuses it outright, which is annoying rather than dangerous, but it is the most common reason a flash "does nothing".
  • Put the stock FlashForge package for your model on a second stick, and keep it separate. That stick is the undo button — see below.

The go/no-go checks — what to look at after the flash, in what order, and what means stop — are in docs/hardware-testing.md. Read it before the first flash.


If something goes wrong

Keep a copy of the stock FlashForge package for your model on a spare USB stick before you start. That stick is the undo button: flashing it restores every file this firmware touches. It is a normal FlashForge update, so it installs the same way — stick in, power on.

A few things are deliberately built in so a bad flash cannot cost you the machine:

  • A crashing UI cannot lock you out. The screen is not how you reach the printer: ssh and Mainsail come up from their own services, before and independently of the UI, so a dead screen costs you the screen and nothing else — you can still print. It is not repairable on the machine, though: HelixScreen is the only UI there is, and getting a working screen back means flashing a package again. MOD_UI=0 in /usr/data/anvil/anvil.conf stops it being started at all.
  • ssh stays up even when the screen does not, so you can get in and look.
  • Your printer.cfg is never overwritten — it is not a file this firmware ships, and it is where your changes belong. The configs the mod does ship (ff-*.cfg, printer.base.cfg) are overwritten on every update, so put overrides in printer.cfg after the includes rather than editing them: Klipper merges same-named sections and the last value of an option wins, so you restate only what you are changing. Each of those files says so in its own header. moonraker.conf works the same way, with moonraker-custom.conf as its seam: that file is created once, never overwritten, and included last, so your settings win. (Keep it — Moonraker refuses to start if the include matches nothing.)
  • The kernel and the motion board are never touched by a normal package.

More detail, including what to do when the printer will not boot at all: docs/hardware-testing.md.


Status

No package has been installed on a real printer yet. The build pipeline and the full test suite pass — including the end-to-end update test, where the package sits on a real FAT filesystem in a replica of the printer and the machine's own boot script finds it, installs it, and boots again with the mod running. That replica is the printer's real filesystem running its real binaries. It is still not a machine.

Have the stock package for your model on a spare stick before you begin.


Documentation

docs/hardware-testing.md The on-hardware procedure, with the checks that say go or stop
docs/how-it-works.md How the mod hooks into the stock firmware, and what the stock firmware does that surprises people
docs/building.md Building your own packages from a stock FlashForge one
docs/testing.md The test suite, and how we know a package does not brick a printer
docs/printer-replica.md The printer replica: what is authentic, what is not
docs/toolchange.md The toolchanger mod: the ff_* Klipper extras, the ff-*.cfg configs, and the Z offsets to get right before you print
docs/notes/ Reverse-engineering notes on the stock firmware, behind the toolchanger work
S
Description
Custom firmware for the FlashForge Creator 5 / Creator 5 Pro: Klipper, Mainsail, ssh and HelixScreen, installed by copying one file to a USB stick
Readme
6.5 MiB
0 Stars 1 Watchers 0 Forks
2026-09-24 11:56:02 -05:00
Languages
Python 59.6%
Shell 26.2%
C 11%
G-code 1.9%
Makefile 1.3%