claude-code-tools 0.1.9__tar.gz → 0.1.11__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.

Potentially problematic release.


This version of claude-code-tools might be problematic. Click here for more details.

Files changed (27) hide show
  1. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/PKG-INFO +1 -1
  2. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/claude_code_tools/__init__.py +1 -1
  3. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/claude_code_tools/tmux_cli_controller.py +69 -11
  4. claude_code_tools-0.1.11/claude_code_tools/tmux_remote_controller.py +69 -0
  5. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/pyproject.toml +6 -2
  6. claude_code_tools-0.1.9/Makefile +0 -37
  7. claude_code_tools-0.1.9/hooks/README.md +0 -211
  8. claude_code_tools-0.1.9/hooks/bash_hook.py +0 -66
  9. claude_code_tools-0.1.9/hooks/file_size_conditional_hook.py +0 -96
  10. claude_code_tools-0.1.9/hooks/git_add_block_hook.py +0 -73
  11. claude_code_tools-0.1.9/hooks/git_checkout_safety_hook.py +0 -126
  12. claude_code_tools-0.1.9/hooks/grep_block_hook.py +0 -12
  13. claude_code_tools-0.1.9/hooks/notification_hook.sh +0 -2
  14. claude_code_tools-0.1.9/hooks/posttask_subtask_flag.py +0 -12
  15. claude_code_tools-0.1.9/hooks/pretask_subtask_flag.py +0 -12
  16. claude_code_tools-0.1.9/hooks/rm_block_hook.py +0 -58
  17. claude_code_tools-0.1.9/hooks/settings.sample.json +0 -64
  18. claude_code_tools-0.1.9/scripts/fcs-function.sh +0 -13
  19. claude_code_tools-0.1.9/uv.lock +0 -362
  20. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/.gitignore +0 -0
  21. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/README.md +0 -0
  22. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/claude_code_tools/dotenv_vault.py +0 -0
  23. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/claude_code_tools/find_claude_session.py +0 -0
  24. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/docs/claude-code-tmux-tutorials.md +0 -0
  25. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/docs/find-claude-session.md +0 -0
  26. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/docs/tmux-cli-instructions.md +0 -0
  27. {claude_code_tools-0.1.9 → claude_code_tools-0.1.11}/docs/vault-documentation.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: claude-code-tools
3
- Version: 0.1.9
3
+ Version: 0.1.11
4
4
  Summary: Collection of tools for working with Claude Code
5
5
  Requires-Python: >=3.11
6
6
  Requires-Dist: click>=8.0.0
@@ -1,3 +1,3 @@
1
1
  """Claude Code Tools - Collection of utilities for Claude Code."""
2
2
 
3
- __version__ = "0.1.9"
3
+ __version__ = "0.1.11"
@@ -11,7 +11,74 @@ from typing import Optional, List, Dict, Tuple, Callable, Union
11
11
  import json
12
12
  import os
13
13
  import hashlib
