chore: import upstream snapshot with attribution
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
CI (OpenClaw E2E) / openclaw test (push) Has been cancelled
CI / coverage-report (push) Has been cancelled
CI / test-kubernetes (push) Has been cancelled
CI / should-run-thorough (push) Has been cancelled
CI / test-thorough (cloudwatch-demo) (push) Has been cancelled
CI / test-thorough (flink-ecs) (push) Has been cancelled
CI / test-thorough (upstream-lambda) (push) Has been cancelled
CI / test-thorough (prefect-ecs-fargate) (push) Has been cancelled
Release / build-binaries (zip, opensre.exe, onefile, windows-latest, windows-x64) (push) Has been cancelled
Benchmark image — build + push to ECR (any adapter) / build + push (push) Has been cancelled
CI / quality (ubuntu-latest) (push) Has been cancelled
CI / test (tools-runtime) (push) Has been cancelled
CI / test (e2e-general) (push) Has been cancelled
CI / test (cli-runtime) (push) Has been cancelled
CI / test (e2e-provider-and-openclaw) (push) Has been cancelled
CI / test (integrations-and-misc) (push) Has been cancelled
Release / verify (push) Has been cancelled
Release / build-python-dist (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-15-intel, darwin-x64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, macos-latest, darwin-arm64) (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04, linux-x64) (push) Has been cancelled
Release / publish-release (push) Has been cancelled
Release / publish-main-release (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-checks (no-LLM) (push) Has been cancelled
CodeQL / Analyze (python) (push) Has been cancelled
Interactive Shell Live (PR + post-merge) / turn-live shard ${{ matrix.shard_index }} (push) Has been cancelled
Release / prepare (push) Has been cancelled
Release / build-binaries (tar.gz, opensre, onedir, ubuntu-22.04-arm, linux-arm64) (push) Has been cancelled
Synthetic Deterministic Tests / Synthetic offline (deterministic) (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,198 @@
|
||||
"""Slash commands: /help and /?."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from collections.abc import Sequence
|
||||
|
||||
from rich.console import Console
|
||||
from rich.markup import escape
|
||||
|
||||
from surfaces.interactive_shell.command_registry.types import SlashCommand
|
||||
from surfaces.interactive_shell.runtime import Session
|
||||
from surfaces.interactive_shell.ui import ERROR
|
||||
from surfaces.interactive_shell.ui.components.choice_menu import repl_tty_interactive
|
||||
from surfaces.interactive_shell.ui.help.help_menu import (
|
||||
HelpSection,
|
||||
choose_help_command,
|
||||
render_command_detail,
|
||||
render_help_index,
|
||||
render_section_detail,
|
||||
)
|
||||
|
||||
QUICK_ACCESS_COMMANDS: list[str] = [
|
||||
"/investigate",
|
||||
"/integrations",
|
||||
"/model",
|
||||
"/health",
|
||||
"/watch",
|
||||
"/status",
|
||||
"/help",
|
||||
]
|
||||
|
||||
|
||||
def _quick_access_section() -> HelpSection:
|
||||
from surfaces.interactive_shell.command_registry import SLASH_COMMANDS
|
||||
|
||||
cmds = [SLASH_COMMANDS[n] for n in QUICK_ACCESS_COMMANDS if n in SLASH_COMMANDS]
|
||||
return ("Quick Access", cmds)
|
||||
|
||||
|
||||
def _raw_help_sections() -> list[HelpSection]:
|
||||
from surfaces.interactive_shell.command_registry.agents import COMMANDS as AGENTS_CMDS
|
||||
from surfaces.interactive_shell.command_registry.alerts import COMMANDS as ALERTS_CMDS
|
||||
from surfaces.interactive_shell.command_registry.background_cmds import (
|
||||
COMMANDS as BACKGROUND_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.cli_parity import (
|
||||
COMMANDS as PARITY_COMMANDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.diagnostics_cmds import (
|
||||
COMMANDS as DIAGNOSTICS_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.gateway_cmds import (
|
||||
COMMANDS as GATEWAY_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.integrations import COMMANDS as INT_CMDS
|
||||
from surfaces.interactive_shell.command_registry.investigation import COMMANDS as INV_CMDS
|
||||
from surfaces.interactive_shell.command_registry.model import COMMANDS as MODEL_CMDS
|
||||
from surfaces.interactive_shell.command_registry.privacy_cmds import (
|
||||
COMMANDS as PRIVACY_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.rca_cmds import COMMANDS as RCA_CMDS
|
||||
from surfaces.interactive_shell.command_registry.session_cmds import (
|
||||
COMMANDS as SESSION_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.settings_cmds import (
|
||||
COMMANDS as SETTINGS_CMDS,
|
||||
)
|
||||
from surfaces.interactive_shell.command_registry.system import COMMANDS as SYS_CMDS
|
||||
from surfaces.interactive_shell.command_registry.tasks_cmds import COMMANDS as TASK_CMDS
|
||||
from surfaces.interactive_shell.command_registry.theme import COMMANDS as THEME_CMDS
|
||||
from surfaces.interactive_shell.command_registry.tools_cmds import COMMANDS as TOOLS_CMDS
|
||||
from surfaces.interactive_shell.command_registry.watch_cmds import COMMANDS as WATCH_CMDS
|
||||
|
||||
return [
|
||||
_quick_access_section(),
|
||||
("Help", list(COMMANDS)),
|
||||
(
|
||||
"Session",
|
||||
list(SESSION_CMDS)
|
||||
+ list(BACKGROUND_CMDS)
|
||||
+ list(SETTINGS_CMDS)
|
||||
+ list(DIAGNOSTICS_CMDS),
|
||||
),
|
||||
("Integrations, Models & Tools", list(INT_CMDS) + list(MODEL_CMDS) + list(TOOLS_CMDS)),
|
||||
("Investigation", list(INV_CMDS) + list(RCA_CMDS)),
|
||||
("Privacy", list(PRIVACY_CMDS)),
|
||||
("Tasks", list(TASK_CMDS) + list(WATCH_CMDS) + list(GATEWAY_CMDS)),
|
||||
("Theme", list(THEME_CMDS)),
|
||||
("Agents", list(AGENTS_CMDS)),
|
||||
("Alerts", list(ALERTS_CMDS)),
|
||||
("CLI (parity)", list(PARITY_COMMANDS)),
|
||||
("System", list(SYS_CMDS)),
|
||||
]
|
||||
|
||||
|
||||
_QUICK_ACCESS_SECTION_NAME = "Quick Access"
|
||||
|
||||
|
||||
def _help_sections() -> list[HelpSection]:
|
||||
"""Return user-visible help sections with duplicate command names hidden.
|
||||
|
||||
The "Quick Access" section is intentionally exempted from the dedup set so
|
||||
its curated commands remain visible in their canonical sections too (e.g.
|
||||
``/help investigation`` still contains ``/investigate``).
|
||||
"""
|
||||
seen: set[str] = set()
|
||||
sections: list[HelpSection] = []
|
||||
for section_name, commands in _raw_help_sections():
|
||||
visible: list[SlashCommand] = []
|
||||
is_quick_access = section_name == _QUICK_ACCESS_SECTION_NAME
|
||||
for command in commands:
|
||||
if command.name in seen:
|
||||
continue
|
||||
visible.append(command)
|
||||
if not is_quick_access:
|
||||
seen.add(command.name)
|
||||
sections.append((section_name, visible))
|
||||
return sections
|
||||
|
||||
|
||||
def _find_command(sections: Sequence[HelpSection], target: str) -> SlashCommand | None:
|
||||
normalized = target.strip().lower()
|
||||
if not normalized:
|
||||
return None
|
||||
if not normalized.startswith("/"):
|
||||
normalized = f"/{normalized}"
|
||||
for _section_name, commands in sections:
|
||||
for command in commands:
|
||||
if command.name.lower() == normalized:
|
||||
return command
|
||||
return None
|
||||
|
||||
|
||||
def _find_section(
|
||||
sections: Sequence[HelpSection],
|
||||
target: str,
|
||||
) -> tuple[str, Sequence[SlashCommand]] | None:
|
||||
normalized = target.strip().lower().replace("-", " ")
|
||||
for section_name, commands in sections:
|
||||
aliases = {
|
||||
section_name.lower(),
|
||||
section_name.lower().replace("&", "and"),
|
||||
section_name.lower().replace(" & ", " "),
|
||||
}
|
||||
if normalized in aliases:
|
||||
return section_name, commands
|
||||
return None
|
||||
|
||||
|
||||
def _cmd_help(_session: Session, console: Console, args: list[str]) -> bool:
|
||||
sections = _help_sections()
|
||||
if args:
|
||||
target = " ".join(args).strip()
|
||||
if target.lower() in {"all", "commands"}:
|
||||
render_help_index(console, sections)
|
||||
return True
|
||||
if not target.startswith("/"):
|
||||
section = _find_section(sections, target)
|
||||
if section is not None:
|
||||
section_name, commands = section
|
||||
render_section_detail(console, section_name, commands)
|
||||
return True
|
||||
command = _find_command(sections, target)
|
||||
if command is not None:
|
||||
render_command_detail(console, command)
|
||||
return True
|
||||
console.print(f"[{ERROR}]unknown help topic:[/] {escape(target)}")
|
||||
console.print(
|
||||
"Try [bold]/help[/bold], [bold]/help /model[/bold], or [bold]/help tasks[/bold]."
|
||||
)
|
||||
return True
|
||||
|
||||
if repl_tty_interactive():
|
||||
selected = choose_help_command(sections)
|
||||
if selected:
|
||||
# Re-dispatch the selected slash command so Enter in the help picker
|
||||
# runs the command directly instead of only opening details.
|
||||
from surfaces.interactive_shell.command_registry import dispatch_slash
|
||||
|
||||
return dispatch_slash(selected, _session, console)
|
||||
return True
|
||||
|
||||
render_help_index(console, sections)
|
||||
return True
|
||||
|
||||
|
||||
COMMANDS: list[SlashCommand] = [
|
||||
SlashCommand(
|
||||
"/help",
|
||||
"Show available commands.",
|
||||
_cmd_help,
|
||||
usage=("/help", "/help <command>", "/help <category>"),
|
||||
examples=("/help /model", "/help tasks"),
|
||||
),
|
||||
SlashCommand("/?", "Shortcut for /help.", _cmd_help),
|
||||
]
|
||||
|
||||
__all__ = ["COMMANDS", "QUICK_ACCESS_COMMANDS"]
|
||||
Reference in New Issue
Block a user