Matthias Nott
2026-03-07 af1543135d42adc2e97dc5243aeef7418cd3b00d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
export type MessageRole = "user" | "assistant" | "system";
export type MessageType = "text" | "voice" | "image";
export interface Message {
  id: string;
  role: MessageRole;
  type: MessageType;
  content: string;
  audioUri?: string;
  imageBase64?: string;
  timestamp: number;
  status?: "sending" | "sent" | "error";
  duration?: number;
}
export interface ServerConfig {
  host: string;
  port: number;
  localHost?: string;
  macAddress?: string;
}
export type ConnectionStatus = "disconnected" | "connecting" | "connected" | "compacting";
// --- WebSocket protocol ---
/** Outgoing from app to watcher */
export interface WsTextMessage {
  type: "text";
  content: string;
}
export interface WsVoiceMessage {
  type: "voice";
  audioBase64: string;
  content: string;
}
export interface WsImageMessage {
  type: "image";
  imageBase64: string;
  caption: string;
  mimeType: string;
}
export interface WsCommandMessage {
  type: "command";
  command: string;
  args?: Record<string, unknown>;
}
export type WsOutgoing = WsTextMessage | WsVoiceMessage | WsImageMessage | WsCommandMessage;
/** Incoming from watcher to app */
export interface WsIncomingText {
  type: "text";
  content: string;
}
export interface WsIncomingVoice {
  type: "voice";
  content: string;
  audioBase64?: string;
}
export interface WsIncomingImage {
  type: "image";
  imageBase64: string;
  caption?: string;
}
export interface WsSession {
  index: number;
  name: string;
  type: "claude" | "terminal";
  kind?: "api" | "visual";
  isActive: boolean;
  id: string;
}
export interface WsIncomingSessions {
  type: "sessions";
  sessions: WsSession[];
}
export interface WsIncomingSessionSwitched {
  type: "session_switched";
  name: string;
  sessionId: string;
}
export interface WsIncomingSessionRenamed {
  type: "session_renamed";
  sessionId: string;
  name: string;
}
export interface WsIncomingError {
  type: "error";
  message: string;
}
export interface WsIncomingStatus {
  type: "status";
  status: string;
}
export type WsIncoming =
  | WsIncomingText
  | WsIncomingVoice
  | WsIncomingImage
  | WsIncomingSessions
  | WsIncomingSessionSwitched
  | WsIncomingSessionRenamed
  | WsIncomingError
  | WsIncomingStatus;