Dispatch ``/deck new [--critique] " "``. Mirrors :func:`_handle_slash_skill`: validates the name, runs the same wiki preflight gate, refuses to overwrite an existing deck (chat has no ``-y`` flag), then invokes ``Generator(target_type="deck")``.
(arg: str, kb_dir: Path, style: Style)
| 610 | |
| 611 | |
| 612 | async def _handle_slash_deck(arg: str, kb_dir: Path, style: Style) -> None: |
| 613 | """Dispatch ``/deck new [--critique] <name> "<intent>"``. |
| 614 | |
| 615 | Mirrors :func:`_handle_slash_skill`: validates the name, runs the |
| 616 | same wiki preflight gate, refuses to overwrite an existing deck |
| 617 | (chat has no ``-y`` flag), then invokes ``Generator(target_type="deck")``. |
| 618 | """ |
| 619 | import shlex |
| 620 | |
| 621 | try: |
| 622 | parts = shlex.split(arg) if arg else [] |
| 623 | except ValueError as exc: |
| 624 | _fmt(style, ("class:error", f"[ERROR] Could not parse: {exc}\n")) |
| 625 | return |
| 626 | if not parts: |
| 627 | _fmt(style, ("class:error", 'Usage: /deck new [--critique] <name> "<intent>"\n')) |
| 628 | return |
| 629 | |
| 630 | sub = parts[0].lower() |
| 631 | if sub != "new": |
| 632 | _fmt(style, ("class:error", f"Unknown deck subcommand: {sub}. Try /deck new.\n")) |
| 633 | return |
| 634 | |
| 635 | # Parse optional --critique flag and --skill <name> option. Both can |
| 636 | # appear anywhere among the remaining tokens. |
| 637 | rest = parts[1:] |
| 638 | critique = False |
| 639 | skill_name: str | None = None |
| 640 | filtered: list[str] = [] |
| 641 | i = 0 |
| 642 | while i < len(rest): |
| 643 | tok = rest[i] |
| 644 | if tok == "--critique": |
| 645 | critique = True |
| 646 | elif tok == "--skill" and i + 1 < len(rest): |
| 647 | skill_name = rest[i + 1] |
| 648 | i += 1 |
| 649 | elif tok.startswith("--skill="): |
| 650 | skill_name = tok.split("=", 1)[1] |
| 651 | else: |
| 652 | filtered.append(tok) |
| 653 | i += 1 |
| 654 | |
| 655 | if len(filtered) < 2: |
| 656 | _fmt( |
| 657 | style, |
| 658 | ("class:error", 'Usage: /deck new [--critique] [--skill <skill>] <name> "<intent>"\n'), |
| 659 | ) |
| 660 | return |
| 661 | |
| 662 | name = filtered[0] |
| 663 | intent = " ".join(filtered[1:]) |
| 664 | |
| 665 | # Reuse the shared safety gates from the CLI (name validation, |
| 666 | # wiki dir, wiki content). Chat has no -y flag, so existing decks |
| 667 | # block with a clear instruction to delete first. |
| 668 | from openkb.cli import _preflight_skill_new |
| 669 |
no test coverage detected