patchpal 0.1.5__tar.gz → 0.1.7__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.5/patchpal.egg-info → patchpal-0.1.7}/PKG-INFO +102 -1
  2. {patchpal-0.1.5 → patchpal-0.1.7}/README.md +101 -0
  3. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/__init__.py +1 -1
  4. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/agent.py +219 -0
  5. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/cli.py +16 -0
  6. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/system_prompt.md +12 -1
  7. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/tools.py +628 -0
  8. {patchpal-0.1.5 → patchpal-0.1.7/patchpal.egg-info}/PKG-INFO +102 -1
  9. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_agent.py +13 -3
  10. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_tools.py +597 -0
  11. {patchpal-0.1.5 → patchpal-0.1.7}/LICENSE +0 -0
  12. {patchpal-0.1.5 → patchpal-0.1.7}/MANIFEST.in +0 -0
  13. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/context.py +0 -0
  14. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/permissions.py +0 -0
  15. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal/skills.py +0 -0
  16. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal.egg-info/SOURCES.txt +0 -0
  17. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal.egg-info/dependency_links.txt +0 -0
  18. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal.egg-info/entry_points.txt +0 -0
  19. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal.egg-info/requires.txt +0 -0
  20. {patchpal-0.1.5 → patchpal-0.1.7}/patchpal.egg-info/top_level.txt +0 -0
  21. {patchpal-0.1.5 → patchpal-0.1.7}/pyproject.toml +0 -0
  22. {patchpal-0.1.5 → patchpal-0.1.7}/setup.cfg +0 -0
  23. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_cli.py +0 -0
  24. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_context.py +0 -0
  25. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_guardrails.py +0 -0
  26. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_operational_safety.py +0 -0
  27. {patchpal-0.1.5 → patchpal-0.1.7}/tests/test_skills.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: patchpal
3
- Version: 0.1.5
3
+ Version: 0.1.7
4
4
  Summary: A lean Claude Code clone in pure Python
5
5
  Author: PatchPal Contributors
6
6
  License-Expression: Apache-2.0
@@ -121,6 +121,10 @@ The agent has the following tools:
121
121
 
122
122
  ### File Operations
123
123
  - **read_file**: Read contents of files in the repository
124
+ - **read_lines**: Read specific line ranges from a file without loading the entire file
125
+ - Example: `read_lines("app.py", 100, 150)` - read lines 100-150
126
+ - More efficient than read_file when you only need a few lines
127
+ - Useful for viewing code sections, error context, or specific regions of large files
124
128
  - **list_files**: List all files in the repository
125
129
  - **get_file_info**: Get detailed metadata for file(s) - size, modification time, type
126
130
  - Supports single files: `get_file_info("file.txt")`
@@ -143,6 +147,29 @@ The agent has the following tools:
143
147
  - **apply_patch**: Modify files by providing complete new content
144
148
  - **run_shell**: Execute shell commands (requires user permission; privilege escalation blocked)
145
149
 
150
+ ### Task Planning (TODO System)
151
+ - **todo_add**: Add a new task to break down complex work into manageable subtasks
152
+ - Example: `todo_add("Implement authentication", details="Use JWT tokens")`
153
+ - Each task gets a unique ID for tracking
154
+ - **todo_list**: Show all tasks with their status and progress
155
+ - Example: `todo_list()` - show pending tasks only
156
+ - Example: `todo_list(show_completed=True)` - show all tasks including completed
157
+ - **todo_complete**: Mark a task as done
158
+ - Example: `todo_complete(1)` - mark task #1 as completed
159
+ - **todo_update**: Update task description or details
160
+ - Example: `todo_update(1, description="Implement OAuth2 authentication")`
161
+ - **todo_remove**: Remove a task from the list
162
+ - Example: `todo_remove(1)` - remove task #1
163
+ - **todo_clear**: Clear completed tasks or start fresh
164
+ - Example: `todo_clear()` - clear completed tasks only
165
+ - Example: `todo_clear(completed_only=False)` - clear all tasks
166
+
167
+ ### User Interaction
168
+ - **ask_user**: Ask the user a question during task execution
169
+ - Example: `ask_user("Which database should I use?", options=["PostgreSQL", "MySQL", "SQLite"])`
170
+ - Useful for clarifying requirements, getting decisions, or gathering additional information
171
+ - Supports multiple choice options or free-form answers
172
+
146
173
  ### Git Operations (No Permission Required)
