webui: auto-generate types.ts from go structs
diff --git a/cmd/go2ts/go2ts.go b/cmd/go2ts/go2ts.go
new file mode 100644
index 0000000..7e619bd
--- /dev/null
+++ b/cmd/go2ts/go2ts.go
@@ -0,0 +1,64 @@
+// A command line tool for generating typescript type declarations from go
+// struct types.
+//
+// Exmaple:
+//
+//	go run cmd/go2ts -o loop/webui/src/types.ts
+package main
+
+import (
+	"flag"
+	"fmt"
+	"os"
+
+	"go.skia.org/infra/go/go2ts"
+	"sketch.dev/ant"
+	"sketch.dev/loop"
+	"sketch.dev/loop/server"
+)
+
+func main() {
+	outputPath := flag.String("o", "", "Path to the output TypeScript file.")
+	flag.Parse()
+
+	generator := TS()
+
+	w, err := os.Create(*outputPath)
+	if err != nil {
+		fmt.Printf("error: %v\n", err)
+		os.Exit(1)
+	}
+	fmt.Fprintf(w, "// Auto-generated by sketch.dev/cmd/go2ts.go\n")
+	generator.Render(w)
+}
+
+// TS returns a Go2TS generator for go types we want to use in TypeScript.
+func TS() *go2ts.Go2TS {
+	generator := go2ts.New()
+
+	// Enum types
+	generator.AddMultipleUnion(
+		[]loop.CodingAgentMessageType{
+			loop.UserMessageType,
+			loop.AgentMessageType,
+			loop.ErrorMessageType,
+			loop.BudgetMessageType,
+			loop.ToolUseMessageType,
+			loop.CommitMessageType,
+			loop.AutoMessageType,
+		},
+	)
+
+	// Struct types
+	generator.AddMultiple(
+		loop.AgentMessage{},
+		loop.GitCommit{},
+		loop.ToolCall{},
+		ant.Usage{},
+		server.State{},
+	)
+
+	generator.GenerateNominalTypes = true
+
+	return generator
+}