Skip to main content

Escape-proof precision file editing — Python bindings for moesniper

Project description

moesniper

Escape-proof precision file editor for LLM agents. Hex-encoded content, line-range splicing, atomic writes, metabolic pacing.

License: MIT Rust: 1.87+

Quick Start

cargo install moesniper

# Replace line 5
sniper file.rs 5 5 68656c6c6f

# Undo
sniper file.rs --undo

Features

Feature What It Does
Hex-encoded content Zero shell corruption — all payloads are hex strings
Line-range splicing Replace or delete any contiguous line range, 1-indexed
Atomic writes Temp file + rename(2) — file is never in an inconsistent state
Multi-step undo Each edit creates a backup; --undo pops the stack
Manifest operations Batch JSON operations applied bottom-up (line numbers never shift)
Dry-run preview --dry-run shows diff with +/-/~ markers before applying
Indentation safety Validation blocks mis-indented edits; --auto-indent fixes them, --force-indent bypasses
Context verification --context <hash> verifies SHA-256 of surrounding lines before applying
PID file locks Per-file locks with stale PID detection — auto-recovery if previous process died
Metabolic pacing llmosafe 0.6.2 ResourceGuard::auto(0.5) — adaptive back-pressure based on RSS, IO wait, and load
Path traversal protection .. components rejected, SecurityPolicy guards all file access
Configurable limits File size, backup retention, lock timeout — all via environment variables
JSON output --json for machine-readable results
Backup retention Count-based + age-based purge policies

Usage

sniper <file> <start> <end> <hex>                Replace lines with hex content
sniper <file> <start> <end> --delete             Delete line range
sniper <file> <start> <end> --stdin              Read content from stdin
sniper <file> <start> <end> <hex> --context <h>  Replace with context verification
sniper <file> --manifest <path>                  Batch operations (JSON)
sniper <file> --undo                             Restore from backup
sniper encode [--stdin|--file <path>|<text>]      Hex-encode content

Flags

Flag Effect
--dry-run Preview changes without writing
--json Output machine-readable JSON
--stdin Read content from stdin instead of hex arg
--context <hash> Verify SHA-256 hash (first 16 hex chars) of lines before/after edit target
--auto-indent Auto-detect and apply indentation from context
--force-indent Bypass indentation validation (allow unindented content)

Encoding

Content must be hex-encoded to prevent shell corruption:

echo -n 'fn main() {}' | sniper encode --stdin
# 666e206d61696e2829207b7d

Manifest Format

[
  {"start": 42, "end": 45, "hex": "6e6577"},
  {"start": 10, "delete": true}
]

Operations apply bottom-up (highest line first, so earlier edits don't shift later targets). Line numbers are 1-indexed.

Examples

# Replace a function
sniper src/main.rs 42 42 $(echo 'new_call()' | sniper encode --stdin)

# Delete a block
sniper src/lib.rs 100 150 --delete

# Safe workflow (preview first)
sniper file.rs 1 5 7878 --dry-run && sniper file.rs 1 5 7878

# Batch edit via manifest
echo '[{"start":1,"end":1,"hex":"78"}]' | sniper file.rs --manifest /dev/stdin

# Insert at end of file
sniper file.rs 4 3 $(echo 'new_line' | sniper encode --stdin)

# Context-verified edit (rejects if surrounding code changed)
sniper file.rs 10 10 7878 --context 1a2b3c4d5e6f7a8b

Configuration

Variable Default Description
SNIPER_LOCK_TIMEOUT 30 Lock acquisition timeout (seconds, min 1)
SNIPER_MAX_FILE_SIZE 100MB Maximum file size to edit (0 = unlimited)
SNIPER_BACKUP_RETENTION_COUNT 50 Number of backups to retain (0 = unlimited)
SNIPER_BACKUP_MAX_AGE_DAYS 30 Max backup age in days (0 = no limit)
SNIPER_DISABLE_AUDIT (unset) Set to any value to disable audit logging

How It Works

  1. Path validationnormalize_path() rejects .. traversal and canonicalizes
  2. File size check — rejects files exceeding SNIPER_MAX_FILE_SIZE
  3. Lock acquisition — PID file lock with configurable timeout; stale PID detection recovers from crashed processes
  4. Context verification — optional --context <sha256> flag hashes 3 lines before and 3 lines after the edit target; if the context changed since the agent computed line numbers, the edit is rejected with a "context mismatch" error
  5. Backup — file copied to .sniper/ with hash+timestamp name
  6. Splice — lines loaded into memory, range replaced, result written atomically (temp file + rename)
  7. Metabolic pacingllmosafe checks RSS, IO wait, load average; sleeps if system is under pressure
  8. Purge — old backups pruned by count and age per retention policy

JSON Output

The --json flag produces a CliResult object with these fields:

Field Type Description
status string ok, dry_run, restored, encoded, or error
file string Target file path
message string Error message (on failure) or encoded hex (on encode)
lines_removed number Number of lines removed
lines_inserted number Number of lines inserted
line_shift number Net line change (lines_inserted - lines_removed); positive = lines moved down
total_lines number Total lines in file after edit
operations number Number of manifest operations applied
backup string Path to backup file created
ai_hint string Suggestion for the LLM agent
diff_preview array Dry-run diff with +/-/~ markers
indent_warning string Indentation mismatch warning
indent_fixed boolean Whether auto-indent was applied

Contributing

See CONTRIBUTING.md.

License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

moesniper-0.7.4.tar.gz (80.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

moesniper-0.7.4-cp312-cp312-manylinux_2_34_x86_64.whl (435.8 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

File details

Details for the file moesniper-0.7.4.tar.gz.

File metadata

  • Download URL: moesniper-0.7.4.tar.gz
  • Upload date:
  • Size: 80.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.13.3

File hashes

Hashes for moesniper-0.7.4.tar.gz
Algorithm Hash digest
SHA256 d72d6f66806770da76b1908fedc3de0b4c130c9de064462fce8e3d4e797e9c61
MD5 b1c96d04e5c903ea63d627f673f9ed05
BLAKE2b-256 edfeabbf5d8cb0667ff51b8b5bb843878438caf5ee1a57d626173a70f08baadf

See more details on using hashes here.

File details

Details for the file moesniper-0.7.4-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for moesniper-0.7.4-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 d6fb318ccc9e4d752353f659a1b2a939f1a8e03257c347c3f4d27fa170acf9f2
MD5 6470b00ab73c4bebce7d59afd13d588f
BLAKE2b-256 65735104a976951fab41a40035ac2c4ae5d44cfff1ae69a2e3787464f13476bc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page