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:

FieldTypeDescription
namestringHuman-readable step name (shown in progress output)
cwdstring / pathStep-local working directory
envtableStep-local environment variables (merged with task)
shellarray of stringsStep-local shell argv prefix
commandstringShell command for this step
argvarray of stringsArgv-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 cwd and env are 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 the cwd field.
  • Step-level cwd: Overrides the task's default working directory for that specific step. It is configured directly inside the [[task.step]] block using the cwd field.

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.