Nash Tasks and VS Code Tasks Support
We're excited to announce Nash Tasks — a first-class task runner built right into Nash. Define, organize, and execute commands from your terminal without leaving your workflow, and if you're already using VS Code, your existing tasks.json tasks are automatically available too.
What Are Nash Tasks?
Nash tasks are named commands defined in TOML manifests. Think of them as bookmarked scripts that live alongside your project, accessible from the Nash command palette in an instant. Every task has an id, a human-readable title, and one of three execution styles.
Tasks live in two places:
- Global —
tasks.tomlin your Nash config directory, available in every project - Project —
.nash.tomlin your project root, scoped to that workspace
A minimal .nash.toml looks like this:
version = 1
[[task]]
id = "build"
title = "Build"
command = "cargo build --release"Drop that file in any project root, open the command palette in Nash, and "Build" is ready to run. For the full manifest format and all supported fields, see the Nash Tasks Overview in the docs.
Three Ways to Run a Task
Every task uses exactly one execution style — pick the one that fits the job. See Execution Styles for the complete reference.
command — shell execution
Pass a string to your system shell. Pipes, redirects, globbing, and variable expansion all work as expected.
[[task]]
id = "serve"
title = "Start Dev Server"
command = "npm run dev -- --port 3000"You can also pin a specific shell with the shell field if you need portable behavior across environments.
argv — direct process execution
Pass an argument vector straight to the executable with no shell in between — no quoting concerns, no unexpected expansion.
[[task]]
id = "lint"
title = "Lint Project"
argv = ["cargo", "clippy", "--", "-D", "warnings"]Multi-step — sequential pipeline
Chain multiple commands into a single task. Each step is named and if any step fails, execution stops immediately.
[[task]]
id = "quality-gates"
title = "Quality Gates"
target = "new_tab"
[[task.step]]
name = "Format Check"
command = "cargo fmt --check"
[[task.step]]
name = "Lint"
command = "cargo clippy -- -D warnings"
[[task.step]]
name = "Tests"
argv = ["cargo", "test"]Controlling Where Tasks Run
The target field determines what happens in the UI when a task executes. Options include current_pane, new_tab, new_window, split_horizontal, and split_vertical. Two companion flags, focus and keep, give you fine-grained control over the spawned pane's behavior:
[[task]]
id = "watch-logs"
title = "Watch Logs"
target = "split_horizontal"
focus = false # don't steal focus
keep = true # stay open after command exits
command = "tail -f /var/log/app.log"This opens a log viewer in a horizontal split alongside your current work, without interrupting what you're doing. For the full target reference and domain options, see Targets & Execution Domains.
Global vs. Project Tasks — Scope & Overrides
Tasks from multiple sources are merged at runtime. The priority order is:
- Global (
tasks.toml) — your personal defaults - Project (
.nash.toml) — project-specific tasks and overrides - VS Code (
tasks.json) — automatically converted and merged in
When the same id appears in multiple sources, the more local definition wins — project overrides global, native Nash overrides VS Code. This means you can define a global test task and silently customize it per project without touching any shared config. See Scope & Overrides for the full merge rules.
VS Code Tasks Integration
If you use VS Code, your .vscode/tasks.json is automatically detected and converted into Nash-compatible tasks. No extra configuration needed — open Nash in a project with a tasks.json and those tasks are immediately available in the command palette alongside any native Nash tasks.
How the Conversion Works
tasks.json ──► Parse & map fields ──► Merge with .nash.toml ──► Available in command palette
Nash maps VS Code task fields to their Nash equivalents:
VS Code tasks.json | Nash .nash.toml equivalent |
|---|---|
label | title |
type: "shell" | command execution style |
type: "process" | argv execution style |
command + args | mapped to command or argv |
options.cwd | cwd |
options.env | env |
options.shell.executable | shell override |
presentation.panel | influences keep behavior |
A standard VS Code build task:
{
"version": "2.0.0",
"tasks": [
{
"label": "Build",
"type": "shell",
"command": "npm run build",
"group": "build",
"problemMatcher": []
}
]
}…is automatically surfaced in Nash as a task titled "Build" that runs npm run build through the shell. Nothing to migrate, nothing to rewrite.
Extending VS Code Tasks with Nash Features
The real power comes from combining both systems. You can augment a VS Code task with Nash-only capabilities — like spawn domains, focus control, or multi-step sequencing — by adding a matching entry in .nash.toml:
# .nash.toml
[[task]]
id = "build"
title = "Build (Dedicated Domain)"
domain = "build-domain"
keep = true
focus = falseNash merges the two: the command comes from tasks.json, while the domain, keep, and focus come from your native definition. Nash values always take precedence on conflict. For the full field-by-field conversion reference, see VS Code Task Conversion Details.
Nash Tasks and VS Code integration are available now. Head over to the download page to get the latest version, and check out the full tasks documentation to see everything that's possible.
-Nash Team
P.S. Don't hesitate to reach out if you have any questions or feedback!