Skip to content

Add auto-scroll fix, persistent memory, mobile UX, and dotfile support#530

Closed
ki-cooley wants to merge 45 commits intoglowingjade:mainfrom
ki-cooley:feature/mobile-ux-and-memory
Closed

Add auto-scroll fix, persistent memory, mobile UX, and dotfile support#530
ki-cooley wants to merge 45 commits intoglowingjade:mainfrom
ki-cooley:feature/mobile-ux-and-memory

Conversation

@ki-cooley
Copy link

@ki-cooley ki-cooley commented Feb 17, 2026

Summary

  • Auto-scroll fix: Rewrote useAutoScroll to detect user scrolling via wheel/touchmove events instead of generic scroll events. Content growth during streaming no longer falsely disables auto-scroll.
  • Persistent memory: Agent can read/write .claude/memory.md for cross-conversation context. File auto-created on plugin load, loaded into both backend and plugin-side prompts.
  • Dotfile support: VaultRpcHandler now uses Obsidian's adapter API for dotfile paths (.claude/), since the vault API doesn't index them.
  • Mobile UX: Added overscroll-behavior: contain and -webkit-overflow-scrolling: touch CSS, wrapped autoScrollToBottom in requestAnimationFrame.

Test plan

  • Auto-scroll stays at bottom throughout full streaming response (tool calls + text summary)
  • User can still scroll up during streaming to pause auto-scroll
  • .claude/memory.md created on plugin load
  • Agent writes preferences to memory, recalled in new conversations
  • VaultRpcHandler reads/writes dotfile paths correctly
  • Type check and build pass

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Rebranded to Claudsidian with updated branding throughout
    • Added backend server deployment option with WebSocket communication
    • Introduced activity tracking UI showing agent's thinking, tool calls, and file operations
    • Added skills and slash commands support from .claude/ directory
    • Implemented edit history with revert capability
    • Added external resource directory configuration
    • Auto-creates persistent memory file for context
  • UI/UX Improvements

    • Redesigned chat content with chronological interspersed layout
    • Enhanced code block display with expand/collapse functionality
    • Improved mobile keyboard handling
  • Chores

    • Added project documentation and configuration files

claude and others added 30 commits January 7, 2026 05:45
Implements the backend WebSocket server that:
- Connects to Claude API with streaming support
- Exposes vault operation tools (read, write, search, list, delete)
- Uses bidirectional RPC protocol for vault operations
- Supports token-based authentication
- Includes Dockerfile for Railway deployment

The backend acts as a bridge between the Obsidian plugin and Claude,
handling the agent loop and tool execution.
- Add MOCK_MODE environment variable for testing without API key
- Add mock agent that simulates Claude responses with tool usage
- Add automated test suite with 6 tests covering:
  - Simple prompt/response streaming
  - vault_list, vault_search, vault_read, vault_write tools
  - Ping/pong keepalive
- Add interactive test client for manual testing
- Update package.json with dev:mock and test scripts

All tests pass: 6/6
- Add railway.toml at repo root to point to backend/Dockerfile
- Update Dockerfile to build from repo root context
- Build TypeScript inside container instead of expecting pre-built dist/
- Add /health and / endpoints that return JSON status
- Attach WebSocket server to HTTP server
- Update Dockerfile health check to use /health endpoint
- Set buildContext = 'backend' in railway.toml
- Fix Dockerfile COPY paths to be relative to backend dir
- Update healthcheckPath to /health
Implements additional Claude Agent SDK-like tools for more powerful
vault operations:
- vault_edit: Precise string replacement in files
- vault_grep: Regex search across file contents with line numbers
- vault_glob: File pattern matching with glob syntax
- vault_rename: Move/rename files with link updates

