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
@@ -131,6 +131,33 @@ class SkillTool(Tool[SkillToolInput, SkillToolOutput]):
131
131
  )
132
132
  return ValidationResult(result=True)
133
133
 
134
+ def _list_skill_files(self, base_dir: Path, max_depth: int = 2) -> List[str]:
135
+ """List documentation files in the skill directory (excluding SKILL.md)."""
136
+ files: List[str] = []
137
+ doc_extensions = {".md", ".txt", ".rst", ".json", ".yaml", ".yml"}
138
+
139
+ def scan_dir(dir_path: Path, depth: int, prefix: str = "") -> None:
140
+ if depth > max_depth or not dir_path.exists():
141
+ return
142
+ try:
143
+ entries = sorted(dir_path.iterdir())
144
+ except PermissionError:
145
+ return
146
+
147
+ for entry in entries:
148
+ # Skip hidden files/directories and SKILL.md
149
+ if entry.name.startswith(".") or entry.name == "SKILL.md":
150
+ continue
151
+ rel_path = f"{prefix}{entry.name}"
152
+ if entry.is_dir():
153
+ files.append(f"{rel_path}/")
154
+ scan_dir(entry, depth + 1, f"{rel_path}/")
155
+ elif entry.suffix.lower() in doc_extensions:
156
+ files.append(rel_path)
157
+
158
+ scan_dir(base_dir, 0)
159
+ return files
160
+
134
161
  def _render_result(self, skill: SkillDefinition) -> str:
135
162
  allowed = ", ".join(skill.allowed_tools) if skill.allowed_tools else "no specific limit"
136
163
  model_hint = f"\nModel hint: {skill.model}" if skill.model else ""
@@ -139,6 +166,17 @@ class SkillTool(Tool[SkillToolInput, SkillToolOutput]):
139
166
  if skill.max_thinking_tokens is not None
140
167
  else ""
141
168
  )
169
+
170
+ # List available documentation files in skill directory
171
+ skill_files = self._list_skill_files(skill.base_dir)
172
+ files_section = ""
173
+ if skill_files:
174
+ files_list = "\n".join(f" - {f}" for f in skill_files)
175
+ files_section = (
176
+ f"\n\nAvailable documentation files in skill directory (use Read tool to access when needed):\n"
177
+ f"{files_list}"
178
+ )
179
+
142
180
  lines = [
143
181
  f"Skill loaded: {skill.name} ({skill.location.value})",
144
182
  f"Description: {skill.description}",
@@ -147,7 +185,8 @@ class SkillTool(Tool[SkillToolInput, SkillToolOutput]):
147
185
  "SKILL.md content:",
148
186
  skill.content,
149
187
  ]
150
- return "\n".join(lines)
188
+ result = "\n".join(lines)
189
+ return result + files_section
151
190
 
152
191
  def _to_output(self, skill: SkillDefinition) -> SkillToolOutput:
153
192
  return SkillToolOutput(
@@ -192,6 +231,17 @@ class SkillTool(Tool[SkillToolInput, SkillToolOutput]):
192
231
  if output.max_thinking_tokens is not None
193
232
  else ""
194
233
  )
234
+
235
+ # List available documentation files in skill directory
236
+ skill_files = self._list_skill_files(Path(output.base_dir))
237
+ files_section = ""
238
+ if skill_files:
239
+ files_list = "\n".join(f" - {f}" for f in skill_files)
240
+ files_section = (
241
+ f"\n\nAvailable documentation files in skill directory (use Read tool to access when needed):\n"
242
+ f"{files_list}"
243
+ )
244
+
195
245
  return (
196
246
  f"Skill loaded: {output.skill} ({output.location})\n"
197
247
  f"Description: {output.description}\n"
@@ -199,6 +249,7 @@ class SkillTool(Tool[SkillToolInput, SkillToolOutput]):
199
249
  f"Allowed tools (if specified): {allowed}{model_hint}{max_tokens}\n"
200
250
  "SKILL.md content:\n"
201
251
  f"{output.content}"
252
+ f"{files_section}"
202
253
  )
203
254
 
204
255
  def render_tool_use_message(self, input_data: SkillToolInput, verbose: bool = False) -> str: # noqa: ARG002