feat: bot file transfer, mobile file download, and relay server improvements#100
Merged
GCWing merged 2 commits intoGCWing:mainfrom Mar 9, 2026
Conversation
added 2 commits
March 9, 2026 20:59
…vements ## Bot file transfer (Feishu + Telegram) - Extract `computer://` links from AI responses and offer download buttons - Feishu: upload files via IM file API (≤30MB), send as file messages - Telegram: send files via sendDocument API (≤30MB), inline keyboard buttons - Shared utilities in bot/mod.rs: resolve_workspace_path, read_workspace_file, detect_mime_type, extract_computer_file_paths, format_file_size - ForwardedTurnResult replaces plain String to carry both display_text and full_text for link extraction - pending_files map on BotChatState for download token management - Auto-inherit desktop workspace when bot session has none - Graceful stop signal (watch channel) for bot pairing loops ## Remote server file commands - Add ReadFile, ReadFileChunk, GetFileInfo commands - Chunked transfer with 3MB raw chunks (4MB base64) for large files - Terminal pre-warming for remote sessions (avoids 30s shell readiness wait) - Increase broadcast channel buffer from 256 to 1024 - accumulated_text() accessor on RemoteSessionStateTracker ## Mobile web file download - FileCard component renders `computer://` links as interactive cards with name, size, and download progress indicator - MarkdownContent: custom `a` renderer for computer:// links + urlTransform to preserve the protocol - RemoteSessionManager: readFile() with chunked transfer + progress callback, getFileInfo() for metadata-only queries - Download triggers browser save dialog via blob URL ## Relay server deployment - Standalone Dockerfile (no workspace dependency, Rust 1.85) - Simplified docker-compose.yml (Caddy commented out) - Add remote-deploy.sh for SSH-based deployment from dev machine - Updated README with local vs remote deploy instructions - WS max_frame_size and max_write_buffer_size set to 64MB - Relay client WebSocket config with matching 64MB limits ## Terminal & input fixes - Fix pty_to_session mapping race: retry lookup for non-Data events - Accept Starting session status when shell integration reaches Prompt - RichTextInput: fix IME composition handling for Safari (delayed clear) - Mobile ChatPage: IME compositionStart/End guards on textarea - Improved scroll behavior: only auto-scroll when near bottom - useLayoutEffect for initial scroll to prevent flash - Theme switching: CSS transition class instead of opacity crossfade - index.html: inline script reads saved theme before first paint - Navigation animations: iOS-style full-width slide with z-index layering Made-with: Cursor
- Keep our delayed isComposingRef clear (Safari fix) while preserving upstream's onCompositionEnd callback propagation Made-with: Cursor
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.
Summary
computer://links in AI responses, present download buttons, and transfer workspace files to users (Feishu IM file API / Telegram sendDocument, ≤30MB).computer://links in chat messages render as interactive FileCard components with file metadata, progress bar, and browser save-as download via chunked transfer (3MB chunks).remote-deploy.shfor SSH-based deployment, WebSocket 64MB limits across relay server and client.Changes
Bot File Transfer
bot/mod.rs: Shared utilities —resolve_workspace_path,read_workspace_file,detect_mime_type,extract_computer_file_paths,format_file_size,WorkspaceFileContentbot/feishu.rs:upload_file_to_feishu,send_file_to_feishu_chat,notify_files_ready,handle_download_request; graceful stop signal for pairing loopbot/telegram.rs:send_message_with_keyboard,send_file_as_document,notify_files_ready,handle_download_request,download_photo(image support); inline keyboard buttons;send_handle_resultwithclean_reply_textbot/command_router.rs:ForwardedTurnResultstruct; auto-inherit workspace; updatedexecute_forwarded_turnto return full_text for link extractionRemote Server
remote_server.rs:ReadFile,ReadFileChunk,GetFileInfocommands; terminal pre-warming; broadcast buffer 256→1024;accumulated_text()accessorrelay_client.rs: WebSocket config with 64MB limitsmod.rs: Graceful stop signal for bot pairing; race guard on bot_connected_infoMobile Web
ChatPage.tsx:FileCardcomponent with chunked download + progress;MarkdownContentcustomarenderer; IME composition guards;useLayoutEffectinitial scroll; near-bottom auto-scroll logicRemoteSessionManager.ts:readFile()chunked transfer,getFileInfo()ThemeProvider.tsx: CSS transition class approach;commitThemeDOM; pre-cached CSSindex.html: Inline theme script before first paintglobal.scss: iOS-style navigation animations with z-index layering;theme-switchingclassRelay Server Deployment
Dockerfile(Rust 1.85, no workspace)docker-compose.yml: Caddy commented out,room-webvolumeremote-deploy.sh: SSH-based deployment scriptdeploy.sh: Stop old containers before rebuildREADME.md: Local vs remote deploy docsFixes
terminal/session/manager.rs: Retry pty_to_session lookup for non-Data events; acceptStartingsession statusRichTextInput.tsx: Safari IME fix (delayedisComposingRefclear)max_frame_size/max_write_buffer_size64MBTest Plan
computer://link → user taps download button → file delivered to chatcomputer://link → FileCard renders with name/size → tap to download → progress bar → browser save dialogbash deploy.shlocal deploy works;bash remote-deploy.sh <host>SSH deploy worksMade with Cursor