Initial commit
This commit is contained in:
138
skills/code-transfer/SKILL.md
Normal file
138
skills/code-transfer/SKILL.md
Normal file
@@ -0,0 +1,138 @@
|
||||
---
|
||||
name: code-transfer
|
||||
description: Transfer code between files with line-based precision. Use when users request copying code from one location to another, moving functions or classes between files, extracting code blocks, or inserting code at specific line numbers.
|
||||
---
|
||||
|
||||
# Code Transfer
|
||||
|
||||
Transfer code between files with precise line-based control. **Dual-mode operation**: native tools (1-10 files) or execution mode (10+ files, 90% token savings).
|
||||
|
||||
## Operation Modes
|
||||
|
||||
### Basic Mode (Default)
|
||||
Use Read, Edit, Bash scripts for 1-10 file operations. Works immediately, no setup required.
|
||||
|
||||
### Execution Mode (10+ files)
|
||||
```python
|
||||
from api.filesystem import batch_copy
|
||||
from api.code_analysis import find_functions
|
||||
|
||||
functions = find_functions('app.py', pattern='handle_.*')
|
||||
operations = [{
|
||||
'source_file': 'app.py',
|
||||
'start_line': f['start_line'],
|
||||
'end_line': f['end_line'],
|
||||
'target_file': 'handlers.py',
|
||||
'target_line': -1
|
||||
} for f in functions]
|
||||
batch_copy(operations)
|
||||
```
|
||||
|
||||
## When to Use
|
||||
|
||||
- "copy this code to [file]"
|
||||
- "move [function/class] to [file]"
|
||||
- "extract this to a new file"
|
||||
- "insert at line [number]"
|
||||
- "reorganize into separate files"
|
||||
|
||||
## Core Operations
|
||||
|
||||
### 1. Extract Source Code
|
||||
```
|
||||
Read(file_path="src/auth.py") # Full file
|
||||
Read(file_path="src/auth.py", offset=10, limit=20) # Line range
|
||||
Grep(pattern="def authenticate", -n=true, -A=10) # Find function
|
||||
```
|
||||
|
||||
### 2. Insert at Specific Line
|
||||
Use `line_insert.py` script for line-based insertion:
|
||||
|
||||
```bash
|
||||
python3 skills/code-transfer/scripts/line_insert.py <file> <line_number> <code> [--backup]
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Insert function at line 50
|
||||
python3 skills/code-transfer/scripts/line_insert.py src/utils.py 50 "def helper():\n pass"
|
||||
|
||||
# Insert with backup
|
||||
python3 skills/code-transfer/scripts/line_insert.py src/utils.py 50 "code" --backup
|
||||
|
||||
# Insert at beginning
|
||||
python3 skills/code-transfer/scripts/line_insert.py src/new.py 1 "import os"
|
||||
```
|
||||
|
||||
**When to use:**
|
||||
- User specifies exact line number
|
||||
- Inserting into new/empty files
|
||||
- Inserting at beginning/end without context
|
||||
|
||||
### 3. Insert Relative to Content
|
||||
Use **Edit** when insertion point is relative to existing code:
|
||||
|
||||
```
|
||||
Edit(
|
||||
file_path="src/utils.py",
|
||||
old_string="def existing():\n pass",
|
||||
new_string="def existing():\n pass\n\ndef new():\n return True"
|
||||
)
|
||||
```
|
||||
|
||||
## Workflow Examples
|
||||
|
||||
### Copy Function Between Files
|
||||
1. Find: `Grep(pattern="def validate_user", -n=true, -A=20)`
|
||||
2. Extract: `Read(file_path="auth.py", offset=45, limit=15)`
|
||||
3. Check target: `Read(file_path="validators.py")`
|
||||
4. Insert: Use `line_insert.py` or Edit based on context
|
||||
|
||||
### Extract Class to New File
|
||||
1. Locate: `Grep(pattern="class DatabaseConnection", -n=true, -A=50)`
|
||||
2. Extract: `Read(file_path="original.py", offset=100, limit=50)`
|
||||
3. Create: `Write(file_path="database.py", content="<extracted>")`
|
||||
4. Update imports: `Edit` in original file
|
||||
5. Remove old class: `Edit` with replacement
|
||||
|
||||
### Insert at Specific Line
|
||||
1. Validate: `Read(file_path="main.py", offset=20, limit=10)`
|
||||
2. Insert: `python3 skills/code-transfer/scripts/line_insert.py main.py 25 "logger.info('...')" --backup`
|
||||
3. Verify: `Read(file_path="main.py", offset=23, limit=5)`
|
||||
|
||||
### Reorganize Into Modules
|
||||
1. Analyze: `Read(file_path="utils.py")`
|
||||
2. Identify groups: `Grep(pattern="^def |^class ", -n=true)`
|
||||
3. Extract each category: `Write` new files
|
||||
4. Update original: Re-export or redirect
|
||||
|
||||
## Best Practices
|
||||
|
||||
**Planning:**
|
||||
- Understand dependencies (imports, references)
|
||||
- Identify exact start/end of code block
|
||||
- Check target file structure
|
||||
- Ensure necessary imports included
|
||||
|
||||
**Preservation:**
|
||||
- Include docstrings and comments
|
||||
- Transfer related functions together
|
||||
- Update imports in both files
|
||||
- Maintain formatting/indentation
|
||||
|
||||
**Validation:**
|
||||
- Verify insertion placement
|
||||
- Check syntax
|
||||
- Test imports
|
||||
- Suggest running tests
|
||||
|
||||
**Backups:**
|
||||
- Use `--backup` for significant changes
|
||||
- Critical file operations
|
||||
- Large deletions
|
||||
|
||||
## Integration
|
||||
|
||||
- **code-refactor**: Refactor after transferring
|
||||
- **test-fixing**: Run tests after reorganizing
|
||||
- **feature-planning**: Plan large reorganizations
|
||||
188
skills/code-transfer/scripts/line_insert.py
Executable file
188
skills/code-transfer/scripts/line_insert.py
Executable file
@@ -0,0 +1,188 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Line-based code insertion utility.
|
||||
|
||||
This script provides precise line-number-based code insertion,
|
||||
which complements Claude's native Edit tool (which requires exact string matching).
|
||||
|
||||
Usage:
|
||||
python line_insert.py <file_path> <line_number> <code> [--backup]
|
||||
|
||||
Examples:
|
||||
# Insert at line 10
|
||||
python line_insert.py src/main.py 10 "print('hello')"
|
||||
|
||||
# Insert with backup
|
||||
python line_insert.py src/main.py 10 "print('hello')" --backup
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from datetime import datetime
|
||||
|
||||
|
||||
def validate_file_path(file_path: Path) -> None:
|
||||
"""
|
||||
Validate that the file path is safe to use.
|
||||
|
||||
Args:
|
||||
file_path: Path object to validate
|
||||
|
||||
Raises:
|
||||
ValueError: If path is invalid or unsafe
|
||||
"""
|
||||
# Resolve to absolute path
|
||||
abs_path = file_path.resolve()
|
||||
|
||||
# Basic security: prevent directory traversal
|
||||
if ".." in str(file_path):
|
||||
raise ValueError(f"Path contains '..' which is not allowed: {file_path}")
|
||||
|
||||
# Check parent directory exists (or can be created)
|
||||
if not abs_path.parent.exists():
|
||||
raise ValueError(f"Parent directory does not exist: {abs_path.parent}")
|
||||
|
||||
|
||||
def create_backup(file_path: Path) -> Path:
|
||||
"""
|
||||
Create a backup of the file with timestamp.
|
||||
|
||||
Args:
|
||||
file_path: Path to the file to backup
|
||||
|
||||
Returns:
|
||||
Path to the backup file
|
||||
"""
|
||||
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
|
||||
backup_path = file_path.with_suffix(f"{file_path.suffix}.backup_{timestamp}")
|
||||
|
||||
if file_path.exists():
|
||||
backup_path.write_text(file_path.read_text())
|
||||
print(f"✅ Created backup: {backup_path}", file=sys.stderr)
|
||||
|
||||
return backup_path
|
||||
|
||||
|
||||
def insert_code(
|
||||
file_path: Path,
|
||||
line_number: int,
|
||||
code: str,
|
||||
create_backup_flag: bool = False
|
||||
) -> None:
|
||||
"""
|
||||
Insert code at a specific line number in a file.
|
||||
|
||||
Args:
|
||||
file_path: Path to the target file
|
||||
line_number: Line number where code should be inserted (1-based)
|
||||
code: Code to insert (can be multiple lines)
|
||||
create_backup_flag: Whether to create a backup before modifying
|
||||
|
||||
Raises:
|
||||
ValueError: If line_number is invalid
|
||||
IOError: If file operations fail
|
||||
"""
|
||||
# Validate inputs
|
||||
validate_file_path(file_path)
|
||||
|
||||
if line_number < 1:
|
||||
raise ValueError(f"Line number must be >= 1, got: {line_number}")
|
||||
|
||||
# Create backup if requested and file exists
|
||||
if create_backup_flag and file_path.exists():
|
||||
create_backup(file_path)
|
||||
|
||||
# Read existing content or start with empty
|
||||
if file_path.exists():
|
||||
with open(file_path, 'r', encoding='utf-8') as f:
|
||||
lines = f.readlines()
|
||||
else:
|
||||
lines = []
|
||||
print(f"ℹ️ Creating new file: {file_path}", file=sys.stderr)
|
||||
|
||||
# Prepare code lines to insert
|
||||
code_lines = code.splitlines(keepends=True)
|
||||
# Ensure last line has newline if inserting in middle of file
|
||||
if code_lines and not code_lines[-1].endswith('\n'):
|
||||
code_lines[-1] += '\n'
|
||||
|
||||
# Insert at the specified line (1-based index)
|
||||
# Line 1 means insert at the beginning
|
||||
# Line len(lines)+1 means append at the end
|
||||
insert_index = line_number - 1
|
||||
|
||||
if insert_index > len(lines):
|
||||
# If line number is beyond file, pad with empty lines
|
||||
lines.extend(['\\n'] * (insert_index - len(lines)))
|
||||
|
||||
# Insert the code
|
||||
lines[insert_index:insert_index] = code_lines
|
||||
|
||||
# Write back to file
|
||||
file_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
with open(file_path, 'w', encoding='utf-8') as f:
|
||||
f.writelines(lines)
|
||||
|
||||
print(f"✅ Inserted {len(code_lines)} line(s) at line {line_number} in {file_path}", file=sys.stderr)
|
||||
|
||||
|
||||
def main():
|
||||
"""Main entry point for CLI usage."""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Insert code at a specific line number in a file",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog="""
|
||||
Examples:
|
||||
# Insert a single line at line 10
|
||||
%(prog)s src/main.py 10 "print('hello')"
|
||||
|
||||
# Insert multiple lines
|
||||
%(prog)s src/main.py 10 "def foo():\\n pass"
|
||||
|
||||
# Insert with backup
|
||||
%(prog)s src/main.py 10 "print('hello')" --backup
|
||||
"""
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'file_path',
|
||||
type=Path,
|
||||
help='Path to the target file'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'line_number',
|
||||
type=int,
|
||||
help='Line number where code should be inserted (1-based)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'code',
|
||||
type=str,
|
||||
help='Code to insert (use \\n for newlines)'
|
||||
)
|
||||
|
||||
parser.add_argument(
|
||||
'--backup',
|
||||
action='store_true',
|
||||
help='Create a backup before modifying the file'
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
insert_code(
|
||||
file_path=args.file_path,
|
||||
line_number=args.line_number,
|
||||
code=args.code,
|
||||
create_backup_flag=args.backup
|
||||
)
|
||||
sys.exit(0)
|
||||
except Exception as e:
|
||||
print(f"❌ Error: {e}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user