Repository navigation
Release 1.0.5 - #82
Open
GhostTypes wants to merge 99 commits into
Open
GhostTypes wants to merge 99 commits into
GhostTypes wants to merge 99 commits into
Conversation
chore(deps): resolve all 67 Dependabot alerts (security)
chore: remove stale security-audit doc
docs(changelog): document unreleased work since 1.0.4-alpha.4
Following the 1.0.4 stable release: - Bump version 1.0.4-alpha.4 -> 1.0.5-alpha.1 (per CLAUDE.md lesson #9: never continue 1.0.4-alpha.N after 1.0.4 stable, or electron-updater 404s on the missing alpha.yml). Channel resolves to "alpha"/prerelease. - Sync CHANGELOG with main: consolidated [1.0.4] - 2026-05-31 entry plus a fresh empty [Unreleased]; alpha CHANGELOG is now identical to main. Verified: electron-builder reports "Channel: alpha (prerelease: true)"; pnpm install --frozen-lockfile passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
chore(release): open 1.0.5-alpha.1 cycle on alpha
Edit mode was only reachable via the undocumented CTRL+E shortcut, while the WebUI already exposed a visible toggle. Add an "Edit Layout" entry to the hamburger dropdown that toggles GridStack edit mode, mirroring the WebUI for discoverability (issue #62). - New menu item with a pencil icon and platform-aware Ctrl+E / Cmd+E hint - Dynamic label: flips between "Edit Layout" and "Exit Edit Mode" - Disabled when no printer is connected, matching edit mode availability - EditModeController gains an onStateChange subscription so the label stays in sync regardless of trigger (menu, CTRL+E, reset, printer disconnect) - Disabled menu-item styling added Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The name implied dead code or a tie to legacy *printers*, but the class is the active window chrome (window controls, hamburger menu, loading overlay) and unrelated to legacy hardware. There is no parallel "old" UI system; the component/GridStack stack is the sole renderer for printer data. - Move src/renderer/src/ui/legacy/LegacyUiController.ts to src/renderer/src/ui/shell/ShellController.ts and rename the class - Update the @fileoverview to describe it accurately as window chrome - Update references in renderer.ts and ai_docs/UI_COMPONENTS.md - Drop the stale "fallback to legacy update system" comment that referenced the already-removed updateAllPanels path No behavior change. "Legacy printer" terminology (Adventurer 3/4) is left intact as a legitimate domain term. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- emitStateChange iterates a copy of the listener array so a listener that unsubscribes during its callback is not skipped - Edit Layout menu item uses the ARIA-correct toggle semantics (role="menuitemcheckbox" + aria-checked) instead of aria-pressed, which is invalid on role="menuitem" Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
feat(ui): add Edit Layout menu item + rename LegacyUiController to ShellController
Add a "Set from Spoolman" affordance to the IFS material-station component. Clicking a slot opens a popover; the user picks a spool from the existing Spoolman picker, the spool's material/color are snapped to the AD5X's fixed 14-material / 24-color palette, and applied to the slot via the library's configureSlot (msConfig_cmd). - src/shared/ifs-palette.ts: pure palette + nearestColor (CIEDE2000) + nearestMaterial (exact-then-leading-token), with a Jest spec. - Apply path: renderer -> preload (material.configureSlot) -> IPC material:configure-slot -> PrinterBackendManager.configureMaterialSlot -> AD5XBackend.configureSlot -> control.configureSlot. - Spool picker reused via a `purpose` flag; slot-config mode returns the picked spool without changing the tracked active spool. - Color falls back color_hex -> first multi_color_hexes; an unrecognized material keeps the slot's current material. Gated on AD5X + Spoolman. Bumps @ghosttypes/ff-api to ^1.3.2 for configureSlot/SlotAction. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace the small "Set from Spoolman" popover with a full slot editor
dialog: a material dropdown (14 recognized materials) and a grid of the
24 recognized color swatches, pre-seeded from the slot's current
material/color. Works with Spoolman disabled.
- material:set-slot IPC + material.setSlot preload: apply an explicit
material + color to a slot (no Spoolman dependency).
- Gate the "Set from Spoolman" shortcut on the global Spoolman config
(enabled + URL), not on spoolman.getStatus() - which the backend
hard-disables for AD5X material-station printers, i.e. exactly the
printers this feature targets. When used it pre-fills the dialog from
the picked spool (snapped to the palette) for review before Apply.
- SpoolmanIntegrationService.isContextSupported now detects AD5X via the
firmware PID (FiveMClient.isAD5X) + material-station capability instead
of the brittle printerModel.startsWith('AD5') string match.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Discovery model detection was name-based: detectPrinterFamily only matched "5m"/"ad5x", so a Creator 5 fell through to the legacy connection path and failed with "Failed to establish final connection" despite speaking the same modern HTTP + check-code protocol. Route on the authoritative, firmware-set USB product ID (discovery packet offset 0x88) instead, falling back to the immutable Machine Type (TypeName) only for manual IP connections - never the user-editable Machine Name. - DiscoveredPrinter now carries productId/productType; PrinterDiscoveryService propagates them from the ff-api discovery result (previously dropped). - Add NEW_API_PRODUCT_IDS map and detectPrinterFamilyFromId / detectPrinterModelTypeFromId; use them in ConnectionFlowManager. - Cover PID-first routing with PrinterUtils tests. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…uting Route the Creator 5 series to a dedicated backend and surface its per-tool temperatures in the UI. Builds on @ghosttypes/ff-api 1.3.4. - Creator5Backend extends AD5XBackend: inherits the 4-slot material station and dual HTTP + TCP transport, and adds per-tool nozzle temps in status, built-in camera, a Creator 5 Pro filtration override (its /product under-reports the fans), door-sensor gating (Pro only), and native /printGcode job starting. - Route creator-5 / creator-5-pro to Creator5Backend (was the interim 5M backend). - Add a tool-temps grid component showing the 4 nozzle temperatures; register it in the component catalog and both component factories. - Thread toolTemps through PrinterStatus and PrinterDataTransformer so the card (and the web UI's status data) receive per-tool temperatures. - Bump @ghosttypes/ff-api to ^1.3.4. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The Creator 5 / 5 Pro are HTTP-only (no legacy TCP on 8899), which is what was breaking the old TCP-first connect. This wires them up properly and cleans up the material handling around them. - Detect C5/5 Pro by USB product ID, use the FiveMClient in httpOnly mode (ff-api ^1.3.6) - Route temperature control over HTTP when there's no TCP client - Add C5-specific filament palette (24 colors, 21 materials) - Renamed ifs-station to material-station Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Bump version and add changelog for the Creator 5 connection fix and material-station updates. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A Creator 5 / 5 Pro saved as legacy under an older build still failed to connect: the saved forceLegacyMode flag routed it down the legacy TCP path, which hangs forever because these printers have no TCP server on 8899. HTTP-only models now always connect over HTTP regardless of forceLegacyMode (in both the discovery and saved-details paths), and the bad flag is healed on the next successful connect. Adds regression tests for the override. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Accidentally added in the previous commit; this is a local working note that should not be in the repo. Keeps the file on disk, untracked. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…very Carry the product ID through the discovery selection so the Creator 5 / 5 Pro is identified and connects over HTTP instead of falling back to legacy TCP. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Expose material slot-config API in component dialog preload (material namespace + slot-config Spoolman flow parity).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…-card migration Resolve the remaining Creator 5 / 5 Pro control gaps and the layout migration that left the generic temperature card in place. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The per-tool Off button now turns the tool head off: ff-api 1.6.1 writes 0 to the nozzle instead of the -100 sentinel the Creator 5 firmware ignores in the nozzles array. Tool heads are also now displayed as T1-T4 to match the printer's own UI (the wire protocol/index stays 0-based). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Multi-tool temperature card (per-tool + bed + chamber), read-only TVOC display, and a general material-station card/slot editor for the built-in WebUI, at parity with the desktop Creator 5 implementation.
The range check already rejects values above CHAMBER_MAX_TEMP, so the follow-up Math.min was dead code. Flagged by Gemini Code Assist on the standalone WebUI PR.
Comment-only cleanup across 8 files; no code behavior changes. - Remove dead commented-out code: the MainProcessPollingCoordinator import in index.ts and the DevTools auto-open block in WindowConfig.ts. The setupDevTools no-op now says why it stays. - Delete stale notes that no longer match behavior: Web UI polling remarks in WebUIManager.ts and the palette drag-forwarding note in palette-handlers.ts. - Fix the handler path in DialogHandlers.ts to the real location, src/main/ipc/handlers/. - Replace the hardcoded per-dialog size list in DialogWindowFactory.ts with a pointer to WINDOW_SIZES, so the docs cannot drift from the source of truth. - Reword the job-selected TODO in job-handlers.ts and the factory note in gridController.ts for clarity. Both still reference issue #77 where relevant.
Rewrote 27 oversized @fileoverview JSDoc headers (36-77 lines each) into short 5-12 line summaries that keep the operative facts and drop the boilerplate: feature bullet lists, usage code samples, redundant export inventories, and prose size/symbol tables that duplicated WindowTypes.ts and the export statements. The old headers were a second source of truth that had already drifted: stale enum lists (missing 7 window types), wrong dialog sizes (e.g. Settings "600x500" vs actual 820x820), a claim of automatic DevTools that is now an intentional no-op, a 30s poll claim vs the real 3000ms constant, and a described nested-path helper that does not exist. The condensed headers keep non-obvious constraints (destroyed-window rule, security invariants, polling pause rationale) and point to the real sources of truth. Continues the comment-hygiene series (RE-term scrub, stacked-header dedupe, stale-comment fixes). Comment-only change: -1288/+165 lines, no executable code touched.
Normalize file headers to the single-tag @fileoverview convention: - Strip redundant JSDoc @module tags from 96 files where they only restated the file path next to an existing @fileoverview. Kept @module only in the two ambient declaration files (global.d.ts, global-main.d.ts) where the tag genuinely names the module for consumers. - Drop the 9 "@author FlashForgeUI Team" lines (component-dialog / shortcut-config cluster). - Convert AutoConnectService.ts's lone old-generation essay header to the standard short @fileoverview style. 97 files, comments only (-215/+4). The repo's own docs:check gate (scripts/check-fileoverview.go) passes.
Comment-only cleanup; no code behavior changes.
- Remove 32 narration comments from the three MultiContext main-process services (NotificationCoordinator, SpoolmanTracker, TemperatureMonitor). Each comment restated the line directly below it ("Emit event", "Store tracker", "Clear map", etc.) and carried no why or caveat.
- Replace duplicated override JSDoc with {@inheritdoc BaseComponent.update} in five renderer UI components (additional-info, filtration-controls, model-preview, printer-status, temperature-controls), plus {@inheritdoc BaseComponent.setupEventListeners} in the two display-only components. The base class already carries the canonical documentation.
Final stage of the comment-hygiene series (RE-term scrub, stacked-header dedupe, stale-comment fixes, header condensing, @module/@author normalization).
Remove the dead `/// <reference types="../../types/global.d.ts" />` directives from component-dialog.ts, shortcut-config-dialog.ts, and spoolman-dialog-renderer.ts. The directives pointed at a path that no longer exists (global.d.ts moved to src/shared/types/), and `types=` resolves against @types packages rather than relative paths, so they were silent no-ops. The global Window augmentations already load ambient via the tsconfig.web.json include of `src/shared/**/*`, so no replacement is needed — full typecheck (web + e2e) passes.
Consolidate the twice-vendored VideoRTC player (two identical 701-line copies) into one canonical copy at src/shared/lib/video-rtc.js. - Renderer: camera-preview.ts imports via the existing @shared alias (rename-detected move, history preserved) - WebUI: copy-webui-assets.cjs vendors from the shared path; the static copy at src/main/webui/static/lib/ is deleted, runtime URL and version stamping unchanged - Drop 4 commented-out console.debug lines from the moved file; neutral @fileoverview covering both consumption paths Verified: full typecheck, webui build (?v= stamp confirmed), electron-vite build, 55 jest suites / 1899 tests, and a live GUI run against a real AD5X.
Matching dialog: the confirm button now reads Confirm on the desktop dialog and the built-in WebUI. It previously read Start Print and promised an action the dialog does not perform. Color mismatches now fill a warning card of their own above the two lists; the card rebuilds on every change, so every mismatch stays visible instead of only the most recent one. Mapping rows gained a color swatch on both sides. Upload dialog: confirmed mappings show as chips with tool, slot, material name, and a swatch per side. The primary button is named after what it does: Start Print with Start Now ticked, Send File otherwise (it read OK before). Slicer warnings moved into their own card, and the print-time highlight became a full-width banner. On phone widths the WebUI stacks the preview above the metadata and keeps both checkboxes on one line. Desktop uploader: the window is taller, its minimum height was raised, and the metadata pane shows a slim scrollbar instead of hiding overflow. Added scripts/ui-shot.mjs, a headless Playwright harness that screenshots dialogs and WebUI screens from fixtures without running the app. It ships four fixtures, the ui:shot npm script, and a .gitignore entry for .ui-shots/. CHANGELOG.md records the rework under [Unreleased]. Verified: type-check (app + e2e), 55 jest suites / 1899 tests, live GUI test against a real AD5X with a material-station 3MF.
Remove the headless ui-shot screenshot harness added in c9506a9. The tool turned out not to be worth keeping. Deleted scripts/ui-shot.mjs, its four DOM fixtures under scripts/ui-shot-fixtures/, and the ui:shot npm script. Removed the .gitignore block that ignored .ui-shots/ and cleaned the local .ui-shots/ output directory. No CHANGELOG changes needed — the harness was never mentioned in the changelog entries.
The emulator E2E job checked out flashforge-emulator-v2 at the branch head, so any emulator change could silently break or silently change this CI with no ref to bisect against. Pin to the v0.2.0 release tag (bump deliberately; workflow_dispatch accepts emulator-ref to test against another ref). The emulator's npm ci now runs with ELECTRON_SKIP_BINARY_DOWNLOAD=1: only the headless runtime is used here, and the app-under-test gets its Electron binary from this repo's node_modules, so the emulator's ~110 MB download was pure waste.
- Port of FlashForgeWebUI bf00b8b: per-tool upload estimates, serial-keyed stores, terminal-only deduction - Completion deducts full estimates; cancel deducts progress fraction; pause/resume deduct nothing - Slot-to-spool assignments via IPC + embedded-webui routes, exposed in both preload surfaces - Exactly-once via reserve-first ledger; Spoolman errors never affect printing
- Port of FlashForgeWebUI 7182227: printer-reported capture at print start, exactly-one-spool rule - Hooks both start paths (IPC + embedded-webui) behind startNow gating; capture never blocks the start - One delayed retry for recent-list propagation lag; job-picker indicator with themed styling
Port of FlashForgeWebUI 5149204. Material-station printers report no per-tool filament use. The old flow kept a spool per slot for each printer serial, but the spools on the printer can change at any time and the app cannot see that. Now the matching dialog asks for the spool of each tool, or "Do not track", in the desktop dialog and the built-in WebUI. The choice applies to that one print only. The app deletes it when the print ends. - Add a spool picker to the desktop and WebUI matching dialogs. - Charge the full slicer estimate per tool when a print completes. - Charge a cancelled print per tool from the 3MF gcode, which the printer reports progress against by byte position. - Charge the last saved progress, marked approximate, when a print ended while the app was not running. - Track AD5X stored files that start through the matching dialog. - Remove the slot-to-spool store, its IPC channel and route, and the slot assignment in the Material Station editor. - Send the gcode tool number (filament id - 1), not the list position, from the desktop uploader and the built-in WebUI. - Let the WebUI matching dialog wait up to 15 s for the station status. - Add unit tests and emulator e2e tests with a tool-change fixture.
The per-job Spoolman e2e tests need 3MF slice weights per tool and AD5X tool ids 0-3. Emulator v0.4.0 adds both.
Move the unreleased CHANGELOG entries into a dated 1.0.5-alpha.13 section. Bump the package version to match. Add a note that Creator 5 tracking is not yet tested on a real printer.
From PR #80. In headless mode the backend-ready startForPrinter() and HeadlessManager.startWebUI() both call start(). Two independent attempts race to bind the same port, the loser fails with EADDRINUSE, and headless exits. - Make start() share one in-flight attempt. Clear it in a finally() callback, which always runs after the assignment, so a failed attempt can be retried. The PR cleared it synchronously, which left a settled attempt in place when start() failed before its first await. - Make stop() wait for an in-flight start, so the start cannot mark the server running again after the stop. - Kill go2rtc on process exit. will-quit does not fire on process.exit(), which the headless failure paths use, so go2rtc was orphaned holding its ports. Register the listener once in the constructor, not on every start. - Add tests for concurrent starts, retry after a failed start, and stop during a start. Co-Authored-By: jsalmon00 <jsalmon00@users.noreply.github.com>
Sync main's post-1.0.4 commits back into alpha ahead of the 1.0.5 stable release so the alpha -> main PR merges cleanly. Alpha already carried the Dependabot fixes and a newer README, so every conflict resolves to alpha.
| return raw; | ||
| } | ||
| if (entry.method === 8) { | ||
| return raw.pipe(zlib.createInflateRaw()); |
Comment on lines
+29
to
+34
| import { | ||
| DEFAULT_HEADLESS_PRINTERS, | ||
| type HeadlessPrinter, | ||
| type HeadlessWebUI, | ||
| startHeadlessWebUI, | ||
| } from './helpers/headless-webui'; |
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.
Release PR for FlashForgeUI 1.0.5 stable. It promotes the 1.0.5 alpha cycle (alpha.1 through alpha.13, plus the headless/go2rtc fixes from #80) to
main.Merge with a merge commit, not a squash, so
mainandalphakeep a shared history.What's in it
package.jsonis set to1.0.5, so the updater channel islatest.## [1.0.5] - 2026-10-10section rolls up the whole alpha cycle. The release workflow reads its notes from this section.pnpm auditgoes from 104 findings (5 critical) to 9 (8 high, 1 moderate), andpnpm audit --prodreports none. What remains:<webview>,contextIsolationon,nodeIntegrationoff, and only local content is loaded.CONTRIBUTING.mddescribing the alpha → main workflow, and a README refresh with fixed wiki links, new feature rows, Creator 5 notes and build prerequisites.v0.4.0.Verification (local, Windows)
type-check,lintandbuildpass.EADDRINUSE) failures and 2 Creator 5 failures.build:winproducesFlashForgeUI-Setup-1.0.5.exeandlatest.yml.pnpm install --frozen-lockfilesucceeds.Before cutting the release
gh workflow run release.yml --ref main -f version=1.0.5 -f prerelease=falsemainback intoalphaand bump to1.0.6-alpha.1