From 1d7faa32b586f856619da4c35bd4080e445d05cd Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Tue, 1 Sep 2026 15:32:18 +0200 Subject: [PATCH 1/3] =?UTF-8?q?chore(hooks):=20notify-attention=20?= =?UTF-8?q?=E2=80=94=20bell=20+=20OSC=20777=20toast=20when=20Claude=20need?= =?UTF-8?q?s=20input?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Notification hook (permission_prompt|idle_prompt|agent_needs_input| elicitation_*) returns BEL x2 + OSC 777 via the terminalSequence JSON field (hooks have no controlling TTY). Client side over Remote-SSH: VS Code accessibility.signals.terminalBell sound:on for the beep, wenbopan.vscode-terminal-osc-notifier extension for the Windows toast. --- hooks/notify-attention.sh | 24 ++++++++++++++++++++++++ settings.json | 13 +++++++++++++ 2 files changed, 37 insertions(+) create mode 100755 hooks/notify-attention.sh diff --git a/hooks/notify-attention.sh b/hooks/notify-attention.sh new file mode 100755 index 0000000..b7a3ef7 --- /dev/null +++ b/hooks/notify-attention.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# Notification hook — signal the user through the terminal when Claude +# needs input (permission prompt, question, idle wait). +# +# Runs on the remote (Linux); the only channel that crosses SSH into the +# VS Code client is the terminal stream. Hooks have no controlling TTY, +# so the sequence goes through the supported `terminalSequence` JSON +# output field and Claude Code writes it to the terminal: +# - BEL x2 (double beep) -> sound, needs VS Code setting +# accessibility.signals.terminalBell { "sound": "on" } +# - OSC 777 notify -> Windows toast via the client-side extension +# "Terminal Notification" (wenbopan.vscode-terminal-osc-notifier) +# Both are invisible no-ops in terminals that ignore them. +set -u + +msg=$(jq -r '.message // .notification_type // empty' 2>/dev/null \ + | tr -d '\000-\037' | cut -c1-200) +[ -n "$msg" ] || msg="Claude Code needs your input" + +bell=$(printf '\a') +esc=$(printf '\033') +seq="${bell}${bell}${esc}]777;notify;Claude Code;${msg}${esc}\\" +jq -cn --arg seq "$seq" '{suppressOutput: true, terminalSequence: $seq}' +exit 0 diff --git a/settings.json b/settings.json index 2ddaa29..7efe32d 100644 --- a/settings.json +++ b/settings.json @@ -273,6 +273,19 @@ ] } ], + "Notification": [ + { + "matcher": "permission_prompt|idle_prompt|agent_needs_input|elicitation_dialog|elicitation_url_dialog", + "hooks": [ + { + "type": "command", + "command": "bash ~/.claude/hooks/notify-attention.sh", + "timeout": 5, + "statusMessage": "Ringing terminal bell..." + } + ] + } + ], "UserPromptSubmit": [ { "hooks": [ From 6c04ada6a89cc6bd0b45ad56c01e0a389563a54d Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Tue, 1 Sep 2026 15:32:25 +0200 Subject: [PATCH 2/3] chore(settings): default model opus[1m] (was claude-fable-5[1m]) --- settings.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.json b/settings.json index 7efe32d..e366d8b 100644 --- a/settings.json +++ b/settings.json @@ -250,7 +250,7 @@ "disableBypassPermissionsMode": "disable", "additionalDirectories": [] }, - "model": "claude-fable-5[1m]", + "model": "opus[1m]", "hooks": { "SessionStart": [ { From f08c3ab51ce35db5c2d28128484e8ce88dacf9a2 Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Tue, 1 Sep 2026 15:32:51 +0200 Subject: [PATCH 3/3] chore(memory): LRN-145 terminalSequence pattern + journal 2026-09-01 --- .claude/memory/journal.md | 4 ++++ .claude/memory/learnings.md | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/.claude/memory/journal.md b/.claude/memory/journal.md index ff63f91..152d470 100644 --- a/.claude/memory/journal.md +++ b/.claude/memory/journal.md @@ -448,3 +448,7 @@ rules: - `/darwin-skill all skills and agents` (background). Fresh results.tsv (May file wiped). 7 blind judges, 54 rows (31 skill-systems + 23 agents), mean 83.4, 13 <80. find-docs excluded — machine-owned ctx7 (gitignored), 3rd exclusion ground after BDR-015/058. - Phase 2: 12 rounds / 13 units, 0 reverts, all paired 3-0 ([[EVAL-028]]). Star: skills-perso detection 8/31 → 31/31 live-verified. Bug pass [[BDR-086]]: 8 commits in above-80 units kept 3-0 (hotfix git-restore data-loss path ★, onboarder contract bounce, plugin data-flow, plan-challenger grammar, handover stale §refs + gate order, tour report-only commit, harden severity, fixtures). - make test green after census-rewrap fix ([[LRN-144]]); [[LRN-143]] head-pipe grep mask. 29 commits, report `.claude/audits/DARWIN-2026-08-26.md` + card PNG. Branch awaits human review + merge. + +## 2026-09-01 +- Attention signal shipped: hooks/notify-attention.sh + Notification entry in settings.json (bell x2 + OSC 777 toast via terminalSequence). Client-side VS Code steps pending: terminalBell sound:on + osc-notifier ext. [[LRN-145]]. Branch chore/notify-attention-hook, UNMERGED. +- Pre-existing model switch opus[1m] committed separately on same branch. diff --git a/.claude/memory/learnings.md b/.claude/memory/learnings.md index c896505..21f5b22 100644 --- a/.claude/memory/learnings.md +++ b/.claude/memory/learnings.md @@ -1389,3 +1389,8 @@ Rule: when editing a doctrine file under structure locks, grep the test's lock s - **Context**: darwin 2026-08-26 — hotfix RULES rewrap split "No verifier is dispatched at hotfix weight"; loops-light.test.sh lock RED; make test caught post-edit. - **Pattern**: lib/tests/*.test.sh lock sentences verbatim, single-line. Rewording/rewrapping skill+agent md near locked phrases silently breaks census. - **Future**: before editing skill/agent prose, grep lib/tests/ for locks in the touched region; run make test BEFORE dispatching judges, not after. + +## LRN-145 — hooks reach the terminal only via terminalSequence JSON field +- **Context**: 2026-09-01 — attention bell for VS Code Remote-SSH (CLI on remote Linux). Hook subprocess has no controlling TTY; /dev/tty unreliable. Docs: terminalSequence = supported side-effect field, fires even on events that discard output. +- **Pattern**: Notification hook → stdout JSON `{suppressOutput:true, terminalSequence:""}`. VS Code terminal ignores OSC 777/9 natively (claude-code #28338); client-side ext wenbopan.vscode-terminal-osc-notifier converts to native toast over Remote-SSH; beep needs accessibility.signals.terminalBell sound:on. permission_prompt fires ~6s late, idle_prompt ~60s. +- **Future**: any hook ringing/notifying the terminal (bell, toast, title) — terminalSequence, never /dev/tty. Input-needed matcher set: permission_prompt|idle_prompt|agent_needs_input|elicitation_dialog|elicitation_url_dialog.