ripperdoc 0.2.9__py3-none-any.whl → 0.3.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 (76) hide show
  1. ripperdoc/__init__.py +1 -1
  2. ripperdoc/cli/cli.py +379 -51
  3. ripperdoc/cli/commands/__init__.py +6 -0
  4. ripperdoc/cli/commands/agents_cmd.py +128 -5
  5. ripperdoc/cli/commands/clear_cmd.py +8 -0
  6. ripperdoc/cli/commands/doctor_cmd.py +29 -0
  7. ripperdoc/cli/commands/exit_cmd.py +1 -0
  8. ripperdoc/cli/commands/memory_cmd.py +2 -1
  9. ripperdoc/cli/commands/models_cmd.py +63 -7
  10. ripperdoc/cli/commands/resume_cmd.py +5 -0
  11. ripperdoc/cli/commands/skills_cmd.py +103 -0
  12. ripperdoc/cli/commands/stats_cmd.py +244 -0
  13. ripperdoc/cli/commands/status_cmd.py +10 -0
  14. ripperdoc/cli/commands/tasks_cmd.py +6 -3
  15. ripperdoc/cli/commands/themes_cmd.py +139 -0
  16. ripperdoc/cli/ui/file_mention_completer.py +63 -13
  17. ripperdoc/cli/ui/helpers.py +6 -3
  18. ripperdoc/cli/ui/interrupt_handler.py +34 -0
  19. ripperdoc/cli/ui/panels.py +14 -8
  20. ripperdoc/cli/ui/rich_ui.py +737 -47
  21. ripperdoc/cli/ui/spinner.py +93 -18
  22. ripperdoc/cli/ui/thinking_spinner.py +1 -2
  23. ripperdoc/cli/ui/tool_renderers.py +10 -9
  24. ripperdoc/cli/ui/wizard.py +24 -19
  25. ripperdoc/core/agents.py +14 -3
  26. ripperdoc/core/config.py +238 -6
  27. ripperdoc/core/default_tools.py +91 -10
  28. ripperdoc/core/hooks/events.py +4 -0
  29. ripperdoc/core/hooks/llm_callback.py +58 -0
  30. ripperdoc/core/hooks/manager.py +6 -0
  31. ripperdoc/core/permissions.py +160 -9
  32. ripperdoc/core/providers/openai.py +84 -28
  33. ripperdoc/core/query.py +489 -87
  34. ripperdoc/core/query_utils.py +17 -14
  35. ripperdoc/core/skills.py +1 -0
  36. ripperdoc/core/theme.py +298 -0
  37. ripperdoc/core/tool.py +15 -5
  38. ripperdoc/protocol/__init__.py +14 -0
  39. ripperdoc/protocol/models.py +300 -0
  40. ripperdoc/protocol/stdio.py +1453 -0
  41. ripperdoc/tools/background_shell.py +354 -139
  42. ripperdoc/tools/bash_tool.py +117 -22
  43. ripperdoc/tools/file_edit_tool.py +228 -50
  44. ripperdoc/tools/file_read_tool.py +154 -3
  45. ripperdoc/tools/file_write_tool.py +53 -11
  46. ripperdoc/tools/grep_tool.py +98 -8
  47. ripperdoc/tools/lsp_tool.py +609 -0
  48. ripperdoc/tools/multi_edit_tool.py +26 -3
  49. ripperdoc/tools/skill_tool.py +52 -1
  50. ripperdoc/tools/task_tool.py +539 -65
  51. ripperdoc/utils/conversation_compaction.py +1 -1
  52. ripperdoc/utils/file_watch.py +216 -7
  53. ripperdoc/utils/image_utils.py +125 -0
  54. ripperdoc/utils/log.py +30 -3
  55. ripperdoc/utils/lsp.py +812 -0
  56. ripperdoc/utils/mcp.py +80 -18
  57. ripperdoc/utils/message_formatting.py +7 -4
  58. ripperdoc/utils/messages.py +198 -33
  59. ripperdoc/utils/pending_messages.py +50 -0
  60. ripperdoc/utils/permissions/shell_command_validation.py +3 -3
  61. ripperdoc/utils/permissions/tool_permission_utils.py +180 -15
  62. ripperdoc/utils/platform.py +198 -0
  63. ripperdoc/utils/session_heatmap.py +242 -0
  64. ripperdoc/utils/session_history.py +2 -2
  65. ripperdoc/utils/session_stats.py +294 -0
  66. ripperdoc/utils/shell_utils.py +8 -5
  67. ripperdoc/utils/todo.py +0 -6
  68. {ripperdoc-0.2.9.dist-info → ripperdoc-0.3.0.dist-info}/METADATA +55 -17
  69. ripperdoc-0.3.0.dist-info/RECORD +136 -0
  70. {ripperdoc-0.2.9.dist-info → ripperdoc-0.3.0.dist-info}/WHEEL +1 -1
  71. ripperdoc/sdk/__init__.py +0 -9
  72. ripperdoc/sdk/client.py +0 -333
  73. ripperdoc-0.2.9.dist-info/RECORD +0 -123
  74. {ripperdoc-0.2.9.dist-info → ripperdoc-0.3.0.dist-info}/entry_points.txt +0 -0
  75. {ripperdoc-0.2.9.dist-info → ripperdoc-0.3.0.dist-info}/licenses/LICENSE +0 -0
  76. {ripperdoc-0.2.9.dist-info → ripperdoc-0.3.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,300 @@
1
+ """Pydantic models for stdio protocol messages.
2
+
3
+ This module defines type-safe models for all JSON messages exchanged
4
+ over the stdio protocol, replacing raw dictionary construction with
5
+ validated, self-documenting Pydantic models.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ from typing import Any, Literal
11
+ from pydantic import BaseModel, Field, ConfigDict
12
+
13
+
14
+ # ============================================================================
15
+ # Content Block Models
16
+ # ============================================================================
17
+
18
+
19
+ class ContentBlock(BaseModel):
20
+ """Base class for content blocks in messages."""
21
+
22
+ model_config = ConfigDict(
23
+ extra="allow",
24
+ populate_by_name=True,
25
+ )
26
+
27
+
28
+ class TextContentBlock(ContentBlock):
29
+ """A text content block."""
30
+
31
+ type: Literal["text"] = "text"
32
+ text: str
33
+
34
+
35
+ class ThinkingContentBlock(ContentBlock):
36
+ """A thinking/reasoning content block."""
37
+
38
+ type: str = Field(default="thinking")
39
+ thinking: str = Field(alias="text")
40
+ signature: str | None = None
41
+
42
+
43
+ class ToolUseContentBlock(ContentBlock):
44
+ """A tool use content block."""
45
+
46
+ type: str = Field(default="tool_use")
47
+ id: str = Field(default="")
48
+ name: str
49
+ input: dict[str, Any] = Field(default_factory=dict)
50
+
51
+
52
+ class ToolResultContentBlock(ContentBlock):
53
+ """A tool result content block."""
54
+
55
+ type: str = Field(default="tool_result")
56
+ tool_use_id: str = Field(default="")
57
+ content: str = Field(default="")
58
+ is_error: bool | None = None
59
+
60
+
61
+ class ImageSource(BaseModel):
62
+ """Image source data."""
63
+
64
+ type: str = Field(default="base64")
65
+ media_type: str = Field(default="image/jpeg")
66
+ data: str
67
+
68
+
69
+ class ImageContentBlock(ContentBlock):
70
+ """An image content block."""
71
+
72
+ type: str = Field(default="image")
73
+ source: ImageSource
74
+
75
+
76
+ # Union type for all content blocks
77
+ ContentBlockType = (
78
+ TextContentBlock
79
+ | ThinkingContentBlock
80
+ | ToolUseContentBlock
81
+ | ToolResultContentBlock
82
+ | ImageContentBlock
83
+ )
84
+
85
+
86
+ # ============================================================================
87
+ # Message Models
88
+ # ============================================================================
89
+
90
+
91
+ class MessageData(BaseModel):
92
+ """Base message data."""
93
+
94
+ model_config = ConfigDict(
95
+ extra="allow",
96
+ populate_by_name=True,
97
+ )
98
+
99
+
100
+ class AssistantMessageData(MessageData):
101
+ """Assistant message data."""
102
+
103
+ content: list[dict[str, Any]] | str
104
+ model: str = "main"
105
+
106
+
107
+ class UserMessageData(MessageData):
108
+ """User message data."""
109
+
110
+ content: str = ""
111
+
112
+
113
+ class AssistantStreamMessage(BaseModel):
114
+ """An assistant message sent to the SDK."""
115
+
116
+ type: str = Field(default="assistant")
117
+ message: AssistantMessageData
118
+ parent_tool_use_id: str | None = None
119
+
120
+
121
+ class UserStreamMessage(BaseModel):
122
+ """A user message sent to the SDK."""
123
+
124
+ type: str = Field(default="user")
125
+ message: UserMessageData
126
+ uuid: str | None = None
127
+ parent_tool_use_id: str | None = None
128
+ tool_use_result: Any = None
129
+
130
+
131
+ # Union type for stream messages
132
+ StreamMessage = AssistantStreamMessage | UserStreamMessage
133
+
134
+
135
+ # ============================================================================
136
+ # Control Protocol Models
137
+ # ============================================================================
138
+
139
+
140
+ class ControlResponseData(BaseModel):
141
+ """Base class for control response data."""
142
+
143
+ model_config = ConfigDict(
144
+ extra="allow",
145
+ populate_by_name=True,
146
+ )
147
+
148
+
149
+ class ControlResponseSuccess(ControlResponseData):
150
+ """A successful control response."""
151
+
152
+ subtype: str = Field(default="success")
153
+ request_id: str
154
+ response: dict[str, Any] | None = None
155
+
156
+
157
+ class ControlResponseError(ControlResponseData):
158
+ """An error control response."""
159
+
160
+ subtype: str = Field(default="error")
161
+ request_id: str
162
+ error: str
163
+
164
+
165
+ class ControlResponseMessage(BaseModel):
166
+ """A control response message wrapper."""
167
+
168
+ type: str = Field(default="control_response")
169
+ response: ControlResponseSuccess | ControlResponseError
170
+
171
+
172
+ # ============================================================================
173
+ # Result/Usage Models
174
+ # ============================================================================
175
+
176
+
177
+ class UsageInfo(BaseModel):
178
+ """Token usage information."""
179
+
180
+ input_tokens: int = 0
181
+ cache_creation_input_tokens: int = 0
182
+ cache_read_input_tokens: int = 0
183
+ output_tokens: int = 0
184
+
185
+
186
+ class MCPServerInfo(BaseModel):
187
+ """MCP server information."""
188
+
189
+ name: str
190
+
191
+
192
+ class InitializeResponseData(BaseModel):
193
+ """Response data for initialize request."""
194
+
195
+ session_id: str
196
+ system_prompt: str
197
+ tools: list[str]
198
+ mcp_servers: list[MCPServerInfo] = Field(default_factory=list)
199
+ slash_commands: list[Any] = Field(default_factory=list)
200
+ apiKeySource: str = "none"
201
+ claude_code_version: str = "0.1.0"
202
+ output_style: str = "default"
203
+ agents: list[str] = Field(default_factory=list)
204
+ skills: list[Any] = Field(default_factory=list)
205
+ plugins: list[Any] = Field(default_factory=list)
206
+
207
+ model_config = ConfigDict(
208
+ extra="allow",
209
+ populate_by_name=True,
210
+ )
211
+
212
+
213
+ class ResultMessage(BaseModel):
214
+ """A result message sent at the end of a query."""
215
+
216
+ type: str = Field(default="result")
217
+ subtype: str = Field(default="result")
218
+ duration_ms: int
219
+ duration_api_ms: int
220
+ is_error: bool
221
+ num_turns: int
222
+ session_id: str
223
+ total_cost_usd: float | None = None
224
+ usage: UsageInfo | None = None
225
+ result: str | None = None
226
+ structured_output: Any = None
227
+
228
+
229
+ # ============================================================================
230
+ # Permission Response Models
231
+ # ============================================================================
232
+
233
+
234
+ class PermissionResponseAllow(BaseModel):
235
+ """A permission allow response."""
236
+
237
+ decision: str = Field(default="allow")
238
+ updatedInput: dict[str, Any] | None = None
239
+
240
+
241
+ class PermissionResponseDeny(BaseModel):
242
+ """A permission deny response."""
243
+
244
+ decision: str = Field(default="deny")
245
+ message: str = ""
246
+
247
+
248
+ # ============================================================================
249
+ # Helper Functions
250
+ # ============================================================================
251
+
252
+
253
+ def model_to_dict(model: BaseModel) -> dict[str, Any]:
254
+ """Convert a Pydantic model to a JSON-serializable dictionary.
255
+
256
+ This handles exclude_none=True and ensures proper serialization,
257
+ while always including type/subtype fields for protocol messages.
258
+
259
+ Args:
260
+ model: The Pydantic model to convert.
261
+
262
+ Returns:
263
+ A JSON-serializable dictionary.
264
+ """
265
+ return model.model_dump(exclude_none=True, by_alias=True, mode="json")
266
+
267
+
268
+ __all__ = [
269
+ # Content Blocks
270
+ "ContentBlock",
271
+ "TextContentBlock",
272
+ "ThinkingContentBlock",
273
+ "ToolUseContentBlock",
274
+ "ToolResultContentBlock",
275
+ "ImageContentBlock",
276
+ "ImageSource",
277
+ "ContentBlockType",
278
+ # Messages
279
+ "MessageData",
280
+ "AssistantMessageData",
281
+ "UserMessageData",
282
+ "AssistantStreamMessage",
283
+ "UserStreamMessage",
284
+ "StreamMessage",
285
+ # Control Protocol
286
+ "ControlResponseData",
287
+ "ControlResponseSuccess",
288
+ "ControlResponseError",
289
+ "ControlResponseMessage",
290
+ # Result/Usage
291
+ "UsageInfo",
292
+ "MCPServerInfo",
293
+ "InitializeResponseData",
294
+ "ResultMessage",
295
+ # Permissions
296
+ "PermissionResponseAllow",
297
+ "PermissionResponseDeny",
298
+ # Helpers
299
+ "model_to_dict",
300
+ ]