1// A command line tool for generating typescript type declarations from go
2// struct types.
3//
4// Example:
5//
6// go run ./cmd/go2ts -o ui/src/generated-types.ts
7package main
8
9import (
10 "flag"
11 "fmt"
12 "os"
13 "time"
14
15 "go.skia.org/infra/go/go2ts"
16 "shelley.exe.dev/db"
17 "shelley.exe.dev/db/generated"
18 "shelley.exe.dev/llm"
19)
20
21func main() {
22 outputPath := flag.String("o", "", "Path to the output TypeScript file.")
23 flag.Parse()
24
25 if *outputPath == "" {
26 fmt.Println("Usage: go run ./cmd/go2ts -o <output-file>")
27 os.Exit(1)
28 }
29
30 generator := TS()
31
32 w, err := os.Create(*outputPath)
33 if err != nil {
34 fmt.Printf("error: %v\n", err)
35 os.Exit(1)
36 }
37 defer w.Close()
38
39 fmt.Fprintf(w, "// Auto-generated by shelley.exe.dev/cmd/go2ts.go\n")
40 fmt.Fprintf(w, "// Do not edit manually - regenerate with: go run ./cmd/go2ts -o ui/src/generated-types.ts\n\n")
41 generator.Render(w)
42}
43
44// TS returns a Go2TS generator for go types we want to use in TypeScript.
45func TS() *go2ts.Go2TS {
46 generator := go2ts.New()
47
48 // Database message types enum
49 generator.AddMultipleUnion(
50 []db.MessageType{
51 db.MessageTypeUser,
52 db.MessageTypeAgent,
53 db.MessageTypeTool,
54 db.MessageTypeError,
55 db.MessageTypeSystem,
56 db.MessageTypeGitInfo,
57 },
58 )
59
60 // Database struct types
61 generator.AddMultiple(
62 generated.Conversation{},
63 llm.Usage{},
64 )
65
66 generator.AddMultiple(
67 apiMessageForTS{},
68 streamResponseForTS{},
69 conversationWithStateForTS{},
70 )
71
72 // Generate clean nominal types
73 generator.GenerateNominalTypes = true
74
75 return generator
76}
77
78type apiMessageForTS struct {
79 MessageID string `json:"message_id"`
80 ConversationID string `json:"conversation_id"`
81 SequenceID int64 `json:"sequence_id"`
82 Type string `json:"type"`
83 LlmData *string `json:"llm_data,omitempty"`
84 UserData *string `json:"user_data,omitempty"`
85 UsageData *string `json:"usage_data,omitempty"`
86 CreatedAt time.Time `json:"created_at"`
87 DisplayData *string `json:"display_data,omitempty"`
88 EndOfTurn *bool `json:"end_of_turn,omitempty"`
89}
90
91type conversationStateForTS struct {
92 ConversationID string `json:"conversation_id"`
93 Working bool `json:"working"`
94 Model string `json:"model,omitempty"`
95}
96
97type conversationWithStateForTS struct {
98 ConversationID string `json:"conversation_id"`
99 Slug *string `json:"slug"`
100 UserInitiated bool `json:"user_initiated"`
101 CreatedAt string `json:"created_at"`
102 UpdatedAt string `json:"updated_at"`
103 Cwd *string `json:"cwd"`
104 Archived bool `json:"archived"`
105 ParentConversationID *string `json:"parent_conversation_id"`
106 Model *string `json:"model"`
107 Working bool `json:"working"`
108}
109
110type streamResponseForTS struct {
111 Messages []apiMessageForTS `json:"messages"`
112 Conversation generated.Conversation `json:"conversation"`
113 ConversationState *conversationStateForTS `json:"conversation_state,omitempty"`
114 Heartbeat bool `json:"heartbeat,omitempty"`
115}