diff --git a/artifact_card.go b/artifact_card.go index 478888f..1bf76d4 100644 --- a/artifact_card.go +++ b/artifact_card.go @@ -10,7 +10,7 @@ import ( "mujicaui/theme" ) -// ArtifactKind is what an artifact holds. The zero value is ArtifactCode. +// ArtifactKind is what an artifact holds; zero is ArtifactCode. type ArtifactKind int const ( @@ -23,7 +23,7 @@ const ( type ArtifactCardOptions struct { Kind ArtifactKind Title string - // Detail is a short fact, such as "Go ยท 120 lines". + // Detail is a short fact, such as "Go, 120 lines". Detail string // Streaming shows the artifact is still being written. Streaming bool @@ -34,7 +34,7 @@ var artifactKinds = [3]struct{ icon, name string }{ {"file", "artifact_card.code"}, {"file-text", "artifact_card.document"}, {"layout-grid", "artifact_card.web"}, } -// ArtifactCard stands for an artifact inside a message; a click or Enter asks to open the artifact panel. +// ArtifactCard stands for an artifact; activating asks to open it. func ArtifactCard(c *ui.Context, opts ArtifactCardOptions) ChoiceResult { if opts.Title == "" { panic("mujica: ArtifactCard needs a Title") diff --git a/capability_cards.go b/capability_cards.go index da12989..fb977cf 100644 --- a/capability_cards.go +++ b/capability_cards.go @@ -9,7 +9,7 @@ import ( "mujicaui/theme" ) -// CapabilityCard explains one thing the assistant can do, with example prompts. +// CapabilityCard explains one assistant capability with example prompts. type CapabilityCard struct { Title, Description string Icon *ui.SVG @@ -30,7 +30,7 @@ type CapabilityCardsView struct { Example string } -// CapabilityCards shows what the assistant can do; clicking an example hands it to the caller. +// CapabilityCards shows capabilities; a clicked example goes to the caller. func CapabilityCards(c *ui.Context, cards []CapabilityCard, opts CapabilityCardsOptions) CapabilityCardsView { if opts.Columns < 0 { panic("mujica: CapabilityCards Columns is negative") @@ -76,7 +76,7 @@ func CapabilityCards(c *ui.Context, cards []CapabilityCard, opts CapabilityCards return v } -// capabilityExample is a quoted example prompt button; it reports a click. +// capabilityExample is a quoted example button reporting a click. func capabilityExample(c *ui.Context, k theme.Tokens, text string) bool { d := Density(c) b := ui.ButtonBase(c).MinHeight(d.ControlHeight()).Padding(d.Unit(), d.Unit()*3).Justify(ui.Start). diff --git a/chat_empty_state.go b/chat_empty_state.go index 38628f9..a386f0a 100644 --- a/chat_empty_state.go +++ b/chat_empty_state.go @@ -8,7 +8,7 @@ import ( "mujicaui/icons" ) -// ChatEmptyKind is why a chat view is empty. The zero value is ChatEmptyNew. +// ChatEmptyKind is why a chat is empty; zero is ChatEmptyNew. type ChatEmptyKind int const ( @@ -20,18 +20,18 @@ const ( ChatEmptyOffline ) -// ChatEmptyStateOptions configure a ChatEmptyState; empty texts use the kind's built-in copy. +// ChatEmptyStateOptions configure a ChatEmptyState; empty texts use built-in copy. type ChatEmptyStateOptions struct { Kind ChatEmptyKind // Query, for ChatEmptyNoResults, is named in the description. Query string Title string Description string - // Action replaces the kind's button text: Start, Clear search or Retry. + // Action replaces the kind's built-in button text. Action string } -// ChatEmptyState explains an empty chat (new, no results, offline) and offers the next step. +// ChatEmptyState explains an empty chat and offers the next step. func ChatEmptyState(c *ui.Context, opts ChatEmptyStateOptions) EmptyStateResult { switch opts.Kind { case ChatEmptyNew: diff --git a/conversation_export.go b/conversation_export.go index e9c6f40..3acf073 100644 --- a/conversation_export.go +++ b/conversation_export.go @@ -13,7 +13,7 @@ import ( "mujicaui/theme" ) -// ExportFormat is the text form of an export. The zero value is ExportMarkdown. +// ExportFormat is an export's text form; zero is ExportMarkdown. type ExportFormat int const ( @@ -22,7 +22,7 @@ const ( ExportText ) -// ExportRange is which messages an export holds. The zero value is ExportAll. +// ExportRange is which messages an export holds; zero is ExportAll. type ExportRange int const ( @@ -35,7 +35,7 @@ const ( var exportRoles = map[SessionRole]string{SessionUser: "user", SessionAssistant: "assistant", SessionSystem: "system"} -// ExportConversation writes messages as Markdown, JSON or plain text; it does not parse their text. +// ExportConversation writes messages as Markdown, JSON or plain text. func ExportConversation(title string, messages []SessionMessage, format ExportFormat) string { var b strings.Builder switch format { @@ -145,13 +145,13 @@ type ConversationExportOptions struct { // ConversationExportView is a built ConversationExport and the export asked for. type ConversationExportView struct { Element *ui.Element - // Exported reports Content is ready for the caller to write, as Format. + // Exported reports Content is ready for the caller to write. Exported bool Content string Format ExportFormat } -// ConversationExport picks a format and range, previews the result and hands the text to the caller to save. +// ConversationExport picks format and range, previews, and hands over text. func ConversationExport(c *ui.Context, s *ConversationExportState, messages []SessionMessage, opts ConversationExportOptions) ConversationExportView { if s == nil || opts.Title == "" { panic("mujica: ConversationExport needs a state and a Title") diff --git a/conversation_item.go b/conversation_item.go index 9d04be3..2846c97 100644 --- a/conversation_item.go +++ b/conversation_item.go @@ -14,21 +14,21 @@ import ( // ConversationItemOptions configure a ConversationItem. type ConversationItemOptions struct { - // Today decides the time stamp's form; zero uses the window clock. + // Today decides the time stamp; zero uses the clock. Today Date Selected bool Disabled bool - // Draggable lets the row be dragged onto a ProjectList as a ConversationDrag. + // Draggable lets the row be dropped on a ProjectList. Draggable bool } // ConversationDrag is the value a dragged conversation carries. type ConversationDrag struct{ ID string } -// ConversationItemView is a built ConversationItem and what the user asked for this frame. +// ConversationItemView is a built ConversationItem and its requests. type ConversationItemView struct { Element *ui.Element - // Opened, Deleted, Exported and PinToggled are requests for the caller to carry out. + // Opened, Deleted, Exported and PinToggled are requests for the caller. Opened, Deleted, Exported, PinToggled bool // Renamed reports a confirmed new title, already in conv.Title. Renamed bool @@ -41,7 +41,7 @@ type conversationItemState struct { type conversationItemKey struct{} -// ConversationItem is a conversation row: title, time, and a menu to rename in place, pin, export or delete. +// ConversationItem is a conversation row with rename, pin, export, delete. func ConversationItem(c *ui.Context, conv *ChatConversation, opts ConversationItemOptions) ConversationItemView { if conv == nil || conv.ID == "" { panic("mujica: ConversationItem needs a conversation with an ID") @@ -118,7 +118,7 @@ func ConversationItem(c *ui.Context, conv *ChatConversation, opts ConversationIt return v } -// conversationItemEditor is the in-place title field: Enter keeps a non-blank title, Escape cancels. +// conversationItemEditor edits the title in place; Escape cancels. func conversationItemEditor(c *ui.Context, k theme.Tokens, conv *ChatConversation, st *conversationItemState, v *ConversationItemView) { d := Density(c) in := ui.TextInputBase(c, &st.draft).Grow(1).MinHeight(d.ControlHeight()-4).Padding(0, d.Unit()*2). @@ -142,7 +142,7 @@ func conversationItemEditor(c *ui.Context, k theme.Tokens, conv *ChatConversatio } } -// conversationItemMenu is a borderless ellipsis button opening the menu build fills. +// conversationItemMenu is a borderless ellipsis button opening a menu. func conversationItemMenu(c *ui.Context, label string, build func(m *PopupMenu)) *ui.Element { b := iconAction(c, icons.Must("ellipsis"), label).Role(ui.RoleMenuButton).Shrink(0) open := ui.Local(b, conversationItemKey{}, func() bool { return false }) diff --git a/conversation_list.go b/conversation_list.go index f2d1a0d..9700a1b 100644 --- a/conversation_list.go +++ b/conversation_list.go @@ -37,7 +37,7 @@ type ConversationListState struct { plan conversationListPlan } -// conversationListPlan is the grouped rows, rebuilt only when the data or day changes. +// conversationListPlan holds grouped rows, rebuilt on new data or day. type conversationListPlan struct { src []ChatConversation day Date @@ -45,7 +45,7 @@ type conversationListPlan struct { built bool } -// conversationListRow is group header g (item < 0) or an index into the items. +// conversationListRow is a header (item < 0) or item index. type conversationListRow struct { group, item int } @@ -60,10 +60,10 @@ type ConversationListView struct { // Changed reports a newly chosen conversation, in State.Selected. func (v ConversationListView) Changed() bool { return v.changed } -// Submitted reports Enter or a double click on the chosen conversation. +// Submitted reports Enter or a double click on the choice. func (v ConversationListView) Submitted() bool { return v.submitted } -// ConversationList groups conversations into pinned, today, yesterday, past 7 days and older, building only rows in view. +// ConversationList groups conversations by recency, building only visible rows. func ConversationList(c *ui.Context, s *ConversationListState, items []ChatConversation, opts ConversationListOptions, row func(conv ChatConversation)) ConversationListView { if s == nil { panic("mujica: ConversationList needs a state") @@ -181,7 +181,7 @@ var conversationListGroups = [5]string{ "conversation_list.week", "conversation_list.older", } -// conversationListGroup is the group index of conv: pinned, today, yesterday, 7 days, older. +// conversationListGroup returns the recency group index of conv. func conversationListGroup(conv ChatConversation, today Date) int { day := DateOf(conv.Updated) switch { diff --git a/conversation_search.go b/conversation_search.go index 44bc501..f711f30 100644 --- a/conversation_search.go +++ b/conversation_search.go @@ -20,9 +20,9 @@ type ConversationSearchHit struct { // ConversationSearchOptions configure a ConversationSearch. type ConversationSearchOptions struct { - // Loading shows the caller's search for the query is under way. + // Loading shows the caller's search is under way. Loading bool - // Error is the caller's failed search; it shows with a retry button. + // Error describes a failed search, shown with a retry button. Error string Placeholder string Label string @@ -32,9 +32,9 @@ type ConversationSearchOptions struct { // ConversationSearchView is a built ConversationSearch and this frame's events. type ConversationSearchView struct { Element *ui.Element - // QueryChanged asks the caller to search again for the new query. + // QueryChanged asks the caller to search for the new query. QueryChanged bool - // Chosen is the hit opened by a click or Enter, empty for none. + // Chosen is the hit opened this frame, or empty. Chosen string Retry bool } @@ -47,7 +47,7 @@ type conversationSearchState struct { type conversationSearchKey struct{} -// ConversationSearch searches titles and content; the caller supplies hits for the query and the matches are highlighted. +// ConversationSearch shows caller-supplied hits for a query, highlighting matches. func ConversationSearch(c *ui.Context, query *string, hits []ConversationSearchHit, opts ConversationSearchOptions) ConversationSearchView { if query == nil { panic("mujica: ConversationSearch needs a query") @@ -97,7 +97,7 @@ func conversationSearchList(c *ui.Context, s *conversationSearchState, q string, s.rows.Key = func(i int) any { return hits[i].ID } s.rows.Label = func(i int) string { return hits[i].Title } s.rows.Selected = &s.cursor - // Rows have one height, so the list can size itself before measuring them. + // Rows share one height, so the list sizes itself early. rowH := d.ControlHeight() + FontSize(c, theme.CaptionSize)*theme.LineHeight + 2 restore := dataSelectTheme(c, 0) list := ui.List(c, &s.rows, len(hits), func(i int) { @@ -134,7 +134,7 @@ func conversationSearchList(c *ui.Context, s *conversationSearchState, q string, return chosen } -// conversationSearchSpans splits text into spans, marking each case-insensitive match of q. +// conversationSearchSpans marks each case-insensitive match of q in text. func conversationSearchSpans(text, q string, k theme.Tokens) []ui.Span { r := []rune(text) var spans []ui.Span @@ -152,7 +152,7 @@ func conversationSearchSpans(text, q string, k theme.Tokens) []ui.Span { return spans } -// conversationSearchMatches returns rune ranges of case-insensitive matches of q in text. +// conversationSearchMatches returns rune ranges where q matches, ignoring case. func conversationSearchMatches(text, q string) [][2]int { t, p := []rune(text), []rune(q) if len(p) == 0 { diff --git a/cost_estimator.go b/cost_estimator.go index 553aa80..b70e411 100644 --- a/cost_estimator.go +++ b/cost_estimator.go @@ -7,11 +7,10 @@ import ( "github.com/egoist/mygo/ui" - "mujicaui/internal" "mujicaui/theme" ) -// CostEstimatorOptions configure a CostEstimator. Prices are per million tokens, from the caller. +// CostEstimatorOptions configure a CostEstimator; prices are per million tokens. type CostEstimatorOptions struct { InputTokens, OutputTokens int InputPrice, OutputPrice float64 @@ -21,7 +20,7 @@ type CostEstimatorOptions struct { Digits int } -// CostEstimate is the cost of the input, the output and both. +// CostEstimate is the input, output and total cost. type CostEstimate struct{ Input, Output, Total float64 } // EstimateCost prices token counts at per-million rates. @@ -31,7 +30,7 @@ func EstimateCost(inputTokens, outputTokens int, inputPrice, outputPrice float64 return CostEstimate{in, out, in + out} } -// CostEstimator shows input and output tokens and their estimated cost at the caller's prices. +// CostEstimator shows token counts and cost at caller prices. func CostEstimator(c *ui.Context, opts CostEstimatorOptions) *ui.Element { if opts.InputTokens < 0 || opts.OutputTokens < 0 { panic("mujica: CostEstimator token counts must not be negative") @@ -76,9 +75,7 @@ func CostEstimator(c *ui.Context, opts CostEstimatorOptions) *ui.Element { cell(msg(c, "cost_estimator.output"), k.Text, false) cell(strconv.Itoa(opts.OutputTokens), k.Text, true) cell(money(est.Output), k.Text, true) - ui.Box(c).ColumnSpan(3).Height(9).Draw(func(p *ui.Painter, r ui.Rect) { - internal.Rule(p, r.X, r.X+r.W, r.Y+r.H/2, k.Ornament) - }) + ui.Box(c).ColumnSpan(3).Height(theme.BorderWidth).MarginY(d.Unit()).Background(k.Ornament) ui.Text(c, msg(c, "cost_estimator.total")).Font(theme.SerifFont).TextColor(k.Text) cell(strconv.Itoa(opts.InputTokens+opts.OutputTokens), k.Text, true) ui.Text(c, money(est.Total)).Bold().TextColor(k.AccentText).JustifySelf(ui.End).FontFeatures("tnum") diff --git a/date_separator.go b/date_separator.go index 1d73c87..7e03af2 100644 --- a/date_separator.go +++ b/date_separator.go @@ -16,7 +16,7 @@ type DateSeparatorOptions struct { Today Date } -// DateSeparator marks where a day's messages begin: Today, Yesterday, or the full date in the window's language. +// DateSeparator marks where a day's messages begin, localized. func DateSeparator(c *ui.Context, day Date, opts DateSeparatorOptions) *ui.Element { if !day.Valid() { panic("mujica: DateSeparator needs a valid date") @@ -30,9 +30,7 @@ func DateSeparator(c *ui.Context, day Date, opts DateSeparatorOptions) *ui.Eleme label := dateSeparatorLabel(c, day, today) row := ui.Row(c).FillWidth().Gap(u*3).AlignItems(ui.Center).Padding(u*2, 0).Role(ui.RoleText).Label(label) line := func() { - ui.Box(c).Grow(1).Height(9).Draw(func(p *ui.Painter, r ui.Rect) { - internal.Rule(p, r.X, r.X+r.W, r.Y+r.H/2, k.Border) - }) + ui.Box(c).Grow(1).Height(theme.BorderWidth).Background(k.Border) } row.Children(func() { line() @@ -59,7 +57,7 @@ func dateSeparatorLabel(c *ui.Context, day, today Date) string { msg(c, fmt.Sprintf("calendar.month_%d", day.Month)), day.Day, day.Year) } -// dateSeparatorWhen is a short time stamp: the clock today, else the relative day or date. +// dateSeparatorWhen is a short stamp: time, day or date. func dateSeparatorWhen(c *ui.Context, t time.Time, today Date) string { day := DateOf(t) if day == today { diff --git a/feedback_form.go b/feedback_form.go index 4edcd75..0b7e0b5 100644 --- a/feedback_form.go +++ b/feedback_form.go @@ -10,7 +10,7 @@ import ( "mujicaui/theme" ) -// FeedbackRating is the thumb the user gave. The zero value is FeedbackUp. +// FeedbackRating is the thumb given; zero is FeedbackUp. type FeedbackRating int const ( @@ -18,7 +18,7 @@ const ( FeedbackDown ) -// FeedbackValue is what the user wrote: chosen reasons and a comment. +// FeedbackValue is the chosen reasons and a comment. type FeedbackValue struct { Reasons []string Comment string @@ -29,7 +29,7 @@ type FeedbackFormOptions struct { Rating FeedbackRating // Reasons replaces the built-in reasons for the rating. Reasons []string - // Submitting shows the caller sending the feedback and blocks the form. + // Submitting shows the caller sending; it blocks the form. Submitting bool Disabled bool } @@ -45,7 +45,7 @@ var feedbackReasons = [2][]string{ {"feedback_form.down.wrong", "feedback_form.down.unhelpful", "feedback_form.down.unsafe", "feedback_form.down.style"}, } -// FeedbackForm asks why after a thumbs up or down: reason chips and a comment, then Submit or Cancel. +// FeedbackForm asks for reasons and a comment after a rating. func FeedbackForm(c *ui.Context, value *FeedbackValue, opts FeedbackFormOptions) FeedbackFormView { if value == nil { panic("mujica: FeedbackForm needs a value") diff --git a/project_knowledge_panel.go b/project_knowledge_panel.go index 8c9208b..4a2cce1 100644 --- a/project_knowledge_panel.go +++ b/project_knowledge_panel.go @@ -11,7 +11,7 @@ import ( "mujicaui/theme" ) -// KnowledgeFile is a file in a project's knowledge, sized in tokens by the caller. +// KnowledgeFile is a project knowledge file, sized in tokens. type KnowledgeFile struct { ID, Name string Tokens int @@ -26,16 +26,16 @@ type ProjectKnowledgePanelOptions struct { Disabled bool } -// ProjectKnowledgePanelView is a built panel and what the user asked for. +// ProjectKnowledgePanelView is a built panel and its requests. type ProjectKnowledgePanelView struct { Element *ui.Element // Add asks the caller to pick files to add. Add bool - // Removed is the ID of a file to remove, empty for none. + // Removed is the ID of a file to remove. Removed string } -// ProjectKnowledgePanel lists a project's knowledge files with add, remove and how full it is. +// ProjectKnowledgePanel lists knowledge files with add, remove and usage. func ProjectKnowledgePanel(c *ui.Context, files []KnowledgeFile, opts ProjectKnowledgePanelOptions) ProjectKnowledgePanelView { if opts.Capacity <= 0 { panic("mujica: ProjectKnowledgePanel needs a positive Capacity") @@ -90,7 +90,7 @@ func ProjectKnowledgePanel(c *ui.Context, files []KnowledgeFile, opts ProjectKno return v } -// projectKnowledgeMeter shows used of capacity; near and over the limit add a word and an icon, not only color. +// projectKnowledgeMeter shows usage; limits get words and icons. func projectKnowledgeMeter(c *ui.Context, k theme.Tokens, used, capacity int) { d := Density(c) frac := float64(used) / float64(capacity) diff --git a/project_list.go b/project_list.go index 4c21553..6c73018 100644 --- a/project_list.go +++ b/project_list.go @@ -12,7 +12,7 @@ import ( "mujicaui/theme" ) -// ChatProject is a project that holds conversations; Folder groups projects, empty for none. +// ChatProject holds conversations; Folder groups projects, empty for none. type ChatProject struct { ID, Name, Folder string } @@ -23,7 +23,7 @@ type ProjectListOptions struct { Disabled bool } -// ProjectListState is the chosen project and which folders and projects are open. +// ProjectListState is the chosen project and open folders and projects. type ProjectListState struct { // Selected is the chosen project's ID; empty for none. Selected string @@ -38,12 +38,12 @@ type ProjectListView struct { Changed bool // Opened is a conversation the user opened, empty for none. Opened string - // Moved asks the caller to move conversation MoveID into project MoveTo. + // Moved asks the caller to move MoveID into MoveTo. Moved bool MoveID, MoveTo string } -// ProjectList shows folders of projects and their conversations; drop a ConversationDrag on a project, or use Move to, to file it. +// ProjectList shows project folders and conversations; drops move them. func ProjectList(c *ui.Context, s *ProjectListState, projects []ChatProject, conversations func(projectID string) []ChatConversation, opts ProjectListOptions) ProjectListView { if s == nil || conversations == nil { panic("mujica: ProjectList needs a state and conversations") @@ -91,7 +91,7 @@ func ProjectList(c *ui.Context, s *ProjectListState, projects []ChatProject, con return v } -// projectListFolder is a folder heading on a CollapsibleBase trigger, which reports expanded. +// projectListFolder is a folder heading on a CollapsibleBase trigger. func projectListFolder(c *ui.Context, title string, open *bool) *ui.Element { k := Tokens(c) d := Density(c) diff --git a/prompt_library.go b/prompt_library.go index 827f12c..738566e 100644 --- a/prompt_library.go +++ b/prompt_library.go @@ -13,7 +13,7 @@ import ( "mujicaui/theme" ) -// PromptTemplate is a reusable prompt; {{name}} in Body is a variable to fill before inserting. +// PromptTemplate is a reusable prompt; {{name}} marks a variable. type PromptTemplate struct { ID, Category, Title, Body string } @@ -24,7 +24,7 @@ type PromptLibraryOptions struct { Disabled bool } -// PromptLibraryState is the library's category, search, chosen template and variable values. +// PromptLibraryState holds category, query, chosen template and variable values. type PromptLibraryState struct { // Category filters templates; empty shows all. Category string @@ -34,7 +34,7 @@ type PromptLibraryState struct { shown promptLibraryShown } -// promptLibraryShown caches the filtered templates until the data, query or category changes. +// promptLibraryShown caches filtered templates until data, query or category change. type promptLibraryShown struct { src []PromptTemplate query, category string @@ -43,10 +43,10 @@ type promptLibraryShown struct { built bool } -// PromptLibraryView is a built PromptLibrary and the text inserted this frame. +// PromptLibraryView is a built PromptLibrary and inserted text. type PromptLibraryView struct { Element *ui.Element - // Inserted is the chosen template with its variables filled, empty for none. + // Inserted is the filled template, or empty. Inserted string } @@ -70,7 +70,7 @@ func PromptLibraryFill(body string, values map[string]string) string { }) } -// PromptLibrary browses templates by category and search, previews one, fills its variables and inserts it. +// PromptLibrary browses, previews, fills and inserts prompt templates. func PromptLibrary(c *ui.Context, s *PromptLibraryState, templates []PromptTemplate, opts PromptLibraryOptions) PromptLibraryView { if s == nil { panic("mujica: PromptLibrary needs a state") @@ -152,7 +152,7 @@ func promptLibraryCategory(c *ui.Context, k theme.Tokens, s *PromptLibraryState, } } -// selectableRow is a focusable row chosen by click, Enter or Space, marked with Selection and a diamond. +// selectableRow is a focusable row marked chosen with a diamond. func selectableRow(c *ui.Context, k theme.Tokens, key, label string, chosen bool) bool { d := Density(c) b := ui.ButtonBase(c).Key(key).MinHeight(d.ControlHeight()).Padding(0, d.Unit()*2).Gap(d.Unit() * 2).Justify(ui.Start). @@ -176,7 +176,7 @@ func selectableRow(c *ui.Context, k theme.Tokens, key, label string, chosen bool return b.Clicked() && !b.IsDisabled() } -// promptLibraryPreview shows the filled body, a field per variable, and Insert once all are filled. +// promptLibraryPreview shows the body, variable fields and Insert. func promptLibraryPreview(c *ui.Context, k theme.Tokens, s *PromptLibraryState, t PromptTemplate, disabled bool) string { d := Density(c) vars := PromptLibraryVariables(t.Body) diff --git a/regenerate_menu.go b/regenerate_menu.go index b224406..95fe6c4 100644 --- a/regenerate_menu.go +++ b/regenerate_menu.go @@ -29,7 +29,7 @@ type RegenerateChoice struct { // RegenerateMenuOptions configure a RegenerateMenu. type RegenerateMenuOptions struct { - // Models lists models to retry with; Current is marked and left out. + // Models lists models to retry with; Current is left out. Models []string Current string // Variants replaces the built-in Longer, Shorter, Simpler and More detailed. @@ -37,14 +37,14 @@ type RegenerateMenuOptions struct { Disabled bool } -// RegenerateMenuView is a built menu and the retry chosen this frame. +// RegenerateMenuView is a built menu and the chosen retry. type RegenerateMenuView struct { Element *ui.Element Chosen bool Choice RegenerateChoice } -// RegenerateMenu offers regenerate, retry with another model, and variants such as longer or shorter. +// RegenerateMenu offers retry, another model, and rewrite variants. func RegenerateMenu(c *ui.Context, opts RegenerateMenuOptions) RegenerateMenuView { variants := opts.Variants if variants == nil { diff --git a/shared_conversation_view.go b/shared_conversation_view.go index 00676df..cda049f 100644 --- a/shared_conversation_view.go +++ b/shared_conversation_view.go @@ -13,7 +13,7 @@ import ( "mujicaui/theme" ) -// SessionRole is who wrote a message. The zero value is SessionUser. +// SessionRole is who wrote a message; zero is SessionUser. type SessionRole int const ( @@ -22,7 +22,7 @@ const ( SessionSystem ) -// SessionMessage is one message of a saved conversation, as plain text. +// SessionMessage is one saved message, as plain text. type SessionMessage struct { Role SessionRole // Author names the writer; empty uses the role's name. @@ -39,7 +39,7 @@ type SharedConversationViewOptions struct { Disabled bool } -// SharedConversationView shows a shared conversation read-only, with who shared it and when; it reports Copy link. +// SharedConversationView shows a shared conversation read-only with Copy link. func SharedConversationView(c *ui.Context, messages []SessionMessage, opts SharedConversationViewOptions) ChoiceResult { if opts.Title == "" { panic("mujica: SharedConversationView needs a Title") @@ -78,7 +78,7 @@ func SharedConversationView(c *ui.Context, messages []SessionMessage, opts Share type sharedConversationKey struct{} -// sessionMessageView is one read-only message: author, time and selectable plain text. +// sessionMessageView shows one read-only message with author and time. func sessionMessageView(c *ui.Context, k theme.Tokens, m SessionMessage) { d := Density(c) if m.Role < SessionUser || m.Role > SessionSystem { diff --git a/stop_generating_button.go b/stop_generating_button.go index c63739c..0d5fe29 100644 --- a/stop_generating_button.go +++ b/stop_generating_button.go @@ -17,7 +17,7 @@ type StopGeneratingButtonOptions struct { Disabled bool } -// StopGeneratingButton asks to stop a reply while one is generating; Cmd+. (Ctrl+. elsewhere) does too. +// StopGeneratingButton asks to stop generating; Mod+. does too. func StopGeneratingButton(c *ui.Context, opts StopGeneratingButtonOptions) ChoiceResult { if !opts.Generating { return ChoiceResult{} diff --git a/suggestion_chips.go b/suggestion_chips.go index 0b4fcc7..c11de04 100644 --- a/suggestion_chips.go +++ b/suggestion_chips.go @@ -12,7 +12,7 @@ import ( // SuggestionChipsOptions configure SuggestionChips. type SuggestionChipsOptions struct { - // Send makes a click send the suggestion; by default it fills the input. + // Send makes a click send instead of filling the input. Send bool // Label names the group, such as "Follow-up questions". Label string @@ -24,11 +24,11 @@ type SuggestionChipsView struct { Element *ui.Element // Chosen is the suggestion clicked, empty for none. Chosen string - // Sent reports that Chosen should be sent now; otherwise it is already in the input. + // Sent asks to send Chosen now instead of filling. Sent bool } -// SuggestionChips offers starter prompts or follow-ups; a click fills *input, or with Send asks to send. +// SuggestionChips offers prompts that fill *input or ask to send. func SuggestionChips(c *ui.Context, input *string, suggestions []string, opts SuggestionChipsOptions) SuggestionChipsView { if input == nil { panic("mujica: SuggestionChips needs an input") diff --git a/system_prompt_editor.go b/system_prompt_editor.go index 7fcba8d..ffb0792 100644 --- a/system_prompt_editor.go +++ b/system_prompt_editor.go @@ -17,23 +17,23 @@ import ( type SystemPromptEditorOptions struct { // Default is what Restore default puts back. Default string - // Saved is the text last saved; a different value shows as unsaved. + // Saved is the text last saved; differences show as unsaved. Saved string - // MaxLength is the character limit; over it, Save is blocked. Zero is none. + // MaxLength limits characters, blocking Save beyond it; zero is none. MaxLength int // Saving shows the caller's save in progress and blocks editing. Saving bool Disabled bool } -// SystemPromptEditorView is a built editor and what the user asked for. +// SystemPromptEditorView is a built editor and its requests. type SystemPromptEditorView struct { Element *ui.Element - // Save asks the caller to save *value; Restored reports the default was put back. + // Save asks to save *value; Restored reports the default returned. Save, Restored bool } -// SystemPromptEditor edits a system prompt with a character count, restore default, an unsaved mark and Mod+S to save. +// SystemPromptEditor edits a system prompt with count, restore and save. func SystemPromptEditor(c *ui.Context, value *string, opts SystemPromptEditorOptions) SystemPromptEditorView { if value == nil { panic("mujica: SystemPromptEditor needs a value") diff --git a/testdata/snapshots/darwin/conversation_list-dark.png b/testdata/snapshots/darwin/conversation_list-dark.png index 493b247..775de36 100644 Binary files a/testdata/snapshots/darwin/conversation_list-dark.png and b/testdata/snapshots/darwin/conversation_list-dark.png differ diff --git a/testdata/snapshots/darwin/conversation_list-light.png b/testdata/snapshots/darwin/conversation_list-light.png index 24d91af..ba51165 100644 Binary files a/testdata/snapshots/darwin/conversation_list-light.png and b/testdata/snapshots/darwin/conversation_list-light.png differ diff --git a/thinking_indicator.go b/thinking_indicator.go index df72017..aa1f61d 100644 --- a/thinking_indicator.go +++ b/thinking_indicator.go @@ -11,11 +11,11 @@ import ( // ThinkingIndicatorOptions configure a ThinkingIndicator. type ThinkingIndicatorOptions struct { - // Phase is the caller's stage text, such as "Searching the web"; empty uses "Thinking". + // Phase is the caller's stage text; empty uses "Thinking". Phase string } -// ThinkingIndicator shows the assistant is working: three diamonds rising in turn and the phase; still under reduced motion. +// ThinkingIndicator shows rising diamonds and a phase, still when reduced. func ThinkingIndicator(c *ui.Context, opts ThinkingIndicatorOptions) *ui.Element { k := Tokens(c) d := Density(c) diff --git a/welcome_screen.go b/welcome_screen.go index fca9d27..cd0d46e 100644 --- a/welcome_screen.go +++ b/welcome_screen.go @@ -17,7 +17,7 @@ type WelcomeScreenOptions struct { Disabled bool } -// WelcomeScreen greets a new conversation with capability cards and a starter-prompt slot; it reports a chosen example. +// WelcomeScreen greets a new conversation with cards and prompts. func WelcomeScreen(c *ui.Context, opts WelcomeScreenOptions) CapabilityCardsView { if opts.Greeting == "" { panic("mujica: WelcomeScreen needs a Greeting")