ripperdoc 0.2.8__py3-none-any.whl → 0.2.10__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 (94) hide show
  1. ripperdoc/__init__.py +1 -1
  2. ripperdoc/cli/cli.py +257 -123
  3. ripperdoc/cli/commands/__init__.py +2 -1
  4. ripperdoc/cli/commands/agents_cmd.py +138 -8
  5. ripperdoc/cli/commands/clear_cmd.py +9 -4
  6. ripperdoc/cli/commands/config_cmd.py +1 -1
  7. ripperdoc/cli/commands/context_cmd.py +3 -2
  8. ripperdoc/cli/commands/doctor_cmd.py +18 -4
  9. ripperdoc/cli/commands/exit_cmd.py +1 -0
  10. ripperdoc/cli/commands/hooks_cmd.py +27 -53
  11. ripperdoc/cli/commands/models_cmd.py +27 -10
  12. ripperdoc/cli/commands/permissions_cmd.py +27 -9
  13. ripperdoc/cli/commands/resume_cmd.py +9 -3
  14. ripperdoc/cli/commands/stats_cmd.py +244 -0
  15. ripperdoc/cli/commands/status_cmd.py +4 -4
  16. ripperdoc/cli/commands/tasks_cmd.py +8 -4
  17. ripperdoc/cli/ui/file_mention_completer.py +2 -1
  18. ripperdoc/cli/ui/interrupt_handler.py +2 -3
  19. ripperdoc/cli/ui/message_display.py +4 -2
  20. ripperdoc/cli/ui/panels.py +1 -0
  21. ripperdoc/cli/ui/provider_options.py +247 -0
  22. ripperdoc/cli/ui/rich_ui.py +403 -81
  23. ripperdoc/cli/ui/spinner.py +54 -18
  24. ripperdoc/cli/ui/thinking_spinner.py +1 -2
  25. ripperdoc/cli/ui/tool_renderers.py +8 -2
  26. ripperdoc/cli/ui/wizard.py +213 -0
  27. ripperdoc/core/agents.py +19 -6
  28. ripperdoc/core/config.py +51 -17
  29. ripperdoc/core/custom_commands.py +7 -6
  30. ripperdoc/core/default_tools.py +101 -12
  31. ripperdoc/core/hooks/config.py +1 -3
  32. ripperdoc/core/hooks/events.py +27 -28
  33. ripperdoc/core/hooks/executor.py +4 -6
  34. ripperdoc/core/hooks/integration.py +12 -21
  35. ripperdoc/core/hooks/llm_callback.py +59 -0
  36. ripperdoc/core/hooks/manager.py +40 -15
  37. ripperdoc/core/permissions.py +118 -12
  38. ripperdoc/core/providers/anthropic.py +109 -36
  39. ripperdoc/core/providers/gemini.py +70 -5
  40. ripperdoc/core/providers/openai.py +89 -24
  41. ripperdoc/core/query.py +273 -68
  42. ripperdoc/core/query_utils.py +2 -0
  43. ripperdoc/core/skills.py +9 -3
  44. ripperdoc/core/system_prompt.py +4 -2
  45. ripperdoc/core/tool.py +17 -8
  46. ripperdoc/sdk/client.py +79 -4
  47. ripperdoc/tools/ask_user_question_tool.py +5 -3
  48. ripperdoc/tools/background_shell.py +307 -135
  49. ripperdoc/tools/bash_output_tool.py +1 -1
  50. ripperdoc/tools/bash_tool.py +63 -24
  51. ripperdoc/tools/dynamic_mcp_tool.py +29 -8
  52. ripperdoc/tools/enter_plan_mode_tool.py +1 -1
  53. ripperdoc/tools/exit_plan_mode_tool.py +1 -1
  54. ripperdoc/tools/file_edit_tool.py +167 -54
  55. ripperdoc/tools/file_read_tool.py +28 -4
  56. ripperdoc/tools/file_write_tool.py +13 -10
  57. ripperdoc/tools/glob_tool.py +3 -2
  58. ripperdoc/tools/grep_tool.py +3 -2
  59. ripperdoc/tools/kill_bash_tool.py +1 -1
  60. ripperdoc/tools/ls_tool.py +1 -1
  61. ripperdoc/tools/lsp_tool.py +615 -0
  62. ripperdoc/tools/mcp_tools.py +13 -10
  63. ripperdoc/tools/multi_edit_tool.py +8 -7
  64. ripperdoc/tools/notebook_edit_tool.py +7 -4
  65. ripperdoc/tools/skill_tool.py +1 -1
  66. ripperdoc/tools/task_tool.py +519 -69
  67. ripperdoc/tools/todo_tool.py +2 -2
  68. ripperdoc/tools/tool_search_tool.py +3 -2
  69. ripperdoc/utils/conversation_compaction.py +9 -5
  70. ripperdoc/utils/file_watch.py +214 -5
  71. ripperdoc/utils/json_utils.py +2 -1
  72. ripperdoc/utils/lsp.py +806 -0
  73. ripperdoc/utils/mcp.py +11 -3
  74. ripperdoc/utils/memory.py +4 -2
  75. ripperdoc/utils/message_compaction.py +21 -7
  76. ripperdoc/utils/message_formatting.py +14 -7
  77. ripperdoc/utils/messages.py +126 -67
  78. ripperdoc/utils/path_ignore.py +35 -8
  79. ripperdoc/utils/permissions/path_validation_utils.py +2 -1
  80. ripperdoc/utils/permissions/shell_command_validation.py +427 -91
  81. ripperdoc/utils/permissions/tool_permission_utils.py +174 -15
  82. ripperdoc/utils/safe_get_cwd.py +2 -1
  83. ripperdoc/utils/session_heatmap.py +244 -0
  84. ripperdoc/utils/session_history.py +13 -6
  85. ripperdoc/utils/session_stats.py +293 -0
  86. ripperdoc/utils/todo.py +2 -1
  87. ripperdoc/utils/token_estimation.py +6 -1
  88. {ripperdoc-0.2.8.dist-info → ripperdoc-0.2.10.dist-info}/METADATA +8 -2
  89. ripperdoc-0.2.10.dist-info/RECORD +129 -0
  90. ripperdoc-0.2.8.dist-info/RECORD +0 -121
  91. {ripperdoc-0.2.8.dist-info → ripperdoc-0.2.10.dist-info}/WHEEL +0 -0
  92. {ripperdoc-0.2.8.dist-info → ripperdoc-0.2.10.dist-info}/entry_points.txt +0 -0
  93. {ripperdoc-0.2.8.dist-info → ripperdoc-0.2.10.dist-info}/licenses/LICENSE +0 -0
  94. {ripperdoc-0.2.8.dist-info → ripperdoc-0.2.10.dist-info}/top_level.txt +0 -0
@@ -72,10 +72,10 @@ the file if it already exists."""
72
72
  ),
73
73
  ]
74
74
 
75
- async def prompt(self, safe_mode: bool = False) -> str:
75
+ async def prompt(self, yolo_mode: bool = False) -> str:
76
76
  prompt = """Use the Write tool to create new files. """
77
77
 
78
- if safe_mode:
78
+ if not yolo_mode:
79
79
  prompt += """IMPORTANT: You must ALWAYS prefer editing existing files.
80
80
  NEVER write new files unless explicitly required by the user."""
81
81
 
@@ -104,6 +104,13 @@ NEVER write new files unless explicitly required by the user."""
104
104
 
105
105
  file_path = os.path.abspath(input_data.file_path)
106
106
 
107
+ file_path_obj = Path(file_path)
108
+ should_proceed, warning_msg = check_path_for_tool(
109
+ file_path_obj, tool_name="Write", warn_only=True
110
+ )
111
+ if warning_msg:
112
+ logger.warning("[file_write_tool] %s", warning_msg)
113
+
107
114
  # If file doesn't exist, it's a new file - allow without reading first
108
115
  if not os.path.exists(file_path):
109
116
  return ValidationResult(result=True)
@@ -132,12 +139,6 @@ NEVER write new files unless explicitly required by the user."""
132
139
  except OSError:
133
140
  pass # File mtime check failed, proceed anyway
134
141
 
135
- # Check if path is ignored (warning for write operations)
136
- file_path_obj = Path(file_path)
137
- should_proceed, warning_msg = check_path_for_tool(file_path_obj, tool_name="Write", warn_only=True)
138
- if warning_msg:
139
- logger.warning("[file_write_tool] %s", warning_msg)
140
-
141
142
  return ValidationResult(result=True)
142
143
 
143
144
  def render_result_for_assistant(self, output: FileWriteToolOutput) -> str:
@@ -171,7 +172,8 @@ NEVER write new files unless explicitly required by the user."""
171
172
  except (OSError, IOError, RuntimeError) as exc:
