Based on claude-code-tools TmuxCLIController, this refactor: - Added DockerTmuxController class for robust tmux session management - Implements send_keys() with configurable delay_enter - Implements capture_pane() for output retrieval - Implements wait_for_prompt() for pattern-based completion detection - Implements wait_for_idle() for content-hash-based idle detection - Implements wait_for_shell_prompt() for shell prompt detection Also includes workflow improvements: - Pre-task git snapshot before agent execution - Post-task commit protocol in agent guidelines Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
105 lines
3.5 KiB
Python
105 lines
3.5 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script to patch the luzia binary with status integration.
|
|
This adds import and initialization code for the status system.
|
|
"""
|
|
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
def create_status_integration_code():
|
|
"""Generate the status integration code to inject"""
|
|
return '''
|
|
# =============================================================================
|
|
# STATUS SYSTEM INTEGRATION (Added by luzia_status_patcher.py)
|
|
# =============================================================================
|
|
try:
|
|
from luzia_status_integration import get_status_system
|
|
STATUS_SYSTEM = get_status_system()
|
|
STATUS_SYSTEM_ENABLED = STATUS_SYSTEM.is_enabled()
|
|
_log(f"[STATUS] System enabled: {STATUS_SYSTEM_ENABLED}", verbose_only=True)
|
|
except Exception as e:
|
|
_log(f"[STATUS] Failed to initialize: {e}", verbose_only=True)
|
|
STATUS_SYSTEM = None
|
|
STATUS_SYSTEM_ENABLED = False
|
|
'''
|
|
|
|
def find_import_location(content: str) -> int:
|
|
"""Find where to insert imports (after docker_bridge import)"""
|
|
lines = content.split('\n')
|
|
for i, line in enumerate(lines):
|
|
if 'from docker_bridge import' in line:
|
|
# Find the end of this import block
|
|
for j in range(i+1, len(lines)):
|
|
if lines[j].strip() and not lines[j].startswith(' ') and not lines[j].startswith('\t'):
|
|
return j
|
|
return i + 1
|
|
return -1
|
|
|
|
def find_main_function(content: str) -> int:
|
|
"""Find the main() function"""
|
|
lines = content.split('\n')
|
|
for i, line in enumerate(lines):
|
|
if line.startswith('def main():'):
|
|
return i
|
|
return -1
|
|
|
|
def find_router_init(content: str) -> int:
|
|
"""Find where Router is initialized in main()"""
|
|
lines = content.split('\n')
|
|
main_idx = find_main_function(content)
|
|
if main_idx == -1:
|
|
return -1
|
|
|
|
for i in range(main_idx, len(lines)):
|
|
if 'router = Router(config)' in lines[i]:
|
|
return i
|
|
return -1
|
|
|
|
def patch_luzia_binary(binary_path: str) -> bool:
|
|
"""Patch the luzia binary with status integration"""
|
|
print(f"Patching {binary_path}...")
|
|
|
|
try:
|
|
# Read current binary
|
|
with open(binary_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Check if already patched
|
|
if 'STATUS SYSTEM INTEGRATION' in content:
|
|
print("Binary already patched, skipping...")
|
|
return True
|
|
|
|
# Find location to insert status code
|
|
main_idx = find_main_function(content)
|
|
if main_idx == -1:
|
|
print("ERROR: Could not find main() function")
|
|
return False
|
|
|
|
# Insert initialization code after "config = load_config()"
|
|
lines = content.split('\n')
|
|
for i in range(main_idx, len(lines)):
|
|
if 'config = load_config()' in lines[i]:
|
|
# Insert status init code
|
|
indent = ' '
|
|
status_code = create_status_integration_code()
|
|
insert_lines = [indent + line if line.strip() else line
|
|
for line in status_code.split('\n')]
|
|
lines = lines[:i+1] + insert_lines + lines[i+1:]
|
|
break
|
|
|
|
# Write patched binary
|
|
with open(binary_path, 'w') as f:
|
|
f.write('\n'.join(lines))
|
|
|
|
print("Patching successful!")
|
|
return True
|
|
|
|
except Exception as e:
|
|
print(f"ERROR: {e}")
|
|
return False
|
|
|
|
if __name__ == '__main__':
|
|
binary = '/opt/server-agents/orchestrator/bin/luzia'
|
|
sys.exit(0 if patch_luzia_binary(binary) else 1)
|