all: use make to build

This overhauls the build system.
We used to use a just-in-time clever build system
so that 'go run' and 'go install' Just Worked.

This was really nice, except that it make it
all but impossible to ship a single binary.
It also required our uses to install npm,
which some folks have an understandably negative reaction to.

This migrates to a makefile for building.
The core typescript building logic is mostly still in Go,
and untouched (boy did I learn that lesson the hard way).

The output is a single file that includes the webui, innie, and outie.

(There are still very mild shenanigans in which we write outie
out to a temp file and then 'docker cp' it into the docker container.
But this is pretty manageable.)

There are some significant follow-ups left after this commit:

- convert the nightly release builds to use the makefile
- lots of dead code removal
- maybe add -race support using a dockerfile for the cgo compilation
- maybe use 'docker cp' stdin reading with tar to avoid the temp outtie file
- all the rest of the "better release" todos (brew install, etc.)
diff --git a/cmd/genwebui/genwebui.go b/cmd/genwebui/genwebui.go
new file mode 100644
index 0000000..2abe552
--- /dev/null
+++ b/cmd/genwebui/genwebui.go
@@ -0,0 +1,29 @@
+package main
+
+import (
+	"flag"
+	"log"
+	"os"
+
+	"sketch.dev/webui"
+)
+
+func main() {
+	flag.Parse()
+	if flag.NArg() != 1 {
+		log.Fatalf("expected exactly 1 arg (destination directory), got %v", flag.NArg())
+	}
+	dest := flag.Arg(0)
+	if dest == "" {
+		log.Fatalf("expected destination directory, got %q", dest)
+	}
+	// TODO: make webui.Build write directly to dest instead of writing to a temp dir and copying to dest
+	fsys, err := webui.Build()
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = os.CopyFS(dest, fsys)
+	if err != nil {
+		log.Fatal(err)
+	}
+}