---
phase: 01-single-consumer-consolidation
plan: 01
type: execute
wave: 1
depends_on: []
files_modified:
  - ~/.claude/automation/claude-telegram-sync/src/main.ts
  - ~/.claude/automation/claude-telegram-sync/src/claude-sync/notification-watcher.ts
autonomous: true
requirements: [NOTIF-01]

must_haves:
  truths:
    - "Bun bot no longer watches the notification directory or sends session-end Telegram messages"
    - "Bun bot /prompt and /sessions commands still work after watcher removal"
    - "Bun bot Q&A text handler (MiniMax) still works — lastSessionBox and registerNotificationButtons exports remain in commands.ts"
    - "Companion receives and processes every session-end notification without duplicates (unchanged — already the sole consumer in practice)"
  artifacts:
    - path: "~/.claude/automation/claude-telegram-sync/src/main.ts"
      provides: "Bun bot entry point without notification watcher"
      contains: "registerCommands"
    - path: "~/.claude/automation/claude-telegram-sync/src/claude-sync/notification-watcher.ts"
      provides: "Disabled notification watcher (file retained with deprecation notice)"
  key_links:
    - from: "~/.claude/automation/claude-telegram-sync/src/main.ts"
      to: "telegram bot polling"
      via: "startBotWithResilience(bot)"
      pattern: "startBotWithResilience"
    - from: "~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts"
      to: "Q&A text handler"
      via: "lastSessionBox export used by message:text handler"
      pattern: "lastSessionBox"
---

<objective>
Remove the Bun bot's notification directory watcher so the companion is the sole consumer of `~/.claude/notifications/` JSON files.

Purpose: Eliminate duplicate Telegram notifications. The companion already processes all session-end notifications; the Bun bot's watcher is redundant. After this, only the companion sends session summaries to Telegram.

Output: Modified `main.ts` (watcher removed from startup and shutdown), retained but deprecated `notification-watcher.ts` (kept as reference, exports removed from main).
</objective>

<execution_context>
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
@$HOME/.claude/get-shit-done/templates/summary.md
</execution_context>

<context>
@.planning/PROJECT.md
@.planning/ROADMAP.md
@.planning/STATE.md
@.planning/phases/01-single-consumer-consolidation/01-CONTEXT.md
</context>

<interfaces>
<!-- Key exports from commands.ts that MUST remain after watcher removal -->

From ~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts:

```typescript
export const lastSessionBox: {
  current: { transcriptText: string; cwd: string; sessionId: string } | null;
} = { current: null };

export function registerNotificationButtons(
  cwd: string,
  workspace: string,
  transcriptPath: string,
  sessionId: string = "",
  transcriptText: string = "",
): number;
```

These are used by the Q&A text handler (bot.on("message:text")) within commands.ts itself. They are NOT consumed by notification-watcher.ts — notification-watcher.ts IMPORTS them. Removing the watcher does NOT remove these exports.
</interfaces>

<tasks>

<task type="auto">
  <name>Task 1: Remove notification watcher from Bun bot main.ts</name>
  <files>~/.claude/automation/claude-telegram-sync/src/main.ts</files>
  <read_first>
    - ~/.claude/automation/claude-telegram-sync/src/main.ts
    - ~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts (verify lastSessionBox and registerNotificationButtons are defined here, not in notification-watcher.ts)
  </read_first>
  <action>
Edit ~/.claude/automation/claude-telegram-sync/src/main.ts to remove the notification watcher:

1. **Remove the import**: Delete `import { watchNotifications } from "./claude-sync/notification-watcher.js";`

2. **Remove the watcher start call**: Delete `const watcher = watchNotifications(bot, config.chatId, botState);` (line ~75)

3. **Remove the watcher stop from SIGINT handler**: Delete `watcher.stop();` from the process.on("SIGINT") handler (line ~89)

4. **Add a comment** where the watcher was started:

   ```typescript
   // Notification watching handled by claude-tts-companion (sole consumer since Phase 1)
   // See: plugins/claude-tts-companion/.planning/ROADMAP.md — NOTIF-01
   ```

All other imports and functionality (createTelegramBot, registerCommands, startBotWithResilience, startThinkingWatcher, drainQueue, setCommandMenu, loadBotState, loadBotCredentials, startHealthProbe) remain untouched.

The startup notification message (sendMessage with status icon) stays — it announces the Bun bot is running.
The thinking watcher (`startThinkingWatcher`) stays — it monitors a different concern.
</action>
<verify>
<automated>cd ~/.claude/automation/claude-telegram-sync && grep -c "watchNotifications" src/main.ts | grep -q "^0$" && echo "PASS: no watchNotifications references" || echo "FAIL: watchNotifications still referenced"</automated>
</verify>
<acceptance_criteria> - main.ts does NOT contain the string "watchNotifications" - main.ts does NOT contain the string "notification-watcher" - main.ts does NOT contain "watcher.stop()" - main.ts DOES contain "startBotWithResilience" (bot polling preserved) - main.ts DOES contain "registerCommands" (command handlers preserved) - main.ts DOES contain "startThinkingWatcher" (thinking watcher preserved) - main.ts DOES contain "drainQueue" (TTS queue drain preserved) - main.ts contains comment referencing "claude-tts-companion" or "NOTIF-01"
</acceptance_criteria>
<done>main.ts no longer imports, starts, or stops the notification watcher. All other Bun bot functionality (commands, polling, thinking watcher, TTS drain, health probe) is preserved.</done>
</task>

<task type="auto">
  <name>Task 2: Deprecate notification-watcher.ts and verify Bun bot starts</name>
  <files>~/.claude/automation/claude-telegram-sync/src/claude-sync/notification-watcher.ts</files>
  <read_first>
    - ~/.claude/automation/claude-telegram-sync/src/claude-sync/notification-watcher.ts
    - ~/.claude/automation/claude-telegram-sync/src/main.ts (after Task 1 edits)
  </read_first>
  <action>
1. **Add deprecation header** to notification-watcher.ts — prepend at line 1:
   ```typescript
   /**
    * @deprecated Since 2026-04-02 (NOTIF-01: Single-Consumer Consolidation).
    * Notification watching is now handled exclusively by claude-tts-companion.
    * This file is retained as reference for the notification format and processing logic.
    * It is no longer imported by main.ts.
    */
   ```

1. **Verify Bun bot starts without errors** by running:

   ```bash
   cd ~/.claude/automation/claude-telegram-sync
   timeout 10 bun run src/main.ts 2>&1 || true
   ```

   Expected: Bot starts, connects to Telegram ("Connected as @..."), does NOT log "Watching for Stop hook notifications".
   The process will be killed by timeout — that's fine, we just need to see it starts.

2. **Verify commands.ts exports are intact** — confirm `lastSessionBox` and `registerNotificationButtons` are still exported:

   ```bash
   grep -n "export.*lastSessionBox\|export.*registerNotificationButtons" ~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts
   ```

   Expected: Both exports present (lines ~106 and ~112).

3. **Verify no other file imports from notification-watcher.ts**:

   ```bash
   grep -r "notification-watcher" ~/.claude/automation/claude-telegram-sync/src/ --include="*.ts" | grep -v "CLAUDE.md" | grep -v "notification-watcher.ts"
   ```

   Expected: Zero results (main.ts import was removed in Task 1, only comments remain in formatter.ts).
   </action>

  <verify>
    <automated>cd ~/.claude/automation/claude-telegram-sync && grep -q "@deprecated" src/claude-sync/notification-watcher.ts && grep -q "export.*lastSessionBox" src/telegram/commands.ts && grep -q "export.*registerNotificationButtons" src/telegram/commands.ts && ! grep -l "notification-watcher" src/main.ts > /dev/null 2>&1 && echo "PASS" || echo "FAIL"</automated>
  </verify>
  <acceptance_criteria>
    - notification-watcher.ts first line contains "@deprecated"
    - notification-watcher.ts contains "NOTIF-01" in the deprecation notice
    - commands.ts contains `export const lastSessionBox`
    - commands.ts contains `export function registerNotificationButtons`
    - main.ts does NOT contain "notification-watcher" (import removed)
    - Bun bot process starts without import errors (exit code is 0 or timeout, not module-not-found)
  </acceptance_criteria>
  <done>notification-watcher.ts is marked deprecated. Bun bot starts cleanly without the notification watcher. /prompt, /sessions commands and Q&A text handler are unaffected because their exports live in commands.ts, not notification-watcher.ts.</done>
</task>

</tasks>

<verification>
1. `grep -c "watchNotifications" ~/.claude/automation/claude-telegram-sync/src/main.ts` returns 0
2. `grep -c "@deprecated" ~/.claude/automation/claude-telegram-sync/src/claude-sync/notification-watcher.ts` returns 1+
3. `grep -c "export.*lastSessionBox" ~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts` returns 1+
4. `grep -c "export.*registerNotificationButtons" ~/.claude/automation/claude-telegram-sync/src/telegram/commands.ts` returns 1+
5. Bun bot starts without module resolution errors
6. Companion's NotificationWatcher.swift is unchanged (already the sole consumer)
</verification>

<success_criteria>

- Bun bot runs without notification watcher (no "Watching for Stop hook notifications" log)
- Bun bot /prompt, /sessions, Q&A text handler all work (commands.ts unchanged)
- notification-watcher.ts is deprecated but retained as reference
- Companion is now the sole consumer of ~/.claude/notifications/ JSON files
  </success_criteria>

<output>
After completion, create `.planning/phases/01-single-consumer-consolidation/01-01-SUMMARY.md`
</output>