147
174
  - **git_status**: Show modified, staged, and untracked files
148
175
  - **git_diff**: Show changes in working directory or staged area
@@ -513,6 +540,80 @@ When web tools are disabled:
513
540
  patchpal --help
514
541
  ```
515
542
 
543
+ ### Maximum Security Mode
544
+
545
+ For maximum security and control, you can require permission for **all** operations including read operations:
546
+
547
+ ```bash
548
+ patchpal --require-permission-for-all
549
+ ```
550
+
551
+ When enabled, the agent will prompt for permission before:
552
+ - **Read operations**: `read_file`, `list_files`, `get_file_info`, `find_files`, `tree`, `grep_code`, `git_status`, `git_diff`, `git_log`
553
+ - **Write operations**: `edit_file`, `apply_patch` (always require permission)
554
+ - **Shell commands**: `run_shell` (always requires permission)
555
+ - **Web operations**: `web_search`, `web_fetch` (always require permission)
556
+
557
+ **Granular session permissions:**
558
+ When you grant permission for read operations, you can choose to grant it for:
559
+ - **This specific operation only** (option 1)
560
+ - **This specific file/pattern for the session** (option 2) - e.g., grant permission to read `config.py` for the session, but still prompt for other files
561
+ - **Cancel the operation** (option 3)
562
+
563
+ This provides fine-grained control over what the agent can access during the session.
564
+
565
+ **Use cases:**
566
+ - Working with highly sensitive codebases
567
+ - Security audits where every operation must be reviewed
568
+ - Training/demonstration purposes where you want to see exactly what the agent does
569
+ - Untrusted environments where you want complete control
570
+
571
+ **Example session:**
572
+ ```bash
573
+ $ patchpal --require-permission-for-all
574
+ ================================================================================
575
+ PatchPal - Claude Code–inspired coding and automation assistant
576
+ ================================================================================
577
+
578
+ Using model: anthropic/claude-sonnet-4-5
579
+ 🔒 Permission required for ALL operations (including reads)
580
+
581
+ You: Read config.py and database.py
582
+
583
+ ================================================================================
584
+ Read File
585
+ --------------------------------------------------------------------------------
586
+ Read: config.py
587
+ --------------------------------------------------------------------------------
588
+
589
+ Do you want to proceed?
590
+ 1. Yes
591
+ 2. Yes, and don't ask again this session for 'config.py'
592
+ 3. No, and tell me what to do differently
593
+
594
+ Choice [1-3]: 2
595
+
596
+ # Agent reads config.py, then prompts for database.py
597
+
598
+ ================================================================================
599
+ Read File
600
+ --------------------------------------------------------------------------------
601
+ Read: database.py
602
+ --------------------------------------------------------------------------------
603
+
604
+ Do you want to proceed?
605
+ 1. Yes
606
+ 2. Yes, and don't ask again this session for 'database.py'
607
+ 3. No, and tell me what to do differently
608
+
609
+ Choice [1-3]: 1
610
+
611
+ # Agent reads database.py, but will prompt again if it tries to read it later
612
+ # Won't prompt again for config.py since you chose option 2
613
+ ```
614
+
615
+ **Note:** This mode is separate from and overrides `PATCHPAL_REQUIRE_PERMISSION=false`. Even if you've disabled the standard permission system, `--require-permission-for-all` will still prompt for all operations.
616
+
516
617
  ## Usage
517
618
 
518
619
  Simply run the `patchpal` command and type your requests interactively:
@@ -84,6 +84,10 @@ The agent has the following tools:
84
84
 
85
85
  ### File Operations
86
86
  - **read_file**: Read contents of files in the repository
87
+ - **read_lines**: Read specific line ranges from a file without loading the entire file
88
+ - Example: `read_lines("app.py", 100, 150)` - read lines 100-150
89
+ - More efficient than read_file when you only need a few lines
90
+ - Useful for viewing code sections, error context, or specific regions of large files
87
91
  - **list_files**: List all files in the repository
88
92
  - **get_file_info**: Get detailed metadata for file(s) - size, modification time, type
89
93
  - Supports single files: `get_file_info("file.txt")`
@@ -106,6 +110,29 @@ The agent has the following tools:
106
110
  - **apply_patch**: Modify files by providing complete new content
107
111
  - **run_shell**: Execute shell commands (requires user permission; privilege escalation blocked)
108
112
 
113
+ ### Task Planning (TODO System)
114
+ - **todo_add**: Add a new task to break down complex work into manageable subtasks
115
+ - Example: `todo_add("Implement authentication", details="Use JWT tokens")`
116
+ - Each task gets a unique ID for tracking
117
+ - **todo_list**: Show all tasks with their status and progress
118
+ - Example: `todo_list()` - show pending tasks only
119
+ - Example: `todo_list(show_completed=True)` - show all tasks including completed
120
+ - **todo_complete**: Mark a task as done
121
+ - Example: `todo_complete(1)` - mark task #1 as completed
122
+ - **todo_update**: Update task description or details
123
+ - Example: `todo_update(1, description="Implement OAuth2 authentication")`
124
+ - **todo_remove**: Remove a task from the list
125
+ - Example: `todo_remove(1)` - remove task #1
126
+ - **todo_clear**: Clear completed tasks or start fresh
127
+ - Example: `todo_clear()` - clear completed tasks only
128
+ - Example: `todo_clear(completed_only=False)` - clear all tasks
129
+
130
+ ### User Interaction
131
+ - **ask_user**: Ask the user a question during task execution
132
+ - Example: `ask_user("Which database should I use?", options=["PostgreSQL", "MySQL", "SQLite"])`
133
+ - Useful for clarifying requirements, getting decisions, or gathering additional information
134
+ - Supports multiple choice options or free-form answers
135
+
109
136
  ### Git Operations (No Permission Required)
110
137
  - **git_status**: Show modified, staged, and untracked files
111
138
  - **git_diff**: Show changes in working directory or staged area
@@ -476,6 +503,80 @@ When web tools are disabled:
476
503
  patchpal --help
477
504
  ```
478
505
 
506
+ ### Maximum Security Mode
507
+
508
+ For maximum security and control, you can require permission for **all** operations including read operations:
509
+
510
+ ```bash
511
+ patchpal --require-permission-for-all
512
+ ```
513
+
514
+ When enabled, the agent will prompt for permission before:
515
+ - **Read operations**: `read_file`, `list_files`, `get_file_info`, `find_files`, `tree`, `grep_code`, `git_status`, `git_diff`, `git_log`
516
+ - **Write operations**: `edit_file`, `apply_patch` (always require permission)
517
+ - **Shell commands**: `run_shell` (always requires permission)
518
+ - **Web operations**: `web_search`, `web_fetch` (always require permission)
519
+
520
+ **Granular session permissions:**
521
+ When you grant permission for read operations, you can choose to grant it for:
522
+ - **This specific operation only** (option 1)
523
+ - **This specific file/pattern for the session** (option 2) - e.g., grant permission to read `config.py` for the session, but still prompt for other files
524
+ - **Cancel the operation** (option 3)
525
+
526
+ This provides fine-grained control over what the agent can access during the session.
527
+
528
+ **Use cases:**
529
+ - Working with highly sensitive codebases
530
+ - Security audits where every operation must be reviewed
531
+ - Training/demonstration purposes where you want to see exactly what the agent does
532
+ - Untrusted environments where you want complete control
533
+
534
+ **Example session:**
535
+ ```bash
536
+ $ patchpal --require-permission-for-all
537
+ ================================================================================
538
+ PatchPal - Claude Code–inspired coding and automation assistant
539
+ ================================================================================
540
+
541
+ Using model: anthropic/claude-sonnet-4-5
542
+ 🔒 Permission required for ALL operations (including reads)
543
+
544
+ You: Read config.py and database.py
545
+
546
+ ================================================================================
547
+ Read File
548
+ --------------------------------------------------------------------------------
549
+ Read: config.py
550
+ --------------------------------------------------------------------------------
551
+
552
+ Do you want to proceed?
553
+ 1. Yes
554
+ 2. Yes, and don't ask again this session for 'config.py'
555
+ 3. No, and tell me what to do differently
556
+
557
+ Choice [1-3]: 2
558
+
559
+ # Agent reads config.py, then prompts for database.py
560
+
561
+ ================================================================================
562
+ Read File
563
+ --------------------------------------------------------------------------------
564
+ Read: database.py
565
+ --------------------------------------------------------------------------------
566
+
567
+ Do you want to proceed?
568
+ 1. Yes
569
+ 2. Yes, and don't ask again this session for 'database.py'
570
+ 3. No, and tell me what to do differently
571
+
572
+ Choice [1-3]: 1
573
+
574
+ # Agent reads database.py, but will prompt again if it tries to read it later
575
+ # Won't prompt again for config.py since you chose option 2
576
+ ```
577
+
578
+ **Note:** This mode is separate from and overrides `PATCHPAL_REQUIRE_PERMISSION=false`. Even if you've disabled the standard permission system, `--require-permission-for-all` will still prompt for all operations.
579
+
479
580
  ## Usage
