klaude-code 1.2.21__py3-none-any.whl → 1.2.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. klaude_code/cli/debug.py +8 -10
  2. klaude_code/command/__init__.py +0 -3
  3. klaude_code/command/status_cmd.py +1 -1
  4. klaude_code/const/__init__.py +10 -7
  5. klaude_code/core/manager/sub_agent_manager.py +1 -1
  6. klaude_code/core/prompt.py +5 -2
  7. klaude_code/core/prompts/prompt-codex-gpt-5-2-codex.md +117 -0
  8. klaude_code/core/prompts/{prompt-codex-gpt-5-1.md → prompt-codex.md} +9 -42
  9. klaude_code/core/reminders.py +87 -2
  10. klaude_code/core/task.py +37 -18
  11. klaude_code/core/tool/__init__.py +1 -9
  12. klaude_code/core/tool/file/_utils.py +6 -0
  13. klaude_code/core/tool/file/apply_patch_tool.py +30 -72
  14. klaude_code/core/tool/file/diff_builder.py +151 -0
  15. klaude_code/core/tool/file/edit_tool.py +35 -18
  16. klaude_code/core/tool/file/read_tool.py +45 -86
  17. klaude_code/core/tool/file/write_tool.py +40 -30
  18. klaude_code/core/tool/shell/bash_tool.py +147 -0
  19. klaude_code/core/tool/skill/__init__.py +0 -0
  20. klaude_code/core/tool/{memory → skill}/skill_tool.py +16 -39
  21. klaude_code/protocol/commands.py +0 -1
  22. klaude_code/protocol/model.py +31 -11
  23. klaude_code/protocol/tools.py +1 -2
  24. klaude_code/session/export.py +76 -21
  25. klaude_code/session/store.py +4 -2
  26. klaude_code/session/templates/export_session.html +28 -0
  27. klaude_code/skill/__init__.py +27 -0
  28. klaude_code/skill/assets/deslop/SKILL.md +17 -0
  29. klaude_code/skill/assets/dev-docs/SKILL.md +108 -0
  30. klaude_code/skill/assets/handoff/SKILL.md +39 -0
  31. klaude_code/skill/assets/jj-workspace/SKILL.md +20 -0
  32. klaude_code/skill/assets/skill-creator/SKILL.md +139 -0
  33. klaude_code/{core/tool/memory/skill_loader.py → skill/loader.py} +60 -24
  34. klaude_code/skill/manager.py +70 -0
  35. klaude_code/skill/system_skills.py +192 -0
  36. klaude_code/ui/modes/repl/completers.py +103 -3
  37. klaude_code/ui/modes/repl/event_handler.py +7 -3
  38. klaude_code/ui/modes/repl/input_prompt_toolkit.py +42 -3
  39. klaude_code/ui/renderers/assistant.py +7 -2
  40. klaude_code/ui/renderers/common.py +26 -11
  41. klaude_code/ui/renderers/developer.py +12 -5
  42. klaude_code/ui/renderers/diffs.py +85 -1
  43. klaude_code/ui/renderers/metadata.py +4 -2
  44. klaude_code/ui/renderers/thinking.py +1 -1
  45. klaude_code/ui/renderers/tools.py +75 -129
  46. klaude_code/ui/renderers/user_input.py +32 -2
  47. klaude_code/ui/rich/markdown.py +27 -12
  48. klaude_code/ui/rich/status.py +9 -24
  49. klaude_code/ui/rich/theme.py +17 -5
  50. {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/METADATA +19 -13
  51. {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/RECORD +54 -54
  52. klaude_code/command/diff_cmd.py +0 -136
  53. klaude_code/command/prompt-deslop.md +0 -14
  54. klaude_code/command/prompt-dev-docs-update.md +0 -56
  55. klaude_code/command/prompt-dev-docs.md +0 -46
  56. klaude_code/command/prompt-handoff.md +0 -33
  57. klaude_code/command/prompt-jj-workspace.md +0 -18
  58. klaude_code/core/tool/file/multi_edit_tool.md +0 -42
  59. klaude_code/core/tool/file/multi_edit_tool.py +0 -175
  60. klaude_code/core/tool/memory/__init__.py +0 -5
  61. klaude_code/core/tool/memory/memory_tool.md +0 -20
  62. klaude_code/core/tool/memory/memory_tool.py +0 -456
  63. /klaude_code/core/tool/{memory → skill}/skill_tool.md +0 -0
  64. {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/WHEEL +0 -0
  65. {klaude_code-1.2.21.dist-info → klaude_code-1.2.23.dist-info}/entry_points.txt +0 -0
@@ -70,9 +70,15 @@ class TodoItem(BaseModel):
70
70
 
71
71
 
72
72
  class FileStatus(BaseModel):
73
- """Tracks file state including modification time and memory file flag."""
73
+ """Tracks file state including modification time and content hash.
74
+
75
+ Notes:
76
+ - `mtime` is a cheap heuristic and may miss changes on some filesystems.
77
+ - `content_sha256` provides an explicit content-based change detector.
78
+ """
74
79
 
75
80
  mtime: float
81
+ content_sha256: str | None = None
76
82
  is_memory: bool = False
77
83
 
78
84
 
@@ -86,9 +92,27 @@ class ToolSideEffect(str, Enum):
86
92
 
87
93
 
88
94
  # Discriminated union types for ToolResultUIExtra
89
- class DiffTextUIExtra(BaseModel):
90
- type: Literal["diff_text"] = "diff_text"
91
- diff_text: str
95
+ class DiffSpan(BaseModel):
96
+ op: Literal["equal", "insert", "delete"]
97
+ text: str
98
+
99
+
100
+ class DiffLine(BaseModel):
101
+ kind: Literal["ctx", "add", "remove", "gap"]
102
+ new_line_no: int | None = None
103
+ spans: list[DiffSpan]
104
+
105
+
106
+ class DiffFileDiff(BaseModel):
107
+ file_path: str
108
+ lines: list[DiffLine]
109
+ stats_add: int = 0
110
+ stats_remove: int = 0
111
+
112
+
113
+ class DiffUIExtra(BaseModel):
114
+ type: Literal["diff"] = "diff"
115
+ files: list[DiffFileDiff]
92
116
 
93
117
 
94
118
  class TodoListUIExtra(BaseModel):
@@ -122,12 +146,7 @@ class SessionStatusUIExtra(BaseModel):
122
146
 
123
147
 
124
148
  ToolResultUIExtra = Annotated[
125
- DiffTextUIExtra
126
- | TodoListUIExtra
127
- | SessionIdUIExtra
128
- | MermaidLinkUIExtra
129
- | TruncationUIExtra
130
- | SessionStatusUIExtra,
149
+ DiffUIExtra | TodoListUIExtra | SessionIdUIExtra | MermaidLinkUIExtra | TruncationUIExtra | SessionStatusUIExtra,
131
150
  Field(discriminator="type"),
132
151
  ]
133
152
 
@@ -211,6 +230,7 @@ class DeveloperMessageItem(BaseModel):
211
230
  at_files: list[AtPatternParseResult] | None = None
212
231
  command_output: CommandOutput | None = None
213
232
  user_image_count: int | None = None
233
+ skill_name: str | None = None # Skill name activated via $skill syntax
214
234
 
215
235
 
216
236
  class ImageURLPart(BaseModel):
@@ -398,7 +418,7 @@ class TaskMetadata(BaseModel):
398
418
  class TaskMetadataItem(BaseModel):
399
419
  """Aggregated metadata for a complete task, stored in conversation history."""
400
420
 
401
- main: TaskMetadata = Field(default_factory=TaskMetadata)
421
+ main_agent: TaskMetadata = Field(default_factory=TaskMetadata) # Main agent metadata
402
422
  sub_agent_task_metadata: list[TaskMetadata] = Field(default_factory=lambda: list[TaskMetadata]())
403
423
  created_at: datetime = Field(default_factory=datetime.now)
404
424
 
@@ -1,14 +1,13 @@
1
1
  BASH = "Bash"
2
2
  APPLY_PATCH = "apply_patch"
3
3
  EDIT = "Edit"
4
- MULTI_EDIT = "MultiEdit"
4
+
5
5
  READ = "Read"
6
6
  WRITE = "Write"
7
7
  TODO_WRITE = "TodoWrite"
8
8
  UPDATE_PLAN = "update_plan"
9
9
  SKILL = "Skill"
10
10
  MERMAID = "Mermaid"
11
- MEMORY = "Memory"
12
11
  WEB_FETCH = "WebFetch"
13
12
  WEB_SEARCH = "WebSearch"
14
13
  REPORT_BACK = "report_back"
@@ -235,7 +235,7 @@ def _render_metadata_item(item: model.TaskMetadataItem) -> str:
235
235
  lines: list[str] = []
236
236
 
237
237
  # Main agent metadata
238
- lines.append(_render_single_metadata(item.main, indent=0, show_context=True))
238
+ lines.append(_render_single_metadata(item.main_agent, indent=0, show_context=True))
239
239
 
240
240
  # Sub-agent metadata with indent
241
241
  for sub in item.sub_agent_task_metadata:
@@ -362,33 +362,87 @@ def _should_collapse(text: str) -> bool:
362
362
  return text.count("\n") + 1 > _COLLAPSIBLE_LINE_THRESHOLD or len(text) > _COLLAPSIBLE_CHAR_THRESHOLD
363
363
 
364
364
 
365
- def _render_diff_block(diff: str) -> str:
366
- lines = diff.splitlines()
365
+ def _render_diff_block(diff: model.DiffUIExtra) -> str:
367
366
  rendered: list[str] = []
368
- for line in lines:
369
- escaped = _escape_html(line)
370
- if line.startswith("+"):
371
- rendered.append(f'<span class="diff-line diff-plus">{escaped}</span>')
372
- elif line.startswith("-"):
373
- rendered.append(f'<span class="diff-line diff-minus">{escaped}</span>')
374
- else:
375
- rendered.append(f'<span class="diff-line diff-ctx">{escaped}</span>')
367
+ line_count = 0
368
+
369
+ for file_diff in diff.files:
370
+ header = _render_diff_file_header(file_diff)
371
+ if header:
372
+ rendered.append(header)
373
+ for line in file_diff.lines:
374
+ rendered.append(_render_diff_line(line))
375
+ line_count += 1
376
+
377
+ if line_count == 0:
378
+ rendered.append('<span class="diff-line diff-ctx">&nbsp;</span>')
379
+
376
380
  diff_content = f'<div class="diff-view">{"".join(rendered)}</div>'
377
- open_attr = "" if _should_collapse(diff) else " open"
381
+ open_attr = "" if _should_collapse("\n" * max(1, line_count)) else " open"
378
382
  return (
379
383
  f'<details class="diff-collapsible"{open_attr}>'
380
- f"<summary>Diff ({len(lines)} lines)</summary>"
384
+ f"<summary>Diff ({line_count} lines)</summary>"
381
385
  f"{diff_content}"
382
386
  "</details>"
383
387
  )
384
388
 
385
389
 
386
- def _get_diff_text(ui_extra: model.ToolResultUIExtra | None) -> str | None:
387
- if isinstance(ui_extra, model.DiffTextUIExtra):
388
- return ui_extra.diff_text
390
+ def _render_diff_file_header(file_diff: model.DiffFileDiff) -> str:
391
+ stats_parts: list[str] = []
392
+ if file_diff.stats_add > 0:
393
+ stats_parts.append(f'<span class="diff-stats-add">+{file_diff.stats_add}</span>')
394
+ if file_diff.stats_remove > 0:
395
+ stats_parts.append(f'<span class="diff-stats-remove">-{file_diff.stats_remove}</span>')
396
+ stats_html = f' <span class="diff-stats">{" ".join(stats_parts)}</span>' if stats_parts else ""
397
+ file_name = _escape_html(file_diff.file_path)
398
+ return f'<div class="diff-file">{file_name}{stats_html}</div>'
399
+
400
+
401
+ def _render_diff_line(line: model.DiffLine) -> str:
402
+ if line.kind == "gap":
403
+ line_class = "diff-ctx"
404
+ prefix = "⋮"
405
+ else:
406
+ line_class = "diff-plus" if line.kind == "add" else "diff-minus" if line.kind == "remove" else "diff-ctx"
407
+ prefix = "+" if line.kind == "add" else "-" if line.kind == "remove" else " "
408
+ spans = [_render_diff_span(span, line.kind) for span in line.spans]
409
+ content = "".join(spans)
410
+ if not content:
411
+ content = "&nbsp;"
412
+ return f'<span class="diff-line {line_class}">{prefix} {content}</span>'
413
+
414
+
415
+ def _render_diff_span(span: model.DiffSpan, line_kind: str) -> str:
416
+ text = _escape_html(span.text)
417
+ if line_kind == "add" and span.op == "insert":
418
+ return f'<span class="diff-span diff-char-add">{text}</span>'
419
+ if line_kind == "remove" and span.op == "delete":
420
+ return f'<span class="diff-span diff-char-remove">{text}</span>'
421
+ return f'<span class="diff-span">{text}</span>'
422
+
423
+
424
+ def _get_diff_ui_extra(ui_extra: model.ToolResultUIExtra | None) -> model.DiffUIExtra | None:
425
+ if isinstance(ui_extra, model.DiffUIExtra):
426
+ return ui_extra
389
427
  return None
390
428
 
391
429
 
430
+ def _build_add_only_diff(text: str, file_path: str) -> model.DiffUIExtra:
431
+ lines: list[model.DiffLine] = []
432
+ new_line_no = 1
433
+ for line in text.splitlines():
434
+ lines.append(
435
+ model.DiffLine(
436
+ kind="add",
437
+ new_line_no=new_line_no,
438
+ spans=[model.DiffSpan(op="equal", text=line)],
439
+ )
440
+ )
441
+ new_line_no += 1
442
+ file_diff = model.DiffFileDiff(file_path=file_path, lines=lines, stats_add=len(lines), stats_remove=0)
443
+ return model.DiffUIExtra(files=[file_diff])
444
+
445
+
392
446
  def _get_mermaid_link_html(
393
447
  ui_extra: model.ToolResultUIExtra | None, tool_call: model.ToolCallItem | None = None
394
448
  ) -> str | None:
@@ -513,18 +567,19 @@ def _format_tool_call(tool_call: model.ToolCallItem, result: model.ToolResultIte
513
567
  ]
514
568
 
515
569
  if result:
516
- diff_text = _get_diff_text(result.ui_extra)
570
+ diff_ui = _get_diff_ui_extra(result.ui_extra)
517
571
  mermaid_html = _get_mermaid_link_html(result.ui_extra, tool_call)
518
572
 
519
573
  should_hide_text = tool_call.name in ("TodoWrite", "update_plan") and result.status != "error"
520
574
 
521
- if tool_call.name == "Edit" and not diff_text and result.status != "error":
575
+ if tool_call.name == "Edit" and not diff_ui and result.status != "error":
522
576
  try:
523
577
  args_data = json.loads(tool_call.arguments)
578
+ file_path = args_data.get("file_path", "Unknown file")
524
579
  old_string = args_data.get("old_string", "")
525
580
  new_string = args_data.get("new_string", "")
526
581
  if old_string == "" and new_string:
527
- diff_text = "\n".join(f"+{line}" for line in new_string.splitlines())
582
+ diff_ui = _build_add_only_diff(new_string, file_path)
528
583
  except (json.JSONDecodeError, TypeError):
529
584
  pass
530
585
 
@@ -536,8 +591,8 @@ def _format_tool_call(tool_call: model.ToolCallItem, result: model.ToolResultIte
536
591
  else:
537
592
  items_to_render.append(_render_text_block(result.output))
538
593
 
539
- if diff_text:
540
- items_to_render.append(_render_diff_block(diff_text))
594
+ if diff_ui:
595
+ items_to_render.append(_render_diff_block(diff_ui))
541
596
 
542
597
  if mermaid_html:
543
598
  items_to_render.append(mermaid_html)
@@ -205,11 +205,13 @@ def build_meta_snapshot(
205
205
  "work_dir": str(work_dir),
206
206
  "sub_agent_state": sub_agent_state.model_dump(mode="json") if sub_agent_state else None,
207
207
  "file_tracker": {path: status.model_dump(mode="json") for path, status in file_tracker.items()},
208
- "todos": [todo.model_dump(mode="json") for todo in todos],
208
+ "todos": [todo.model_dump(mode="json", exclude_defaults=True) for todo in todos],
209
209
  "created_at": created_at,
210
210
  "updated_at": updated_at,
211
211
  "messages_count": messages_count,
212
212
  "model_name": model_name,
213
213
  "model_config_name": model_config_name,
214
- "model_thinking": model_thinking.model_dump(mode="json") if model_thinking else None,
214
+ "model_thinking": model_thinking.model_dump(mode="json", exclude_defaults=True, exclude_none=True)
215
+ if model_thinking
216
+ else None,
215
217
  }
@@ -31,6 +31,8 @@
31
31
  --bg-overlay: rgba(248, 246, 240, 0.98);
32
32
  --bg-error: #fdecec;
33
33
  --bg-success: #eaf6ed;
34
+ --bg-error-strong: #f9d6d6;
35
+ --bg-success-strong: #d5efdd;
34
36
  --bg-code: #f7f7f4;
35
37
  --border: #ded8cf;
36
38
  --text: #151515;
@@ -815,6 +817,21 @@
815
817
  overflow-x: auto;
816
818
  border: 1px solid var(--border);
817
819
  }
820
+ .diff-file {
821
+ color: var(--accent);
822
+ font-weight: 700;
823
+ margin: 6px 0 4px 0;
824
+ font-size: var(--font-size-sm);
825
+ }
826
+ .diff-stats {
827
+ font-weight: 600;
828
+ }
829
+ .diff-stats-add {
830
+ color: var(--success);
831
+ }
832
+ .diff-stats-remove {
833
+ color: var(--error);
834
+ }
818
835
  .diff-line {
819
836
  white-space: pre;
820
837
  }
@@ -833,6 +850,17 @@
833
850
  opacity: 0.7;
834
851
  display: block;
835
852
  }
853
+ .diff-span {
854
+ white-space: pre;
855
+ }
856
+ .diff-char-add {
857
+ background: var(--bg-success-strong);
858
+ font-weight: 600;
859
+ }
860
+ .diff-char-remove {
861
+ background: var(--bg-error-strong);
862
+ font-weight: 600;
863
+ }
836
864
 
837
865
  /* Collapsible Diff View */
838
866
  details.diff-collapsible {
@@ -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|