klaude-code 1.2.6__py3-none-any.whl → 1.8.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.
Files changed (205) hide show
  1. klaude_code/auth/__init__.py +24 -0
  2. klaude_code/auth/codex/__init__.py +20 -0
  3. klaude_code/auth/codex/exceptions.py +17 -0
  4. klaude_code/auth/codex/jwt_utils.py +45 -0
  5. klaude_code/auth/codex/oauth.py +229 -0
  6. klaude_code/auth/codex/token_manager.py +84 -0
  7. klaude_code/cli/auth_cmd.py +73 -0
  8. klaude_code/cli/config_cmd.py +91 -0
  9. klaude_code/cli/cost_cmd.py +338 -0
  10. klaude_code/cli/debug.py +78 -0
  11. klaude_code/cli/list_model.py +307 -0
  12. klaude_code/cli/main.py +233 -134
  13. klaude_code/cli/runtime.py +309 -117
  14. klaude_code/{version.py → cli/self_update.py} +114 -5
  15. klaude_code/cli/session_cmd.py +37 -21
  16. klaude_code/command/__init__.py +88 -27
  17. klaude_code/command/clear_cmd.py +8 -7
  18. klaude_code/command/command_abc.py +31 -31
  19. klaude_code/command/debug_cmd.py +79 -0
  20. klaude_code/command/export_cmd.py +19 -53
  21. klaude_code/command/export_online_cmd.py +154 -0
  22. klaude_code/command/fork_session_cmd.py +267 -0
  23. klaude_code/command/help_cmd.py +7 -8
  24. klaude_code/command/model_cmd.py +60 -10
  25. klaude_code/command/model_select.py +84 -0
  26. klaude_code/command/prompt-jj-describe.md +32 -0
  27. klaude_code/command/prompt_command.py +19 -11
  28. klaude_code/command/refresh_cmd.py +8 -10
  29. klaude_code/command/registry.py +139 -40
  30. klaude_code/command/release_notes_cmd.py +84 -0
  31. klaude_code/command/resume_cmd.py +111 -0
  32. klaude_code/command/status_cmd.py +104 -60
  33. klaude_code/command/terminal_setup_cmd.py +7 -9
  34. klaude_code/command/thinking_cmd.py +98 -0
  35. klaude_code/config/__init__.py +14 -6
  36. klaude_code/config/assets/__init__.py +1 -0
  37. klaude_code/config/assets/builtin_config.yaml +303 -0
  38. klaude_code/config/builtin_config.py +38 -0
  39. klaude_code/config/config.py +378 -109
  40. klaude_code/config/select_model.py +117 -53
  41. klaude_code/config/thinking.py +269 -0
  42. klaude_code/{const/__init__.py → const.py} +50 -19
  43. klaude_code/core/agent.py +20 -28
  44. klaude_code/core/executor.py +327 -112
  45. klaude_code/core/manager/__init__.py +2 -4
  46. klaude_code/core/manager/llm_clients.py +1 -15
  47. klaude_code/core/manager/llm_clients_builder.py +10 -11
  48. klaude_code/core/manager/sub_agent_manager.py +37 -6
  49. klaude_code/core/prompt.py +63 -44
  50. klaude_code/core/prompts/prompt-claude-code.md +2 -13
  51. klaude_code/core/prompts/prompt-codex-gpt-5-1-codex-max.md +117 -0
  52. klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +117 -0
  53. klaude_code/core/prompts/prompt-codex.md +9 -42
  54. klaude_code/core/prompts/prompt-minimal.md +12 -0
  55. klaude_code/core/prompts/{prompt-subagent-explore.md → prompt-sub-agent-explore.md} +16 -3
  56. klaude_code/core/prompts/{prompt-subagent-oracle.md → prompt-sub-agent-oracle.md} +1 -2
  57. klaude_code/core/prompts/prompt-sub-agent-web.md +51 -0
  58. klaude_code/core/reminders.py +283 -95
  59. klaude_code/core/task.py +113 -75
  60. klaude_code/core/tool/__init__.py +24 -31
  61. klaude_code/core/tool/file/_utils.py +36 -0
  62. klaude_code/core/tool/file/apply_patch.py +17 -25
  63. klaude_code/core/tool/file/apply_patch_tool.py +57 -77
  64. klaude_code/core/tool/file/diff_builder.py +151 -0
  65. klaude_code/core/tool/file/edit_tool.py +50 -63
  66. klaude_code/core/tool/file/move_tool.md +41 -0
  67. klaude_code/core/tool/file/move_tool.py +435 -0
  68. klaude_code/core/tool/file/read_tool.md +1 -1
  69. klaude_code/core/tool/file/read_tool.py +86 -86
  70. klaude_code/core/tool/file/write_tool.py +59 -69
  71. klaude_code/core/tool/report_back_tool.py +84 -0
  72. klaude_code/core/tool/shell/bash_tool.py +265 -22
  73. klaude_code/core/tool/shell/command_safety.py +3 -6
  74. klaude_code/core/tool/{memory → skill}/skill_tool.py +16 -26
  75. klaude_code/core/tool/sub_agent_tool.py +13 -2
  76. klaude_code/core/tool/todo/todo_write_tool.md +0 -157
  77. klaude_code/core/tool/todo/todo_write_tool.py +1 -1
  78. klaude_code/core/tool/todo/todo_write_tool_raw.md +182 -0
  79. klaude_code/core/tool/todo/update_plan_tool.py +1 -1
  80. klaude_code/core/tool/tool_abc.py +18 -0
  81. klaude_code/core/tool/tool_context.py +27 -12
  82. klaude_code/core/tool/tool_registry.py +7 -7
  83. klaude_code/core/tool/tool_runner.py +44 -36
  84. klaude_code/core/tool/truncation.py +29 -14
  85. klaude_code/core/tool/web/mermaid_tool.md +43 -0
  86. klaude_code/core/tool/web/mermaid_tool.py +2 -5
  87. klaude_code/core/tool/web/web_fetch_tool.md +1 -1
  88. klaude_code/core/tool/web/web_fetch_tool.py +112 -22
  89. klaude_code/core/tool/web/web_search_tool.md +23 -0
  90. klaude_code/core/tool/web/web_search_tool.py +130 -0
  91. klaude_code/core/turn.py +168 -66
  92. klaude_code/llm/__init__.py +2 -10
  93. klaude_code/llm/anthropic/client.py +190 -178
  94. klaude_code/llm/anthropic/input.py +39 -15
  95. klaude_code/llm/bedrock/__init__.py +3 -0
  96. klaude_code/llm/bedrock/client.py +60 -0
  97. klaude_code/llm/client.py +7 -21
  98. klaude_code/llm/codex/__init__.py +5 -0
  99. klaude_code/llm/codex/client.py +149 -0
  100. klaude_code/llm/google/__init__.py +3 -0
  101. klaude_code/llm/google/client.py +309 -0
  102. klaude_code/llm/google/input.py +215 -0
  103. klaude_code/llm/input_common.py +3 -9
  104. klaude_code/llm/openai_compatible/client.py +72 -164
  105. klaude_code/llm/openai_compatible/input.py +6 -4
  106. klaude_code/llm/openai_compatible/stream.py +273 -0
  107. klaude_code/llm/openai_compatible/tool_call_accumulator.py +17 -1
  108. klaude_code/llm/openrouter/client.py +89 -160
  109. klaude_code/llm/openrouter/input.py +18 -30
  110. klaude_code/llm/openrouter/reasoning.py +118 -0
  111. klaude_code/llm/registry.py +39 -7
  112. klaude_code/llm/responses/client.py +184 -171
  113. klaude_code/llm/responses/input.py +20 -1
  114. klaude_code/llm/usage.py +17 -12
  115. klaude_code/protocol/commands.py +17 -1
  116. klaude_code/protocol/events.py +31 -4
  117. klaude_code/protocol/llm_param.py +13 -10
  118. klaude_code/protocol/model.py +232 -29
  119. klaude_code/protocol/op.py +90 -1
  120. klaude_code/protocol/op_handler.py +35 -1
  121. klaude_code/protocol/sub_agent/__init__.py +117 -0
  122. klaude_code/protocol/sub_agent/explore.py +63 -0
  123. klaude_code/protocol/sub_agent/oracle.py +91 -0
  124. klaude_code/protocol/sub_agent/task.py +61 -0
  125. klaude_code/protocol/sub_agent/web.py +79 -0
  126. klaude_code/protocol/tools.py +4 -2
  127. klaude_code/session/__init__.py +2 -2
  128. klaude_code/session/codec.py +71 -0
  129. klaude_code/session/export.py +293 -86
  130. klaude_code/session/selector.py +89 -67
  131. klaude_code/session/session.py +320 -309
  132. klaude_code/session/store.py +220 -0
  133. klaude_code/session/templates/export_session.html +595 -83
  134. klaude_code/session/templates/mermaid_viewer.html +926 -0
  135. klaude_code/skill/__init__.py +27 -0
  136. klaude_code/skill/assets/deslop/SKILL.md +17 -0
  137. klaude_code/skill/assets/dev-docs/SKILL.md +108 -0
  138. klaude_code/skill/assets/handoff/SKILL.md +39 -0
  139. klaude_code/skill/assets/jj-workspace/SKILL.md +20 -0
  140. klaude_code/skill/assets/skill-creator/SKILL.md +139 -0
  141. klaude_code/{core/tool/memory/skill_loader.py → skill/loader.py} +55 -15
  142. klaude_code/skill/manager.py +70 -0
  143. klaude_code/skill/system_skills.py +192 -0
  144. klaude_code/trace/__init__.py +20 -2
  145. klaude_code/trace/log.py +150 -5
  146. klaude_code/ui/__init__.py +4 -9
  147. klaude_code/ui/core/input.py +1 -1
  148. klaude_code/ui/core/stage_manager.py +7 -7
  149. klaude_code/ui/modes/debug/display.py +2 -1
  150. klaude_code/ui/modes/repl/__init__.py +3 -48
  151. klaude_code/ui/modes/repl/clipboard.py +5 -5
  152. klaude_code/ui/modes/repl/completers.py +487 -123
  153. klaude_code/ui/modes/repl/display.py +5 -4
  154. klaude_code/ui/modes/repl/event_handler.py +370 -117
  155. klaude_code/ui/modes/repl/input_prompt_toolkit.py +552 -105
  156. klaude_code/ui/modes/repl/key_bindings.py +146 -23
  157. klaude_code/ui/modes/repl/renderer.py +189 -99
  158. klaude_code/ui/renderers/assistant.py +9 -2
  159. klaude_code/ui/renderers/bash_syntax.py +178 -0
  160. klaude_code/ui/renderers/common.py +78 -0
  161. klaude_code/ui/renderers/developer.py +104 -48
  162. klaude_code/ui/renderers/diffs.py +87 -6
  163. klaude_code/ui/renderers/errors.py +11 -6
  164. klaude_code/ui/renderers/mermaid_viewer.py +57 -0
  165. klaude_code/ui/renderers/metadata.py +112 -76
  166. klaude_code/ui/renderers/sub_agent.py +92 -7
  167. klaude_code/ui/renderers/thinking.py +40 -18
  168. klaude_code/ui/renderers/tools.py +405 -227
  169. klaude_code/ui/renderers/user_input.py +73 -13
  170. klaude_code/ui/rich/__init__.py +10 -1
  171. klaude_code/ui/rich/cjk_wrap.py +228 -0
  172. klaude_code/ui/rich/code_panel.py +131 -0
  173. klaude_code/ui/rich/live.py +17 -0
  174. klaude_code/ui/rich/markdown.py +305 -170
  175. klaude_code/ui/rich/searchable_text.py +10 -13
  176. klaude_code/ui/rich/status.py +190 -49
  177. klaude_code/ui/rich/theme.py +135 -39
  178. klaude_code/ui/terminal/__init__.py +55 -0
  179. klaude_code/ui/terminal/color.py +1 -1
  180. klaude_code/ui/terminal/control.py +13 -22
  181. klaude_code/ui/terminal/notifier.py +44 -4
  182. klaude_code/ui/terminal/selector.py +658 -0
  183. klaude_code/ui/utils/common.py +0 -18
  184. klaude_code-1.8.0.dist-info/METADATA +377 -0
  185. klaude_code-1.8.0.dist-info/RECORD +219 -0
  186. {klaude_code-1.2.6.dist-info → klaude_code-1.8.0.dist-info}/entry_points.txt +1 -0
  187. klaude_code/command/diff_cmd.py +0 -138
  188. klaude_code/command/prompt-dev-docs-update.md +0 -56
  189. klaude_code/command/prompt-dev-docs.md +0 -46
  190. klaude_code/config/list_model.py +0 -162
  191. klaude_code/core/manager/agent_manager.py +0 -127
  192. klaude_code/core/prompts/prompt-subagent-webfetch.md +0 -46
  193. klaude_code/core/tool/file/multi_edit_tool.md +0 -42
  194. klaude_code/core/tool/file/multi_edit_tool.py +0 -199
  195. klaude_code/core/tool/memory/memory_tool.md +0 -16
  196. klaude_code/core/tool/memory/memory_tool.py +0 -462
  197. klaude_code/llm/openrouter/reasoning_handler.py +0 -209
  198. klaude_code/protocol/sub_agent.py +0 -348
  199. klaude_code/ui/utils/debouncer.py +0 -42
  200. klaude_code-1.2.6.dist-info/METADATA +0 -178
  201. klaude_code-1.2.6.dist-info/RECORD +0 -167
  202. /klaude_code/core/prompts/{prompt-subagent.md → prompt-sub-agent.md} +0 -0
  203. /klaude_code/core/tool/{memory → skill}/__init__.py +0 -0
  204. /klaude_code/core/tool/{memory → skill}/skill_tool.md +0 -0
  205. {klaude_code-1.2.6.dist-info → klaude_code-1.8.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,27 @@
1
+ """Skill module - independent skill management system.
2
+
3
+ This module provides the core skill functionality:
4
+ - Skill discovery and loading from multiple directories
5
+ - System skill installation
6
+ - Global skill access via manager functions
7
+
8
+ Public API:
9
+ - get_skill(name) - Get a skill by name
10
+ - get_available_skills() - Get list of (name, description, location) tuples
11
+ - get_skill_loader() - Get the global SkillLoader instance
12
+ - list_skill_names() - Get list of skill names
13
+ - Skill - Skill data class
14
+ - SkillLoader - Skill loader class
15
+ """
16
+
17
+ from klaude_code.skill.loader import Skill, SkillLoader
18
+ from klaude_code.skill.manager import get_available_skills, get_skill, get_skill_loader, list_skill_names
19
+
20
+ __all__ = [
21
+ "Skill",
22
+ "SkillLoader",
23
+ "get_available_skills",
24
+ "get_skill",
25
+ "get_skill_loader",
26
+ "list_skill_names",
27
+ ]
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: deslop
3
+ description: Remove AI-generated code slop from files or diffs. Use this skill when reviewing AI-generated code to clean up unnecessary comments, defensive code, type hacks, and style inconsistencies. Triggers include "deslop", "remove slop", "clean up AI code", "review for slop".
4
+ metadata:
5
+ short-description: Remove AI code slop
6
+ ---
7
+
8
+ # Deslop
9
+
10
+ Remove AI-generated slop from code. Check the specified files or diff and remove:
11
+
12
+ - Extra comments that a human wouldn't add or are inconsistent with the rest of the file
13
+ - Extra defensive checks or try/catch blocks that are abnormal for that area of the codebase (especially if called by trusted/validated codepaths)
14
+ - Casts to `any` or `# type: ignore` to get around type issues
15
+ - Any other style that is inconsistent with the file
16
+
17
+ Report at the end with only a 1-3 sentence summary of what you changed.
@@ -0,0 +1,108 @@
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.
@@ -0,0 +1,39 @@
1
+ ---
2
+ name: handoff
3
+ description: Write a HANDOFF.md file for another agent to continue the conversation. Use this skill when switching to a new conversation/session and need to pass context to the next agent. Triggers include "handoff", "write handoff", "create handoff", "pass to another agent".
4
+ metadata:
5
+ short-description: Write handoff document for agent continuation
6
+ ---
7
+
8
+ # Handoff
9
+
10
+ Write a HANDOFF.md file in the current working directory for another agent to continue this conversation.
11
+
12
+ Extract relevant context from the conversation to facilitate continuing this work. Write from the user's perspective (first person: "I did...", "I told you...").
13
+
14
+ ## Consider What Would Be Useful
15
+
16
+ - What did the user just do or implement?
17
+ - What instructions did the user give that are still relevant (e.g., follow patterns in the codebase)?
18
+ - Did the user provide a plan or spec that should be included?
19
+ - What important information did the user share (certain libraries, patterns, constraints, preferences)?
20
+ - What key technical details were discovered (APIs, methods, patterns)?
21
+ - What caveats, limitations, or open questions remain?
22
+
23
+ Extract only what matters for the specific goal. Skip irrelevant questions. Choose an appropriate length based on the complexity.
24
+
25
+ Focus on capabilities and behavior, not file-by-file changes. Avoid excessive implementation details (variable names, storage keys, constants) unless critical.
26
+
27
+ ## Format
28
+
29
+ - Plain text with bullets
30
+ - No markdown headers, no bold/italic, no code fences
31
+ - Use workspace-relative paths for files
32
+ - List relevant file or directory paths at the end:
33
+
34
+ ```
35
+ @src/project/main.py
36
+ @src/project/llm/
37
+ ```
38
+
39
+ If the user's goal is unclear, ask for clarification.
@@ -0,0 +1,20 @@
1
+ ---
2
+ name: jj-workspace
3
+ description: Create a jj workspace before starting work to enable parallel Claude sessions. Use this skill when starting a new task that should be isolated from other concurrent work. Triggers include "jj workspace", "parallel work", "create workspace", "isolated workspace".
4
+ metadata:
5
+ short-description: Create jj workspace for parallel work
6
+ ---
7
+
8
+ # JJ Workspace
9
+
10
+ Create a dedicated jj workspace before starting any task. This allows multiple Claude sessions to work in parallel without conflicts.
11
+
12
+ ## Steps
13
+
14
+ 1. Generate a short, descriptive workspace name based on the task (e.g., `workspace-add-login` or `workspace-fix-typo`)
15
+ 2. Run `jj workspace add <workspace-name>` to create the workspace
16
+ 3. Change into the workspace directory: `cd <workspace-name>`
17
+ 4. Describe the change: `jj describe -m '<brief task description>'`
18
+ 5. Continue all subsequent work within this workspace directory
19
+
20
+ If no task is provided, ask the user for a task description.
@@ -0,0 +1,139 @@
1
+ ---
2
+ name: skill-creator
3
+ description: Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
4
+ metadata:
5
+ short-description: Create or update a skill
6
+ ---
7
+
8
+ # Skill Creator
9
+
10
+ This skill provides guidance for creating effective skills.
11
+
12
+ ## About Skills
13
+
14
+ Skills are modular, self-contained packages that extend the agent's capabilities by providing
15
+ specialized knowledge, workflows, and tools. Think of them as "onboarding guides" for specific
16
+ domains or tasks - they transform the agent from a general-purpose assistant into a specialized
17
+ agent equipped with procedural knowledge.
18
+
19
+ ### What Skills Provide
20
+
21
+ 1. Specialized workflows - Multi-step procedures for specific domains
22
+ 2. Tool integrations - Instructions for working with specific file formats or APIs
23
+ 3. Domain expertise - Company-specific knowledge, schemas, business logic
24
+ 4. Bundled resources - Scripts, references, and assets for complex and repetitive tasks
25
+
26
+ ## Core Principles
27
+
28
+ ### Concise is Key
29
+
30
+ The context window is a public good. Skills share the context window with everything else:
31
+ system prompt, conversation history, other Skills' metadata, and the actual user request.
32
+
33
+ **Default assumption: The agent is already very smart.** Only add context the agent doesn't
34
+ already have. Challenge each piece of information: "Does the agent really need this explanation?"
35
+ and "Does this paragraph justify its token cost?"
36
+
37
+ Prefer concise examples over verbose explanations.
38
+
39
+ ### Anatomy of a Skill
40
+
41
+ Every skill consists of a required SKILL.md file and optional bundled resources:
42
+
43
+ ```
44
+ skill-name/
45
+ ├── SKILL.md (required)
46
+ │ ├── YAML frontmatter metadata (required)
47
+ │ │ ├── name: (required)
48
+ │ │ └── description: (required)
49
+ │ └── Markdown instructions (required)
50
+ └── Bundled Resources (optional)
51
+ ├── scripts/ - Executable code (Python/Bash/etc.)
52
+ ├── references/ - Documentation intended to be loaded into context as needed
53
+ └── assets/ - Files used in output (templates, icons, fonts, etc.)
54
+ ```
55
+
56
+ #### SKILL.md (required)
57
+
58
+ Every SKILL.md consists of:
59
+
60
+ - **Frontmatter** (YAML): Contains `name` and `description` fields. These are the only fields
61
+ that determine when the skill gets used, thus it is very important to be clear and comprehensive
62
+ in describing what the skill is, and when it should be used.
63
+ - **Body** (Markdown): Instructions and guidance for using the skill. Only loaded AFTER the
64
+ skill triggers (if at all).
65
+
66
+ #### Bundled Resources (optional)
67
+
68
+ ##### Scripts (`scripts/`)
69
+
70
+ Executable code (Python/Bash/etc.) for tasks that require deterministic reliability or are
71
+ repeatedly rewritten.
72
+
73
+ - **When to include**: When the same code is being rewritten repeatedly or deterministic
74
+ reliability is needed
75
+ - **Example**: `scripts/rotate_pdf.py` for PDF rotation tasks
76
+ - **Benefits**: Token efficient, deterministic, may be executed without loading into context
77
+
78
+ ##### References (`references/`)
79
+
80
+ Documentation and reference material intended to be loaded as needed into context.
81
+
82
+ - **When to include**: For documentation that the agent should reference while working
83
+ - **Examples**: `references/schema.md` for database schemas, `references/api_docs.md` for
84
+ API specifications
85
+ - **Benefits**: Keeps SKILL.md lean, loaded only when needed
86
+
87
+ ##### Assets (`assets/`)
88
+
89
+ Files not intended to be loaded into context, but rather used within the output.
90
+
91
+ - **When to include**: When the skill needs files that will be used in the final output
92
+ - **Examples**: `assets/logo.png` for brand assets, `assets/template.html` for HTML templates
93
+ - **Benefits**: Separates output resources from documentation
94
+
95
+ ## Skill Creation Process
96
+
97
+ Skill creation involves these steps:
98
+
99
+ 1. Understand the skill with concrete examples
100
+ 2. Plan reusable skill contents (scripts, references, assets)
101
+ 3. Create the skill directory structure
102
+ 4. Write SKILL.md with proper frontmatter
103
+ 5. Add bundled resources as needed
104
+ 6. Test and iterate based on real usage
105
+
106
+ ### Skill Naming
107
+
108
+ - Use lowercase letters, digits, and hyphens only
109
+ - Prefer short, verb-led phrases that describe the action
110
+ - Name the skill folder exactly after the skill name
111
+
112
+ ### Writing Guidelines
113
+
114
+ Always use imperative/infinitive form.
115
+
116
+ #### Frontmatter
117
+
118
+ Write the YAML frontmatter with `name` and `description`:
119
+
120
+ - `name`: The skill name (required)
121
+ - `description`: This is the primary triggering mechanism for your skill. Include both what
122
+ the Skill does and specific triggers/contexts for when to use it. Include all "when to use"
123
+ information here - Not in the body.
124
+
125
+ #### Body
126
+
127
+ Write instructions for using the skill and its bundled resources. Keep SKILL.md body to the
128
+ essentials and under 500 lines to minimize context bloat.
129
+
130
+ ## Skill Storage Locations
131
+
132
+ Skills can be stored in multiple locations with the following priority (higher priority overrides lower):
133
+
134
+ | Priority | Scope | Path | Description |
135
+ |----------|---------|-----------------------------|-----------------------|
136
+ | 1 | Project | `.claude/skills/` | Current project only |
137
+ | 2 | User | `~/.klaude/skills/` | User-level |
138
+ | 3 | User | `~/.claude/skills/` | User-level (Claude) |
139
+ | 4 | System | `~/.klaude/skills/.system/` | Built-in system skills|
@@ -1,6 +1,7 @@
1
1
  import re
2
2
  from dataclasses import dataclass
3
3
  from pathlib import Path
4
+ from typing import ClassVar
4
5
 
5
6
  import yaml
6
7
 
@@ -14,12 +15,22 @@ class Skill:
14
15
  name: str # Skill identifier (lowercase-hyphen)
15
16
  description: str # What the skill does and when to use it
16
17
  content: str # Full markdown instructions
17
- location: str # Skill location: 'user' or 'project'
18
+ location: str # Skill location: 'system', 'user', or 'project'
18
19
  license: str | None = None
19
20
  allowed_tools: list[str] | None = None
20
21
  metadata: dict[str, str] | None = None
21
22
  skill_path: Path | None = None
22
23
 
24
+ @property
25
+ def short_description(self) -> str:
26
+ """Get short description for display in completions.
27
+
28
+ Returns metadata['short-description'] if available, otherwise falls back to description.
29
+ """
30
+ if self.metadata and "short-description" in self.metadata:
31
+ return self.metadata["short-description"]
32
+ return self.description
33
+
23
34
  def to_prompt(self) -> str:
24
35
  """Convert skill to prompt format for agent consumption"""
25
36
  return f"""# Skill: {self.name}
@@ -35,14 +46,16 @@ class Skill:
35
46
  class SkillLoader:
36
47
  """Load and manage Claude Skills from SKILL.md files"""
37
48
 
49
+ # System-level skills directory (built-in, lowest priority)
50
+ SYSTEM_SKILLS_DIR: ClassVar[Path] = Path("~/.klaude/skills/.system")
51
+
38
52
  # User-level skills directories (checked in order, later ones override earlier ones with same name)
39
- USER_SKILLS_DIRS = [
53
+ USER_SKILLS_DIRS: ClassVar[list[Path]] = [
40
54
  Path("~/.claude/skills"),
41
55
  Path("~/.klaude/skills"),
42
- Path("~/.claude/plugins/marketplaces"),
43
56
  ]
44
- # Project-level skills directory
45
- PROJECT_SKILLS_DIR = Path("./.claude/skills")
57
+ # Project-level skills directory (highest priority)
58
+ PROJECT_SKILLS_DIR: ClassVar[Path] = Path("./.claude/skills")
46
59
 
47
60
  def __init__(self) -> None:
48
61
  """Initialize the skill loader"""
@@ -53,7 +66,7 @@ class SkillLoader:
53
66
 
54
67
  Args:
55
68
  skill_path: Path to SKILL.md file
56
- location: Skill location ('user' or 'project')
69
+ location: Skill location ('system', 'user', or 'project')
57
70
 
58
71
  Returns:
59
72
  Skill object or None if loading failed
@@ -115,22 +128,40 @@ class SkillLoader:
115
128
 
116
129
  return skill
117
130
 
118
- except Exception:
131
+ except (OSError, yaml.YAMLError) as e:
132
+ log_debug(f"Failed to load skill from {skill_path}: {e}")
119
133
  return None
120
134
 
121
135
  def discover_skills(self) -> list[Skill]:
122
- """Recursively find all SKILL.md files and load them from both user and project directories
136
+ """Recursively find all SKILL.md files and load them from system, user and project directories.
137
+
138
+ Loading order (lower priority first, higher priority overrides):
139
+ 1. System skills (~/.klaude/skills/.system/) - built-in, lowest priority
140
+ 2. User skills (~/.claude/skills/, ~/.klaude/skills/) - user-level
141
+ 3. Project skills (./.claude/skills/) - project-level, highest priority
123
142
 
124
143
  Returns:
125
144
  List of successfully loaded Skill objects
126
145
  """
127
146
  skills: list[Skill] = []
128
147
 
129
- # Load user-level skills from all directories
148
+ # Load system-level skills first (lowest priority, can be overridden)
149
+ system_dir = self.SYSTEM_SKILLS_DIR.expanduser()
150
+ if system_dir.exists():
151
+ for skill_file in system_dir.rglob("SKILL.md"):
152
+ skill = self.load_skill(skill_file, location="system")
153
+ if skill:
154
+ skills.append(skill)
155
+ self.loaded_skills[skill.name] = skill
156
+
157
+ # Load user-level skills (override system skills if same name)
130
158
  for user_dir in self.USER_SKILLS_DIRS:
131
159
  expanded_dir = user_dir.expanduser()
132
160
  if expanded_dir.exists():
133
161
  for skill_file in expanded_dir.rglob("SKILL.md"):
162
+ # Skip files under .system directory (already loaded above)
163
+ if ".system" in skill_file.parts:
164
+ continue
134
165
  skill = self.load_skill(skill_file, location="user")
135
166
  if skill:
136
167
  skills.append(skill)
@@ -147,9 +178,12 @@ class SkillLoader:
147
178
 
148
179
  # Log discovery summary
149
180
  if skills:
181
+ system_count = sum(1 for s in skills if s.location == "system")
150
182
  user_count = sum(1 for s in skills if s.location == "user")
151
183
  project_count = sum(1 for s in skills if s.location == "project")
152
184
  parts: list[str] = []
185
+ if system_count > 0:
186
+ parts.append(f"{system_count} system")
153
187
  if user_count > 0:
154
188
  parts.append(f"{user_count} user")
155
189
  if project_count > 0:
@@ -167,11 +201,17 @@ class SkillLoader:
167
201
  Returns:
168
202
  Skill object or None if not found
169
203
  """
204
+ # Prefer exact match first (supports namespaced skill names).
205
+ skill = self.loaded_skills.get(name)
206
+ if skill is not None:
207
+ return skill
208
+
170
209
  # Support both formats: 'pdf' and 'document-skills:pdf'
171
210
  if ":" in name:
172
- name = name.split(":")[-1]
211
+ short = name.split(":")[-1]
212
+ return self.loaded_skills.get(short)
173
213
 
174
- return self.loaded_skills.get(name)
214
+ return None
175
215
 
176
216
  def list_skills(self) -> list[str]:
177
217
  """Get list of all loaded skill names"""
@@ -220,25 +260,25 @@ class SkillLoader:
220
260
  content = re.sub(dir_pattern, replace_dir_path, content)
221
261
 
222
262
  # Pattern 2: Markdown links [text](./path or path)
223
- # e.g., "[Guide](./docs/guide.md)" -> "[Guide](`/abs/path/to/docs/guide.md`) (use read_file to access)"
263
+ # e.g., "[Guide](./docs/guide.md)" -> "[Guide](`/abs/path/to/docs/guide.md`) (use the Read tool to access)"
224
264
  link_pattern = r"\[([^\]]+)\]\((\./)?([^\)]+\.md)\)"
225
265
 
226
266
  def replace_link(match: re.Match[str]) -> str:
227
267
  text = match.group(1)
228
268
  filename = match.group(3)
229
269
  abs_path = skill_dir / filename
230
- return f"[{text}](`{abs_path}`) (use read_file to access)"
270
+ return f"[{text}](`{abs_path}`) (use the Read tool to access)"
231
271
 
232
272
  content = re.sub(link_pattern, replace_link, content)
233
273
 
234
274
  # Pattern 3: Standalone markdown references
235
- # e.g., "see reference.md" -> "see `/abs/path/to/reference.md` (use read_file to access)"
275
+ # e.g., "see reference.md" -> "see `/abs/path/to/reference.md` (use the Read tool to access)"
236
276
  standalone_pattern = r"(?<!\])\b(\w+\.md)\b(?!\))"
237
277
 
238
278
  def replace_standalone(match: re.Match[str]) -> str:
239
279
  filename = match.group(1)
240
280
  abs_path = skill_dir / filename
241
- return f"`{abs_path}` (use read_file to access)"
281
+ return f"`{abs_path}` (use the Read tool to access)"
242
282
 
243
283
  content = re.sub(standalone_pattern, replace_standalone, content)
244
284
 
@@ -0,0 +1,70 @@
1
+ """Global skill manager with lazy initialization.
2
+
3
+ This module provides a centralized interface for accessing skills throughout the application.
4
+ Skills are loaded lazily on first access to avoid unnecessary IO at startup.
5
+ """
6
+
7
+ from klaude_code.skill.loader import Skill, SkillLoader
8
+ from klaude_code.skill.system_skills import install_system_skills
9
+
10
+ _loader: SkillLoader | None = None
11
+ _initialized: bool = False
12
+
13
+
14
+ def _ensure_initialized() -> SkillLoader:
15
+ """Ensure the skill system is initialized and return the loader."""
16
+ global _loader, _initialized
17
+ if not _initialized:
18
+ install_system_skills()
19
+ _loader = SkillLoader()
20
+ _loader.discover_skills()
21
+ _initialized = True
22
+ assert _loader is not None
23
+ return _loader
24
+
25
+
26
+ def get_skill_loader() -> SkillLoader:
27
+ """Get the global skill loader instance.
28
+
29
+ Lazily initializes the skill system on first call.
30
+
31
+ Returns:
32
+ The global SkillLoader instance
33
+ """
34
+ return _ensure_initialized()
35
+
36
+
37
+ def get_skill(name: str) -> Skill | None:
38
+ """Get a skill by name.
39
+
40
+ Args:
41
+ name: Skill name (supports both 'skill-name' and 'namespace:skill-name')
42
+
43
+ Returns:
44
+ Skill object or None if not found
45
+ """
46
+ return _ensure_initialized().get_skill(name)
47
+
48
+
49
+ def get_available_skills() -> list[tuple[str, str, str]]:
50
+ """Get list of available skills for completion and display.
51
+
52
+ Returns:
53
+ List of (name, short_description, location) tuples.
54
+ Uses metadata['short-description'] if available, otherwise falls back to description.
55
+ Skills are ordered by priority: project > user > system.
56
+ """
57
+ loader = _ensure_initialized()
58
+ skills = [(s.name, s.short_description, s.location) for s in loader.loaded_skills.values()]
59
+ location_order = {"project": 0, "user": 1, "system": 2}
60
+ skills.sort(key=lambda x: location_order.get(x[2], 3))
61
+ return skills
62
+
63
+
64
+ def list_skill_names() -> list[str]:
65
+ """Get list of all loaded skill names.
66
+
67
+ Returns:
68
+ List of skill names
69
+ """
70
+ return _ensure_initialized().list_skills()