480
581
 
481
582
  Simply run the `patchpal` command and type your requests interactively:
@@ -1,6 +1,6 @@
1
1
  """PatchPal - An open-source Claude Code clone implemented purely in Python."""
2
2
 
3
- __version__ = "0.1.5"
3
+ __version__ = "0.1.7"
4
4
 
5
5
  from patchpal.agent import create_agent
6
6
  from patchpal.tools import (
@@ -14,6 +14,7 @@ from rich.markdown import Markdown
14
14
  from patchpal.context import ContextManager
15
15
  from patchpal.tools import (
16
16
  apply_patch,
17
+ ask_user,
17
18
  edit_file,
18
19
  find_files,
19
20
  get_file_info,
@@ -24,7 +25,14 @@ from patchpal.tools import (
24
25
  list_files,
25
26
  list_skills,
26
27
  read_file,
28
+ read_lines,
27
29
  run_shell,
30
+ todo_add,
31
+ todo_clear,
32
+ todo_complete,
33
+ todo_list,
34
+ todo_remove,
35
+ todo_update,
28
36
  tree,
29
37
  use_skill,
30
38
  web_fetch,
@@ -104,6 +112,31 @@ TOOLS = [
104
112
  },
105
113
  },
106
114
  },
115
+ {
116
+ "type": "function",
117
+ "function": {
118
+ "name": "read_lines",
119
+ "description": "Read specific lines from a file without loading the entire file. Useful for viewing code sections, error context, or specific regions of large files. More efficient than read_file when you only need a few lines.",
120
+ "parameters": {
121
+ "type": "object",
122
+ "properties": {
123
+ "path": {
124
+ "type": "string",
125
+ "description": "Path to the file - can be relative to repository root or an absolute path",
126
+ },
127
+ "start_line": {
128
+ "type": "integer",
129
+ "description": "Starting line number (1-indexed)",
130
+ },
131
+ "end_line": {
132
+ "type": "integer",
133
+ "description": "Ending line number (inclusive, 1-indexed). If omitted, reads only start_line",
134
+ },
135
+ },
136
+ "required": ["path", "start_line"],
137
+ },
138
+ },
139
+ },
107
140
  {
108
141
  "type": "function",
109
142
  "function": {
@@ -368,6 +401,142 @@ TOOLS = [
368
401
  },
369
402
  },
370
403
  },
404
+ {
405
+ "type": "function",
406
+ "function": {
407
+ "name": "todo_add",
408
+ "description": "Add a new task to the TODO list. Use this to break down complex tasks into manageable subtasks. Essential for planning multi-step work.",
409
+ "parameters": {
410
+ "type": "object",
411
+ "properties": {
412
+ "description": {
413
+ "type": "string",
414
+ "description": "Brief task description (one line)",
415
+ },
416
+ "details": {
417
+ "type": "string",
418
+ "description": "Optional detailed notes about the task",
419
+ },
420
+ },
421
+ "required": ["description"],
422
+ },
423
+ },
424
+ },
425
+ {
426
+ "type": "function",
427
+ "function": {
428
+ "name": "todo_list",
429
+ "description": "List all tasks in the TODO list with their status and progress.",
430
+ "parameters": {
431
+ "type": "object",
432
+ "properties": {
433
+ "show_completed": {
434
+ "type": "boolean",
435
+ "description": "If true, show completed tasks; if false, show only pending tasks (default: false)",
436
+ },
437
+ },
438
+ "required": [],
439
+ },
440
+ },
441
+ },
442
+ {
443
+ "type": "function",
444
+ "function": {
445
+ "name": "todo_complete",
446
+ "description": "Mark a task as completed.",
447
+ "parameters": {
448
+ "type": "object",
449
+ "properties": {
450
+ "task_id": {
451
+ "type": "integer",
452
+ "description": "The ID of the task to complete",
453
+ },
454
+ },
455
+ "required": ["task_id"],
456
+ },
457
+ },
458
+ },
459
+ {
460
+ "type": "function",
461
+ "function": {
462
+ "name": "todo_update",
463
+ "description": "Update a task's description or details.",
464
+ "parameters": {
465
+ "type": "object",
466
+ "properties": {
467
+ "task_id": {
468
+ "type": "integer",
469
+ "description": "The ID of the task to update",
470
+ },
471
+ "description": {
472
+ "type": "string",
473
+ "description": "New description (optional)",
474
+ },
475
+ "details": {
476
+ "type": "string",
477
+ "description": "New details (optional)",
478
+ },
479
+ },
480
+ "required": ["task_id"],
481
+ },
482
+ },
483
+ },
484
+ {
485
+ "type": "function",
486
+ "function": {
487
+ "name": "todo_remove",
488
+ "description": "Remove a task from the TODO list.",
489
+ "parameters": {
490
+ "type": "object",
491
+ "properties": {
492
+ "task_id": {
493
+ "type": "integer",
494
+ "description": "The ID of the task to remove",
495
+ },
496
+ },
497
+ "required": ["task_id"],
498
+ },
499
+ },
500
+ },
501
+ {
502
+ "type": "function",
503
+ "function": {
504
+ "name": "todo_clear",
505
+ "description": "Clear tasks from the TODO list (completed tasks only by default, or all tasks).",
506
+ "parameters": {
507
+ "type": "object",
508
+ "properties": {
509
+ "completed_only": {
510
+ "type": "boolean",
511
+ "description": "If true, clear only completed tasks; if false, clear all tasks (default: true)",
512
+ },
513
+ },
514
+ "required": [],
515
+ },
516
+ },
517
+ },
518
+ {
519
+ "type": "function",
520
+ "function": {
521
+ "name": "ask_user",
522
+ "description": "Ask the user a question and wait for their response. Use this to clarify requirements, get decisions, or gather additional information during task execution.",
523
+ "parameters": {
524
+ "type": "object",
525
+ "properties": {
526
+ "question": {
527
+ "type": "string",
528
+ "description": "The question to ask the user",
529
+ },
530
+ "options": {
531
+ "type": "array",
532
+ "items": {"type": "string"},
533
+ "description": "Optional list of predefined answer choices (e.g., ['yes', 'no', 'skip']). User can select from these or provide custom answer.",
534
+ },
535
+ },
536
+ "required": ["question"],
537
+ },
538
+ },
539
+ },
371
540
  {
372
541
  "type": "function",
373
542
  "function": {
@@ -387,6 +556,7 @@ TOOLS = [
387
556
  # Map tool names to functions
388
557
  TOOL_FUNCTIONS = {
389
558
  "read_file": read_file,
559
+ "read_lines": read_lines,
390
560
  "list_files": list_files,
391
561
  "get_file_info": get_file_info,
392
562
  "find_files": find_files,
@@ -401,6 +571,13 @@ TOOL_FUNCTIONS = {
401
571
  "web_fetch": web_fetch,
402
572
  "list_skills": list_skills,
403
573
  "use_skill": use_skill,
574
+ "todo_add": todo_add,
575
+ "todo_list": todo_list,
576
+ "todo_complete": todo_complete,
577
+ "todo_update": todo_update,
578
+ "todo_remove": todo_remove,
579
+ "todo_clear": todo_clear,
580
+ "ask_user": ask_user,
404
581
  "run_shell": run_shell,
405
582
  }
406
583
 
@@ -792,6 +969,13 @@ class PatchPalAgent:
792
969
  f"\033[2m📖 Reading: {tool_args.get('path', '')}\033[0m",
793
970
  flush=True,
794
971
  )
972
+ elif tool_name == "read_lines":
973
+ start = tool_args.get("start_line", "")
974
+ end = tool_args.get("end_line", start)
975
+ print(
976
+ f"\033[2m📖 Reading lines {start}-{end}: {tool_args.get('path', '')}\033[0m",
977
+ flush=True,
978
+ )
795
979
  elif tool_name == "list_files":
796
980
  print("\033[2m📁 Listing files...\033[0m", flush=True)
797
981
  elif tool_name == "get_file_info":
@@ -855,6 +1039,41 @@ class PatchPalAgent:
855
1039
  f"\033[2m⚡ Running: {tool_args.get('cmd', '')}\033[0m",
856
1040
  flush=True,
857
1041
  )
1042
+ elif tool_name == "todo_add":
1043
+ print(
1044
+ f"\033[2m✅ Adding TODO: {tool_args.get('description', '')[:50]}\033[0m",
1045
+ flush=True,
1046
+ )
1047
+ elif tool_name == "todo_list":
1048
+ print("\033[2m📋 Listing TODO tasks...\033[0m", flush=True)
1049
+ elif tool_name == "todo_complete":
1050
+ print(
1051
+ f"\033[2m✓ Completing task #{tool_args.get('task_id', '')}\033[0m",
1052
+ flush=True,
1053
+ )
1054
+ elif tool_name == "todo_update":
1055
+ print(
1056
+ f"\033[2m📝 Updating task #{tool_args.get('task_id', '')}\033[0m",
1057
+ flush=True,
1058
+ )
1059
+ elif tool_name == "todo_remove":
1060
+ print(
1061
+ f"\033[2m🗑️ Removing task #{tool_args.get('task_id', '')}\033[0m",
1062
+ flush=True,
1063
+ )
1064
+ elif tool_name == "todo_clear":
1065
+ clear_type = (
1066
+ "completed" if tool_args.get("completed_only", True) else "all"
1067
+ )
1068
+ print(
1069
+ f"\033[2m🧹 Clearing {clear_type} TODO tasks...\033[0m",
1070
+ flush=True,
1071
+ )
1072
+ elif tool_name == "ask_user":
1073
+ print(
1074
+ "\033[2m❓ Asking user a question...\033[0m",
1075
+ flush=True,
1076
+ )
858
1077
 
859
1078
  # Execute the tool (permission checks happen inside the tool)
860
1079
  try:
@@ -194,8 +194,20 @@ Supported models: Any LiteLLM-supported model
194
194
  help="LiteLLM model identifier (e.g., openai/gpt-4o, anthropic/claude-opus-4, ollama_chat/llama3.1). "
195
195
  "Can also be set via PATCHPAL_MODEL environment variable.",
196
196
  )
197
+ parser.add_argument(
198
+ "--require-permission-for-all",
199
+ action="store_true",
200
+ help="Require permission for ALL operations including read operations (read_file, list_files, etc.). "
201
+ "Use this for maximum security when you want to review every operation the agent performs.",
202
+ )
197
203
  args = parser.parse_args()
198
204
 
205
+ # Set the require-permission-for-all flag if specified
206
+ if args.require_permission_for_all:
207
+ from patchpal.tools import set_require_permission_for_all
208
+
209
+ set_require_permission_for_all(True)
210
+
199
211
  # Determine model to use (priority: CLI arg > env var > default)
200
212
  model_id = args.model or os.getenv("PATCHPAL_MODEL") or "anthropic/claude-sonnet-4-5"
201
213
 
@@ -226,6 +238,10 @@ Supported models: Any LiteLLM-supported model
226
238
  print("=" * 80)
227
239
  print(f"\nUsing model: {model_id}")
228
240
 
241
+ # Show require-permission-for-all indicator if active
242
+ if args.require_permission_for_all:
243
+ print("\033[1;33m🔒 Permission required for ALL operations (including reads)\033[0m")
244
+
229
245
  # Show custom prompt indicator if set
230
246
  custom_prompt_path = os.getenv("PATCHPAL_SYSTEM_PROMPT")
231
247
  if custom_prompt_path:
@@ -8,6 +8,7 @@ Today is {current_date}. Current time is {current_time}.
8
8
  # Available Tools
9
9
 
10
10
  - **read_file**: Read any file on the system (repository files, /etc configs, logs, etc.) - sensitive files blocked for safety
11
+ - **read_lines**: Read specific line ranges from a file without loading the entire file (efficient for large files or viewing code sections)
11
12
  - **list_files**: List all files in the repository (repository-only)
12
13
  - **get_file_info**: Get metadata for any file(s) - size, type, modified time (supports globs like '*.py', '/etc/*.conf')
13
14
  - **find_files**: Find files by name pattern using glob wildcards in repository (e.g., '*.py', 'test_*.txt')
@@ -30,7 +31,7 @@ You are a LOCAL CODE ASSISTANT with flexible file access. Security model (inspir
30
31
 
31
32
  Your tools are organized into:
32
33
 
33
- - **File navigation/reading**: read_file (system-wide), list_files (repo-only), find_files (repo-only), tree (system-wide), get_file_info (system-wide)
34
+ - **File navigation/reading**: read_file (system-wide), read_lines (system-wide), list_files (repo-only), find_files (repo-only), tree (system-wide), get_file_info (system-wide)
34
35
  - **Code search**: grep_code (repo-only)
35
36
  - **File modification**: edit_file, apply_patch (repo files; outside requires permission)
36
37
  - **Git operations**: git_status, git_diff, git_log (read-only, no permission needed)
@@ -102,6 +103,7 @@ The user will primarily request software engineering tasks like solving bugs, ad
102
103
  - Use find_files to locate specific files by name pattern in repository (e.g., '*.py', 'test_*.txt')
103
104
  - Use get_file_info to check file metadata anywhere (supports globs like '/etc/*.conf')
104
105
  - Use read_file to examine any file on the system (repository, configs, logs, etc.)
106
+ - Use read_lines to read specific line ranges from files (more efficient for large files)
105
107
  - Use grep_code to search for patterns in repository file contents
106
108
  - For system file exploration (outside repository):
107
109
  - Use tree for directory listing (e.g., tree("/etc") to list /etc)
@@ -111,6 +113,15 @@ The user will primarily request software engineering tasks like solving bugs, ad
111
113
  - Use edit_file for small, targeted changes (repository files; outside requires permission)
112
114
  - Use apply_patch for larger changes or rewriting significant portions
113
115
  - Use git_status, git_diff, git_log to understand repository state (no permission needed){web_usage}
116
+ - For complex multi-step tasks:
117
+ - Use todo_add to break down work into manageable subtasks
118
+ - Use todo_list to check progress and see what's next
119
+ - Use todo_complete when finishing each task
120
+ - This helps track progress and ensures nothing is forgotten
121
+ - Use ask_user to clarify requirements, get decisions, or gather information during execution
122
+ - Ask when user intent is ambiguous
123
+ - Get preferences on implementation choices
124
+ - Confirm before making significant architectural decisions
114
125
  - Use run_shell when no dedicated tool exists (requires permission)
115
126
  - Never use run_shell for repository file operations - dedicated tools are available
116
127