usecli 0.1.69__tar.gz → 0.1.70__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 (70) hide show
  1. {usecli-0.1.69 → usecli-0.1.70}/PKG-INFO +1 -1
  2. {usecli-0.1.69 → usecli-0.1.70}/pyproject.toml +1 -1
  3. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/__init__.py +26 -0
  4. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/base_command.py +1 -0
  5. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/ui/list.py +65 -23
  6. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/services/command_service.py +7 -0
  7. {usecli-0.1.69 → usecli-0.1.70}/LICENSE +0 -0
  8. {usecli-0.1.69 → usecli-0.1.70}/README.md +0 -0
  9. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/__init__.py +0 -0
  10. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/README.md +0 -0
  11. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/__init__.py +0 -0
  12. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/custom/README.md +0 -0
  13. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/custom/__init__.py +0 -0
  14. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/__init__.py +0 -0
  15. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/__init__.py +0 -0
  16. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/about_command.py +0 -0
  17. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/help_command.py +0 -0
  18. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/inspire_command.py +0 -0
  19. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/internal/__init__.py +0 -0
  20. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/base/internal/fzf_command.py +0 -0
  21. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/core/__init__.py +0 -0
  22. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/core/utils.py +0 -0
  23. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/make/__init__.py +0 -0
  24. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/make/make_command.py +0 -0
  25. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/defaults/make/make_theme_command.py +0 -0
  26. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/commands/init_command.py +0 -0
  27. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/config/__init__.py +0 -0
  28. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/config/colors.py +0 -0
  29. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/__init__.py +0 -0
  30. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/error/__init__.py +0 -0
  31. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/error/handler.py +0 -0
  32. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/error/utils.py +0 -0
  33. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/exceptions/__init__.py +0 -0
  34. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/exceptions/base.py +0 -0
  35. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/exceptions/config.py +0 -0
  36. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/exceptions/usage.py +0 -0
  37. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/exceptions/validation.py +0 -0
  38. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/ui/__init__.py +0 -0
  39. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/ui/title.py +0 -0
  40. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/ui/title.txt +0 -0
  41. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/validators/__init__.py +0 -0
  42. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/validators/network.py +0 -0
  43. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/validators/numeric.py +0 -0
  44. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/validators/path.py +0 -0
  45. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/core/validators/string.py +0 -0
  46. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/services/__init__.py +0 -0
  47. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/templates/command.py.j2 +0 -0
  48. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/templates/theme.toml.j2 +0 -0
  49. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/templates/usecli.config.toml.j2 +0 -0
  50. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/ayu_dark.toml +0 -0
  51. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/catppuccin_frappe.toml +0 -0
  52. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/catppuccin_latte.toml +0 -0
  53. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/catppuccin_macchiato.toml +0 -0
  54. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/catppuccin_mocha.toml +0 -0
  55. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/default.toml +0 -0
  56. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/dracula.toml +0 -0
  57. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/gruvbox_dark.toml +0 -0
  58. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/nord.toml +0 -0
  59. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/themes/tokyo_night.toml +0 -0
  60. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/utils/__init__.py +0 -0
  61. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/utils/interactive/__init__.py +0 -0
  62. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/cli/utils/interactive/terminal_menu.py +0 -0
  63. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/menu.py +0 -0
  64. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/params.py +0 -0
  65. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/shared/__init__.py +0 -0
  66. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/shared/config/__init__.py +0 -0
  67. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/shared/config/globals.py +0 -0
  68. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/shared/config/manager.py +0 -0
  69. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/ui.py +0 -0
  70. {usecli-0.1.69 → usecli-0.1.70}/src/usecli/usecli.config.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: usecli
3
- Version: 0.1.69
3
+ Version: 0.1.70
4
4
  Summary: A powerful Python CLI framework for building beautiful, developer-friendly command-line tools.
5
5
  Author: Edward Boswell
6
6
  Author-email: Edward Boswell <thememium@gmail.com>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "usecli"
3
- version = "0.1.69"
3
+ version = "0.1.70"
4
4
  description = "A powerful Python CLI framework for building beautiful, developer-friendly command-line tools."
5
5
  readme = "README.md"
6
6
  authors = [{ name = "Edward Boswell", email = "thememium@gmail.com" }]
@@ -331,6 +331,32 @@ class _FilteredListCommand:
331
331
  def __init__(self, prefix_filter: str) -> None:
