klaude-code 2.0.2__py3-none-any.whl → 2.1.1__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.
Files changed (157) hide show
  1. klaude_code/app/__init__.py +12 -0
  2. klaude_code/app/runtime.py +215 -0
  3. klaude_code/cli/auth_cmd.py +2 -2
  4. klaude_code/cli/config_cmd.py +2 -2
  5. klaude_code/cli/cost_cmd.py +1 -1
  6. klaude_code/cli/debug.py +12 -36
  7. klaude_code/cli/list_model.py +3 -3
  8. klaude_code/cli/main.py +17 -60
  9. klaude_code/cli/self_update.py +2 -187
  10. klaude_code/cli/session_cmd.py +2 -2
  11. klaude_code/config/config.py +1 -1
  12. klaude_code/config/select_model.py +1 -1
  13. klaude_code/const.py +9 -1
  14. klaude_code/core/agent.py +9 -62
  15. klaude_code/core/agent_profile.py +291 -0
  16. klaude_code/core/executor.py +335 -230
  17. klaude_code/core/manager/llm_clients_builder.py +1 -1
  18. klaude_code/core/manager/sub_agent_manager.py +16 -29
  19. klaude_code/core/reminders.py +84 -103
  20. klaude_code/core/task.py +12 -20
  21. klaude_code/core/tool/__init__.py +5 -19
  22. klaude_code/core/tool/context.py +84 -0
  23. klaude_code/core/tool/file/apply_patch_tool.py +18 -21
  24. klaude_code/core/tool/file/edit_tool.py +39 -42
  25. klaude_code/core/tool/file/read_tool.py +14 -9
  26. klaude_code/core/tool/file/write_tool.py +12 -13
  27. klaude_code/core/tool/report_back_tool.py +4 -1
  28. klaude_code/core/tool/shell/bash_tool.py +6 -11
  29. klaude_code/core/tool/sub_agent_tool.py +8 -7
  30. klaude_code/core/tool/todo/todo_write_tool.py +3 -9
  31. klaude_code/core/tool/todo/update_plan_tool.py +3 -5
  32. klaude_code/core/tool/tool_abc.py +2 -1
  33. klaude_code/core/tool/tool_registry.py +2 -33
  34. klaude_code/core/tool/tool_runner.py +13 -10
  35. klaude_code/core/tool/web/mermaid_tool.py +3 -1
  36. klaude_code/core/tool/web/web_fetch_tool.py +5 -3
  37. klaude_code/core/tool/web/web_search_tool.py +5 -3
  38. klaude_code/core/turn.py +87 -30
  39. klaude_code/llm/anthropic/client.py +1 -1
  40. klaude_code/llm/bedrock/client.py +1 -1
  41. klaude_code/llm/claude/client.py +1 -1
  42. klaude_code/llm/codex/client.py +1 -1
  43. klaude_code/llm/google/client.py +1 -1
  44. klaude_code/llm/openai_compatible/client.py +1 -1
  45. klaude_code/llm/openai_compatible/tool_call_accumulator.py +1 -1
  46. klaude_code/llm/openrouter/client.py +1 -1
  47. klaude_code/llm/openrouter/reasoning.py +1 -1
  48. klaude_code/llm/responses/client.py +1 -1
  49. klaude_code/protocol/commands.py +1 -0
  50. klaude_code/protocol/events/__init__.py +57 -0
  51. klaude_code/protocol/events/base.py +18 -0
  52. klaude_code/protocol/events/chat.py +20 -0
  53. klaude_code/protocol/events/lifecycle.py +22 -0
  54. klaude_code/protocol/events/metadata.py +15 -0
  55. klaude_code/protocol/events/streaming.py +43 -0
  56. klaude_code/protocol/events/system.py +53 -0
  57. klaude_code/protocol/events/tools.py +27 -0
  58. klaude_code/protocol/op.py +5 -0
  59. klaude_code/protocol/tools.py +0 -1
  60. klaude_code/session/session.py +6 -7
  61. klaude_code/skill/assets/create-plan/SKILL.md +76 -0
  62. klaude_code/skill/loader.py +32 -88
  63. klaude_code/skill/manager.py +38 -0
  64. klaude_code/skill/system_skills.py +1 -1
  65. klaude_code/tui/__init__.py +8 -0
  66. klaude_code/{command → tui/command}/__init__.py +3 -0
  67. klaude_code/{command → tui/command}/clear_cmd.py +2 -1
  68. klaude_code/tui/command/copy_cmd.py +53 -0
  69. klaude_code/{command → tui/command}/debug_cmd.py +3 -2
  70. klaude_code/{command → tui/command}/export_cmd.py +2 -1
  71. klaude_code/{command → tui/command}/export_online_cmd.py +2 -1
  72. klaude_code/{command → tui/command}/fork_session_cmd.py +4 -3
  73. klaude_code/{command → tui/command}/help_cmd.py +2 -1
  74. klaude_code/{command → tui/command}/model_cmd.py +4 -3
  75. klaude_code/{command → tui/command}/model_select.py +2 -2
  76. klaude_code/{command → tui/command}/prompt_command.py +4 -3
  77. klaude_code/{command → tui/command}/refresh_cmd.py +3 -1
  78. klaude_code/{command → tui/command}/registry.py +6 -5
  79. klaude_code/{command → tui/command}/release_notes_cmd.py +2 -1
  80. klaude_code/{command → tui/command}/resume_cmd.py +4 -3
  81. klaude_code/{command → tui/command}/status_cmd.py +2 -1
  82. klaude_code/{command → tui/command}/terminal_setup_cmd.py +2 -1
  83. klaude_code/{command → tui/command}/thinking_cmd.py +3 -2
  84. klaude_code/tui/commands.py +164 -0
  85. klaude_code/{ui/renderers → tui/components}/assistant.py +3 -3
  86. klaude_code/{ui/renderers → tui/components}/bash_syntax.py +2 -2
  87. klaude_code/{ui/renderers → tui/components}/common.py +1 -1
  88. klaude_code/{ui/renderers → tui/components}/developer.py +4 -4
  89. klaude_code/{ui/renderers → tui/components}/diffs.py +2 -2
  90. klaude_code/{ui/renderers → tui/components}/errors.py +2 -2
  91. klaude_code/{ui/renderers → tui/components}/metadata.py +7 -7
  92. klaude_code/{ui → tui/components}/rich/markdown.py +9 -23
  93. klaude_code/{ui → tui/components}/rich/status.py +2 -2
  94. klaude_code/{ui → tui/components}/rich/theme.py +3 -1
  95. klaude_code/{ui/renderers → tui/components}/sub_agent.py +23 -43
  96. klaude_code/{ui/renderers → tui/components}/thinking.py +3 -3
  97. klaude_code/{ui/renderers → tui/components}/tools.py +13 -17
  98. klaude_code/{ui/renderers → tui/components}/user_input.py +3 -20
  99. klaude_code/tui/display.py +85 -0
  100. klaude_code/{ui/modes/repl → tui/input}/__init__.py +1 -1
  101. klaude_code/{ui/modes/repl → tui/input}/completers.py +1 -1
  102. klaude_code/{ui/modes/repl/input_prompt_toolkit.py → tui/input/prompt_toolkit.py} +6 -6
  103. klaude_code/tui/machine.py +608 -0
  104. klaude_code/tui/renderer.py +707 -0
  105. klaude_code/tui/runner.py +321 -0
  106. klaude_code/tui/terminal/__init__.py +56 -0
  107. klaude_code/{ui → tui}/terminal/color.py +1 -1
  108. klaude_code/{ui → tui}/terminal/control.py +1 -1
  109. klaude_code/{ui → tui}/terminal/notifier.py +1 -1
  110. klaude_code/ui/__init__.py +6 -50
  111. klaude_code/ui/core/display.py +3 -3
  112. klaude_code/ui/core/input.py +2 -1
  113. klaude_code/ui/{modes/debug/display.py → debug_mode.py} +1 -1
  114. klaude_code/ui/{modes/exec/display.py → exec_mode.py} +0 -2
  115. klaude_code/ui/terminal/__init__.py +6 -54
  116. klaude_code/ui/terminal/title.py +31 -0
  117. klaude_code/update.py +163 -0
  118. {klaude_code-2.0.2.dist-info → klaude_code-2.1.1.dist-info}/METADATA +1 -1
  119. klaude_code-2.1.1.dist-info/RECORD +233 -0
  120. klaude_code/cli/runtime.py +0 -518
  121. klaude_code/core/prompt.py +0 -108
  122. klaude_code/core/tool/skill/skill_tool.md +0 -24
  123. klaude_code/core/tool/skill/skill_tool.py +0 -87
  124. klaude_code/core/tool/tool_context.py +0 -148
  125. klaude_code/protocol/events.py +0 -195
  126. klaude_code/skill/assets/dev-docs/SKILL.md +0 -108
  127. klaude_code/trace/__init__.py +0 -21
  128. klaude_code/ui/core/stage_manager.py +0 -48
  129. klaude_code/ui/modes/__init__.py +0 -1
  130. klaude_code/ui/modes/debug/__init__.py +0 -1
  131. klaude_code/ui/modes/exec/__init__.py +0 -1
  132. klaude_code/ui/modes/repl/display.py +0 -61
  133. klaude_code/ui/modes/repl/event_handler.py +0 -629
  134. klaude_code/ui/modes/repl/renderer.py +0 -464
  135. klaude_code/ui/renderers/__init__.py +0 -0
  136. klaude_code/ui/utils/__init__.py +0 -1
  137. klaude_code-2.0.2.dist-info/RECORD +0 -227
  138. /klaude_code/{trace/log.py → log.py} +0 -0
  139. /klaude_code/{command → tui/command}/command_abc.py +0 -0
  140. /klaude_code/{command → tui/command}/prompt-commit.md +0 -0
  141. /klaude_code/{command → tui/command}/prompt-init.md +0 -0
  142. /klaude_code/{core/tool/skill → tui/components}/__init__.py +0 -0
  143. /klaude_code/{ui/renderers → tui/components}/mermaid_viewer.py +0 -0
  144. /klaude_code/{ui → tui/components}/rich/__init__.py +0 -0
  145. /klaude_code/{ui → tui/components}/rich/cjk_wrap.py +0 -0
  146. /klaude_code/{ui → tui/components}/rich/code_panel.py +0 -0
  147. /klaude_code/{ui → tui/components}/rich/live.py +0 -0
  148. /klaude_code/{ui → tui/components}/rich/quote.py +0 -0
  149. /klaude_code/{ui → tui/components}/rich/searchable_text.py +0 -0
  150. /klaude_code/{ui/modes/repl → tui/input}/clipboard.py +0 -0
  151. /klaude_code/{ui/modes/repl → tui/input}/key_bindings.py +0 -0
  152. /klaude_code/{ui → tui}/terminal/image.py +0 -0
  153. /klaude_code/{ui → tui}/terminal/progress_bar.py +0 -0
  154. /klaude_code/{ui → tui}/terminal/selector.py +0 -0
  155. /klaude_code/ui/{utils/common.py → common.py} +0 -0
  156. {klaude_code-2.0.2.dist-info → klaude_code-2.1.1.dist-info}/WHEEL +0 -0
  157. {klaude_code-2.0.2.dist-info → klaude_code-2.1.1.dist-info}/entry_points.txt +0 -0