Also adds UI formatting for new tool results with clickable wikilinks.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Loads CLAUDE.md from vault root for project-specific instructions
- Loads .claude/instructions.md as alternative location
- Loads custom skills from .claude/skills/*.md
- Skills can be invoked by name (e.g., "/weekly-review")
- Updates system prompt with new tool capabilities

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add model field to PromptMessage protocol
- Pass selected model from BackendProvider to WebSocket
- Backend agent now uses model from request instead of hardcoded default
- Default still falls back to claude-opus-4-5-20250514 if not specified

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- claude-opus-4-5-20251101 (was 20250514)
- claude-sonnet-4-5-20250929
- claude-haiku-4-5-20251001
- claude-opus-4-1-20250805

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Collapsed file lists: show first 3 files with "+N more" instead of full lists
- Edit batching: suppress duplicate edit messages within 5 second window
- Clean up temp test scripts and debug files
- Add ConflictManager and instance singleton for backend
- Update various UI components for better integration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Backend:
- Enable built-in Anthropic web_search tool for real-time web access
- Update system prompt to mention web search capability

Frontend:
- Add enterKeyHint="send" for mobile keyboard submit button
- Blur input after submit to hide mobile keyboard
- Add code block truncation (15 lines) with expand/collapse

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Enables the backend to connect to external MCP servers via SSE transport,
discover their tools, and forward tool calls from Claude. This allows
cookbook search tools (and any future MCP servers) to work through the
backend provider, which is required for mobile support.

- New src/mcp-client.ts: MCP client manager using @modelcontextprotocol/sdk
- Modified agent.ts: merges MCP tools with vault tools, routes tool calls
- Modified index.ts: initializes MCP client after server starts (non-blocking)
- Added @modelcontextprotocol/sdk dependency

Configured via MCP_SERVERS env var (JSON):
  {"server-name":{"type":"sse","url":"https://example.com/mcp/sse"}}

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace @anthropic-ai/sdk + manual agent loop with @anthropic-ai/claude-agent-sdk.
SDK's query() handles tool execution, message history, and MCP connections
automatically. Auth now supports CLAUDE_CODE_OAUTH_TOKEN (subscription) or
ANTHROPIC_API_KEY. Default model updated to claude-opus-4-6.

- Rewrite agent.ts: replace manual streaming loop with SDK query()
- New vault-tools.ts: Zod v4 schemas + tool() + createSdkMcpServer()
- Delete mcp-client.ts (SDK handles MCP connections internally)
- Delete mcp-tools.ts (replaced by vault-tools.ts)
- Update index.ts: remove MCP client init, dual auth check
- Upgrade zod ^3.23 → ^4.0 (Agent SDK peer dependency)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Agent SDK CLI requires git at runtime. Also set HOME=/tmp/claude-home
for writable config directory in Docker, and log full error stacks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…p diag

- Add stderr callback to query() to capture CLI subprocess errors
- Create /tmp/claude-home/.claude/ in Dockerfile so CLI has writable HOME
- Remove slow startup diagnostic that blocked module load

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The Agent SDK CLI refuses --dangerously-skip-permissions when running
as root. Create a 'claude' user and switch to it before running.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tool names like "mcp__vault-tools__vault_read" are now cleaned to
just "vault_read" before sending to the plugin. This makes the
activity accordion show meaningful tool names instead of MCP internals.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The SDK handles external MCP tool execution internally, so we never
got tool_end events for tools like search_cookbooks. Now we track
pending tool starts and emit synthetic tool_end events when the SDK
moves to the next turn (text streaming or new assistant message).

This ensures the plugin's activity accordion correctly shows all
tool executions with proper start/end lifecycle.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaces the old tool message display with a modern activity tracking system:
- ActivityAccordion: collapsible exploration summary (auto-expand during streaming)
- ActivityItem: individual activities with live timers, clickable file links
- EditDiffBlock: green/red diff display with Undo button for file changes
- EditHistory: singleton snapshot manager for revert functionality
- Full support for cookbook search tools (search_cookbooks, list_cookbook_sources)
- ActivityEvent type system with 13 activity types + generic fallback
- BackendProvider emits structured ActivityEvent objects during streaming
- tool-result-formatter parses raw results into structured diff/count/path data
- 320 lines of Obsidian-native CSS with theme variable integration
- Cleaned up debug logging artifacts from main.ts and settings.ts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…tocol-level

Railway's proxy doesn't forward WebSocket ping/pong frames, causing the
server's protocol-level heartbeat to terminate connections after ~45 seconds.
Now tracks last message activity time and allows 90s of inactivity. The
plugin already sends application-level ping messages every 25s which keep
the connection alive through the proxy.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tell the agent to always include exact page numbers and source names
when citing cookbook search results, preventing vague references.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix activity ID mismatch between BackendProvider and VaultRpcHandler
  that prevented undo from finding the correct snapshot. Track activity
  IDs from tool_start events and consume them in the RPC handler.
- Fix revert for new files: delete file instead of writing empty content.
- Add clickable file links in EditDiffBlock that open files in editor.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…MCP restriction

- Add externalResourceDir plugin setting for vault-relative PDF path
- Fix duplicate activity items by deduplicating editActivities by filePath+type
- Map search_cookbooks/list_cookbook_sources/web_search to proper activity types
- Remove blanket mobile MCP disable; let transports fail gracefully
- Update backend system prompt with source filter and citation format guidance
- Settings migration 12→13

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ki-cooley and others added 15 commits February 12, 2026 01:21
LLM was stripping [[cookbooks/file.pdf#page=N]] wikilinks and reformatting
as plain text. Updated Cookbook Research Tools section to mark wikilink
preservation as CRITICAL with explicit examples and instructions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
BackendProvider: Race message promise against abort signal so clicking
Stop immediately wakes the generator and sends cancel to backend.

WebSocketClient: Notify active stream handlers on disconnect so
generators don't hang forever when the connection drops.

server.ts: Send safety-net complete message in finally block so the
client never gets stuck waiting for a terminal event.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When an external MCP server dies (e.g. cookbook-rag OOM), the SDK's
query() hangs forever waiting for a tool response. This wraps the
iterator with a 2-minute timeout that aborts the agent and yields
an error if no message arrives.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…, stream thinking tokens

- Replace 2-min withMessageTimeout (killed legitimate multi-tool turns) with
  activity-based approach: heartbeat updated by SDK messages, vault tool
  handlers, and stderr; 15s interval check; 5-min inactivity threshold
- Stream thinking_delta tokens in real time (Cursor-like UX)
- Emit tool_start from content_block_start stream events (earlier than
  waiting for full assistant message), with dedup against assistant fallback
- Add heartbeat callback to createVaultMcpServer, called by all 9 vault
  tool handlers on execution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Revert early tool_start from content_block_start (sent empty input {},
  caused "Cookbook search: ''" in activity UI). Tool_start now emits from
  the assistant message which has the complete input parameters.
- Keep thinking_delta streaming from stream events (real-time thinking)
- Add pending tool cleanup in catch block so cancelled requests don't
  leave stuck "running" activities in the UI
- Remove unused streamStartedToolIds tracking

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix 2: Track completeSent flag in server.ts to prevent safety-net
  complete from racing with tool_end events. Delay handler deletion
  in WebSocketClient by 1s after complete.
- Fix 3: Enable extended thinking (budgetTokens: 10000) in SDK query.
  Add diagnostic logging for thinking block start and deltas.
- Fix 4: Increase maxTurns 10→25, inactivity timeout 5→10min,
  RPC timeout 30→60s. Add result logging for timeout diagnosis.
- Add interspersed layout spec doc for future implementation.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…on error

- Remove `thinking: { type: 'enabled', budgetTokens: 10000 }` option that
  was causing the Agent SDK CLI to fail silently (2s empty response + exit 1)
- Track `completedSuccessfully` flag to suppress the spurious "process exited
  with code 1" error the SDK throws after normal completion

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Root cause of empty responses was ANTHROPIC_API_KEY env var on Railway
overriding the working CLAUDE_CODE_OAUTH_TOKEN. The thinking option
itself is fine.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- maxTurns 25→50 to support complex multi-source research queries
- Detect error_max_turns and append truncation notice to response
- Add system prompt guidance: batch tool calls 5-8 at a time, present
  final synthesis instead of repeating findings in multiple formats

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace grouped activity layout (all activities at top, text at bottom)
with chronologically interspersed layout — text and activities appear
in the order they happen during agent execution, like Cursor.

Also restore rendered markdown preview in edit diff blocks with a
Raw/Rendered toggle button, defaulting to rendered view.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip [[]] from file names in edit diff headers, activity item links,
and activity accordion labels. The link styling already distinguishes
clickable filenames without needing bracket decoration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add images field to PromptMessage protocol (both frontend and backend)
- Skip file reading/RAG in PromptGenerator for backend provider — pass
  file paths instead so the agent reads via vault_read
- Extract images from request in BackendProvider, send separately from
  prompt text via WebSocket
- Forward images through server.ts to agent.ts, construct multimodal
  Anthropic content blocks when images are present
- Add console.log tracing for image flow debugging

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix streaming auto-scroll: use wheel/touchmove events to detect user
  scrolling instead of scroll events (which also fire on content growth),
  preventing false auto-scroll disable during streaming
- Add persistent memory via .claude/memory.md: auto-create on plugin
  load, load into prompt generator, agent can read/write via vault tools
- Fix dotfile support in VaultRpcHandler: use adapter API for paths
  containing dotfiles (.claude/) since Obsidian vault API doesn't index them
- Add mobile scroll CSS (overscroll-behavior, webkit-overflow-scrolling)
- Wrap autoScrollToBottom in requestAnimationFrame for DOM sync

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Feb 17, 2026

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This PR introduces a major rebranding from "Smart Composer" to "Claudsidian" and implements a complete backend agent system with WebSocket communication, vault RPC operations, activity tracking, and interspersed content rendering. It adds backend infrastructure (Node.js server with Docker support), protocol definitions, frontend-to-backend integration, and new UI components for visualizing agent activities and edits.

Changes

Cohort / File(s) Summary
Backend Infrastructure
backend/.env.example, backend/.gitignore, backend/Dockerfile, backend/railway.json, backend/tsconfig.json, railway.toml, backend/README.md, backend/package.json
Configuration files, environment setup, Docker containerization, TypeScript build config, and Railway deployment manifests for backend service.
Backend Core Server & Protocol
backend/src/index.ts, backend/src/server.ts, backend/src/protocol.ts
Main entry point with environment validation, WebSocket server implementation with connection handling, RPC routing, and bidirectional message protocol definitions.
Backend Agent & Tools
backend/src/agent.ts, backend/src/mock-agent.ts, backend/src/vault-tools.ts, backend/src/utils.ts
Claude agent integration with streaming support, mock agent for testing, vault tool definitions with MCP server creation, and utility functions (logging, retry, JSON parsing).
Backend Testing
backend/test/automated-test.ts, backend/test/test-client.ts
End-to-end test suite connecting via WebSocket and simulating Obsidian environment with RPC vault operations.
Frontend Backend Integration
src/core/backend/WebSocketClient.ts, src/core/backend/BackendProvider.ts, src/core/backend/instance.ts, src/core/backend/protocol.ts
WebSocket client for browser communication, backend LLM provider implementation, singleton instance, and frontend-side protocol definitions.
Frontend Vault & History Management
src/core/backend/VaultRpcHandler.ts, src/core/backend/ConflictManager.ts, src/core/backend/EditHistory.ts, src/core/backend/tool-result-formatter.ts
RPC dispatcher for vault operations, conflict detection for external modifications, edit snapshots for revert functionality, and tool result parsing/formatting.
Activity & Content UI Components
src/components/chat-view/ActivityAccordion.tsx, src/components/chat-view/ActivityItem.tsx, src/components/chat-view/EditDiffBlock.tsx, src/components/chat-view/InterspersedContent.tsx
Collapsible activity display, activity event rendering with timers and details, live streaming edit diffs with revert capability, and interspersed text/activity block rendering.
Chat View Updates
src/components/chat-view/Chat.tsx, src/components/chat-view/AssistantToolMessageGroupItem.tsx, src/components/chat-view/ToolMessage.tsx, src/components/chat-view/MarkdownCodeComponent.tsx
Auto-scroll fixes for mobile keyboard, activity extraction and interspersed content support, backend tool filtering, and code block line truncation.
Chat Input & Template Enhancements
src/components/chat-view/chat-input/ChatUserInput.tsx, src/components/chat-view/chat-input/LexicalContentEditable.tsx, src/components/chat-view/chat-input/plugins/template/TemplatePlugin.tsx
Mobile keyboard dismiss, send button hint, slash-command option consolidation with skill/command support.
Auto-Scroll & Stream Management
src/components/chat-view/useAutoScroll.ts, src/components/chat-view/useChatStreamManager.ts
User-scroll detection for explicit scrolling threshold, requestAnimationFrame scheduling for scroll operations.
Settings & Configuration
src/settings/schema/setting.types.ts, src/settings/schema/migrations/12_to_13.ts, src/settings/schema/migrations/index.ts, src/settings/schema/settings.ts
New externalResourceDir field, version 12→13 migration, and settings parsing updates.
Provider & Model Types
src/types/provider.types.ts, src/types/chat-model.types.ts, src/types/chat.ts, src/types/llm/response.ts
New backend provider configuration, activity types, content blocks, and streaming delta extensions.
Utilities & Helpers
src/utils/chat/promptGenerator.ts, src/utils/chat/responseGenerator.ts, src/hooks/useSkills.ts
Backend-aware prompt generation skipping RAG, memory integration, activity/content-block merging, and skill/command loading from dot-folders.
Settings UI
src/components/settings/sections/ChatSection.tsx, src/components/settings/sections/ProvidersSection.tsx, src/components/settings/modals/AddChatModelModal.tsx, src/components/settings/modals/AddEmbeddingModelModal.tsx, src/components/settings/modals/ProviderFormModal.tsx
External resource directory input, backend provider credential masking, provider type filtering, and backend-specific URL/token fields.
Error Handling & Navigation
src/components/modals/ErrorModal.tsx, src/components/modals/InstallerUpdateRequiredModal.tsx
GitHub issues link update and Claudsidian branding in error modals.
Plugin Core & Main
src/main.ts, src/ChatView.tsx
Backend initialization with RPC listener, edit history, memory file, conflict manager, and VaultRpcHandler integration; display text branding.
Constants & Branding
src/constants.ts, manifest.json, src/components/settings/SettingsTabRoot.tsx, package.json, styles.css, .claude/settings.json, CLAUDE.md
Default model switched to backend-agent, manifest id/name updated to Claudsidian, support link redirected to GitHub, comprehensive UI styles for activities/diffs/interspersed content, Claude AI configuration, and architecture documentation.

Sequence Diagram(s)

sequenceDiagram
    actor User
    participant FrontendPlugin as Frontend Plugin<br/>(Obsidian)
    participant WSClient as WebSocket<br/>Client
    participant BackendServer as Backend Server<br/>(Node.js)
    participant Agent as Claude Agent<br/>(with MCP)
    participant VaultRPC as Vault RPC<br/>Handler

    User->>FrontendPlugin: Submit prompt with context
    FrontendPlugin->>WSClient: Send PromptMessage
    WSClient->>BackendServer: Connect & authenticate
    BackendServer->>Agent: Initialize agent with system prompt
    Agent->>Agent: Load skills, memory, instructions
    Agent->>Agent: Build MCP server config
    BackendServer->>Agent: Stream prompt to Claude
    Agent->>Agent: Process streaming response
    
    alt Agent uses tool (e.g., vault_read)
        Agent->>BackendServer: Emit tool_start
        BackendServer->>WSClient: Send ToolStartMessage
        WSClient->>FrontendPlugin: Display tool activity
        Agent->>VaultRPC: Request vault operation
        VaultRPC->>FrontendPlugin: Send RpcRequestMessage
        FrontendPlugin->>VaultRPC: RpcResponseMessage with result
        VaultRPC->>Agent: Return tool result
        Agent->>BackendServer: Emit tool_end
        BackendServer->>WSClient: Send ToolEndMessage
        WSClient->>FrontendPlugin: Update activity, record edit history
    end
    
    Agent->>BackendServer: Emit text_delta, thinking, complete
    BackendServer->>WSClient: Stream TextDeltaMessage, ThinkingMessage
    WSClient->>FrontendPlugin: Update assistant message, activities
    FrontendPlugin->>FrontendPlugin: Render interspersed content blocks
    
    Agent->>BackendServer: Streaming complete
    BackendServer->>WSClient: Send CompleteMessage
    WSClient->>FrontendPlugin: Finalize response
    FrontendPlugin->>User: Display chat with activities & edits
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • style: Update css styles #344: Modifies MarkdownCodeComponent.tsx and styles.css for code-block rendering and styling, overlapping with this PR's code-block truncation and style updates.
  • Improve Diff View #325: Introduces diff UI/logic with new diff-block components and rendering, directly related to the new EditDiffBlock and diff styling in this PR.
  • Add plan-based Claude/OpenAI connections with OAuth #509: Touches LLM provider wiring and schemas in src/core/llm/manager.ts and src/types/provider.types.ts, affecting backend provider registration.

Poem

🐰 Claudsidian hops with joy so bright,
WebSockets dance through day and night,
Agent friends with vault RPC call,
Activities grouped, interspersed fall,
From Smart Composer to Claude's new hall!

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@ki-cooley ki-cooley closed this Feb 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants