Skip to content
slidictPublic

About

Wip is a native, standalone CLI for WSL Containers (WSLC), providing native-like interaction with containerized applications.

Topics

Resources

Contributing

Security policy

Stars

37 stars

Watchers

0 watching

Forks

Repository files navigation

wip logo

wip

Tests License: MIT Platform

Homepage: https://wslc-wip.slidict.com/ · Full documentation: wip Wiki

wip slide

wip is an OSS CLI wrapper that brings a dip-like workflow to Microsoft WSLC. It collects a project's container, image, environment variables, and commands into a single wip.yml, and forwards them to wslc.exe / wslc as safe argument arrays (no shell interpolation).

wip demo

Status: early release. Expect to track WSLC's own interface as it evolves.

This README is just the fastest path to a running wip.yml. For everything else — every config key, every command's flags, guides, and troubleshooting — see the wip Wiki.

Contents

Highlights

  • No orchestration engine of its own — every mode ultimately shells out to wslc.exe / wslc as a safe argv array; wip never talks to Docker and never grows logic that competes with wslc. See Architecture.
  • Three modes for three project shapes — drive containers directly, parse an existing compose.yml yourself, or bridge to a third-party compose-for-wslc tool. See Which mode should you use? below.
  • wip init --ai — describe your stack in natural language and get a validated wip.yml back, via any local OpenAI-compatible server (Ollama, LM Studio). See AI-Assisted Initialization.
  • Healthcheck-aware startup — wip up waits on a dependency's healthcheck: before starting whatever depends on it, in every mode. See Restart Policies.
  • Works from WSL2 shells, not just PowerShell — wip.exe runs on Windows and drives wslc directly, but is meant to be typed from wherever you work. See Running from a WSL2 Shell.
  • Secrets stay masked — wip config redacts credential-shaped values by default. See Secret Masking.
  • --debug shows where time is going — a step trace plus periodic host resource snapshots. See Debug Output.

v2 switched from Ruby to a C# Native AOT binary — wip.exe is now a single self-contained executable with no runtime to install. The Ruby implementation still works and stays available at v1.1.4 / the wslc-wip gem, but has no further updates planned.

Which mode should you use?

wip.yml runs in one of three modes, set with mode:. Pick the one that matches your project:

Situation Use
No compose.yml — wip manages containers directly mode: container (default)
Have compose.yml, don't want to install a third-party tool mode: compose-native
Have compose.yml and already use/prefer a third-party compose-for-wslc tool mode: compose

wip init picks compose-native automatically when it finds a compose.yml/.yaml or docker-compose.yml/.yaml next to it, and container otherwise. For the full breakdown, trade-offs, and compose.yml key support, see Choosing a Mode on the wiki.

Requirements & installation

Windows with WSL2 and Microsoft WSLC. There is no runtime to install: wip.exe is a self-contained Native AOT binary.

WSLC is generally available starting with WSL 3.0.1. Update using the normal release channel, then check the installed version and tooling:

wsl --update
wsl --version
wip doctor

If Microsoft Store updates are unavailable, download the stable release directly from GitHub with wsl --update --web-download, then run wip doctor again.

Install directly from this repository with Scoop:

scoop install https://raw.githubusercontent.com/slidict/wip/main/wip.json

Or with WinGet:

winget install Slidict.Wip

Or manually: download and extract wip-<version>-win-x64.zip from Releases, then add the directory holding wip.exe to your PATH.

Building from source requires MSVC build tools in addition to the .NET SDK — see Building from Source for the one-time setup and common linker errors.

Quick start

This walks through mode: container (the default). Already have a compose.yml? See Which mode should you use? first, or read the wiki's Getting Started guide.

cd my-project
wip init   # writes a starter wip.yml; edit the TODOs, then:
wip doctor
wip build
wip up -d
wip rails console

Starter templates

wip init --template NAME preloads the sync.exclude list in the generated wip.yml with the directories that stack regenerates inside the container, or that are too large to mirror (and names the preset in the comment above the list):

--template sync.exclude patterns written
rails .git, log/, tmp/, storage/, public/assets/, public/packs/, .bundle/, vendor/bundle/, coverage/, node_modules/
ruby .git, log/, tmp/, .bundle/, vendor/bundle/, coverage/
node .git, node_modules/, dist/, build/, .next/, .cache/, coverage/
rust .git, target/
csharp .git, bin/, obj/, .vs/, packages/
wip init --template csharp

