ripperdoc 0.2.3__py3-none-any.whl → 0.2.5__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/__main__.py +0 -5
  3. ripperdoc/cli/cli.py +37 -16
  4. ripperdoc/cli/commands/__init__.py +2 -0
  5. ripperdoc/cli/commands/agents_cmd.py +12 -9
  6. ripperdoc/cli/commands/compact_cmd.py +7 -3
  7. ripperdoc/cli/commands/context_cmd.py +35 -15
  8. ripperdoc/cli/commands/doctor_cmd.py +27 -14
  9. ripperdoc/cli/commands/exit_cmd.py +1 -1
  10. ripperdoc/cli/commands/mcp_cmd.py +13 -8
  11. ripperdoc/cli/commands/memory_cmd.py +5 -5
  12. ripperdoc/cli/commands/models_cmd.py +47 -16
  13. ripperdoc/cli/commands/permissions_cmd.py +302 -0
  14. ripperdoc/cli/commands/resume_cmd.py +1 -2
  15. ripperdoc/cli/commands/tasks_cmd.py +24 -13
  16. ripperdoc/cli/ui/rich_ui.py +523 -396
  17. ripperdoc/cli/ui/tool_renderers.py +298 -0
  18. ripperdoc/core/agents.py +172 -4
  19. ripperdoc/core/config.py +130 -6
  20. ripperdoc/core/default_tools.py +13 -2
  21. ripperdoc/core/permissions.py +20 -14
  22. ripperdoc/core/providers/__init__.py +31 -15
  23. ripperdoc/core/providers/anthropic.py +122 -8
  24. ripperdoc/core/providers/base.py +93 -15
  25. ripperdoc/core/providers/gemini.py +539 -96
  26. ripperdoc/core/providers/openai.py +371 -26
  27. ripperdoc/core/query.py +301 -62
  28. ripperdoc/core/query_utils.py +51 -7
  29. ripperdoc/core/skills.py +295 -0
  30. ripperdoc/core/system_prompt.py +79 -67
  31. ripperdoc/core/tool.py +15 -6
  32. ripperdoc/sdk/client.py +14 -1
  33. ripperdoc/tools/ask_user_question_tool.py +431 -0
  34. ripperdoc/tools/background_shell.py +82 -26
  35. ripperdoc/tools/bash_tool.py +356 -209
  36. ripperdoc/tools/dynamic_mcp_tool.py +428 -0
  37. ripperdoc/tools/enter_plan_mode_tool.py +226 -0
  38. ripperdoc/tools/exit_plan_mode_tool.py +153 -0
  39. ripperdoc/tools/file_edit_tool.py +53 -10
  40. ripperdoc/tools/file_read_tool.py +17 -7
  41. ripperdoc/tools/file_write_tool.py +49 -13
  42. ripperdoc/tools/glob_tool.py +10 -9
  43. ripperdoc/tools/grep_tool.py +182 -51
  44. ripperdoc/tools/ls_tool.py +6 -6
  45. ripperdoc/tools/mcp_tools.py +172 -413
  46. ripperdoc/tools/multi_edit_tool.py +49 -9
  47. ripperdoc/tools/notebook_edit_tool.py +57 -13
  48. ripperdoc/tools/skill_tool.py +205 -0
  49. ripperdoc/tools/task_tool.py +91 -9
  50. ripperdoc/tools/todo_tool.py +12 -12
  51. ripperdoc/tools/tool_search_tool.py +5 -6
  52. ripperdoc/utils/coerce.py +34 -0
  53. ripperdoc/utils/context_length_errors.py +252 -0
  54. ripperdoc/utils/file_watch.py +5 -4
  55. ripperdoc/utils/json_utils.py +4 -4
  56. ripperdoc/utils/log.py +3 -3
  57. ripperdoc/utils/mcp.py +82 -22
  58. ripperdoc/utils/memory.py +9 -6
  59. ripperdoc/utils/message_compaction.py +19 -16
  60. ripperdoc/utils/messages.py +73 -8
  61. ripperdoc/utils/path_ignore.py +677 -0
  62. ripperdoc/utils/permissions/__init__.py +7 -1
  63. ripperdoc/utils/permissions/path_validation_utils.py +5 -3
  64. ripperdoc/utils/permissions/shell_command_validation.py +496 -18
  65. ripperdoc/utils/prompt.py +1 -1
  66. ripperdoc/utils/safe_get_cwd.py +5 -2
  67. ripperdoc/utils/session_history.py +38 -19
  68. ripperdoc/utils/todo.py +6 -2
  69. ripperdoc/utils/token_estimation.py +34 -0
  70. {ripperdoc-0.2.3.dist-info → ripperdoc-0.2.5.dist-info}/METADATA +14 -1
  71. ripperdoc-0.2.5.dist-info/RECORD +107 -0
  72. ripperdoc-0.2.3.dist-info/RECORD +0 -95
  73. {ripperdoc-0.2.3.dist-info → ripperdoc-0.2.5.dist-info}/WHEEL +0 -0
  74. {ripperdoc-0.2.3.dist-info → ripperdoc-0.2.5.dist-info}/entry_points.txt +0 -0
  75. {ripperdoc-0.2.3.dist-info → ripperdoc-0.2.5.dist-info}/licenses/LICENSE +0 -0
  76. {ripperdoc-0.2.3.dist-info → ripperdoc-0.2.5.dist-info}/top_level.txt +0 -0
@@ -101,15 +101,16 @@ class SessionHistory:
101
101
  msg_uuid = payload.get("uuid")
102
102
  if isinstance(msg_uuid, str):
103
103
  self._seen_ids.add(msg_uuid)
104
- except Exception as exc:
104
+ except (json.JSONDecodeError, KeyError, TypeError, ValueError) as exc:
105
105
  logger.debug(
106
- f"Failed to parse session history line: {exc}",
107
- exc_info=True,
106
+ "[session_history] Failed to parse session history line: %s: %s",
107
+ type(exc).__name__, exc,
108
108
  )
109
109
  continue
110
- except Exception:
111
- logger.exception(
112
- "Failed to load seen IDs from session",
110
+ except (OSError, IOError) as exc:
111
+ logger.warning(
112
+ "Failed to load seen IDs from session: %s: %s",
113
+ type(exc).__name__, exc,
113
114
  extra={"session_id": self.session_id, "path": str(self.path)},
114
115
  )
115
116
  return
@@ -126,6 +127,7 @@ class SessionHistory:
126
127
  payload = message.model_dump(mode="json")
127
128
  entry = {
128
129
  "logged_at": _now_iso(),
130
+ "project_path": str(self.project_path.resolve()),
129
131
  "payload": payload,
130
132
  }
131
133
  try:
@@ -134,10 +136,11 @@ class SessionHistory:
134
136
  fh.write("\n")
135
137
  if isinstance(msg_uuid, str):
136
138
  self._seen_ids.add(msg_uuid)
137
- except Exception:
139
+ except (OSError, IOError) as exc:
138
140
  # Avoid crashing the UI if logging fails
139
- logger.exception(
140
- "Failed to append message to session log",
141
+ logger.warning(
142
+ "Failed to append message to session log: %s: %s",
143
+ type(exc).__name__, exc,
141
144
  extra={"session_id": self.session_id, "path": str(self.path)},
142
145
  )
143
146
  return
@@ -149,18 +152,33 @@ def list_session_summaries(project_path: Path) -> List[SessionSummary]:
149
152
  if not directory.exists():
150
153
  return []
151
154
 
155
+ current_project = str(project_path.resolve())
152
156
  summaries: List[SessionSummary] = []
153
157
  for jsonl_path in directory.glob("*.jsonl"):
154
158
  try:
155
159
  with jsonl_path.open("r", encoding="utf-8") as fh:
156
160
  messages = [json.loads(line) for line in fh if line.strip()]
157
- except Exception as exc:
158
- logger.exception(
159
- "Failed to load session summary",
160
- extra={"path": str(jsonl_path), "error": str(exc)},
161
+ except (OSError, IOError, json.JSONDecodeError) as exc:
162
+ logger.warning(
163
+ "Failed to load session summary: %s: %s",
164
+ type(exc).__name__, exc,
165
+ extra={"path": str(jsonl_path)},
161
166
  )
162
167
  continue
163
168
 
169
+ # Check if this session belongs to the current project
170
+ # If any message has a project_path field, use it to verify
171
+ session_project_path = None
172
+ for entry in messages:
173
+ entry_path = entry.get("project_path")
174
+ if entry_path:
175
+ session_project_path = entry_path
176
+ break
177
+
178
+ # Skip sessions that belong to a different project
179
+ if session_project_path and session_project_path != current_project:
180
+ continue
181
+
164
182
  payloads = [entry.get("payload") or {} for entry in messages]
165
183
  conversation_payloads = [
166
184
  payload for payload in payloads if payload.get("type") in ("user", "assistant")
@@ -217,15 +235,16 @@ def load_session_messages(project_path: Path, session_id: str) -> List[Conversat
217
235
  msg = _deserialize_message(payload)
218
236
  if msg is not None and getattr(msg, "type", None) != "progress":
219
237
  messages.append(msg)
220
- except Exception as exc:
238
+ except (json.JSONDecodeError, KeyError, TypeError, ValueError) as exc:
221
239
  logger.debug(
222
- f"Failed to deserialize message in session {session_id}: {exc}",
223
- exc_info=True,
240
+ "[session_history] Failed to deserialize message in session %s: %s: %s",
241
+ session_id, type(exc).__name__, exc,
224
242
  )
225
243
  continue
226
- except Exception:
227
- logger.exception(
228
- "Failed to load session messages",
244
+ except (OSError, IOError) as exc:
245
+ logger.warning(
246
+ "Failed to load session messages: %s: %s",
247
+ type(exc).__name__, exc,
229
248
  extra={"session_id": session_id, "path": str(path)},
230
249
  )
231
250
  return []
ripperdoc/utils/todo.py CHANGED
@@ -83,8 +83,12 @@ def load_todos(project_root: Optional[Path] = None) -> List[TodoItem]:
83
83
 
84
84
  try:
85
85
  raw = json.loads(path.read_text())
86
- except Exception:
87
- logger.exception("Failed to load todos from disk", extra={"path": str(path)})
86
+ except (json.JSONDecodeError, OSError, IOError, UnicodeDecodeError) as exc:
87
+ logger.warning(
88
+ "Failed to load todos from disk: %s: %s",
89
+ type(exc).__name__, exc,
90
+ extra={"path": str(path)},
91
+ )
88
92
  return []
89
93
 
90
94
  todos: List[TodoItem] = []
@@ -0,0 +1,34 @@
1
+ """Shared token estimation utilities."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import math
6
+
7
+ from ripperdoc.utils.log import get_logger
8
+
9
+ logger = get_logger()
10
+
11
+ # Optional: use tiktoken for accurate counts when available.
12
+ _TIKTOKEN_ENCODING: tiktoken.Encoding | None = None
13
+ try: # pragma: no cover - optional dependency
14
+ import tiktoken # type: ignore
15
+
16
+ _TIKTOKEN_ENCODING = tiktoken.get_encoding("cl100k_base")
17
+ except (ImportError, ModuleNotFoundError, OSError, RuntimeError): # pragma: no cover - runtime fallback
18
+ pass
19
+
20
+
21
+ def estimate_tokens(text: str) -> int:
22
+ """Estimate token count, preferring tiktoken when available."""
23
+ if not text:
24
+ return 0
25
+ if _TIKTOKEN_ENCODING:
26
+ try:
27
+ return len(_TIKTOKEN_ENCODING.encode(text))
28
+ except (UnicodeDecodeError, ValueError, RuntimeError):
29
+ logger.debug("[token_estimation] tiktoken encode failed; falling back to heuristic")
30
+ # Heuristic: ~4 characters per token
31
+ return max(1, math.ceil(len(text) / 4))
32
+
33
+
34
+ __all__ = ["estimate_tokens"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ripperdoc
3
- Version: 0.2.3
3
+ Version: 0.2.5
4
4
  Summary: AI-powered terminal assistant for coding tasks
5
5
  Author: Ripperdoc Team
6
6
  License: Apache-2.0
@@ -25,6 +25,8 @@ Requires-Dist: prompt-toolkit>=3.0.0
25
25
  Requires-Dist: PyYAML>=6.0.0
26
26
  Requires-Dist: mcp[cli]>=1.22.0
27
27
  Requires-Dist: json_repair>=0.54.2
28
+ Requires-Dist: tiktoken>=0.7.0
29
+ Requires-Dist: google-genai>=0.3.0
28
30
  Provides-Extra: dev
29
31
  Requires-Dist: pytest>=7.0.0; extra == "dev"
30
32
  Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
@@ -48,6 +50,7 @@ Ripperdoc is an AI-powered terminal assistant for coding tasks, providing an int
48
50
  - **Codebase Understanding** - Analyzes project structure and code relationships
49
51
  - **Command Execution** - Run shell commands with real-time feedback
50
52
  - **Tool System** - Extensible architecture with specialized tools
53
+ - **Agent Skills** - Load SKILL.md bundles to extend the agent on demand
51
54
  - **Subagents** - Delegate tasks to specialized agents with their own tool scopes
52
55
  - **File Operations** - Read, write, edit, search, and manage files
53
56
  - **Todo Tracking** - Plan, read, and update persistent todo lists per project
@@ -115,6 +118,16 @@ See the [examples/](examples/) directory for complete SDK usage examples.
115
118
 
116
119
  Safe mode is the default. Use `--unsafe` to skip permission prompts. Choose `a`/`always` to allow a tool for the current session (not persisted across sessions).
117
120
 
121
+ ### Agent Skills
122
+
123
+ Extend Ripperdoc with reusable Skill bundles:
124
+
125
+ - Personal skills live in `~/.ripperdoc/skills/<skill-name>/SKILL.md`
126
+ - Project skills live in `.ripperdoc/skills/<skill-name>/SKILL.md` and can be checked into git
127
+ - Each `SKILL.md` starts with YAML frontmatter (`name`, `description`, optional `allowed-tools`, `model`, `max-thinking-tokens`, `disable-model-invocation`) followed by the instructions; add supporting files alongside it
128
+ - Model and max-thinking-token hints from skills are applied automatically for the rest of the session after you load them with the `Skill` tool
129
+ - Ripperdoc exposes skill names/descriptions in the system prompt and loads full content on demand via the `Skill` tool
130
+
118
131
  ## Examples
119
132
 
120
133
  ### Code Analysis
@@ -0,0 +1,107 @@
1
+ ripperdoc/__init__.py,sha256=yu1UEi-eeA10beQYjks__erioKMDvDfpz-KL5K9UIJc,66
2
+ ripperdoc/__main__.py,sha256=1Avq2MceBfwUlNsfasC8n4dqVL_V56Bl3DRsnY4_Nxk,370
3
+ ripperdoc/cli/__init__.py,sha256=03wf6gXBcEgXJrDJS-W_5BEG_DdJ_ep7CxQFPML-73g,35
4
+ ripperdoc/cli/cli.py,sha256=ECbi5Rm8prKkNtiv4P191ftSMEMSwYIG2LKC5IJXyIk,14140
5
+ ripperdoc/cli/commands/__init__.py,sha256=rSB7hmuMRBfqYCxuUMsdb3-8mloKQyfOTinXU3wm3Uo,2414
6
+ ripperdoc/cli/commands/agents_cmd.py,sha256=YDE9oIXPmsPyvkHhq95aXxnneN3PqZ1ZOtcn26cXeO8,10438
7
+ ripperdoc/cli/commands/base.py,sha256=4KUjxCM04MwbSMUKVNEBph_jeAKPI8b5MHsUFoz7l5g,386
8
+ ripperdoc/cli/commands/clear_cmd.py,sha256=zSYT0Nn_htZzLWTTQ4E5KWHfRg0Q5CYvRO4e--7thBY,345
9
+ ripperdoc/cli/commands/compact_cmd.py,sha256=uR_nB1OX7cUL1TOJoefwdO31Qfyjd0nZSSttErqUxbA,473
10
+ ripperdoc/cli/commands/config_cmd.py,sha256=ebIQk7zUFv353liWfbBSSfPiOaaCR7rQsd_eTw7nsvY,884
11
+ ripperdoc/cli/commands/context_cmd.py,sha256=6Yrz3_Oa2NwEsZo4tLK_PFFYP0Vq-amQCMBomSVFmBo,5220
12
+ ripperdoc/cli/commands/cost_cmd.py,sha256=yD9LSqgxVvYNTDPnEHxugjyLWcmbtH5dXim7DIW9zXc,2822
13
+ ripperdoc/cli/commands/doctor_cmd.py,sha256=q_PO1mnknRysVG7uopiqDWvkIIcvRX2i-JWgfKN-0gQ,7052
14
+ ripperdoc/cli/commands/exit_cmd.py,sha256=ASOoLeXarbWK2vdC0223s98qmAMMRh1lcJPX0Qe5o7c,327
15
+ ripperdoc/cli/commands/help_cmd.py,sha256=iz1vR-rmWsvvfzdebLiIWEWrcMZo5_Eb55_wLr4Ufno,508
16
+ ripperdoc/cli/commands/mcp_cmd.py,sha256=ZCnswx0TIiaiUUsIX7NpHaLZLZtvlUhBnN12s_ZtPCA,2424
17
+ ripperdoc/cli/commands/memory_cmd.py,sha256=gDvRr_-U1gMrOdC3OvujYLL5_CUgyZpwaJdytRP5CBM,6549
18
+ ripperdoc/cli/commands/models_cmd.py,sha256=p6IeV_K9BjOahmtqmI2Gu7xsqRagVsIPYy7FEeuKQWQ,16135
19
+ ripperdoc/cli/commands/permissions_cmd.py,sha256=3ERLLYTLUFW7jV7uo29i6SmLxrizpK4LXayLrPZbB1U,10827
20
+ ripperdoc/cli/commands/resume_cmd.py,sha256=to-904VX5TVT60-YF92WTUKF-IBRf30UN4dZnLvHKME,2997
21
+ ripperdoc/cli/commands/status_cmd.py,sha256=yM_c_GgoAL7CMH_ucGSwUhlbHggxYuvCEb4AXtpN-8s,5534
22
+ ripperdoc/cli/commands/tasks_cmd.py,sha256=QrRF9MKg6LIH9BQz5E39KKdrwMiI3HTvI-c14aM7BU0,8815
23
+ ripperdoc/cli/commands/todos_cmd.py,sha256=7Q0B1NVqGtB3R29ndbn4m0VQQm-YQ7d4Wlk7vJ7dLQI,1848
24
+ ripperdoc/cli/commands/tools_cmd.py,sha256=3cMi0vN4mAUhpKqJtRgNvZfcKzRPaMs_pkYYXlyvSSU,384
25
+ ripperdoc/cli/ui/__init__.py,sha256=TxSzTYdITlrYmYVfins_w_jzPqqWRpqky5u1ikwvmtM,43
26
+ ripperdoc/cli/ui/context_display.py,sha256=3ezdtHVwltkPQ5etYwfqUh-fjnpPu8B3P81UzrdHxZs,10020
27
+ ripperdoc/cli/ui/helpers.py,sha256=TJCipP0neh-96ETQfGhusCJ4aWt5gLw1HZbI-3bWDpw,739
28
+ ripperdoc/cli/ui/rich_ui.py,sha256=I8jX_Cl6DyW7BVX2HPA8bJW-INyI4mfGujGUThd9g3M,54659
29
+ ripperdoc/cli/ui/spinner.py,sha256=XsPRwJ-70InLX9Qw50CEgSHn5oKA5PFIue8Un4edhUk,1449
30
+ ripperdoc/cli/ui/thinking_spinner.py,sha256=9Et5EqPChfkmkiOO8w1OPs8t-sHaisgjn9A__kEYLyg,2824
31
+ ripperdoc/cli/ui/tool_renderers.py,sha256=cG0aFa8alIYJryG9tV6a7arslMN-iN8bAF5Q2XNL5Dc,11195
32
+ ripperdoc/core/__init__.py,sha256=UemJCA-Y8df1466AX-YbRFj071zKajmqO1mi40YVW2g,40
33
+ ripperdoc/core/agents.py,sha256=2aOvGEdj-P7MVMPtcFT4mAFIWeaFLSd6aVTqXtNjew0,19930
34
+ ripperdoc/core/commands.py,sha256=NXCkljYbAP4dDoRy-_3semFNWxG4YAk9q82u8FTKH60,835
35
+ ripperdoc/core/config.py,sha256=fuzXTSSpPFIkzgZJW-tOf18cNeemrot64ihO4cdM79g,20979
36
+ ripperdoc/core/default_tools.py,sha256=fHmqIlPIE9qGwmgeYYw-QepKRoQLMhclnCv6Qahews0,3090
37
+ ripperdoc/core/permissions.py,sha256=_WLWE7Kq-Z5j3zEDAPr8JqdT0fz2oFqNs18NL0qoeWQ,9768
38
+ ripperdoc/core/query.py,sha256=oEpDyh2xT8hje0VmQY-C3hi7Ze8R49jbJN_W-sPdhgM,38268
39
+ ripperdoc/core/query_utils.py,sha256=PA2rmHBwT5dczF8YYfbrL3QWrfNxQOhCA57G1Z-XBXE,24776
40
+ ripperdoc/core/skills.py,sha256=XkMt3WPT2_0xfx2qQhEnBbwJ0121aRFmuXLckw3MtVU,10251
41
+ ripperdoc/core/system_prompt.py,sha256=smhuRfzbvhfzNsQ3D89Mucll16u_40VWpOzKS0kJPFQ,26724
42
+ ripperdoc/core/tool.py,sha256=y4Er5Dp2yWO0JeXFlOSy-mWvzkN-P_zJiZsDmjG7qYg,7616
43
+ ripperdoc/core/providers/__init__.py,sha256=yevsHF0AUI4b6Wiq_401NXewJ3dqe8LUUtQm0TLPPNQ,1911
44
+ ripperdoc/core/providers/anthropic.py,sha256=XNv_LhQTBrsFN5dB5rdYrNikBQ6Qq4sEu_PxukJXuks,10257
45
+ ripperdoc/core/providers/base.py,sha256=HNOa3_XWszu6DbI8BYixxV0hnZb9qZ_FU4uinFVRHjU,9271
46
+ ripperdoc/core/providers/gemini.py,sha256=3U69Gh6hiL8QWsf-nawZJTfh5oeZP5DAmXYDfWtrEQE,24786
47
+ ripperdoc/core/providers/openai.py,sha256=FiNTCBtFpq0i0K6S0OyC-F-0HssSWJE6jrH3xRsPzD4,20981
48
+ ripperdoc/sdk/__init__.py,sha256=aDSgI4lcCDs9cV3bxNmEEV3SuYx2aCd4VnUjs6H-R7E,213
49
+ ripperdoc/sdk/client.py,sha256=aNnFs8pE2IUslXcHEtEUtkCHrDztAtq9moddjlOVxZs,11357
50
+ ripperdoc/tools/__init__.py,sha256=RBFz0DDnztDXMqv_zRxFHVY-ez2HYcncx8zh_y-BX6w,42
51
+ ripperdoc/tools/ask_user_question_tool.py,sha256=QgzmIDVR-wdlLf9fSiVPbRm_8tSaIlGJhuuRYOCGiUU,15446
52
+ ripperdoc/tools/background_shell.py,sha256=HangGLwN4iy-udo02zUZF3QRPIqOa7sVDesbv2wL9Js,12854
53
+ ripperdoc/tools/bash_output_tool.py,sha256=ljIOzTOnkbQfe3jExlhpUlMiLT6HpeD-1QI-D1CwHh8,3379
54
+ ripperdoc/tools/bash_tool.py,sha256=YE4mZWLLrfgdEsKkhTu2wNRx-JEYWVgyhVEpbDS4qHQ,42003
55
+ ripperdoc/tools/dynamic_mcp_tool.py,sha256=GERh7qT1mPVivFUIhlFxPNRUwOGNw5CmCnymEwQ-7vk,15662
56
+ ripperdoc/tools/enter_plan_mode_tool.py,sha256=FYjm_TmBL55pY4GdP7t0ISlqg-Qe3DwpIt-2weL1S4s,7976
57
+ ripperdoc/tools/exit_plan_mode_tool.py,sha256=3smkwGLTITem5fgA8catSSRay_a1OGQrjs8JF1zDdUQ,5756
58
+ ripperdoc/tools/file_edit_tool.py,sha256=56MlfE1BdtHIo9TFXmNIuSiRaoY-2xopCbWLRNZKOAc,13639
59
+ ripperdoc/tools/file_read_tool.py,sha256=3kfE5KEOvCcFieNND7e0ylWnAIbfQ-ZtQHIHKTOT-jY,7276
60
+ ripperdoc/tools/file_write_tool.py,sha256=9NgojNtjoi-TX6vUFLlcobh4alWPZvUmmRkmGxGPZIk,6915
61
+ ripperdoc/tools/glob_tool.py,sha256=oy1S-MrQl57X_wpNXcqXyE4oHI3kmpOQoTYavx3mzEg,5932
62
+ ripperdoc/tools/grep_tool.py,sha256=n_YNKg8w63JgVJVpg7Qakj75JrymeKByNoapl8IS05U,14125
63
+ ripperdoc/tools/kill_bash_tool.py,sha256=36F8w2Rm1IVQitwOAwS-D8NTnyQdWfKWIam44qlXErk,4625
64
+ ripperdoc/tools/ls_tool.py,sha256=x0nw7F5cWjKK7Vb66nqdg9djgupPpCTwPAqd5rZlMUs,15367
65
+ ripperdoc/tools/mcp_tools.py,sha256=P0wbk_WRUD_MVkLDpMjttjQ13nje8Zc-mR3ud94QqZ0,23018
66
+ ripperdoc/tools/multi_edit_tool.py,sha256=da9WUvQRp8ZOm7G6OUUJhKIL4h0unjHSjg-oNco_NuE,17579
67
+ ripperdoc/tools/notebook_edit_tool.py,sha256=jCdB33d61EYUKpqNpIHrxs4zBmcLfu3mNu2VMwpX_64,14269
68
+ ripperdoc/tools/skill_tool.py,sha256=vquTDL8ZihGvgP6U6EswOm5IjQYFHwxIiLzlzCEWrVw,7701
69
+ ripperdoc/tools/task_tool.py,sha256=EcUAaWY3aTTZawE84wvk2LyHSNU7nXAbpeDoOjU4_K0,18325
70
+ ripperdoc/tools/todo_tool.py,sha256=9LpU5PZpnXacvtcY41z6qeFow8n15uCtk9ELBUAFCtI,20001
71
+ ripperdoc/tools/tool_search_tool.py,sha256=97v_5Epbr-qeltrCtJkwB73weegcF_TE8TeuqATXl3g,13870
72
+ ripperdoc/utils/__init__.py,sha256=gdso60znB2hsYZ_YZBKVcuOY3QVfoqD2wHQ4pvr5lSw,37
73
+ ripperdoc/utils/bash_constants.py,sha256=KNn8bzB6nVU5jid9jvjiH4FAu8pP3DZONJ-OknJypAQ,1641
74
+ ripperdoc/utils/bash_output_utils.py,sha256=3Cf5wKJzRbUesmCNy5HtXIBtv0Z2BxklTfFHJ9q1T3w,1210
75
+ ripperdoc/utils/coerce.py,sha256=KOPb4KR4p32nwHWG_6GsGHeVZunJyYc2YhC5DLmEZO8,1015
76
+ ripperdoc/utils/context_length_errors.py,sha256=oyDVr_ME_6j97TLwVZ8bDMb6ISGQx6wEHrY7ckc0GuA,7714
77
+ ripperdoc/utils/exit_code_handlers.py,sha256=QtO1iDxVAb8Xp03D6_QixPoJC-RQlcp3ssIo_rm4two,7973
78
+ ripperdoc/utils/file_watch.py,sha256=CoUIcLuS-VcfxotuxFkel5KpNluMmLGJKDzx26MG3yY,4039
79
+ ripperdoc/utils/git_utils.py,sha256=Hq-Zx-KPyX4lp_i8ozhic15LyYdX_IfCRm-EyoFu59A,9047
80
+ ripperdoc/utils/json_utils.py,sha256=e12eMpWlLDniHZVg7zdOkXw5wBZhnjhVtDm8tpBEOjk,741
81
+ ripperdoc/utils/log.py,sha256=mieFMPxiv-M87bB-dgiY8D5WMxQbjVKJdsrW8QvCui8,6138
82
+ ripperdoc/utils/mcp.py,sha256=xszG3kDrlctVVZvXOHr7wgndthpu-AwMySSwpnaHFGc,19445
83
+ ripperdoc/utils/memory.py,sha256=KNB8Eoobl0vgIEh6phXKtGmDUct7_DNQH-F6Il4KRDQ,8009
84
+ ripperdoc/utils/message_compaction.py,sha256=9OX7eDYaUEbolGzqWk_4Uz-S1wrxahI2b6EfrOcS98Y,25063
85
+ ripperdoc/utils/messages.py,sha256=b34bl7pvX3RSPKO0EbDQwve_ZEy88VkiSww5s3kB-Wk,20265
86
+ ripperdoc/utils/output_utils.py,sha256=R3wqFh9Dko_GK00Exx7XI0DnnldRWMsxZypYX5y6SJo,7448
87
+ ripperdoc/utils/path_ignore.py,sha256=2THb4h__cnFz_mZoR6gchDFiIirxSvsbcEKONJhiAQQ,17607
88
+ ripperdoc/utils/path_utils.py,sha256=C45Q3OeXnj-0FVEtvf_tdG5922XB6HthUzlUCvfc17Y,1626
89
+ ripperdoc/utils/prompt.py,sha256=zICNEsA_OtKx8t3zo9tHLXXu6G5K8rPO3jFLKz4j5tg,560
90
+ ripperdoc/utils/safe_get_cwd.py,sha256=IvG8dIJd2tC5_glUsfeWXkpcF1EHzdkjFtuUGJd669w,815
91
+ ripperdoc/utils/sandbox_utils.py,sha256=G91P8dw2VFcCiCpjXZ4LvzbAPiO8REqMhw39eI5Z4dU,1123
92
+ ripperdoc/utils/session_history.py,sha256=M7TzmXibbWwh1xjHi_v3RfogaN6ZlKvfBYGRrsJp2hE,8978
93
+ ripperdoc/utils/session_usage.py,sha256=p8_s46zDTzV1qzP4HR4PuZmLeJvSfq9mG_Y5rCnRYyA,3213
94
+ ripperdoc/utils/shell_token_utils.py,sha256=SduoSU-RERJdM_7gBn0urr5UXtl4XOpPgydBd2fwzWg,2500
95
+ ripperdoc/utils/shell_utils.py,sha256=t-neFPy_VhEmWZ79J7hh1ULBEdX116Rb9_pnXvir1Jw,5235
96
+ ripperdoc/utils/todo.py,sha256=6aj3-AuKaY93bzljsIpvZlM_O8CPgnRROSLEEgzaMHU,7039
97
+ ripperdoc/utils/token_estimation.py,sha256=t98_zC95CZaA95A-1yu9H4p9r_IOjelspl2qqBLVyf8,1047
98
+ ripperdoc/utils/permissions/__init__.py,sha256=33FfOaDLepxJSkp0RLvTdVu7qBXuEcnOoTHFbEtFOt0,653
99
+ ripperdoc/utils/permissions/path_validation_utils.py,sha256=BkEcyfG253XGfdUU1V3VeScgBv_rl6YNMqU1TMgvmLE,5756
100
+ ripperdoc/utils/permissions/shell_command_validation.py,sha256=94ylqoDUiTF4v4wEiVS35jFJakyaSxdIFqYKumPTrGk,21205
101
+ ripperdoc/utils/permissions/tool_permission_utils.py,sha256=6Fdu9-dMKhLsUExjEjoS0EUeRpEVN5UkqyseIC05YmM,9207
102
+ ripperdoc-0.2.5.dist-info/licenses/LICENSE,sha256=bRv9UhBor6GhnQDj12RciDcRfu0R7sB-lqCy1sWF75c,9242
103
+ ripperdoc-0.2.5.dist-info/METADATA,sha256=ploMbgX_AJ9oAmN2Bxi7PTiwGhTuYyMK9sP27FiQOQI,6218
104
+ ripperdoc-0.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
105
+ ripperdoc-0.2.5.dist-info/entry_points.txt,sha256=79aohFxFPJmrQ3-Mhain04vb3EWpuc0EyzvDDUnwAu4,81
106
+ ripperdoc-0.2.5.dist-info/top_level.txt,sha256=u8LbdTr1a-laHgCO0Utl_R3QGFUhLxWelCDnP2ZgpCU,10
107
+ ripperdoc-0.2.5.dist-info/RECORD,,
@@ -1,95 +0,0 @@
1
- ripperdoc/__init__.py,sha256=UNSvPbYxqTbZJseto7Btn4nFqfZkKezUBuwPQuI2yOk,66
2
- ripperdoc/__main__.py,sha256=7oIFEXI2irIoZ_dhcMd3hCs4Dj8tmMBbwiVACAoeE-k,506
3
- ripperdoc/cli/__init__.py,sha256=03wf6gXBcEgXJrDJS-W_5BEG_DdJ_ep7CxQFPML-73g,35
4
- ripperdoc/cli/cli.py,sha256=fszg31t6QyWeBEM6PkoidpwamYXvYQScKCSSq8F8uHM,13043
5
- ripperdoc/cli/commands/__init__.py,sha256=J13i7g-69PVLhO5IJH5OvVK0FJLIFj0b84mm33JvpcE,2329
6
- ripperdoc/cli/commands/agents_cmd.py,sha256=Iq_sycFhLnEK8o1agdxy0yFXt38DhLIQoxETXM4aVRs,10183
7
- ripperdoc/cli/commands/base.py,sha256=4KUjxCM04MwbSMUKVNEBph_jeAKPI8b5MHsUFoz7l5g,386
8
- ripperdoc/cli/commands/clear_cmd.py,sha256=zSYT0Nn_htZzLWTTQ4E5KWHfRg0Q5CYvRO4e--7thBY,345
9
- ripperdoc/cli/commands/compact_cmd.py,sha256=C_qdPTPdg1cOHdmODkaYoRusosgiqRK6c6KID_Gwq0k,330
10
- ripperdoc/cli/commands/config_cmd.py,sha256=ebIQk7zUFv353liWfbBSSfPiOaaCR7rQsd_eTw7nsvY,884
11
- ripperdoc/cli/commands/context_cmd.py,sha256=d0KiJyjbuDNXYlfSzVTFmxmkLXJZe3pUDg_Tt67OWqs,4359
12
- ripperdoc/cli/commands/cost_cmd.py,sha256=yD9LSqgxVvYNTDPnEHxugjyLWcmbtH5dXim7DIW9zXc,2822
13
- ripperdoc/cli/commands/doctor_cmd.py,sha256=JQVexktceKTBMml5MO-V86IsDsSqXcSA8igw2zf3Qpo,6655
14
- ripperdoc/cli/commands/exit_cmd.py,sha256=B0CNKQos2eRC4LSjizLdKsFYzFfwRkrUur6Afu3Fh9M,334
15
- ripperdoc/cli/commands/help_cmd.py,sha256=iz1vR-rmWsvvfzdebLiIWEWrcMZo5_Eb55_wLr4Ufno,508
16
- ripperdoc/cli/commands/mcp_cmd.py,sha256=S0iQxclxqgbIxbKcC9oFrckLalzk-1eyAYwkfEZQsGU,2307
17
- ripperdoc/cli/commands/memory_cmd.py,sha256=Wu8Mh72jBY_9A-hEnW430by0piSOOlGx9PJd4IdpVVs,6494
18
- ripperdoc/cli/commands/models_cmd.py,sha256=WM4UYEISQkSOqquNIftzkciscqjaj8DNyq9Oa-b6CMU,14367
19
- ripperdoc/cli/commands/resume_cmd.py,sha256=dJNZ44UvJImGKMrVrgiYw5NSK-vTUnp9GxduvIXtmf8,3013
20
- ripperdoc/cli/commands/status_cmd.py,sha256=yM_c_GgoAL7CMH_ucGSwUhlbHggxYuvCEb4AXtpN-8s,5534
21
- ripperdoc/cli/commands/tasks_cmd.py,sha256=lgVzN6_KFQGltb7bgn4Wwmkuq91H_mgzCrga67hgjT4,8292
22
- ripperdoc/cli/commands/todos_cmd.py,sha256=7Q0B1NVqGtB3R29ndbn4m0VQQm-YQ7d4Wlk7vJ7dLQI,1848
23
- ripperdoc/cli/commands/tools_cmd.py,sha256=3cMi0vN4mAUhpKqJtRgNvZfcKzRPaMs_pkYYXlyvSSU,384
24
- ripperdoc/cli/ui/__init__.py,sha256=TxSzTYdITlrYmYVfins_w_jzPqqWRpqky5u1ikwvmtM,43
25
- ripperdoc/cli/ui/context_display.py,sha256=3ezdtHVwltkPQ5etYwfqUh-fjnpPu8B3P81UzrdHxZs,10020
26
- ripperdoc/cli/ui/helpers.py,sha256=TJCipP0neh-96ETQfGhusCJ4aWt5gLw1HZbI-3bWDpw,739
27
- ripperdoc/cli/ui/rich_ui.py,sha256=Qs0rzd-P56Bkd6W7uHXjV2R3pCFAloZOwe2F6fds_L4,51991
28
- ripperdoc/cli/ui/spinner.py,sha256=XsPRwJ-70InLX9Qw50CEgSHn5oKA5PFIue8Un4edhUk,1449
29
- ripperdoc/cli/ui/thinking_spinner.py,sha256=9Et5EqPChfkmkiOO8w1OPs8t-sHaisgjn9A__kEYLyg,2824
30
- ripperdoc/core/__init__.py,sha256=UemJCA-Y8df1466AX-YbRFj071zKajmqO1mi40YVW2g,40
31
- ripperdoc/core/agents.py,sha256=kGVLTcXVwOwrRBvvC9E_tKaQJ5u-wChIYE2VqYMJx00,10348
32
- ripperdoc/core/commands.py,sha256=NXCkljYbAP4dDoRy-_3semFNWxG4YAk9q82u8FTKH60,835
33
- ripperdoc/core/config.py,sha256=DRPi8uzfBmRKefcqlRKLDf4zYYsj0sxF42ROUZ10GN8,15709
34
- ripperdoc/core/default_tools.py,sha256=t8cLZBOVReF5hvmyhUTziUSnnDMyKDjS7YjuSd_yolw,2568
35
- ripperdoc/core/permissions.py,sha256=qWaVIaps9Ht0M4jgDk9J0gDErptvf6jzEZ2t48lZ_1I,9187
36
- ripperdoc/core/query.py,sha256=nxi8Q2JH2VHfCsb5FbwQ1k-ZObt2xeAqovsYQVJ9Yjc,29190
37
- ripperdoc/core/query_utils.py,sha256=dmbuFM_PZOntBHBLkyzq0-OubH1z3GF_Nn80aChT_TA,22940
38
- ripperdoc/core/system_prompt.py,sha256=QH7Wg8QqwzvAzjuBayr57w-BazqIQrHfuGvC2KqVkgI,24190
39
- ripperdoc/core/tool.py,sha256=QEmkygAiXsBK3NBnJnL2NevrcgRpG83OIA0TAwuc7OQ,7027
40
- ripperdoc/core/providers/__init__.py,sha256=CSqOeET3UowMQV3esmAHI7JfsyYV-m-C5vC6VutI-fY,888
41
- ripperdoc/core/providers/anthropic.py,sha256=vqQfbGOGKpPEHVc7x4uJFE_nHtWCgiK65KGslVarJkU,5139
42
- ripperdoc/core/providers/base.py,sha256=cwkWUvLzWxesKI-xzvj1STIlMPNgyKGvCBCLIpZgV9c,6604
43
- ripperdoc/core/providers/gemini.py,sha256=aS93WBcLzk871DavETNmS5IYaodQEsVWbS19GhGBYOk,6409
44
- ripperdoc/core/providers/openai.py,sha256=pYMeTQvmnAfT-BimnymDp_7zieNShkfd9573A4S0U7k,5594
45
- ripperdoc/sdk/__init__.py,sha256=aDSgI4lcCDs9cV3bxNmEEV3SuYx2aCd4VnUjs6H-R7E,213
46
- ripperdoc/sdk/client.py,sha256=gkduot4gvN1k41WVkHCpiuU7wGLL-SFG-KTTQrMomWc,10814
47
- ripperdoc/tools/__init__.py,sha256=RBFz0DDnztDXMqv_zRxFHVY-ez2HYcncx8zh_y-BX6w,42
48
- ripperdoc/tools/background_shell.py,sha256=1PEdlzOBzRKSOmzO_OViDMXcdXzW9grTzukGzRocYb0,10362
49
- ripperdoc/tools/bash_output_tool.py,sha256=ljIOzTOnkbQfe3jExlhpUlMiLT6HpeD-1QI-D1CwHh8,3379
50
- ripperdoc/tools/bash_tool.py,sha256=s4FrJTqC_bIN7gqBtbBUr9gt11LsVmWWkplp1ljlzmw,37461
51
- ripperdoc/tools/file_edit_tool.py,sha256=3fLBcXpwX_SumZRiP-1TJ1qIfWA-AQF88Ji_MCI1Ldo,11871
52
- ripperdoc/tools/file_read_tool.py,sha256=kKdhj6BXIyKCSxbB063BDAKNjAd36xtTUH-fixWhwHE,6721
53
- ripperdoc/tools/file_write_tool.py,sha256=fxh4qUGNqby7iFWuADImF4AyOAskMTzqC7CZLHCqcpo,5296
54
- ripperdoc/tools/glob_tool.py,sha256=e7yS1RvE3VJw5aOwoEPk8fLUSUr6mUmFsi8u8_3TV9Y,5856
55
- ripperdoc/tools/grep_tool.py,sha256=LfLpPmqD9CIPk6kFYDDmIcykj7uN0xoKtyodc2412FA,8340
56
- ripperdoc/tools/kill_bash_tool.py,sha256=36F8w2Rm1IVQitwOAwS-D8NTnyQdWfKWIam44qlXErk,4625
57
- ripperdoc/tools/ls_tool.py,sha256=RlaTciHmjgNFopzUEOJjBp1NqNYhr8F1VIekRgqDwSg,15249
58
- ripperdoc/tools/mcp_tools.py,sha256=ejofb2UEwH0r-ZAEvvq9nWvCgRGTAqiOws_X2T0YBU0,31263
59
- ripperdoc/tools/multi_edit_tool.py,sha256=63xircd2ovrk9n1YJ8tfkLDFLvSRFtWAJh3aURmELcE,15829
60
- ripperdoc/tools/notebook_edit_tool.py,sha256=zGFLRoIUCYEQUUcAiV4izJ09YFKUjaY2zGUJAjucq8c,12656
61
- ripperdoc/tools/task_tool.py,sha256=bKvJy0hMJcY4MEmWDXqYH0CKfgMKEtaCO9UF9xdngc0,11983
62
- ripperdoc/tools/todo_tool.py,sha256=QqgWW7LjylD8nmeeO_rkgjnzs8o1O-UVDD-rXObcVuE,19954
63
- ripperdoc/tools/tool_search_tool.py,sha256=YmSGCviaHiMmYghmPO0Km6ZOI5kkQrjz7qb3G_EFjiI,13763
64
- ripperdoc/utils/__init__.py,sha256=gdso60znB2hsYZ_YZBKVcuOY3QVfoqD2wHQ4pvr5lSw,37
65
- ripperdoc/utils/bash_constants.py,sha256=KNn8bzB6nVU5jid9jvjiH4FAu8pP3DZONJ-OknJypAQ,1641
66
- ripperdoc/utils/bash_output_utils.py,sha256=3Cf5wKJzRbUesmCNy5HtXIBtv0Z2BxklTfFHJ9q1T3w,1210
67
- ripperdoc/utils/exit_code_handlers.py,sha256=QtO1iDxVAb8Xp03D6_QixPoJC-RQlcp3ssIo_rm4two,7973
68
- ripperdoc/utils/file_watch.py,sha256=idleNFevHctDSJd23d4Y25XdJooFRpgepOcOEmp9pDg,3970
69
- ripperdoc/utils/git_utils.py,sha256=Hq-Zx-KPyX4lp_i8ozhic15LyYdX_IfCRm-EyoFu59A,9047
70
- ripperdoc/utils/json_utils.py,sha256=Ayv4h0aafTbzhpoN4FMPaBxLx9MfoK2PuOVd1_52-k0,706
71
- ripperdoc/utils/log.py,sha256=98JbVkZQd2OsFo789pgf9q96D6A5IcyT5ubzrPAEoWs,6176
72
- ripperdoc/utils/mcp.py,sha256=aIGmJLErQ1xRSzTj9Hm3ns2gW8oTvfrFBIukyNXaURk,17037
73
- ripperdoc/utils/memory.py,sha256=gRhVTRaCo0YOQeXm1i-sndnTku7qhTB-PSYdFD0OzxU,7872
74
- ripperdoc/utils/message_compaction.py,sha256=307IXnYqGYmj2iZUbfhNULj0BOVSlSTeOUg0Sik79EA,24797
75
- ripperdoc/utils/messages.py,sha256=8iRolxS6VoJtcaFU41tzKSdsfBSJMXMGUnUTLXKkfnw,17334
76
- ripperdoc/utils/output_utils.py,sha256=R3wqFh9Dko_GK00Exx7XI0DnnldRWMsxZypYX5y6SJo,7448
77
- ripperdoc/utils/path_utils.py,sha256=C45Q3OeXnj-0FVEtvf_tdG5922XB6HthUzlUCvfc17Y,1626
78
- ripperdoc/utils/prompt.py,sha256=BV87KXX4aPdv63zsZdtD169ZAqat5wxltgUCcN1vIuk,523
79
- ripperdoc/utils/safe_get_cwd.py,sha256=hZXQ1oJBCXuk1QBmmfqgDsr1icVOAfGSxABp032GauI,716
80
- ripperdoc/utils/sandbox_utils.py,sha256=G91P8dw2VFcCiCpjXZ4LvzbAPiO8REqMhw39eI5Z4dU,1123
81
- ripperdoc/utils/session_history.py,sha256=Z-stx88yaWzJ5iqOLCeS_z8gg1G4w6j4OMoff9r7JvA,7965
82
- ripperdoc/utils/session_usage.py,sha256=p8_s46zDTzV1qzP4HR4PuZmLeJvSfq9mG_Y5rCnRYyA,3213
83
- ripperdoc/utils/shell_token_utils.py,sha256=SduoSU-RERJdM_7gBn0urr5UXtl4XOpPgydBd2fwzWg,2500
84
- ripperdoc/utils/shell_utils.py,sha256=t-neFPy_VhEmWZ79J7hh1ULBEdX116Rb9_pnXvir1Jw,5235
85
- ripperdoc/utils/todo.py,sha256=ejWd42AAVT15GJvCqb21GERSIbsdY-bwZDNnst4xebQ,6903
86
- ripperdoc/utils/permissions/__init__.py,sha256=-1aKvRC05kuvLacbeu7w1W5ANamOTAho4Y0lY2vz0W0,522
87
- ripperdoc/utils/permissions/path_validation_utils.py,sha256=jWcvBWUOgiEOncn_b2Fz7FBJL3XiPlyPQhNT4ZJ7p10,5681
88
- ripperdoc/utils/permissions/shell_command_validation.py,sha256=BkK-wEwAuJPoC4XIx2Zj6MF3gXcWReozIwigXgib0z0,2446
89
- ripperdoc/utils/permissions/tool_permission_utils.py,sha256=6Fdu9-dMKhLsUExjEjoS0EUeRpEVN5UkqyseIC05YmM,9207
90
- ripperdoc-0.2.3.dist-info/licenses/LICENSE,sha256=bRv9UhBor6GhnQDj12RciDcRfu0R7sB-lqCy1sWF75c,9242
91
- ripperdoc-0.2.3.dist-info/METADATA,sha256=0ko9dUoMiBntF-XdI7oD70VpbU7-GWpDBiZy_oAknq8,5362
92
- ripperdoc-0.2.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
93
- ripperdoc-0.2.3.dist-info/entry_points.txt,sha256=79aohFxFPJmrQ3-Mhain04vb3EWpuc0EyzvDDUnwAu4,81
94
- ripperdoc-0.2.3.dist-info/top_level.txt,sha256=u8LbdTr1a-laHgCO0Utl_R3QGFUhLxWelCDnP2ZgpCU,10
95
- ripperdoc-0.2.3.dist-info/RECORD,,