Skip to main content
Version: 0.1.0-alpha.1

Working Directory

Control where your commands execute with the workdir setting. This is especially useful for monorepos and projects with complex directory structures.

Default Behavior​

By default, commands run in the current directory (where you invoked invowk).

Setting Working Directory​

Command Level​

{
name: "build frontend"
workdir: "./frontend" // Run in frontend subdirectory
implementations: [{
script: "npm run build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Implementation Level​

{
name: "build"
implementations: [
{
script: "npm run build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
workdir: "./web" // This implementation runs in ./web
},
{
script: "go build ./..."
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
workdir: "./api" // This implementation runs in ./api
}
]
}

Root Level​

workdir: "./src" // All commands default to ./src

cmds: [
{
name: "build"
// Inherits workdir: ./src
implementations: [...]
},
{
name: "test"
workdir: "./tests" // Override to ./tests
implementations: [...]
}
]

CLI Override​

Override the working directory at runtime:

invowk cmd build --invk-workdir ./frontend

Path Types​

Relative Paths​

Relative to the invkfile location:

workdir: "./frontend"
workdir: "../shared"
workdir: "src/app"

Absolute Paths​

Full system paths:

workdir: "/opt/myapp"
workdir: "/home/user/projects/myapp"

Environment Variables​

Expand variables in paths:

workdir: "${HOME}/projects/myapp"
workdir: "${PROJECT_ROOT}/src"

Precedence​

Implementation overrides command, which overrides root:

workdir: "./root" // Default: ./root

cmds: [
{
name: "build"
workdir: "./command" // Override: ./command
implementations: [
{
script: "make"
workdir: "./implementation" // Final: ./implementation
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}
]
}
]

Monorepo Pattern​

Perfect for monorepos with multiple packages:

cmds: [
{
name: "web build"
workdir: "./packages/web"
implementations: [{
script: "npm run build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},
{
name: "api build"
workdir: "./packages/api"
implementations: [{
script: "go build ./..."
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},
{
name: "mobile build"
workdir: "./packages/mobile"
implementations: [{
script: "flutter build"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}
]

Container Working Directory​

For containers, the current directory is mounted to /workspace:

{
name: "build"
implementations: [{
script: """
pwd # /workspace
ls # Shows your project files
"""
runtimes: [{name: "container", image: "debian:bookworm-slim"}]
platforms: [{name: "linux"}]
}]
}

With workdir, that subdirectory becomes the container's working directory:

{
name: "build frontend"
workdir: "./frontend"
implementations: [{
script: """
pwd # /workspace/frontend
npm run build
"""
runtimes: [{name: "container", image: "node:20"}]
platforms: [{name: "linux"}]
}]
}

Cross-Platform Paths​

Use forward slashes for cross-platform compatibility:

// Good - works everywhere
workdir: "./src/app"

// Avoid - Windows-specific
workdir: ".\\src\\app"

Invowk™ automatically converts to native path separators at runtime.

Real-World Examples​

Frontend/Backend Split​

cmds: [
{
name: "start frontend"
workdir: "./frontend"
implementations: [{
script: "npm run dev"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
},
{
name: "start backend"
workdir: "./backend"
implementations: [{
script: "go run ./cmd/server"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}
]

Test Organization​

cmds: [
{
name: "test unit"
workdir: "./tests/unit"
implementations: [{
script: "pytest"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
},
{
name: "test integration"
workdir: "./tests/integration"
implementations: [{
script: "pytest"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}]
}]
},
{
name: "test e2e"
workdir: "./tests/e2e"
implementations: [{
script: "cypress run"
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}
]

Build in Subdirectory​

{
name: "build"
workdir: "./src"
implementations: [{
script: """
# Now in ./src
go build -o ../bin/app ./...
"""
runtimes: [{name: "native"}]
platforms: [{name: "linux"}, {name: "macos"}, {name: "windows"}]
}]
}

Best Practices​

  1. Use relative paths: More portable across machines
  2. Forward slashes: Cross-platform compatible
  3. Root level for defaults: Override where needed
  4. Keep paths short: Easier to understand

Next Steps​