That is the whole of it — the preset touches no other key. mode: is still decided by whether a compose file sits next to the target, every other key is still written as the same placeholder or TODO, and omitting --template just starts sync.exclude at .git, tmp/, node_modules/ instead. An unknown name is rejected with the valid list, and --template cannot be combined with --ai (which generates the whole file from a natural-language request instead).

Examples

The quick start above is intentionally minimal. For fuller wip.yml/compose.yml pairs modeled on real stacks — with the sidecars, healthchecks, and day-to-day commands a project actually ends up with — see examples/:

Each has its own README with copy-and-adapt setup instructions.

Configuration

Put a wip.yml in your project root. Running from a subdirectory walks up to find it, or pass --config PATH to point at one explicitly.

version: 1
mode: container # default
container: app # required once dependencies: has entries
dependencies:
  app:
    image: slidict/slidict:development
    workdir: /app
    command: server
    ports:
      - "3000:3000"
    volumes:
      - ".:/app"
interaction:
  rails:
    type: exec
    command: bin/rails
    container: app
    interactive: true

Every config key — dependencies, healthchecks, interaction:/commands:, env files, .dockerignore handling, source sync, secret masking — is covered in full on the wiki, starting at the Configuration Reference.

Commands

Command Description
wip init Write a starter wip.yml
wip doctor Diagnose WSL2, WSLC, config, and the --ai host
wip build / wip up [-d] / wip down Build the image / start the stack / stop and remove it
wip exec / wip run Run a command in the existing container / a new ephemeral one
wip shell Open the configured shell
wip logs [-f] Follow logs
wip NAME ARGS... Run interaction.NAME, appending any extra arguments

Every command's flags, per-mode behavior, and examples are on the CLI Command Reference.

Sandboxes

Besides your app's stack, wip.yml can declare named sandboxes — long-lived containers with their own image and their own storage, for running a tool somewhere isolated from the project's own containers. wip up, wip down and wip exec never touch a sandbox, and wip sandbox never touches the stack.

version: 1
resource_namespace: example-project

volumes:
  - name: state
    persistent: true # kept when the sandbox is destroyed; `false` means ephemeral
    mount: /home/user/state

sandboxes:
  - name: agent
    image: example/tool:1 # its default command has to keep running
    volumes: [state]
wip sandbox create agent                     # run it, mounting the declared volumes
wip sandbox exec agent --interactive -- sh   # a session you drive; `--` keeps sh's own flags
wip sandbox stop agent                       # pause it — `create` resumes the same container
wip sandbox destroy agent                    # remove it; persistent volumes survive

create / list / status / exec / attach / stop / destroy are the whole set. exec runs non-interactively with a 300-second deadline unless you pass --interactive, which has no deadline and cannot be combined with --timeout. Anything that has to survive destroy belongs in the image or on a persistent volume — and installing or signing into whatever CLI the image ships is outside wip's scope.

For the operations and their guarantees, see Sandbox lifecycle; for the configuration and ownership model, Sandbox and volume contract; for declared volumes on their own, volume storage.

Development

git clone https://github.com/slidict/wip.git
cd wip
dotnet build wip.slnx
dotnet test tests/Wip.Tests/Wip.Tests.csproj

Requires the .NET 10 SDK. The test suite doesn't need WSLC and runs on Linux and macOS as well as Windows. See CONTRIBUTING.md for the full setup, and Development on the wiki for the e2e suite, the golden-corpus tests, and architecture notes. Known gaps and deferred decisions are tracked in docs/csharp-migration-plan.md.

A Docker Desktop vs. Wip/WSLC benchmark workflow lives under benchmark/, driven by the wip-benchmark skill. Latest run (2026-09-16, single Windows 11 PC): wip served ~40% higher throughput and about half the p50 latency versus Docker Desktop, at roughly half the host CPU under load — see the full report for the numbers and caveats.

Contributing

Bug reports and pull requests are welcome on GitHub. See CONTRIBUTING.md for commit conventions, versioning policy, and the PR checklist.

License

MIT License

About

Wip is a native, standalone CLI for WSL Containers (WSLC), providing native-like interaction with containerized applications.

Topics

Resources

Contributing

Security policy

Stars

37 stars

Watchers

0 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages