Soldered MicroPython Helper is a Visual Studio Code extension that helps you get started with your MicroPython projects using a friendly graphical interface.
@@ -277,57 +381,53 @@
You can explore the full source code on GitHub, submit issues or pull requests, and leave feedback on the extension page in the VS Code Marketplace.
-
- - Flash Firmware: The Download + Flash from Web option supports
ESP32_GENERIC (via esptool, .bin) and RP2040/RP2350 boards (via .uf2 copy to the boot drive; e.g., Raspberry Pi Pico / Pico W, Pico 2 / Pico 2 W, Arduino Nano RP2040 Connect, SparkFun Pro Micro RP2040/RP2350). Flashing methods may differ for other microcontrollers—consult official docs if you're using a different board.
- - Upload Python Scripts: You can upload the currently active file as
main.py, keep the original filename, or select a local .py file from your computer.
- - Manage Files: List, delete, run, or open files stored on the device. Double-click a file to open it in the VS Code editor.
- - Serial Monitor: View live output from the board over serial. Starts automatically after running a script, or can be launched manually.
- - Fetch Soldered Modules: Search and download libraries and/or examples for Soldered hardware modules. You don’t need to specify the category (e.g., Sensor, Display, Actuator).
+ - Flash Firmware: The Download + Flash from Web option supports
ESP32_GENERIC (via esptool, .bin) and RP2040/RP2350 boards (via .uf2 copy to the boot drive).
+ - Upload Python Scripts: Upload the currently open file or pick a file from your PC.
+ - Manage Files: List, delete, run, or open files stored on the device. Double-click a file to open it in the editor.
+ - Serial Monitor: View live output from the board over serial.
+ - Fetch Soldered Modules: Search and download libraries and examples for Soldered hardware modules.
ESP32_GENERIC (via esptool, .bin) and RP2040/RP2350 boards (via .uf2 copy to the boot drive; e.g., Raspberry Pi Pico / Pico W, Pico 2 / Pico 2 W, Arduino Nano RP2040 Connect, SparkFun Pro Micro RP2040/RP2350). Flashing methods may differ for other microcontrollers—consult official docs if you're using a different board.main.py, keep the original filename, or select a local .py file from your computer.ESP32_GENERIC (via esptool, .bin) and RP2040/RP2350 boards (via .uf2 copy to the boot drive).- ⚠ If you encounter errors, make sure the selected port is correct and not in use by another application. + If you encounter errors, make sure the selected port is correct and not in use by another application.
-At Soldered, we design and manufacture a wide selection of electronic products to help you turn your ideas into acts and bring you one step closer to your final project. Our products are intented for makers and crafted in-house by our experienced team in Osijek, Croatia. We believe that sharing is a crucial element for improvement and innovation, and we work hard to stay connected with all our makers regardless of their skill or experience level. Therefore, all our products are open-source. Finally, we always have your back. If you face any problem concerning either your shopping experience or your electronics project, our team will help you deal with it, offering efficient customer service and cost-free technical support anytime. Some of those might be useful for you:
+At Soldered, we design and manufacture a wide selection of electronic products to help you turn your ideas into acts and bring you one step closer to your final project. Our products are intended for makers and crafted in-house by our experienced team in Osijek, Croatia. We believe that sharing is a crucial element for improvement and innovation, and we work hard to stay connected with all our makers regardless of their skill or experience level. Therefore, all our products are open-source. Finally, we always have your back. If you face any problem concerning either your shopping experience or your electronics project, our team will help you deal with it, offering efficient customer service and cost-free technical support anytime. Some of those might be useful for you:
- [Web Store](https://www.soldered.com/shop)
- [Tutorials & Projects](https://soldered.com/learn)
@@ -184,7 +163,7 @@ At Soldered, we design and manufacture a wide selection of electronic products t
Soldered invests vast amounts of time into hardware & software for these products, which are all open-source. Please support future development by buying one of our products.
-Check license details in the LICENSE file. Long story short, use these open-source files for any purpose you want to, as long as you apply the same open-source licence to it and disclose the original source. No warranty - all designs in this repository are distributed in the hope that they will be useful, but without any warranty. They are provided "AS IS", therefore without warranty of any kind, either expressed or implied. The entire quality and performance of what you do with the contents of this repository are your responsibility. In no event, Soldered (TAVU) will be liable for your damages, losses, including any general, special, incidental or consequential damage arising out of the use or inability to use the contents of this repository.
+Check license details in the LICENSE file. Long story short, use these open-source files for any purpose you want to, as long as you apply the same open-source licence to it and disclose the original source. No warranty — all designs in this repository are distributed in the hope that they will be useful, but without any warranty. They are provided "AS IS", therefore without warranty of any kind, either expressed or implied. The entire quality and performance of what you do with the contents of this repository are your responsibility. In no event, Soldered (TAVU) will be liable for your damages, losses, including any general, special, incidental or consequential damage arising out of the use or inability to use the contents of this repository.
## Have fun!
diff --git a/package-lock.json b/package-lock.json
index cf16526..5b691dd 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "soldered-micropython-helper",
- "version": "0.1.3",
+ "version": "0.2.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "soldered-micropython-helper",
- "version": "0.1.3",
+ "version": "0.2.0",
"dependencies": {
"cheerio": "^1.1.0",
"fuse.js": "^7.1.0",
@@ -447,9 +447,9 @@
}
},
"node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.4.tgz",
+ "integrity": "sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==",
"dev": true,
"license": "BSD-3-Clause",
"engines": {
@@ -775,9 +775,9 @@
}
},
"node_modules/undici": {
- "version": "7.10.0",
- "resolved": "https://registry.npmjs.org/undici/-/undici-7.10.0.tgz",
- "integrity": "sha512-u5otvFBOBZvmdjWLVW+5DAc9Nkq8f24g0O9oY7qw2JVIF1VocIFoyz9JFkuVOS2j41AufeO0xnlweJ2RLT8nGw==",
+ "version": "7.25.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.25.0.tgz",
+ "integrity": "sha512-xXnp4kTyor2Zq+J1FfPI6Eq3ew5h6Vl0F/8d9XU5zZQf1tX9s2Su1/3PiMmUANFULpmksxkClamIZcaUqryHsQ==",
"license": "MIT",
"engines": {
"node": ">=20.18.1"
diff --git a/package.json b/package.json
index 07c740f..56e8fd0 100644
--- a/package.json
+++ b/package.json
@@ -3,26 +3,36 @@
"displayName": "Soldered MicroPython Helper",
"publisher": "solderedelectronics",
"description": "A MicroPython-focused helper for working with ESP-based boards directly inside Visual Studio Code.",
- "version": "0.1.3",
+ "version": "0.3.0",
"engines": {
- "vscode": "^1.100.0"
+ "vscode": "^1.85.0"
},
"icon": "mp.png",
"main": "./dist/extension.js",
+ "repository": {
+ "type": "git",
+ "url": "https://github.com/SolderedElectronics/Soldered-MicroPython-Helper"
+ },
+ "categories": [
+ "Other",
+ "Programming Languages",
+ "Debuggers"
+ ],
+ "keywords": [
+ "micropython",
+ "esp32",
+ "rp2040",
+ "embedded",
+ "serial",
+ "esptool",
+ "soldered"
+ ],
"scripts": {
"vscode:prepublish": "tsc -p ./"
},
"activationEvents": [],
"contributes": {
"commands": [
- {
- "command": "espFlasher.flashFirmware",
- "title": "Flash Firmware (.bin)"
- },
- {
- "command": "espFlasher.uploadPython",
- "title": "Upload Python File"
- },
{
"command": "mp.savePython",
"title": "Save Python (PC or MicroPython device)"
@@ -44,14 +54,14 @@
"default": true,
"description": "When saving a Python file, also upload it to the connected MicroPython device (using the last selected port). If disabled, you will be prompted to choose where to save the file (PC, device, or both)."
},
- "mp.alsoSaveLocally": {
- "type": "boolean",
- "default": true,
- "description": "When uploading to device on save, also save the file locally to disk."
- },
"mp.savePromptMode": {
"type": "string",
- "enum": ["ask", "pc", "device", "both"],
+ "enum": [
+ "ask",
+ "pc",
+ "device",
+ "both"
+ ],
"default": "ask",
"description": "How to save .py files when 'save to device on save' is disabled: always ask, only to PC, only to device, or to both."
},
@@ -59,6 +69,11 @@
"type": "boolean",
"default": false,
"description": "If enabled, upload to device as main.py instead of using the original filename."
+ },
+ "mp.esptoolPath": {
+ "type": "string",
+ "default": "esptool",
+ "description": "Path to the esptool executable (e.g. 'esptool', 'esptool.py', or a full path like '/opt/homebrew/bin/esptool')."
}
}
},
@@ -90,7 +105,6 @@
},
"dependencies": {
"cheerio": "^1.1.0",
- "fuse.js": "^7.1.0",
"serialport": "^13.0.0"
}
}
diff --git a/src/EspFlasherProvider.ts b/src/EspFlasherProvider.ts
new file mode 100644
index 0000000..815d91a
--- /dev/null
+++ b/src/EspFlasherProvider.ts
@@ -0,0 +1,268 @@
+import * as vscode from 'vscode';
+import * as path from 'path';
+import * as fs from 'fs';
+import { SerialPort } from 'serialport';
+import { ChildProcess } from 'child_process';
+
+import { HandlerContext } from './types';
+import { startSerialMonitor, handleRunPythonFile, handleStopRunningCode, closeAllSerial } from './handlers/serialHandler';
+import { handleFlashFromWeb, handleFlashFirmware, fetchFirmwareList } from './handlers/flashHandler';
+import { handleListFiles, handleDeleteFile, handleDeleteAllFiles } from './handlers/fileHandler';
+import { handleUploadPythonAsIs, handleUploadPythonFromPc, handleOpenFileFromDevice } from './handlers/uploadHandler';
+import { handleFetchModule, handleGetCategories, handleGetModulesForCategory, handleGetAllModules } from './handlers/moduleHandler';
+import { execMpremote } from './utils/execUtils';
+
+const IGNORED_PORT_PATTERNS = ['debug-console', 'Bluetooth-Incoming-Port'];
+
+function filterPorts(ports: { path: string }[]): string[] {
+ return ports
+ .map(p => p.path)
+ .filter(p => !IGNORED_PORT_PATTERNS.some(pattern => p.includes(pattern)));
+}
+
+export class EspFlasherViewProvider implements vscode.WebviewViewProvider {
+
+ private mpRunProc: ChildProcess | null = null;
+ private runSerial: SerialPort | null = null;
+ private _view?: vscode.WebviewView;
+ private outputChannel = vscode.window.createOutputChannel('ESP Output');
+ private serialMonitor: SerialPort | null = null;
+
+ constructor(private readonly context: vscode.ExtensionContext) {}
+
+ /**
+ * Builds a HandlerContext object that always reflects current class state
+ * via getter properties for serialMonitor and mpRunProc.
+ */
+ private getHandlerContext(): HandlerContext {
+ const self = this;
+ return {
+ postMessage: (msg: any) => self._view?.webview.postMessage(msg),
+ outputChannel: this.outputChannel,
+ get serialMonitor() { return self.serialMonitor; },
+ setSerialMonitor: (s: SerialPort | null) => { self.serialMonitor = s; },
+ get mpRunProc() { return self.mpRunProc; },
+ setMpRunProc: (p: ChildProcess | null) => { self.mpRunProc = p; },
+ get runSerial() { return self.runSerial; },
+ setRunSerial: (s: SerialPort | null) => { self.runSerial = s; },
+ extensionContext: this.context,
+ };
+ }
+
+ /**
+ * Triggers a file list refresh on the connected device.
+ * Called from extension.ts after mp.savePython uploads a file.
+ */
+ public refreshFileListOnDevice(port: string): void {
+ this._view?.webview.postMessage({ command: 'triggerListFiles', port });
+ }
+
+ /**
+ * Returns the shared output channel for logging.
+ */
+ public getOutputChannel(): vscode.OutputChannel {
+ return this.outputChannel;
+ }
+
+ /**
+ * Closes all active serial connections so the port is free for external callers
+ * (e.g. mp.savePython in extension.ts which calls uploadFileToDevice directly).
+ */
+ public async releasePort(): Promise