332
332
  self.prefix_filter = prefix_filter
333
333
  self.name = "filtered-list"
334
+ self.allow_extra_args = True
335
+ self.allow_interspersed_args = True
336
+ self.ignore_unknown_options = True
337
+ self.hidden = False
338
+ self.deprecated = False
339
+ self.params = []
340
+ self.callback = None
341
+ self.help = None
342
+ self.epilog = None
343
+ self.short_help = None
344
+ self.no_args_is_help = False
345
+ self.context_settings = {}
346
+
347
+ def get_short_help_str(self, limit=45):
348
+ return ""
349
+
350
+ def make_context(self, info_name: str, args: list[str], **kwargs: object):
351
+ from click import Context
352
+
353
+ ctx = Context(self, info_name=info_name, **kwargs) # type: ignore[arg-type]
354
+ return ctx
355
+
356
+ def invoke(self, ctx):
357
+ from usecli.cli.core.ui.list import list_commands
358
+
359
+ list_commands(_get_app(), prefix_filter=self.prefix_filter)
334
360
 
335
361
  def __call__(self, *args, **kwargs):
336
362
  from usecli.cli.core.ui.list import list_commands
@@ -69,6 +69,7 @@ class NestedCommandRegistry:
69
69
  help=f"Commands for {group_name}",
70
70
  invoke_without_command=True,
71
71
  no_args_is_help=False,
72
+ add_completion=False,
72
73
  )
73
74
  self._groups[group_name] = group_app
74
75
  self._group_commands[group_name] = []
@@ -57,7 +57,8 @@ def list_commands(app: typer.Typer, prefix_filter: str | None = None) -> None:
57
57
  prefix_filter: Optional prefix to filter commands by name.
