cmdlet refactor

This commit is contained in:
2026-05-04 18:41:01 -07:00
parent 3ce339b3c1
commit 24f983473f
44 changed files with 1320 additions and 309 deletions
+98 -29
View File
@@ -725,8 +725,29 @@ class CmdletCompleter(Completer):
return None
@staticmethod
def _selected_plugin_name(cmd_name: str, stage_tokens: Sequence[str]) -> Optional[str]:
def _effective_cmd_name(cmd_name: str, stage_tokens: Sequence[str]) -> str:
canonical_cmd = str(cmd_name or "").replace("_", "-").strip().lower()
if canonical_cmd != "file":
return canonical_cmd
lowered = {str(tok or "").strip().lower() for tok in (stage_tokens or [])}
if "-search" in lowered or "--search" in lowered:
return "search-file"
if "-download" in lowered or "--download" in lowered or "-dl" in lowered or "--dl" in lowered:
return "download-file"
if "-add" in lowered or "--add" in lowered:
return "add-file"
if "-get" in lowered or "--get" in lowered:
return "get-file"
if "-delete" in lowered or "--delete" in lowered or "-del" in lowered or "--del" in lowered:
return "delete-file"
if "-merge" in lowered or "--merge" in lowered:
return "merge-file"
return canonical_cmd
@staticmethod
def _selected_plugin_name(cmd_name: str, stage_tokens: Sequence[str]) -> Optional[str]:
canonical_cmd = CmdletCompleter._effective_cmd_name(cmd_name, stage_tokens)
if canonical_cmd not in {"search-file", "add-file", "download-file"}:
return None
return CmdletCompleter._flag_value(stage_tokens, "-plugin", "--plugin")
@@ -778,7 +799,7 @@ class CmdletCompleter(Completer):
if not arg_names:
return []
canonical_cmd = str(cmd_name or "").replace("_", "-").strip().lower()
canonical_cmd = self._effective_cmd_name(cmd_name, stage_tokens)
plugin_name = self._selected_plugin_name(canonical_cmd, stage_tokens)
instance_choices = self._plugin_instance_choices(plugin_name, config)
has_named_instances = bool(instance_choices)
@@ -862,6 +883,7 @@ class CmdletCompleter(Completer):
return
cmd_name = stage_tokens[0].replace("_", "-").lower()
effective_cmd = self._effective_cmd_name(cmd_name, stage_tokens)
if ends_with_space:
current_token = ""
prev_token = stage_tokens[-1].lower()
@@ -872,12 +894,12 @@ class CmdletCompleter(Completer):
config = self._config_loader.load_shared()
provider_name = None
if cmd_name == "search-file":
if effective_cmd == "search-file":
provider_name = self._flag_value(stage_tokens, "-plugin", "--plugin")
selected_plugin = self._selected_plugin_name(cmd_name, stage_tokens)
selected_plugin = self._selected_plugin_name(effective_cmd, stage_tokens)
query_specs = self._query_args(cmd_name, config)
query_specs = self._query_args(effective_cmd, config)
query_flag_index = -1
for idx, tok in enumerate(stage_tokens):
if str(tok or "").strip().lower() in {"-query", "--query"}:
@@ -923,7 +945,7 @@ class CmdletCompleter(Completer):
partial_lower = partial.strip().lower()
inline_choices = []
if cmd_name == "search-file" and provider_name:
if effective_cmd == "search-file" and provider_name:
inline_choices = self._inline_query_choices(provider_name, field, config)
choice_pool = inline_choices or field_choices.get(field, [])
@@ -948,7 +970,7 @@ class CmdletCompleter(Completer):
return
if (
cmd_name == "search-file"
effective_cmd == "search-file"
and provider_name
and not ends_with_space
and ":" in current_token
@@ -990,7 +1012,7 @@ class CmdletCompleter(Completer):
choices = self._plugin_instance_choices(selected_plugin, config)
if not choices:
choices = self._arg_choices(
cmd_name=cmd_name,
cmd_name=effective_cmd,
arg_name=prev_token,
config=config,
force=False,
@@ -1016,12 +1038,12 @@ class CmdletCompleter(Completer):
return
arg_names = self._filter_stage_arg_names(
cmd_name=cmd_name,
cmd_name=effective_cmd,
stage_tokens=stage_tokens,
config=config,
arg_names=self._cmdlet_args(cmd_name, config),
arg_names=self._cmdlet_args(effective_cmd, config),
)
used_logicals = self._used_arg_logicals(cmd_name, stage_tokens, config)
used_logicals = self._used_arg_logicals(effective_cmd, stage_tokens, config)
logical_seen: Set[str] = set()
for arg in arg_names:
arg_low = arg.lower()
@@ -1228,6 +1250,26 @@ class CmdletExecutor:
emitted_items: Optional[List[Any]] = None,
cmd_args: Optional[List[str]] = None,
) -> str:
def _file_action(args: Optional[List[str]]) -> str | None:
tokens = [str(t or "").strip().lower() for t in (args or [])]
token_set = set(tokens)
if "-search" in token_set or "--search" in token_set:
return "search-file"
if "-download" in token_set or "--download" in token_set or "-dl" in token_set or "--dl" in token_set:
return "download-file"
if "-get" in token_set or "--get" in token_set:
return "get-file"
if "-add" in token_set or "--add" in token_set:
return "add-file"
if "-delete" in token_set or "--delete" in token_set or "-del" in token_set or "--del" in token_set:
return "delete-file"
if "-merge" in token_set or "--merge" in token_set:
return "merge-file"
return None
normalized_cmd = str(cmd_name or "").replace("_", "-").lower().strip()
mapped_cmd = _file_action(cmd_args) if normalized_cmd == "file" else normalized_cmd
title_map = {
"search-file": "Results",
"search_file": "Results",
@@ -1235,14 +1277,9 @@ class CmdletExecutor:
"download_data": "Downloads",
"download-file": "Downloads",
"download_file": "Downloads",
"get-tag": "Tags",
"get_tag": "Tags",
"metadata": "Tags",
"get-file": "Results",
"get_file": "Results",
"add-tags": "Results",
"add_tags": "Results",
"delete-tag": "Results",
"delete_tag": "Results",
"add-url": "Results",
"add_url": "Results",
"get-url": "url",
@@ -1266,7 +1303,7 @@ class CmdletExecutor:
"get-metadata": None,
"get_metadata": None,
}
mapped = title_map.get(cmd_name, "Results")
mapped = title_map.get(mapped_cmd or normalized_cmd, "Results")
if mapped is not None:
return mapped
@@ -1358,10 +1395,25 @@ class CmdletExecutor:
) -> None:
nonlocal progress_ui, pipe_idx
def _effective_file_cmd(name: str, args: List[str]) -> str:
norm = str(name or "").replace("_", "-").strip().lower()
if norm != "file":
return norm
lowered = {str(a or "").strip().lower() for a in (args or [])}
if "-add" in lowered or "--add" in lowered:
return "add-file"
if "-delete" in lowered or "--delete" in lowered or "-del" in lowered or "--del" in lowered:
return "delete-file"
if "-download" in lowered or "--download" in lowered or "-dl" in lowered or "--dl" in lowered:
return "download-file"
return norm
effective_cmd = _effective_file_cmd(cmd_name_norm, filtered_args)
# Keep behavior consistent with pipeline runner exclusions.
# Some commands render their own Rich UI (tables/panels) and don't
# play nicely with Live cursor control.
if cmd_name_norm in {
if effective_cmd in {
"get-relationship",
"get-rel",
".pipe",
@@ -1375,8 +1427,7 @@ class CmdletExecutor:
return
# add-file directory selector mode: show only the selection table, no Live progress.
if cmd_name_norm in {"add-file",
"add_file"}:
if effective_cmd in {"add-file", "add_file"}:
try:
from pathlib import Path as _Path
@@ -1457,8 +1508,7 @@ class CmdletExecutor:
while i < len(toks):
t = str(toks[i])
low = t.lower().strip()
if (cmd_name_norm in {"add-file",
"add_file"} and low in {"-path",
if (effective_cmd in {"add-file", "add_file"} and low in {"-path",
"--path",
"-p"}
and i + 1 < len(toks)):
@@ -1706,6 +1756,25 @@ class CmdletExecutor:
filtered_args
)
def _effective_cmd_name(name: str, args: List[str]) -> str:
norm = str(name or "").replace("_", "-").strip().lower()
if norm != "file":
return norm
lowered = {str(a or "").strip().lower() for a in (args or [])}
if "-search" in lowered or "--search" in lowered:
return "search-file"
if "-download" in lowered or "--download" in lowered or "-dl" in lowered or "--dl" in lowered:
return "download-file"
if "-get" in lowered or "--get" in lowered:
return "get-file"
if "-add" in lowered or "--add" in lowered:
return "add-file"
if "-delete" in lowered or "--delete" in lowered or "-del" in lowered or "--del" in lowered:
return "delete-file"
return norm
effective_cmd = _effective_cmd_name(cmd_name, filtered_args)
selectable_commands = {
"search-file",
"download-data",
@@ -1729,8 +1798,7 @@ class CmdletExecutor:
"get_metadata",
}
self_managing_commands = {
"get-tag",
"get_tag",
"tag",
"tags",
"get-metadata",
"get_metadata",
@@ -1740,9 +1808,10 @@ class CmdletExecutor:
"search_file",
"add-file",
"add_file",
"file",
}
if cmd_name in self_managing_commands:
if effective_cmd in self_managing_commands or cmd_name in self_managing_commands:
table = (
ctx.get_display_table()
if hasattr(ctx, "get_display_table") else None
@@ -1758,11 +1827,11 @@ class CmdletExecutor:
for emitted in emits:
table.add_result(emitted)
if cmd_name in selectable_commands:
table.set_source_command(cmd_name, filtered_args)
if effective_cmd in selectable_commands:
table.set_source_command(effective_cmd, filtered_args)
ctx.set_last_result_table(table, emits)
ctx.set_current_stage_table(None)
elif cmd_name in display_only_commands:
elif effective_cmd in display_only_commands or cmd_name in display_only_commands:
ctx.set_last_result_items_only(emits)
else:
ctx.set_last_result_items_only(emits)