nexus-tui 0.1.5__tar.gz → 0.1.14__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/PKG-INFO +4 -1
  2. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/tool_selector.py +45 -27
  3. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/style.tcss +18 -7
  4. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/pyproject.toml +4 -4
  5. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/.gitignore +0 -0
  6. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/LICENSE +0 -0
  7. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/README.md +0 -0
  8. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/__init__.py +0 -0
  9. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/app.py +0 -0
  10. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/config.py +0 -0
  11. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/container.py +0 -0
  12. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/logger.py +0 -0
  13. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/models.py +0 -0
  14. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/__init__.py +0 -0
  15. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/create_project.py +0 -0
  16. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/error.py +0 -0
  17. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/help.py +0 -0
  18. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/project_picker.py +0 -0
  19. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/screens/theme_picker.py +0 -0
  20. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/services/__init__.py +0 -0
  21. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/services/executor.py +0 -0
  22. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/services/scanner.py +0 -0
  23. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/state.py +0 -0
  24. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/tools.toml +0 -0
  25. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/widgets/__init__.py +0 -0
  26. {nexus_tui-0.1.5 → nexus_tui-0.1.14}/nexus/widgets/tool_list_item.py +0 -0
@@ -1,11 +1,14 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: nexus-tui
3
- Version: 0.1.5
3
+ Version: 0.1.14
4
4
  Summary: A TUI orchestrator to manage your installed terminal tools—access everything through a single command
5
5
  License-File: LICENSE
6
6
  Requires-Python: >=3.12
7
+ Requires-Dist: platformdirs>=4.0.0
7
8
  Requires-Dist: pydantic>=2.12.5
9
+ Requires-Dist: structlog>=24.1.0
8
10
  Requires-Dist: textual>=0.86.0
11
+ Requires-Dist: thefuzz>=0.20.0
9
12
  Description-Content-Type: text/markdown
10
13
 
11
14
  # Nexus
@@ -9,16 +9,11 @@ from textual.containers import Horizontal, Vertical
9
9
  from textual.events import Key
10
10
  from textual.reactive import reactive
11
11
  from textual.screen import Screen
12
- from textual.widgets import Label, ListView, Input
12
+ from textual.widgets import Label, ListView
13
13
 
14
14
  from nexus.config import get_tools
15
- from nexus.logger import get_logger
16
- from nexus.models import Tool
17
15
  from nexus.widgets.tool_list_item import CategoryListItem, ToolListItem
18
-
19
-
20
-
21
- log = get_logger(__name__)
16
+ from nexus.models import Tool
22
17
 
23
18
 
24
19
  class ToolSelector(Screen[None]):
@@ -40,12 +35,13 @@ class ToolSelector(Screen[None]):
40
35
  BINDINGS = [
41
36
  ("ctrl+t", "show_theme_picker", "Theme"),
42
37
  ("ctrl+f", "toggle_favorite", "Favorite"),
43
- ("escape", "focus_search", "Search"),
38
+ ("escape", "clear_search", "Clear Search"),
44
39
  ("down", "cursor_down", "Next Item"),
45
40
  ("up", "cursor_up", "Previous Item"),
46
41
  ("right", "cursor_right", "Enter List"),
47
42
  ("left", "cursor_left", "Back to Categories"),
48
43
  ("enter", "launch_current", "Launch Tool"),
44
+ ("backspace", "delete_char", "Delete Character"),
49
45
  ("?", "show_help", "Help"),
50
46
  ("f1", "show_help", "Help"),
51
47
  ]
@@ -67,7 +63,7 @@ class ToolSelector(Screen[None]):
67
63
  "**********************************\n Nexus Interface \n**********************************",
68
64
  id="header-left",
69
65
  )
70
- yield Input(placeholder="Search tools...", id="tool-search")
66
+ yield Label("Search tools...", id="tool-search")
71
67
 
72
68
  with Horizontal(id="main-container"):
73
69
  with Vertical(id="left-pane"):
@@ -107,7 +103,7 @@ class ToolSelector(Screen[None]):
107
103
  yield Label("Type", classes="key-badge")
108
104
  yield Label("Filter", classes="key-desc")
109
105
  yield Label("Esc", classes="key-badge")
110
- yield Label("Reset", classes="key-desc")
106
+ yield Label("Clear", classes="key-desc")
111
107
 
112
108
  # SYSTEM
113
109
  with Horizontal(classes="footer-col"):
@@ -189,31 +185,48 @@ class ToolSelector(Screen[None]):
189
185
  def select_all_category(self) -> None:
190
186
  """Selects the 'ALL' category in the list."""
191
187
  category_list = self.query_one("#category-list", ListView)
192
- # Assuming ALL is always index 1 (FAVORITES is 0)
193
- if category_list.index != 1:
194
- category_list.index = 1
188
+ # Find the index of the ALL category
189
+ for idx, child in enumerate(category_list.children):
190
+ if isinstance(child, CategoryListItem) and child.category_id == "ALL":
191
+ if category_list.index != idx:
192
+ category_list.index = idx
193
+ break
195
194
 
196
- def on_input_changed(self, event: Input.Changed) -> None:
197
- """Called when the search input changes.
195
+ def watch_search_query(self, old_value: str, new_value: str) -> None:
196
+ """Reacts to changes in the search query.
198
197
 
199
198
  Args:
