diff --git a/doPlayback.go b/doPlayback.go index 57d99cc..94fd82d 100644 --- a/doPlayback.go +++ b/doPlayback.go @@ -2,35 +2,34 @@ package main import ( "fmt" - "os" - "path/filepath" - "strings" - "go.wit.com/lib/protobuf/chatpb" "go.wit.com/log" ) -const termWidth = 120 // The target width for the formatted output boxes. - func doPlayback() { if argv.Playback.Uuid != "" { showChat(argv.Playback.Uuid) return } - log.Infof("Found %d chat topic(s) in the log.", len(me.chats.GetChats())) fmt.Println("-------------------------------------------------") + // Iterate through the top-level Chat messages, which are now named groups. for _, chat := range me.chats.GetChats() { + + // Get the number of entries in the chat. entryCount := len(chat.GetEntries()) + + // Get the timestamp of the first entry to represent the chat's start time. var formattedTime string - if ctime := chat.GetCtime(); ctime != nil { - t := ctime.AsTime() - formattedTime = t.Format("2006-01-02 15:04:05") + if entryCount > 0 && chat.GetEntries()[0].GetCtime() != nil { + t := chat.GetEntries()[0].GetCtime().AsTime() + formattedTime = t.Format("2006-01-02 15:04:05") // YYYY-MM-DD HH:MM:SS } else { formattedTime = "No Timestamp" } + // Print the formatted one-line summary. fmt.Printf("Topic: %-25s | Entries: %-4d | Started: %s | UUID: %s\n", chat.GetChatName(), entryCount, @@ -47,116 +46,6 @@ func showChat(uuid string) { log.Info("unknown uuid", uuid) return } - - fmt.Printf("\n========================================================\n") - fmt.Printf("== Chat Topic: %s (UUID: %s)\n", chat.GetChatName(), chat.GetUuid()) - fmt.Printf("========================================================\n\n") - - // Since content files are relative, we need a path to a log file. - // This is a limitation. We'll assume the main config file's location. - logDir := filepath.Dir(me.chats.GetConfigPath()) - - for _, entry := range chat.GetEntries() { - author := entry.GetFrom().String() - var formattedTime string - if ctime := entry.GetCtime(); ctime != nil { - t := ctime.AsTime() - formattedTime = t.Format("2006-01-02 15:04:05") - } else { - formattedTime = "No Timestamp" - } - - var content string - if contentFile := entry.GetContentFile(); contentFile != "" { - contentPath := filepath.Join(logDir, contentFile) - contentBytes, err := os.ReadFile(contentPath) - if err != nil { - content = fmt.Sprintf("--- ERROR: Could not read content file %s: %v ---", contentPath, err) - } else { - content = string(contentBytes) - } - } else { - content = entry.GetContent() - } - - if content != "" { - fmt.Printf("✦ %s (%s):\n%s\n", author, formattedTime, strings.TrimSpace(content)) - } - - if table := entry.GetTable(); table != nil { - printTable(table) - } - for _, toolCall := range entry.GetToolCalls() { - printToolCallBox(toolCall) - } - if snippets := entry.GetSnippets(); snippets != nil { - for _, snippet := range snippets { - printCodeSnippet(snippet, logDir) - } - } - fmt.Println() - } -} - -func printTable(table *chatpb.Table) { - if table == nil || len(table.GetRows()) == 0 { - return - } - fmt.Println("┌─[ Table Data ]──────────────────────────────────────────") - for _, row := range table.GetRows() { - fmt.Printf("│ %s\n", strings.Join(row.GetFields(), " │ ")) - } - fmt.Printf("└─────────────────────────────────────────────────────────\n\n") -} - -func printCodeSnippet(snippet *chatpb.CodeSnippet, logDir string) { - snippetPath := filepath.Join(logDir, snippet.GetFilename()) - codeBytes, err := os.ReadFile(snippetPath) - if err != nil { - fmt.Printf("┌─[ ERROR: Could not read snippet file %s ]─\n\n", snippetPath) - return - } - code := string(codeBytes) - language := filepath.Base(snippet.GetFilename()) - fmt.Printf("┌─[ Code Snippet: %s ]──────────────────────────────────\n", language) - for _, line := range strings.Split(strings.TrimSpace(code), "\n") { - fmt.Printf("│ %s\n", line) - } - fmt.Printf("└─────────────────────────────────────────────────────────\n\n") -} - -func printToolCallBox(tc *chatpb.ToolCall) { - boxWidth := termWidth - 2 - fmt.Printf(" ╭%s╮\n", strings.Repeat("─", boxWidth)) - header := fmt.Sprintf(" ✔ %s %s (%s)", tc.GetName(), tc.GetInput(), tc.GetDescription()) - printWrappedLine(header, boxWidth) - printEmptyLine(boxWidth) - if stdout := tc.GetOutputStdout(); stdout != "" { - for _, line := range strings.Split(stdout, "\n") { - printWrappedLine(" "+line, boxWidth) - } - } - if stderr := tc.GetOutputStderr(); stderr != "" { - for _, line := range strings.Split(stderr, "\n") { - printWrappedLine(" "+line, boxWidth) - } - } - printEmptyLine(boxWidth) - fmt.Printf(" ╰%s╯\n", strings.Repeat("─", boxWidth)) -} - -func printWrappedLine(text string, width int) { - if len(text) == 0 { - printEmptyLine(width) - return - } - for len(text) > width { - fmt.Printf(" │ %-*s │\n", width, text[:width]) - text = text[width:] - } - fmt.Printf(" │ %-*s │\n", width, text) -} - -func printEmptyLine(width int) { - fmt.Printf(" │ %*s │\n", width, "") + log.Info("uuid was found ok", uuid) + // TODO: show the chat entries here }