Refactor cockpit to use DockerTmuxController pattern
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>
This commit is contained in:
345
QUICK-START.md
Normal file
345
QUICK-START.md
Normal file
@@ -0,0 +1,345 @@
|
||||
# Responsive Dispatcher - Quick Start Guide
|
||||
|
||||
## 30-Second Overview
|
||||
|
||||
The Responsive Dispatcher makes Luzia CLI non-blocking:
|
||||
- Dispatch tasks in **<100ms** (instead of 3-5 seconds)
|
||||
- Returns immediately with **job_id**
|
||||
- Tasks run in **background**
|
||||
- Check status **anytime** without waiting
|
||||
- Manage **multiple concurrent tasks**
|
||||
|
||||
---
|
||||
|
||||
## Installation
|
||||
|
||||
1. **Copy files** to `/opt/server-agents/orchestrator/`:
|
||||
```bash
|
||||
lib/responsive_dispatcher.py
|
||||
lib/cli_feedback.py
|
||||
lib/dispatcher_enhancements.py
|
||||
```
|
||||
|
||||
2. **Run tests** to verify:
|
||||
```bash
|
||||
python3 tests/test_responsive_dispatcher.py
|
||||
# Expected: 11/11 tests passing ✓
|
||||
```
|
||||
|
||||
3. **Try demo**:
|
||||
```bash
|
||||
python3 examples/demo_concurrent_tasks.py
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### Dispatch a Task (Non-blocking)
|
||||
```bash
|
||||
$ luzia overbits "fix the login button"
|
||||
✓ Dispatched
|
||||
Job ID: 113754-a2f5
|
||||
Project: overbits
|
||||
|
||||
Use: luzia jobs to view status
|
||||
luzia jobs 113754-a2f5 for details
|
||||
```
|
||||
|
||||
**Key Point**: Returns immediately! CLI is responsive.
|
||||
|
||||
### Check Status Anytime
|
||||
```bash
|
||||
$ luzia jobs 113754-a2f5
|
||||
RUNNING [██████░░░░░░░░░░░░░░] 30% Processing files...
|
||||
|
||||
Details:
|
||||
Job ID: 113754-a2f5
|
||||
Project: overbits
|
||||
Status: running
|
||||
Progress: 30%
|
||||
```
|
||||
|
||||
### List All Jobs
|
||||
```bash
|
||||
$ luzia jobs
|
||||
|
||||
Recent Jobs:
|
||||
|
||||
Job ID Status Prog Project Message
|
||||
------------------------------------
|
||||
113754-a2f5 running 30% overbits Processing files...
|
||||
113754-8e4b running 65% musica Analyzing audio...
|
||||
113754-7f2d completed 100% dss Completed
|
||||
```
|
||||
|
||||
### Watch Job Progress (Interactive)
|
||||
```bash
|
||||
$ luzia jobs 113754-a2f5 --watch
|
||||
|
||||
Monitoring job: 113754-a2f5
|
||||
|
||||
starting [░░░░░░░░░░░░░░░░░░░░] 5%
|
||||
running [██████░░░░░░░░░░░░░░] 30%
|
||||
running [████████████░░░░░░░░] 65%
|
||||
completed [██████████████████████] 100%
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Multiple Concurrent Tasks
|
||||
|
||||
```bash
|
||||
# Dispatch multiple tasks (all start immediately)
|
||||
$ luzia overbits "task 1" &
|
||||
$ luzia musica "task 2" &
|
||||
$ luzia dss "task 3" &
|
||||
|
||||
agent:overbits:113754-a2f5
|
||||
agent:musica:113754-8e4b
|
||||
agent:dss:113754-9f3c
|
||||
|
||||
# Check all are running
|
||||
$ luzia jobs
|
||||
|
||||
Task Summary:
|
||||
Running: 3
|
||||
Pending: 0
|
||||
Completed: 0
|
||||
Failed: 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API Usage (Python)
|
||||
|
||||
### Quick Dispatch
|
||||
```python
|
||||
from lib.dispatcher_enhancements import EnhancedDispatcher
|
||||
|
||||
enhanced = EnhancedDispatcher()
|
||||
|
||||
# Dispatch and show feedback
|
||||
job_id, status = enhanced.dispatch_and_report(
|
||||
project="overbits",
|
||||
task="fix the login button"
|
||||
)
|
||||
|
||||
# Check status
|
||||
status = enhanced.get_status_and_display(job_id)
|
||||
|
||||
# List jobs
|
||||
enhanced.show_jobs_summary(project="overbits")
|
||||
```
|
||||
|
||||
### Low-Level Access
|
||||
```python
|
||||
from lib.responsive_dispatcher import ResponseiveDispatcher
|
||||
|
||||
dispatcher = ResponseiveDispatcher()
|
||||
|
||||
# Dispatch only
|
||||
job_id, status = dispatcher.dispatch_task("overbits", "task")
|
||||
|
||||
# Get status with cache
|
||||
status = dispatcher.get_status(job_id) # <1ms
|
||||
|
||||
# Update status (for monitor)
|
||||
dispatcher.update_status(job_id, "running", progress=50)
|
||||
|
||||
# Wait for completion (optional)
|
||||
final_status = dispatcher.wait_for_job(job_id, timeout=3600)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance
|
||||
|
||||
**Metrics Achieved**:
|
||||
```
|
||||
Dispatch latency: <100ms (was 3-5s)
|
||||
Status retrieval: <1ms cached
|
||||
Throughput: 434 tasks/second
|
||||
Memory per job: ~2KB
|
||||
Monitor thread: ~5MB
|
||||
```
|
||||
|
||||
**Improvement**: 30-50x faster dispatch
|
||||
|
||||
---
|
||||
|
||||
## Status States
|
||||
|
||||
Job progresses through:
|
||||
```
|
||||
dispatched → starting → running → completed
|
||||
↓
|
||||
failed
|
||||
↓
|
||||
stalled
|
||||
Any state → killed
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Locations
|
||||
|
||||
**Job data**: `/var/lib/luzia/jobs/<job_id>/`
|
||||
```
|
||||
├── status.json (current status, updated by monitor)
|
||||
├── meta.json (job metadata)
|
||||
├── output.log (agent output)
|
||||
├── progress.md (progress tracking)
|
||||
└── pid (process ID)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
| Issue | Solution |
|
||||
|-------|----------|
|
||||
| Job stuck in "dispatched" | Check `/var/lib/luzia/jobs/<job_id>/output.log` |
|
||||
| Status not updating | Ensure `/var/lib/luzia/jobs/` is writable |
|
||||
| Cache stale | Use `get_status(..., use_cache=False)` |
|
||||
| Monitor not running | Manual start: `start_background_monitoring()` |
|
||||
|
||||
---
|
||||
|
||||
## Integration into Luzia CLI
|
||||
|
||||
**Step 1**: Import in `bin/luzia`
|
||||
```python
|
||||
from lib.dispatcher_enhancements import get_enhanced_dispatcher
|
||||
```
|
||||
|
||||
**Step 2**: Update `route_project_task()` handler
|
||||
```python
|
||||
enhanced = get_enhanced_dispatcher()
|
||||
job_id, status = enhanced.dispatch_and_report(project, task)
|
||||
print(f"agent:{project}:{job_id}")
|
||||
```
|
||||
|
||||
**Step 3**: Add `route_jobs()` handler
|
||||
```python
|
||||
def route_jobs(config, args, kwargs):
|
||||
enhanced = get_enhanced_dispatcher()
|
||||
if not args:
|
||||
enhanced.show_jobs_summary()
|
||||
else:
|
||||
enhanced.get_status_and_display(args[0])
|
||||
return 0
|
||||
```
|
||||
|
||||
**Step 4**: Start monitor in `main()`
|
||||
```python
|
||||
enhanced = get_enhanced_dispatcher()
|
||||
enhanced.dispatcher.start_background_monitor()
|
||||
```
|
||||
|
||||
**See**: `docs/DISPATCHER-INTEGRATION-GUIDE.md` for complete steps
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
Run comprehensive tests:
|
||||
```bash
|
||||
python3 tests/test_responsive_dispatcher.py
|
||||
```
|
||||
|
||||
Expected output:
|
||||
```
|
||||
=== Responsive Dispatcher Test Suite ===
|
||||
8 tests PASSED ✓
|
||||
|
||||
=== Enhanced Dispatcher Test Suite ===
|
||||
3 tests PASSED ✓
|
||||
|
||||
✓ All tests passed!
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Demo
|
||||
|
||||
See it in action:
|
||||
```bash
|
||||
python3 examples/demo_concurrent_tasks.py
|
||||
```
|
||||
|
||||
Demonstrates:
|
||||
1. Concurrent dispatch (5 tasks in 0.01s)
|
||||
2. Non-blocking polling
|
||||
3. Independent monitoring
|
||||
4. Job listing
|
||||
5. Concurrent summary
|
||||
6. Performance metrics
|
||||
|
||||
---
|
||||
|
||||
## Key Files to Review
|
||||
|
||||
1. **Implementation**
|
||||
- `lib/responsive_dispatcher.py` - Core engine
|
||||
- `lib/cli_feedback.py` - Terminal output
|
||||
- `lib/dispatcher_enhancements.py` - Integration
|
||||
|
||||
2. **Documentation**
|
||||
- `RESPONSIVE-DISPATCHER-SUMMARY.md` - Executive summary
|
||||
- `docs/RESPONSIVE-DISPATCHER.md` - Complete user guide
|
||||
- `docs/DISPATCHER-INTEGRATION-GUIDE.md` - How to integrate
|
||||
|
||||
3. **Testing**
|
||||
- `tests/test_responsive_dispatcher.py` - 11 tests
|
||||
- `examples/demo_concurrent_tasks.py` - Live demo
|
||||
|
||||
---
|
||||
|
||||
## Common Commands
|
||||
|
||||
```bash
|
||||
# Dispatch (non-blocking)
|
||||
luzia project "task"
|
||||
|
||||
# Check status
|
||||
luzia jobs job_id
|
||||
|
||||
# List all jobs
|
||||
luzia jobs
|
||||
|
||||
# Watch progress
|
||||
luzia jobs job_id --watch
|
||||
|
||||
# API usage
|
||||
from lib.dispatcher_enhancements import EnhancedDispatcher
|
||||
enhanced = EnhancedDispatcher()
|
||||
job_id, status = enhanced.dispatch_and_report(project, task)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. ✅ Review `RESPONSIVE-DISPATCHER-SUMMARY.md` (5 min read)
|
||||
2. ✅ Run `python3 tests/test_responsive_dispatcher.py` (verify working)
|
||||
3. ✅ Run `python3 examples/demo_concurrent_tasks.py` (see it work)
|
||||
4. 📖 Read `docs/RESPONSIVE-DISPATCHER.md` (understand architecture)
|
||||
5. 🔧 Follow `docs/DISPATCHER-INTEGRATION-GUIDE.md` (integrate into Luzia)
|
||||
6. ✅ Run full system test (verify integration)
|
||||
7. 🚀 Deploy to production
|
||||
|
||||
---
|
||||
|
||||
## Support
|
||||
|
||||
- **User Guide**: `docs/RESPONSIVE-DISPATCHER.md`
|
||||
- **Integration**: `docs/DISPATCHER-INTEGRATION-GUIDE.md`
|
||||
- **Tests**: `python3 tests/test_responsive_dispatcher.py`
|
||||
- **Demo**: `python3 examples/demo_concurrent_tasks.py`
|
||||
|
||||
---
|
||||
|
||||
**Ready to use!** 🚀
|
||||
|
||||
For complete information, see `RESPONSIVE-DISPATCHER-SUMMARY.md`
|
||||
Reference in New Issue
Block a user