From a3d1dce2cac7b6b1a8def4b44e7c1dcb5d3c4402 Mon Sep 17 00:00:00 2001 From: nntrivi2001 Date: Tue, 3 Nov 2026 10:06:12 +0700 Subject: [PATCH] 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 /chat/ files are left in place (unused). --- CLAUDE.md | 3 +- client/src/components/Sagi/ChatDock.tsx | 108 -- client/src/components/Sagi/ChatHub.tsx | 1307 ----------------- client/src/components/Sagi/Sagi.tsx | 150 +- client/src/components/Sagi/SagiMount.tsx | 16 +- .../Sagi/__tests__/ChatDock.test.tsx | 69 - .../Sagi/__tests__/ChatHub.test.tsx | 389 ----- .../components/Sagi/__tests__/Pets.test.tsx | 8 +- .../Sagi/__tests__/useChat.test.tsx | 137 -- client/src/components/Sagi/sagi.css | 22 +- client/src/components/Sagi/useChat.ts | 305 ---- client/src/i18n/locales/en/settings.json | 121 +- client/src/i18n/locales/vi/settings.json | 139 +- client/src/lib/api.ts | 95 -- client/src/lib/types.ts | 19 +- docs/API.md | 21 - server/__tests__/chat.test.js | 306 ---- server/db.js | 50 - server/index.js | 1 - server/lib/chat.js | 567 ------- server/lib/scope.js | 8 +- server/openapi-extra.js | 3 +- server/openapi-extra/chat.js | 352 ----- server/routes/chat.js | 215 --- 24 files changed, 72 insertions(+), 4339 deletions(-) delete mode 100644 client/src/components/Sagi/ChatDock.tsx delete mode 100644 client/src/components/Sagi/ChatHub.tsx delete mode 100644 client/src/components/Sagi/__tests__/ChatDock.test.tsx delete mode 100644 client/src/components/Sagi/__tests__/ChatHub.test.tsx delete mode 100644 client/src/components/Sagi/__tests__/useChat.test.tsx delete mode 100644 client/src/components/Sagi/useChat.ts delete mode 100644 server/__tests__/chat.test.js delete mode 100644 server/lib/chat.js delete mode 100644 server/openapi-extra/chat.js delete mode 100644 server/routes/chat.js diff --git a/CLAUDE.md b/CLAUDE.md index ccb3d8fd..1700282b 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ # Claude Code Working Guide -_Last synced: v2.8.66 (2026-11-03) — chat: delete for yourself, purge what everyone deleted, Seen, chat button without the pet._ A change that makes any statement in this file, `AGENTS.md`, or a README wrong — a moved path, a new or changed extension point, a retired rule — updates that file in the same change-set and bumps this marker. **Bump = replace the version/date and a ≤ 1-line summary; never append a changelog here** — details belong in the commit message and `docs/`, because this whole file is loaded into every session. +_Last synced: v2.8.67 (2026-11-03) — user chat removed (reverted)._ A change that makes any statement in this file, `AGENTS.md`, or a README wrong — a moved path, a new or changed extension point, a retired rule — updates that file in the same change-set and bumps this marker. **Bump = replace the version/date and a ≤ 1-line summary; never append a changelog here** — details belong in the commit message and `docs/`, because this whole file is loaded into every session. ## Project mission - Maintain a reliable local-first dashboard for Claude Code session monitoring. @@ -65,7 +65,6 @@ A **workspace** — called a **lane** in the API, CLI, database and code, which - **A workspace's sessions are the ones it OWNS, never the ones that ran in its folder.** `sessions.lane_id` is stamped by `bindRunSession` (`server/routes/hooks.js`) for the session a dashboard pane holds — first writer wins, a nested `claude -p` excluded — and no route sets it. A Codex/Antigravity session (their hooks are opt-in, so a pane may never learn its session) is also stamped by `claimToolSessions` (`server/lib/dashboard-runs.js`, called by both pollers and once at start): the lane of the newest same-tool dashboard run in the session's folder that was live when the session started, never a Claude session. A new Claude pane is started with `--session-id ` (`spawnRun`), so its `dashboard_runs.session_id` is known before any hook and a hook that carries no `run_id` (a hook handler older than `AGENTHUB_RUN_ID` forwarding) is still stamped from that run (`laneForSession`). Every workspace session list reads `GET /api/sessions?lane=` — which also counts a still-unstamped session one of the lane's `dashboard_runs` holds, because hooks reach only the lowest-port dashboard on a shared DB and that one may be an older build that never stamps — and shows nothing else (no "other sessions in this folder"). Do not go back to listing a workspace by `cwd`, and do not guess ownership for old history. Billing has one more owner: a session NO workspace owns belongs to the user of the Linux account it ran as (`sessions.account` — the hook's peer, else its folder; `server/lib/session-account.js`, the host's account → the admin marked `users.host_account`, else the only admin), so a script's `claude -p` counts in Today, the Users page and spend quotas — a workspace's ownership always wins over it. - **A session's worktree is `claude --worktree`'s, resolved from the session row — and removing it never forces.** A Worktree start passes `--worktree=` (the `=` form: `-w [name]` eats the prompt otherwise) and Claude Code makes, populates and cleans up `/.claude/worktrees/`; AgentHub only excludes `/.claude/worktrees/` at the repo root. A git route, a resume or a removal may work in a session's worktree only through `sessionWorktree` (`server/lib/session-worktree.js`: the session owned by the lane, its cwd not the lane's folder, registered by `git worktree list`) — `?session=` on the git routes answers `ENOWORKTREE` rather than falling back to the main folder. `POST /api/lanes/:id/session-worktree/remove` (same-origin, `confirm: true`, refused while a live pane holds the session) is the ONE dashboard path that deletes a worktree: `git worktree remove` with no `--force`, `git branch -d` never `-D`, a live-pid lock refused. Do not add a force, and do not let it touch a lane's own folder. - **Opening a session never resumes it — only SENDING a message to it does.** The sidebar and a workspace home ATTACH pane 0 to a session's live tmux pane (`/workspace?lane=&run=`, `attachRequest` on `LaneConsolePane`) or, for an ended one, open it in its workspace like Claude Desktop (`/workspace?lane=&session=`, `client/src/components/lanes/SessionReplay.tsx`: its conversation read-only plus a prompt box; the console is only hidden, CSS). A resume re-reads the whole transcript into context, so it happens only on an explicit action: a message SENT from that replay (`resumeSessionId` + `prompt`, first free slot), the transcript page's **Resume**/**Fork** (`SessionResumeButton.tsx`, behind a warning), or the ticked sessions of the **Resume interrupted sessions?** dialog (`InterruptedSessionsPrompt.tsx`, `GET /api/run/interrupted` — runs whose pane died under them; opening it resumes nothing). The analysis page `/sessions/` is reached from the session view's **Analyst** button (beside Files/Changes in the right panel). Do not add a path that resumes on a click. A resume is refused while a live pane holds the session (`409 ESESSIONLIVE` with that pane's `run_id`) — open that pane instead; a fork makes a new session and is allowed. -- **A chat between users is its members' alone.** `server/lib/chat.js` (`/api/chat`, server mode only): every read and write resolves the room through `roomFor(caller, id)` — not a member is `404`, an admin included, and there is no route listing another user's rooms; `chat_message`/`chat_room`/`chat_deleted` frames go only to the ids in `to` (`exactAudience`); a message is deleted only by its author; "delete chat" is the caller's alone (`cleared_id`/`hidden`), and only what EVERY member deleted is purged for real (`purge` — messages, files, a direct chat both deleted). A read mark never passes the room's newest message (it is what others see as Seen). Files are stored under a server-made name in `/chat//` and served only to members under a `sandbox` CSP + `nosniff` (raster images inline, anything else an attachment). Do not add an admin view of chats. - **A web page is previewed by URL in the session panel's Preview tab, never on the dashboard's origin, and every link follows ONE rule.** `client/src/components/lanes/UrlPreview.tsx` shows an `