commands.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. from __future__ import annotations
  2. import json
  3. from dataclasses import dataclass
  4. from functools import lru_cache
  5. from pathlib import Path
  6. from .models import PortingBacklog, PortingModule
  7. SNAPSHOT_PATH = Path(__file__).resolve().parent / 'reference_data' / 'commands_snapshot.json'
  8. @dataclass(frozen=True)
  9. class CommandExecution:
  10. name: str
  11. source_hint: str
  12. prompt: str
  13. handled: bool
  14. message: str
  15. @lru_cache(maxsize=1)
  16. def load_command_snapshot() -> tuple[PortingModule, ...]:
  17. raw_entries = json.loads(SNAPSHOT_PATH.read_text())
  18. return tuple(
  19. PortingModule(
  20. name=entry['name'],
  21. responsibility=entry['responsibility'],
  22. source_hint=entry['source_hint'],
  23. status='mirrored',
  24. )
  25. for entry in raw_entries
  26. )
  27. PORTED_COMMANDS = load_command_snapshot()
  28. @lru_cache(maxsize=1)
  29. def built_in_command_names() -> frozenset[str]:
  30. return frozenset(module.name for module in PORTED_COMMANDS)
  31. def build_command_backlog() -> PortingBacklog:
  32. return PortingBacklog(title='Command surface', modules=list(PORTED_COMMANDS))
  33. def command_names() -> list[str]:
  34. return [module.name for module in PORTED_COMMANDS]
  35. def get_command(name: str) -> PortingModule | None:
  36. needle = name.lower()
  37. for module in PORTED_COMMANDS:
  38. if module.name.lower() == needle:
  39. return module
  40. return None
  41. def get_commands(cwd: str | None = None, include_plugin_commands: bool = True, include_skill_commands: bool = True) -> tuple[PortingModule, ...]:
  42. commands = list(PORTED_COMMANDS)
  43. if not include_plugin_commands:
  44. commands = [module for module in commands if 'plugin' not in module.source_hint.lower()]
  45. if not include_skill_commands:
  46. commands = [module for module in commands if 'skills' not in module.source_hint.lower()]
  47. return tuple(commands)
  48. def find_commands(query: str, limit: int = 20) -> list[PortingModule]:
  49. needle = query.lower()
  50. matches = [module for module in PORTED_COMMANDS if needle in module.name.lower() or needle in module.source_hint.lower()]
  51. return matches[:limit]
  52. def execute_command(name: str, prompt: str = '') -> CommandExecution:
  53. module = get_command(name)
  54. if module is None:
  55. return CommandExecution(name=name, source_hint='', prompt=prompt, handled=False, message=f'Unknown mirrored command: {name}')
  56. action = f"Mirrored command '{module.name}' from {module.source_hint} would handle prompt {prompt!r}."
  57. return CommandExecution(name=module.name, source_hint=module.source_hint, prompt=prompt, handled=True, message=action)
  58. def render_command_index(limit: int = 20, query: str | None = None) -> str:
  59. modules = find_commands(query, limit) if query else list(PORTED_COMMANDS[:limit])
  60. lines = [f'Command entries: {len(PORTED_COMMANDS)}', '']
  61. if query:
  62. lines.append(f'Filtered by: {query}')
  63. lines.append('')
  64. lines.extend(f'- {module.name} — {module.source_hint}' for module in modules)
  65. return '\n'.join(lines)