patchpal 0.1.2__tar.gz → 0.1.4__tar.gz

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 (27) hide show
  1. {patchpal-0.1.2/patchpal.egg-info → patchpal-0.1.4}/PKG-INFO +7 -2
  2. {patchpal-0.1.2 → patchpal-0.1.4}/README.md +5 -1
  3. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/__init__.py +1 -1
  4. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/agent.py +1 -1
  5. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/cli.py +13 -0
  6. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/system_prompt.md +1 -1
  7. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/tools.py +7 -1
  8. {patchpal-0.1.2 → patchpal-0.1.4/patchpal.egg-info}/PKG-INFO +7 -2
  9. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal.egg-info/requires.txt +1 -0
  10. {patchpal-0.1.2 → patchpal-0.1.4}/pyproject.toml +1 -0
  11. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_tools.py +41 -0
  12. {patchpal-0.1.2 → patchpal-0.1.4}/LICENSE +0 -0
  13. {patchpal-0.1.2 → patchpal-0.1.4}/MANIFEST.in +0 -0
  14. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/context.py +0 -0
  15. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/permissions.py +0 -0
  16. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal/skills.py +0 -0
  17. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal.egg-info/SOURCES.txt +0 -0
  18. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal.egg-info/dependency_links.txt +0 -0
  19. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal.egg-info/entry_points.txt +0 -0
  20. {patchpal-0.1.2 → patchpal-0.1.4}/patchpal.egg-info/top_level.txt +0 -0
  21. {patchpal-0.1.2 → patchpal-0.1.4}/setup.cfg +0 -0
  22. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_agent.py +0 -0
  23. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_cli.py +0 -0
  24. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_context.py +0 -0
  25. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_guardrails.py +0 -0
  26. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_operational_safety.py +0 -0
  27. {patchpal-0.1.2 → patchpal-0.1.4}/tests/test_skills.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: A lean Claude Code clone in pure Python
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
@@ -27,6 +27,7 @@ Requires-Dist: rich>=13.0.0
27
27
  Requires-Dist: pyyaml>=6.0.0
28
28
  Requires-Dist: prompt_toolkit>=3.0.0
29
29
  Requires-Dist: tiktoken>=0.5.0
30
+ Requires-Dist: boto3
30
31
  Provides-Extra: dev
31
32
  Requires-Dist: pytest>=7.0.0; extra == "dev"
32
33
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -606,12 +607,16 @@ PatchPal includes comprehensive security protections enabled by default:
606
607
  ```bash
607
608
  # Critical Security Controls
608
609
  export PATCHPAL_REQUIRE_PERMISSION=true # Prompt for permission before executing commands/modifying files (default: true)
609
- # Set to false to disable prompts (not recommended for production use)
610
+ # ⚠️ WARNING: Setting to false disables prompts - only use in trusted, controlled environments
611
+ # When disabled, the agent can modify files and run commands without asking
610
612
  export PATCHPAL_MAX_FILE_SIZE=5242880 # Maximum file size in bytes for read/write operations (default: 10485760 = 10MB)
611
613
  export PATCHPAL_READ_ONLY=true # Prevent all file modifications, analysis-only mode (default: false)
612
614
  # Useful for: code review, exploration, security audits, CI/CD analysis, or trying PatchPal risk-free
613
615
  export PATCHPAL_ALLOW_SENSITIVE=true # Allow access to .env, credentials, API keys (default: false - blocked for safety)
614
616
  # Only enable when working with test/dummy credentials or intentionally managing config files
617
+ export PATCHPAL_ALLOW_SUDO=true # Allow sudo commands (default: false - blocked for safety)
618
+ # ⚠️ WARNING: Only enable in trusted, controlled environments where sudo is necessary
619
+ # When enabled, all privilege escalation blocking is disabled
615
620
 
616
621
  # Operational Safety Controls
617
622
  export PATCHPAL_AUDIT_LOG=false # Log all operations to ~/.patchpal/<repo-name>/audit.log (default: true)
@@ -570,12 +570,16 @@ PatchPal includes comprehensive security protections enabled by default:
570
570
  ```bash
571
571
  # Critical Security Controls
572
572
  export PATCHPAL_REQUIRE_PERMISSION=true # Prompt for permission before executing commands/modifying files (default: true)
573
- # Set to false to disable prompts (not recommended for production use)
573
+ # ⚠️ WARNING: Setting to false disables prompts - only use in trusted, controlled environments
574
+ # When disabled, the agent can modify files and run commands without asking
574
575
  export PATCHPAL_MAX_FILE_SIZE=5242880 # Maximum file size in bytes for read/write operations (default: 10485760 = 10MB)
