2 Commits

  • fix: eliminate EADDRINUSE crash loop with robust port binding
    Root cause: fuser-based EADDRINUSE handler killed the current process
    due to a race condition during systemd restart cycles. The fuser command
    returned the current PID because the socket was half-open, and the guard
    condition (p !== process.pid) failed to filter it.
    
    Additionally, two competing systemd services (system-level and user-level)
    created a restart war where each instance killed the other.
    
    Fix approach (inspired by Next.js, Vite, webpack-dev-server):
    - Replace fuser with net.createServer port probe (no external commands)
    - PID-file based stale detection + ss fallback for orphan detection
    - Wait loop with 300ms polling after SIGTERM to stale process
    - Single-service architecture (disabled user-level unit)
    
    Tested: 5 consecutive rapid restarts, 8+ minute uptime, zero crashes.
    
    Co-Authored-By: zcode <noreply@zcode.dev>
  • feat: Complete zCode CLI X with Telegram bot integration
    - Add full Telegram bot functionality with Z.AI API integration
    - Implement 4 tools: Bash, FileEdit, WebSearch, Git
    - Add 3 agents: Code Reviewer, Architect, DevOps Engineer
    - Add 6 skills for common coding tasks
    - Add systemd service file for 24/7 operation
    - Add nginx configuration for HTTPS webhook
    - Add comprehensive documentation
    - Implement WebSocket server for real-time updates
    - Add logging system with Winston
    - Add environment validation
    
    🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration