ripperdoc 0.2.7__py3-none-any.whl → 0.2.9__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 (87) hide show
  1. ripperdoc/__init__.py +1 -1
  2. ripperdoc/cli/cli.py +33 -115
  3. ripperdoc/cli/commands/__init__.py +70 -6
  4. ripperdoc/cli/commands/agents_cmd.py +6 -3
  5. ripperdoc/cli/commands/clear_cmd.py +1 -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/help_cmd.py +11 -1
  10. ripperdoc/cli/commands/hooks_cmd.py +610 -0
  11. ripperdoc/cli/commands/models_cmd.py +26 -9
  12. ripperdoc/cli/commands/permissions_cmd.py +57 -37
  13. ripperdoc/cli/commands/resume_cmd.py +6 -4
  14. ripperdoc/cli/commands/status_cmd.py +4 -4
  15. ripperdoc/cli/commands/tasks_cmd.py +8 -4
  16. ripperdoc/cli/ui/file_mention_completer.py +64 -8
  17. ripperdoc/cli/ui/interrupt_handler.py +3 -4
  18. ripperdoc/cli/ui/message_display.py +5 -3
  19. ripperdoc/cli/ui/panels.py +13 -10
  20. ripperdoc/cli/ui/provider_options.py +247 -0
  21. ripperdoc/cli/ui/rich_ui.py +196 -77
  22. ripperdoc/cli/ui/spinner.py +25 -1
  23. ripperdoc/cli/ui/tool_renderers.py +8 -2
  24. ripperdoc/cli/ui/wizard.py +215 -0
  25. ripperdoc/core/agents.py +9 -3
  26. ripperdoc/core/config.py +49 -12
  27. ripperdoc/core/custom_commands.py +412 -0
  28. ripperdoc/core/default_tools.py +11 -2
  29. ripperdoc/core/hooks/__init__.py +99 -0
  30. ripperdoc/core/hooks/config.py +301 -0
  31. ripperdoc/core/hooks/events.py +535 -0
  32. ripperdoc/core/hooks/executor.py +496 -0
  33. ripperdoc/core/hooks/integration.py +344 -0
  34. ripperdoc/core/hooks/manager.py +745 -0
  35. ripperdoc/core/permissions.py +40 -8
  36. ripperdoc/core/providers/anthropic.py +548 -68
  37. ripperdoc/core/providers/gemini.py +70 -5
  38. ripperdoc/core/providers/openai.py +60 -5
  39. ripperdoc/core/query.py +140 -39
  40. ripperdoc/core/query_utils.py +2 -0
  41. ripperdoc/core/skills.py +9 -3
  42. ripperdoc/core/system_prompt.py +4 -2
  43. ripperdoc/core/tool.py +9 -5
  44. ripperdoc/sdk/client.py +2 -2
  45. ripperdoc/tools/ask_user_question_tool.py +5 -3
  46. ripperdoc/tools/background_shell.py +2 -1
  47. ripperdoc/tools/bash_output_tool.py +1 -1
  48. ripperdoc/tools/bash_tool.py +30 -20
  49. ripperdoc/tools/dynamic_mcp_tool.py +29 -8
  50. ripperdoc/tools/enter_plan_mode_tool.py +1 -1
  51. ripperdoc/tools/exit_plan_mode_tool.py +1 -1
  52. ripperdoc/tools/file_edit_tool.py +8 -4
  53. ripperdoc/tools/file_read_tool.py +9 -5
  54. ripperdoc/tools/file_write_tool.py +9 -5
  55. ripperdoc/tools/glob_tool.py +3 -2
  56. ripperdoc/tools/grep_tool.py +3 -2
  57. ripperdoc/tools/kill_bash_tool.py +1 -1
  58. ripperdoc/tools/ls_tool.py +1 -1
  59. ripperdoc/tools/mcp_tools.py +13 -10
  60. ripperdoc/tools/multi_edit_tool.py +8 -7
  61. ripperdoc/tools/notebook_edit_tool.py +7 -4
  62. ripperdoc/tools/skill_tool.py +1 -1
  63. ripperdoc/tools/task_tool.py +5 -4
  64. ripperdoc/tools/todo_tool.py +2 -2
  65. ripperdoc/tools/tool_search_tool.py +3 -2
  66. ripperdoc/utils/conversation_compaction.py +11 -7
  67. ripperdoc/utils/file_watch.py +8 -2
  68. ripperdoc/utils/json_utils.py +2 -1
  69. ripperdoc/utils/mcp.py +11 -3
  70. ripperdoc/utils/memory.py +4 -2
  71. ripperdoc/utils/message_compaction.py +21 -7
  72. ripperdoc/utils/message_formatting.py +11 -7
  73. ripperdoc/utils/messages.py +105 -66
  74. ripperdoc/utils/path_ignore.py +38 -12
  75. ripperdoc/utils/permissions/path_validation_utils.py +2 -1
  76. ripperdoc/utils/permissions/shell_command_validation.py +427 -91
  77. ripperdoc/utils/safe_get_cwd.py +2 -1
  78. ripperdoc/utils/session_history.py +13 -6
  79. ripperdoc/utils/todo.py +2 -1
  80. ripperdoc/utils/token_estimation.py +6 -1
  81. {ripperdoc-0.2.7.dist-info → ripperdoc-0.2.9.dist-info}/METADATA +24 -3
  82. ripperdoc-0.2.9.dist-info/RECORD +123 -0
  83. ripperdoc-0.2.7.dist-info/RECORD +0 -113
  84. {ripperdoc-0.2.7.dist-info → ripperdoc-0.2.9.dist-info}/WHEEL +0 -0
  85. {ripperdoc-0.2.7.dist-info → ripperdoc-0.2.9.dist-info}/entry_points.txt +0 -0
  86. {ripperdoc-0.2.7.dist-info → ripperdoc-0.2.9.dist-info}/licenses/LICENSE +0 -0
  87. {ripperdoc-0.2.7.dist-info → ripperdoc-0.2.9.dist-info}/top_level.txt +0 -0
@@ -26,8 +26,29 @@ class PermissionResult:
26
26
  decision: Optional[PermissionDecision] = None
27
27
 
28
28
 
29
- def _format_input_preview(parsed_input: Any) -> str:
30
- """Create a short, human-friendly preview for prompts."""
29
+ def _format_input_preview(parsed_input: Any, tool_name: Optional[str] = None) -> str:
30
+ """Create a human-friendly preview for prompts.
31
+
32
+ For Bash commands, shows full details for security review.
33
+ For other tools, shows a concise preview.
34
+ """
35
+ # For Bash tool, show full command details for security review
36
+ if tool_name == "Bash" and hasattr(parsed_input, "command"):
37
+ lines = [f"Command: {getattr(parsed_input, 'command')}"]
38
+
39
+ # Add other relevant parameters
40
+ if hasattr(parsed_input, "timeout") and parsed_input.timeout:
41
+ lines.append(f"Timeout: {parsed_input.timeout}ms")
42
+ if hasattr(parsed_input, "sandbox"):
43
+ lines.append(f"Sandbox: {parsed_input.sandbox}")
44
+ if hasattr(parsed_input, "run_in_background"):
45
+ lines.append(f"Background: {parsed_input.run_in_background}")
46
+ if hasattr(parsed_input, "shell_executable") and parsed_input.shell_executable:
47
+ lines.append(f"Shell: {parsed_input.shell_executable}")
48
+
49
+ return "\n ".join(lines)
50
+
51
+ # For other tools with commands, show concise preview
31
52
  if hasattr(parsed_input, "command"):
32
53
  return f"command='{getattr(parsed_input, 'command')}'"
33
54
  if hasattr(parsed_input, "file_path"):
@@ -94,10 +115,13 @@ def _rule_strings(rule_suggestions: Optional[Any]) -> list[str]:
94
115
 
95
116
  def make_permission_checker(
96
117
  project_path: Path,
97
- safe_mode: bool,
118
+ yolo_mode: bool,
98
119
  prompt_fn: Optional[Callable[[str], str]] = None,
99
120
  ) -> Callable[[Tool[Any, Any], Any], Awaitable[PermissionResult]]:
100
- """Create a permission checking function for the current project."""
121
+ """Create a permission checking function for the current project.
122
+
123
+ In yolo mode, all tool calls are allowed without prompting.
124
+ """
101
125
 
102
126
  project_path = project_path.resolve()
103
127
  config_manager.get_project_config(project_path)
@@ -120,7 +144,7 @@ def make_permission_checker(
120
144
  """Check and optionally persist permission for a tool invocation."""
121
145
  config = config_manager.get_project_config(project_path)
122
146
 
123
- if not safe_mode:
147
+ if yolo_mode:
124
148
  return PermissionResult(result=True)
125
149
 
126
150
  try:
@@ -130,7 +154,11 @@ def make_permission_checker(
130
154
  # Tool implementation error - log and deny for safety
131
155
  logger.warning(
132
156
  "[permissions] Tool needs_permissions check failed",
133
- extra={"tool": getattr(tool, "name", None), "error": str(exc), "error_type": type(exc).__name__},
157
+ extra={
158
+ "tool": getattr(tool, "name", None),
159
+ "error": str(exc),
160
+ "error_type": type(exc).__name__,
161
+ },
134
162
  )
135
163
  return PermissionResult(
136
164
  result=False,
@@ -172,7 +200,11 @@ def make_permission_checker(
172
200
  # Tool implementation error - fall back to asking user
173
201
  logger.warning(
174
202
  "[permissions] Tool check_permissions failed",
175
- extra={"tool": getattr(tool, "name", None), "error": str(exc), "error_type": type(exc).__name__},
203
+ extra={
204
+ "tool": getattr(tool, "name", None),
205
+ "error": str(exc),
206
+ "error_type": type(exc).__name__,
207
+ },
176
208
  )
177
209
  decision = PermissionDecision(
178
210
  behavior="ask",
@@ -203,7 +235,7 @@ def make_permission_checker(
203
235
  )
204
236
 
205
237
  # Ask/passthrough flows prompt the user.
206
- input_preview = _format_input_preview(parsed_input)
238
+ input_preview = _format_input_preview(parsed_input, tool_name=tool.name)
207
239
  prompt_lines = [
208
240
  f"{tool.name}",
209
241
  "",