bambu-printer-mcp 1.1.26 → 1.1.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CONTRIBUTORS.md +4 -0
- package/README.md +43 -8
- package/dist/bambu-native.d.ts +55 -0
- package/dist/bambu-native.js +212 -13
- package/dist/index.js +154 -26
- package/dist/printers/bambu.d.ts +29 -2
- package/dist/printers/bambu.js +45 -12
- package/dist/safety/hidden-hms.d.ts +32 -0
- package/dist/safety/hidden-hms.js +405 -0
- package/dist/safety/print-file.js +54 -4
- package/dist/safety/printer-state.d.ts +9 -0
- package/dist/safety/printer-state.js +80 -13
- package/dist/slicer/profile-files.d.ts +2 -0
- package/dist/slicer/profile-files.js +24 -0
- package/dist/slicer/profile-flatten.js +27 -13
- package/dist/stl/stl-manipulator.d.ts +1 -0
- package/dist/stl/stl-manipulator.js +6 -8
- package/native/bambu-native-print.cpp +100 -26
- package/package.json +7 -5
- package/scripts/build-bambu-native.sh +53 -0
- package/scripts/setup-bambu-native.mjs +372 -0
- package/src/bambu-native.ts +229 -14
- package/src/index.ts +152 -25
- package/src/printers/bambu.ts +51 -12
- package/src/safety/hidden-hms.ts +406 -0
- package/src/safety/print-file.ts +43 -4
- package/src/safety/printer-state.ts +85 -13
- package/src/slicer/profile-files.ts +21 -0
- package/src/slicer/profile-flatten.ts +34 -11
- package/src/stl/stl-manipulator.ts +7 -10
- package/scripts/build-bambu-native.zsh +0 -33
package/CONTRIBUTORS.md
CHANGED
|
@@ -6,6 +6,9 @@ Thank you to everyone who builds, tests, reports problems, and shares real print
|
|
|
6
6
|
|
|
7
7
|
| Contributor | Contribution |
|
|
8
8
|
| --- | --- |
|
|
9
|
+
| [mygrexit](https://github.com/mygrexit) | Contributes pinned x86-64 Linux X2D native setup, emergency routing and one-shot cleanup in [#56](https://github.com/DMontgomery40/bambu-printer-mcp/pull/56), checked Orca/time-lapse G-code forms in [#57](https://github.com/DMontgomery40/bambu-printer-mcp/pull/57), and model-specific hidden-HMS notices in [#58](https://github.com/DMontgomery40/bambu-printer-mcp/pull/58). Supplies regressions, review corrections, and contributor-reported Debian/X2D read-only, heater-off and print-start evidence in [#55](https://github.com/DMontgomery40/bambu-printer-mcp/issues/55); maintainer validation is offline and mocked. |
|
|
10
|
+
| [patrikmadoran-cyber](https://github.com/patrikmadoran-cyber) | Adds explicit Standard/High Flow nozzle selection across slicing and print auto-slicing in [#54](https://github.com/DMontgomery40/bambu-printer-mcp/pull/54), with unsupported-variant regressions and real Windows BambuStudio 02.06.00.51 H2S 0.6 slicing evidence. No physical print is claimed. |
|
|
11
|
+
| [Patrick Juchli (@patrickjuchli)](https://github.com/patrickjuchli) | Maintains basic-ftp and supplies the 6.2.3 fixes for rejected-command recovery, asynchronous credential-error crashes, and password redaction used by direct FTPS transfers. |
|
|
9
12
|
| [Aleksei Popovich (alexpapay)](https://github.com/alexpapay) | Fixes cross-platform AMS profile resolution and packed P2S chamber status in [#43](https://github.com/DMontgomery40/bambu-printer-mcp/pull/43), contributes regressions, and supplies read-only Windows P2S/AMS 2 Pro status and local slicing evidence. No physical print is claimed for this contribution. |
|
|
10
13
|
| [Adam (@adamkaplan)](https://github.com/adamkaplan) | Identifies the reversed H2C/H2D Pro serial prefixes in [#47](https://github.com/DMontgomery40/bambu-printer-mcp/issues/47), verifies corrected H2C status locally, and isolates the official H2C startup commands and config-block marker failure in [#48](https://github.com/DMontgomery40/bambu-printer-mcp/issues/48). Provides exact Bambu Studio version/template hash and unsafe-file reproductions; maintainer validation is offline and mocked. |
|
|
11
14
|
| [travismcashan](https://github.com/travismcashan) | Reports stock X2D material-switch and runout-purge rejection, misleading unchecked confirmation, and stdout diagnostics in [#44](https://github.com/DMontgomery40/bambu-printer-mcp/issues/44). Supplies exact preset syntax and firmware evidence, then reports a clean physical X2D cube print with a local workaround; maintainer validation remains isolated and mocked. Reports the accepted native job and subsequent helper teardown crash in [#46](https://github.com/DMontgomery40/bambu-printer-mcp/issues/46), with completed-print and macOS crash evidence informing result preservation and duplicate-print warnings. |
|
|
@@ -13,6 +16,7 @@ Thank you to everyone who builds, tests, reports problems, and shares real print
|
|
|
13
16
|
| [Steavie (steavie)](https://github.com/steavie) | Reports the reversed A1/A1 mini serial prefixes in [#39](https://github.com/DMontgomery40/bambu-printer-mcp/issues/39), with A1 status and configuration evidence that identifies the status and fresh-identity regression. |
|
|
14
17
|
| [JaviOFC](https://github.com/JaviOFC) | Reports the X2D identity rejection in [#36](https://github.com/DMontgomery40/bambu-printer-mcp/issues/36) and supplies current firmware, connection-mode, status-field, serial-prefix, and cloud-job evidence showing that `model_id` can contain a print-job identifier while `model` correctly identifies the printer. |
|
|
15
18
|
| [Izzy Mansurov (sapoepsilon)](https://github.com/sapoepsilon) | Fixes Bambu Studio 02.08 P2S extruder-variant metadata and airduct-command inspection in [#33](https://github.com/DMontgomery40/bambu-printer-mcp/pull/33). Supplies regression tests and offline inspection evidence from four real P2S 0.6 mm PLA/PETG jobs and unsafe mutated copies; this contribution does not claim a physical print. |
|
|
19
|
+
| [Bambuddy](https://github.com/maziggy/bambuddy) contributors | Document that Bambu lists some `hms[]` codes with empty text and never shows them, with P2S evidence for `0500-0600-0002-0070` and H2C evidence for `-0005` and `-0006` in [#2728](https://github.com/maziggy/bambuddy/issues/2728) and [#1840](https://github.com/maziggy/bambuddy/issues/1840); this informs the hidden-HMS notice handling. |
|
|
16
20
|
| [Boardy (@boardyai)](https://x.com/boardyai) | Raises the nozzle-verification question that informs the added printer safety checks. |
|
|
17
21
|
| Fable red-team review, shared by David Montgomery | Supplies archive-ambiguity reproductions and hardware-safety review findings used for plate binding, upload checks, temperature policy, and human preflight. Network/security suggestions remain outside this hardware-safety release. |
|
|
18
22
|
| [Sebastian (sebas1986)](https://github.com/sebas1986) | Isolates the multi-filament CLI crash with real BambuStudio bisection, contributes per-slot colours and multi-nozzle prime-tower placement, and verifies X2D identification, status, and slicing in [#18](https://github.com/DMontgomery40/bambu-printer-mcp/pull/18). Also isolates FTPS session-host identity and supplies physical X2D USB upload/size/deletion evidence in [#24](https://github.com/DMontgomery40/bambu-printer-mcp/pull/24); that test does not establish MQTT print dispatch. |
|
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ an existing slicer before suggesting an install. For FULU/Orca CLI auto-slicing,
|
|
|
49
49
|
require MCP 1.1.11+ and its matching installed profile tree (see guide).
|
|
50
50
|
A slicer is not needed here to print a pre-sliced file. Configure the optional FULU
|
|
51
51
|
BambuNetwork bridge only if I choose it, and explain its runtime/auth needs.
|
|
52
|
-
X2D supports status and slicing; native printing requires macOS and a locally built helper.
|
|
52
|
+
X2D supports status and slicing; native printing requires macOS or x86-64 Linux and a locally built helper.
|
|
53
53
|
|
|
54
54
|
If this harness does not already provide code mode or an equivalent, suggest
|
|
55
55
|
a compatible code-mode integration as an optional addition. It is not required;
|
|
@@ -196,7 +196,7 @@ The optional FULU **BambuNetwork bridge** exposes `bambu_network_bridge_status`,
|
|
|
196
196
|
- Capture a JPEG snapshot from the chamber camera. Supports A1, A1 mini, P1S, P1P (TCP-on-6000), and X1, X1C, X1E, P2S, H2, H2S, H2D, H2C, H2D Pro, X2D (RTSP via ffmpeg). Requires ffmpeg in PATH for the RTSP path.
|
|
197
197
|
- Upload and print pre-sliced `.3mf` projects with checked plate selection and calibration flags. Legacy `.gcode.3mf` routes require a single external-spool-only plate; see the [slicing guide](https://github.com/DMontgomery40/bambu-printer-mcp/blob/main/docs/SLICING.md).
|
|
198
198
|
- Slice through BambuStudio CLI with automatic BBL inheritance/include resolution, per-slot filament colours, and fallback prime-tower placement for multi-nozzle printers. Missing dependencies stop the slice; custom settings and saved project tower positions are preserved. Multi-colour slicing is verified by the contributor on BambuStudio 02.08.02.60 for Windows; older CLI versions have separate limitations. See [slicing guide](https://github.com/DMontgomery40/bambu-printer-mcp/blob/main/docs/SLICING.md).
|
|
199
|
-
- Recognize X2D status and slice with its own installed BambuStudio preset (`BAMBU_MODEL=x2d`). On macOS, `print_3mf` selects the native eMMC route after resolving the model, including an elicited model. Install the optional helper as described below;
|
|
199
|
+
- Recognize X2D status and slice with its own installed BambuStudio preset (`BAMBU_MODEL=x2d`). On macOS and x86-64 Linux, `print_3mf` selects the native eMMC route after resolving the model, including an elicited model. Install the optional helper as described below; Windows native print requests, and Linux requests without the helper, fail before slicing or contacting the printer. Legacy FTPS and remote G-code starts remain unsupported for X2D.
|
|
200
200
|
- Parse AMS mapping from the 3MF's embedded slicer metadata (`Metadata/plate_<n>.json` + gcode filament header) and send it correctly formatted per the OpenBambuAPI spec, with correct H2S/H2D/H2C `ams_mapping2` parallel array format
|
|
201
201
|
- **Auto-match AMS slots by RFID** (`auto_match_ams` flag on `print_3mf`). Resolves required `tray_info_idx` from the sliced 3MF against live AMS inventory. Handles same-SKU different-color filaments by matching on `(tray_info_idx, tray_color)` and tracking already-claimed slots. Dry-run with `resolve_3mf_ams_slots` before printing.
|
|
202
202
|
- Cancel, pause, and resume in-progress print jobs via MQTT
|
|
@@ -878,6 +878,24 @@ To stop drying:
|
|
|
878
878
|
}
|
|
879
879
|
```
|
|
880
880
|
|
|
881
|
+
#### inspect_print_file
|
|
882
|
+
|
|
883
|
+
Inspect a prepared sliced 3MF or textual G-code file offline before deciding what to export or print. This tool copies the file into a private read-only snapshot and reuses the same archive, selected-plate, model/nozzle/material and temperature checks used by print preflight. It never contacts a printer or auto-slices an unsliced project.
|
|
884
|
+
|
|
885
|
+
```json
|
|
886
|
+
{
|
|
887
|
+
"file_path": "/path/to/bracket.gcode.3mf",
|
|
888
|
+
"bambu_model": "p1s",
|
|
889
|
+
"plate_index": 0,
|
|
890
|
+
"nozzle_diameters": [0.4],
|
|
891
|
+
"bed_type": "textured_plate"
|
|
892
|
+
}
|
|
893
|
+
```
|
|
894
|
+
|
|
895
|
+
`file_path` and explicit `bambu_model` are required; the model is never inferred from configuration. `plate_index` is zero-based and defaults to 0. Nozzle/bed checks are optional comparisons against file declarations, not observations of installed hardware. Only these five argument names are accepted; credentials, host and executable/bridge overrides are not part of this tool.
|
|
896
|
+
|
|
897
|
+
The generic result has `receipt_version: "1"`, `evidence: "file-only"`, `dispatch_authorized: false`, `artifact` (`sha256`, `byte_length`, `file_format`), the requested `selection`, and the original `inspection` including declared model, nozzles, materials/used filament positions, internal plate path and checked temperature peaks. Hash and byte length identify the exact inspected snapshot; a consumer must compare them with its own artifact and selected plate. The temporary snapshot is removed, and its path is not a dispatch capability. The receipt does not prove printer readiness, physical material/nozzle contents, fit, full motion simulation or permission to print. Actual print routes still independently inspect the dispatched snapshot and require fresh hardware state and human preflight.
|
|
898
|
+
|
|
881
899
|
#### print_3mf
|
|
882
900
|
|
|
883
901
|
The primary tool for starting a Bambu print. **Recommended input: a pre-sliced `.gcode.3mf` exported from FULU OrcaSlicer-bambulab, OrcaSlicer, or Bambu Studio** — see [slicing guide](https://github.com/DMontgomery40/bambu-printer-mcp/blob/main/docs/SLICING.md). This tool handles the complete workflow:
|
|
@@ -886,7 +904,7 @@ The primary tool for starting a Bambu print. **Recommended input: a pre-sliced `
|
|
|
886
904
|
2. If no G-code is found, attempts to auto-slice via the configured slicer. Profile preparation or slicing failures stop the operation before upload. See the slicing guide for tested CLI versions and combinations.
|
|
887
905
|
3. Parses the sliced 3MF to extract the correct plate file and compute its MD5 hash.
|
|
888
906
|
4. Reads slicer metadata and any explicit AMS selection to build the filament mapping.
|
|
889
|
-
5. Uploads via `basic-ftp` to the model-specific location: SD root for H2/full-size A1, `cache/` for P1/X1/A1 mini/P2S. X2D `print_3mf` instead uses its checked native eMMC route on macOS.
|
|
907
|
+
5. Uploads via `basic-ftp` to the model-specific location: SD root for H2/full-size A1, `cache/` for P1/X1/A1 mini/P2S. X2D `print_3mf` instead uses its checked native eMMC route on macOS or Linux.
|
|
890
908
|
6. Sends the correct MQTT print command for the target printer family. For H2S/H2D/H2C that means `project_file` with project-length `ams_mapping`, parallel `ams_mapping2`, and H2-compatible calibration flags.
|
|
891
909
|
|
|
892
910
|
```json
|
|
@@ -908,7 +926,7 @@ The primary tool for starting a Bambu print. **Recommended input: a pre-sliced `
|
|
|
908
926
|
|
|
909
927
|
`bambu_model` is **required** for model-specific routing and preset selection. It does not by itself validate pre-sliced G-code. BambuStudio, FULU, and Orca CLI preparation additionally require the exact model/nozzle machine preset and reject incomplete profiles. Using the wrong model can damage hardware. If `bambu_model` is not provided in the tool call and `BAMBU_MODEL` is not set in the environment, the server will ask you interactively via MCP elicitation (if your client supports it) or return a clear error.
|
|
910
928
|
|
|
911
|
-
`bed_type` defaults to `textured_plate` if omitted. `nozzle_type` (`stainless_steel`, `hardened_steel`, `tungsten_carbide`, `brass`; default `BAMBU_NOZZLE_TYPE`) sets the installed nozzle when the project must be auto-sliced; the job's nozzle type must match the printer's report, and stock P1S/P1P/A1 presets assume stainless steel. After an MQTT print command the server listens to the printer's pushed reports for up to 15 seconds (`BAMBU_DISPATCH_CHECK_MS`) and returns `dispatch: "started"` or `"unconfirmed"`; if firmware 01.08.05+ refuses the command (HMS 0500-0500-0001-0007, needs LAN Only Mode and Developer Mode), the call fails and says so; clear that fatal HMS entry with `clear_hms_errors` before printing again. `ams_slots` is the preferred override input; `ams_mapping` remains the raw escape hatch. On AMS-equipped H2 printers, `use_ams: false` does not suppress mapping lookup if the sliced file declares filaments. If no mapping is provided for an H2 pre-sliced job with declared filaments, the server fails before sending; pass explicit `ams_slots`, raw `ams_mapping`, or `auto_match_ams: true`.
|
|
929
|
+
`bed_type` defaults to `textured_plate` if omitted. `nozzle_type` (`stainless_steel`, `hardened_steel`, `tungsten_carbide`, `brass`; default `BAMBU_NOZZLE_TYPE`) sets the installed nozzle when the project must be auto-sliced; the job's nozzle type must match the printer's report, and stock P1S/P1P/A1 presets assume stainless steel. `nozzle_volume_type` (`standard`, `high_flow`; default `BAMBU_NOZZLE_VOLUME_TYPE`) likewise sets the installed nozzle's flow type for auto-slicing; it must match the printer's reported nozzle flow. After an MQTT print command the server listens to the printer's pushed reports for up to 15 seconds (`BAMBU_DISPATCH_CHECK_MS`) and returns `dispatch: "started"` or `"unconfirmed"`; if firmware 01.08.05+ refuses the command (HMS 0500-0500-0001-0007, needs LAN Only Mode and Developer Mode), the call fails and says so; clear that fatal HMS entry with `clear_hms_errors` before printing again. `ams_slots` is the preferred override input; `ams_mapping` remains the raw escape hatch. On AMS-equipped H2 printers, `use_ams: false` does not suppress mapping lookup if the sliced file declares filaments. If no mapping is provided for an H2 pre-sliced job with declared filaments, the server fails before sending; pass explicit `ams_slots`, raw `ams_mapping`, or `auto_match_ams: true`.
|
|
912
930
|
|
|
913
931
|
Set `auto_match_ams: true` to match the sliced 3MF's `tray_info_idx` values against the live AMS inventory and use the matching `ams_slots`. The matcher joins on `(tray_info_idx, tray_color)` and tracks already-claimed slots, so prints with two filaments of the same SKU but different colors (e.g. two GFG02 PETG HF in black and white) resolve correctly. Falls back to SKU-only when the 3MF's filament has no color set or only one tray of that SKU is loaded. Returns a structured `missing` report (`reason: "no_loaded_match" | "color_mismatch" | "exhausted" | "no_sku"`) when a filament can't be resolved. Ignored when you provide `ams_slots` or `ams_mapping` explicitly.
|
|
914
932
|
|
|
@@ -926,14 +944,28 @@ Call an allowed read-only probe such as `{"method": "net.is_user_login", "payloa
|
|
|
926
944
|
|
|
927
945
|
#### X2D native transport (macOS)
|
|
928
946
|
|
|
929
|
-
Install Bambu Studio and its networking plug-in, plus the Apple command-line developer tools (`clang++`). The plug-in is loaded at runtime and is not redistributed. In the installed `bambu-printer-mcp` package directory, run `npm run build:native`. For a global install, locate that directory with `npm root -g`; for an extracted desktop extension, run the same command in the extension directory. Rebuild after updating the package. Linux
|
|
947
|
+
Install Bambu Studio and its networking plug-in, plus the Apple command-line developer tools (`clang++`). The plug-in is loaded at runtime and is not redistributed. In the installed `bambu-printer-mcp` package directory, run `npm run build:native`. For a global install, locate that directory with `npm root -g`; for an extracted desktop extension, run the same command in the extension directory. Rebuild after updating the package. For Linux, see [X2D native transport (Linux)](#x2d-native-transport-linux); Windows can use status and slicing only.
|
|
930
948
|
|
|
931
|
-
The npm package and desktop bundle include `native/bambu-native-print.cpp
|
|
949
|
+
The npm package and desktop bundle include `native/bambu-native-print.cpp`, `scripts/build-bambu-native.sh` and the Linux setup script, never a developer's compiled binary. The server finds the built helper relative to its installed package, regardless of the launch directory. A trusted server setting `BAMBU_NATIVE_HELPER` can select an alternate executable.
|
|
932
950
|
|
|
933
951
|
For X2D, `print_3mf` defaults to `connection_mode: "bambu_native"`; legacy `lan_mqtt_ftps` requests are redirected to it. Supply `ams_slots`, a complete project-level `ams_mapping`, or `auto_match_ams: true`. An external-spool job requires explicit `use_ams: false`. Raw `ams_mapping2` and nozzle/extra-option overrides are rejected before dispatch; the server derives both AMS representations from the checked structured mapping. Model/nozzle/material inspection, fresh printer-state checks, and human preflight apply before the helper receives a private snapshot. The native helper requests fresh shared printer-state authorization immediately before each print submission, including a certificate retry, and before checked heating, resume, or error-clearing commands; custom helpers must support this handshake. Stop and heater-off remain available without preflight. Native upload-only requests use the same all-plate inspection as FTPS uploads. They accept `project_name`, `preset_name`, `bed_type`, and an existing `plate_index`; AMS, nozzle, and calibration print options are rejected. Use `print_3mf` for checked print settings.
|
|
934
952
|
|
|
935
953
|
The helper waits for connection/certificate exchange and retries only the initial `-4030` send once. Rebuild the helper after upgrading to receive the teardown fix. A successful dispatch receipt ends the helper before plug-in cleanup can turn an accepted job into an error. If an older/custom helper crashes after dispatch, the server reports uncertainty: check the printer state and job name before retrying, because resending can duplicate a print. Previous hardware testing reached `RUNNING` on X2D; this revision is validated with mocked transport regressions and clean installs, not a new physical print. `bambu_connect` is an optional macOS handoff for user review in Bambu Connect and does not start a print. Native task, heater, and error controls retain the common safety checks; raw controls cannot bypass them. Request cancellation, stop, and heater-off interrupt pending native helpers; the server waits for process exit before releasing a checked file. A command already sent to the printer cannot be recalled by cancelling the request, so verify printer state before retrying.
|
|
936
954
|
|
|
955
|
+
#### X2D native transport (Linux)
|
|
956
|
+
|
|
957
|
+
On x86-64 Linux, one command builds the helper and installs Bambu's networking plug-in and the Bambu Studio certificates. It needs a C++ compiler (`g++` or `clang++`) and network access; no desktop or slicer is required:
|
|
958
|
+
|
|
959
|
+
```bash
|
|
960
|
+
npx -y -p bambu-printer-mcp bambu-printer-mcp-native-setup
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
Use the same package version as the server, for example `bambu-printer-mcp@1.2.3`; when the installation is missing or stale, the server's error names the exact command. The setup downloads the Linux plug-in that Bambu Studio itself installs, pinned to an exact version and SHA-256, and stores it with the certificates under `~/.config/bambu-printer-mcp/bambu-native` (`BAMBU_NATIVE_HOME` or `XDG_CONFIG_HOME` move it; set the same value for the server). The plug-in is not redistributed by this package, and Bambu Studio's own auto-updating copy is never used. The server finds the installation automatically and passes the plug-in and certificate paths to the helper. Rerun the setup with the server's package version after upgrading: the server refuses a helper built from another version. Only missing or changed files are downloaded again. The setup then loads the plug-in once, offline, so missing system libraries are reported during installation rather than on a stop command. `--verify` repeats these checks without network access. On Linux the server uses only this managed helper or `BAMBU_NATIVE_HELPER`; a package-local `npm run build:native` binary is not used.
|
|
964
|
+
|
|
965
|
+
`--check-update` asks Bambu's plug-in service for the newest Linux plug-in and compares the `PrintParams` layout in the matching Bambu Studio header with the helper. It reports only: the setup never installs an unpinned plug-in, because a changed layout would send wrong print parameters. A pin is raised by a package release after the check passes and a hardware test.
|
|
966
|
+
|
|
967
|
+
Once the helper, plug-in and certificates are installed, X2D printing, upload and controls use the same routing, safety checks and authorization handshake described for macOS above. On Linux, stop and heater-off go out over the native route and MQTT at the same time, so a stuck helper cannot delay them. MQTT is sent again once every older print or heating helper for that printer has exited, so none can dispatch after it; either the native route or that later MQTT send succeeding counts, and the result lists all sends under `routes`. A repeated stop or heater-off is harmless. macOS keeps its native-only route. The server accepts only the pinned plug-in checksums; `BAMBU_NATIVE_ALLOW_UNPINNED_PLUGIN=1` is a trusted override for testing another build at your own risk. Without a complete installation, Linux keeps its previous behavior: X2D status and slicing work, stop, pause and heater-off use MQTT, and native print requests name the setup command before contacting the printer. Bambu publishes the Linux plug-in for x86-64 only; other architectures keep the MQTT behavior.
|
|
968
|
+
|
|
937
969
|
#### x2d_native_control
|
|
938
970
|
|
|
939
971
|
This optional X2D metadata tool accepts `ams_filament_setting` and `extrusion_cali_sel`, plus the read-only queries `extrusion_cali_get`, `extrusion_cali_get_result`, and `flowrate_get_result`. It validates command fields, numeric metadata, and AMS unit/slot selection. Motion, filament loading, heating, safety-setting changes, and task control are not exposed through raw JSON; use the dedicated checked tools where available. A metadata declaration does not verify the physical spool contents.
|
|
@@ -1102,6 +1134,7 @@ When `slicer_type` is `bambustudio` (the default), these additional parameters a
|
|
|
1102
1134
|
| `skip_objects` | string | Object indices to skip, comma-separated (e.g. `"3,5,10"`) |
|
|
1103
1135
|
| `load_filaments` | string | Filament profile paths, semicolon-separated |
|
|
1104
1136
|
| `load_filament_ids` | string | Filament-to-object mapping, comma-separated |
|
|
1137
|
+
| `nozzle_volume_type` | string | Installed nozzle flow type: `standard` or `high_flow` (default: `BAMBU_NOZZLE_VOLUME_TYPE`, else the preset's Standard default). `high_flow` uses the presets' High Flow values, such as the filament's High Flow max volumetric speed, and is refused if the machine preset declares no High Flow variant. Also on `slice_with_template`. |
|
|
1105
1138
|
| `filament_colours` | string | Slot colours, one `#RRGGBB` per filament slot, semicolon-separated. Explicit values take priority, followed by input 3MF colours, each custom profile's colour, then the BambuStudio default. |
|
|
1106
1139
|
| `enable_timelapse` | boolean | Enable timelapse-aware slicing |
|
|
1107
1140
|
| `allow_mix_temp` | boolean | Allow mixed-temperature filaments on one plate |
|
|
@@ -1246,9 +1279,11 @@ Understanding these constraints will help you avoid frustrating errors and set a
|
|
|
1246
1279
|
|
|
1247
1280
|
5. **Status and command submission are separate evidence.** Local MQTT connections are reused and status is read from received printer reports. Reports can lag during startup, sleep, or state transitions. Inspect HMS errors and the printer's actual state after submitting a job; a tool's success response is not physical-print confirmation.
|
|
1248
1281
|
|
|
1249
|
-
6. **
|
|
1282
|
+
6. **Only hidden or informational HMS entries let an operation proceed.** Fatal, serious and common HMS entries block printing, heating and resume. The exceptions are info-level entries and serious or common entries that Bambu lists for the exact printer model with empty text: the printer screen, Bambu Studio and Bambu Handy never show those, and the printer keeps printing with them. An X2D, for example, raises the hidden camera code `HMS 0500-0600-0002-0070` at every boot. The list comes from the bundled HMS tables of a pinned Bambu Studio commit (`scripts/generate-hidden-hms.mjs`), selected by the printer's serial prefix as Bambu Studio does, and covers X2D, P2S, H2D, H2D Pro, H2S and H2C. Each model's own table decides: `0500-0600-0002-0070` is hidden in the X2D table, but the P2S table does not list it, so it still blocks a P2S. If Bambu later publishes text for a listed code, the gate keeps passing it until the list is regenerated from a newer Studio release. The print preflight names any hidden entry it passes, and the first check that passes each one logs it on stderr, so headless runs still record it. `clear_hms_errors` leaves hidden entries alone. Unlisted codes and other models' tables never qualify.
|
|
1283
|
+
|
|
1284
|
+
7. **Network requirements depend on the path.** Direct MQTT/FTPS tools require local reachability and compatible LAN/Developer Mode settings. FULU bridge cloud jobs use BambuNetwork and require its runtime, internet access, and authentication. Standard status, camera, file, and control tools remain local; bridge printing does not turn them into cloud tools.
|
|
1250
1285
|
|
|
1251
|
-
|
|
1286
|
+
8. **Self-signed TLS certificate.** The printer's FTPS server uses a self-signed certificate. The `basic-ftp` client is configured with `rejectUnauthorized: false` to accept it. This is standard for local network Bambu connections but assumes a trusted local network environment.
|
|
1252
1287
|
|
|
1253
1288
|
</details>
|
|
1254
1289
|
|
package/dist/bambu-native.d.ts
CHANGED
|
@@ -49,7 +49,62 @@ export type BambuNativeTemperatureCommand = {
|
|
|
49
49
|
temperature: number;
|
|
50
50
|
messageJson: string;
|
|
51
51
|
};
|
|
52
|
+
/**
|
|
53
|
+
* Hosts for which the native helper and Bambu's networking plug-in exist.
|
|
54
|
+
* Bambu publishes its Linux plug-in for x86-64 only.
|
|
55
|
+
*/
|
|
56
|
+
export declare function isBambuNativePlatform(platform?: NodeJS.Platform, arch?: string): boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Private directory used by `bambu-printer-mcp-native-setup` on Linux. Mirrors
|
|
59
|
+
* nativeHomeDir() in native/bambu-native-print.cpp: empty values count as unset.
|
|
60
|
+
*/
|
|
61
|
+
export declare function bambuNativeHomeDir(env?: NodeJS.ProcessEnv): string;
|
|
62
|
+
export declare const BAMBU_NATIVE_CERTIFICATES: readonly ["slicer_base64.cer", "printer.cer"];
|
|
63
|
+
/**
|
|
64
|
+
* The networking plug-in followed by the library it loads from its own
|
|
65
|
+
* directory for the eMMC file tunnel; without it uploads fail with -4.
|
|
66
|
+
*/
|
|
67
|
+
export declare const BAMBU_NATIVE_PLUGIN_LIBRARIES: readonly ["libbambu_networking.so", "libBambuSource.so"];
|
|
68
|
+
/**
|
|
69
|
+
* The only Linux plug-in build whose PrintParams layout matches the helper
|
|
70
|
+
* (Bambu Studio v02.08.02.61, network agent 02.08.02.54). The setup installs
|
|
71
|
+
* exactly these files and the server refuses anything else.
|
|
72
|
+
*/
|
|
73
|
+
export declare const BAMBU_NATIVE_PINNED_PLUGIN: Readonly<{
|
|
74
|
+
version: "02.08.02.54";
|
|
75
|
+
sha256: Readonly<Record<"libbambu_networking.so" | "libBambuSource.so", string>>;
|
|
76
|
+
}>;
|
|
77
|
+
/** Layout shared by the Linux setup script, the server and the helper's environment. */
|
|
78
|
+
export declare function bambuNativeManagedPaths(env?: NodeJS.ProcessEnv): {
|
|
79
|
+
home: string;
|
|
80
|
+
helper: string;
|
|
81
|
+
plugin: string;
|
|
82
|
+
certDir: string;
|
|
83
|
+
configDir: string;
|
|
84
|
+
receipt: string;
|
|
85
|
+
};
|
|
86
|
+
export declare const BAMBU_NATIVE_SOURCE: string;
|
|
87
|
+
export declare function sha256Hex(data: Buffer | string): string;
|
|
88
|
+
export declare function sha256File(file: string): string;
|
|
89
|
+
/**
|
|
90
|
+
* Name the setup from this server's own version, whose helper source it
|
|
91
|
+
* accepts, and its own install directory when that is not the default.
|
|
92
|
+
*/
|
|
93
|
+
export declare function bambuNativeSetupCommand(version?: string, env?: NodeJS.ProcessEnv): string;
|
|
52
94
|
export declare function assertBambuNativeAvailable(): void;
|
|
95
|
+
/**
|
|
96
|
+
* True when X2D controls should use the native route. macOS keeps its
|
|
97
|
+
* unconditional routing. Linux opts in only with a complete installation, so
|
|
98
|
+
* stop, pause and heater-off keep their MQTT route otherwise.
|
|
99
|
+
*/
|
|
100
|
+
export declare function bambuNativeControlsAvailable(): boolean;
|
|
101
|
+
/** Why native X2D controls are not used on this host, or undefined when they are. */
|
|
102
|
+
export declare function bambuNativeUnavailableReason(): string | undefined;
|
|
103
|
+
/**
|
|
104
|
+
* Interrupt this printer's pending print, upload and heating helpers and
|
|
105
|
+
* resolve once they have exited, so none can still dispatch afterwards.
|
|
106
|
+
*/
|
|
107
|
+
export declare function interruptNativeOperations(serial: string): Promise<void>;
|
|
53
108
|
export declare function buildBambuNativeFanCommand(fan: string | number, speed: number, sequenceId?: string): BambuNativeFanCommand;
|
|
54
109
|
export declare function buildBambuNativeTemperatureCommand(component: string, temperature: number, sequenceId?: string): BambuNativeTemperatureCommand;
|
|
55
110
|
export declare function validateBambuNativeControlMessage(messageJson: string): {
|
package/dist/bambu-native.js
CHANGED
|
@@ -1,32 +1,228 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
2
3
|
import fs from "node:fs";
|
|
4
|
+
import os from "node:os";
|
|
3
5
|
import path from "node:path";
|
|
4
6
|
import { fileURLToPath } from "node:url";
|
|
5
7
|
function firstExistingExecutable(candidates) {
|
|
6
8
|
return candidates.find((candidate) => {
|
|
7
9
|
try {
|
|
8
|
-
|
|
10
|
+
const stat = fs.statSync(candidate);
|
|
11
|
+
return stat.isFile() && (stat.mode & 0o111) !== 0;
|
|
9
12
|
}
|
|
10
13
|
catch {
|
|
11
14
|
return false;
|
|
12
15
|
}
|
|
13
16
|
});
|
|
14
17
|
}
|
|
18
|
+
/**
|
|
19
|
+
* Hosts for which the native helper and Bambu's networking plug-in exist.
|
|
20
|
+
* Bambu publishes its Linux plug-in for x86-64 only.
|
|
21
|
+
*/
|
|
22
|
+
export function isBambuNativePlatform(platform = process.platform, arch = process.arch) {
|
|
23
|
+
return platform === "darwin" || (platform === "linux" && arch === "x64");
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Private directory used by `bambu-printer-mcp-native-setup` on Linux. Mirrors
|
|
27
|
+
* nativeHomeDir() in native/bambu-native-print.cpp: empty values count as unset.
|
|
28
|
+
*/
|
|
29
|
+
export function bambuNativeHomeDir(env = process.env) {
|
|
30
|
+
if (env.BAMBU_NATIVE_HOME)
|
|
31
|
+
return env.BAMBU_NATIVE_HOME;
|
|
32
|
+
const configHome = env.XDG_CONFIG_HOME || path.join(env.HOME || os.homedir(), ".config");
|
|
33
|
+
return path.join(configHome, "bambu-printer-mcp", "bambu-native");
|
|
34
|
+
}
|
|
35
|
+
export const BAMBU_NATIVE_CERTIFICATES = ["slicer_base64.cer", "printer.cer"];
|
|
36
|
+
/**
|
|
37
|
+
* The networking plug-in followed by the library it loads from its own
|
|
38
|
+
* directory for the eMMC file tunnel; without it uploads fail with -4.
|
|
39
|
+
*/
|
|
40
|
+
export const BAMBU_NATIVE_PLUGIN_LIBRARIES = ["libbambu_networking.so", "libBambuSource.so"];
|
|
41
|
+
/**
|
|
42
|
+
* The only Linux plug-in build whose PrintParams layout matches the helper
|
|
43
|
+
* (Bambu Studio v02.08.02.61, network agent 02.08.02.54). The setup installs
|
|
44
|
+
* exactly these files and the server refuses anything else.
|
|
45
|
+
*/
|
|
46
|
+
export const BAMBU_NATIVE_PINNED_PLUGIN = Object.freeze({
|
|
47
|
+
version: "02.08.02.54",
|
|
48
|
+
sha256: Object.freeze({
|
|
49
|
+
"libbambu_networking.so": "bba49709c8dea14ba70251b43965646c0a5e2cde8fd133c64f764d425691bdf2",
|
|
50
|
+
"libBambuSource.so": "4e05f16fa02740fd12f0040b9efc3e70d43446c7a1a877c6a3926ef0758ca7db",
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
/** Layout shared by the Linux setup script, the server and the helper's environment. */
|
|
54
|
+
export function bambuNativeManagedPaths(env = process.env) {
|
|
55
|
+
const home = bambuNativeHomeDir(env);
|
|
56
|
+
return {
|
|
57
|
+
home,
|
|
58
|
+
helper: path.join(home, "bin", "bambu-native-print"),
|
|
59
|
+
plugin: path.join(home, "plugins", BAMBU_NATIVE_PLUGIN_LIBRARIES[0]),
|
|
60
|
+
certDir: path.join(home, "cert"),
|
|
61
|
+
configDir: path.join(home, "config"),
|
|
62
|
+
receipt: path.join(home, "install.json"),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
const PACKAGE_ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
|
66
|
+
export const BAMBU_NATIVE_SOURCE = path.join(PACKAGE_ROOT, "native", "bambu-native-print.cpp");
|
|
67
|
+
export function sha256Hex(data) {
|
|
68
|
+
return createHash("sha256").update(data).digest("hex");
|
|
69
|
+
}
|
|
70
|
+
export function sha256File(file) {
|
|
71
|
+
return sha256Hex(fs.readFileSync(file));
|
|
72
|
+
}
|
|
73
|
+
let nativeSourceSha256;
|
|
74
|
+
/** The packaged helper source never changes while the server runs. */
|
|
75
|
+
function packagedHelperSha256() {
|
|
76
|
+
nativeSourceSha256 ?? (nativeSourceSha256 = sha256File(BAMBU_NATIVE_SOURCE));
|
|
77
|
+
return nativeSourceSha256;
|
|
78
|
+
}
|
|
79
|
+
function packageVersion() {
|
|
80
|
+
try {
|
|
81
|
+
return String(JSON.parse(fs.readFileSync(path.join(PACKAGE_ROOT, "package.json"), "utf8")).version || "");
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return "";
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Name the setup from this server's own version, whose helper source it
|
|
89
|
+
* accepts, and its own install directory when that is not the default.
|
|
90
|
+
*/
|
|
91
|
+
export function bambuNativeSetupCommand(version = packageVersion(), env = process.env) {
|
|
92
|
+
const home = bambuNativeHomeDir(env);
|
|
93
|
+
const defaultHome = bambuNativeHomeDir({ HOME: env.HOME });
|
|
94
|
+
const homeOption = home === defaultHome ? "" : ` --home ${JSON.stringify(home)}`;
|
|
95
|
+
return `npx -y -p bambu-printer-mcp${version ? `@${version}` : ""} bambu-printer-mcp-native-setup${homeOption}`;
|
|
96
|
+
}
|
|
97
|
+
const linuxSetupHint = () => `Run \`${bambuNativeSetupCommand()}\` to build the helper and install the pinned networking plug-in.`;
|
|
98
|
+
const verifiedLibraries = new Map();
|
|
99
|
+
/** Hash a plug-in library once per file version; it is ~16 MB. */
|
|
100
|
+
function libraryMatches(file, expected) {
|
|
101
|
+
const stat = fs.statSync(file);
|
|
102
|
+
const key = `${fs.realpathSync(file)}\n${stat.dev}:${stat.ino}:${stat.size}:${stat.mtimeMs}`;
|
|
103
|
+
let digest = verifiedLibraries.get(key);
|
|
104
|
+
if (!digest) {
|
|
105
|
+
digest = sha256File(file);
|
|
106
|
+
verifiedLibraries.set(key, digest);
|
|
107
|
+
}
|
|
108
|
+
return digest === expected;
|
|
109
|
+
}
|
|
110
|
+
function samePath(a, b) {
|
|
111
|
+
try {
|
|
112
|
+
return fs.realpathSync(a) === fs.realpathSync(b);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return path.resolve(a) === path.resolve(b);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function isRegularFile(file) {
|
|
119
|
+
try {
|
|
120
|
+
return fs.statSync(file).isFile();
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Resolve a complete native installation. On Linux the helper, the pinned
|
|
128
|
+
* plug-in and both certificates must be present before any native route is
|
|
129
|
+
* chosen, and their resolved paths are handed to the helper so server and
|
|
130
|
+
* helper can never disagree about which plug-in is loaded.
|
|
131
|
+
*/
|
|
132
|
+
function resolveNativeInstall() {
|
|
133
|
+
if (!isBambuNativePlatform()) {
|
|
134
|
+
throw new Error("Bambu native X2D transport requires macOS or x86-64 Linux and Bambu's networking plug-in.");
|
|
135
|
+
}
|
|
136
|
+
const helper = resolveNativeHelper();
|
|
137
|
+
if (process.platform !== "linux")
|
|
138
|
+
return { helper, env: {} };
|
|
139
|
+
const managed = bambuNativeManagedPaths();
|
|
140
|
+
const plugin = process.env.BAMBU_NATIVE_PLUGIN || managed.plugin;
|
|
141
|
+
const certDir = process.env.BAMBU_NATIVE_CERT_DIR || managed.certDir;
|
|
142
|
+
const configDir = process.env.BAMBU_NATIVE_CONFIG_DIR || managed.configDir;
|
|
143
|
+
const certFile = process.env.BAMBU_NATIVE_CERT_FILE || BAMBU_NATIVE_CERTIFICATES[0];
|
|
144
|
+
if (!isRegularFile(plugin)) {
|
|
145
|
+
throw new Error(`Bambu networking plug-in is not installed at ${plugin}. ${linuxSetupHint()}`);
|
|
146
|
+
}
|
|
147
|
+
for (const library of BAMBU_NATIVE_PLUGIN_LIBRARIES.slice(1)) {
|
|
148
|
+
if (!isRegularFile(path.join(path.dirname(plugin), library))) {
|
|
149
|
+
throw new Error(`Bambu networking library ${library} is missing beside ${plugin}. ${linuxSetupHint()}`);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// A different plug-in build can change the PrintParams layout passed by
|
|
153
|
+
// value to start_local_print. Only an explicit trusted opt-in skips this.
|
|
154
|
+
if (process.env.BAMBU_NATIVE_ALLOW_UNPINNED_PLUGIN !== "1") {
|
|
155
|
+
const files = [
|
|
156
|
+
[plugin, BAMBU_NATIVE_PINNED_PLUGIN.sha256[BAMBU_NATIVE_PLUGIN_LIBRARIES[0]]],
|
|
157
|
+
...BAMBU_NATIVE_PLUGIN_LIBRARIES.slice(1).map(library => [path.join(path.dirname(plugin), library), BAMBU_NATIVE_PINNED_PLUGIN.sha256[library]]),
|
|
158
|
+
];
|
|
159
|
+
for (const [file, expected] of files) {
|
|
160
|
+
if (!libraryMatches(file, expected)) {
|
|
161
|
+
throw new Error(`${file} is not the pinned Bambu plug-in ${BAMBU_NATIVE_PINNED_PLUGIN.version}. ${linuxSetupHint()}`);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
for (const certificate of new Set([certFile, ...BAMBU_NATIVE_CERTIFICATES.slice(1)])) {
|
|
166
|
+
if (!isRegularFile(path.join(certDir, certificate))) {
|
|
167
|
+
throw new Error(`Bambu certificate ${certificate} is missing from ${certDir}. ${linuxSetupHint()}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
if (samePath(helper, managed.helper)) {
|
|
171
|
+
// A setup run from another package version builds a different helper.
|
|
172
|
+
let built;
|
|
173
|
+
try {
|
|
174
|
+
built = JSON.parse(fs.readFileSync(managed.receipt, "utf8")).helperSourceSha256;
|
|
175
|
+
}
|
|
176
|
+
catch {
|
|
177
|
+
built = undefined;
|
|
178
|
+
}
|
|
179
|
+
if (built !== packagedHelperSha256()) {
|
|
180
|
+
throw new Error(`The installed native helper was built from a different bambu-printer-mcp version. ${linuxSetupHint()}`);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
helper,
|
|
185
|
+
env: { BAMBU_NATIVE_PLUGIN: plugin, BAMBU_NATIVE_CERT_DIR: certDir, BAMBU_NATIVE_CONFIG_DIR: configDir },
|
|
186
|
+
};
|
|
187
|
+
}
|
|
15
188
|
export function assertBambuNativeAvailable() {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
189
|
+
resolveNativeInstall();
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* True when X2D controls should use the native route. macOS keeps its
|
|
193
|
+
* unconditional routing. Linux opts in only with a complete installation, so
|
|
194
|
+
* stop, pause and heater-off keep their MQTT route otherwise.
|
|
195
|
+
*/
|
|
196
|
+
export function bambuNativeControlsAvailable() {
|
|
197
|
+
return bambuNativeUnavailableReason() === undefined;
|
|
198
|
+
}
|
|
199
|
+
/** Why native X2D controls are not used on this host, or undefined when they are. */
|
|
200
|
+
export function bambuNativeUnavailableReason() {
|
|
201
|
+
if (process.platform === "darwin")
|
|
202
|
+
return undefined;
|
|
203
|
+
if (process.platform !== "linux")
|
|
204
|
+
return "Native X2D controls require macOS or x86-64 Linux.";
|
|
205
|
+
try {
|
|
206
|
+
resolveNativeInstall();
|
|
207
|
+
return undefined;
|
|
208
|
+
}
|
|
209
|
+
catch (error) {
|
|
210
|
+
return error instanceof Error ? error.message : String(error);
|
|
211
|
+
}
|
|
19
212
|
}
|
|
20
213
|
function resolveNativeHelper() {
|
|
21
214
|
const configured = process.env.BAMBU_NATIVE_HELPER?.trim();
|
|
22
|
-
|
|
215
|
+
// Linux uses only the setup-managed helper, whose receipt proves it matches
|
|
216
|
+
// this package; a package-local build could be stale after an update.
|
|
23
217
|
const candidates = [
|
|
24
218
|
configured,
|
|
25
|
-
path.resolve(
|
|
219
|
+
process.platform === "linux" ? bambuNativeManagedPaths().helper : path.resolve(PACKAGE_ROOT, "native/bambu-native-print"),
|
|
26
220
|
].filter((value) => Boolean(value));
|
|
27
221
|
const helper = firstExistingExecutable(candidates);
|
|
28
222
|
if (!helper) {
|
|
29
|
-
throw new Error(
|
|
223
|
+
throw new Error(process.platform === "linux"
|
|
224
|
+
? `Bambu native helper is not installed. ${linuxSetupHint()} Alternatively set BAMBU_NATIVE_HELPER.`
|
|
225
|
+
: "Bambu native helper is not installed. Build native/bambu-native-print with clang++ or set BAMBU_NATIVE_HELPER.");
|
|
30
226
|
}
|
|
31
227
|
return helper;
|
|
32
228
|
}
|
|
@@ -48,7 +244,11 @@ function isEmergencyCommand(messageJson) {
|
|
|
48
244
|
(command?.command === "set_bed_temp" && command.temp === 0) ||
|
|
49
245
|
(command?.command === "set_nozzle_temp" && command.target_temp === 0);
|
|
50
246
|
}
|
|
51
|
-
|
|
247
|
+
/**
|
|
248
|
+
* Interrupt this printer's pending print, upload and heating helpers and
|
|
249
|
+
* resolve once they have exited, so none can still dispatch afterwards.
|
|
250
|
+
*/
|
|
251
|
+
export async function interruptNativeOperations(serial) {
|
|
52
252
|
const pending = [...activeHelpers.values()].filter(helper => helper.serial === serial && !helper.emergency);
|
|
53
253
|
for (const helper of pending)
|
|
54
254
|
helper.interrupt();
|
|
@@ -63,11 +263,10 @@ function runNativeHelper(mode, env, timeoutMs, onUpdate, execution = {}) {
|
|
|
63
263
|
if (needsAuthorization && typeof execution.beforeDispatch !== "function") {
|
|
64
264
|
throw new Error("Native dispatch requires a beforeDispatch fresh-state check.");
|
|
65
265
|
}
|
|
66
|
-
|
|
67
|
-
const helper = resolveNativeHelper();
|
|
266
|
+
const install = resolveNativeInstall();
|
|
68
267
|
return new Promise((resolve, reject) => {
|
|
69
|
-
const child = spawn(helper, [mode], {
|
|
70
|
-
env,
|
|
268
|
+
const child = spawn(install.helper, [mode], {
|
|
269
|
+
env: { ...env, ...install.env },
|
|
71
270
|
stdio: ["pipe", "pipe", "pipe"],
|
|
72
271
|
});
|
|
73
272
|
let markClosed;
|
|
@@ -514,7 +713,7 @@ export async function probeBambuNative(host, token) {
|
|
|
514
713
|
BAMBU_NATIVE_ACCESS_CODE: token,
|
|
515
714
|
}, 20000);
|
|
516
715
|
if (result.resultCode !== 0) {
|
|
517
|
-
throw new Error(`Bambu native local tunnel probe failed (${result.resultCode})
|
|
716
|
+
throw new Error(`Bambu native local tunnel probe failed (${result.resultCode}): ${result.updates.join(" | ") || tail(result.stderr, 500)}`);
|
|
518
717
|
}
|
|
519
718
|
return { status: "ok", route: "bambu:///local", updates: result.updates };
|
|
520
719
|
}
|