Task Runner for Invoke
Run your Invoke (pyinvoke) tasks without leaving VS Code. The @task functions in
your tasks.py (or tasks/ package) show up in Terminal → Run Task..., in an Invoke Tasks view in the
Explorer side bar, and as a ▶ Run button right above each task function.
Why this extension
Invoke is a popular way to keep a Python project's chores (build, lint, release, deploy) in plain Python. The older
Invoke extension on the Marketplace has not been updated since 2019. This one is a fresh, tested implementation that
follows how Invoke 2.x/3.x names and finds tasks, and runs them with your own invoke the same way you would in a
terminal.
It does not install or bundle Invoke. Install it the way you normally do (pip install invoke,
uv add --dev invoke, poetry add --group dev invoke, pipx install invoke...) and, if invoke is not on your
PATH, point the extension at it with the invokeTasks.command setting.
Features
Run Task integration. Every task becomes a VS Code task of type invoke, with the first line of its
docstring as the detail. Reference tasks from .vscode/tasks.json to bind a key or chain them with dependsOn:
{
"version": "2.0.0",
"tasks": [
{ "type": "invoke", "task": "test", "args": ["-k", "slow"], "label": "slow tests" },
{ "type": "invoke", "task": "docs.build", "file": "services/api/tasks.py" }
]
}
task is required (a name or alias, exactly as typed after invoke). args go after the task name. file
picks the project (relative to the workspace folder); without it the project at the folder root is used.
Invoke Tasks view in the Explorer: one entry per project, its tasks, and its sub-collections as folders. The
default task is starred. Hover a task to see its options (-m, --my-arg=STRING, --[no-]flag, which arguments are
positional, their help= text), aliases, and pre/post tasks. Click a task to jump to its function; use ▶ to
run it, or the context menu for Run Task with Arguments... (the input box suggests the flags).
▶ Run CodeLens above each @task in tasks.py and in the modules of a tasks/ package, using the task's
full name (for example docs.build for a task in tasks/docs.py). It follows unsaved edits.
Invoke's own naming rules: build_docs is run as build-docs; @task(name=..., aliases=[...], default=True) are honoured; tasks.auto_dash_names: false in invoke.yaml / invoke.yml / invoke.json keeps
underscores. Flags are named like Invoke does (my_arg → --my-arg, with automatic short flags).
Namespaces: ns = Collection(...) / namespace = Collection(...), ns.add_task(task, name=...),
ns.add_collection(module_or_collection, name=..., default=...), Collection.from_module(...), and modules imported
from your project (from . import docs, import deploy) become dotted task names, the same as invoke --list.
Monorepos. Every folder with a tasks.py or tasks/__init__.py that uses Invoke is a project; tasks start
in that folder. A tasks.py that is not an Invoke file (for example a Celery or Django tasks.py) is ignored, as
are virtual environments and node_modules.
The list updates when you edit task files or invoke.yaml.
Settings
| Setting |
Default |
What it does |
invokeTasks.command |
["invoke"] |
Command that starts Invoke. Examples: ["inv"], ["uv", "run", "invoke"], ["poetry", "run", "inv"], [".venv/bin/invoke"]. ${workspaceFolder} is replaced, and a relative program path containing / is resolved from the workspace folder. |
invokeTasks.discovery |
static |
static reads your code without running it. invoke runs invoke --list in each project folder whenever the list refreshes, which is exact for dynamic namespaces but imports (runs) your tasks.py. If it fails, the extension falls back to reading the code and says why in the view. |
invokeTasks.collectionName |
tasks |
The module name Invoke loads (invoke -c NAME). Other names are passed with -c. |
invokeTasks.codeLens |
true |
Show the ▶ Run buttons. |
invokeTasks.exclude |
.venv, venv, node_modules, .tox, .nox, site-packages, .git |
Folders that are not searched. |
Command palette: Invoke: Run Task (pick from all tasks) and Invoke: Refresh.
Known limitations
- With the default
static discovery the extension reads code, it does not run it. It shows what is written at the
top level of your task modules (also inside if/try blocks). It cannot see tasks or collections built in loops or
helper functions, collections imported from installed packages (such as invocations), or invoke.py / user-level
config files. When a namespace uses something it cannot read, the view shows a warning naming the line, and you can
switch invokeTasks.discovery to invoke for that workspace.
- Aliases given to
ns.add_task(..., aliases=[...]) are not shown, because Invoke 3.0 does not accept them on the
command line either.
- Invoke searches parent folders for
tasks.py; this extension runs each task in its own project folder.
- Only local folders are supported (not virtual workspaces), and the extension is disabled in untrusted workspaces
because it runs project tasks.
Privacy
The extension reads your files locally. It starts invoke only when you run a task, or when you choose
invokeTasks.discovery: invoke. It sends nothing over the network.
Feedback
Problems and ideas are welcome on the Marketplace page (Q & A / rating). This is an independent extension: it is not
an official Invoke product and is not affiliated with or endorsed by Invoke's authors or maintainers. It was built with
AI assistance by Honestrel and is checked by automated tests in a real VS Code.
| |