200
- event: The input changed event.
199
+ old_value: The previous search query.
200
+ new_value: The new search query.
201
201
  """
202
- if event.input.id == "tool-search":
203
- self.search_query = event.value
204
- # Switch to ALL category automatically if searching
205
- if event.value:
206
- self.select_all_category()
202
+ try:
203
+ feedback = self.query_one("#tool-search", Label)
204
+ except Exception:
205
+ return
206
+
207
+ if new_value:
208
+ feedback.update(f"SEARCH: {new_value}_")
209
+ # Switch to ALL category automatically if not already
210
+ self.select_all_category()
211
+ # Populate tools with filter
212
+ self.refresh_tools()
213
+ else:
214
+ feedback.update("Search tools...")
215
+ # Re-populate without filter
207
216
  self.refresh_tools()
208
217
 
209
- def action_focus_search(self) -> None:
210
- """Focuses the search input and clears it."""
211
- search = self.query_one("#tool-search", Input)
212
- search.value = ""
213
- search.focus()
218
+ def action_delete_char(self) -> None:
219
+ """Deletes the last character from search query."""
220
+ if self.search_query:
221
+ self.search_query = self.search_query[:-1]
222
+
223
+ def action_clear_search(self) -> None:
224
+ """Clears the search input."""
225
+ if self.search_query:
226
+ self.search_query = ""
214
227
 
215
228
  def on_key(self, event: Key) -> None:
216
- """Global key handler for numeric quick launch.
229
+ """Global key handler for type-to-search and numeric quick launch.
217
230
 
218
231
  Args:
219
232
  event: The key event.
@@ -229,6 +242,11 @@ class ToolSelector(Screen[None]):
229
242
  event.stop()
230
243
  return
231
244
 
245
+ if event.key.isprintable() and len(event.key) == 1:
246
+ # Append char to query
247
+ self.search_query += event.key
248
+ event.stop()
249
+
232
250
  def refresh_tools(self) -> None:
233
251
  """Refreshes tool list based on current selection and search text."""
234
252
  category_list = self.query_one("#category-list", ListView)
@@ -24,13 +24,9 @@ Screen {
24
24
  #tool-search {
25
25
  width: 60%;
26
26
  margin-left: 2;
27
- background: transparent;
28
- border: none;
29
- color: #c0caf5;
30
- }
31
-
32
- #tool-search:focus {
33
- border: solid #7aa2f7;
27
+ padding: 0 1;
28
+ height: 3;
29
+ /* Colors/Borders moved to theme sections */
34
30
  }
35
31
 
36
32
  #tool-description {
@@ -153,6 +149,11 @@ ListItem {
153
149
  .theme-dark #left-pane { border-right: solid #c0caf5; }
154
150
  .theme-dark .pane-header-container { border-bottom: solid #c0caf5; }
155
151
  .theme-dark #tool-description { color: #bb9af7; border-top: solid #c0caf5; }
152
+ .theme-dark #tool-search {
153
+ background: #292e42;
154
+ color: #c0caf5;
155
+ border: tall #7aa2f7;
156
+ }
156
157
 
157
158
  /* Highlight - Dark (Only when list has focus OR it is the tool-list) */
158
159
  .theme-dark ListView:focus > ListItem.--highlight,
@@ -198,6 +199,11 @@ ListItem {
198
199
  .theme-storm #left-pane { border-right: solid #c0caf5; }
199
200
  .theme-storm .pane-header-container { border-bottom: solid #c0caf5; }
200
201
  .theme-storm #tool-description { color: #bb9af7; border-top: solid #c0caf5; }
202
+ .theme-storm #tool-search {
203
+ background: #414868;
204
+ color: #c0caf5;
205
+ border: tall #bb9af7;
206
+ }
201
207
 
202
208
  /* Highlight - Storm (Only when list has focus OR it is the tool-list) */
203
209
  .theme-storm ListView:focus > ListItem.--highlight,
@@ -244,6 +250,11 @@ ListItem {
244
250
  .theme-light #left-pane { border-right: solid #343b58; }
245
251
  .theme-light .pane-header-container { border-bottom: solid #343b58; }
246
252
  .theme-light #tool-description { color: #8c4351; border-top: solid #343b58; }
253
+ .theme-light #tool-search {
254
+ background: #ffffff;
255
+ color: #343b58;
256
+ border: tall #343b58;
257
+ }
247
258
 
248
259
  /* Highlight - Light (Only when list has focus OR it is the tool-list) */
249
260
  .theme-light ListView:focus > ListItem.--highlight,
@@ -1,12 +1,15 @@
1
1
  [project]
2
2
  name = "nexus-tui"
3
- version = "0.1.5"
3
+ version = "0.1.14"
4
4
  description = "A TUI orchestrator to manage your installed terminal tools—access everything through a single command"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
7
7
  dependencies = [
8
8
  "pydantic>=2.12.5",
9
9
  "textual>=0.86.0",
10
+ "structlog>=24.1.0",
11
+ "thefuzz>=0.20.0",
12
+ "platformdirs>=4.0.0",
10
13
  ]
11
14
 
12
15
  [project.scripts]
@@ -30,12 +33,9 @@ dev = [
30
33
  "ruff>=0.14.13",
31
34
  "pytest>=8.0.0",
32
35
  "mypy>=1.0.0",
33
- "structlog>=24.1.0",
34
36
  "pytest-asyncio>=1.3.0",
35
37
  "types-toml>=0.10.8",
36
38
  "pytest-cov>=4.1.0",
37
- "thefuzz>=0.20.0",
38
- "platformdirs>=4.0.0",
39
39
  ]
40
40
 
41
41
  [tool.mypy]
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes