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