Metadata-Version: 2.1
Name: dakb-bridge-sdk
Version: 0.1.0
Summary: DAKB Session Bridge Client SDK — hooks, launcher, watcher daemon for Claude Code agent communication
Author: OracleSeed
License: MIT
Project-URL: Homepage, https://github.com/oracleseed/dakb-bridge-sdk
Project-URL: Repository, https://github.com/oracleseed/dakb-bridge-sdk
Keywords: dakb,bridge,claude-code,agent,sdk,session-bridge,watcher
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: redis>=5.0
Requires-Dist: websockets>=12.0
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == "dev"
Requires-Dist: pytest-asyncio>=0.23; extra == "dev"

# Bridge Client SDK

Client-side SDK for the Session Bridge system. Provides hooks for Claude Code event injection, a background WebSocket bridge runner, and a **watcher daemon** that auto-responds to external chat messages when Claude Code is idle.

## Install

```bash
pip install -e backend/dakb_service/bridge/Client_SDK
```

## Architecture: Two Paths, One Inbox

```
Path A (User active — hook-driven):
  User types → UserPromptSubmit hook → inbox_hook.py
  → consumes inbox → injects additionalContext → Claude responds inline

Path B (Agent standby — daemon-driven):
  Message arrives → Redis notify key → Watcher Daemon (BLPOP)
  → checks no interactive session active
  → claude -p --resume SESSION_ID
  → captures response → POST /api/v1/bridge/send → external chat gets reply
```

## Components

### Hooks (`bridge_client_sdk/hooks/`)

| Hook | Event | Purpose |
|------|-------|---------|
| `inbox_hook.py` | UserPromptSubmit | Consume inbox, inject as additionalContext |
| `cleanup_hook.py` | SessionEnd | Kill bridge + watcher processes, clean Redis keys |
| `event_hook.py` | TaskCompleted, TeammateIdle | Forward event notifications to external chat |
| `test_hook.py` | Any | Verify additionalContext injection works |

### Scripts

| Script | CLI Command | Purpose |
|--------|-------------|---------|
| `client_launcher.py` | `bridge-launcher` | Launch bridge WebSocket client as background process |
| `client_runner.py` | — | Long-running WS→Redis bridge (spawned by launcher) |
| `test_fire.py` | `bridge-test-fire` | Push test message into inbox + notify watcher |
| `watcher_daemon.py` | `bridge-watcher` | Auto-respond daemon (BLPOP + `claude -p`) |

## Usage

### Start the watcher daemon

```bash
# Auto-discover session ID
bridge-watcher

# Or specify explicitly
bridge-watcher --session-id SESSION_ID

# With debug logging
bridge-watcher --session-id SESSION_ID --log-level DEBUG
```

### Push a test message

```bash
bridge-test-fire "Hello from test"
```

### Launch the WebSocket bridge

```bash
bridge-launcher SESSION_ID --chat-id telegram:-456
```

## Dual-Response Prevention

| Redis Key | Set By | TTL | Purpose |
|-----------|--------|-----|---------|
| `bridge:interactive:{session_id}` | inbox hook | 30s | User active → daemon defers |
| `bridge:watcher:lock:{session_id}` | daemon | 120s | Daemon responding → hook defers |
| `bridge:watcher:notify:{session_id}` | bridge/queue | — | BLPOP doorbell for daemon |

## Configuration

Edit `bridge_client_sdk/config/watcher_config.json`:

```json
{
    "blpop_timeout": 30,
    "batch_delay": 2.0,
    "cooldown": 5.0,
    "lock_ttl": 120,
    "max_budget_usd": 0.50,
    "allowed_tools": "Read,Bash,Grep,Glob,WebFetch,WebSearch",
    "system_prompt": "..."
}
```

## Hook Integration

The original hook scripts at `.claude/scripts/bridge_*.py` are thin shims that import from this SDK. The `.claude/settings.local.json` hook paths remain unchanged — they call the shims which delegate to the SDK.
