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.