Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Notifications silently dropped: hooks have no controlling terminal, so warp-notify.sh write to /dev/tty fails

Đang mở
#49 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Đánh giá

Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức phù hợp với người mới
68/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Ít trao đổi
Công nghệ
macos, shell
Lĩnh vực
cli, desktop

Hướng nghiên cứu

Read scripts/warp-notify.sh, especially the gate, payload, and /dev/tty write path. Reproduce a hook without a controlling terminal on macOS, then verify that notifications and the CLI-agent indicator render through the plugin flow while normal interactive-shell behavior still works.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

Plugin: warp@claude-code-warp v2.0.0 (commit b8ad3cc6c1e40b2d2a944f900a4ae0904a54dd7f)
Affected file: scripts/warp-notify.sh
Platform: macOS (Darwin 25.3.0), Warp v0.2026.05.13.09.15.stable_03, WARP_CLI_AGENT_PROTOCOL_VERSION=1

Summary

The plugin never delivers any notification (no desktop banner, no in-tab CLI-agent
indicator) because the only delivery path writes to /dev/tty, and Claude Code
spawns hook subprocesses without a controlling terminal. The write fails and is
swallowed by 2>/dev/null || true, so the failure is completely silent — the plugin
appears installed and healthy, the gate passes, valid payloads are built, and nothing
ever reaches Warp.

This is not specific to wrapper/alias launchers; it reproduces with a plain
claude invocation. Any environment where Claude Code runs hooks detached from the
controlling TTY is affected.

Root cause

scripts/warp-notify.sh:

printf '\033]777;notify;%s;%s\007' "$TITLE" "$BODY" > /dev/tty 2>/dev/null || true

The hook process inherits no controlling terminal from Claude Code, so /dev/tty
is unopenable. 2>/dev/null || true then masks the failure.

Evidence

Diagnostic instrumentation added to warp-notify.sh (logging only, no behavior
change), then a normal task run in real Claude Code sessions. Every hook firing —
session_start, stop, etc., across multiple profiles — logged:

TERM_PROGRAM=WarpTerminal PROT=1 VER=v0.2026.05.13.09.15.stable_03
tty=not a tty
devtty=UNWRITABLE
gate=PASS
title=warp://cli-agent bodylen=164

So: gate passes, payload is correct, but the target terminal is unwritable.

Working reference: emitting the exact same session_start → stop handshake
(schema built by the plugin's own build_payload) from an interactive shell that
does own the Warp pane PTY makes the CLI-agent tab indicator appear correctly.
The only differing variable is the writable terminal device. Because the very first
session_start handshake is also lost, Warp never registers the agent session, so
every subsequent event is orphaned too.

Suggested fix

Keep /dev/tty as the primary path (correct for normal shells), but when it is
unwritable, walk up the process ancestry to the Claude Code process — which does
own the Warp pane's PTY — and write the OSC there:

_warp_resolve_tty() {
    if { : > /dev/tty; } 2>/dev/null; then
        echo "/dev/tty"; return 0
    fi
    local pid=$$ hop tty_name dev
    for hop in $(seq 1 16); do
        pid=$(ps -o ppid= -p "$pid" 2>/dev/null | tr -d ' ')
        { [ -z "$pid" ] || [ "$pid" = "0" ] || [ "$pid" = "1" ]; } && break
        tty_name=$(ps -o tty= -p "$pid" 2>/dev/null | tr -d ' ')
        { [ -z "$tty_name" ] || [ "$tty_name" = "??" ]; } && continue
        dev="/dev/$tty_name"
        [ -w "$dev" ] && { echo "$dev"; return 0; }
    done
    return 1
}

TARGET_TTY="$(_warp_resolve_tty)"
[ -n "$TARGET_TTY" ] && \
    printf '\033]777;notify;%s;%s\007' "$TITLE" "$BODY" > "$TARGET_TTY" 2>/dev/null || true

Verified: in a no-controlling-terminal process (the exact hook condition) this
resolves the Claude Code process's real PTY and the CLI-agent indicator then renders
correctly from the unmodified plugin flow.

Secondary suggestion

Consider not masking the write failure unconditionally — even a one-line stderr or
opt-in debug log would have made this self-diagnosable instead of silent.

Reproduction

  1. macOS, Warp with WARP_CLI_AGENT_PROTOCOL_VERSION set.
  2. Install the plugin; run claude; complete any task.
  3. Observe: no notification, no tab indicator. Add a log line before the /dev/tty
    write and observe tty is not a tty / /dev/tty unwritable in the hook.
Ngôn ngữ chính
Shell
Star
232
Fork
56
Merge trung bình
4 ngày 15 giờ
Pull request đã merge (30 ngày)
1

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của warpdotdev/claude-code-warp

Tất cả issue của warpdotdev/claude-code-warp

Issue tương tự

Thêm issue về Shell/Bash

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.