added repl injection

This commit is contained in:
2026-03-18 20:17:28 -07:00
parent 7c526784a8
commit 5cbc2c09df
7 changed files with 896 additions and 184 deletions

View File

@@ -1778,6 +1778,9 @@ class PipelineExecutor:
return [str(x) for x in candidate if x is not None]
return None
def _norm_cmd_name(value: Any) -> str:
return str(value or "").replace("_", "-").strip().lower()
# ============================================================================
# PHASE 2: Parse source command and table metadata
# ============================================================================
@@ -1841,11 +1844,23 @@ class PipelineExecutor:
else:
selected_row_args: List[str] = []
skip_pipe_expansion = source_cmd in {".pipe", ".mpv"} and len(stages) > 0
prefer_row_action = False
if len(selection_indices) == 1 and not stages:
try:
row_action = _get_row_action(selection_indices[0])
except Exception:
row_action = None
if row_action:
prefer_row_action = True
debug(
"@N: skipping source command expansion because row has explicit selection_action "
f"{row_action}"
)
# Command expansion via @N:
# - Default behavior: expand ONLY for single-row selections.
# - Special case: allow multi-row expansion for add-file directory tables by
# combining selected rows into a single `-path file1,file2,...` argument.
if source_cmd and not skip_pipe_expansion:
if source_cmd and not skip_pipe_expansion and not prefer_row_action:
src = str(source_cmd).replace("_", "-").strip().lower()
if src == "add-file" and selection_indices:
@@ -2119,7 +2134,7 @@ class PipelineExecutor:
source_args_for_selection = []
if not stages and selection_indices and source_cmd_for_selection:
src_norm = _norm_cmd(source_cmd_for_selection)
src_norm = _norm_cmd_name(source_cmd_for_selection)
if src_norm in {".worker", "worker", "workers"}:
if len(selection_indices) == 1:
idx = selection_indices[0]
@@ -2197,7 +2212,7 @@ class PipelineExecutor:
logger.exception("Failed to record pipeline log step for applied row action (pipeline_session=%r)", getattr(pipeline_session, 'worker_id', None))
else:
first_cmd = stages[0][0] if stages and stages[0] else None
first_cmd_norm = _norm_cmd(first_cmd)
first_cmd_norm = _norm_cmd_name(first_cmd)
inserted_provider_download = False
if first_cmd_norm == "add-file":
@@ -2205,7 +2220,7 @@ class PipelineExecutor:
# run download before add-file so add-file receives local files.
if len(selection_indices) == 1:
row_action = _get_row_action(selection_indices[0], items_list)
if row_action and _norm_cmd(row_action[0]) == "download-file":
if row_action and _norm_cmd_name(row_action[0]) == "download-file":
stages.insert(0, [str(x) for x in row_action if x is not None])
inserted_provider_download = True
debug("Auto-inserting row download-file action before add-file")
@@ -2218,7 +2233,7 @@ class PipelineExecutor:
has_download_row_action = False
for idx in selection_indices:
row_action = _get_row_action(idx, items_list)
if row_action and _norm_cmd(row_action[0]) == "download-file":
if row_action and _norm_cmd_name(row_action[0]) == "download-file":
has_download_row_action = True
break
if has_download_row_action:
@@ -2237,8 +2252,8 @@ class PipelineExecutor:
print("Auto-inserting get-tag after metadata selection")
stages.insert(0, ["get-tag"])
elif auto_stage:
first_cmd_norm = _norm_cmd(stages[0][0] if stages and stages[0] else None)
auto_cmd_norm = _norm_cmd(auto_stage[0])
first_cmd_norm = _norm_cmd_name(stages[0][0] if stages and stages[0] else None)
auto_cmd_norm = _norm_cmd_name(auto_stage[0])
if first_cmd_norm not in (auto_cmd_norm, ".pipe", ".mpv"):
debug(f"Auto-inserting {auto_cmd_norm} after selection")
# Insert the auto stage before the user-specified stage

64
SYS/repl_queue.py Normal file
View File

@@ -0,0 +1,64 @@
from __future__ import annotations
import json
import time
import uuid
from pathlib import Path
from typing import Any, Dict, List, Optional
def repl_queue_dir(root: Path) -> Path:
return Path(root) / "Log" / "repl_queue"
def enqueue_repl_command(
root: Path,
command: str,
*,
source: str = "external",
metadata: Optional[Dict[str, Any]] = None,
) -> Path:
queue_dir = repl_queue_dir(root)
queue_dir.mkdir(parents=True, exist_ok=True)
payload: Dict[str, Any] = {
"id": uuid.uuid4().hex,
"command": str(command or "").strip(),
"source": str(source or "external").strip() or "external",
"created_at": time.time(),
}
if isinstance(metadata, dict) and metadata:
payload["metadata"] = metadata
stamp = int(time.time() * 1000)
token = payload["id"][:8]
final_path = queue_dir / f"{stamp:013d}-{token}.json"
temp_path = final_path.with_suffix(".tmp")
temp_path.write_text(json.dumps(payload, ensure_ascii=False), encoding="utf-8")
temp_path.replace(final_path)
return final_path
def pop_repl_commands(root: Path, *, limit: int = 8) -> List[Dict[str, Any]]:
queue_dir = repl_queue_dir(root)
if not queue_dir.exists():
return []
items: List[Dict[str, Any]] = []
for entry in sorted(queue_dir.glob("*.json"))[: max(1, int(limit or 1))]:
try:
payload = json.loads(entry.read_text(encoding="utf-8"))
except Exception:
payload = {
"id": entry.stem,
"command": "",
"source": "invalid",
"created_at": entry.stat().st_mtime,
}
try:
entry.unlink()
except Exception:
continue
if isinstance(payload, dict):
items.append(payload)
return items