The two "0.0.0.0" comparisons in test_support_helpers verify the
support-bundle net.info[*].ip redaction sentinel (mirrors the
support.py:1193 annotation), not a socket bind. Annotate inline.
The support bundle shipped support-info.json + bambuddy.log, but the raw
shape of the printer's MQTT push_status — the field that blocks per-model
work like AMS Backup detection (deferred in 85fbd7fc) and every vt_tray /
vir_slot / mapping shape regression — was never captured.
Each connected printer now contributes push-status/printer-{i}.json with
{model, firmware_version, captured_at, raw_data}, indexed against
support-info.json["printers"]. Two-pass redaction: a structural walk
drops user-private keys (subtask_name, gcode_file, subtask_id, task_id,
project_id, design_id, profile_id, model_id, gcode_state,
gcode_file_prepare_percent) and rewrites net.info[*].ip to 0.0.0.0
(matches the #1429 VP bridge fix); then the JSON runs through the same
DB-derived sensitive_strings sanitizer the log path uses, catching any
printer name / serial / access code / cloud email that leaked into a
nested string field.
print.cfg, print.option, ams, vt_tray, vir_slot, mapping,
ams_extruder_map, and hardware fields are all preserved — those are the
fields per-model work needs.
Always-on inside the existing debug-logging-required gate; no opt-in
toggle (the bundle is already user-initiated and downloads locally
before the user chooses to send).
Adds a passive log-health check that complements the active Connection
Diagnostic. Scans Bambuddy's recent app log against a curated allowlist
catalog of known failure signatures (rejected access code, FTPS :990
timeout, FTPS TLS failure, flapping MQTT, unreachable camera, SQLite
"database is locked" contention), dedupes and classifies each finding
as layer8/environment/bug, and deep-links to the troubleshooting wiki.
Sample log lines are sanitized before they leave the process. Exposed
via GET /system/health and surfaced on two surfaces sharing one
SystemHealthPanel component: a System Health section on the System
page, and inline in the bug reporter when the form opens.
The Add-Printer and Edit-Printer dialogs gained a setup-time pre-flight:
saving runs the connection diagnostic and, on a failed check, warns with
a "save anyway" escape hatch instead of silently saving a printer that
will immediately show offline.
Log read/parse/sanitize primitives extracted from routes/support.py into
a shared services/log_reader.py (behaviour-preserving); affected support
tests repointed accordingly.
Tests: test_log_health.py (11), test_system_api.py (2 new),
SystemHealthPanel + BugReportBubble + AddPrinterPreflight +
EditPrinterPreflight (8 frontend). All strings translated across the 9
locales. Backend ruff clean, full unit suite green, frontend build +
eslint clean, i18n parity green.
Issue #1312 follow-up. Investigation traced the "Name cannot be empty"
report to a sidecar image pre-dating the /profiles/bundle endpoint
addition. Two changes so the next occurrence is self-diagnosable from
the support bundle without a manual curl.
Backend: new _fetch_slicer_health(url) helper does a 2s GET on /health,
walks every non-dataPath key under checks looking for a version field
(the wrapper labels both sidecars as checks.orcaslicer regardless of
which CLI is bundled). _collect_slicer_api_info now exposes
bambu_studio_version and orcaslicer_version. Strips trailing slash
before appending /health to avoid double-slash 404s.
Docs: bambuddy-wiki/docs/features/slicer-api.md gains a Quick Start
callout that branch-built sidecars don't auto-update, a corrected
/health troubleshooting entry (both "unknown" version and "orcaslicer"
field name on bambu-studio-api are cosmetic wrapper bugs, not stale-
image indicators), a new "Name cannot be empty" troubleshooting entry,
and an Updating section that requires --no-cache --pull together
(BuildKit caches the git context separately from layers, so --no-cache
alone silently reuses the old checkout).
The settings-table passthrough auto-captured everything in `settings` (with
sensitive-key redaction), but features storing config in dedicated tables
were invisible. Triaging recent OIDC / 2FA / group bugs and the X1C slicer
investigation needed data that wasn't in the bundle.
New blocks in _collect_support_info:
- auth: OIDC providers (cleartext names, no secrets), TOTP / OTP /
API-key / long-lived-token / group counts
- library: file / folder / external / trash / makerworld totals
- inventory: spool + k-profile counts
- queue: pending count, oldest pending age
- maintenance: items total + enabled
- integrations.github_backup: providers used + recent failures
- integrations.slicer_api: enabled, URL source, reachability ping
- per-printer obico_enabled flag
Plus three smaller fixes caught testing against a real bundle:
- mqtt_broker no longer leaks (broker keyword added)
- virtual_printer_tailscale_auth_key no longer leaks (auth_key keyword
+ tskey- value-prefix safety net for future Tailscale settings)
- slicer-API reachability check now mirrors the route's three-level URL
precedence (DB → env var → default), instead of only looking at the
DB setting. Previously returned null for every installation running
the sidecar via env var or default port — i.e. most of them.
Settings dump now retains every key from the Settings table and replaces
sensitive values with [REDACTED] instead of dropping the row. New config
flags automatically surface in future bundles without a code change.
Adds integrations.spoolbuddy with per-device firmware, NFC/scale hardware,
calibration, online state and uptime — anonymized (no hostnames, IPs or
device IDs). Both /support/bundle and the bug-report bubble benefit, since
they share _collect_support_info().
Settings → Support → Debug Logging elevated httpx/httpcore to DEBUG,
which makes httpx log every outbound request URL. For Discord and
generic webhook notifications the bearer token is embedded in the URL
path, so users who turned on debug logging to capture a support bundle
were writing their webhook tokens straight into bambuddy.log.
Pin httpx/httpcore to WARNING regardless of the debug toggle. paho.mqtt
still honours debug. Users who enabled debug logging while notifications
were sending must rotate any exposed Discord/webhook URLs — the token
is the path, so the whole URL has to be regenerated in the provider UI.
Four support package improvements:
1. Mask first two octets of subnet IPs in support info
(192.168.1.0/24 → x.x.1.0/24) to avoid leaking private network
addresses.
2. Fix Docker network_mode_hint detection. The old heuristic
(interface count > 2) always reported "bridge" on single-NIC
hosts because get_network_interfaces() excludes Docker
interfaces. Now checks for docker0/br-*/veth* visibility via
socket.if_nameindex() — these are only visible in host mode.
3. Parse MQTT "fun" field at top level of payload (not just inside
"print" key). Some firmware versions send it there, which
explains why developer_mode was null for most users.
4. Add virtual_printers section to support info with mode, model,
enabled/running status, and pending file count.
Suppress SQL/aiosqlite debug noise (~90% log volume reduction), add
caller-traced PRINT COMMAND logging to start_print(), log scheduler
queue checks, tighten stale archive ilike match to exact match, and
warn on multiple queue items in "printing" status. Includes 18 new
unit tests.