klaude-code 2.8.0__py3-none-any.whl → 2.9.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 (100) hide show
  1. klaude_code/app/runtime.py +2 -1
  2. klaude_code/auth/antigravity/oauth.py +0 -9
  3. klaude_code/auth/antigravity/token_manager.py +0 -18
  4. klaude_code/auth/base.py +53 -0
  5. klaude_code/auth/codex/exceptions.py +0 -4
  6. klaude_code/auth/codex/oauth.py +32 -28
  7. klaude_code/auth/codex/token_manager.py +0 -18
  8. klaude_code/cli/cost_cmd.py +128 -39
  9. klaude_code/cli/list_model.py +27 -10
  10. klaude_code/cli/main.py +15 -4
  11. klaude_code/config/assets/builtin_config.yaml +8 -24
  12. klaude_code/config/config.py +47 -25
  13. klaude_code/config/sub_agent_model_helper.py +18 -13
  14. klaude_code/config/thinking.py +0 -8
  15. klaude_code/const.py +2 -2
  16. klaude_code/core/agent_profile.py +11 -53
  17. klaude_code/core/compaction/compaction.py +4 -6
  18. klaude_code/core/compaction/overflow.py +0 -4
  19. klaude_code/core/executor.py +51 -5
  20. klaude_code/core/manager/llm_clients.py +9 -1
  21. klaude_code/core/prompts/prompt-claude-code.md +4 -4
  22. klaude_code/core/reminders.py +21 -23
  23. klaude_code/core/task.py +0 -4
  24. klaude_code/core/tool/__init__.py +3 -2
  25. klaude_code/core/tool/file/apply_patch.py +0 -27
  26. klaude_code/core/tool/file/edit_tool.py +1 -2
  27. klaude_code/core/tool/file/read_tool.md +3 -2
  28. klaude_code/core/tool/file/read_tool.py +15 -2
  29. klaude_code/core/tool/offload.py +0 -35
  30. klaude_code/core/tool/sub_agent/__init__.py +6 -0
  31. klaude_code/core/tool/sub_agent/image_gen.md +16 -0
  32. klaude_code/core/tool/sub_agent/image_gen.py +146 -0
  33. klaude_code/core/tool/sub_agent/task.md +20 -0
  34. klaude_code/core/tool/sub_agent/task.py +205 -0
  35. klaude_code/core/tool/tool_registry.py +0 -16
  36. klaude_code/core/turn.py +1 -1
  37. klaude_code/llm/anthropic/input.py +6 -5
  38. klaude_code/llm/antigravity/input.py +14 -7
  39. klaude_code/llm/codex/client.py +22 -0
  40. klaude_code/llm/codex/prompt_sync.py +237 -0
  41. klaude_code/llm/google/client.py +8 -6
  42. klaude_code/llm/google/input.py +20 -12
  43. klaude_code/llm/image.py +18 -11
  44. klaude_code/llm/input_common.py +14 -6
  45. klaude_code/llm/json_stable.py +37 -0
  46. klaude_code/llm/openai_compatible/input.py +0 -10
  47. klaude_code/llm/openai_compatible/stream.py +16 -1
  48. klaude_code/llm/registry.py +0 -5
  49. klaude_code/llm/responses/input.py +15 -5
  50. klaude_code/llm/usage.py +0 -8
  51. klaude_code/protocol/commands.py +1 -0
  52. klaude_code/protocol/events.py +2 -1
  53. klaude_code/protocol/message.py +2 -2
  54. klaude_code/protocol/model.py +20 -1
  55. klaude_code/protocol/op.py +27 -0
  56. klaude_code/protocol/op_handler.py +10 -0
  57. klaude_code/protocol/sub_agent/AGENTS.md +5 -5
  58. klaude_code/protocol/sub_agent/__init__.py +13 -34
  59. klaude_code/protocol/sub_agent/explore.py +7 -34
  60. klaude_code/protocol/sub_agent/image_gen.py +3 -74
  61. klaude_code/protocol/sub_agent/task.py +3 -47
  62. klaude_code/protocol/sub_agent/web.py +8 -52
  63. klaude_code/protocol/tools.py +2 -0
  64. klaude_code/session/export.py +308 -299
  65. klaude_code/session/session.py +58 -21
  66. klaude_code/session/store.py +0 -4
  67. klaude_code/session/templates/export_session.html +430 -134
  68. klaude_code/skill/assets/deslop/SKILL.md +9 -0
  69. klaude_code/skill/system_skills.py +0 -20
  70. klaude_code/tui/command/__init__.py +3 -0
  71. klaude_code/tui/command/continue_cmd.py +34 -0
  72. klaude_code/tui/command/fork_session_cmd.py +5 -2
  73. klaude_code/tui/command/resume_cmd.py +9 -2
  74. klaude_code/tui/command/sub_agent_model_cmd.py +85 -18
  75. klaude_code/tui/components/assistant.py +0 -26
  76. klaude_code/tui/components/command_output.py +3 -1
  77. klaude_code/tui/components/developer.py +3 -0
  78. klaude_code/tui/components/diffs.py +2 -208
  79. klaude_code/tui/components/errors.py +4 -0
  80. klaude_code/tui/components/mermaid_viewer.py +2 -2
  81. klaude_code/tui/components/rich/markdown.py +60 -63
  82. klaude_code/tui/components/rich/theme.py +2 -0
  83. klaude_code/tui/components/sub_agent.py +2 -46
  84. klaude_code/tui/components/thinking.py +0 -33
  85. klaude_code/tui/components/tools.py +43 -21
  86. klaude_code/tui/input/images.py +21 -18
  87. klaude_code/tui/input/key_bindings.py +2 -2
  88. klaude_code/tui/input/prompt_toolkit.py +49 -49
  89. klaude_code/tui/machine.py +15 -11
  90. klaude_code/tui/renderer.py +12 -20
  91. klaude_code/tui/runner.py +2 -1
  92. klaude_code/tui/terminal/image.py +6 -34
  93. klaude_code/ui/common.py +0 -70
  94. {klaude_code-2.8.0.dist-info → klaude_code-2.9.0.dist-info}/METADATA +3 -6
  95. {klaude_code-2.8.0.dist-info → klaude_code-2.9.0.dist-info}/RECORD +97 -92
  96. klaude_code/core/tool/sub_agent_tool.py +0 -126
  97. klaude_code/llm/openai_compatible/tool_call_accumulator.py +0 -108
  98. klaude_code/tui/components/rich/searchable_text.py +0 -68
  99. {klaude_code-2.8.0.dist-info → klaude_code-2.9.0.dist-info}/WHEEL +0 -0
  100. {klaude_code-2.8.0.dist-info → klaude_code-2.9.0.dist-info}/entry_points.txt +0 -0
@@ -92,10 +92,6 @@ class Session(BaseModel):
92
92
  ]
93
93
  return self._user_messages_cache
94
94
 
95
- @staticmethod
96
- def _project_key() -> str:
97
- return project_key_from_cwd()
98
-
99
95
  @classmethod
100
96
  def paths(cls) -> ProjectPaths:
101
97
  return get_default_store().paths
@@ -410,7 +406,9 @@ class Session(BaseModel):
410
406
  )
411
407
  yield from self._iter_sub_agent_history(tr, seen_sub_agent_sessions)
412
408
  case message.UserMessage() as um:
413
- images = [part for part in um.parts if isinstance(part, message.ImageURLPart)]
409
+ images = [
410
+ part for part in um.parts if isinstance(part, (message.ImageURLPart, message.ImageFilePart))
411
+ ]
414
412
  yield events.UserMessageEvent(
415
413
  content=message.join_text_parts(um.parts),
416
414
  session_id=self.id,
@@ -608,27 +606,66 @@ class Session(BaseModel):
608
606
  return resolved[0]
609
607
 
610
608
  @classmethod
611
- def clean_small_sessions(cls, min_messages: int = 5) -> int:
612
- sessions = cls.list_sessions()
613
- deleted_count = 0
609
+ def find_sessions_by_prefix(cls, prefix: str) -> list[str]:
610
+ """Find main session IDs matching a prefix.
611
+
612
+ Args:
613
+ prefix: Session ID prefix to match.
614
+
615
+ Returns:
616
+ List of matching session IDs, sorted alphabetically.
617
+ """
618
+ prefix = (prefix or "").strip().lower()
619
+ if not prefix:
620
+ return []
621
+
614
622
  store = get_default_store()
615
- for session_meta in sessions:
616
- if session_meta.messages_count < 0:
623
+ matches: set[str] = set()
624
+
625
+ for meta_path in store.iter_meta_files():
626
+ data = _read_json_dict(meta_path)
627
+ if data is None:
617
628
  continue
618
- if session_meta.messages_count < min_messages:
619
- store.delete_session(session_meta.id)
620
- deleted_count += 1
621
- return deleted_count
629
+ # Exclude sub-agent sessions.
630
+ if data.get("sub_agent_state") is not None:
631
+ continue
632
+ sid = str(data.get("id", meta_path.parent.name)).strip()
633
+ if sid.lower().startswith(prefix):
634
+ matches.add(sid)
635
+
636
+ return sorted(matches)
622
637
 
623
638
  @classmethod
624
- def clean_all_sessions(cls) -> int:
625
- sessions = cls.list_sessions()
626
- deleted_count = 0
639
+ def shortest_unique_prefix(cls, session_id: str, min_length: int = 4) -> str:
640
+ """Find the shortest unique prefix for a session ID.
641
+
642
+ Args:
643
+ session_id: The session ID to find prefix for.
644
+ min_length: Minimum prefix length (default 4).
645
+
646
+ Returns:
647
+ The shortest prefix that uniquely identifies this session.
648
+ """
627
649
  store = get_default_store()
628
- for session_meta in sessions:
629
- store.delete_session(session_meta.id)
630
- deleted_count += 1
631
- return deleted_count
650
+ other_ids: list[str] = []
651
+
652
+ for meta_path in store.iter_meta_files():
653
+ data = _read_json_dict(meta_path)
654
+ if data is None:
655
+ continue
656
+ if data.get("sub_agent_state") is not None:
657
+ continue
658
+ sid = str(data.get("id", meta_path.parent.name)).strip()
659
+ if sid != session_id:
660
+ other_ids.append(sid.lower())
661
+
662
+ session_lower = session_id.lower()
663
+ for length in range(min_length, len(session_id) + 1):
664
+ prefix = session_lower[:length]
665
+ if not any(other.startswith(prefix) for other in other_ids):
666
+ return session_id[:length]
667
+
668
+ return session_id
632
669
 
633
670
  @classmethod
634
671
  def exports_dir(cls) -> Path:
@@ -2,7 +2,6 @@ from __future__ import annotations
2
2
 
3
3
  import asyncio
4
4
  import json
5
- import shutil
6
5
  from collections.abc import Iterable, Sequence
7
6
  from dataclasses import dataclass
8
7
  from pathlib import Path
@@ -152,9 +151,6 @@ class JsonlSessionStore:
152
151
  return []
153
152
  return sessions_dir.glob("*/meta.json")
154
153
 
155
- def delete_session(self, session_id: str) -> None:
156
- shutil.rmtree(self._paths.session_dir(session_id), ignore_errors=True)
157
-
158
154
  async def aclose(self) -> None:
159
155
  await self._writer.aclose()
160
156