Fix/headless bridges slash#114
Merged
Merged
Conversation
…resizable sidebar
ChatGPT-style session organization in the Chat UI, layered on top of the
slash-fix work in the previous commit. Five independent UX features behind
a single coordinated change so the schema migration only runs once.
Folders
- New `folders` table (per-user, name unique). chat_sessions gains a
nullable `folder_id` FK.
- In-place migration in init_db(): PRAGMA table_info probes for the
column on existing DBs and ALTER TABLE adds it. No Alembic, no manual
upgrade steps.
- Endpoints: GET/POST /api/folders, PATCH/DELETE /api/folders/{id},
PATCH /api/sessions/{id}/folder. Cross-user folders return 404 the
same way single-session ownership checks do.
- Deleting a folder reparents its sessions to Ungrouped (folder_id =
NULL) rather than deleting them. Repo layer NULLs explicitly because
SQLite PRAGMA foreign_keys is off in this engine.
Drag-drop + Move-to context menu
- Sessions are HTML5-draggable; folder rows + Ungrouped header are
drop targets with visual highlight.
- Right-click on a session: flat Move-to list with every folder, plus
(Ungrouped) when applicable, plus "+ New folder…" for create-and-move
in one click.
- Right-click on a folder: Rename / Delete, with a confirm() that says
"sessions become Ungrouped — they are NOT deleted".
Active-folder context (ChatGPT-style)
- Click a folder name (not the disclosure arrow) to enter that folder.
Row gets accent highlight; topbar grows a "Chat · in <Folder>"
breadcrumb.
- While a folder is active, + New and direct-typing auto-create both
drop the new session into that folder. Switching to any session
syncs the active context to that session's folder.
- State persists across reloads via localStorage (cc-active-folder).
Deleted folders auto-clear.
Batch operations
- "Select" button enters multi-select mode (checkboxes, Select all
respects the search filter). Footer action bar batch-deletes (single
confirm + total-message count) or batch-exports as one combined
Markdown (chats-N-sessions.md).
- Endpoints: POST /api/sessions/batch_delete and batch_export.
- Right-click is suppressed in select mode to avoid mode confusion.
Resizable sidebar
- 4-px drag handle between sidebar and main pane (mouse + touch).
Width clamped to 200–600 px and persisted to localStorage
(cc-sidebar-w). Double-click resets to default. Hidden under
@media (max-width: 768px) so the mobile drawer keeps its swipe
behavior.
Tests
- +10 in tests/test_web_api.py: folder CRUD, duplicate-409, move,
delete-preserves-as-ungrouped, cross-user isolation, list-includes-
folder_id, batch delete, batch delete cross-user, batch export,
batch export empty 400.
- File now at 31 tests, all passing. Zero regressions on the prior 21.
Docs
- README news entry (today, latest), Web UI feature table, API ASCII
diagram.
- docs/news.md — same two May 10 entries (feature + earlier bug-fix).
- docs/guides/web-ui.md — Layout, Persistence (5 tables), Session
management table, new Folders & active-folder context section, HTTP
API (Folders subsection, Sessions extras), Architecture notes
(migration + delete_folder PRAGMA detail + two-step session
placement), Tests 21 → 31.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
follow-up) In Docker / --web headless deploys, Telegram / Slack / WeChat bridges silently dropped /<cmd> messages — no reply, no log line. The bridges' poll loops gate on `session_ctx.handle_slash` and fall through to `continue` when it's None. The interactive `repl()` wired the callback at cheetahclaws.py:1142, but `_start_headless_bridges()` only set `run_query` and `agent_state`, never `handle_slash`. So in any deploy without a terminal REPL (Docker compose, --web), every Telegram /help, /monitor, /model, /status was a no-op. Fix: - Extract the slash handler (originally inlined inside repl()) into a module-level factory `_make_bridge_slash_handler(state, config, run_query)`. Same closure shape; takes the run_query callable so repl() and headless paths can each pass their own. - `_start_headless_bridges()` now sets `session_ctx.handle_slash = _make_bridge_slash_handler(...)` right after wiring `run_query`. - `repl()` switches to the same factory, deleting the duplicate inline definition. Single source of truth, no future drift between REPL and headless slash behavior. Tests: tests/test_bridge_slash_handler.py — 5 cases: - simple commands return "simple", run_query untouched - __brainstorm__ sentinel dispatches one run_query with the strict todo-write rules - __worker__ sentinel dispatches one run_query per task in order - unknown sentinel is a no-op, doesn't crash - end-to-end pin: after _start_headless_bridges runs with bridge config present, session_ctx.handle_slash is callable. This is the direct regression guard — pre-fix this attribute was None, which was the actual user-visible bug. Refs: #84 (file round-trip + clickable approve was fixed in a099a47; this addresses the slash-command silence reported as a follow-up). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Brings in two commits from fix/web-ui: - b74e14a fix(web): slash commands no longer reply twice; --web --model X persists - 28f1ffd feat(web): folders + drag-drop + active-folder context + batch ops + resizable sidebar Combined with the headless-bridges slash fix on this branch, fix/headless-bridges-slash now carries the full set of Chat UI + bridges work.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.