klaude-code 1.2.21__py3-none-any.whl → 1.2.23__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/debug.py +8 -10
- klaude_code/command/__init__.py +0 -3
- klaude_code/command/status_cmd.py +1 -1
- klaude_code/const/__init__.py +10 -7
- klaude_code/core/manager/sub_agent_manager.py +1 -1
- klaude_code/core/prompt.py +5 -2
- klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +117 -0
- klaude_code/core/prompts/{prompt-codex-gpt-5-1.md → prompt-codex.md} +9 -42
- klaude_code/core/reminders.py +87 -2
- klaude_code/core/task.py +37 -18
- klaude_code/core/tool/__init__.py +1 -9
- klaude_code/core/tool/file/_utils.py +6 -0
- klaude_code/core/tool/file/apply_patch_tool.py +30 -72
- klaude_code/core/tool/file/diff_builder.py +151 -0
- klaude_code/core/tool/file/edit_tool.py +35 -18
- klaude_code/core/tool/file/read_tool.py +45 -86
- klaude_code/core/tool/file/write_tool.py +40 -30
- klaude_code/core/tool/shell/bash_tool.py +147 -0
- klaude_code/core/tool/skill/__init__.py +0 -0
- klaude_code/core/tool/{memory → skill}/skill_tool.py +16 -39
- klaude_code/protocol/commands.py +0 -1
- klaude_code/protocol/model.py +31 -11
- klaude_code/protocol/tools.py +1 -2
- klaude_code/session/export.py +76 -21
- klaude_code/session/store.py +4 -2
- klaude_code/session/templates/export_session.html +28 -0
- klaude_code/skill/__init__.py +27 -0
- klaude_code/skill/assets/deslop/SKILL.md +17 -0
- klaude_code/skill/assets/dev-docs/SKILL.md +108 -0
- klaude_code/skill/assets/handoff/SKILL.md +39 -0
- klaude_code/skill/assets/jj-workspace/SKILL.md +20 -0
- klaude_code/skill/assets/skill-creator/SKILL.md +139 -0
- klaude_code/{core/tool/memory/skill_loader.py → skill/loader.py} +60 -24
- klaude_code/skill/manager.py +70 -0
- klaude_code/skill/system_skills.py +192 -0
- klaude_code/ui/modes/repl/completers.py +103 -3
- klaude_code/ui/modes/repl/event_handler.py +7 -3
- klaude_code/ui/modes/repl/input_prompt_toolkit.py +42 -3
- klaude_code/ui/renderers/assistant.py +7 -2
- klaude_code/ui/renderers/common.py +26 -11
- klaude_code/ui/renderers/developer.py +12 -5
- klaude_code/ui/renderers/diffs.py +85 -1
- klaude_code/ui/renderers/metadata.py +4 -2
- klaude_code/ui/renderers/thinking.py +1 -1
- klaude_code/ui/renderers/tools.py +75 -129
- klaude_code/ui/renderers/user_input.py +32 -2
- klaude_code/ui/rich/markdown.py +27 -12
- klaude_code/ui/rich/status.py +9 -24
- klaude_code/ui/rich/theme.py +17 -5
- {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/METADATA +19 -13
- {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/RECORD +54 -54
- klaude_code/command/diff_cmd.py +0 -136
- klaude_code/command/prompt-deslop.md +0 -14
- klaude_code/command/prompt-dev-docs-update.md +0 -56
- klaude_code/command/prompt-dev-docs.md +0 -46
- klaude_code/command/prompt-handoff.md +0 -33
- klaude_code/command/prompt-jj-workspace.md +0 -18
- klaude_code/core/tool/file/multi_edit_tool.md +0 -42
- klaude_code/core/tool/file/multi_edit_tool.py +0 -175
- klaude_code/core/tool/memory/__init__.py +0 -5
- klaude_code/core/tool/memory/memory_tool.md +0 -20
- klaude_code/core/tool/memory/memory_tool.py +0 -456
- /klaude_code/core/tool/{memory → skill}/skill_tool.md +0 -0
- {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/WHEEL +0 -0
- {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/entry_points.txt +0 -0
|
@@ -7,6 +7,7 @@ from typing import NamedTuple, override
|
|
|
7
7
|
|
|
8
8
|
from prompt_toolkit import PromptSession
|
|
9
9
|
from prompt_toolkit.completion import ThreadedCompleter
|
|
10
|
+
from prompt_toolkit.cursor_shapes import CursorShape
|
|
10
11
|
from prompt_toolkit.formatted_text import FormattedText
|
|
11
12
|
from prompt_toolkit.history import FileHistory
|
|
12
13
|
from prompt_toolkit.patch_stdout import patch_stdout
|
|
@@ -17,6 +18,8 @@ from klaude_code.ui.core.input import InputProviderABC
|
|
|
17
18
|
from klaude_code.ui.modes.repl.clipboard import capture_clipboard_tag, copy_to_clipboard, extract_images_from_text
|
|
18
19
|
from klaude_code.ui.modes.repl.completers import AT_TOKEN_PATTERN, create_repl_completer
|
|
19
20
|
from klaude_code.ui.modes.repl.key_bindings import create_key_bindings
|
|
21
|
+
from klaude_code.ui.renderers.user_input import USER_MESSAGE_MARK
|
|
22
|
+
from klaude_code.ui.terminal.color import is_light_terminal_background
|
|
20
23
|
from klaude_code.ui.utils.common import get_current_git_branch, show_path_with_tilde
|
|
21
24
|
|
|
22
25
|
|
|
@@ -32,16 +35,23 @@ class REPLStatusSnapshot(NamedTuple):
|
|
|
32
35
|
|
|
33
36
|
COMPLETION_SELECTED = "#5869f7"
|
|
34
37
|
COMPLETION_MENU = "ansibrightblack"
|
|
35
|
-
INPUT_PROMPT_STYLE = "ansimagenta"
|
|
38
|
+
INPUT_PROMPT_STYLE = "ansimagenta bold"
|
|
39
|
+
PLACEHOLDER_TEXT_STYLE_DARK_BG = "fg:#5a5a5a italic"
|
|
40
|
+
PLACEHOLDER_TEXT_STYLE_LIGHT_BG = "fg:#7a7a7a italic"
|
|
41
|
+
PLACEHOLDER_TEXT_STYLE_UNKNOWN_BG = "fg:#8a8a8a italic"
|
|
42
|
+
PLACEHOLDER_SYMBOL_STYLE_DARK_BG = "bg:#2a2a2a fg:#5a5a5a"
|
|
43
|
+
PLACEHOLDER_SYMBOL_STYLE_LIGHT_BG = "bg:#e6e6e6 fg:#7a7a7a"
|
|
44
|
+
PLACEHOLDER_SYMBOL_STYLE_UNKNOWN_BG = "bg:#2a2a2a fg:#8a8a8a"
|
|
36
45
|
|
|
37
46
|
|
|
38
47
|
class PromptToolkitInput(InputProviderABC):
|
|
39
48
|
def __init__(
|
|
40
49
|
self,
|
|
41
|
-
prompt: str =
|
|
50
|
+
prompt: str = USER_MESSAGE_MARK,
|
|
42
51
|
status_provider: Callable[[], REPLStatusSnapshot] | None = None,
|
|
43
52
|
): # ▌
|
|
44
53
|
self._status_provider = status_provider
|
|
54
|
+
self._is_light_terminal_background = is_light_terminal_background(timeout=0.2)
|
|
45
55
|
|
|
46
56
|
project = str(Path.cwd()).strip("/").replace("/", "-")
|
|
47
57
|
history_path = Path.home() / ".klaude" / "projects" / project / "input" / "input_history.txt"
|
|
@@ -60,6 +70,7 @@ class PromptToolkitInput(InputProviderABC):
|
|
|
60
70
|
[(INPUT_PROMPT_STYLE, prompt)],
|
|
61
71
|
history=FileHistory(str(history_path)),
|
|
62
72
|
multiline=True,
|
|
73
|
+
cursor=CursorShape.BEAM,
|
|
63
74
|
prompt_continuation=[(INPUT_PROMPT_STYLE, " ")],
|
|
64
75
|
key_bindings=kb,
|
|
65
76
|
completer=ThreadedCompleter(create_repl_completer()),
|
|
@@ -144,6 +155,34 @@ class PromptToolkitInput(InputProviderABC):
|
|
|
144
155
|
toolbar_text = left_text + padding + right_text
|
|
145
156
|
return FormattedText([("#2c7eac", toolbar_text)])
|
|
146
157
|
|
|
158
|
+
def _render_input_placeholder(self) -> FormattedText:
|
|
159
|
+
if self._is_light_terminal_background is True:
|
|
160
|
+
text_style = PLACEHOLDER_TEXT_STYLE_LIGHT_BG
|
|
161
|
+
symbol_style = PLACEHOLDER_SYMBOL_STYLE_LIGHT_BG
|
|
162
|
+
elif self._is_light_terminal_background is False:
|
|
163
|
+
text_style = PLACEHOLDER_TEXT_STYLE_DARK_BG
|
|
164
|
+
symbol_style = PLACEHOLDER_SYMBOL_STYLE_DARK_BG
|
|
165
|
+
else:
|
|
166
|
+
text_style = PLACEHOLDER_TEXT_STYLE_UNKNOWN_BG
|
|
167
|
+
symbol_style = PLACEHOLDER_SYMBOL_STYLE_UNKNOWN_BG
|
|
168
|
+
|
|
169
|
+
return FormattedText(
|
|
170
|
+
[
|
|
171
|
+
(text_style, " " * 10),
|
|
172
|
+
(symbol_style, " @ "),
|
|
173
|
+
(text_style, " "),
|
|
174
|
+
(text_style, "files"),
|
|
175
|
+
(text_style, " "),
|
|
176
|
+
(symbol_style, " $ "),
|
|
177
|
+
(text_style, " "),
|
|
178
|
+
(text_style, "skills"),
|
|
179
|
+
(text_style, " "),
|
|
180
|
+
(symbol_style, " / "),
|
|
181
|
+
(text_style, " "),
|
|
182
|
+
(text_style, "commands"),
|
|
183
|
+
]
|
|
184
|
+
)
|
|
185
|
+
|
|
147
186
|
async def start(self) -> None:
|
|
148
187
|
pass
|
|
149
188
|
|
|
@@ -154,7 +193,7 @@ class PromptToolkitInput(InputProviderABC):
|
|
|
154
193
|
async def iter_inputs(self) -> AsyncIterator[UserInputPayload]:
|
|
155
194
|
while True:
|
|
156
195
|
with patch_stdout():
|
|
157
|
-
line: str = await self._session.prompt_async()
|
|
196
|
+
line: str = await self._session.prompt_async(placeholder=self._render_input_placeholder())
|
|
158
197
|
|
|
159
198
|
# Extract images referenced in the input text
|
|
160
199
|
images = extract_images_from_text(line)
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
from rich.console import RenderableType
|
|
2
|
+
from rich.padding import Padding
|
|
2
3
|
|
|
4
|
+
from klaude_code import const
|
|
3
5
|
from klaude_code.ui.renderers.common import create_grid
|
|
4
6
|
from klaude_code.ui.rich.markdown import NoInsetMarkdown
|
|
5
7
|
|
|
8
|
+
# UI markers
|
|
9
|
+
ASSISTANT_MESSAGE_MARK = "➤"
|
|
10
|
+
|
|
6
11
|
|
|
7
12
|
def render_assistant_message(content: str, *, code_theme: str) -> RenderableType | None:
|
|
8
13
|
"""Render assistant message for replay history display.
|
|
@@ -15,7 +20,7 @@ def render_assistant_message(content: str, *, code_theme: str) -> RenderableType
|
|
|
15
20
|
|
|
16
21
|
grid = create_grid()
|
|
17
22
|
grid.add_row(
|
|
18
|
-
|
|
19
|
-
NoInsetMarkdown(stripped, code_theme=code_theme),
|
|
23
|
+
ASSISTANT_MESSAGE_MARK,
|
|
24
|
+
Padding(NoInsetMarkdown(stripped, code_theme=code_theme), (0, const.MARKDOWN_RIGHT_MARGIN, 0, 0)),
|
|
20
25
|
)
|
|
21
26
|
return grid
|
|
@@ -31,16 +31,20 @@ def truncate_display(
|
|
|
31
31
|
return Text(f"… (more {remaining} lines)", style=ThemeKey.TOOL_RESULT_TRUNCATED)
|
|
32
32
|
|
|
33
33
|
lines = text.split("\n")
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lines = lines[:max_lines]
|
|
34
|
+
truncated_lines = 0
|
|
35
|
+
head_lines: list[str] = []
|
|
36
|
+
tail_lines: list[str] = []
|
|
38
37
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
if len(lines) > max_lines:
|
|
39
|
+
truncated_lines = len(lines) - max_lines
|
|
40
|
+
head_count = max_lines // 2
|
|
41
|
+
tail_count = max_lines - head_count
|
|
42
|
+
head_lines = lines[:head_count]
|
|
43
|
+
tail_lines = lines[-tail_count:]
|
|
44
|
+
else:
|
|
45
|
+
head_lines = lines
|
|
42
46
|
|
|
43
|
-
|
|
47
|
+
def append_line(out: Text, line: str) -> None:
|
|
44
48
|
if len(line) > max_line_length:
|
|
45
49
|
extra_chars = len(line) - max_line_length
|
|
46
50
|
out.append(line[:max_line_length])
|
|
@@ -53,10 +57,21 @@ def truncate_display(
|
|
|
53
57
|
else:
|
|
54
58
|
out.append(line)
|
|
55
59
|
|
|
56
|
-
|
|
60
|
+
out = Text()
|
|
61
|
+
if base_style is not None:
|
|
62
|
+
out.style = base_style
|
|
63
|
+
|
|
64
|
+
for idx, line in enumerate(head_lines):
|
|
65
|
+
append_line(out, line)
|
|
66
|
+
if idx < len(head_lines) - 1 or truncated_lines > 0 or tail_lines:
|
|
57
67
|
out.append("\n")
|
|
58
68
|
|
|
59
|
-
if
|
|
60
|
-
out.append_text(Text(f"
|
|
69
|
+
if truncated_lines > 0:
|
|
70
|
+
out.append_text(Text(f"⋮ (more {truncated_lines} lines)\n", style=ThemeKey.TOOL_RESULT_TRUNCATED))
|
|
71
|
+
|
|
72
|
+
for idx, line in enumerate(tail_lines):
|
|
73
|
+
append_line(out, line)
|
|
74
|
+
if idx < len(tail_lines) - 1:
|
|
75
|
+
out.append("\n")
|
|
61
76
|
|
|
62
77
|
return out
|
|
@@ -4,7 +4,6 @@ from rich.table import Table
|
|
|
4
4
|
from rich.text import Text
|
|
5
5
|
|
|
6
6
|
from klaude_code.protocol import commands, events, model
|
|
7
|
-
from klaude_code.ui.renderers import diffs as r_diffs
|
|
8
7
|
from klaude_code.ui.renderers.common import create_grid, truncate_display
|
|
9
8
|
from klaude_code.ui.renderers.tools import render_path
|
|
10
9
|
from klaude_code.ui.rich.markdown import NoInsetMarkdown
|
|
@@ -18,6 +17,7 @@ def need_render_developer_message(e: events.DeveloperMessageEvent) -> bool:
|
|
|
18
17
|
or e.item.todo_use
|
|
19
18
|
or e.item.at_files
|
|
20
19
|
or e.item.user_image_count
|
|
20
|
+
or e.item.skill_name
|
|
21
21
|
)
|
|
22
22
|
|
|
23
23
|
|
|
@@ -94,6 +94,17 @@ def render_developer_message(e: events.DeveloperMessageEvent) -> RenderableType:
|
|
|
94
94
|
)
|
|
95
95
|
parts.append(grid)
|
|
96
96
|
|
|
97
|
+
if sn := e.item.skill_name:
|
|
98
|
+
grid = create_grid()
|
|
99
|
+
grid.add_row(
|
|
100
|
+
Text(" +", style=ThemeKey.REMINDER),
|
|
101
|
+
Text.assemble(
|
|
102
|
+
("Activated skill ", ThemeKey.REMINDER),
|
|
103
|
+
(sn, ThemeKey.REMINDER_BOLD),
|
|
104
|
+
),
|
|
105
|
+
)
|
|
106
|
+
parts.append(grid)
|
|
107
|
+
|
|
97
108
|
return Group(*parts) if parts else Text("")
|
|
98
109
|
|
|
99
110
|
|
|
@@ -103,10 +114,6 @@ def render_command_output(e: events.DeveloperMessageEvent) -> RenderableType:
|
|
|
103
114
|
return Text("")
|
|
104
115
|
|
|
105
116
|
match e.item.command_output.command_name:
|
|
106
|
-
case commands.CommandName.DIFF:
|
|
107
|
-
if e.item.content is None or len(e.item.content) == 0:
|
|
108
|
-
return Padding.indent(Text("(no changes)", style=ThemeKey.TOOL_RESULT), level=2)
|
|
109
|
-
return r_diffs.render_diff_panel(e.item.content, show_file_name=True)
|
|
110
117
|
case commands.CommandName.HELP:
|
|
111
118
|
return Padding.indent(Text.from_markup(e.item.content or ""), level=2)
|
|
112
119
|
case commands.CommandName.STATUS:
|
|
@@ -5,6 +5,7 @@ from rich.panel import Panel
|
|
|
5
5
|
from rich.text import Text
|
|
6
6
|
|
|
7
7
|
from klaude_code import const
|
|
8
|
+
from klaude_code.protocol import model
|
|
8
9
|
from klaude_code.ui.renderers.common import create_grid
|
|
9
10
|
from klaude_code.ui.rich.theme import ThemeKey
|
|
10
11
|
|
|
@@ -179,11 +180,35 @@ def render_diff(diff_text: str, show_file_name: bool = False) -> RenderableType:
|
|
|
179
180
|
return grid
|
|
180
181
|
|
|
181
182
|
|
|
183
|
+
def render_structured_diff(ui_extra: model.DiffUIExtra, show_file_name: bool = False) -> RenderableType:
|
|
184
|
+
files = ui_extra.files
|
|
185
|
+
if not files:
|
|
186
|
+
return Text("")
|
|
187
|
+
|
|
188
|
+
grid = create_grid()
|
|
189
|
+
grid.padding = (0, 0)
|
|
190
|
+
show_headers = show_file_name or len(files) > 1
|
|
191
|
+
|
|
192
|
+
for idx, file_diff in enumerate(files):
|
|
193
|
+
if idx > 0:
|
|
194
|
+
grid.add_row("", "")
|
|
195
|
+
|
|
196
|
+
if show_headers:
|
|
197
|
+
grid.add_row(*_render_file_header(file_diff))
|
|
198
|
+
|
|
199
|
+
for line in file_diff.lines:
|
|
200
|
+
prefix = _make_structured_prefix(line, const.DIFF_PREFIX_WIDTH)
|
|
201
|
+
text = _render_structured_line(line)
|
|
202
|
+
grid.add_row(Text(prefix, ThemeKey.TOOL_RESULT), text)
|
|
203
|
+
|
|
204
|
+
return grid
|
|
205
|
+
|
|
206
|
+
|
|
182
207
|
def render_diff_panel(
|
|
183
208
|
diff_text: str,
|
|
184
209
|
*,
|
|
185
210
|
show_file_name: bool = True,
|
|
186
|
-
heading: str = "
|
|
211
|
+
heading: str = "DIFF",
|
|
187
212
|
indent: int = 2,
|
|
188
213
|
) -> RenderableType:
|
|
189
214
|
lines = diff_text.splitlines()
|
|
@@ -210,3 +235,62 @@ def render_diff_panel(
|
|
|
210
235
|
if indent <= 0:
|
|
211
236
|
return panel
|
|
212
237
|
return Padding.indent(panel, level=indent)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _render_file_header(file_diff: model.DiffFileDiff) -> tuple[Text, Text]:
|
|
241
|
+
file_text = Text(file_diff.file_path, style=ThemeKey.DIFF_FILE_NAME)
|
|
242
|
+
stats_text = Text()
|
|
243
|
+
if file_diff.stats_add > 0:
|
|
244
|
+
stats_text.append(f"+{file_diff.stats_add}", style=ThemeKey.DIFF_STATS_ADD)
|
|
245
|
+
if file_diff.stats_remove > 0:
|
|
246
|
+
if stats_text.plain:
|
|
247
|
+
stats_text.append(" ")
|
|
248
|
+
stats_text.append(f"-{file_diff.stats_remove}", style=ThemeKey.DIFF_STATS_REMOVE)
|
|
249
|
+
|
|
250
|
+
file_line = Text(style=ThemeKey.DIFF_FILE_NAME)
|
|
251
|
+
file_line.append_text(file_text)
|
|
252
|
+
if stats_text.plain:
|
|
253
|
+
file_line.append(" (")
|
|
254
|
+
file_line.append_text(stats_text)
|
|
255
|
+
file_line.append(")")
|
|
256
|
+
|
|
257
|
+
if file_diff.stats_add > 0 and file_diff.stats_remove == 0:
|
|
258
|
+
file_mark = "+"
|
|
259
|
+
elif file_diff.stats_remove > 0 and file_diff.stats_add == 0:
|
|
260
|
+
file_mark = "-"
|
|
261
|
+
else:
|
|
262
|
+
file_mark = "±"
|
|
263
|
+
|
|
264
|
+
prefix = Text(f"{file_mark:>{const.DIFF_PREFIX_WIDTH}} ", style=ThemeKey.DIFF_FILE_NAME)
|
|
265
|
+
return prefix, file_line
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def _make_structured_prefix(line: model.DiffLine, width: int) -> str:
|
|
269
|
+
if line.kind == "gap":
|
|
270
|
+
return f"{'⋮':>{width}} "
|
|
271
|
+
number = " " * width
|
|
272
|
+
if line.kind in {"add", "ctx"} and line.new_line_no is not None:
|
|
273
|
+
number = f"{line.new_line_no:>{width}}"
|
|
274
|
+
marker = "+" if line.kind == "add" else "-" if line.kind == "remove" else " "
|
|
275
|
+
return f"{number} {marker}"
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
def _render_structured_line(line: model.DiffLine) -> Text:
|
|
279
|
+
if line.kind == "gap":
|
|
280
|
+
return Text("")
|
|
281
|
+
text = Text()
|
|
282
|
+
for span in line.spans:
|
|
283
|
+
text.append(span.text, style=_span_style(line.kind, span.op))
|
|
284
|
+
return text
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def _span_style(line_kind: str, span_op: str) -> ThemeKey:
|
|
288
|
+
if line_kind == "add":
|
|
289
|
+
if span_op == "insert":
|
|
290
|
+
return ThemeKey.DIFF_ADD_CHAR
|
|
291
|
+
return ThemeKey.DIFF_ADD
|
|
292
|
+
if line_kind == "remove":
|
|
293
|
+
if span_op == "delete":
|
|
294
|
+
return ThemeKey.DIFF_REMOVE_CHAR
|
|
295
|
+
return ThemeKey.DIFF_REMOVE
|
|
296
|
+
return ThemeKey.TOOL_RESULT
|
|
@@ -45,7 +45,7 @@ def _render_task_metadata_block(
|
|
|
45
45
|
currency_symbol = "¥" if currency == "CNY" else "$"
|
|
46
46
|
|
|
47
47
|
# First column: mark only
|
|
48
|
-
mark = Text("└", style=ThemeKey.METADATA_DIM) if is_sub_agent else Text("
|
|
48
|
+
mark = Text("└", style=ThemeKey.METADATA_DIM) if is_sub_agent else Text("⇅", style=ThemeKey.METADATA)
|
|
49
49
|
|
|
50
50
|
# Second column: model@provider / tokens / cost / ...
|
|
51
51
|
content = Text()
|
|
@@ -151,7 +151,9 @@ def render_task_metadata(e: events.TaskMetadataEvent) -> RenderableType:
|
|
|
151
151
|
"""Render task metadata including main agent and sub-agents, aggregated by model+provider."""
|
|
152
152
|
renderables: list[RenderableType] = []
|
|
153
153
|
|
|
154
|
-
renderables.append(
|
|
154
|
+
renderables.append(
|
|
155
|
+
_render_task_metadata_block(e.metadata.main_agent, is_sub_agent=False, show_context_and_time=True)
|
|
156
|
+
)
|
|
155
157
|
|
|
156
158
|
# Aggregate by (model_name, provider), sorted by total_cost descending
|
|
157
159
|
sorted_items = model.TaskMetadata.aggregate_by_model(e.metadata.sub_agent_task_metadata)
|
|
@@ -9,7 +9,7 @@ from klaude_code.ui.rich.theme import ThemeKey
|
|
|
9
9
|
|
|
10
10
|
|
|
11
11
|
def thinking_prefix() -> Text:
|
|
12
|
-
return Text.from_markup("[not italic]⸫[/not italic] Thinking …", style=ThemeKey.
|
|
12
|
+
return Text.from_markup("[not italic]⸫[/not italic] Thinking …", style=ThemeKey.THINKING_BOLD)
|
|
13
13
|
|
|
14
14
|
|
|
15
15
|
def normalize_thinking_content(content: str) -> str:
|