575
576
  export PATCHPAL_READ_ONLY=true # Prevent all file modifications, analysis-only mode (default: false)
576
577
  # Useful for: code review, exploration, security audits, CI/CD analysis, or trying PatchPal risk-free
577
578
  export PATCHPAL_ALLOW_SENSITIVE=true # Allow access to .env, credentials, API keys (default: false - blocked for safety)
578
579
  # Only enable when working with test/dummy credentials or intentionally managing config files
580
+ export PATCHPAL_ALLOW_SUDO=true # Allow sudo commands (default: false - blocked for safety)
581
+ # ⚠️ WARNING: Only enable in trusted, controlled environments where sudo is necessary
582
+ # When enabled, all privilege escalation blocking is disabled
579
583
 
580
584
  # Operational Safety Controls
581
585
  export PATCHPAL_AUDIT_LOG=false # Log all operations to ~/.patchpal/<repo-name>/audit.log (default: true)
@@ -1,6 +1,6 @@
1
1
  """PatchPal - An open-source Claude Code clone implemented purely in Python."""
2
2
 
3
- __version__ = "0.1.2"
3
+ __version__ = "0.1.4"
4
4
 
5
5
  from patchpal.agent import create_agent
6
6
  from patchpal.tools import (
@@ -372,7 +372,7 @@ TOOLS = [
372
372
  "type": "function",
373
373
  "function": {
374
374
  "name": "run_shell",
375
- "description": "Run a safe shell command in the repository. Dangerous commands (rm, mv, sudo, etc.) are blocked.",
375
+ "description": "Run a safe shell command in the repository. Privilege escalation (sudo, su) blocked by default unless PATCHPAL_ALLOW_SUDO=true.",
376
376
  "parameters": {
377
377
  "type": "object",
378
378
  "properties": {
@@ -92,6 +92,13 @@ class SmartPathCompleter(Completer):
92
92
  )
93
93
 
94
94
 
95
+ def _get_version() -> str:
96
+ """Get the PatchPal version string."""
97
+ from patchpal import __version__
98
+
99
+ return __version__
100
+
101
+
95
102
  def _get_patchpal_dir() -> Path:
96
103
  """Get the patchpal directory for this repository.
97
104
 
@@ -174,6 +181,12 @@ Supported models: Any LiteLLM-supported model
174
181
  - Others: See https://docs.litellm.ai/docs/providers
175
182
  """,
176
183
  )
184
+ parser.add_argument(
185
+ "--version",
186
+ action="version",
187
+ version=f"%(prog)s {_get_version()}",
188
+ help="Show program's version number and exit",
189
+ )
177
190
  parser.add_argument(
178
191
  "--model",
179
192
  type=str,
@@ -20,7 +20,7 @@ Today is {current_date}. Current time is {current_time}.
20
20
  - **grep_code**: Search for patterns in code files (faster than run_shell with grep)
21
21
  - **list_skills**: List available skills (custom workflows in ~/.patchpal/skills/ or .patchpal/skills/)
22
22
  - **use_skill**: Invoke a skill with optional arguments
23
- {web_tools}- **run_shell**: Run shell commands (requires permission; privilege escalation blocked)
23
+ {web_tools}- **run_shell**: Run shell commands (requires permission; privilege escalation blocked unless PATCHPAL_ALLOW_SUDO=true)
24
24
 
25
25
  ## Tool Overview and Scope
26
26
 
@@ -32,7 +32,13 @@ REPO_ROOT = Path(".").resolve()
32
32
 
33
33
  # Platform-aware command blocking - minimal list since we have permission system
34
34
  # Only block privilege escalation commands specific to each platform
35
- if platform.system() == "Windows":
35
+ # Allow sudo if explicitly enabled via environment variable
36
+ ALLOW_SUDO = os.getenv("PATCHPAL_ALLOW_SUDO", "false").lower() == "true"
37
+
38
+ if ALLOW_SUDO:
39
+ # Sudo allowed - no command blocking
40
+ FORBIDDEN = set()
41
+ elif platform.system() == "Windows":
36
42
  # Windows privilege escalation commands
37
43
  FORBIDDEN = {"runas", "psexec"} # Run as different user, SysInternals elevated execution
38
44
  else:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Summary: A lean Claude Code clone in pure Python
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
@@ -27,6 +27,7 @@ Requires-Dist: rich>=13.0.0
27
27
  Requires-Dist: pyyaml>=6.0.0
28
28
  Requires-Dist: prompt_toolkit>=3.0.0
29
29
  Requires-Dist: tiktoken>=0.5.0
30
+ Requires-Dist: boto3
30
31
  Provides-Extra: dev
31
32
  Requires-Dist: pytest>=7.0.0; extra == "dev"
32
33
  Requires-Dist: pytest-cov>=4.0.0; extra == "dev"
@@ -606,12 +607,16 @@ PatchPal includes comprehensive security protections enabled by default:
606
607
  ```bash
607
608
  # Critical Security Controls
608
609
  export PATCHPAL_REQUIRE_PERMISSION=true # Prompt for permission before executing commands/modifying files (default: true)
609
- # Set to false to disable prompts (not recommended for production use)
610
+ # ⚠️ WARNING: Setting to false disables prompts - only use in trusted, controlled environments
611
+ # When disabled, the agent can modify files and run commands without asking
610
612
  export PATCHPAL_MAX_FILE_SIZE=5242880 # Maximum file size in bytes for read/write operations (default: 10485760 = 10MB)
611
613
  export PATCHPAL_READ_ONLY=true # Prevent all file modifications, analysis-only mode (default: false)
612
614
  # Useful for: code review, exploration, security audits, CI/CD analysis, or trying PatchPal risk-free
613
615
  export PATCHPAL_ALLOW_SENSITIVE=true # Allow access to .env, credentials, API keys (default: false - blocked for safety)
614
616
  # Only enable when working with test/dummy credentials or intentionally managing config files
617
+ export PATCHPAL_ALLOW_SUDO=true # Allow sudo commands (default: false - blocked for safety)
618
+ # ⚠️ WARNING: Only enable in trusted, controlled environments where sudo is necessary
619
+ # When enabled, all privilege escalation blocking is disabled
615
620
 
616
621
  # Operational Safety Controls
617
622
  export PATCHPAL_AUDIT_LOG=false # Log all operations to ~/.patchpal/<repo-name>/audit.log (default: true)
@@ -6,6 +6,7 @@ rich>=13.0.0
6
6
  pyyaml>=6.0.0
7
7
  prompt_toolkit>=3.0.0
8
8
  tiktoken>=0.5.0
9
+ boto3
9
10
 
10
11
  [dev]
11
12
  pytest>=7.0.0
@@ -33,6 +33,7 @@ dependencies = [
33
33
  "pyyaml>=6.0.0",
34
34
  "prompt_toolkit>=3.0.0",
35
35
  "tiktoken>=0.5.0",
36
+ "boto3"
36
37
  ]
37
38
 
38
39
  [project.optional-dependencies]
@@ -155,6 +155,47 @@ def test_run_shell_forbidden_commands(temp_repo):
155
155
  run_shell(cmd)
156
156
 
157
157
 
158
+ def test_run_shell_allow_sudo(temp_repo, monkeypatch):
159
+ """Test that sudo can be allowed via PATCHPAL_ALLOW_SUDO."""
160
+ import platform
161
+
162
+ from patchpal.tools import run_shell
163
+
164
+ # Set environment variable to allow sudo
165
+ monkeypatch.setenv("PATCHPAL_ALLOW_SUDO", "true")
166
+
167
+ # Need to reload the module to pick up the new environment variable
168
+ import importlib
169
+
170
+ import patchpal.tools
171
+
172
+ importlib.reload(patchpal.tools)
173
+
174
+ # Re-patch REPO_ROOT after reload
175
+ monkeypatch.setattr("patchpal.tools.REPO_ROOT", temp_repo)
176
+
177
+ if platform.system() != "Windows":
178
+ # On Unix-like systems, sudo should now be allowed (will fail but not blocked)
179
+ # We can't actually test sudo execution without root, but we can verify
180
+ # it's not blocked by the FORBIDDEN check
181
+ try:
182
+ # This will fail with "sudo: a terminal is required" or similar
183
+ # but NOT with "Blocked dangerous command"
184
+ run_shell("sudo --version")
185
+ # If it succeeds, that's fine too
186
+ except ValueError as e:
187
+ # Should not be blocked by our FORBIDDEN check
188
+ assert "Blocked dangerous command" not in str(e)
189
+ # Might fail for other reasons (e.g., sudo not installed in test env)
190
+ assert "sudo" not in str(e).lower() or "not found" in str(e).lower()
191
+ else:
192
+ # On Windows, test runas
193
+ try:
194
+ run_shell("runas /?")
195
+ except ValueError as e:
196
+ assert "Blocked dangerous command" not in str(e)
197
+
198
+
158
199
  def test_run_shell_complex_safe_command(temp_repo):
159
200
  """Test that complex but safe commands work."""
160
201
  from patchpal.tools import run_shell
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes