feat: unify main session and icon cues
This commit is contained in:
21
docs/mac/icon.md
Normal file
21
docs/mac/icon.md
Normal file
@@ -0,0 +1,21 @@
|
||||
# Menu Bar Icon States
|
||||
|
||||
Author: steipete · Updated: 2025-12-06 · Scope: macOS app (`apps/macos`)
|
||||
|
||||
- **Idle:** Normal icon animation (blink, occasional wiggle).
|
||||
- **Paused:** Status item uses `appearsDisabled`; no motion.
|
||||
- **Voice trigger (big ears):** Voice wake detector calls `AppState.triggerVoiceEars()` → `earBoostActive=true` for ~5s. Ears scale up (1.9x) then auto-reset. Only fired from the in-app voice pipeline.
|
||||
- **Working (agent running):** `AppState.isWorking=true` drives a “tail/leg scurry” micro-motion: faster leg wiggle and slight offset while work is in-flight. Currently toggled around WebChat agent runs; add the same toggle around other long tasks when you wire them.
|
||||
|
||||
Wiring points
|
||||
- Voice wake: see `VoiceWakeTester.handleResult` in `AppMain.swift`—on detection it calls `triggerVoiceEars()`.
|
||||
- Agent activity: set `AppStateStore.shared.setWorking(true/false)` around work spans (already done in WebChat agent call). Keep spans short and reset in `defer` blocks to avoid stuck animations.
|
||||
|
||||
Shapes & sizes
|
||||
- Base icon drawn in `CritterIconRenderer.makeIcon(blink:legWiggle:earWiggle:earScale:)`.
|
||||
- Ear scale defaults to `1.0`; voice boost sets `earScale=1.9` without changing overall frame (18×16pt template image).
|
||||
- Scurry uses leg wiggle up to ~1.0 with a small horizontal jiggle; it’s additive to any existing idle wiggle.
|
||||
|
||||
Behavioral notes
|
||||
- No external CLI/XPC toggle for ears/working; keep it internal to the app’s own signals to avoid accidental flapping.
|
||||
- Keep TTLs short (<10s) so the icon returns to baseline quickly if a job hangs.
|
||||
@@ -10,11 +10,13 @@ CLAWDIS keeps lightweight session state so your agent can remember context betwe
|
||||
|
||||
## How session keys are chosen
|
||||
|
||||
- Direct chats: normalized E.164 sender number (e.g., `+15551234567`).
|
||||
- Direct chats: by default collapse to the canonical key `main` so all 1:1 channels (WhatsApp, WebChat, Telegram) share a single session.
|
||||
- Group chats: `group:<whatsapp-jid>` so group history stays isolated from DMs.
|
||||
- Global mode: set `inbound.reply.session.scope = "global"` to force a single shared session for all chats.
|
||||
- Unknown senders fall back to `unknown`.
|
||||
|
||||
To change the canonical key (or disable collapsing), set `inbound.reply.session.mainKey` to another string or leave it empty.
|
||||
|
||||
## When sessions reset
|
||||
|
||||
- Idle timeout: `inbound.reply.session.idleMinutes` (default 60). If no messages arrive within this window, a new `sessionId` is created on the next message.
|
||||
@@ -32,11 +34,20 @@ CLAWDIS keeps lightweight session state so your agent can remember context betwe
|
||||
scope: "per-sender", // or "global"
|
||||
resetTriggers: ["/new"], // additional triggers allowed
|
||||
idleMinutes: 120, // extend or shrink timeout (min 1)
|
||||
store: "~/state/clawdis-sessions.json" // optional custom path
|
||||
store: "~/state/clawdis-sessions.json", // optional custom path
|
||||
mainKey: "main" // canonical direct-chat bucket
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
## Surfaces (channel labels)
|
||||
|
||||
Each inbound message can carry a `Surface` hint in the templating context (e.g., `whatsapp`, `webchat`, `telegram`, `voice`). Routing stays deterministic: replies are sent back to the origin surface, but the shared `main` session keeps context unified across direct channels. Groups retain their `group:<jid>` buckets.
|
||||
|
||||
## WebChat history
|
||||
|
||||
WebChat always attaches to the `main` session and hydrates the full Tau JSONL transcript from `~/.clawdis/sessions/<SessionId>.jsonl`, so desktop view reflects all turns, even those that arrived via WhatsApp/Telegram.
|
||||
```
|
||||
|
||||
Other session-related behaviors:
|
||||
|
||||
14
docs/surface.md
Normal file
14
docs/surface.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# Surfaces & Routing
|
||||
|
||||
Updated: 2025-12-06
|
||||
|
||||
Goal: make replies deterministic per channel while keeping one shared context for direct chats.
|
||||
|
||||
- **Surfaces** (channel labels): `whatsapp`, `webchat`, `telegram`, `voice`, etc. Add `Surface` to inbound `MsgContext` so templates/agents can log which channel a turn came from. Routing is fixed: replies go back to the origin surface; the model doesn’t choose.
|
||||
- **Canonical direct session:** Direct chats collapse into `main` by default via `inbound.reply.session.mainKey` (configurable). Groups stay `group:<jid>`. This keeps context unified across WhatsApp/WebChat/Telegram while preserving group isolation.
|
||||
- **Session store:** Keys are resolved via `resolveSessionKey(scope, ctx, mainKey)`; the Tau JSONL path still lives under `~/.clawdis/sessions/<SessionId>.jsonl`.
|
||||
- **WebChat:** Always attaches to `main`, loads the full Tau transcript so desktop reflects cross-surface history, and writes new turns back to the same session.
|
||||
- **Implementation hints:**
|
||||
- Set `Surface` in each ingress (WhatsApp relay, WebChat bridge, future Telegram).
|
||||
- Keep routing deterministic: originate → same surface. Use IPC/web senders accordingly.
|
||||
- Do not let the agent emit “send to X” decisions; keep that policy in the host code.
|
||||
@@ -6,7 +6,7 @@ The macOS Clawdis app ships a built-in web chat window that reuses your primary
|
||||
|
||||
- UI: `pi-mono/packages/web-ui` bundle loaded in a `WKWebView`.
|
||||
- Bridge: `WKScriptMessageHandler` named `clawdis` (see `apps/macos/Sources/Clawdis/WebChatWindow.swift`). The page posts `sessionKey` + message; Swift shells `pnpm clawdis agent --to <sessionKey> --message <text> --json` and returns the first payload text to the page. No sockets are opened.
|
||||
- Session selection: picks the most recently updated entry in `~/.clawdis/sessions/sessions.json`; falls back to `+1003` if none exist. This keeps the web chat on the same primary conversation as the relay/CLI.
|
||||
- Session selection: always uses the canonical `main` session key (or `inbound.reply.session.mainKey`), hydrating from the Tau JSONL session file so you see the full history even when messages arrived via WhatsApp/Telegram.
|
||||
- Assets: the entire `pi-web-ui` dist plus dependencies (pi-ai, mini-lit, lit, lucide, pdfjs-dist, docx-preview, jszip) is bundled into `apps/macos/Sources/Clawdis/Resources/WebChat/` and shipped with the app. No external checkout is required at runtime.
|
||||
|
||||
## Requirements
|
||||
|
||||
Reference in New Issue
Block a user