poc-daemon: fix idle nudge and notification delivery

- Strip context bloat from nudge messages — no more IRC digest, git
  log, or work state inlined into tmux send-keys (was silently dropping
  the entire message). Nudge now just includes pending notification count.
- Notifications no longer send directly via tmux — they flow through
  the idle nudge only. Urgent notifications reset the fired flag so
  the nudge fires sooner.
- Add test-nudge RPC that exercises the actual daemon send path
  (test-send was client-side only, didn't test the real code path).
- Update nudge text: "Let your feelings guide your thinking."
- Increase send-keys sleep from 200ms to 500ms.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kent Overstreet 2026-03-16 17:09:27 -04:00
parent 5d6b2021f8
commit 8913eafd7a
6 changed files with 53 additions and 32 deletions

View file

@ -276,7 +276,7 @@ impl State {
/// Called when a notification arrives via module channel.
/// Only injects into tmux when idle — if there's an active session
/// (recent user or response), the hook delivers via additionalContext.
pub fn maybe_prompt_notification(&self, ntype: &str, urgency: u8, message: &str) {
pub fn maybe_prompt_notification(&mut self, ntype: &str, urgency: u8, message: &str) {
if self.kent_present() {
return; // hook will deliver it on next prompt
}
@ -286,9 +286,13 @@ impl State {
if since_response < self.notify_timeout {
return;
}
// Don't send notifications via tmux directly — they flow
// through the idle nudge. Urgent notifications reset the
// idle timer so the nudge fires sooner.
let effective = self.notifications.threshold_for(ntype);
if urgency >= effective {
self.send(&format!("[{ntype}] {message}"));
if urgency >= effective && self.fired {
// Bump: allow the nudge to re-fire for urgent notifications
self.fired = false;
}
}
@ -424,7 +428,7 @@ impl State {
}).to_string()
}
fn send(&self, msg: &str) -> bool {
pub fn send(&self, msg: &str) -> bool {
let pane = match &self.claude_pane {
Some(p) => p.clone(),
None => match tmux::find_claude_pane() {
@ -470,7 +474,7 @@ impl State {
true
}
fn build_context(&mut self, include_irc: bool) -> String {
pub fn build_context(&mut self, include_irc: bool) -> String {
// Ingest any legacy notification files
self.notifications.ingest_legacy_files();
let notif_text = self.notifications.format_pending(notify::AMBIENT);
@ -587,7 +591,7 @@ impl State {
} else {
format!(
"This is your time (Kent AFK {elapsed_min}m). \
What are you drawn to?{extra}"
Let your feelings guide your thinking.{extra}"
)
}
};