58
58
  """
59
59
  project_name = get_project_name()
60
- print_title(title=project_name)
60
+ if not prefix_filter:
61
+ print_title(title=project_name)
61
62
 
62
63
  click_group = typer.main.get_command(app)
63
64
 
@@ -122,7 +123,6 @@ def list_commands(app: typer.Typer, prefix_filter: str | None = None) -> None:
122
123
  option_flags.append(flags)
123
124
 
124
125
  help_flags = "--help, -h"
125
- all_option_flags = [help_flags] + option_flags
126
126
  group_entries: list[CommandEntry] = []
127
127
  for group_name, group_help in groups.items():
128
128
  aliases = group_alias_registry.get(group_name, list[str]())
@@ -158,31 +158,73 @@ def list_commands(app: typer.Typer, prefix_filter: str | None = None) -> None:
158
158
  all_display_names = [cmd["display_name"] for cmd in commands] + [
159
159
  entry["display_name"] for entry in group_entries
160
160
  ]
161
- all_labels = all_display_names + all_option_flags
161
+ all_labels = all_display_names + [help_flags]
162
162
  longest_label_length = max((len(label) for label in all_labels), default=0)
163
163
 
164
- console.print(f"[bold {COLOR.SECONDARY}]Usage:[/bold {COLOR.SECONDARY}]")
165
- console.print(f" [{COLOR.PRIMARY}]{command_name} [OPTIONS] [ARGUMENTS]")
166
- console.print()
164
+ if prefix_filter:
165
+ command_name = get_script_command_name(default="usecli")
166
+ interactive_flags = "--interactive, -i"
167
+ filtered_labels = (
168
+ [cmd["display_name"] for cmd in commands]
169
+ + [entry["display_name"] for entry in group_entries]
170
+ + [help_flags, interactive_flags]
171
+ )
172
+ longest_label_length = max((len(label) for label in filtered_labels), default=0)
173
+ console.print()
174
+ console.print(f"[bold {COLOR.SECONDARY}]Usage:[/bold {COLOR.SECONDARY}]")
175
+ # Detect colon-separated commands (e.g., "make:command" matching prefix "make")
176
+ has_colon_commands = any(
177
+ ":" in cmd["name"] and cmd["name"].startswith(prefix_filter + ":")
178
+ for cmd in commands
179
+ )
180
+ if has_colon_commands:
181
+ # Colon-separated: use make:COMMAND [OPTIONS]
182
+ console.print(
183
+ f" [not bold {COLOR.PRIMARY}]{command_name} {prefix_filter}:COMMAND [OPTIONS][/]"
184
+ )
185
+ else:
186
+ # Space-separated nested groups: use make [COMMAND] [OPTIONS]
187
+ console.print(
188
+ f" [not bold {COLOR.PRIMARY}]{command_name} {prefix_filter} [COMMAND] [OPTIONS][/]"
189
+ )
190
+ console.print()
191
+ console.print(f"[bold {COLOR.SECONDARY}]Options:")
192
+ help_padding = " " * (longest_label_length - len(help_flags) + SPACER_LENGTH)
193
+ console.print(
194
+ f" [{COLOR.OPTION}]{help_flags}[/{COLOR.OPTION}]{help_padding}Show this message and exit."
195
+ )
196
+ interactive_padding = " " * (
197
+ longest_label_length - len(interactive_flags) + SPACER_LENGTH
198
+ )
199
+ console.print(
200
+ f" [{COLOR.OPTION}]{interactive_flags}[/{COLOR.OPTION}]{interactive_padding}Run in interactive mode."
201
+ )
202
+ console.print()
203
+ else:
204
+ console.print(f"[bold {COLOR.SECONDARY}]Usage:[/bold {COLOR.SECONDARY}]")
205
+ console.print(
206
+ f" [not bold {COLOR.PRIMARY}]{command_name} [OPTIONS] [ARGUMENTS][/]"
207
+ )
208
+ console.print()
167
209
 
168
- console.print(f"[bold {COLOR.SECONDARY}]Options:")
210
+ console.print(f"[bold {COLOR.SECONDARY}]Options:")
169
211
 
170
- help_padding = " " * (longest_label_length - len(help_flags) + SPACER_LENGTH)
171
- console.print(
172
- f" [{COLOR.OPTION}]{help_flags}[/{COLOR.OPTION}]{help_padding}Show this message and exit."
173
- )
212
+ help_padding = " " * (longest_label_length - len(help_flags) + SPACER_LENGTH)
213
+ console.print(
214
+ f" [{COLOR.OPTION}]{help_flags}[/{COLOR.OPTION}]{help_padding}Show this message and exit."
215
+ )
174
216
 
175
- if display_params:
176
- for param in display_params:
177
- flags = ", ".join(param.opts)
178
- if "--help" in flags:
179
- continue
180
- description = _get_option_description(param)
181
- padding = " " * (longest_label_length - len(flags) + SPACER_LENGTH)
182
- console.print(
183
- f" [{COLOR.OPTION}]{flags}[/{COLOR.OPTION}]{padding}{description}"
184
- )
185
- console.print()
217
+ if display_params:
218
+ for param in display_params:
219
+ flags = ", ".join(param.opts)
220
+ if "--help" in flags:
221
+ continue
222
+ description = _get_option_description(param)
223
+ padding = " " * (longest_label_length - len(flags) + SPACER_LENGTH)
224
+ console.print(
225
+ f" [{COLOR.OPTION}]{flags}[/{COLOR.OPTION}]{padding}{description}"
226
+ )
227
+ console.print()
186
228
 
187
229
  if not prefix_filter:
188
230
  console.print(f"[bold {COLOR.SECONDARY}]Available commands:")
@@ -241,7 +283,7 @@ def list_group_commands(group_app: typer.Typer, group_name: str) -> None:
241
283
 
242
284
  console.print(f"[bold {COLOR.SECONDARY}]Usage:[/bold {COLOR.SECONDARY}]")
243
285
  console.print(
244
- f" [{COLOR.PRIMARY}]{command_name} {group_name} [COMMAND] [OPTIONS][/]"
286
+ f" [not bold {COLOR.PRIMARY}]{command_name} {group_name} [COMMAND] [OPTIONS][/]"
245
287
  )
246
288
  console.print()
247
289
  commands_by_name: dict[str, CommandMeta] = {}
@@ -177,6 +177,13 @@ class CommandService:
177
177
  if spec and spec.loader:
178
178
  module = importlib.util.module_from_spec(spec)
179
179
  sys.modules[module_name] = module
180
+
181
+ from usecli.shared.config.manager import find_project_root
182
+
183
+ project_root = find_project_root(path.parent)
184
+ if project_root and str(project_root) not in sys.path:
185
+ sys.path.insert(0, str(project_root))
186
+
180
187
  spec.loader.exec_module(module)
181
188
  return module
182
189
  return None
File without changes
File without changes
File without changes
File without changes
File without changes