Workspace manager for coding agents

siding

One task, one track, across every repo it touches, with any agent.

Each task gets its own track: one git worktree per repo, a shared branch, and a generated AGENTS.md. Main clones stay untouched. The agent stops at two gates, and you decide.

$ brew install rans0/tap/siding
MAIN LINE · repos/ never edited tracks/add-promo · backend + web tracks/fix-crash · backend --hotfix GATE 1 · PRD GATE 2 · DIFF add-promo fix-crash main MAIN LINE · repos/ never edited tracks/add-promo · backend + web tracks/fix-crash · --hotfix GATE 1 · PRD GATE 2 · DIFF add-promo fix-crash main
signal red: agent stopped, waiting for you green: siding approve main line never blocked
CLI is the core

Any agent that runs shell commands can use it. Adapters only add conveniences.

Plain files

TOML config. Markdown docs and knowledge. JSON track state. No database, no daemon.

Git only

The single hard dependency. gh, node and agents are optional.

Two human gates

Agent stops after the PRD, and again with the uncommitted diff.

Workflow

A task, start to finish

Stages run prd → GATE 1 → build → GATE 2 → ship. The agent runs siding submit and stops. Only you run siding approve; in Claude Code, Codex, Cursor and OpenCode a hook enforces it.

~/work

      
Anatomy of a track

Parallel work, no stash

Every task is a folder with one worktree per repo and the same branch name in each. Several tracks run at once, each in its own terminal, on its own ports.

~/work/
├── siding.toml          # workspace config
├── repos/               # main clones, never edited
│   ├── backend/
│   └── web/
├── tracks/add-promo/
│   ├── AGENTS.md        # rules, repos, skills for this stage
│   ├── .track.json      # stage + base commit
│   ├── backend/         # worktree · rans/add-promo
│   └── web/             # worktree · rans/add-promo
├── docs/2026-10-18_add-promo/
│   └── prd.md plan.md testing.md log.md
└── knowledge/
    ├── rules/  skills/  repos/
    └── inbox/           # lesson proposals

Main clones untouched

Worktrees branch off repos/. A hook blocks edits there. No git checkout between tasks.

Generated AGENTS.md

Rules, worktree paths, branches, repo facts and the skills for the current stage. Regenerated when the stage changes.

Safe by default

Existing branches are reused. done checks everything first and refuses on uncommitted or unpushed work.

A port slot per track

Each worktree gets a .env with env_ports shifted by slot × port_stride and its own COMPOSE_PROJECT_NAME.

slot
0
1
2
web
3000
3100
3200
backend
8080
8180
8280
Learning loop

Every task teaches the next

retro · log.md inbox/ siding learn AGENTS.md KNOW LEDGE
  1. RetroBefore done, the agent writes up to retro_max lesson proposals to knowledge/inbox/, one Markdown file each.
  2. Reviewsiding learn or the board's Inbox: accept, edit, skip or delete, one at a time.
  3. StoreAccepted facts land in knowledge/repos/<repo>.md with a verified commit marker. skill: and rule: proposals become skills or rules.
  4. ReuseEvery later track touching that repo gets the facts in its AGENTS.md. siding doctor flags facts whose paths no longer exist.
Documentation

Read the manual

Quick reference below. The full README covers adopting an existing workspace, epics with siding next, hotfixes and deep reviews.

$ siding init ~/work && cd ~/work
$ siding repo add git@github.com:acme/backend.git
$ siding repo add git@github.com:acme/web.git
$ siding adapter install claude      # or: codex, cursor, opencode, agents

$ siding new add-promo backend,web   # tracks/add-promo/{backend,web}
$ siding open add-promo              # agent in this terminal, also live on the board
$ siding ui                          # board at http://127.0.0.1:4747
$ siding approve add-promo           # you pass Gate 1, later Gate 2
$ siding pr add-promo                # commit, push, one PR per repo
$ siding done add-promo              # after log.md is written

Something looks wrong? Run siding doctor.

Open to contribute

Lay some track with us

siding is MIT licensed and small on purpose: Go stdlib first, plain files, git as the only hard dependency. Issues and PRs welcome.

01 · Setup

git clone https://github.com/rans0/siding
cd siding
go build ./cmd/siding
go vet ./... && go test ./...
siding init /tmp/ws   # scratch workspace
  • Tests use real git repos in t.TempDir(), no network.
  • CI runs Linux, macOS and Windows.

02 · Where code goes

  • cmd/siding: flag parsing and output only
  • internal/core: everything else, shared by CLI and board
  • internal/ui: board handlers, terminal websocket
  • web/: board templates and CSS
  • templates/, starter-knowledge/: embedded into the binary

03 · House rules

  1. One change per commit, imperative message.
  2. A test for each behavior you change.
  3. Paths via filepath.Join, JSON via json.Marshal.
  4. Update the README when a command or flag changes.
  5. New Go module? Needs a reason a few lines can't cover.
RoadmapSessions that outlive the terminal

Keep the agent PTY alive after the starting terminal closes.

Roadmap · WindowsLive board terminal via ConPTY

Today the board shows no terminal on Windows.

AdapterBring your harness

Add an entry to adapters, handle its hook in Guard, cover it in TestGuardPayloads and TestAdapterFiles.