14
- from pathlib import Path
14
+ import importlib.resources
15
+
16
+
17
+ def _load_help_text():
18
+ """Load help text from the package's docs directory."""
19
+ try:
20
+ # For development, try to load from the actual file system first
21
+ import pathlib
22
+ module_dir = pathlib.Path(__file__).parent
23
+ # Try looking in the parent directory (repo root) for docs
24
+ docs_file = module_dir.parent / 'docs' / 'tmux-cli-instructions.md'
25
+ if docs_file.exists():
26
+ return docs_file.read_text(encoding='utf-8')
27
+
28
+ # For installed packages, use importlib.resources
29
+ if hasattr(importlib.resources, 'files'):
30
+ # Python 3.9+ style
31
+ import importlib.resources as resources
32
+
33
+ # Try different possible locations for the docs
34
+ # 1. Try docs as a subdirectory within the package
35
+ try:
36
+ help_file = resources.files('claude_code_tools') / 'docs' / 'tmux-cli-instructions.md'
37
+ if help_file.is_file():
38
+ return help_file.read_text(encoding='utf-8')
39
+ except:
40
+ pass
41
+
42
+ # 2. Try accessing parent package to find docs at root level
43
+ try:
44
+ # This assumes docs/ is packaged at the same level as claude_code_tools/
45
+ package_root = resources.files('claude_code_tools').parent
46
+ help_file = package_root / 'docs' / 'tmux-cli-instructions.md'
47
+ if help_file.is_file():
48
+ return help_file.read_text(encoding='utf-8')
49
+ except:
50
+ pass
51
+
52
+ # Try pkg_resources as another fallback
53
+ try:
54
+ import pkg_resources
55
+ # Try different paths
56
+ for path in ['docs/tmux-cli-instructions.md', '../docs/tmux-cli-instructions.md']:
57
+ try:
58
+ return pkg_resources.resource_string(
59
+ 'claude_code_tools', path
60
+ ).decode('utf-8')
61
+ except:
62
+ continue
63
+ except:
64
+ pass
65
+
66
+ except Exception as e:
67
+ pass
68
+
69
+ # If all else fails, return a basic help message
70
+ return """# tmux-cli Instructions
71
+
72
+ Error: Could not load full documentation.
73
+
74
+ Basic usage:
75
+ - tmux-cli launch "command" - Launch a CLI application
76
+ - tmux-cli send "text" --pane=PANE_ID - Send input to a pane
77
+ - tmux-cli capture --pane=PANE_ID - Capture output from a pane
78
+ - tmux-cli kill --pane=PANE_ID - Kill a pane
79
+ - tmux-cli help - Display full help
80
+
81
+ For full documentation, see docs/tmux-cli-instructions.md in the package repository."""
15
82
 
16
83
 
17
84
  class TmuxCLIController:
@@ -657,10 +724,6 @@ class CLI:
657
724
 
658
725
  def help(self):
659
726
  """Display tmux-cli usage instructions."""
660
- # Find the instructions file relative to this module
661
- module_dir = Path(__file__).parent.parent
662
- instructions_file = module_dir / "docs" / "tmux-cli-instructions.md"
663
-
664
727
  # Add mode-specific header
665
728
  mode_info = f"\n{'='*60}\n"
666
729
  if self.mode == 'local':
@@ -670,12 +733,7 @@ class CLI:
670
733
  mode_info += f"{'='*60}\n"
671
734
 
672
735
  print(mode_info)
673
-
674
- if instructions_file.exists():
675
- print(instructions_file.read_text())
676
- else:
677
- print("Error: tmux-cli-instructions.md not found")
678
- print(f"Expected location: {instructions_file}")
736
+ print(_load_help_text())
679
737
 
680
738
  if self.mode == 'remote':
