This commit is contained in:
nose
2025-12-12 21:55:38 -08:00
parent e2ffcab030
commit 85750247cc
78 changed files with 5726 additions and 6239 deletions

76
CLI.py
View File

@@ -68,7 +68,7 @@ from typing import Callable
from config import get_local_storage_path, load_config
from cmdlets.catalog import (
from cmdlet.catalog import (
import_cmd_module as _catalog_import_cmd_module,
list_cmdlet_metadata as _catalog_list_cmdlet_metadata,
list_cmdlet_names as _catalog_list_cmdlet_names,
@@ -482,7 +482,7 @@ def _get_cmdlet_names() -> List[str]:
def _import_cmd_module(mod_name: str):
"""Import a cmdlet/native module from cmdlets or cmdnats packages."""
"""Import a cmdlet/native module from cmdlet or cmdnat packages."""
try:
return _catalog_import_cmd_module(mod_name)
except Exception:
@@ -518,7 +518,7 @@ def _get_arg_choices(cmd_name: str, arg_name: str) -> List[str]:
# Dynamic search providers
if normalized_arg == "provider":
try:
from Provider.registry import list_search_providers
from ProviderCore.registry import list_search_providers
providers = list_search_providers(_load_cli_config())
available = [name for name, is_ready in providers.items() if is_ready]
provider_choices = sorted(available) if available else sorted(providers.keys())
@@ -607,9 +607,23 @@ if (
return
arg_names = _get_cmdlet_args(cmd_name)
logical_seen: Set[str] = set()
for arg in arg_names:
if arg.lower().startswith(current_token):
arg_low = arg.lower()
# If the user has only typed '-', prefer single-dash flags (e.g. -url)
# and avoid suggesting both -name and --name for the same logical arg.
if current_token == "-" and arg_low.startswith("--"):
continue
logical = arg.lstrip("-").lower()
if current_token == "-" and logical in logical_seen:
continue
if arg_low.startswith(current_token):
yield CompletionType(arg, start_position=-len(current_token))
if current_token == "-":
logical_seen.add(logical)
if "--help".startswith(current_token):
yield CompletionType("--help", start_position=-len(current_token))
@@ -715,10 +729,21 @@ def _create_cmdlet_cli():
print(f"Error parsing seeds JSON: {e}")
return
try:
from cli_syntax import validate_pipeline_text
syntax_error = validate_pipeline_text(command)
if syntax_error:
print(syntax_error.message, file=sys.stderr)
return
except Exception:
# Best-effort only; if validator can't load, fall back to shlex handling below.
pass
try:
tokens = shlex.split(command)
except ValueError:
tokens = command.split()
except ValueError as exc:
print(f"Syntax error: {exc}", file=sys.stderr)
return
if not tokens:
return
@@ -728,7 +753,7 @@ def _create_cmdlet_cli():
@app.command("repl")
def repl():
"""Start interactive REPL for cmdlets with autocomplete."""
"""Start interactive REPL for cmdlet with autocomplete."""
banner = """
Medeia-Macina
=====================
@@ -967,11 +992,22 @@ def _create_cmdlet_cli():
except Exception:
pipeline_ctx_ref = None
try:
from cli_syntax import validate_pipeline_text
syntax_error = validate_pipeline_text(user_input)
if syntax_error:
print(syntax_error.message, file=sys.stderr)
continue
except Exception:
# Best-effort only; if validator can't load, continue with shlex.
pass
try:
import shlex
tokens = shlex.split(user_input)
except ValueError:
tokens = user_input.split()
except ValueError as exc:
print(f"Syntax error: {exc}", file=sys.stderr)
continue
if not tokens:
continue
@@ -1078,12 +1114,12 @@ def _create_cmdlet_cli():
def _execute_pipeline(tokens: list):
"""Execute a pipeline of cmdlets separated by pipes (|).
"""Execute a pipeline of cmdlet separated by pipes (|).
Example: cmd1 arg1 arg2 | cmd2 arg2 | cmd3 arg3
"""
try:
from cmdlets import REGISTRY
from cmdlet import REGISTRY
import json
import pipeline as ctx
@@ -1333,7 +1369,7 @@ def _execute_pipeline(tokens: list):
filtered = [resolved_items[i] for i in first_stage_selection_indices if 0 <= i < len(resolved_items)]
if filtered:
# Convert filtered items to PipeObjects for consistent pipeline handling
from cmdlets._shared import coerce_to_pipe_object
from cmdlet._shared import coerce_to_pipe_object
filtered_pipe_objs = [coerce_to_pipe_object(item) for item in filtered]
piped_result = filtered_pipe_objs if len(filtered_pipe_objs) > 1 else filtered_pipe_objs[0]
# Build log message with proper string conversion
@@ -1529,7 +1565,7 @@ def _execute_pipeline(tokens: list):
filtered = [resolved_list[i] for i in selection_indices if 0 <= i < len(resolved_list)]
if filtered:
# Convert filtered items to PipeObjects for consistent pipeline handling
from cmdlets._shared import coerce_to_pipe_object
from cmdlet._shared import coerce_to_pipe_object
filtered_pipe_objs = [coerce_to_pipe_object(item) for item in filtered]
piped_result = filtered_pipe_objs if len(filtered_pipe_objs) > 1 else filtered_pipe_objs[0]
print(f"Selected {len(filtered)} item(s) using {cmd_name}")
@@ -1817,13 +1853,13 @@ def _execute_cmdlet(cmd_name: str, args: list):
- @{1,3,5} - select rows 1, 3, 5
"""
try:
from cmdlets import REGISTRY
from cmdlet import REGISTRY
import json
import pipeline as ctx
# Ensure native commands (cmdnats) are loaded
# Ensure native commands (cmdnat) are loaded
try:
from cmdlets.catalog import ensure_registry_loaded as _ensure_registry_loaded
from cmdlet.catalog import ensure_registry_loaded as _ensure_registry_loaded
_ensure_registry_loaded()
except Exception:
pass
@@ -1832,7 +1868,7 @@ def _execute_cmdlet(cmd_name: str, args: list):
cmd_fn = REGISTRY.get(cmd_name)
if not cmd_fn:
# Attempt lazy import of the module and retry
from cmdlets.catalog import import_cmd_module as _catalog_import
from cmdlet.catalog import import_cmd_module as _catalog_import
try:
mod = _catalog_import(cmd_name)
data = getattr(mod, "CMDLET", None) if mod else None
@@ -1893,7 +1929,7 @@ def _execute_cmdlet(cmd_name: str, args: list):
# Filter to selected indices only
result = [piped_items[idx] for idx in selected_indices if 0 <= idx < len(piped_items)]
else:
# No selection specified, pass all items (cmdlets handle lists via normalize_result_input)
# No selection specified, pass all items (cmdlet handle lists via normalize_result_input)
result = piped_items
worker_manager = _ensure_worker_manager(config)
@@ -2038,10 +2074,10 @@ def _execute_cmdlet(cmd_name: str, args: list):
def _show_cmdlet_list():
"""Display available cmdlets with full metadata: cmd:name alias:aliases args:args."""
"""Display available cmdlet with full metadata: cmd:name alias:aliases args:args."""
try:
metadata = _catalog_list_cmdlet_metadata()
print("\nAvailable cmdlets:")
print("\nAvailable cmdlet:")
for cmd_name in sorted(metadata.keys()):
info = metadata[cmd_name]
aliases = info.get("aliases", [])