Coverage for src / lilbee / cli / tui / messages.py: 100%

179 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-04-29 19:16 +0000

1"""Centralized user-facing messages for the TUI. 

2 

3ALL user-facing text MUST be defined here. Inline strings in 

4screens and widgets are forbidden -- this enables future i18n 

5and ensures consistent messaging. 

6""" 

7 

8from __future__ import annotations 

9 

10from lilbee.config import cfg 

11from lilbee.wiki.shared import WIKI_TYPE_HEADINGS as _WIKI_TYPE_HEADINGS 

12 

13CMD_UNKNOWN = "Unknown command: {cmd}" 

14CMD_ADD_NOT_FOUND = "Not found: {path}" 

15CMD_ADD_SUCCESS = "Added {count} file(s), syncing..." 

16CMD_ADD_DUPLICATE_TITLE = "File already in knowledge base" 

17CMD_ADD_DUPLICATE_MESSAGE = "{name} is already in the knowledge base. Overwrite and re-sync?" 

18CMD_ADD_SKIPPED_DUPLICATE = "Kept existing copy of {name}." 

19CMD_ADD_ERROR = "Error: {error}" 

20CMD_CRAWL_USAGE = "Usage: /crawl <url> [--depth N] [--max-pages N]" 

21CMD_CRAWL_STARTED = "Crawling {url}..." 

22CMD_CRAWL_PAGE = "Crawling [{current}/{total}]: {url}" 

23CMD_CRAWL_SUCCESS = "Crawled {count} page(s) from {url}" 

24CMD_CRAWL_FAILED = "Crawl failed: {error}" 

25CMD_CRAWL_SYNCING = "Syncing crawled pages..." 

26SETUP_CHROMIUM_NAME = "Install Chromium browser" 

27SETUP_CHROMIUM_FAILED = "Chromium install failed: {error}" 

28SETUP_CHROMIUM_DETAIL = "chromium: {done}/{total} MB" 

29SETUP_CHROMIUM_DETAIL_UNKNOWN = "chromium: {done} MB" 

30SETUP_CHROMIUM_CLI_PROGRESS = " chromium: {pct}%" 

31SYNC_FAILED_FILES = "Sync failed for {files}" 

32CMD_DELETE_NO_DOCS = "No documents indexed" 

33CMD_DELETE_USAGE = "Documents: {names}\nUsage: /delete <filename>" 

34CMD_DELETE_NOT_FOUND = "Not found: {name}" 

35CMD_DELETE_SUCCESS = "Deleted {name}" 

36CMD_RESET_CONFIRM = "Type '/reset confirm' to delete all data" 

37CMD_RESET_SUCCESS = "Knowledge base reset" 

38CMD_RESET_PARTIAL = "Knowledge base reset ({skipped} item(s) could not be deleted)" 

39CMD_RESET_FAILED = "Reset failed: {error}" 

40CMD_SET_UNKNOWN = "Unknown setting: {key}" 

41CMD_SET_SUCCESS = "{key} = {value}" 

42CMD_SET_INVALID = "Invalid value for {key}: {error}" 

43CMD_SET_READONLY = "{key} is read-only; use the Models screen" 

44CMD_MODEL_SET = "Model set to {name}" 

45CMD_REMOVE_USAGE = "Usage: /remove <model_name>" 

46CMD_REMOVE_NOT_FOUND = "{name} is not installed" 

47CMD_REMOVE_SUCCESS = "Removed {name}" 

48CMD_REMOVE_FAILED = "Failed to remove {name}" 

49CMD_CANCEL = "Cancelled active operations" 

50CMD_CLEAR = "Conversation cleared" 

51CMD_THEME_LIST = "Themes: {names}" 

52CMD_WIKI_DISABLED = "Wiki is disabled (set wiki = true in settings)" 

53TASK_NAME_CRAWL = "Crawl {url}" 

54STREAM_ERROR = "\n\n*Error: {error}*" 

55SYNC_STATUS_SYNCING = "Syncing..." 

56SYNC_STATUS_DONE = "Synced ({count} docs)" 

57SYNC_STATUS_FAILED = "Sync failed" 

58SYNC_FILE_PROGRESS = "Syncing [{current}/{total}]: {file}" 

59SYNC_ALREADY_ACTIVE = "Sync in progress, please wait" 

60EMBEDDING_SET = "Embedding model: {name}" 

61CMD_CRAWL_UNAVAILABLE = "Web crawling is not available. Run 'uv sync --extra crawler' to enable it." 

62CRAWL_DIALOG_TITLE = "Crawl a URL" 

63CRAWL_DIALOG_URL_PLACEHOLDER = "example.com (https:// added automatically)" 

64CRAWL_DIALOG_DEPTH_PLACEHOLDER = "blank = no limit" 

65CRAWL_DIALOG_MAX_PAGES_PLACEHOLDER = "blank = no limit" 

66CRAWL_DIALOG_URL_LABEL = "URL" 

67CRAWL_DIALOG_RECURSIVE_LABEL = "Recursive (crawl whole site)" 

68CRAWL_DIALOG_ADVANCED_TITLE = "Advanced" 

69CRAWL_DIALOG_DEPTH_LABEL = "Depth cap" 

70CRAWL_DIALOG_MAX_PAGES_LABEL = "Max pages" 

71CRAWL_DIALOG_SUBMIT = "Crawl" 

72CRAWL_DIALOG_CANCEL = "Cancel" 

73CRAWL_DIALOG_URL_REQUIRED = "URL is required" 

74CRAWL_DIALOG_INVALID_URL = "Invalid URL: {error}" 

75CRAWL_DIALOG_INVALID_NUMBER = "{field} must be a positive integer or blank" 

76EMBEDDING_MISSING = ( 

77 "No embedding model, search disabled. " 

78 "Run /models to install one, or: lilbee models install nomic-embed-text" 

79) 

80THEME_SET = "Theme: {name}" 

81HEADING_OUR_PICKS = "Our picks" 

82HEADING_INSTALLED = "Installed" 

83CATALOG_USING_REMOTE = "Using {name} (remote)" 

84CATALOG_ALREADY_INSTALLED = "{name} is already installed" 

85CATALOG_NO_TASK_BAR = "Cannot download: task bar not found" 

86CATALOG_QUEUED_DOWNLOAD = "Queued download: {name}" 

87CATALOG_INSTALLED_OK = "{name} installed" 

88CATALOG_GATED_REPO = "{name} requires login, run /login or lilbee login" 

89CATALOG_DOWNLOAD_FAILED = "{name}: download failed" 

90CATALOG_SELECT_TO_DELETE = "Select a model to delete" 

91CATALOG_NOT_INSTALLED = "{name} is not installed" 

92CATALOG_CONFIRM_DELETE = "Delete {name}? Press d again to confirm" 

93CATALOG_DELETED = "Deleted {name}" 

94CATALOG_DELETE_FAILED = "Delete failed: {error}" 

95CATALOG_NO_MATCH = "No models match your filters." 

96CATALOG_FILTER_PLACEHOLDER = "Filter models..." 

97CATALOG_VIEW_TOGGLE_GRID = "Press v for full list view · / to search" 

98CATALOG_VIEW_TOGGLE_LIST = "Press v for card view · s to sort" 

99CATALOG_BROWSE_MORE = "Browse more models →" 

100CATALOG_SORT_LIST_ONLY = "Sort is available in list view (press v)" 

101CATALOG_SEARCHING_HF = "Searching HuggingFace…" 

102CATALOG_SEARCH_HF_CTA = '→ Search HuggingFace for "{query}"' 

103CHAT_INPUT_PLACEHOLDER = "Ask a question or type / for commands" 