172
173
  logger.warning(
173
174
  "[file_write_tool] Failed to record file snapshot: %s: %s",
174
- type(exc).__name__, exc,
175
+ type(exc).__name__,
176
+ exc,
175
177
  extra={"file_path": abs_file_path},
176
178
  )
177
179
 
@@ -189,7 +191,8 @@ NEVER write new files unless explicitly required by the user."""
189
191
  except (OSError, IOError, PermissionError, UnicodeEncodeError) as e:
190
192
  logger.warning(
191
193
  "[file_write_tool] Error writing file: %s: %s",
192
- type(e).__name__, e,
194
+ type(e).__name__,
195
+ e,
193
196
  extra={"file_path": input_data.file_path},
194
197
  )
195
198
  error_output = FileWriteToolOutput(
@@ -76,7 +76,7 @@ class GlobTool(Tool[GlobToolInput, GlobToolOutput]):
76
76
  ),
77
77
  ]
78
78
 
79
- async def prompt(self, _safe_mode: bool = False) -> str:
79
+ async def prompt(self, _yolo_mode: bool = False) -> str:
80
80
  return GLOB_USAGE
81
81
 
82
82
  def is_read_only(self) -> bool:
@@ -169,7 +169,8 @@ class GlobTool(Tool[GlobToolInput, GlobToolOutput]):
169
169
  except (OSError, RuntimeError, ValueError) as e:
170
170
  logger.warning(
171
171
  "[glob_tool] Error executing glob: %s: %s",
172
- type(e).__name__, e,
172
+ type(e).__name__,
173
+ e,
173
174
  extra={"pattern": input_data.pattern, "path": input_data.path},
174
175
  )
175
176
  error_output = GlobToolOutput(matches=[], pattern=input_data.pattern, count=0)
@@ -148,7 +148,7 @@ class GrepTool(Tool[GrepToolInput, GrepToolOutput]):
148
148
  ),
149
149
  ]
150
150
 
151
- async def prompt(self, _safe_mode: bool = False) -> str:
151
+ async def prompt(self, _yolo_mode: bool = False) -> str:
152
152
  return GREP_USAGE
153
153
 
154
154
  def is_read_only(self) -> bool:
@@ -358,7 +358,8 @@ class GrepTool(Tool[GrepToolInput, GrepToolOutput]):
358
358
  except (OSError, RuntimeError, ValueError, subprocess.SubprocessError) as e:
359
359
  logger.warning(
360
360
  "[grep_tool] Error executing grep: %s: %s",
361
- type(e).__name__, e,
361
+ type(e).__name__,
362
+ e,
362
363
  extra={"pattern": input_data.pattern, "path": input_data.path},
363
364
  )
364
365
  error_output = GrepToolOutput(
@@ -53,7 +53,7 @@ class KillBashTool(Tool[KillBashInput, KillBashOutput]):
53
53
  async def description(self) -> str:
54
54
  return "Kill a background bash shell by ID"
55
55
 
56
- async def prompt(self, safe_mode: bool = False) -> str:
56
+ async def prompt(self, yolo_mode: bool = False) -> str:
57
57
  return KILL_BASH_PROMPT
58
58
 
59
59
  @property
@@ -320,7 +320,7 @@ class LSTool(Tool[LSToolInput, LSToolOutput]):
320
320
  ),
321
321
  ]
322
322
 
323
- async def prompt(self, safe_mode: bool = False) -> str:
323
+ async def prompt(self, yolo_mode: bool = False) -> str:
324
324
  return (
325
325
  "Lists files and directories in a given path. The path parameter must be an absolute path, "
326
326
  "not a relative path. You can optionally provide an array of glob patterns to ignore with "