pre-migration commit

This commit is contained in:
2026-04-26 15:08:35 -07:00
parent c724cb36b1
commit 39ee857559
32 changed files with 335 additions and 106 deletions
+107 -30
View File
@@ -506,28 +506,21 @@ class CmdletIntrospection:
if normalized_arg == "plugin":
canonical_cmd = (cmd_name or "").replace("_", "-").lower()
try:
from ProviderCore.registry import list_search_plugins, list_upload_plugins
from ProviderCore.registry import (
list_search_plugin_names,
list_upload_plugin_names,
)
except Exception:
list_search_plugins = None # type: ignore
list_upload_plugins = None # type: ignore
list_search_plugin_names = None # type: ignore
list_upload_plugin_names = None # type: ignore
provider_choices: List[str] = []
if canonical_cmd in {"add-file"} and list_upload_plugins is not None:
providers = list_upload_plugins(config) or {}
available = [
name for name, is_ready in providers.items() if is_ready
]
return sorted(available) if available else sorted(providers.keys())
if canonical_cmd in {"add-file"} and list_upload_plugin_names is not None:
return list_upload_plugin_names() or []
if list_search_plugins is not None:
providers = list_search_plugins(config) or {}
available = [
name for name, is_ready in providers.items() if is_ready
]
provider_choices = sorted(available) if available else sorted(
providers.keys()
)
if list_search_plugin_names is not None:
provider_choices = list_search_plugin_names() or []
if provider_choices:
return provider_choices
@@ -579,11 +572,90 @@ class CmdletIntrospection:
class CmdletCompleter(Completer):
"""Prompt-toolkit completer for the Medeia cmdlet REPL."""
_CMDLET_NAME_REFRESH_SECONDS = 2.0
def __init__(self, *, config_loader: "ConfigLoader") -> None:
self._config_loader = config_loader
self.cmdlet_names = CmdletIntrospection.cmdlet_names()
self._cmdlet_names_refreshed_at = time.monotonic()
self._cmdlet_args_cache: Dict[Tuple[str, int], List[str]] = {}
self._query_args_cache: Dict[Tuple[str, int], List[Dict[str, Any]]] = {}
self._arg_choices_cache: Dict[Tuple[str, str, int], List[str]] = {}
self._inline_query_choices_cache: Dict[Tuple[str, str, int], List[str]] = {}
def _refresh_cmdlet_names(self) -> None:
now = time.monotonic()
if self.cmdlet_names and (now - self._cmdlet_names_refreshed_at) < self._CMDLET_NAME_REFRESH_SECONDS:
return
self.cmdlet_names = CmdletIntrospection.cmdlet_names(force=False)
self._cmdlet_names_refreshed_at = now
@staticmethod
def _config_cache_key(config: Dict[str, Any]) -> int:
return id(config) if isinstance(config, dict) else 0
def _cmdlet_args(self, cmd_name: str, config: Dict[str, Any]) -> List[str]:
key = (str(cmd_name or "").lower(), self._config_cache_key(config))
cached = self._cmdlet_args_cache.get(key)
if cached is not None:
return cached
value = CmdletIntrospection.cmdlet_args(cmd_name, config)
self._cmdlet_args_cache[key] = value
return value
def _query_args(self, cmd_name: str, config: Dict[str, Any]) -> List[Dict[str, Any]]:
key = (str(cmd_name or "").lower(), self._config_cache_key(config))
cached = self._query_args_cache.get(key)
if cached is not None:
return cached
value = CmdletIntrospection.query_args(cmd_name, config)
self._query_args_cache[key] = value
return value
def _arg_choices(
self,
*,
cmd_name: str,
arg_name: str,
config: Dict[str, Any],
force: bool = False,
) -> List[str]:
key = (
str(cmd_name or "").lower(),
str(arg_name or "").lower(),
self._config_cache_key(config),
)
if not force:
cached = self._arg_choices_cache.get(key)
if cached is not None:
return cached
value = CmdletIntrospection.arg_choices(
cmd_name=cmd_name,
arg_name=arg_name,
config=config,
force=force,
)
self._arg_choices_cache[key] = value
return value
def _inline_query_choices(
self,
provider_name: str,
field_name: str,
config: Dict[str, Any],
) -> List[str]:
key = (
str(provider_name or "").lower(),
str(field_name or "").lower(),
self._config_cache_key(config),
)
cached = self._inline_query_choices_cache.get(key)
if cached is not None:
return cached
value = plugin_inline_query_choices(provider_name, field_name, config)
self._inline_query_choices_cache[key] = value
return value
def _used_arg_logicals(
cmd_name: str,
stage_tokens: List[str],
@@ -595,7 +667,7 @@ class CmdletCompleter(Completer):
Example: if the user has typed `download-file -url ...`, then `url`
is considered used and should not be suggested again (even as `--url`).
"""
arg_flags = CmdletIntrospection.cmdlet_args(cmd_name, config)
arg_flags = self._cmdlet_args(cmd_name, config)
allowed = {a.lstrip("-").strip().lower()
for a in arg_flags if a}
if not allowed:
@@ -636,8 +708,7 @@ class CmdletCompleter(Completer):
document: Document,
complete_event
): # type: ignore[override]
# Refresh cmdlet names from introspection to pick up dynamic updates
self.cmdlet_names = CmdletIntrospection.cmdlet_names(force=True)
self._refresh_cmdlet_names()
text = document.text_before_cursor
tokens = text.split()
@@ -660,7 +731,7 @@ class CmdletCompleter(Completer):
if ends_with_space:
cmd_name = current.replace("_", "-")
config = self._config_loader.load()
config = self._config_loader.load_shared()
if cmd_name == "help":
for cmd in self.cmdlet_names:
@@ -670,7 +741,7 @@ class CmdletCompleter(Completer):
if cmd_name not in self.cmdlet_names:
return
arg_names = CmdletIntrospection.cmdlet_args(cmd_name, config)
arg_names = self._cmdlet_args(cmd_name, config)
seen_logicals: Set[str] = set()
for arg in arg_names:
arg_low = arg.lower()
@@ -701,13 +772,13 @@ class CmdletCompleter(Completer):
current_token = stage_tokens[-1].lower()
prev_token = stage_tokens[-2].lower() if len(stage_tokens) > 1 else ""
config = self._config_loader.load()
config = self._config_loader.load_shared()
provider_name = None
if cmd_name == "search-file":
provider_name = self._flag_value(stage_tokens, "-plugin", "--plugin")
query_specs = CmdletIntrospection.query_args(cmd_name, config)
query_specs = self._query_args(cmd_name, config)
query_flag_index = -1
for idx, tok in enumerate(stage_tokens):
if str(tok or "").strip().lower() in {"-query", "--query"}:
@@ -754,7 +825,7 @@ class CmdletCompleter(Completer):
inline_choices = []
if cmd_name == "search-file" and provider_name:
inline_choices = plugin_inline_query_choices(provider_name, field, config)
inline_choices = self._inline_query_choices(provider_name, field, config)
choice_pool = inline_choices or field_choices.get(field, [])
if choice_pool:
@@ -800,7 +871,7 @@ class CmdletCompleter(Completer):
field, partial = inline_token.split(":", 1)
field = field.strip().lower()
partial_lower = partial.strip().lower()
inline_choices = plugin_inline_query_choices(provider_name, field, config)
inline_choices = self._inline_query_choices(provider_name, field, config)
if inline_choices:
filtered = (
[c for c in inline_choices if partial_lower in str(c).lower()]
@@ -814,11 +885,11 @@ class CmdletCompleter(Completer):
yield Completion(suggestion, start_position=start_pos)
return
choices = CmdletIntrospection.arg_choices(
choices = self._arg_choices(
cmd_name=cmd_name,
arg_name=prev_token,
config=config,
force=True
force=False,
)
if choices:
choice_list = choices
@@ -835,7 +906,7 @@ class CmdletCompleter(Completer):
# is considered used and should not be suggested again (even as `--url`).
return
arg_names = CmdletIntrospection.cmdlet_args(cmd_name, config)
arg_names = self._cmdlet_args(cmd_name, config)
used_logicals = self._used_arg_logicals(cmd_name, stage_tokens, config)
logical_seen: Set[str] = set()
for arg in arg_names:
@@ -869,9 +940,15 @@ class ConfigLoader:
def __init__(self, *, root: Path) -> None:
self._root = root
def load_shared(self) -> Dict[str, Any]:
try:
return load_config(emit_summary=False)
except Exception:
return {}
def load(self) -> Dict[str, Any]:
try:
return deepcopy(load_config())
return deepcopy(self.load_shared())
except Exception:
return {}