# Building from source This repo ships two Go binaries under `cmd/`: | Binary | Purpose | Path | |--------------|-----------------------------------------------------------------|-------------------------| | `jj-commitd` | Debounced commit daemon for Claude Code sessions (optional). | `cmd/jj-commitd/` | | `planctl` | Lint tool for spec-driven plan directories. | `cmd/planctl/` | Both are pure-Go, standard-module-layout, and require no system libraries at runtime. `jj-commitd` shells out to the `jj` CLI; `planctl` has no runtime dependencies beyond the Go standard library and the one compiled-in `github.com/yuin/goldmark` module. ## Requirements - **Go 1.22 or newer** on `PATH`. The repo's `go.mod` pins a higher toolchain (`go 1.26.1`) for development, but both binaries compile on 1.22 per PRD R7.1 and the CI matrix in `.forgejo/workflows/planctl.yml`. - **`jj`** — only needed at *runtime* for `jj-commitd`. Not a build dependency. - No other tools needed for a vanilla build. ## Installing with `go install` (recommended) Places the binary at `$GOBIN` (falls back to `$GOPATH/bin`, defaulting to `~/go/bin/`). Make sure that directory is on your `PATH`. ```bash # From anywhere: go install forgejo.zerova.net/sid/template-jj/cmd/planctl@latest go install forgejo.zerova.net/sid/template-jj/cmd/jj-commitd@latest # Pin a specific tag or commit: go install forgejo.zerova.net/sid/template-jj/cmd/planctl@v1.0.0 go install forgejo.zerova.net/sid/template-jj/cmd/planctl@ ``` Both binaries are tagged in lockstep with the repo. ## Building from a checkout ```bash git clone https://forgejo.zerova.net/sid/template-jj.git cd template-jj # Binaries to ./bin/ go build -o bin/planctl ./cmd/planctl/ go build -o bin/jj-commitd ./cmd/jj-commitd/ ``` `go build` without `-o` emits the binary into the current directory using the package directory name — useful for one-off checks: ```bash cd cmd/planctl && go build && ./planctl --version ``` ## Reproducible builds Per PRD R7.3 for `planctl` — `go build -trimpath -ldflags="-buildid="` produces byte-stable binaries given the same source. ```bash go build -trimpath -ldflags="-buildid=" -o bin/planctl ./cmd/planctl/ ``` `-trimpath` strips the absolute checkout path from the binary; `-buildid=` zeroes the per-build Go toolchain fingerprint. The output is suitable for deterministic distribution and CI caching. ## Verifying the build ```bash ./bin/planctl --version # planctl 0.1.0-dev ./bin/jj-commitd status # over an existing socket — see docs/jj-commitd.md ``` Run the test suite: ```bash go test ./cmd/planctl/... go test ./cmd/jj-commitd/... ``` `planctl` also has a benchmark: ```bash go test -bench=. -benchtime=3x -run=^$ ./cmd/planctl/ ``` Expected output on a 2023-era machine: ~1 ms per `Benchmark_Lint_BigPlan` invocation (the ~90 KB `testdata/perf/big-plan` fixture), well under the PRD success metric M3 ceiling of 100 ms. ## CI matrix `planctl` is exercised in `.forgejo/workflows/planctl.yml` across: - `os`: `ubuntu-latest`, `macos-latest`, `windows-latest` - `go`: `1.22`, `stable` A dedicated benchmark job runs once per push on `ubuntu-latest` + `stable`. `jj-commitd` has no CI cell yet — it's covered by its own package tests and integration in practice. ## Binary sizes On `darwin/arm64` with Go 1.26.1, stripped with `-ldflags="-s -w"`: - `planctl`: ~5 MB (includes goldmark). - `jj-commitd`: ~3 MB (stdlib only). Both well under any practical size budget. ## Cross-compiling Standard Go cross-compile: ```bash GOOS=linux GOARCH=amd64 go build -o bin/planctl-linux-amd64 ./cmd/planctl/ GOOS=windows GOARCH=amd64 go build -o bin/planctl.exe ./cmd/planctl/ ``` No cgo dependencies; cross-builds work on any platform with the Go toolchain. ## See also - [`docs/planctl.md`](planctl.md) — `planctl` command reference. - [`docs/jj-commitd.md`](jj-commitd.md) — `jj-commitd` command reference. - [`INTEGRATION.md`](../INTEGRATION.md) — integrating this template into an existing or new project.