Execution Styles#
Nash tasks support three execution styles. Each task must use exactly one style.
Command Style#
The command field passes a single string to the system shell for
interpretation. Shell features like pipes, redirects, globbing, and variable
expansion are all available.
[[task]] id = "serve" title = "Start Dev Server" command = "npm run dev -- --port 3000"
A shell override can be used to force a specific shell regardless of the
platform default:
[[task]] id = "deploy" title = "Deploy" shell = ["bash", "-c"] command = "deploy.sh --env production"
Argv Style#
The argv field passes an argument vector directly to the executable
without shell interpretation. No globbing, no variable expansion, no piping
— the process receives exactly the tokens you specify.
[[task]] id = "lint" title = "Lint Project" argv = ["cargo", "clippy", "--", "-D", "warnings"]
This is ideal when arguments contain spaces, special characters, or when you want deterministic behavior across platforms without quoting concerns.
Multi-Step Execution#
Tasks with [[task.step]] entries run a sequence of commands in order. If any
step fails, execution stops and the task is marked as failed.
[[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"]
Step-Level Overrides#
Each step can override task-level settings:
| Field | Type | Description |
|---|---|---|
name | string | Human-readable step name (shown in progress output) |
cwd | string / path | Step-local working directory |
env | table | Step-local environment variables (merged with task) |
shell | array of strings | Step-local shell argv prefix |
command | string | Shell command for this step |
argv | array of strings | Argv-style execution for this step |
[[task]] id = "build-and-test" title = "Build & Test" env = { NODE_ENV = "production" } [[task.step]] name = "Frontend Build" cwd = "./frontend" command = "npm run build" [[task.step]] name = "Backend Tests" cwd = "./backend" env = { TEST_DB = "sqlite" } command = "pytest"
Note: Step
cwdandenvare composed into generated scripts in declaration order. Earlier steps' env vars are inherited by later steps within the same task.
Working Directory (cwd) Behavior#
Nash provides native support for setting working directories at both the Task level and the Step level, with clear precedence, relative path resolution, and execution isolation.
1. Where do I specify cwd?#
- Task-level
cwd: Applies a default working directory to the entire task execution. It is configured directly inside the[[task]]block using thecwdfield. - Step-level
cwd: Overrides the task's default working directory for that specific step. It is configured directly inside the[[task.step]]block using thecwdfield.
Both options support absolute paths as well as relative paths.
[!NOTE] Relative paths are automatically resolved relative to your active project directory at parse time by the internal path resolver.
2. Can I specify cwd in task.step?#
Yes, absolutely. ``
configure it exactly like this in your .nash.toml or tasks.toml file:
[[task.step]] name = "My Step" cwd = "path/to/subdirectory" command = "npm run build"
3. Isolated Working Directories per Step#
Each step can have its own completely independent working directory.
Nash wraps the execution in a subshell (cd path/to/dir && command), the
directory change cd is fully isolated to that specific step and does not
leak or pollute the working directory of subsequent steps.
On Windows#
The command renderer prefixes each step with an explicit directory switch using
the /d flag:
lines.push(format!("cd /d {}", cmd_quote(cwd.to_string_lossy().as_ref())));
This guarantees that each step explicitly shifts to its designated directory before running.
Concrete TOML Example#
Here is how you would configure a multi-step task in your .nash.toml where
each step runs in a different directory:
[[task]] id = "build-subprojects" title = "Build Frontend and Backend" description = "Compiles frontend assets and updates backend dependencies" icon = "cod_run_all" [[task.step]] name = "Build Frontend" cwd = "client/frontend" command = "npm run build" [[task.step]] name = "Prepare Backend" cwd = "server/backend" command = "cargo build --release"
Continue to Targets & Execution Domains to control where (new window, new tab, new pane etc...) your tasks run.