klaude-code 1.4.3__py3-none-any.whl → 1.5.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -19,7 +19,7 @@ import re
19
19
  import shutil
20
20
  import subprocess
21
21
  import time
22
- from collections.abc import Iterable
22
+ from collections.abc import Callable, Iterable
23
23
  from pathlib import Path
24
24
  from typing import NamedTuple
25
25
 
@@ -27,7 +27,7 @@ from prompt_toolkit.completion import Completer, Completion
27
27
  from prompt_toolkit.document import Document
28
28
  from prompt_toolkit.formatted_text import FormattedText
29
29
 
30
- from klaude_code.command import CommandABC, get_commands
30
+ from klaude_code.protocol.commands import CommandInfo
31
31
  from klaude_code.trace.log import DebugType, log_debug
32
32
 
33
33
  # Pattern to match @token for completion refresh (used by key bindings).
@@ -40,12 +40,18 @@ AT_TOKEN_PATTERN = re.compile(r'(^|\s)@(?P<frag>"[^"]*"|[^\s]*)$')
40
40
  SKILL_TOKEN_PATTERN = re.compile(r"^[$¥](?P<frag>\S*)$")
41
41
 
42
42
 
43
- def create_repl_completer() -> Completer:
43
+ def create_repl_completer(
44
+ command_info_provider: Callable[[], list[CommandInfo]] | None = None,
45
+ ) -> Completer:
44
46
  """Create and return the combined REPL completer.
45
47
 
48
+ Args:
49
+ command_info_provider: Optional callable that returns command metadata.
50
+ If None, slash command completion is disabled.
51
+
46
52
  Returns a completer that handles both @ file paths and / slash commands.
47
53
  """
48
- return _ComboCompleter()
54
+ return _ComboCompleter(command_info_provider=command_info_provider)
49
55
 
50
56
 
51
57
  class _CmdResult(NamedTuple):
@@ -66,6 +72,9 @@ class _SlashCommandCompleter(Completer):
66
72
 
67
73
  _SLASH_TOKEN_RE = re.compile(r"^/(?P<frag>\S*)$")
68
74
 
75
+ def __init__(self, command_info_provider: Callable[[], list[CommandInfo]] | None = None) -> None:
76
+ self._command_info_provider = command_info_provider
77
+
69
78
  def get_completions(
70
79
  self,
71
80
  document: Document,
@@ -75,6 +84,9 @@ class _SlashCommandCompleter(Completer):
75
84
  if document.cursor_position_row != 0:
76
85
  return
77
86
 
87
+ if self._command_info_provider is None:
88
+ return
89
+
78
90
  text_before = document.current_line_before_cursor
79
91
  m = self._SLASH_TOKEN_RE.search(text_before)
80
92
  if not m:
@@ -84,20 +96,20 @@ class _SlashCommandCompleter(Completer):
84
96
  token_start = len(text_before) - len(f"/{frag}")
85
97
  start_position = token_start - len(text_before) # negative offset
86
98
 
87
- # Get available commands
88
- commands = get_commands()
99
+ # Get available commands from provider
100
+ command_infos = self._command_info_provider()
89
101
 
90
102
  # Filter commands that match the fragment (preserve registration order)
91
- matched: list[tuple[str, CommandABC, str]] = []
92
- for cmd_name, cmd_obj in commands.items():
93
- if cmd_name.startswith(frag):
94
- hint = f" [{cmd_obj.placeholder}]" if cmd_obj.support_addition_params else ""
95
- matched.append((cmd_name, cmd_obj, hint))
103
+ matched: list[tuple[str, CommandInfo, str]] = []
104
+ for cmd_info in command_infos:
105
+ if cmd_info.name.startswith(frag):
106
+ hint = f" [{cmd_info.placeholder}]" if cmd_info.support_addition_params else ""
107
+ matched.append((cmd_info.name, cmd_info, hint))
96
108
 
97
109
  if not matched:
98
110
  return
99
111
 
100
- for cmd_name, cmd_obj, hint in matched:
112
+ for cmd_name, cmd_info, hint in matched:
101
113
  completion_text = f"/{cmd_name} "
102
114
  # Use FormattedText to style the hint (placeholder) in bright black
103
115
  display = FormattedText([("", cmd_name), ("ansibrightblack", hint)]) if hint else cmd_name
@@ -105,7 +117,7 @@ class _SlashCommandCompleter(Completer):
105
117
  text=completion_text,
106
118
  start_position=start_position,
107
119
  display=display,
108
- display_meta=str(cmd_obj.summary),
120
+ display_meta=cmd_info.summary,
109
121
  )
110
122
 
111
123
  def is_slash_command_context(self, document: Document) -> bool:
@@ -200,9 +212,9 @@ class _SkillCompleter(Completer):
200
212
  class _ComboCompleter(Completer):
201
213
  """Combined completer that handles @ file paths, / slash commands, and $ skills."""
202
214
 
203
- def __init__(self) -> None:
215
+ def __init__(self, command_info_provider: Callable[[], list[CommandInfo]] | None = None) -> None:
204
216
  self._at_completer = _AtFilesCompleter()
205
- self._slash_completer = _SlashCommandCompleter()
217
+ self._slash_completer = _SlashCommandCompleter(command_info_provider=command_info_provider)
206
218
  self._skill_completer = _SkillCompleter()
207
219
 
208
220
  def get_completions(
@@ -15,7 +15,7 @@ from klaude_code.ui.renderers.thinking import THINKING_MESSAGE_MARK, normalize_t
15
15
  from klaude_code.ui.rich import status as r_status
16
16
  from klaude_code.ui.rich.markdown import MarkdownStream, ThinkingMarkdown
17
17
  from klaude_code.ui.rich.theme import ThemeKey
18
- from klaude_code.ui.terminal.notifier import Notification, NotificationType, TerminalNotifier
18
+ from klaude_code.ui.terminal.notifier import Notification, NotificationType, TerminalNotifier, emit_tmux_signal
19
19
  from klaude_code.ui.terminal.progress_bar import OSC94States, emit_osc94
20
20
 
21
21
 
@@ -509,6 +509,7 @@ class DisplayEventHandler:
509
509
  self.spinner_status.reset()
510
510
  self.renderer.spinner_stop()
511
511
  self.renderer.console.print(Rule(characters="─", style=ThemeKey.LINES))
512
+ emit_tmux_signal() # Signal test harness if KLAUDE_TEST_SIGNAL is set
512
513
  await self.stage_manager.transition_to(Stage.WAITING)
513
514
  self._maybe_notify_task_finish(event)
514
515