104CHAT_ONLY_BANNER = "Chat only, no document search. Press F5 to set up embedding model." 

105CHAT_WELCOME_TITLE = "lilbee" 

106CHAT_WELCOME_TAGLINE = "your local search engine and personal encyclopedia." 

107CHAT_WELCOME_HINT = "Press / for commands, or just ask." 

108CHAT_LOGIN_PROMPT = "Paste your token with /login <token>" 

109CHAT_LOGGED_IN = "Logged in to HuggingFace" 

110CHAT_LOGIN_FAILED = "Login failed: {error}" 

111CHAT_VERSION = "lilbee {version}" 

112CHAT_RENDERING = "Rendering: {label}" 

113SETTINGS_READ_ONLY = "read-only" 

114SETTINGS_INVALID_VALUE = "Invalid value: {error}" 

115SETTINGS_RESET_TO_DEFAULT_TOOLTIP = "Reset to default" 

116SETTINGS_RESET_ALL_LABEL = "Reset all defaults" 

117SETTINGS_RESET_ALL_CONFIRM_TITLE = "Reset all settings?" 

118SETTINGS_RESET_ALL_CONFIRM_MESSAGE = ( 

119 "Every writable setting will be restored to its built-in default. " 

120 "Readonly fields (like installed models) are not affected." 

121) 

122SETTINGS_RESET_ALL_SUCCESS = "All settings reset to defaults" 

123SETTINGS_RESET_ALL_PARTIAL = "Settings reset with skips: {skipped}" 

124SETTINGS_LIST_EDITOR_TITLE = "{key} ({count} lines)" 

125SETTINGS_LIST_EDITOR_INVALID_REGEX = "Invalid regex on line {n}: {error}" 

126SETTINGS_LIST_EDITOR_RESTORE_DEFAULTS = "Restore defaults" 

127WIKI_EMPTY_STATE = "No wiki pages found" 

128WIKI_SEARCH_PLACEHOLDER = "Filter pages..." 

129WIKI_NO_CONTENT = "Select a page to view" 

130WIKI_INDEX_LABEL = "Index" 

131WIKI_LOG_LABEL = "Log" 

132WIKI_DRAFTS_TITLE = "Wiki Drafts" 

133WIKI_DRAFTS_EMPTY = "No drafts pending review" 

134WIKI_DRAFTS_LOAD_FAILED = "Failed to load drafts: {error}" 

135WIKI_DRAFTS_COLUMN_SLUG = "Slug" 

136WIKI_DRAFTS_COLUMN_KIND = "Kind" 

137WIKI_DRAFTS_COLUMN_DRIFT = "Drift" 

138WIKI_DRAFTS_COLUMN_FAITHFULNESS = "Faithfulness" 

139WIKI_DRAFTS_COLUMN_PUBLISHED = "Published?" 

140WIKI_DRAFTS_KIND_DRIFT = "drift" 

141WIKI_DRAFTS_DIFF_EMPTY = "Select a draft to view its diff" 

142WIKI_DRAFTS_DIFF_NONE = "(no differences)" 

143WIKI_DRAFTS_DIFF_FAILED = "Failed to load diff: {error}" 

144WIKI_DRAFTS_ACCEPT_CONFIRM_TITLE = "Accept draft?" 

145WIKI_DRAFTS_ACCEPT_CONFIRM_MESSAGE = ( 

146 "Overwrite the published page with {slug} and re-index? This cannot be undone." 

147) 

148WIKI_DRAFTS_REJECT_CONFIRM_TITLE = "Reject draft?" 

149WIKI_DRAFTS_REJECT_CONFIRM_MESSAGE = "Delete draft {slug}? The published page will not change." 

150WIKI_DRAFTS_ACCEPTED = "Accepted {slug}" 

151WIKI_DRAFTS_REJECTED = "Rejected {slug}" 

152WIKI_DRAFTS_ACCEPT_FAILED = "Accept failed: {error}" 

153WIKI_DRAFTS_REJECT_FAILED = "Reject failed: {error}" 

154WIKI_DRAFTS_PUBLISHED_YES = "yes" 

155WIKI_DRAFTS_PUBLISHED_NO = "no" 

156WIKI_DRAFTS_SEARCH_PLACEHOLDER = "Filter drafts..." 

157# Re-export the shared heading map with string keys so callers can 

158# look up by raw ``page_type`` string without coercion. 

159WIKI_TYPE_HEADINGS: dict[str, str] = { 

160 kind.value: label for kind, label in _WIKI_TYPE_HEADINGS.items() 

161} 

162APP_CANCELLED = "Cancelled" 

163SETUP_WELCOME = "Welcome to lilbee" 

164SETUP_SUBTITLE = "Pick a chat model and an embedding model to get started." 

165SETUP_INTRO = ( 

166 "lilbee needs two models to work: one for chat and one for search. " 

167 "Pick one of each below — highlight a card and press [b]Enter[/b] to install. " 

168 "Downloads continue in the background, so you can keep picking or press [b]Esc[/b] when done." 

169) 

170SETUP_HEADING_CHAT = "Chat Models" 

171SETUP_HEADING_EMBED = "Embedding Models" 

172SETUP_ENTER_HINT = "Enter on a card to install · Esc when done" 

173SETUP_RETURN_HINT = "Your existing models are ready · Esc to return" 

174SETUP_CARD_HINT = "↵ Enter to install" 

175DEFAULT_VIEW = "Chat" 

176_BASE_NAV_VIEWS: tuple[str, ...] = (DEFAULT_VIEW, "Catalog", "Status", "Settings", "Tasks") 

177 

178 

179def get_nav_views() -> list[str]: 

180 """Return the active nav view names, including Wiki when enabled.""" 

181 views = list(_BASE_NAV_VIEWS) 

182 if cfg.wiki: 

183 views.append("Wiki") 

184 return views 

185 

186 

187MODE_NORMAL = "NORMAL" 

188MODE_INSERT = "INSERT" 

189TASKBAR_HINT = "Press t for Tasks" 

190TASKBAR_HINT_INPUT = "Esc then t for Tasks" 

191CHAT_REASONING_STREAMING = "thinking..." 

192CHAT_REASONING_FINISHED = "reasoning · {tokens} tokens" 

193CHAT_SOURCES_LABEL = "sources" 

194 

195TASK_CENTER_TITLE = "Background Tasks" 

196TASK_CENTER_COUNTS = "{active} running · {queued} queued · {done} done" 

197TASK_CENTER_HINT = "r refresh c cancel C clear done q back j/k navigate" 

198TASK_CENTER_EMPTY_HEADLINE = "✓ all caught up" 

199TASK_CENTER_EMPTY_DETAIL = "no background tasks" 

200TASKBAR_SINGLE = "{name} [b]{pct:.1f}%[/b]" 

201TASKBAR_MULTIPLE = "[b]{count} tasks running[/b]" 

202TASKBAR_ONE = "[b]1 task running[/b]" 

203TASKBAR_QUEUED_COUNT = "{count} queued" 

204TASKBAR_ALL_DONE = "[b]Done[/b]" 

205TASKBAR_FAILED = "[b]{count} task failed[/b]" 

206TASKBAR_FAILED_PLURAL = "[b]{count} tasks failed[/b]" 

207SYNC_EMBEDDING = "Embedding {file}" 

208SYNC_FILE_DONE = "Done: {file}" 

209 

210SETTINGS_API_KEYS_WARNING = ( 

211 "These keys are stored in plain text at {path}. " 

212 "Anything you send to these providers leaves your machine. " 

213 "Do not route sensitive documents from lilbee through them." 

214) 

215MODEL_BAR_CLOUD_PROVIDER_WARNING = ( 

216 "Chat prompts are being sent to {provider}. Do not share sensitive data." 

217)