TaskLens — Visual Task Runner for VS Code
A clean, fast, free-forever task panel for tasks.json. List, run, re-run, stop, tail, favorite, and jump-to-definition for every VS Code task — Workspace, Global (User), and Auto-detected — from one activity-bar panel.

TaskLens is a lightweight task panel for people who want quick access to VS Code tasks without extra runtime machinery: zero telemetry, no license gates, no output-buffering CPU spikes, bundled with esbuild. It uses the native VS Code Tasks API (vscode.tasks.fetchTasks()) so it sees every task that VS Code sees — npm, gulp, grunt, typescript, and your own tasks.json — without re-implementing a single provider.
Table of Contents
Why TaskLens
TaskLens keeps tasks visible while you work: grouped labels, favorites, current results, and run history in VS Code's native sidebar. It uses the Tasks API for discovery and execution and opens the existing integrated terminal when you want to inspect output.
The Find and Run Task command searches all discovered tasks, with favorites first. Selecting an already-running task opens its terminal. Completed history entries have a re-run action.
Screenshots
The TaskLens panel in the activity bar — Workspace, Global, and Auto-detected views with hierarchical grouping and a Favorites pin.

Features
Three views, one panel
| View |
Source |
When to use |
| Workspace |
.vscode/tasks.json in the open folder(s) |
Tasks you wrote for this project |
| Global |
User-level tasks.json (Tasks: Open User Tasks) |
Tasks you reuse across every project |
| Auto-detected |
Contributed by extensions (npm, gulp, typescript, …) |
Tasks VS Code discovered for you |
Hierarchical grouping
Split task labels on a configurable separator (default ::) into nested, foldable groups. A task named db::migrate::up shows under db › migrate › up. Set the separator to : for legacy npm/gulp-style auto-nesting, - for dash-prefixed conventions, or any string you like.
Favorites
Pin frequently-used tasks to a ★ Favorites group at the top of each view. Per-workspace, persisted across reloads, never leaks across projects. Click the star to add; click again to remove. Favorited tasks still appear in their normal grouped location with a star indicator — favorites are quick-access, not exclusive.
Live status
Every task row shows an icon for its current state:
| Icon |
State |
| ⚪ idle |
Not running |
| 🔵 spinner |
Running |
| ✅ green check |
Last run succeeded |
| ❌ red error |
Nonzero exit code |
| Yellow stop |
Task was terminated |
| Neutral question mark |
Task ended without an exit code |
Process exits update the result immediately. TaskLens restores active executions when it starts and reconciles missing lifecycle events while tasks are running. An unavailable exit code is shown as an unknown result, without claiming success or failure.
Inline & context actions
- ▶ Run — execute the task.
- ⏹ Stop — terminate a running task.
- 🔁 Re-run — terminate the in-flight execution (with optional confirm), wait for it to end, then start fresh.
- 🖥 Show Terminal — reveal the task terminal, including completed runs whose terminal is still open.
- ★ / ☆ Favorite — toggle favorite state.
- ➔ Reveal Definition — open
tasks.json and select the matching task object (JSONC-aware).
Auto-reload on save
Saving tasks.json, the workspace file, or package.json refreshes the shared task list. Reload Tasks is available in each task view and the palette for external edits or provider changes. Loading failures keep the previous list visible and show a retry action.
Empty-state CTAs
- No folder open? → [Open Folder] button.
- Folder open but no
tasks.json? → [Create tasks.json] button that scaffolds a starter file with one echo task and the standard JSONC header.
Multi-root aware
Workspaces with multiple folders bucket tasks by folder before grouping. Single-folder workspaces render flat. Tasks scoped to Workspace or Global go into a synthetic Workspace group.
Out of scope (by design)
- Editing tasks. Use
tasks.json directly — it's JSONC and VS Code's editor handles it well.
- Debugging tasks. VS Code's
launch.json / F5 surface owns that.
- Task scheduling. Cron-style scheduling belongs in a CI tool, not your editor.
Quick Start
- Install TaskLens from the VS Code Marketplace or run:
ext install pydemia.tasklens
- Open a folder that has (or could have) a
.vscode/tasks.json.
- Click the TaskLens icon in the activity bar — it appears as a stylized magnifying lens.
- Run a task by clicking the ▶ button on any row, or click the row label to jump to its definition.
No configuration required. The defaults work for the vast majority of projects.
The Three Views: Workspace, Global, Auto-detected
VS Code organizes tasks by scope, but the built-in palette mixes them all. TaskLens splits them so you can find what you need without scrolling.
Workspace — tasks defined in <folder>/.vscode/tasks.json. These are the tasks you and your teammates explicitly wrote and committed. The view shows a [Create tasks.json] button when this file is missing.
Global — tasks in your user-level tasks.json (Cmd/Ctrl+Shift+P → Tasks: Open User Tasks). Reusable across every project — perfect for "open my notes file", "rebuild dotfiles", or any per-machine workflow.
Auto-detected — everything VS Code's contributed providers discovered: every npm script, every gulp/grunt target, every tsc build configuration, every Makefile target (with the right extension), and so on. TaskLens delegates entirely to those providers; if a task shows up in Tasks: Run Task it shows up here.
The discriminator is task.source === 'Workspace' for the first two views; everything else is auto-detected. See src/tree/filters.ts.
Hierarchical Grouping
By default, TaskLens splits each task's label on :: to derive a tree:
db::migrate::up → db › migrate › up
db::migrate::down → db › migrate › down
db::seed → db › seed
build → build (top-level leaf)
Use the Tree View / List View button in a task view's title bar to switch presentation. You can also open … → Task View and choose Tree View or List View; the current option is checked. The choice is saved for the current workspace and applies to Workspace, Global, and Auto-detected views.
If an extension update leaves the current window unable to register tasklens.viewMode, the choice is saved in VS Code's workspace storage instead. It takes effect immediately and survives reopening that workspace. The next successful switch writes the setting normally; changing the configured mode in Settings also replaces the stored choice.
Tree View groups names using the separator. List View shows full task names without name or folder groups; in a multi-root workspace, each row identifies its folder. Favorites keep their own section in both views. Switching preserves running status and favorites and uses the cached task list.
The separate Change Group Separator button (the string icon) controls Tree View grouping. Click it in a task view's title bar, or run Tasklens: Change Group Separator from the command palette. Choose a suggested separator, or type a literal separator and press Enter. Each candidate shows how many task names it splits and an example of the resulting hierarchy. Changing the separator leaves the selected view unchanged; List View uses it when you return to Tree View.
Suggestions use repeated punctuation and shared task-name prefixes. They run locally without an LLM or network requests. Plain labels or a single task may have no useful suggestion; custom input is always available. Escape cancels the picker without changing the tree.
The selected separator is saved only for the current workspace (.vscode/settings.json for a folder, or the settings section of a .code-workspace file). All three task views update immediately, without refetching tasks. Use inherited setting removes the workspace override and restores the user/default value. The current separator is also shown in the Tree View header.
You can still set tasklens.groupSeparator directly:
// .vscode/settings.json
{
"tasklens.groupSeparator": ":" // legacy npm/gulp-style: "npm: watch:tsc" → npm › watch › tsc
}
Common conventions:
| Separator |
Effect |
Good for |
:: (default) |
Opt-in nesting; most existing tasks stay flat |
Modern projects naming tasks like db::migrate::up |
: |
Auto-nests every npm/gulp task that uses prefixes |
Repos with npm: build, npm: test:unit style names |
- |
Nests dash-prefixed naming conventions |
dev-build, dev-test, prod-build style |
/ |
Path-style hierarchy |
tools/lint, tools/format, ci/release |
If you set the separator to an empty string, TaskLens falls back to ::.
Favorites
Favorites live at the top of each view as a synthetic ★ Favorites group. Click the ☆ star on any task row to pin it; the same task gets a ★ indicator wherever else it appears in the tree.
- Storage: per-workspace, via VS Code's
Memento (context.workspaceState). Favorites survive reloads but do not leak across projects — pinning db::migrate::up in one repo doesn't add it to another.
- Removal: click the ★ (filled) on either the favorites entry or the original entry — both un-pin it.
- Visibility: the favorites group only renders when non-empty.
Run, Re-run, Stop, Tail
Run
Clicks vscode.tasks.executeTask(task) directly. The task starts in a new integrated terminal, exactly as if you'd invoked it from Tasks: Run Task.
Re-run
If the task is already running, TaskLens:
- Optionally confirms (controlled by
tasklens.confirmRerunIfRunning, default true).
- Calls
terminate() on the live execution.
- Waits up to 10 seconds for
onDidEndTask to fire.
- Calls
executeTask for a fresh run.
If the task is not running, re-run is just run.
Stop
Stops the live executions of the selected task and waits for termination. Repeated clicks do not launch concurrent run or restart requests.
Tail (Show Terminal)
Show Task Terminal opens an existing integrated terminal. It works after completion while the terminal remains available. TaskLens prefers exact task-name matches, then known task terminal naming patterns. If several terminals match, it asks you to choose.
VS Code does not expose a public Task-to-Terminal mapping, and shared terminals may be reused by another task. If no terminal matches, TaskLens shows a notice. No output is captured or buffered.
Reveal Definition (JSONC-aware)
Click a task label or choose Reveal Definition to select its task object. Folder tasks open their own .vscode/tasks.json; user tasks open user tasks.json; workspace-file tasks open the .code-workspace file. JSONC comments and trailing commas are supported.
A task without a matching definition shows a notice. TaskLens does not fall back to another folder's task file.
Settings Reference
| Setting |
Type |
Default |
Description |
tasklens.viewMode |
"tree" \| "list" |
"tree" |
Workspace presentation. Tree View groups names by separator; List View shows full task names. Choose it with the toolbar button or the Task View menu. |
tasklens.groupSeparator |
string |
"::" |
Separator used to derive the hierarchical task tree from task labels. With ::, a task db::migrate::up nests under db › migrate › up. Set to : for legacy npm/gulp-style nesting. Empty string falls back to ::. |
tasklens.confirmRerunIfRunning |
boolean |
true |
Show a confirmation prompt when re-running a task that is already running. Set to false to re-run without confirmation. |
Edit via Settings UI (search "tasklens") or .vscode/settings.json / user settings.json.
Commands Reference
All commands are namespaced tasklens.*. Per-task commands are hidden from the command palette because they require a tree-node argument.
| Command |
Title |
Where |
tasklens.showTreeView |
Tree View |
Task view title bar, Task View menu, palette |
tasklens.showListView |
List View |
Task view title bar, Task View menu, palette |
tasklens.toggleViewMode |
Toggle Tree/List View |
Palette |
tasklens.changeGroupSeparator |
Change Group Separator |
Separate title bar button, view menu, palette |
tasklens.quickRun |
Find and Run Task |
View title bar, palette |
tasklens.rerunHistory |
Re-run Task |
History row |
tasklens.clearHistory |
Clear Run History |
History title bar, palette |
tasklens.reload |
Reload Tasks |
View title bar, palette |
tasklens.createTasksJson |
Create tasks.json |
Welcome view, palette |
tasklens.runTask |
Run Task |
Inline ▶ on idle tasks |
tasklens.stopTask |
Stop Task |
Inline ⏹ on running tasks |
tasklens.tailLogs |
Show Task Terminal |
Inline 🖥 on any task |
tasklens.rerunTask |
Re-run Task |
Context menu |
tasklens.addFavorite |
Add to Favorites |
Inline ☆ / context menu (un-favorited) |
tasklens.removeFavorite |
Remove from Favorites |
Inline ★ / context menu (favorited) |
tasklens.revealDefinition |
Reveal Definition |
Default click, context menu |
Multi-root Workspaces
When vscode.workspace.workspaceFolders.length > 1, each view buckets tasks by their owning folder before grouping by separator. Top-level groups become folder nodes; the separator hierarchy applies within each folder bucket. Tasks scoped to Workspace or Global go into a synthetic Workspace group.
Single-folder workspaces render flat — no folder bucket overhead.
FAQ
Does TaskLens send any telemetry?
No. TaskLens makes zero network calls. It does not import any analytics SDK. Audit the source: src/ is ~1500 lines of TypeScript, easily readable in one sitting.
Will TaskLens ever require a license, paid tier, or trial activation?
No. TaskLens is Apache-2.0-licensed, free forever, no preview phase, no "unlock all features" upsell. The whole codebase ships in dist/extension.js — there is no server, no key check, no gated functionality.
Why do I need to install TaskLens if VS Code already has Tasks: Run Task?
The palette is fine for occasional use, but it doesn't:
- Show running status at a glance.
- Group tasks hierarchically.
- Pin frequently-used tasks.
- Surface tasks from your own
tasks.json separately from auto-detected ones.
- Provide single-click stop / re-run / reveal-definition.
If you run more than ~5 tasks regularly, a dedicated panel pays for itself within a week.
Why doesn't TaskLens implement its own npm / gulp / tsc provider?
Because VS Code already does. vscode.tasks.fetchTasks() returns every contributed task. Re-implementing providers means re-implementing parsers, edge cases, and bug-for-bug compatibility for every framework — and then re-doing it whenever the framework changes. TaskLens trusts the platform and never falls behind.
Can TaskLens debug a task?
No, by design. VS Code's launch.json / F5 surface is the right tool. Mixing debug and run controls in one panel makes both worse.
Why no animated icons?
Because animated icons (especially in TreeView rows) cause measurable CPU drain on some systems. TaskLens uses VS Code's native ThemeIcon with the ~spin modifier on running tasks — VS Code's renderer handles the animation efficiently and respects your theme.
My task isn't showing up — what now?
- Click the 🔄 Reload Tasks button in the view title bar (or run
tasklens.reload).
- Open the command palette and run
Tasks: Run Task — does VS Code itself see the task? If not, the issue is upstream of TaskLens.
- Check that the task's source extension is enabled (npm, typescript, etc.).
- If the task is in
tasks.json, check that it has a label field — TaskLens (and VS Code) use label as the identifier.
How do I stop the auto-detected view from showing every npm script I have?
Disable VS Code's auto-detection per-language:
// .vscode/settings.json
{
"npm.autoDetect": "off",
"typescript.tsc.autoDetect": "off",
"gulp.autoDetect": "off",
"grunt.autoDetect": "off"
}
These are VS Code settings, not TaskLens settings — they affect every task surface (including Tasks: Run Task).
Does TaskLens work in remote-SSH / Codespaces / WSL?
Yes — it's a UI extension that calls the standard Tasks API, which works identically in all VS Code remote contexts. No special configuration needed.
Does TaskLens support User-level (Global) tasks?
Yes. The Global view shows tasks from your user-level tasks.json (open via Tasks: Open User Tasks). They run in the active workspace folder.
Architecture
For the load-bearing reference on how TaskLens is built — module layout, data model, status registry, log-tailing strategy, JSONC reveal-definition, multi-root scoping, and resolved design decisions — see BLUEPRINT.md.
Highlights:
- Pure modules for grouping (src/tree/group.ts), JSONC location (src/jsonc/locate.ts), — no runtime
vscode import, unit-testable with Mocha alone.
- Single status registry (src/runner/registry.ts) is the source of truth for "is this task running"; all task views subscribe to one event emitter.
- Startup tracking, lazy discovery. TaskLens starts tracking lifecycle events after VS Code startup. Task discovery waits until a view or command needs the list.
- esbuild bundle with
mainFields: ['module', 'main'] to fully bundle jsonc-parser (avoids its UMD dynamic-require runtime crash).
Contributing & Development
yarn install
yarn watch # esbuild + tsc in watch mode
# F5 in VS Code to launch the Extension Development Host
yarn test # @vscode/test-cli + Mocha
yarn package # production bundle
Source layout:
src/
extension.ts # activate / deactivate; wires modules, events
commands.ts # registers tasklens.* commands
tasksJson.ts # detect / scaffold .vscode/tasks.json
taskScopes.ts # global vs workspace classification
types.ts # TaskKey, TaskStatus, TaskNode
tree/ # TreeDataProvider, filters, grouping, icons
runner/ # registry + execute (run/rerun/stop)
terminal/ # terminal focus
jsonc/ # tasks.json JSONC parsing
favorites/ # Memento-backed favorites store
test/ # unit + smoke tests
Issues and PRs welcome at github.com/pydemia/tasklens.
Recommended companion settings
These are VS Code settings, not TaskLens settings — they affect every task surface, but are worth setting once for a cleaner Auto-detected view:
// .vscode/settings.json or user settings.json
{
"npm.autoDetect": "on", // keep on — TaskLens delegates discovery to it
"typescript.tsc.autoDetect": "on",
"gulp.autoDetect": "off", // turn off if you don't use gulp
"grunt.autoDetect": "off",
"task.quickOpen.history": 0 // de-emphasize the palette; you have TaskLens now
}
License
Apache License 2.0 © pydemia.
Keywords
task, tasks, runner, run, shell, script, test, build