klaude-code 2.0.2__py3-none-any.whl → 2.1.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/app/__init__.py +12 -0
- klaude_code/app/runtime.py +215 -0
- klaude_code/cli/auth_cmd.py +2 -2
- klaude_code/cli/config_cmd.py +2 -2
- klaude_code/cli/cost_cmd.py +1 -1
- klaude_code/cli/debug.py +12 -36
- klaude_code/cli/list_model.py +3 -3
- klaude_code/cli/main.py +17 -60
- klaude_code/cli/self_update.py +2 -187
- klaude_code/cli/session_cmd.py +2 -2
- klaude_code/config/config.py +1 -1
- klaude_code/config/select_model.py +1 -1
- klaude_code/const.py +9 -1
- klaude_code/core/agent.py +9 -62
- klaude_code/core/agent_profile.py +284 -0
- klaude_code/core/executor.py +335 -230
- klaude_code/core/manager/llm_clients_builder.py +1 -1
- klaude_code/core/manager/sub_agent_manager.py +16 -29
- klaude_code/core/reminders.py +64 -99
- klaude_code/core/task.py +12 -20
- klaude_code/core/tool/__init__.py +5 -17
- klaude_code/core/tool/context.py +84 -0
- klaude_code/core/tool/file/apply_patch_tool.py +18 -21
- klaude_code/core/tool/file/edit_tool.py +39 -42
- klaude_code/core/tool/file/read_tool.py +14 -9
- klaude_code/core/tool/file/write_tool.py +12 -13
- klaude_code/core/tool/report_back_tool.py +4 -1
- klaude_code/core/tool/shell/bash_tool.py +6 -11
- klaude_code/core/tool/skill/skill_tool.py +3 -1
- klaude_code/core/tool/sub_agent_tool.py +8 -7
- klaude_code/core/tool/todo/todo_write_tool.py +3 -9
- klaude_code/core/tool/todo/update_plan_tool.py +3 -5
- klaude_code/core/tool/tool_abc.py +2 -1
- klaude_code/core/tool/tool_registry.py +2 -33
- klaude_code/core/tool/tool_runner.py +13 -10
- klaude_code/core/tool/web/mermaid_tool.py +3 -1
- klaude_code/core/tool/web/web_fetch_tool.py +5 -3
- klaude_code/core/tool/web/web_search_tool.py +5 -3
- klaude_code/core/turn.py +86 -26
- klaude_code/llm/anthropic/client.py +1 -1
- klaude_code/llm/bedrock/client.py +1 -1
- klaude_code/llm/claude/client.py +1 -1
- klaude_code/llm/codex/client.py +1 -1
- klaude_code/llm/google/client.py +1 -1
- klaude_code/llm/openai_compatible/client.py +1 -1
- klaude_code/llm/openai_compatible/tool_call_accumulator.py +1 -1
- klaude_code/llm/openrouter/client.py +1 -1
- klaude_code/llm/openrouter/reasoning.py +1 -1
- klaude_code/llm/responses/client.py +1 -1
- klaude_code/protocol/events/__init__.py +57 -0
- klaude_code/protocol/events/base.py +18 -0
- klaude_code/protocol/events/chat.py +20 -0
- klaude_code/protocol/events/lifecycle.py +22 -0
- klaude_code/protocol/events/metadata.py +15 -0
- klaude_code/protocol/events/streaming.py +43 -0
- klaude_code/protocol/events/system.py +53 -0
- klaude_code/protocol/events/tools.py +23 -0
- klaude_code/protocol/op.py +5 -0
- klaude_code/session/session.py +6 -5
- klaude_code/skill/assets/create-plan/SKILL.md +76 -0
- klaude_code/skill/loader.py +1 -1
- klaude_code/skill/system_skills.py +1 -1
- klaude_code/tui/__init__.py +8 -0
- klaude_code/{command → tui/command}/clear_cmd.py +2 -1
- klaude_code/{command → tui/command}/debug_cmd.py +3 -2
- klaude_code/{command → tui/command}/export_cmd.py +2 -1
- klaude_code/{command → tui/command}/export_online_cmd.py +2 -1
- klaude_code/{command → tui/command}/fork_session_cmd.py +4 -3
- klaude_code/{command → tui/command}/help_cmd.py +2 -1
- klaude_code/{command → tui/command}/model_cmd.py +4 -3
- klaude_code/{command → tui/command}/model_select.py +2 -2
- klaude_code/{command → tui/command}/prompt_command.py +4 -3
- klaude_code/{command → tui/command}/refresh_cmd.py +3 -1
- klaude_code/{command → tui/command}/registry.py +6 -5
- klaude_code/{command → tui/command}/release_notes_cmd.py +2 -1
- klaude_code/{command → tui/command}/resume_cmd.py +4 -3
- klaude_code/{command → tui/command}/status_cmd.py +2 -1
- klaude_code/{command → tui/command}/terminal_setup_cmd.py +2 -1
- klaude_code/{command → tui/command}/thinking_cmd.py +3 -2
- klaude_code/tui/commands.py +164 -0
- klaude_code/{ui/renderers → tui/components}/assistant.py +3 -3
- klaude_code/{ui/renderers → tui/components}/bash_syntax.py +2 -2
- klaude_code/{ui/renderers → tui/components}/common.py +1 -1
- klaude_code/{ui/renderers → tui/components}/developer.py +4 -4
- klaude_code/{ui/renderers → tui/components}/diffs.py +2 -2
- klaude_code/{ui/renderers → tui/components}/errors.py +2 -2
- klaude_code/{ui/renderers → tui/components}/metadata.py +7 -7
- klaude_code/{ui → tui/components}/rich/markdown.py +9 -23
- klaude_code/{ui → tui/components}/rich/status.py +2 -2
- klaude_code/{ui → tui/components}/rich/theme.py +3 -1
- klaude_code/{ui/renderers → tui/components}/sub_agent.py +23 -43
- klaude_code/{ui/renderers → tui/components}/thinking.py +3 -3
- klaude_code/{ui/renderers → tui/components}/tools.py +9 -9
- klaude_code/{ui/renderers → tui/components}/user_input.py +3 -20
- klaude_code/tui/display.py +85 -0
- klaude_code/{ui/modes/repl → tui/input}/__init__.py +1 -1
- klaude_code/{ui/modes/repl → tui/input}/completers.py +1 -1
- klaude_code/{ui/modes/repl/input_prompt_toolkit.py → tui/input/prompt_toolkit.py} +6 -6
- klaude_code/tui/machine.py +606 -0
- klaude_code/tui/renderer.py +707 -0
- klaude_code/tui/runner.py +321 -0
- klaude_code/tui/terminal/__init__.py +56 -0
- klaude_code/{ui → tui}/terminal/color.py +1 -1
- klaude_code/{ui → tui}/terminal/control.py +1 -1
- klaude_code/{ui → tui}/terminal/notifier.py +1 -1
- klaude_code/ui/__init__.py +6 -50
- klaude_code/ui/core/display.py +3 -3
- klaude_code/ui/core/input.py +2 -1
- klaude_code/ui/{modes/debug/display.py → debug_mode.py} +1 -1
- klaude_code/ui/{modes/exec/display.py → exec_mode.py} +0 -2
- klaude_code/ui/terminal/__init__.py +6 -54
- klaude_code/ui/terminal/title.py +31 -0
- klaude_code/update.py +163 -0
- {klaude_code-2.0.2.dist-info → klaude_code-2.1.0.dist-info}/METADATA +1 -1
- klaude_code-2.1.0.dist-info/RECORD +235 -0
- klaude_code/cli/runtime.py +0 -518
- klaude_code/core/prompt.py +0 -108
- klaude_code/core/tool/tool_context.py +0 -148
- klaude_code/protocol/events.py +0 -195
- klaude_code/skill/assets/dev-docs/SKILL.md +0 -108
- klaude_code/trace/__init__.py +0 -21
- klaude_code/ui/core/stage_manager.py +0 -48
- klaude_code/ui/modes/__init__.py +0 -1
- klaude_code/ui/modes/debug/__init__.py +0 -1
- klaude_code/ui/modes/exec/__init__.py +0 -1
- klaude_code/ui/modes/repl/display.py +0 -61
- klaude_code/ui/modes/repl/event_handler.py +0 -629
- klaude_code/ui/modes/repl/renderer.py +0 -464
- klaude_code/ui/utils/__init__.py +0 -1
- klaude_code-2.0.2.dist-info/RECORD +0 -227
- /klaude_code/{trace/log.py → log.py} +0 -0
- /klaude_code/{command → tui/command}/__init__.py +0 -0
- /klaude_code/{command → tui/command}/command_abc.py +0 -0
- /klaude_code/{command → tui/command}/prompt-commit.md +0 -0
- /klaude_code/{command → tui/command}/prompt-init.md +0 -0
- /klaude_code/{ui/renderers → tui/components}/__init__.py +0 -0
- /klaude_code/{ui/renderers → tui/components}/mermaid_viewer.py +0 -0
- /klaude_code/{ui → tui/components}/rich/__init__.py +0 -0
- /klaude_code/{ui → tui/components}/rich/cjk_wrap.py +0 -0
- /klaude_code/{ui → tui/components}/rich/code_panel.py +0 -0
- /klaude_code/{ui → tui/components}/rich/live.py +0 -0
- /klaude_code/{ui → tui/components}/rich/quote.py +0 -0
- /klaude_code/{ui → tui/components}/rich/searchable_text.py +0 -0
- /klaude_code/{ui/modes/repl → tui/input}/clipboard.py +0 -0
- /klaude_code/{ui/modes/repl → tui/input}/key_bindings.py +0 -0
- /klaude_code/{ui → tui}/terminal/image.py +0 -0
- /klaude_code/{ui → tui}/terminal/progress_bar.py +0 -0
- /klaude_code/{ui → tui}/terminal/selector.py +0 -0
- /klaude_code/ui/{utils/common.py → common.py} +0 -0
- {klaude_code-2.0.2.dist-info → klaude_code-2.1.0.dist-info}/WHEEL +0 -0
- {klaude_code-2.0.2.dist-info → klaude_code-2.1.0.dist-info}/entry_points.txt +0 -0
klaude_code/session/session.py
CHANGED
|
@@ -289,7 +289,7 @@ class Session(BaseModel):
|
|
|
289
289
|
return True
|
|
290
290
|
return isinstance(prev_item, (message.UserMessage, message.ToolResultMessage, message.DeveloperMessage))
|
|
291
291
|
|
|
292
|
-
def get_history_item(self) -> Iterable[events.
|
|
292
|
+
def get_history_item(self) -> Iterable[events.ReplayEventUnion]:
|
|
293
293
|
seen_sub_agent_sessions: set[str] = set()
|
|
294
294
|
prev_item: message.HistoryEvent | None = None
|
|
295
295
|
last_assistant_content: str = ""
|
|
@@ -314,8 +314,8 @@ class Session(BaseModel):
|
|
|
314
314
|
response_id=am.response_id,
|
|
315
315
|
session_id=self.id,
|
|
316
316
|
)
|
|
317
|
-
yield events.
|
|
318
|
-
thinking_text=thinking_text,
|
|
317
|
+
yield events.ResponseCompleteEvent(
|
|
318
|
+
thinking_text=thinking_text or None,
|
|
319
319
|
content=content,
|
|
320
320
|
response_id=am.response_id,
|
|
321
321
|
session_id=self.id,
|
|
@@ -360,7 +360,8 @@ class Session(BaseModel):
|
|
|
360
360
|
images=images or None,
|
|
361
361
|
)
|
|
362
362
|
case model.TaskMetadataItem() as mt:
|
|
363
|
-
|
|
363
|
+
if self.sub_agent_state is None:
|
|
364
|
+
yield events.TaskMetadataEvent(session_id=self.id, metadata=mt)
|
|
364
365
|
case message.DeveloperMessage() as dm:
|
|
365
366
|
yield events.DeveloperMessageEvent(session_id=self.id, item=dm)
|
|
366
367
|
case message.StreamErrorItem() as se:
|
|
@@ -377,7 +378,7 @@ class Session(BaseModel):
|
|
|
377
378
|
|
|
378
379
|
def _iter_sub_agent_history(
|
|
379
380
|
self, tool_result: message.ToolResultMessage, seen_sub_agent_sessions: set[str]
|
|
380
|
-
) -> Iterable[events.
|
|
381
|
+
) -> Iterable[events.ReplayEventUnion]:
|
|
381
382
|
ui_extra = tool_result.ui_extra
|
|
382
383
|
if not isinstance(ui_extra, model.SessionIdUIExtra):
|
|
383
384
|
return
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: create-plan
|
|
3
|
+
description: Create a concise plan. Use when a user explicitly asks for a plan related to a coding task.
|
|
4
|
+
metadata:
|
|
5
|
+
short-description: Create a plan
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Create Plan
|
|
9
|
+
|
|
10
|
+
## Goal
|
|
11
|
+
|
|
12
|
+
Turn a user prompt into a **single, actionable plan** delivered in the final assistant message.
|
|
13
|
+
|
|
14
|
+
## Minimal workflow
|
|
15
|
+
|
|
16
|
+
1. **Scan context quickly**
|
|
17
|
+
- Read `README.md` and any obvious docs (`docs/`, `CONTRIBUTING.md`, `ARCHITECTURE.md`).
|
|
18
|
+
- Skim relevant files (the ones most likely touched).
|
|
19
|
+
- Identify constraints (language, frameworks, CI/test commands, deployment shape).
|
|
20
|
+
|
|
21
|
+
2. **Ask follow-ups only if blocking**
|
|
22
|
+
- Ask **at most 1–2 questions**.
|
|
23
|
+
- Only ask if you cannot responsibly plan without the answer; prefer multiple-choice.
|
|
24
|
+
- If unsure but not blocked, make a reasonable assumption and proceed.
|
|
25
|
+
|
|
26
|
+
3. **Create a plan using the template below**
|
|
27
|
+
- Start with **1 short paragraph** describing the intent and approach.
|
|
28
|
+
- Clearly call out what is **in scope** and what is **not in scope** in short.
|
|
29
|
+
- Then provide a **small checklist** of action items (default 6–10 items).
|
|
30
|
+
- Each checklist item should be a concrete action and, when helpful, mention files/commands.
|
|
31
|
+
- **Make items atomic and ordered**: discovery → changes → tests → rollout.
|
|
32
|
+
- **Verb-first**: “Add…”, “Refactor…”, “Verify…”, “Ship…”.
|
|
33
|
+
- Include at least one item for **tests/validation** and one for **edge cases/risk** when applicable.
|
|
34
|
+
- If there are unknowns, include a tiny **Open questions** section (max 3).
|
|
35
|
+
|
|
36
|
+
4. **Write the plan to `plan.md` in the current working directory**
|
|
37
|
+
- Use the Write tool to save the plan to `./plan.md`
|
|
38
|
+
- If `plan.md` already exists, overwrite it with the new plan
|
|
39
|
+
|
|
40
|
+
5. **Do not preface the plan with meta explanations; output only the plan as per template**
|
|
41
|
+
|
|
42
|
+
## Plan template (follow exactly)
|
|
43
|
+
|
|
44
|
+
```markdown
|
|
45
|
+
# Plan
|
|
46
|
+
|
|
47
|
+
<1–3 sentences: what we’re doing, why, and the high-level approach.>
|
|
48
|
+
|
|
49
|
+
## Scope
|
|
50
|
+
- In:
|
|
51
|
+
- Out:
|
|
52
|
+
|
|
53
|
+
## Action items
|
|
54
|
+
[ ] <Step 1>
|
|
55
|
+
[ ] <Step 2>
|
|
56
|
+
[ ] <Step 3>
|
|
57
|
+
[ ] <Step 4>
|
|
58
|
+
[ ] <Step 5>
|
|
59
|
+
[ ] <Step 6>
|
|
60
|
+
|
|
61
|
+
## Open questions
|
|
62
|
+
- <Question 1>
|
|
63
|
+
- <Question 2>
|
|
64
|
+
- <Question 3>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Checklist item guidance
|
|
68
|
+
Good checklist items:
|
|
69
|
+
- Point to likely files/modules: src/..., app/..., services/...
|
|
70
|
+
- Name concrete validation: “Run npm test”, “Add unit tests for X”
|
|
71
|
+
- Include safe rollout when relevant: feature flag, migration plan, rollback note
|
|
72
|
+
|
|
73
|
+
Avoid:
|
|
74
|
+
- Vague steps (“handle backend”, “do auth”)
|
|
75
|
+
- Too many micro-steps
|
|
76
|
+
- Writing code snippets (keep the plan implementation-agnostic)
|
klaude_code/skill/loader.py
CHANGED
|
@@ -11,7 +11,7 @@ from contextlib import contextmanager
|
|
|
11
11
|
from importlib import resources
|
|
12
12
|
from pathlib import Path
|
|
13
13
|
|
|
14
|
-
from klaude_code.
|
|
14
|
+
from klaude_code.log import log_debug
|
|
15
15
|
|
|
16
16
|
# Marker file name for tracking installed skills version
|
|
17
17
|
SYSTEM_SKILLS_MARKER_FILENAME = ".klaude-system-skills.marker"
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Terminal (TUI) frontend for klaude-code.
|
|
2
|
+
|
|
3
|
+
This package contains all terminal-specific UI code (Rich rendering,
|
|
4
|
+
prompt-toolkit input, and terminal integrations).
|
|
5
|
+
|
|
6
|
+
The tui layer may depend on `klaude_code.ui`, but `klaude_code.ui` must not
|
|
7
|
+
depend on `klaude_code.tui`.
|
|
8
|
+
"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
1
|
from klaude_code.protocol import commands, message, op
|
|
3
2
|
|
|
3
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
class ClearCommand(CommandABC):
|
|
6
7
|
"""Clear current session and start a new conversation"""
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from klaude_code.
|
|
1
|
+
from klaude_code.log import DebugType, get_current_log_file, is_debug_enabled, set_debug_logging
|
|
2
2
|
from klaude_code.protocol import commands, events, message, model
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
4
5
|
|
|
5
6
|
|
|
6
7
|
def _format_status() -> str:
|
|
@@ -2,9 +2,10 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
6
5
|
from klaude_code.protocol import commands, message, op
|
|
7
6
|
|
|
7
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
class ExportCommand(CommandABC):
|
|
10
11
|
"""Export the current session into a standalone HTML transcript."""
|
|
@@ -9,10 +9,11 @@ from pathlib import Path
|
|
|
9
9
|
from rich.console import Console
|
|
10
10
|
from rich.text import Text
|
|
11
11
|
|
|
12
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
13
12
|
from klaude_code.protocol import commands, events, message, model
|
|
14
13
|
from klaude_code.session.export import build_export_html
|
|
15
14
|
|
|
15
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
16
|
+
|
|
16
17
|
|
|
17
18
|
class ExportOnlineCommand(CommandABC):
|
|
18
19
|
"""Export and deploy the current session to surge.sh as a static webpage."""
|
|
@@ -5,10 +5,11 @@ from typing import Literal
|
|
|
5
5
|
|
|
6
6
|
from prompt_toolkit.styles import Style
|
|
7
7
|
|
|
8
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
9
8
|
from klaude_code.protocol import commands, events, message, model
|
|
10
|
-
from klaude_code.
|
|
11
|
-
from klaude_code.
|
|
9
|
+
from klaude_code.tui.input.clipboard import copy_to_clipboard
|
|
10
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
11
|
+
|
|
12
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
12
13
|
|
|
13
14
|
FORK_SELECT_STYLE = Style(
|
|
14
15
|
[
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
1
|
from klaude_code.protocol import commands, events, message, model
|
|
3
2
|
|
|
3
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
class HelpCommand(CommandABC):
|
|
6
7
|
"""Display help information for all available slash commands."""
|
|
@@ -2,10 +2,11 @@ import asyncio
|
|
|
2
2
|
|
|
3
3
|
from prompt_toolkit.styles import Style
|
|
4
4
|
|
|
5
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
6
|
-
from klaude_code.command.model_select import select_model_interactive
|
|
7
5
|
from klaude_code.protocol import commands, events, message, model, op
|
|
8
|
-
from klaude_code.
|
|
6
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
7
|
+
|
|
8
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
9
|
+
from .model_select import select_model_interactive
|
|
9
10
|
|
|
10
11
|
SELECT_STYLE = Style(
|
|
11
12
|
[
|
|
@@ -4,7 +4,7 @@ import sys
|
|
|
4
4
|
|
|
5
5
|
from klaude_code.config.config import load_config
|
|
6
6
|
from klaude_code.config.select_model import match_model_from_config
|
|
7
|
-
from klaude_code.
|
|
7
|
+
from klaude_code.log import log
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
def select_model_interactive(preferred: str | None = None) -> str | None:
|
|
@@ -38,7 +38,7 @@ def select_model_interactive(preferred: str | None = None) -> str | None:
|
|
|
38
38
|
# Interactive selection
|
|
39
39
|
from prompt_toolkit.styles import Style
|
|
40
40
|
|
|
41
|
-
from klaude_code.
|
|
41
|
+
from klaude_code.tui.terminal.selector import build_model_select_items, select_one
|
|
42
42
|
|
|
43
43
|
config = load_config()
|
|
44
44
|
names = [m.model_name for m in result.filtered_models]
|
|
@@ -2,9 +2,10 @@ from importlib.resources import files
|
|
|
2
2
|
|
|
3
3
|
import yaml
|
|
4
4
|
|
|
5
|
-
from klaude_code.
|
|
5
|
+
from klaude_code.log import log_debug
|
|
6
6
|
from klaude_code.protocol import commands, message, op
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class PromptCommand(CommandABC):
|
|
@@ -30,7 +31,7 @@ class PromptCommand(CommandABC):
|
|
|
30
31
|
return
|
|
31
32
|
|
|
32
33
|
try:
|
|
33
|
-
raw_text = files("klaude_code.command").joinpath(self.template_name).read_text(encoding="utf-8")
|
|
34
|
+
raw_text = files("klaude_code.tui.command").joinpath(self.template_name).read_text(encoding="utf-8")
|
|
34
35
|
|
|
35
36
|
if raw_text.startswith("---"):
|
|
36
37
|
parts = raw_text.split("---", 2)
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
1
|
from klaude_code.protocol import commands, events, message
|
|
3
2
|
|
|
3
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
4
|
+
|
|
4
5
|
|
|
5
6
|
class RefreshTerminalCommand(CommandABC):
|
|
6
7
|
"""Refresh terminal display"""
|
|
@@ -26,6 +27,7 @@ class RefreshTerminalCommand(CommandABC):
|
|
|
26
27
|
return CommandResult(
|
|
27
28
|
events=[
|
|
28
29
|
events.WelcomeEvent(
|
|
30
|
+
session_id=agent.session.id,
|
|
29
31
|
work_dir=str(agent.session.work_dir),
|
|
30
32
|
llm_config=agent.get_llm_client().get_llm_config(),
|
|
31
33
|
),
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
from importlib.resources import files
|
|
2
2
|
from typing import TYPE_CHECKING
|
|
3
3
|
|
|
4
|
-
from klaude_code.
|
|
5
|
-
from klaude_code.command.prompt_command import PromptCommand
|
|
4
|
+
from klaude_code.log import log_debug
|
|
6
5
|
from klaude_code.protocol import commands, events, message, model, op
|
|
7
|
-
|
|
6
|
+
|
|
7
|
+
from .command_abc import Agent, CommandResult
|
|
8
|
+
from .prompt_command import PromptCommand
|
|
8
9
|
|
|
9
10
|
if TYPE_CHECKING:
|
|
10
11
|
from .command_abc import CommandABC
|
|
@@ -82,7 +83,7 @@ def register(cmd: "CommandABC") -> None:
|
|
|
82
83
|
def load_prompt_commands():
|
|
83
84
|
"""Dynamically load prompt-based commands from the command directory."""
|
|
84
85
|
try:
|
|
85
|
-
command_files = files("klaude_code.command").iterdir()
|
|
86
|
+
command_files = files("klaude_code.tui.command").iterdir()
|
|
86
87
|
for file_path in command_files:
|
|
87
88
|
name = file_path.name
|
|
88
89
|
if (name.startswith("prompt_") or name.startswith("prompt-")) and name.endswith(".md"):
|
|
@@ -94,7 +95,7 @@ def load_prompt_commands():
|
|
|
94
95
|
|
|
95
96
|
def _ensure_commands_loaded() -> None:
|
|
96
97
|
"""Ensure all commands are loaded (lazy initialization)."""
|
|
97
|
-
from klaude_code.command import ensure_commands_loaded
|
|
98
|
+
from klaude_code.tui.command import ensure_commands_loaded
|
|
98
99
|
|
|
99
100
|
ensure_commands_loaded()
|
|
100
101
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
from pathlib import Path
|
|
2
2
|
|
|
3
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
4
3
|
from klaude_code.protocol import commands, events, message, model
|
|
5
4
|
|
|
5
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
6
|
+
|
|
6
7
|
|
|
7
8
|
def _read_changelog() -> str:
|
|
8
9
|
"""Read CHANGELOG.md from project root."""
|
|
@@ -2,11 +2,12 @@ import asyncio
|
|
|
2
2
|
|
|
3
3
|
from prompt_toolkit.styles import Style
|
|
4
4
|
|
|
5
|
-
from klaude_code.
|
|
5
|
+
from klaude_code.log import log
|
|
6
6
|
from klaude_code.protocol import commands, events, message, model, op
|
|
7
7
|
from klaude_code.session.selector import build_session_select_options, format_user_messages_display
|
|
8
|
-
from klaude_code.
|
|
9
|
-
|
|
8
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
9
|
+
|
|
10
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
10
11
|
|
|
11
12
|
SESSION_SELECT_STYLE = Style(
|
|
12
13
|
[
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
2
1
|
from klaude_code.protocol import commands, events, message, model
|
|
3
2
|
from klaude_code.session.session import Session
|
|
4
3
|
|
|
4
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
5
|
+
|
|
5
6
|
|
|
6
7
|
class AggregatedUsage(model.BaseModel):
|
|
7
8
|
"""Aggregated usage statistics including per-model breakdown."""
|
|
@@ -2,9 +2,10 @@ import os
|
|
|
2
2
|
import subprocess
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
|
|
5
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
6
5
|
from klaude_code.protocol import commands, events, message, model
|
|
7
6
|
|
|
7
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
8
|
+
|
|
8
9
|
|
|
9
10
|
class TerminalSetupCommand(CommandABC):
|
|
10
11
|
"""Setup shift+enter newline functionality in terminal"""
|
|
@@ -2,10 +2,11 @@ import asyncio
|
|
|
2
2
|
|
|
3
3
|
from prompt_toolkit.styles import Style
|
|
4
4
|
|
|
5
|
-
from klaude_code.command.command_abc import Agent, CommandABC, CommandResult
|
|
6
5
|
from klaude_code.config.thinking import get_thinking_picker_data, parse_thinking_value
|
|
7
6
|
from klaude_code.protocol import commands, events, llm_param, message, model, op
|
|
8
|
-
from klaude_code.
|
|
7
|
+
from klaude_code.tui.terminal.selector import SelectItem, select_one
|
|
8
|
+
|
|
9
|
+
from .command_abc import Agent, CommandABC, CommandResult
|
|
9
10
|
|
|
10
11
|
SELECT_STYLE = Style(
|
|
11
12
|
[
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
|
|
5
|
+
from rich.console import RenderableType
|
|
6
|
+
from rich.text import Text
|
|
7
|
+
|
|
8
|
+
from klaude_code.protocol import events
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@dataclass(frozen=True, slots=True)
|
|
12
|
+
class RenderCommand:
|
|
13
|
+
pass
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True, slots=True)
|
|
17
|
+
class RenderReplayHistory(RenderCommand):
|
|
18
|
+
event: events.ReplayHistoryEvent
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(frozen=True, slots=True)
|
|
22
|
+
class RenderWelcome(RenderCommand):
|
|
23
|
+
event: events.WelcomeEvent
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@dataclass(frozen=True, slots=True)
|
|
27
|
+
class RenderUserMessage(RenderCommand):
|
|
28
|
+
event: events.UserMessageEvent
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@dataclass(frozen=True, slots=True)
|
|
32
|
+
class RenderTaskStart(RenderCommand):
|
|
33
|
+
event: events.TaskStartEvent
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@dataclass(frozen=True, slots=True)
|
|
37
|
+
class RenderDeveloperMessage(RenderCommand):
|
|
38
|
+
event: events.DeveloperMessageEvent
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
@dataclass(frozen=True, slots=True)
|
|
42
|
+
class RenderTurnStart(RenderCommand):
|
|
43
|
+
event: events.TurnStartEvent
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@dataclass(frozen=True, slots=True)
|
|
47
|
+
class RenderAssistantImage(RenderCommand):
|
|
48
|
+
session_id: str
|
|
49
|
+
file_path: str
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
@dataclass(frozen=True, slots=True)
|
|
53
|
+
class RenderToolCall(RenderCommand):
|
|
54
|
+
event: events.ToolCallEvent
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
@dataclass(frozen=True, slots=True)
|
|
58
|
+
class RenderToolResult(RenderCommand):
|
|
59
|
+
event: events.ToolResultEvent
|
|
60
|
+
is_sub_agent_session: bool
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
@dataclass(frozen=True, slots=True)
|
|
64
|
+
class RenderTaskMetadata(RenderCommand):
|
|
65
|
+
event: events.TaskMetadataEvent
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
@dataclass(frozen=True, slots=True)
|
|
69
|
+
class RenderTaskFinish(RenderCommand):
|
|
70
|
+
event: events.TaskFinishEvent
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclass(frozen=True, slots=True)
|
|
74
|
+
class RenderInterrupt(RenderCommand):
|
|
75
|
+
session_id: str
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
@dataclass(frozen=True, slots=True)
|
|
79
|
+
class RenderError(RenderCommand):
|
|
80
|
+
event: events.ErrorEvent
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@dataclass(frozen=True, slots=True)
|
|
84
|
+
class StartThinkingStream(RenderCommand):
|
|
85
|
+
session_id: str
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@dataclass(frozen=True, slots=True)
|
|
89
|
+
class AppendThinking(RenderCommand):
|
|
90
|
+
session_id: str
|
|
91
|
+
content: str
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
@dataclass(frozen=True, slots=True)
|
|
95
|
+
class EndThinkingStream(RenderCommand):
|
|
96
|
+
session_id: str
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@dataclass(frozen=True, slots=True)
|
|
100
|
+
class StartAssistantStream(RenderCommand):
|
|
101
|
+
session_id: str
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@dataclass(frozen=True, slots=True)
|
|
105
|
+
class AppendAssistant(RenderCommand):
|
|
106
|
+
session_id: str
|
|
107
|
+
content: str
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@dataclass(frozen=True, slots=True)
|
|
111
|
+
class EndAssistantStream(RenderCommand):
|
|
112
|
+
session_id: str
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
@dataclass(frozen=True, slots=True)
|
|
116
|
+
class RenderThinkingHeader(RenderCommand):
|
|
117
|
+
session_id: str
|
|
118
|
+
header: str
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
@dataclass(frozen=True, slots=True)
|
|
122
|
+
class SpinnerStart(RenderCommand):
|
|
123
|
+
pass
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
@dataclass(frozen=True, slots=True)
|
|
127
|
+
class SpinnerStop(RenderCommand):
|
|
128
|
+
pass
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
@dataclass(frozen=True, slots=True)
|
|
132
|
+
class SpinnerUpdate(RenderCommand):
|
|
133
|
+
status_text: str | Text
|
|
134
|
+
right_text: RenderableType | None
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
@dataclass(frozen=True, slots=True)
|
|
138
|
+
class PrintBlankLine(RenderCommand):
|
|
139
|
+
pass
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
@dataclass(frozen=True, slots=True)
|
|
143
|
+
class PrintRuleLine(RenderCommand):
|
|
144
|
+
pass
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
@dataclass(frozen=True, slots=True)
|
|
148
|
+
class EmitOsc94Error(RenderCommand):
|
|
149
|
+
pass
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
@dataclass(frozen=True, slots=True)
|
|
153
|
+
class EmitTmuxSignal(RenderCommand):
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
@dataclass(frozen=True, slots=True)
|
|
158
|
+
class TaskClockStart(RenderCommand):
|
|
159
|
+
pass
|
|
160
|
+
|
|
161
|
+
|
|
162
|
+
@dataclass(frozen=True, slots=True)
|
|
163
|
+
class TaskClockClear(RenderCommand):
|
|
164
|
+
pass
|
|
@@ -3,9 +3,9 @@ from rich.padding import Padding
|
|
|
3
3
|
from rich.text import Text
|
|
4
4
|
|
|
5
5
|
from klaude_code.const import MARKDOWN_RIGHT_MARGIN
|
|
6
|
-
from klaude_code.
|
|
7
|
-
from klaude_code.
|
|
8
|
-
from klaude_code.
|
|
6
|
+
from klaude_code.tui.components.common import create_grid
|
|
7
|
+
from klaude_code.tui.components.rich.markdown import NoInsetMarkdown
|
|
8
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
9
9
|
|
|
10
10
|
# UI markers
|
|
11
11
|
ASSISTANT_MESSAGE_MARK = "•"
|
|
@@ -8,8 +8,8 @@ from pygments.token import Token
|
|
|
8
8
|
from rich.text import Text
|
|
9
9
|
|
|
10
10
|
from klaude_code.const import BASH_MULTILINE_STRING_TRUNCATE_MAX_LINES
|
|
11
|
-
from klaude_code.
|
|
12
|
-
from klaude_code.
|
|
11
|
+
from klaude_code.tui.components.common import truncate_head
|
|
12
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
13
13
|
|
|
14
14
|
# Token types for bash syntax highlighting
|
|
15
15
|
_STRING_TOKENS = frozenset(
|
|
@@ -11,7 +11,7 @@ from klaude_code.const import (
|
|
|
11
11
|
TRUNCATE_DISPLAY_MAX_LINES,
|
|
12
12
|
TRUNCATE_HEAD_MAX_LINES,
|
|
13
13
|
)
|
|
14
|
-
from klaude_code.
|
|
14
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
15
15
|
|
|
16
16
|
|
|
17
17
|
def create_grid(*, overflow: Literal["fold", "crop", "ellipsis", "ignore"] = "fold") -> Table:
|
|
@@ -4,10 +4,10 @@ from rich.table import Table
|
|
|
4
4
|
from rich.text import Text
|
|
5
5
|
|
|
6
6
|
from klaude_code.protocol import commands, events, message, model
|
|
7
|
-
from klaude_code.
|
|
8
|
-
from klaude_code.
|
|
9
|
-
from klaude_code.
|
|
10
|
-
from klaude_code.
|
|
7
|
+
from klaude_code.tui.components.common import create_grid, truncate_middle
|
|
8
|
+
from klaude_code.tui.components.rich.markdown import NoInsetMarkdown
|
|
9
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
10
|
+
from klaude_code.tui.components.tools import render_path
|
|
11
11
|
|
|
12
12
|
REMINDER_BULLET = " ⧉"
|
|
13
13
|
|
|
@@ -6,8 +6,8 @@ from rich.text import Text
|
|
|
6
6
|
|
|
7
7
|
from klaude_code.const import DIFF_PREFIX_WIDTH, MAX_DIFF_LINES
|
|
8
8
|
from klaude_code.protocol import model
|
|
9
|
-
from klaude_code.
|
|
10
|
-
from klaude_code.
|
|
9
|
+
from klaude_code.tui.components.common import create_grid
|
|
10
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
def _make_diff_prefix(line: str, new_ln: int | None, width: int) -> tuple[str, int | None]:
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
from rich.console import RenderableType
|
|
2
2
|
from rich.text import Text
|
|
3
3
|
|
|
4
|
-
from klaude_code.
|
|
5
|
-
from klaude_code.
|
|
4
|
+
from klaude_code.tui.components.common import create_grid
|
|
5
|
+
from klaude_code.tui.components.rich.theme import ThemeKey
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def render_error(error_msg: Text) -> RenderableType:
|