This guide is for contributors who want to build Wallfacer from source, run tests, and create releases.
- Go 1.25+ — go.dev
claudeCLI (and optionallycodex) on yourPATH— tasks exec it directly- Node.js 22+ — for frontend tests and Tailwind CSS regeneration
- A Claude credential — OAuth token (
claude setup-token) or API key from console.anthropic.com
# Clone the repository
git clone https://github.com/changkun/wallfacer.git
cd wallfacer
# Build the server binary
go build -o wallfacer .make build runs the full gate (fmt + lint + TypeScript build + binary). At runtime the server execs the claude/codex CLI directly; the binary selected per task is set via the WALLFACER_AGENT env var (claude or codex).
# Start the server once to create ~/.wallfacer/.env
wallfacer run
# Stop with Ctrl-C, then edit the env file:# wallfacer/.env — set one of:
CLAUDE_CODE_OAUTH_TOKEN=<your-token>
# ANTHROPIC_API_KEY=sk-ant-...Alternatively, start the server and configure via Settings → Sandbox in the browser.
make test # All tests (backend + frontend)
make test-backend # Go unit tests: go test ./...
make test-frontend # Frontend tests: cd frontend && bunx vitest run| Target | Description |
|---|---|
make build |
Full gate: fmt + lint (Go + Vue typecheck) + frontend build + binary |
make build-binary |
Build just the Go binary, skipping fmt/lint (accepts optional VERSION=) |
make build-desktop |
Build the native desktop app for the current platform (uses go tool wails) |
make build-desktop-darwin / -windows / -linux |
Cross-platform desktop builds |
make install-wails |
Install the Wails CLI tracked as a tool in go.mod |
make server |
Build and run the server natively |
make fmt |
Format Go in place |
make lint |
Lint only (golangci-lint + frontend vue-tsc typecheck); fastest way to catch style regressions |
make test |
Lint + backend tests + frontend tests |
make test-backend |
Go unit tests (go test ./...) |
make test-frontend |
Frontend Vitest runner (cd frontend && bunx vitest run) |
make frontend-build |
Build the Vue SPA into frontend/dist/ for embedding |
make api-contract |
Regenerate API route artifacts from apicontract/routes.go |
make e2e-lifecycle |
E2E task-lifecycle test (supports SANDBOX=claude|codex) |
make e2e-dependency-dag WORKSPACE=/path/to/repo |
E2E dependency DAG with conflict resolution |
make release-notes |
Generate an LLM prompt for release notes (requires RELEASE_VERSION=) |
make release |
Commit release notes, tag, push, create GitHub release (requires RELEASE_VERSION= and RELEASE_NOTES=) |
The Vue SPA is built to frontend/dist/ and embedded into the binary via
go:embed, so an edit normally requires a rebuild. During active frontend
work, run the Vite dev server instead:
make server # Go server on :8080 (serves the embedded SPA + the API)
cd frontend && bun run dev # Vite on :5173 with hot-reload, proxies /api → :8080Open http://localhost:5173 and edit files under frontend/src/ — Vite
hot-reloads in the browser with no rebuild. The Go server only needs
rebuilding when backend code changes.
Releases are triggered by pushing a version tag (v*). Two GitHub Actions workflows run in parallel in this repository:
| Workflow | Artifact |
|---|---|
release-binary.yml |
wallfacer-{linux,darwin,windows}-{amd64,arm64} binaries on the GitHub Release |
release-desktop.yml |
Signed desktop apps (Wallfacer-Desktop-*) on the GitHub Release |
Version embedding. Release binaries are built with -ldflags "-X changkun.de/x/wallfacer/internal/cli.Version=X.Y.Z". This stamps the wallfacer version for wallfacer doctor and usage output.
Creating a release:
# 1. Generate release notes (pipes git diff through claude, writes to docs/releases/)
make release-notes RELEASE_VERSION=v0.0.6
# 2. Review and edit docs/releases/v0.0.6.md
# 3. Commit notes, tag, push, and create GitHub release
make release RELEASE_VERSION=v0.0.6The make release-notes target runs scripts/release-notes.sh, which collects the commit log and diffstat since the previous tag, pipes them through the claude CLI with style instructions derived from the previous release notes, and writes the result to docs/releases/v0.0.6.md.
The make release target:
- Commits
docs/releases/v0.0.6.md - Creates an annotated git tag
- Pushes the commit and tag to origin
- Creates a GitHub release via
gh release createusing the same notes file
The pushed tag triggers the three CI workflows above. All release notes are archived in docs/releases/.