Skip to content

Signal Handling Lifecycle

Documents how amplihack-rs handles OS signals (SIGINT, SIGTERM, SIGTSTP, SIGWINCH) across the CLI, fleet manager, and child processes.

Signal Dispatch Overview

flowchart TD
    OS([OS sends signal]) --> Router{Which process\nreceives it?}

    Router -- amplihack CLI\nforeground --> CLIHandler[CLI signal handler]
    Router -- tmux pane\nchild process --> TmuxPropagation[tmux propagates\nto Claude process]

    subgraph CLIHandler
        SigInt[SIGINT\nCtrl-C] --> GracefulShutdown[Drain in-flight ops\nexit code 0]
        SigTerm[SIGTERM] --> GracefulShutdown
        SigTstp[SIGTSTP\nCtrl-Z] --> PauseFleet[Pause all Running\nfleet sessions]
        SigWinch[SIGWINCH\nterminal resize] --> Repaint[Recalculate layout\nredraw TUI]
    end

    GracefulShutdown --> Exit0([Exit 0])
    PauseFleet --> Suspend([Process suspended])
    Repaint --> Dashboard([Dashboard redrawn])

SIGINT Parity Contract

SIGINT (Ctrl-C) must exit with code 0, not 130. This matches the Python amplihack behaviour and allows shell scripts to treat user interruption as a normal exit.

sequenceDiagram
    participant User
    participant CLI as amplihack CLI
    participant Fleet as Fleet Manager
    participant Claude as Claude Process

    User->>CLI: Ctrl-C (SIGINT)
    CLI->>Fleet: signal: shutdown
    Fleet->>Claude: SIGTERM (graceful)
    Claude-->>Fleet: exited
    Fleet-->>CLI: all sessions stopped
    CLI->>CLI: flush metrics / memory
    CLI-->>User: exit 0  ✅

Signal Forwarding to Child Sessions

flowchart LR
    SIGINT --> |"fleet admiral\nreceives"| Admiral
    Admiral --> |"for each Running session"| TmuxSend["tmux send-keys\n'' Enter"]
    TmuxSend --> ClaudeExit[Claude exits cleanly]
    ClaudeExit --> SessionState[Session → Stopped]
    SessionState --> Admiral
    Admiral --> |"all sessions drained"| Exit0([exit 0])

Terminal Resize (SIGWINCH)

sequenceDiagram
    participant Terminal
    participant CLI as amplihack TUI
    participant Renderer

    Terminal->>CLI: SIGWINCH (terminal resized)
    CLI->>CLI: query new dimensions\n(ioctl TIOCGWINSZ)
    CLI->>Renderer: layout(new_width, new_height)
    Renderer->>Terminal: redraw all panels