Skip to content

Push notifications lack session/project context and deep linking #100

@mebpenguin

Description

@mebpenguin

Description

Push notifications from Happy CLI are generic and don't include context about which session needs attention. When multiple sessions are running, there's no way to know which one to check without opening the app and looking through all sessions.

Current notification: "Claude is waiting for your command"
Desired notification: "admin has a question for you" (with deep link to that session)

Current Behavior

  1. Notifications show generic message regardless of which project/session triggered them
  2. No deep linking - tapping notification just opens the app, not the specific session
  3. In Yolo mode, AskUserQuestion tool calls don't reliably trigger notifications

Expected Behavior

  1. Notifications should include the project name (from session metadata path)
  2. Notifications should include or link to the session ID
  3. Tapping notification should deep-link to the specific session
  4. AskUserQuestion should always trigger a notification (even in Yolo mode)

Environment

  • Happy CLI version: 0.12.0
  • Platform: macOS (darwin arm64)
  • Server: Self-hosted (denysvitali/happy-server)

Proposed Code Fix

Based on reviewing the source code, here's a suggested implementation:

1. Enhance PushNotificationClient.sendToAllDevices() in src/api/pushNotifications.ts

Add session context parameters:

// Current signature:
sendToAllDevices(title: string, body: string, data?: Record<string, any>): void

// Proposed signature:
sendToAllDevices(
  title: string,
  body: string,
  options?: {
    sessionId?: string;
    projectPath?: string;
    data?: Record<string, any>;
  }
): void

Implementation change:

sendToAllDevices(title: string, body: string, options?: NotificationOptions): void {
  const { sessionId, projectPath, data = {} } = options || {};

  // Extract project name from path
  const projectName = projectPath ? path.basename(projectPath) : undefined;

  // Include context in notification data for deep linking
  const notificationData = {
    ...data,
    sessionId,
    projectPath,
    projectName,
    action: 'open_session'  // For app to handle deep link
  };

  // Use project name in body if available
  const enhancedBody = projectName
    ? `${projectName}: ${body}`
    : body;

  void (async () => {
    // ... existing implementation with enhancedBody and notificationData
  })();
}

2. Pass session context when triggering notifications

In src/api/apiSession.ts, when emitting events that trigger notifications, include the session metadata:

// When AskUserQuestion or permission-request is detected:
this.pushClient?.sendToAllDevices(
  '🤔 Input Needed',
  'has a question for you',
  {
    sessionId: this.sessionId,
    projectPath: this.metadata?.path,
  }
);

3. Handle AskUserQuestion tool calls explicitly

In the agent message handler (likely in src/agent/ or session handler), detect AskUserQuestion tool calls and trigger notifications:

// In message handler:
if (message.type === 'tool-call' && message.toolName === 'AskUserQuestion') {
  // Trigger notification even in Yolo mode
  this.sendInputNeededNotification({
    sessionId: this.sessionId,
    projectPath: this.metadata?.path,
    reason: 'question'
  });
}

4. Update iOS app to handle deep links

The app should read sessionId from notification data and navigate directly to that session when tapped.

Workaround

For now, I'm using a Claude Code hook that calls happy notify on AskUserQuestion. It sends a generic notification but at least alerts me to check the app:

# ~/.claude/hooks/notify-on-question.sh
#!/bin/bash
command -v happy &>/dev/null || exit 0
(sleep 1; happy notify -t "🤔 Input Needed" -p "A Claude session has a question for you") &
exit 0

With settings.json:

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "AskUserQuestion",
      "hooks": [{ "type": "command", "command": "~/.claude/hooks/notify-on-question.sh", "timeout": 5 }]
    }]
  }
}

Additional Context

The sendToAllDevices method in pushNotifications.ts already accepts a data parameter that could carry session context. The infrastructure is there - it just needs to be wired up:

  1. Session metadata (including path) is available in ApiSessionClient
  2. PushNotificationClient can accept arbitrary data
  3. Just need to connect them and update the notification body format

Related Files

  • src/api/pushNotifications.ts - Push notification client
  • src/api/apiSession.ts - Session state management
  • src/agent/AgentBackend.ts - Tool call handling interface

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions