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
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
1"""Centralized user-facing messages for the TUI.
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"""
8from __future__ import annotations
10from lilbee.config import cfg
11from lilbee.wiki.shared import WIKI_TYPE_HEADINGS as _WIKI_TYPE_HEADINGS
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")
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
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"
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}"
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)