An agent-first repository layout
One wok, any stack.
npm, Cargo, and Go put one language's project at the top of the repository. Agents work across stacks, and without firm rules they scatter files until the repository is a mess. Wokspace puts a workspace at the top and gives every file a definite place.
curl -fsSL https://raw.githubusercontent.com/XiaoXianThis/wokspace/main/apps/site/public/install.sh | shirm https://raw.githubusercontent.com/XiaoXianThis/wokspace/main/apps/site/public/install.ps1 | iexThe install scripts verify SHA-256 checksums. Binaries for every platform are also on the releases page.
A workspace at the top, not a project
AGENTS.md the rules every agent reads first apps/ independent projects, each in its own language's native layout build/ final build output (not committed) docs/ long-lived facts: architecture, decisions, guides, API contracts work/ everything else: specs, scripts, tests, assets, infra, scratch space
A frozen root
Three committed files and four directories. A whitelist .gitignore keeps everything else out of git, including .cursor/, .kiro/, and .claude/.
A frozen skeleton
Every directory exists from day one with a README of its rules, so agents know where a file goes before they write it.
Any stack, side by side
Each app in apps/ is a normal Go, Rust, Node, Python, .NET, or Java project. Apps never share source.
Works without a tool
The rules are plain Markdown. wok only speeds things up: create, run tasks from the root, check the rules.
Convention over configuration
No config file. Task commands live in each app's AGENTS.md; empty cells are detected.
Every platform
Naming rules, line endings, and commands work on Windows, macOS, and Linux.
Get started
wok init my-project # the full skeleton, plus git init cd my-project wok new web # apps/web/AGENTS.md, listed in apps/README.md cd apps/web npm create vite@latest . cd ../.. wok dev web # runs npm run dev in apps/web/
Or ask your agent: "Create a web app with Vite." The rules in AGENTS.md tell it to run wok new web, initialize the app inside apps/web/, fill in the task table, and run wok check before it finishes.
Commands
wok init [dir] # create a wokspace; --existing adds missing files to a non-empty directory wok new <app> # create apps/<app>/ with its AGENTS.md wok dev [app...] # start apps; several run in parallel with labeled output wok build [app...] [--all] # build apps into build/<app>/ wok test [app...] [--all] # test apps wok install [app...] [--all] # install app dependencies wok run <app> <task> [-- args] # run any task wok ls [app] # list apps and the command behind each task wok check # check the layout against AGENTS.md
wok works from any directory inside a wokspace. Inside apps/<app>/, the app name can be left out.
Tasks: convention first, config if needed
Each app's AGENTS.md has a task table that humans, agents, and wok all read. An empty command means "use what wok detects"; wok ls shows the result and where each command came from.
| task | command | windows | |---------|------------------------------------------------------|---------| | install | | | | dev | | | | test | cargo test --all-features | | | build | cargo build --release && cp target/release/api "$WOK_OUT" | cargo build --release && copy target\release\api.exe "$WOK_OUT" |
Detection
| project file | install | dev | test | build |
|---|---|---|---|---|
package.jsonnpm, pnpm, yarn, or bun, chosen from the lock file | <pm> install | <pm> run dev | <pm> run test | <pm> run build |
deno.json | deno install | deno task dev | deno task test | deno task build |
Cargo.toml | cargo fetch | cargo run | cargo test | cargo build --release |
go.mod | go mod download | go run . | go test ./... | go build -o "$WOK_OUT" . |
*.sln *.csproj *.fsproj | dotnet restore | dotnet run | dotnet test | dotnet publish -c Release -o "$WOK_OUT" |
gradlew build.gradle(.kts) | gradlew test | gradlew build | ||
pom.xml | mvn dependency:resolve | mvn test | mvn package | |
pyproject.toml + uv.lock | uv sync | uv run pytest | uv build --out-dir "$WOK_OUT" | |
pyproject.toml + poetry.lock | poetry install | poetry run pytest | poetry build |
Every package.json script and deno.json task becomes a task too, so wok run web lint works without a table row.
Commands run in the app directory, through sh on macOS and Linux and cmd on Windows. Before a command runs, wok replaces $WOK_ROOT, $WOK_APP, and $WOK_OUT (the app's build/<app>/ directory) on every platform, and also sets them as environment variables.
Living with every agent
AGENTS.md is the only committed rule entry point. Kiro, Codex, Cursor, GitHub Copilot, and others read it directly. For Claude Code, create a local CLAUDE.md containing the single line @AGENTS.md.
Agent tool directories stay out of git. Configs a team wants to share (MCP servers, hooks, ...) are kept as standard versions in work/agent/configs/ and copied locally. Kiro specs can be linked from .kiro/specs to work/specs/; on Windows a directory junction needs no admin rights.
The full rules are in AGENTS.md; the trade-offs are in the decision records.