@@ -1,87 +0,0 @@
1
- """SkillTool - Tool for agent to activate and load skills."""
2
-
3
- from pathlib import Path
4
-
5
- from pydantic import BaseModel
6
-
7
- from klaude_code.core.tool.tool_abc import ToolABC, load_desc
8
- from klaude_code.core.tool.tool_registry import register
9
- from klaude_code.protocol import llm_param, message, tools
10
- from klaude_code.skill import get_available_skills, get_skill, list_skill_names
11
-
12
-
13
- @register(tools.SKILL)
14
- class SkillTool(ToolABC):
15
- """Tool to execute/load a skill within the main conversation."""
16
-
17
- @classmethod
18
- def schema(cls) -> llm_param.ToolSchema:
19
- """Generate schema with embedded available skills metadata."""
20
- skills_xml = cls._generate_skills_xml()
21
-
22
- return llm_param.ToolSchema(
23
- name=tools.SKILL,
24
- type="function",
25
- description=load_desc(Path(__file__).parent / "skill_tool.md", {"skills_xml": skills_xml}),
26
- parameters={
27
- "type": "object",
28
- "properties": {
29
- "command": {
30
- "type": "string",
31
- "description": "Name of the skill to execute",
32
- }
33
- },
34
- "required": ["command"],
35
- },
36
- )
37
-
38
- @classmethod
39
- def _generate_skills_xml(cls) -> str:
40
- """Generate XML format skills metadata."""
41
- skills = get_available_skills()
42
- if not skills:
43
- return ""
44
-
45
- xml_parts: list[str] = []
46
- for name, description, location in skills:
47
- xml_parts.append(f"""<skill>
48
- <name>{name}</name>
49
- <description>{description}</description>
50
- <location>{location}</location>
51
- </skill>""")
52
- return "\n".join(xml_parts)
53
-
54
- class SkillArguments(BaseModel):
55
- command: str
56
-
57
- @classmethod
58
- async def call(cls, arguments: str) -> message.ToolResultMessage:
59
- """Load and return full skill content."""
60
- try:
61
- args = cls.SkillArguments.model_validate_json(arguments)
62
- except ValueError as e:
63
- return message.ToolResultMessage(
64
- status="error",
65
- output_text=f"Invalid arguments: {e}",
66
- )
67
-
68
- skill = get_skill(args.command)
69
-
70
- if not skill:
71
- available = ", ".join(list_skill_names())
72
- return message.ToolResultMessage(
73
- status="error",
74
- output_text=f"Skill '{args.command}' does not exist. Available skills: {available}",
75
- )
76
-
77
- # Get base directory from skill_path
78
- base_dir = str(skill.skill_path.parent) if skill.skill_path else "unknown"
79
-
80
- # Return with loading message format
81
- result = f"""<command-message>The "{skill.name}" skill is activated</command-message>
82
- <command-name>{skill.name}</command-name>
83
-
84
- Base directory for this skill: {base_dir}
85
-
86
- {skill.to_prompt()}"""
87
- return message.ToolResultMessage(status="success", output_text=result)
@@ -1,148 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Awaitable, Callable, Generator, MutableMapping
4
- from contextlib import contextmanager
5
- from contextvars import ContextVar, Token
6
- from dataclasses import dataclass
7
-
8
- from klaude_code.protocol import model
9
- from klaude_code.protocol.sub_agent import SubAgentResult
10
- from klaude_code.session.session import Session
11
-
12
- type FileTracker = MutableMapping[str, model.FileStatus]
13
-
14
-
15
- @dataclass
16
- class TodoContext:
17
- """Todo access interface exposed to tools.
18
-
19
- Tools can only read the current todo list and replace it with
20
- a new list; they cannot access the full Session object.
21
- """
22
-
23
- get_todos: Callable[[], list[model.TodoItem]]
24
- set_todos: Callable[[list[model.TodoItem]], None]
25
-
26
-
27
- @dataclass
28
- class SessionTodoStore:
29
- """Adapter exposing session todos through an explicit interface."""
30
-
31
- session: Session
32
-
33
- def get(self) -> list[model.TodoItem]:
34
- return self.session.todos
35
-
36
- def set(self, todos: list[model.TodoItem]) -> None:
37
- self.session.todos = todos
38
-
39
-
40
- @dataclass
41
- class ToolContextToken:
42
- """Tokens used to restore tool execution context.
43
-
44
- This captures the contextvar tokens for the current file tracker
45
- and todo context so callers can safely reset them after a tool
46
- finishes running.
47
- """
48
-
49
- file_tracker_token: Token[FileTracker | None] | None
50
- todo_token: Token[TodoContext | None] | None
51
-
52
-
53
- # Holds the current file tracker mapping for tool execution context.
54
- # Set by Agent/Reminder right before invoking a tool.
55
- current_file_tracker_var: ContextVar[FileTracker | None] = ContextVar("current_file_tracker", default=None)
56
-
57
-
58
- # Holds the todo access context for tools.
59
- current_todo_context_var: ContextVar[TodoContext | None] = ContextVar("current_todo_context", default=None)
60
-
61
-
62
- def set_tool_context_from_session(session: Session) -> ToolContextToken:
63
- """Bind the given session's file tracker and todos into tool context.
64
-
65
- This should be called by the Agent or reminder helpers immediately
66
- before invoking tools so that file and todo tools can operate on
67
- the correct per-session state without seeing the full Session.
68
- """
69
-
70
- file_tracker_token = current_file_tracker_var.set(session.file_tracker)
71
- todo_ctx = build_todo_context(session)
72
- todo_token = current_todo_context_var.set(todo_ctx)
73
- return ToolContextToken(file_tracker_token=file_tracker_token, todo_token=todo_token)
74
-
75
-
76
- def reset_tool_context(token: ToolContextToken) -> None:
77
- """Restore tool execution context from a previously captured token."""
78
-
79
- if token.file_tracker_token is not None:
80
- current_file_tracker_var.reset(token.file_tracker_token)
81
- if token.todo_token is not None:
82
- current_todo_context_var.reset(token.todo_token)
83
-
84
-
85
- @contextmanager
86
- def tool_context(file_tracker: FileTracker, todo_ctx: TodoContext) -> Generator[ToolContextToken]:
87
- """Context manager for setting and resetting tool execution context."""
88
-
89
- file_tracker_token = current_file_tracker_var.set(file_tracker)
90
- todo_token = current_todo_context_var.set(todo_ctx)
91
- token = ToolContextToken(file_tracker_token=file_tracker_token, todo_token=todo_token)
92
- try:
93
- yield token
94
- finally:
95
- reset_tool_context(token)
96
-
97
-
98
- def build_todo_context(session: Session) -> TodoContext:
99
- """Create a TodoContext backed by the given session."""
100
-
101
- store = SessionTodoStore(session)
102
- return TodoContext(get_todos=store.get, set_todos=store.set)
103
-
104
-
105
- def get_current_file_tracker() -> FileTracker | None:
106
- """Return the current file tracker mapping for this tool context."""
107
-
108
- return current_file_tracker_var.get()
109
-
110
-
111
- def get_current_todo_context() -> TodoContext | None:
112
- """Return the current todo access context for this tool context."""
113
-
114
- return current_todo_context_var.get()
115
-
116
-
117
- # Holds a handle to run a nested subtask (sub-agent) from within a tool call.
118
- # The callable takes a model.SubAgentState and returns a SubAgentResult.
119
- current_run_subtask_callback: ContextVar[Callable[[model.SubAgentState], Awaitable[SubAgentResult]] | None] = (
120
- ContextVar("current_run_subtask_callback", default=None)
121
- )
122
-
123
-
124
- # Allows sub-agent execution to record the created/used session id for the currently
125
- # executing tool call (used by ToolExecutor.cancel() to include session_id in UIExtra).
126
- current_sub_agent_session_id_recorder: ContextVar[Callable[[str], None] | None] = ContextVar(
127
- "current_sub_agent_session_id_recorder",
128
- default=None,
129
- )
130
-
131
-
132
- def record_sub_agent_session_id(session_id: str) -> None:
133
- """Record the sub-agent session id for the current tool call, if supported."""
134
-
135
- recorder = current_sub_agent_session_id_recorder.get()
136
- if recorder is None:
137
- return
138
- recorder(session_id)
139
-
140
-
141
- # Tracks sub-agent resume claims for the current turn.
142
- #
143
- # This is used to reject multiple sub-agent tool calls in the same LLM response
144
- # that attempt to resume the same agent ID.
145
- current_sub_agent_resume_claims: ContextVar[set[str] | None] = ContextVar(
146
- "current_sub_agent_resume_claims",
147
- default=None,
148
- )
@@ -1,195 +0,0 @@
1
- from typing import Literal
2
-
3
- from pydantic import BaseModel
4
-
5
- from klaude_code.protocol import llm_param, message, model
6
-
7
- """
8
- Event is how Agent Executor and UI Display communicate.
9
- """
10
-
11
-
12
- class EndEvent(BaseModel):
13
- pass
14
-
15
-
16
- class ErrorEvent(BaseModel):
17
- error_message: str
18
- can_retry: bool = False
19
- session_id: str | None = None
20
-
21
-
22
- class TaskStartEvent(BaseModel):
23
- session_id: str
24
- sub_agent_state: model.SubAgentState | None = None
25
-
26
-
27
- class TaskFinishEvent(BaseModel):
28
- session_id: str
29
- task_result: str
30
- has_structured_output: bool = False
31
-
32
-
33
- class TurnStartEvent(BaseModel):
34
- """For now, this event is used for UI to flush developer message buffer and print an empty line"""
35
-
36
- session_id: str
37
-
38
-
39
- class TurnEndEvent(BaseModel):
40
- session_id: str
41
-
42
-
43
- class TurnToolCallStartEvent(BaseModel):
44
- """For UI changing status text"""
45
-
46
- session_id: str
47
- response_id: str | None = None
48
- tool_call_id: str
49
- tool_name: str
50
- arguments: str
51
-
52
-
53
- class ThinkingDeltaEvent(BaseModel):
54
- session_id: str
55
- response_id: str | None = None
56
- content: str
57
-
58
-
59
- class AssistantTextDeltaEvent(BaseModel):
60
- session_id: str
61
- response_id: str | None = None
62
- content: str
63
-
64
-
65
- class AssistantImageDeltaEvent(BaseModel):
66
- session_id: str
67
- response_id: str | None = None
68
- file_path: str
69
-
70
-
71
- class AssistantMessageEvent(BaseModel):
72
- response_id: str | None = None
73
- session_id: str
74
- content: str
75
- thinking_text: str | None = None
76
-
77
-
78
- class DeveloperMessageEvent(BaseModel):
79
- """DeveloperMessages are reminders in user messages or tool results, see: core/reminders.py"""
80
-
81
- session_id: str
82
- item: message.DeveloperMessage
83
-
84
-
85
- class ToolCallEvent(BaseModel):
86
- session_id: str
87
- response_id: str | None = None
88
- tool_call_id: str
89
- tool_name: str
90
- arguments: str
91
-
92
-
93
- class ToolResultEvent(BaseModel):
94
- session_id: str
95
- response_id: str | None = None
96
- tool_call_id: str
97
- tool_name: str
98
- result: str
99
- ui_extra: model.ToolResultUIExtra | None = None
100
- status: Literal["success", "error"]
101
- task_metadata: model.TaskMetadata | None = None # Sub-agent task metadata
102
- # Whether this tool result is the last one emitted in the current turn.
103
- # Used by UI renderers to close tree-style prefixes.
104
- is_last_in_turn: bool = True
105
-
106
-
107
- class ResponseMetadataEvent(BaseModel):
108
- """Internal event for turn-level metadata. Not exposed to UI directly."""
109
-
110
- session_id: str
111
- metadata: model.Usage
112
-
113
-
114
- class TaskMetadataEvent(BaseModel):
115
- """Task-level aggregated metadata for UI display."""
116
-
117
- session_id: str
118
- metadata: model.TaskMetadataItem
119
-
120
-
121
- class UserMessageEvent(BaseModel):
122
- session_id: str
123
- content: str
124
- images: list[message.ImageURLPart] | None = None
125
-
126
-
127
- class WelcomeEvent(BaseModel):
128
- work_dir: str
129
- llm_config: llm_param.LLMConfigParameter
130
- show_klaude_code_info: bool = True
131
-
132
-
133
- class InterruptEvent(BaseModel):
134
- session_id: str
135
-
136
-
137
- class TodoChangeEvent(BaseModel):
138
- session_id: str
139
- todos: list[model.TodoItem]
140
-
141
-
142
- class ContextUsageEvent(BaseModel):
143
- """Real-time context usage update during task execution."""
144
-
145
- session_id: str
146
- context_percent: float # Context usage percentage (0-100)
147
-
148
-
149
- HistoryItemEvent = (
150
- TaskStartEvent
151
- | TaskFinishEvent
152
- | TurnStartEvent # This event is used for UI to print new empty line
153
- | AssistantImageDeltaEvent
154
- | AssistantMessageEvent
155
- | ToolCallEvent
156
- | ToolResultEvent
157
- | UserMessageEvent
158
- | TaskMetadataEvent
159
- | InterruptEvent
160
- | DeveloperMessageEvent
161
- | ErrorEvent
162
- )
163
-
164
-
165
- class ReplayHistoryEvent(BaseModel):
166
- session_id: str
167
- events: list[HistoryItemEvent]
168
- updated_at: float
169
- is_load: bool = True
170
-
171
-
172
- Event = (
173
- TaskStartEvent
174
- | TaskFinishEvent
175
- | ThinkingDeltaEvent
176
- | AssistantTextDeltaEvent
177
- | AssistantImageDeltaEvent
178
- | AssistantMessageEvent
179
- | ToolCallEvent
180
- | ToolResultEvent
181
- | ResponseMetadataEvent
182
- | TaskMetadataEvent
183
- | ReplayHistoryEvent
184
- | ErrorEvent
185
- | EndEvent
186
- | WelcomeEvent
187
- | UserMessageEvent
188
- | InterruptEvent
189
- | DeveloperMessageEvent
190
- | TodoChangeEvent
191
- | TurnStartEvent
192
- | TurnEndEvent
193
- | TurnToolCallStartEvent
194
- | ContextUsageEvent
195
- )
@@ -1,108 +0,0 @@
1
- ---
2
- name: dev-docs
3
- description: Manage development documentation for complex tasks. Use this skill when users want to create a strategic plan with structured task breakdown, or update development documentation before context compaction/reset. Triggers include "create a plan", "dev docs", "update docs before context reset", "context limit approaching".
4
- metadata:
5
- short-description: Create and update development documentation
6
- ---
7
-
8
- # Dev Docs
9
-
10
- Manage development documentation for complex, multi-phase tasks. This skill supports two workflows:
11
- 1. **Create**: Generate a comprehensive strategic plan with structured task breakdown
12
- 2. **Update**: Update documentation before context compaction or reset
13
-
14
- ## Create Development Plan
15
-
16
- When creating a new plan:
17
-
18
- 1. **Analyze the request** and determine the scope of planning needed
19
- 2. **Examine relevant files** in the codebase to understand current state
20
- 3. **Create a structured plan** with:
21
- - Executive Summary
22
- - Current State Analysis
23
- - Proposed Future State
24
- - Implementation Phases (broken into sections)
25
- - Detailed Tasks (actionable items with clear acceptance criteria)
26
- - Risk Assessment and Mitigation Strategies
27
- - Success Metrics
28
- - Required Resources and Dependencies
29
-
30
- 4. **Task Breakdown Structure**:
31
- - Each major section represents a phase or component
32
- - Number and prioritize tasks within sections
33
- - Include clear acceptance criteria for each task
34
- - Specify dependencies between tasks
35
- - Estimate effort levels (S/M/L/XL)
36
-
37
- 5. **Create task management structure**:
38
- - Create directory: `dev/active/[task-name]/` (relative to project root)
39
- - Generate three files:
40
- - `[task-name]-plan.md` - The comprehensive plan
41
- - `[task-name]-context.md` - Key files, decisions, dependencies
42
- - `[task-name]-tasks.md` - Checklist format for tracking progress
43
- - Include "Last Updated: YYYY-MM-DD" in each file
44
-
45
- 6. **Stop and Consult**: Pause and negotiate the plan with the user.
46
-
47
- ### Quality Standards
48
-
49
- - Plans must be self-contained with all necessary context
50
- - Use clear, actionable language
51
- - Include specific technical details where relevant
52
- - Consider both technical and business perspectives
53
- - Account for potential risks and edge cases
54
-
55
- ## Update Development Documentation
56
-
57
- When approaching context limits or before context reset:
58
-
59
- ### 1. Update Active Task Documentation
60
-
61
- For each task in `/dev/active/`:
62
-
63
- Update `[task-name]-context.md` with:
64
- - Current implementation state
65
- - Key decisions made this session
66
- - Files modified and why
67
- - Any blockers or issues discovered
68
- - Next immediate steps
69
- - Last Updated timestamp
70
-
71
- Update `[task-name]-tasks.md` with:
72
- - Mark completed tasks with checkmark
73
- - Add any new tasks discovered
74
- - Update in-progress tasks with current status
75
- - Reorder priorities if needed
76
-
77
- ### 2. Capture Session Context
78
-
79
- Include any relevant information about:
80
- - Complex problems solved
81
- - Architectural decisions made
82
- - Tricky bugs found and fixed
83
- - Integration points discovered
84
- - Testing approaches used
85
- - Performance optimizations made
86
-
87
- ### 3. Update Memory (if applicable)
88
-
89
- - Store any new patterns or solutions in project memory/documentation
90
- - Update entity relationships discovered
91
- - Add observations about system behavior
92
-
93
- ### 4. Document Unfinished Work
94
-
95
- - What was being worked on when context limit approached
96
- - Exact state of any partially completed features
97
- - Commands that need to be run on restart
98
- - Any temporary workarounds that need permanent fixes
99
-
100
- ### 5. Create Handoff Notes
101
-
102
- If switching to a new conversation:
103
- - Exact file and line being edited
104
- - The goal of current changes
105
- - Any uncommitted changes that need attention
106
- - Test commands to verify work
107
-
108
- **Priority**: Focus on capturing information that would be hard to rediscover or reconstruct from code alone.
@@ -1,21 +0,0 @@
1
- from .log import (
2
- DebugType,
3
- get_current_log_file,
4
- is_debug_enabled,
5
- log,
6
- log_debug,
7
- logger,
8
- prepare_debug_log_file,
9
- set_debug_logging,
10
- )
11
-
12
- __all__ = [
13
- "DebugType",
14
- "get_current_log_file",
15
- "is_debug_enabled",
16
- "log",
17
- "log_debug",
18
- "logger",
19
- "prepare_debug_log_file",
20
- "set_debug_logging",
21
- ]
@@ -1,48 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from collections.abc import Awaitable, Callable
4
- from enum import Enum
5
-
6
-
7
- class Stage(Enum):
8
- WAITING = "waiting"
9
- THINKING = "thinking"
10
- ASSISTANT = "assistant"
11
- TOOL_CALL = "tool_call"
12
- TOOL_RESULT = "tool_result"
13
-
14
-
15
- class StageManager:
16
- """Manage display stage transitions and invoke lifecycle callbacks."""
17
-
18
- def __init__(
19
- self,
20
- *,
21
- finish_assistant: Callable[[], Awaitable[None]],
22
- finish_thinking: Callable[[], Awaitable[None]],
23
- ):
24
- self._stage = Stage.WAITING
25
- self._finish_assistant = finish_assistant
26
- self._finish_thinking = finish_thinking
27
-
28
- @property
29
- def current_stage(self) -> Stage:
30
- return self._stage
31
-
32
- async def transition_to(self, new_stage: Stage) -> None:
33
- if self._stage == new_stage:
34
- return
35
- await self._leave_current_stage()
36
- self._stage = new_stage
37
-
38
- async def enter_thinking_stage(self) -> None:
39
- if self._stage == Stage.THINKING:
40
- return
41
- await self.transition_to(Stage.THINKING)
42
-
43
- async def _leave_current_stage(self) -> None:
44
- if self._stage == Stage.THINKING:
45
- await self._finish_thinking()
46
- elif self._stage == Stage.ASSISTANT:
47
- await self._finish_assistant()
48
- self._stage = Stage.WAITING
@@ -1 +0,0 @@
1
- # UI mode implementations
@@ -1 +0,0 @@
1
- # Debug mode
@@ -1 +0,0 @@
1
- # Exec mode
@@ -1,61 +0,0 @@
1
- from __future__ import annotations
2
-
3
- import contextlib
4
- from typing import override
5
-
6
- from klaude_code.protocol import events
7
- from klaude_code.ui.core.display import DisplayABC
8
- from klaude_code.ui.modes.repl.event_handler import DisplayEventHandler
9
- from klaude_code.ui.modes.repl.renderer import REPLRenderer
10
- from klaude_code.ui.terminal.notifier import TerminalNotifier
11
-
12
-
13
- class REPLDisplay(DisplayABC):
14
- """
15
- Interactive terminal display using Rich for rendering.
16
-
17
- REPLDisplay provides a full-featured terminal UI with:
18
- - Rich markdown rendering for assistant messages
19
- - Syntax-highlighted code blocks and diffs
20
- - Animated spinners for in-progress operations
21
- - Tool call and result visualization
22
- - OSC94 error indicator (for supported terminals)
23
- - Desktop notifications on task completion
24
-
25
- This is the primary display mode for interactive klaude-code sessions.
26
- For non-interactive use, see ExecDisplay. For debugging, wrap with
27
- DebugEventDisplay.
28
-
29
- Lifecycle:
30
- 1. start(): No-op (initialization happens in __init__)
31
- 2. consume_event(): Delegates to DisplayEventHandler for event processing
32
- 3. stop(): Stops the event handler and ensures spinner is cleaned up
33
-
34
- Attributes:
35
- renderer: The REPLRenderer instance for terminal output
36
- notifier: TerminalNotifier for desktop notifications
37
- event_handler: DisplayEventHandler that processes events
38
- """
39
-
40
- def __init__(self, theme: str | None = None, notifier: TerminalNotifier | None = None):
41
- self.renderer = REPLRenderer(theme)
42
- self.notifier = notifier or TerminalNotifier()
43
- self.event_handler = DisplayEventHandler(self.renderer, notifier=self.notifier)
44
-
45
- @override
46
- async def consume_event(self, event: events.Event) -> None:
47
- await self.event_handler.consume_event(event)
48
-
49
- @override
50
- async def start(self) -> None:
51
- pass
52
-
53
- @override
54
- async def stop(self) -> None:
55
- await self.event_handler.stop()
56
- # Ensure any active spinner is stopped so Rich restores the cursor.
57
- # Spinner may already be stopped or not started; ignore.
58
- with contextlib.suppress(Exception):
59
- self.renderer.spinner_stop()
60
- with contextlib.suppress(Exception):
61
- self.renderer.stop_bottom_live()