681
739
  print("\n" + "="*60)
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Remote Tmux Controller - Stub implementation
4
+ This is a minimal stub to prevent import errors when tmux-cli is used outside tmux.
5
+ """
6
+
7
+ import subprocess
8
+ from typing import Optional, List, Dict
9
+
10
+
11
+ class RemoteTmuxController:
12
+ """Stub implementation of RemoteTmuxController to prevent import errors."""
13
+
14
+ def __init__(self, session_name: str = "remote-cli-session"):
15
+ """Initialize with session name."""
16
+ self.session_name = session_name
17
+ print(f"Warning: RemoteTmuxController is not fully implemented.")
18
+ print(f"Remote mode functionality is currently unavailable.")
19
+ print(f"Please use tmux-cli from inside a tmux session for full functionality.")
20
+
21
+ def list_panes(self) -> List[Dict[str, str]]:
22
+ """Return empty list."""
23
+ return []
24
+
25
+ def launch_cli(self, command: str, name: Optional[str] = None) -> Optional[str]:
26
+ """Not implemented."""
27
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
28
+
29
+ def send_keys(self, text: str, pane_id: Optional[str] = None, enter: bool = True,
30
+ delay_enter: bool = True):
31
+ """Not implemented."""
32
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
33
+
34
+ def capture_pane(self, pane_id: Optional[str] = None, lines: Optional[int] = None) -> str:
35
+ """Not implemented."""
36
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
37
+
38
+ def wait_for_idle(self, pane_id: Optional[str] = None, idle_time: float = 2.0,
39
+ check_interval: float = 0.5, timeout: Optional[int] = None) -> bool:
40
+ """Not implemented."""
41
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
42
+
43
+ def send_interrupt(self, pane_id: Optional[str] = None):
44
+ """Not implemented."""
45
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
46
+
47
+ def send_escape(self, pane_id: Optional[str] = None):
48
+ """Not implemented."""
49
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
50
+
51
+ def kill_window(self, window_id: Optional[str] = None):
52
+ """Not implemented."""
53
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
54
+
55
+ def attach_session(self):
56
+ """Not implemented."""
57
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
58
+
59
+ def cleanup_session(self):
60
+ """Not implemented."""
61
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
62
+
63
+ def list_windows(self) -> List[Dict[str, str]]:
64
+ """Not implemented."""
65
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
66
+
67
+ def _resolve_pane_id(self, pane: Optional[str]) -> Optional[str]:
68
+ """Not implemented."""
69
+ raise NotImplementedError("Remote mode is not available. Please use tmux-cli from inside tmux.")
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "claude-code-tools"
3
- version = "0.1.9"
3
+ version = "0.1.11"
4
4
  description = "Collection of tools for working with Claude Code"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.11"
@@ -23,6 +23,10 @@ requires = ["hatchling"]
23
23
  build-backend = "hatchling.build"
24
24
 
25
25
  [tool.hatch.build]
26
+ include = [
27
+ "claude_code_tools/**/*.py",
28
+ "docs/*.md",
29
+ ]
26
30
  exclude = [
27
31
  "demos/",
28
32
  "*.mp4",
@@ -36,7 +40,7 @@ exclude = [
36
40
 
37
41
  [tool.commitizen]
38
42
  name = "cz_conventional_commits"
39
- version = "0.1.9"
43
+ version = "0.1.11"
40
44
  tag_format = "v$version"
41
45
  version_files = [
42
46
  "pyproject.toml:version",
@@ -1,37 +0,0 @@
1
- .PHONY: install release patch minor major dev-install help publish
2
-
3
- help:
4
- @echo "Available commands:"
5
- @echo " make install - Install in editable mode (for development)"
6
- @echo " make dev-install - Install with dev dependencies (includes commitizen)"
7
- @echo " make release - Bump patch version and install globally"
8
- @echo " make patch - Bump patch version (0.0.X) and install"
9
- @echo " make minor - Bump minor version (0.X.0) and install"
10
- @echo " make major - Bump major version (X.0.0) and install"
11
- @echo " make publish - Bump patch version, build, and publish to PyPI"
12
-
13
- install:
14
- uv tool install --force -e .
15
-
16
- dev-install:
17
- uv pip install -e ".[dev]"
18
-
19
- release: patch
20
-
21
- patch:
22
- @echo "Bumping patch version..."
23
- uv run cz bump --increment PATCH --yes
24
- uv tool install --force --reinstall .
25
- @echo "Installation complete!"
26
-
27
- minor:
28
- @echo "Bumping minor version..."
29
- uv run cz bump --increment MINOR --yes
30
- uv tool install --force --reinstall .
31
- @echo "Installation complete!"
32
-
33
- major:
34
- @echo "Bumping major version..."
35
- uv run cz bump --increment MAJOR --yes
36
- uv tool install --force --reinstall .
37
- @echo "Installation complete!"
@@ -1,211 +0,0 @@
1
- # Claude Code Hooks
2
-
3
- This directory contains safety and utility hooks for Claude Code that enhance its
4
- behavior and prevent dangerous operations.
5
-
6
- ## Overview
7
-
8
- Claude Code hooks are scripts that intercept tool operations to:
9
- - Prevent accidental data loss
10
- - Enforce best practices
11
- - Manage context size
12
- - Send notifications
13
- - Track operation state
14
-
15
- ## Setup
16
-
17
- 1. Copy `settings.sample.json` to `settings.json`:
18
- ```bash
19
- cp settings.sample.json settings.json
20
- ```
21
-
22
- 2. Set the `CLAUDE_CODE_TOOLS_PATH` environment variable:
23
- ```bash
24
- export CLAUDE_CODE_TOOLS_PATH=/path/to/claude-code-tools
25
- ```
26
-
27
- 3. Make hook scripts executable:
28
- ```bash
29
- chmod +x hooks/*.py hooks/*.sh
30
- ```
31
-
32
- 4. Place your `settings.json` at (or add contents to) your global claude location, e.g. `~/.claude/settings.json``
33
-
34
- ## Hook Types
35
-
36
- ### Notification Hooks
37
-
38
- Triggered for various events to send notifications.
39
-
40
- ### PreToolUse Hooks
41
-
42
- Triggered before a tool executes. Can block operations by returning non-zero exit
43
- codes with error messages.
44
-
45
- ### PostToolUse Hooks
46
-
47
- Triggered after a tool completes. Used for cleanup and state management.
48
-
49
- ## Available Hooks
50
-
51
- ### 1. notification_hook.sh
52
-
53
- **Type:** Notification
54
- **Purpose:** Send notifications to ntfy.sh channel
55
- **Behavior:**
56
- - Reads JSON input and extracts the 'message' field
57
- - Sends notification to ntfy.sh/cc-alerts channel
58
- - Never blocks operations
59
-
60
- **Configuration:** Update the ntfy.sh URL in the script if using a different
61
- channel.
62
-
63
- ### 2. bash_hook.py
64
-
65
- **Type:** PreToolUse (Bash)
66
- **Purpose:** Unified safety checks for bash commands
67
- **Blocks:**
68
- - `rm` commands (enforces TRASH directory pattern)
69
- - Dangerous `git add` patterns (`-A`, `--all`, `.`, `*`)
70
- - Unsafe `git checkout` operations
71
- - Commands that could cause data loss
72
-
73
- **Features:**
74
- - Combines multiple safety checks
75
- - Provides helpful alternative suggestions
76
- - Prevents accidental file deletion and git mishaps
77
-
78
- ### 3. file_size_conditional_hook.py
79
-
80
- **Type:** PreToolUse (Read)
81
- **Purpose:** Prevent reading large files that bloat context
82
- **Behavior:**
83
- - Main agent: Blocks files > 500 lines
84
- - Sub-agents: Blocks files > 10,000 lines
85
- - Binary files are always allowed
86
- - Considers offset/limit parameters
87
-
88
- **Suggestions:**
89
- - Use sub-agents for large file analysis
90
- - Use grep/search tools for specific content
91
- - Consider external tools for very large files
92
-
93
- ### 4. pretask_subtask_flag.py & posttask_subtask_flag.py
94
-
95
- **Type:** PreToolUse/PostToolUse (Task)
96
- **Purpose:** Track sub-agent execution state
97
- **Behavior:**
98
- - Pre: Creates `.claude_in_subtask.flag` file
99
- - Post: Removes the flag file
100
- - Enables different behavior for sub-agents (like larger file limits)
101
-
102
- ### 5. grep_block_hook.py
103
-
104
- **Type:** PreToolUse (Grep)
105
- **Purpose:** Enforce use of ripgrep over grep
106
- **Behavior:**
107
- - Always blocks grep commands
108
- - Suggests using `rg` (ripgrep) instead
109
- - Ensures better performance and features
110
-
111
- ## Safety Features
112
-
113
- ### Git Safety
114
-
115
- The bash hook includes comprehensive git safety:
116
-
117
- **Blocked Commands:**
118
- - `git add -A`, `git add --all`, `git add .`
119
- - `git commit -a` without message
120
- - `git checkout -f`, `git checkout .`
121
- - Operations that could lose uncommitted changes
122
-
123
- **Alternatives Suggested:**
124
- - `git add -u` for modified files
125
- - `git add <specific-files>` for targeted staging
126
- - `git stash` before dangerous operations
127
- - `git switch` for branch changes
128
-
129
- ### File Deletion Safety
130
-
131
- **Instead of `rm`:**
132
- - Move files to `TRASH/` directory
133
- - Document in `TRASH-FILES.md` with reason
134
- - Preserves ability to recover files
135
-
136
- Example:
137
- ```bash
138
- # Instead of: rm unwanted.txt
139
- mv unwanted.txt TRASH/
140
- echo "unwanted.txt - moved to TRASH/ - no longer needed" >> TRASH-FILES.md
141
- ```
142
-
143
- ### Context Management
144
-
145
- The file size hook prevents Claude from reading huge files that would:
146
- - Consume excessive context
147
- - Slow down processing
148
- - Potentially cause errors
149
-
150
- ## Customization
151
-
152
- ### Adding New Hooks
153
-
154
- 1. Create your hook script in the `hooks/` directory
155
- 2. Add it to your `settings.json`:
156
- ```json
157
- {
158
- "matcher": "ToolName",
159
- "hooks": [{
160
- "type": "command",
161
- "command": "$CLAUDE_CODE_TOOLS_PATH/hooks/your_hook.py"
162
- }]
163
- }
164
- ```
165
-
166
- ### Hook Return Codes
167
-
168
- - `0`: Allow operation to proceed
169
- - Non-zero: Block operation (error message goes to stderr)
170
-
171
- ### Hook Input/Output
172
-
173
- Hooks receive:
174
- - Tool parameters as JSON on stdin
175
- - Environment variables with context
176
-
177
- Hooks output:
178
- - Approval/rejection via exit code
179
- - Error messages to stderr
180
- - Logs to stdout (not shown to user)
181
-
182
- ## Best Practices
183
-
184
- 1. **Make hooks fast** - They run synchronously before operations
185
- 2. **Provide helpful errors** - Explain why operations are blocked
186
- 3. **Suggest alternatives** - Help users accomplish their goals safely
187
- 4. **Log for debugging** - Use stdout for diagnostic information
188
- 5. **Test thoroughly** - Hooks can significantly impact Claude's behavior
189
-
190
- ## Troubleshooting
191
-
192
- ### Hooks not triggering
193
-
194
- - Verify `settings.json` is in the correct location
195
- - Check file permissions (`chmod +x`)
196
- - Ensure paths use `$CLAUDE_CODE_TOOLS_PATH`
197
- - Test with `echo` statements to debug
198
-
199
- ### Operations being blocked unexpectedly
200
-
201
- - Check hook logic for edge cases
202
- - Review blocking conditions
203
- - Add logging to understand decisions
204
- - Consider making hooks more permissive for sub-agents
205
-
206
- ### Performance issues
207
-
208
- - Hooks run synchronously - keep them fast
209
- - Avoid network calls in hooks
210
- - Cache results when possible
211
- - Consider async notifications post-operation
@@ -1,66 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Unified Bash hook that combines all bash command safety checks.
4
- This ensures that if ANY check wants to block, the command is blocked.
5
- """
6
- import json
7
- import sys
8
- import os
9
-
10
- # Add hooks directory to Python path so we can import the other modules
11
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
12
-
13
- # Import check functions from other hooks
14
- from git_add_block_hook import check_git_add_command
15
- from git_checkout_safety_hook import check_git_checkout_command
16
- from rm_block_hook import check_rm_command
17
-
18
-
19
- def main():
20
- data = json.load(sys.stdin)
21
-
22
- # Check if this is a Bash tool call
23
- tool_name = data.get("tool_name")
24
- if tool_name != "Bash":
25
- print(json.dumps({"decision": "approve"}))
26
- sys.exit(0)
27
-
28
- # Get the command being executed
29
- command = data.get("tool_input", {}).get("command", "")
30
-
31
- # Run all checks - collect all blocking reasons
32
- checks = [
33
- check_rm_command,
34
- check_git_add_command,
35
- check_git_checkout_command,
36
- ]
37
-
38
- blocking_reasons = []
39
-
40
- for check_func in checks:
41
- should_block, reason = check_func(command)
42
- if should_block:
43
- blocking_reasons.append(reason)
44
-
45
- # If any check wants to block, block the command
46
- if blocking_reasons:
47
- # If multiple checks want to block, combine the reasons
48
- if len(blocking_reasons) == 1:
49
- combined_reason = blocking_reasons[0]
50
- else:
51
- combined_reason = "Multiple safety checks failed:\n\n"
52
- for i, reason in enumerate(blocking_reasons, 1):
53
- combined_reason += f"{i}. {reason}\n\n"
54
-
55
- print(json.dumps({
56
- "decision": "block",
57
- "reason": combined_reason
58
- }, ensure_ascii=False))
59
- else:
60
- print(json.dumps({"decision": "approve"}))
61
-
62
- sys.exit(0)
63
-
64
-
65
- if __name__ == "__main__":
66
- main()
@@ -1,96 +0,0 @@
1
- #!/usr/bin/env python3
2
- import os
3
- import json
4
- import sys
5
- import subprocess
6
-
7
-
8
- data = json.load(sys.stdin)
9
-
10
- # Check if we're in a subtask
11
- flag_file = '.claude_in_subtask.flag'
12
- is_main_agent = not os.path.exists(flag_file)
13
- # if os.path.exists(flag_file):
14
- # print(json.dumps({"decision": "approve"}))
15
- # sys.exit(0)
16
-
17
- # Check file size
18
- file_path = data.get("tool_input", {}).get("file_path")
19
- offset = data.get("tool_input", {}).get("offset",0)
20
- limit = data.get("tool_input", {}).get("limit",0) # 0 if absent
21
-
22
- if file_path and os.path.exists(file_path):
23
- # Check if this is a binary file by examining its content
24
- def is_binary_file(filepath):
25
- """Check if a file is binary by looking for null bytes in first chunk"""
26
- try:
27
- with open(filepath, 'rb') as f:
28
- # Read first 8192 bytes (or less if file is smaller)
29
- chunk = f.read(8192)
30
- if not chunk: # Empty file
31
- return False
32
-
33
- # Files with null bytes are likely binary
34
- if b'\x00' in chunk:
35
- return True
36
-
37
- # Try to decode as UTF-8
38
- try:
39
- chunk.decode('utf-8')
40
- return False
41
- except UnicodeDecodeError:
42
- return True
43
- except Exception:
44
- # If we can't read the file, assume it's binary to be safe
45
- return True
46
-
47
- # Skip line count check for binary files
48
- if is_binary_file(file_path):
49
- print(json.dumps({"decision": "approve"}))
50
- sys.exit(0)
51
-
52
- line_count = int(subprocess.check_output(['wc', '-l', file_path]).split()[0])
53
-
54
- # Compute effective number of lines to be read
55
- if limit > 0:
56
- # If limit is specified, we read from offset to offset+limit
57
- effective_lines = min(limit, max(0, line_count - offset))
58
- else:
59
- # If no limit, we read from offset to end of file
60
- effective_lines = max(0, line_count - offset)
61
-
62
- if is_main_agent and line_count > 500:
63
- print(json.dumps({
64
- "decision": "block",
65
- "reason": f"""
66
- I see you are trying to read a file with {line_count} lines,
67
- or a part of it.
68
- Please delegate the analysis to a SUB-AGENT using your Task tool,
69
- so you don't bloat your context with the file content!
70
- """,
71
- }))
72
- sys.exit(0)
73
- elif (not is_main_agent) and line_count > 10_000:
74
- # use gemini-cli to delegate the analysis
75
- print(json.dumps({
76
- "decision": "block",
77
- "reason": f"""
78
- File too large ({line_count} lines), please use the Gemini CLI
79
- bash command to delegate the analysis to Gemini since it has
80
- a 1M-token context window! This will help you avoid bloating
81
- your context.
82
-
83
- You can use Gemini CLI as in these EXAMPLES:
84
-
85
- `gemini -p "@src/somefile.py tell me at which line the definition of
86
- the function 'my_function' is located"
87
-
88
- `gemini -p "@package.json @src/index.js Analyze the dependencies used in the code"
89
-
90
- See further guidelines in claude-mds/use-gemini-cli.md
91
- """,
92
- }))
93
- sys.exit(0)
94
-
95
- print(json.dumps({"decision": "approve"}))
96
- sys.exit(0)