Files
computer-playbook/cli/console/repl.py
T
kevinveenbirkenbachandClaude Opus 5 5137465c6f style: delete every comment the comments-valid policy rejects
3529 invalid comments in 528 files, grandfathered in while the linter
only saw the working-tree diff. Removal ran through the linter's own
collectors, so detection and deletion cannot drift: a comment whose
opener line is blank before it and whose closer line is blank after it
loses all its lines, anything else loses only the comment region, and a
line left holding a bare delimiter goes with it.

Five files keep their comments behind a nocheck marker instead. Four are
upstream configs whose inline docs are upstream's own (mautrix, systemd
journald, nextcloud-oidc-login, MediaWiki). In littlejs the
commented-out entries ARE the deactivation mechanism for an example
tile, so deleting them would delete configuration.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-18 03:22:02 +02:00

129 lines
3.1 KiB
Python

"""Interactive REPL that forwards each input line to ``python -m cli`` on the host.
Ctrl+C only cancels the current input; the console exits on ``exit``/``quit`` or EOF (Ctrl+D).
Ctrl+Shift+C is intercepted by the terminal emulator (copy shortcut) and never reaches the app.
The prompt tracks a category stack: typing a bare category name cd's into it,
``..`` walks one level up, ``/`` returns to root, path tokens with ``/`` or
``..`` navigate, ``infinito [path]`` jumps absolute, ``ls`` lists the current
folder, everything else runs with the current path prepended.
"""
from __future__ import annotations
import contextlib
import shlex
import sys
from .banner import print_banner as _print_banner
from .constants import (
AUTHOR,
AUTHOR_URL,
CLI_ROOT,
DOCS_URL,
EXIT_TOKENS,
HELP_ALIASES,
LICENSE_NAME,
LICENSE_URL,
LS_DESC_LIMIT,
LS_TOKEN,
PROMPT_PREFIX,
ROOT_NAV_TOKEN,
STRIPPABLE_PREFIXES,
WEB_URL,
)
from .ls import do_ls as _do_ls
from .navigation import (
is_category as _is_category,
)
from .navigation import (
is_navigation_token as _is_navigation_token,
)
from .navigation import (
normalize as _normalize,
)
from .navigation import (
prompt as _prompt,
)
from .navigation import (
resolve_argv as _resolve_argv,
)
from .navigation import (
resolve_cd as _resolve_cd,
)
from .runner import (
run_cli as _run_cli,
)
with contextlib.suppress(ImportError):
import readline # noqa: F401
__all__ = [
"AUTHOR",
"AUTHOR_URL",
"CLI_ROOT",
"DOCS_URL",
"EXIT_TOKENS",
"HELP_ALIASES",
"LICENSE_NAME",
"LICENSE_URL",
"LS_DESC_LIMIT",
"LS_TOKEN",
"PROMPT_PREFIX",
"ROOT_NAV_TOKEN",
"STRIPPABLE_PREFIXES",
"WEB_URL",
"main",
]
def main() -> int:
_print_banner()
current: list[str] = []
while True:
try:
line = input(_prompt(current))
except KeyboardInterrupt:
print()
continue
except EOFError:
print()
return 0
stripped = line.strip()
if not stripped:
continue
if stripped in EXIT_TOKENS:
return 0
try:
argv = shlex.split(stripped)
except ValueError as exc:
print(f"console: parse error: {exc}", file=sys.stderr)
continue
head = argv[0]
if head == LS_TOKEN and len(argv) == 1:
_do_ls(current)
continue
if head == ROOT_NAV_TOKEN:
target = "/" + "/".join(argv[1:]) if len(argv) > 1 else "/"
resolved = _resolve_cd(current, target)
if resolved is not None:
current = resolved
continue
if len(argv) == 1 and _is_navigation_token(head):
resolved = _resolve_cd(current, head)
if resolved is not None:
current = resolved
continue
if len(argv) == 1 and _is_category([*current, head]):
current.append(head)
continue
_run_cli(_resolve_argv(current, _normalize(argv)), current=current)
if __name__ == "__main__":
raise SystemExit(main())