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.
- klaude_code/cli/main.py +75 -11
- klaude_code/cli/runtime.py +171 -34
- klaude_code/command/__init__.py +4 -0
- klaude_code/command/help_cmd.py +2 -1
- klaude_code/command/model_cmd.py +3 -5
- klaude_code/command/model_select.py +84 -0
- klaude_code/command/registry.py +23 -0
- klaude_code/command/resume_cmd.py +52 -2
- klaude_code/command/thinking_cmd.py +30 -199
- klaude_code/config/select_model.py +47 -97
- klaude_code/config/thinking.py +255 -0
- klaude_code/core/executor.py +53 -63
- klaude_code/protocol/commands.py +11 -0
- klaude_code/protocol/op.py +15 -0
- klaude_code/session/__init__.py +2 -2
- klaude_code/session/selector.py +33 -61
- klaude_code/ui/modes/repl/completers.py +27 -15
- klaude_code/ui/modes/repl/event_handler.py +2 -1
- klaude_code/ui/modes/repl/input_prompt_toolkit.py +393 -57
- klaude_code/ui/modes/repl/key_bindings.py +30 -10
- klaude_code/ui/renderers/metadata.py +3 -6
- klaude_code/ui/renderers/user_input.py +18 -1
- klaude_code/ui/rich/theme.py +2 -2
- klaude_code/ui/terminal/notifier.py +42 -0
- klaude_code/ui/terminal/selector.py +419 -136
- {klaude_code-1.4.3.dist-info → klaude_code-1.5.0.dist-info}/METADATA +1 -1
- {klaude_code-1.4.3.dist-info → klaude_code-1.5.0.dist-info}/RECORD +29 -27
- {klaude_code-1.4.3.dist-info → klaude_code-1.5.0.dist-info}/WHEEL +0 -0
- {klaude_code-1.4.3.dist-info → klaude_code-1.5.0.dist-info}/entry_points.txt +0 -0
|
@@ -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.
|
|
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(
|
|
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
|
-
|
|
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,
|
|
92
|
-
for
|
|
93
|
-
if
|
|
94
|
-
hint = f" [{
|
|
95
|
-
matched.append((
|
|
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,
|
|
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=
|
|
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
|
|