A VSCode extension that runs tasks defined in .vscode/tasks.json with
interactive parameter prompts — serial port pickers, file dialogs, and
validated text input — tailored for firmware development workflows.
- Activity bar view that lists tasks defined in the workspace (
.vscode/tasks.json) - Run / terminate / restart tasks directly from the tree
- Favorite frequently used tasks
- Interactive input commands usable from the standard
inputsarray oftasks.json:- Auto-detected serial port picker (
pickSerialPort) - Validated text prompt (
promptInput) - File / folder pickers (
pickFile,pickFolder) - Dynamic list picker (
pickFromList)
- Auto-detected serial port picker (
- Pre-configure inputs without running: a gear icon ⚙️ next to tasks with
${input:...}variables opens the input UI without launching the task; the selected values are stored and reused on the next ▶ run (no re-prompt). Current values appear as a description next to the task name (e.g.flash port=/dev/cu.usbserial · cfg=debug). - Remembers the last value entered per task and prefills it on the next run
Use these commands as "type": "command" inputs in your tasks.json.
| Command | Purpose | Args |
|---|---|---|
firmware-task.pickSerialPort |
Auto-detects and lets the user pick a serial port. Falls back to manual entry if none detected. | placeholder, filter (regex) |
firmware-task.promptInput |
Free-form text prompt. | prompt, placeholder, value, password, validateRegex, validateMessage |
firmware-task.pickFile |
File picker (showOpenDialog). |
title, openLabel, filters, defaultUri, canSelectMany, relative |
firmware-task.pickFolder |
Folder picker. | title, openLabel, defaultUri, relative |
firmware-task.pickFromList |
QuickPick over a custom list. | items (string[] or {label,value,description}[]), placeholder |
{
"version": "2.0.0",
"tasks": [
{
"label": "Serial Monitor",
"type": "shell",
"command": "pyserial-miniterm ${input:port} ${input:baud}"
},
{
"label": "Flash Firmware",
"type": "shell",
"command": "openocd -f interface/stlink.cfg -c 'program ${input:bin} verify reset exit'"
}
],
"inputs": [
{ "id": "port", "type": "command", "command": "firmware-task.pickSerialPort" },
{
"id": "baud",
"type": "command",
"command": "firmware-task.promptInput",
"args": { "prompt": "Baud rate", "value": "115200", "validateRegex": "^\\d+$" }
},
{
"id": "bin",
"type": "command",
"command": "firmware-task.pickFile",
"args": { "filters": { "Firmware": ["bin", "hex", "elf"] } }
}
]
}Variables (${input:port}, etc.) are substituted by Firmware Task Manager when
you launch the task from its tree view. Standard VSCode promptString and
pickString input types are also supported.
VSCode tasks always spawn a fresh task terminal, which does not inherit the
environment of a terminal you already set up (e.g. an ESP-IDF terminal where
export.sh / export.ps1 was sourced). To reuse such a terminal, add
"runInActiveTerminal": true to the task. When set, running the task types
the command into a terminal instead of launching a new task terminal:
Terminal selection priority:
terminalNamegiven → the terminal with that exact name (created if none exists). Use this to pin sends to one terminal when several are open.- Otherwise → the active terminal.
- If no terminal is open → a new one is created with the default profile (so a configured terminal profile, e.g. one that sources the IDF environment, still applies).
The command is sent with a trailing newline, so it executes immediately.
Notes / limitations:
runInActiveTerminalandterminalNameare custom keys, so VSCode's editor may flag them with a "not allowed" warning. This is cosmetic — the extension reads them directly fromtasks.jsonand they work regardless.- Commands sent this way are not tracked as VSCode task executions: the tree's
running indicator, Terminate, Restart, and the running-count badge do not
apply to them.
${input:...}substitution is still applied.
VSCode's Run Build Task shortcut runs the default build task through its
native task system, which bypasses this extension — so runInActiveTerminal
would be ignored. To fix that, mark your build task as the default build task and
add runInActiveTerminal:
{
"label": "idf-build",
"type": "shell",
"command": "idf.py build",
"runInActiveTerminal": true,
"group": { "kind": "build", "isDefault": true }
}When a workspace contains a default build task (group.kind = "build",
isDefault = true) with runInActiveTerminal: true, the extension reroutes
the build shortcut to itself so the command is sent to your terminal:
- macOS:
Cmd+Shift+B· Windows / Linux:Ctrl+Shift+B(matches the native bindings). - The override is scoped by the
firmwareTask.hasBuildInTerminalcontext key — it only takes effect in workspaces that actually have such a task. Other projects keep the normal VSCode build behavior. ${input:...}is resolved exactly like a tree-view run. (Remembered input values are cached per task; values entered via the tree are not shared with the shortcut path, so the first shortcut run of an input-bearing task may prompt once.)
| Setting | Default | Description |
|---|---|---|
firmwareTask.showOnlyWorkspaceTasks |
true |
Show only tasks defined in .vscode/tasks.json. Set to false to also show auto-detected tasks (CMake, npm, tsc, etc.). |
firmwareTask.rememberInputs |
true |
Remember last entered input values per task and prefill on subsequent runs. |
firmwareTask.serialPortFilter |
"" |
Regex applied to detected serial port device names. |
firmwareTask.exclude |
null |
Regex pattern for excluding tasks by name. |
firmwareTask.collapseLargeTaskTree |
true |
Collapse top-level groups when there are more than three groups and more than 30 tasks. |
firmwareTask.taskSortOrder |
"label" |
Sort order: "label", "group", or "provider". |
firmwareTask.favorites |
[] |
Saved favorite task ids (workspace settings). |
pnpm install
pnpm run vsix
# → dist-vsix/firmware-task-manager-1.0.0.vsixInstall it in VSCode via Extensions: Install from VSIX... in the command palette, or from the CLI:
code --install-extension dist-vsix/firmware-task-manager-1.0.0.vsixpnpm install
pnpm run watch # rolldown + tsc in watch mode
# Press F5 in VSCode to launch the Extension Development HostThis extension is based on cnshenj/vscode-task-manager, with modifications focused on firmware development workflows (serial port picking, file dialogs, per-task remembered inputs, copy-command-line action, etc.).
MIT
{ "label": "build", "type": "shell", "command": "idf.py build", "runInActiveTerminal": true, // type into a terminal instead of a new task terminal "terminalName": "ESP-IDF" // optional: always target this named terminal (created if missing) }