revert: remove user chat (direct + groups) from the pet window

Reverts 21a042d, 0d3e92c, 0016b6a, c797e98, 03ebea1. Keeps the pet's
own-sessions scope, status bar mine=1, scroll speed and the health hover card.
The chat_* tables and <data dir>/chat/ files are left in place (unused).
This commit is contained in:
2026-11-03 10:06:12 +07:00
parent db2e61a74b
commit a3d1dce2ca
24 changed files with 72 additions and 4339 deletions
-95
View File
@@ -547,44 +547,6 @@ function ccQuery(scope?: CcScope, cwd?: string): string {
/** Fired on `window` when a request answers 401 `EAUTH` (server mode). */
export const AUTH_REQUIRED_EVENT = "agenthub:auth-required";
/** Someone to chat with (`GET /api/chat/people`). */
export type ChatPerson = {
id: number;
username: string;
displayName: string | null;
avatarAt: string | null;
/** A disabled account: named in old chats, never offered for a new one. */
disabled?: boolean;
};
/** A file of a chat message (`GET /api/chat/rooms/:id/files/:fileId`). */
export type ChatFile = { id: string; name: string; type: string; size: number };
/** One chat message; `system` bodies: created, renamed, left, added:<ids>, removed:<ids>. */
export type ChatMessage = {
id: number;
roomId: number;
userId: number | null;
kind: "text" | "system";
body: string;
createdAt: string;
files: ChatFile[];
};
/** A direct chat or a group, as the caller sees it. */
export type ChatRoom = {
id: number;
kind: "dm" | "group";
name: string;
createdBy: number | null;
createdAt: string;
lastMessageAt: string | null;
members: number[];
lastMessage: ChatMessage | null;
lastReadId: number;
/** Messages up to this id were deleted by the viewer for themselves. */
clearedId?: number;
/** Every member's read mark by user id ("Seen"); absent from an older server. */
reads?: Record<string, number>;
unread: number;
};
/** One account in Settings → Users (`GET /api/users`). */
export type ServerUserUsage = AuthUser & {
disabled: boolean;
@@ -1605,63 +1567,6 @@ export const api = {
request<HostHistory>(`/host/history?range=${range}`),
},
// ───────────────────────── Server mode staff views (routes/users.js) ─────────────────────────
/** `/api/chat` — chat between users in server mode (the pet's window). */
chat: {
people: () => request<{ people: ChatPerson[] }>("/chat/people"),
rooms: () => request<{ rooms: ChatRoom[] }>("/chat/rooms"),
/** The one direct chat with `userId`, made on first use. */
openDm: (userId: number) =>
request<{ room: ChatRoom }>("/chat/rooms", {
method: "POST",
body: JSON.stringify({ kind: "dm", userId }),
}),
createGroup: (name: string, userIds: number[]) =>
request<{ room: ChatRoom }>("/chat/rooms", {
method: "POST",
body: JSON.stringify({ kind: "group", name, userIds }),
}),
/** The group's creator only. */
updateGroup: (id: number, patch: { name?: string; add?: number[]; remove?: number[] }) =>
request<{ room: ChatRoom }>(`/chat/rooms/${id}`, {
method: "PATCH",
body: JSON.stringify(patch),
}),
leave: (id: number) => request<{ ok: true }>(`/chat/rooms/${id}/leave`, { method: "POST" }),
messages: (id: number, before?: number) =>
request<{ messages: ChatMessage[]; hasMore: boolean }>(
`/chat/rooms/${id}/messages${before ? `?before=${before}` : ""}`
),
/** Text and files (multipart when there are files). */
post: (id: number, body: string, files: File[] = []) => {
if (!files.length)
return request<{ message: ChatMessage }>(`/chat/rooms/${id}/messages`, {
method: "POST",
body: JSON.stringify({ body }),
});
const form = new FormData();
form.append("body", body);
for (const f of files) form.append("files", f, f.name);
return request<{ message: ChatMessage }>(`/chat/rooms/${id}/messages`, {
method: "POST",
body: form,
});
},
read: (id: number, upTo: number) =>
request<{ lastReadId: number }>(`/chat/rooms/${id}/read`, {
method: "POST",
body: JSON.stringify({ upTo }),
}),
/** Delete the chat for yourself only (a direct chat leaves your list). */
clear: (id: number) =>
request<{ hidden: boolean }>(`/chat/rooms/${id}/clear`, { method: "POST" }),
/** The group's creator deletes it for everyone. */
disband: (id: number) => request<{ ok: true }>(`/chat/rooms/${id}`, { method: "DELETE" }),
/** Your own message only (403 otherwise). */
deleteMessage: (roomId: number, messageId: number) =>
request<{ ok: true }>(`/chat/rooms/${roomId}/messages/${messageId}`, { method: "DELETE" }),
fileUrl: (roomId: number, fileId: string) =>
`${BASE}/chat/rooms/${roomId}/files/${encodeURIComponent(fileId)}`,
},
users: {
/** URL of one account's avatar (any signed-in account), versioned by `avatarAt` (null = none). */
avatarUrl: (id: number, avatarAt?: string | null) =>
+2 -17
View File
@@ -1917,16 +1917,10 @@ export interface WSMessage {
* alert_triggered/alert_updated → AlertEvent; workflow_upserted → WorkflowRun;
* remote_source.status → RemoteSourceStatusPayload;
* remote_data.updated → RemoteDataUpdatedPayload;
* lane_update → { lane?: Lane; removed?: number };
* chat_message → { roomId, message: ChatMessage, to }; chat_room → { roomId, to };
* chat_deleted → { roomId, messageId, to }; chat_read → { roomId, userId, lastReadId, to }. */
* lane_update → { lane?: Lane; removed?: number }. */
type:
| "session_created"
| "session_updated"
| "chat_message"
| "chat_room"
| "chat_deleted"
| "chat_read"
| "agent_created"
| "agent_updated"
| "new_event"
@@ -1973,16 +1967,7 @@ export interface WSMessage {
| { lane?: Lane; removed?: number }
| LaneHookOutputPayload
| LaneRuntimePayload
| LaneHookResultPayload
/** chat_message / chat_room (lib/api.ts ChatMessage). */
| {
roomId: number;
message?: unknown;
messageId?: number;
userId?: number;
lastReadId?: number;
to?: number[];
};
| LaneHookResultPayload;
/** ISO timestamp the server broadcast this message (not necessarily the
* same instant the underlying event occurred). */
timestamp: string;