A Windows desktop app that bridges Azure DevOps work items to git worktrees — and now hosts your AI coding agents right where the code lives.
One window to see every worktree across your registered workspaces, pin the ADO tasks you're working on, spin up task-linked worktrees in a single dialog, launch Explorer / Windows Terminal / VS Code rooted at any worktree, and run embedded agent terminals (Claude / Copilot / Codex / ad-hoc) attributed to the worktree — and, by derivation, the task — they run in.
Built for a solo developer juggling several multi-repo projects with multiple AI coding agents running in parallel on different branches. It hosts nothing itself beyond the agent PTYs — external tools are spawned as child processes.
Going from "task in ADO" to "worktree on disk with tools open on it" is normally a manual chain of terminal commands, path memorization, and window juggling — with no single overview. Once several agents are running, loose terminal windows make it worse. Playground collapses that into one dashboard.
Navigation & worktrees
- Register workspace folders; auto-discover their git repos and every
git worktreewith live dirty/clean status - Sidebar Tree (workspaces → repos → worktrees) with a detail pane: branch, status pills, copyable path, linked-task card
- Create a worktree (with or without a task) and delete one — guarded: refuses a dirty or primary checkout
- One-click launchers: File Explorer, Windows Terminal, VS Code
Azure DevOps tasks & start-work
- Pin tasks by ID or URL; title / type / state fetched live (refresh on focus + manual)
- Start work: task → worktree with a branch from a configurable template (
{type}/{id}-{slug}), editable in the dialog with a live path preview - The task↔worktree link is derived from the branch name (the first standalone multi-digit number) — no shadow state. Task tags appear on worktree rows, cards, and the detail pane
- Auth is strictly via
az account get-access-token— no stored secrets; a graceful "runaz login" prompt on failure
Board view
- A task-centric layout: pinned-task chip strip + a workspace/repo-grouped worktree card grid; clicking a chip highlights its linked worktree cards
Embedded agent sessions
- Spawn CLI coding agents (Claude / Copilot / Codex) as worktree-rooted embedded terminals — a card rail next to a live
xterm.jsterminal (master-detail) - Multiple concurrent sessions; attach/detach with ring-buffer scrollback replay; per-session Stop / Respawn / Remove
- Sessions are attributed to their worktree and task; sessions persist as metadata and reload as stopped (one-click respawn) — PTYs never survive app quit
Throughout
- Light / dark theme, persisted last-session UI state (direction, selection, theme)
- Per-workspace overrides via
.app/config.json(branch + worktree-folder templates); global defaults in Settings - Worktree initialization: a repo's init command runs in every new worktree — from the dialogs and from workflows alike. A failing command never costs you the worktree; the exit code and output are reported inline. The command can be declared in the repo or, to keep a shared team repo clean, in the workspace beside it
// <repo>/.app/config.json — checked in, so it travels with the repo
{
"postCreateCommand": ".\\SetupSkills.cmd"
}Precedence: the repo's own postCreateCommand wins; the workspace's
postCreateCommands[<repoName>] applies only when the repo declares nothing. Exactly one
command ever runs. Keys are per-repo — a repo the map does not name runs nothing — matched
exactly, or case-insensitively when that is unambiguous (Windows folder names are
case-insensitive). The workspace is the repo folder's parent, since a repo is always a direct
child of its workspace.
The command runs through a shell (so .cmd/.ps1 work), with PLAYGROUND_WORKTREE_PATH,
PLAYGROUND_REPO_PATH and PLAYGROUND_BRANCH in its environment, and is killed after 120 s.
A malformed or blank value is ignored (no hook runs). Note that a repo-declared command is repo
content: cloning an untrusted repo into a registered workspace means its postCreateCommand
runs on your next worktree create for that repo — the workspace-level declaration does not carry
that risk, since you author it yourself.
- Electron + React 19 + TypeScript, scaffolded with electron-vite
- node-pty PTYs (main process) + xterm.js (renderer), bridged by typed streaming IPC
- A single typed IPC contract (
src/shared/ipc-contract.ts) is the spine between main / preload / renderer - Vitest for behavior-level tests (real git / FS in temp dirs; hand-rolled fakes, no mocking library)
- JSON config persisted to
%APPDATA%/playground/config.json— no database
Windows-only. ADO integration is view-only.
npm install
npm run dev # start the app with HMR
npm test # vitest run
npm run typecheck # type-check main + renderer
npm run lint # eslint
npm run format # prettier
npm run build:win # production build + Windows installerPre-PR gate: npm run typecheck && npm run lint && npm test.
CLAUDE.md— architecture overview and working notes.specs/project/— vision, roadmap, and decision log;.specs/features/— per-feature spec → design → tasksdesign/handoff/— the hifi design reference (the source of the screenshots above); reference-only, never shipped- The screenshots are regenerated from the prototype with
npx electron scripts/capture-prototype-shots.mjs


