ๆ–‡ไปถๆœ€ๅŽๆไบค่ฎฐๅฝ•ๆœ€ๅŽๆ›ดๆ–ฐๆ—ถ้—ด
feat: rebrand stable app icon Signed-off-by: Innei <tukon479@gmail.com> 3 ไธชๆœˆๅ‰
โœจ feat(agent): add floating chat panel and workspace improvements (#13887) * โœจ feat(FloatingChatPanel): add single-instance mount guard * โœจ feat(FloatingChatPanel): add inner ChatBody layout * โœจ feat(FloatingChatPanel): add reusable floating conversation panel * โœ… test(FloatingChatPanel): add props wiring smoke tests * Refactor agent topic and page routes * Restore topic page routing for floating chat panel * โœจ feat(FloatingChatPanel): enhance ChatBody and TopicItem for improved routing and styling - Updated ChatBody to maintain scroll ownership while hiding overflow. - Refactored TopicItem to correctly highlight active topics based on routing context. - Added tests for TopicItem to ensure correct active state behavior. - Introduced static styles for FloatingChatPanel to manage layout overflow. Signed-off-by: Innei <tukon479@gmail.com> * chore: help to merge & rebase * chore: align merge with canary โ€” drop pkg.pr.new ui, adopt canary useMenu, remove NotebookButton * โœจ feat: add ViewSwitcher component and update localization for chat views - Introduced a new ViewSwitcher component to toggle between chat, page, and task views in the conversation header. - Updated English and Chinese localization files to include new labels for the view switcher options. - Refactored the conversation header to integrate the ViewSwitcher, enhancing the user interface for better navigation. Signed-off-by: Innei <tukon479@gmail.com> * fix: update @lobehub/ui to version 5.9.1 and refactor FloatingChatPanel to use FloatingSheet component - Updated the @lobehub/ui dependency in package.json to version 5.9.1. - Refactored FloatingChatPanel to utilize the new FloatingSheet component, enhancing its layout and state management. - Introduced a new ChatLayout component for better organization of chat-related UI elements. - Adjusted routing configuration to incorporate the new ChatLayout for agent chat pages. Signed-off-by: Innei <tukon479@gmail.com> * feat: add TopicCanvas and TitleSection components for topic management - Introduced TopicCanvas component to serve as a document canvas for topics, integrating an editor and title section. - Added TitleSection component for managing topic titles and emojis, enhancing user interaction with a dedicated UI. - Updated FloatingChatPanel to accommodate the new TopicCanvas, ensuring a cohesive layout in the topic page. - Enhanced tests to verify the integration of TopicCanvas within the topic page route. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(agent-page): bind documentId to URL and introduce HeaderSlot - Add nested /agent/:aid/:topicId/page/:docId route with PageRedirect for bare /page - Introduce useAutoCreateTopicDocument with module-level inflight de-dup - Lift Portal + WorkingSidebar to (chat) layout; keep ChatHeader in left column - Sidebar document clicks on page route navigate to /page/:docId instead of opening Portal - Add HeaderSlot (context + createPortal) as a reusable header injection point - Mount AutoSaveHint via HeaderSlot; register Files hotkey scope in TopicCanvas so Cmd+S triggers manual save - Sync desktopRouter.config.tsx and desktopRouter.config.desktop.tsx - Extend RecentlyViewed plugin to round-trip optional docId segment * Use topic titles for auto-created page documents * Add page-agent init gating and runtime diagnostics * Support current-topic agent documents * Implement Active Topic Document and Disabled Tool Call Filtering - Introduced ActiveTopicDocumentContextInjector to inject context for active topic documents into user messages. - Added DisabledToolCallFilter to remove historical tool calls for disabled tools in the current runtime scope. - Updated MessagesEngine to utilize the new context injectors and filters. - Enhanced tests to verify the correct injection of active topic document context and filtering of disabled tool calls. This update improves the handling of document editing contexts and tool management in the conversation flow. Signed-off-by: Innei <tukon479@gmail.com> * feat: enhance agent document management with LiteXML operations - Updated API names for clarity, changing 'patchDocument' to 'modifyNodes'. - Introduced LiteXML operation schema for document modifications. - Implemented new mutation for modifying document nodes via LiteXML. - Enhanced document retrieval methods to support format options (XML, Markdown, Both). - Added support for editor data snapshots and normalization of diff nodes. - Improved document history management to handle editor data with diff nodes. - Created tests for new features and ensured existing functionality remains intact. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ› fix: apply agent document xml edits directly * Refine document cache invalidation and editor hydration * ๐Ÿ› fix: stabilize agent topic hydration * fix: update @lobehub/editor dependency version and clean up test mocks Signed-off-by: Innei <tukon479@gmail.com> * Potential fix for pull request finding 'Useless assignment to local variable' Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com> * ๐Ÿ› fix(document): preserve pending diff nodes through save path Skip normalizeEditorDataDiffNodes on every autosave so diff nodes awaiting user review survive persistence. Normalization now runs only on explicit Accept/Reject via DiffAllToolbar. Also flip headless litexml ops to delay:true to match the new review flow. * ๐Ÿ› fix(agent): detect agent sub-route from URL params not cached topic isInAgentSubRoute used routeTopicId (with activeTopicId fallback) as its base path. On /agent/:aid/profile with a cached activeTopicId, the base became /agent/:aid/:cachedTopicId which pathname cannot startsWith, so sub-route detection returned false and sidebar topic clicks only called switchTopic without routing back to chat โ€” users stayed stuck on profile. Derive the sub-route base from params.topicId directly so stale store state cannot mask the check. routeTopicId export keeps the fallback for sidebar highlighting. * ๐Ÿ› fix(page): repair topic page document recovery * ๐Ÿ› fix(page-agent): block tool calls when page editor is not mounted scope is topic-bound not route-bound, so navigating from /agent/.../Page to /agent/... keeps scope==='page' and PageAgentIdentifier stayed in the injected plugin list. The LLM could still call initPage / modifyNodes / etc. against a stale editor reference, returning misleading success (e.g. nodeCount=0). Two layers of guard: - PageAgentExecutor wraps `invoke` and returns a structured PAGE_EDITOR_NOT_MOUNTED / kind: 'replan' result when the runtime editor is not mounted, pointing the LLM at lobe-agent-documents. - streamingExecutor drops PageAgentIdentifier from the tool set via the new `composeEnabledTools` pipeline when scope==='page' and the page-agent runtime is not ready. Also extract the tool-set composition (inject merge + runtime drops) out of the ~320-line internal_createAgentState into `mecha/toolSetComposer`, with unit tests. * ๐Ÿ› fix(chat): unify message stream for /agent/:topicId and /page/:docId Before this change a page-scoped conversation (FloatingChatPanel with scope='page' in the /Page route) partitioned the client message store by scope, so /agent/:topicId and /agent/:topicId/page/:docId each built their own messagesMap slot and SWR cache โ€” but the TRPC getMessages endpoint ignores scope and returned the same messages for both, producing duplicate fetches and a visible message-history split between the two surfaces. Fixes by keeping scope='page' as a capability/surfacing marker only: - messageMapKey: collapse 'page' to the default scope early in toMessageMapContext, so threadId/groupId still win and only the main/page pair actually unifies. - useFetchMessages: build the SWR key from identity fields (agentId, groupId, threadId, topicId) instead of the full ConversationContext, so scope no longer partitions the cache. agentConfigResolver/streamingExecutor/composeEnabledTools still read scope='page' from operation.context for PageAgent injection and initialContext.pageEditor wiring โ€” the capability layer is unchanged. Also fix two pre-existing test regressions surfaced by re-running the impacted suites: - streamingExecutor page-editor initialContext test now mocks pageAgentRuntime.isReady() (required since the PageAgent editor-ready guard landed). - FloatingChatPanel default shell props test updated to match the [180,320,520,800] snap points introduced in 62dc91e444. * โ™ป๏ธ refactor(FloatingChatPanel): read main slot without changing scope Revert the global messageMapKey/SWR-key changes from b650cdc9d7 โ€” the global collapse over-reached and coupled message routing to scope in ways other surfaces don't want. Instead, specialize only the place that actually has the dual-role problem. `scope` should be a capability marker (PageAgent tool + pageEditor initialContext injection), not a message-list partition. Floating panel on /agent/:topicId/page is the only caller that sets scope='page', and its message list should mirror /agent/:topicId โ€” the surfaces share a topic. Local collapse in FloatingChatPanel: compute chatKey with `scope === 'page' ? 'main' : scope`, so messagesMap is read from the main slot. The downstream ConversationContext keeps scope='page' for the capability layer; only the slot lookup is specialized. Kept from b650cdc9d7 (unrelated to the revert): - streamingExecutor test mocks pageAgentRuntime.isReady() โ€” required by the PageAgent editor-ready guard in 01ef7bc142. - FloatingChatPanel snap-points test matches [180,320,520,800] from 62dc91e444. * ๐Ÿ› fix(FloatingChatPanel): simplify chat key computation for message retrieval Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ› fix(index.desktop.test): update LocationProbe to reflect route changes and improve test accuracy Signed-off-by: Innei <tukon479@gmail.com> * Constrain agent header title under centered switcher * ๐Ÿ› Fix conversation header view switcher layout * ๐Ÿ› Fix agent topic path links and cmdk context * ๐Ÿ› fix(test): align document history fixtures and layout ui mock * ๐Ÿ› fix(e2e): support dialog-based topic rename * โ™ป๏ธ refactor(debug): use scoped debuggers for PR logging --------- Signed-off-by: Innei <tukon479@gmail.com> Co-authored-by: Neko Ayaka <neko@ayaka.moe> Co-authored-by: Copilot Autofix powered by AI <223894421+github-code-quality[bot]@users.noreply.github.com>29 ๅคฉๅ‰
๐ŸŒ chore: translate non-English strings to English in apps/cli, apps/device-gateway, and apps/desktop scripts (#14626) Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>13 ๅคฉๅ‰
๐Ÿ› fix(conversation): only swap model name for remote hetero agents in Usage (#15156) * ๐Ÿ› fix(conversation): only swap model name for remote hetero agents in Usage Local CLI hetero agents (claude-code, codex) report their actual model id on `turn_metadata` and persist it on the assistant message, but the Usage extra was unconditionally replacing it with the provider brand label ("Claude Code" / "Codex") whenever `HETEROGENEOUS_TYPE_LABELS` had an entry. Gate the swap to remote platform agents (openclaw, hermes) โ€” those don't expose a real model id โ€” so CC/Codex turns show the underlying model again. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * โœ… test(desktop): update GatewayConnectionCtr tests for lh hetero exec route Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>27 ๅˆ†้’Ÿๅ‰
โœจ feat: set OSS default model to DeepSeek V4 Pro (#14555)14 ๅคฉๅ‰
โœจ feat(agent-browser): add browser automation skill and tool detection (#12858) * โœจ feat(tool-detectors): add browser automation support and refactor tool detector categories - Introduced browser automation detectors to the tool detector manager. - Updated tool categories to include 'browser-automation'. - Refactored imports to use type imports where applicable for better clarity. - Cleaned up unnecessary comments in tool filters. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore: add browser automation tool detection UI * ๐Ÿ”ง chore: update react-scan version and enhance agent-browser documentation - Updated `react-scan` dependency from version 0.4.3 to 0.5.3 in package.json. - Improved documentation in `content.ts` for the agent-browser, clarifying command usage and workflows. - Added development mode flag `__DEV__` in sharedRendererConfig for better environment handling. - Integrated `scan` functionality in `initialize.ts` to enable scanning in development mode. - Updated global type definitions to include `__DEV__` constant for clarity. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore(builtin-skills): add dependency and refactor skill filtering logic - Added `@lobechat/const` as a dependency in package.json. - Introduced a new function `shouldEnableBuiltinSkill` to determine if a skill should be enabled based on the environment. - Refactored the `builtinSkills` export to filter skills using the new logic. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore(builtin-skills): refactor skill management and add filtering logic - Removed unnecessary dependency from package.json. - Simplified skill filtering logic by introducing `filterBuiltinSkills` and `shouldEnableBuiltinSkill` functions. - Updated various components to utilize the new filtering logic for managing builtin skills based on the environment. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(builtin-skills): introduce new skill APIs and refactor manifest structure - Added new APIs for skill management: `runSkillApi`, `readReferenceApi`, and `exportFileApi` to enhance functionality. - Created a base manifest file (`manifest.base.ts`) to centralize API definitions. - Updated the desktop manifest (`manifest.desktop.ts`) to utilize the new base APIs. - Refactored existing manifest to streamline API integration and improve maintainability. - Introduced a detailed system prompt for better user guidance on skill usage. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat: desktop skill runtime, skill store inspectors, and tool UI updates Made-with: Cursor * โœจ feat: enhance skill import functionality and testing - Updated `importFromUrl` method in `SkillImporter` to accept additional options for identifier and source. - Modified `importFromMarket` in `agentSkillsRouter` to utilize the new options for better tracking of skill imports. - Added integration tests to ensure stable behavior when re-importing skills from the market, verifying that identifiers remain consistent across imports. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore: update .gitignore and package.json dependencies - Added 'bin' to .gitignore to exclude binary files from version control. - Included 'fflate' as a new dependency in package.json to support file compression in the application. - Updated writeFile method in LocalFileCtr to handle file content as Uint8Array for improved type safety. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore: update package.json dependencies - Removed 'fflate' from dependencies and added it to devDependencies for better organization. - Ensured proper formatting by adding a newline at the end of the file. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat: add agent-browser download script and integrate binary handling - Introduced a new script to download the `agent-browser` binary, ensuring it is available for the application. - Updated `electron-builder.mjs` to include the binary in the build process. - Modified `dir.ts` to define the binary directory path based on the packaging state. - Enhanced the `App` class to set environment variables for the agent-browser integration. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat: add DevTools toggle to Linux and Windows menus - Introduced a new menu item for toggling DevTools with the F12 accelerator key in both Linux and Windows menu implementations. - Added a separator for better organization of the view submenu items. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat: integrate agent-browser binary download into build process - Added functionality to download the `agent-browser` binary during the build process in `electron-builder.mjs`. - Enhanced the download script with detailed logging for better visibility of the download status and errors. - Updated the `App` class to log the binary directory path for improved debugging. - Reintroduced the `AuthRequiredModal` in the layout for desktop users. Signed-off-by: Innei <tukon479@gmail.com> * fix: mock binary directory path in tests - Added a mock for the binary directory path in the App tests to facilitate testing of the agent-browser integration. - This change enhances the test environment by providing a consistent path for the binary during test execution. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ› fix: improve authorization notification handling - Updated the `notifyAuthorizationRequired` method to implement trailing-edge debounce, ensuring that rapid 401 responses are coalesced and the IPC event is sent after the burst settles. - Refactored the notification logic to enhance clarity and maintainability. โœจ feat: add desktop onboarding redirect - Introduced a `useEffect` hook in `StoreInitialization` to redirect users to the `/desktop-onboarding` page if onboarding is not completed, ensuring a smoother user experience on fresh installs. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ› fix(desktop): hide Agent Browser skill on Windows Made-with: Cursor * ๐Ÿ”ง chore: update memory limits for build processes - Increased the `NODE_OPTIONS` memory limit for both `build:next` and `build:spa` scripts from 6144 to 7168, optimizing build performance and resource management. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>2 ไธชๆœˆๅ‰
๐Ÿ› fix(desktop): add auth required modal and improve error handling (#11574) * ๐Ÿ› fix(desktop): add auth required modal and improve error handling - Add AuthRequiredModal component to handle authentication expiration - Improve backend proxy protocol error handling for auth errors - Add updater manager authentication header support - Add i18n strings for auth error messages * ๐Ÿ”ง fix(desktop): update UpdaterManager to leave channel unset for GitHub prerelease matching - Modify UpdaterManager to leave the channel unset, allowing GitHub to use version tags for prerelease matching. - Update logging to reflect the new behavior when the channel is unset or kept as is. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง fix(desktop): clarify UpdaterManager behavior for GitHub provider - Update comments and logging in UpdaterManager to clarify that the channel is left unset for beta/nightly, allowing GitHub to use version tags for prerelease matching. - Ensure logging accurately reflects the new behavior when the channel is unset. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(desktop): add desktop build channel script and update documentation - Introduced a new script for building desktop applications for specific release channels (stable, beta, nightly). - Updated package.json to include a new npm command for the build channel. - Enhanced README documentation to guide users on simulating CI channel builds and retaining changes. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง fix(desktop): streamline NODE_ENV usage in logger and config - Removed redundant process.env.NODE_ENV definition from electron.vite.config.ts. - Simplified logger implementation by directly using process.env.NODE_ENV for environment checks. - Improved readability and maintainability of logging behavior based on the environment. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง fix(desktop): enhance logging configuration to support debug mode - Updated logger configuration to allow for debug level logging when DEBUG environment variable is set. - Simplified the logic for console logging levels based on the environment, improving clarity and maintainability. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง fix(desktop): enhance version generation and logging in UpdaterManager - Updated version generation logic in manual-build-desktop.yml to handle channel suffixes more effectively. - Added inferredChannel logging in UpdaterManager to improve clarity on the current update channel being used. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง fix(desktop): update localization files and set default entry locale to English - Changed default entry locale from Chinese (zh-CN) to English (en) in .i18nrc.js. - Added full disk access messages in multiple languages (Arabic, Bulgarian, German, Spanish, French, Italian, Japanese, Korean, Dutch, Polish, Portuguese, Russian, Turkish, Vietnamese, Traditional Chinese). - Enhanced menu localization with new settings and permissions options across various languages. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>4 ไธชๆœˆๅ‰
โช revert: revert pnpm v11 migration (#14372) * Revert "๐Ÿ‘ท build: disable pnpm gvs for desktop ci (#14357)" This reverts commit 948ba5ec68e347a116f52e3599894d3002f0cb9a. * Revert "๐Ÿ‘ท build(repo): migrate to pnpm v11 and consolidate workspace config (#14316)" This reverts commit 1d9b6099bd7ce72d0b656d45936fc81cd8d0ee68.22 ๅคฉๅ‰
โœจ feat: refactor desktop implement with brand new 2.0 4 ไธชๆœˆๅ‰
๐Ÿ”ง chore: update eslint v2 configuration and suppressions (#12133) * v2 init * chore: update eslint suppressions and package dependencies - Removed several eslint suppressions related to array sorting and reversing from eslint-suppressions.json to clean up the configuration. - Updated @lobehub/lint package version from 2.0.0-beta.6 to 2.0.0-beta.7 in package.json for improvements and bug fixes. - Made minor formatting adjustments in vitest.config.mts and various SKILL.md files for better readability and consistency. Signed-off-by: Innei <tukon479@gmail.com> * fix: clean up import statements and formatting - Removed unnecessary whitespace in replaceComponentImports.ts for improved readability. - Standardized import statements in contextEngineering.ts and createAgentExecutors.ts by adding missing spaces for consistency. Signed-off-by: Innei <tukon479@gmail.com> * chore: update eslint suppressions and clean up code formatting * ๐Ÿ› fix: use vi.hoisted for mock variable initialization Fix TDZ error in persona service test by using vi.hoisted() to ensure mock variables are available when vi.mock factory runs. --------- Signed-off-by: Innei <tukon479@gmail.com> 3 ไธชๆœˆๅ‰
โœจ feat: refactor desktop implement with brand new 2.0 4 ไธชๆœˆๅ‰
โœจ feat(desktop): screen capture overlay, Quick Chat tray, and upload pipeline improvements (#13818) * feat: add screen capture functionality with overlay support - Implemented ScreenCaptureManager to handle screen capture sessions. - Added ScreenCaptureCtr for IPC methods related to screen capture. - Created overlay.html and ScreenCaptureOverlay component for user interaction. - Integrated window enumeration and capture logic using node-screenshots and get-windows. - Updated menu options to include screen capture actions. - Enhanced RendererUrlManager to support overlay routing. - Introduced drag selection for capturing specific screen areas. - Added necessary types and events for screen capture in electron-client-ipc. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(desktop): refine screen capture overlay flow * โœจ feat(desktop): refine screen capture overlay flow * โšก feat(desktop): optimize screen capture overlay flow * Delete apps/desktop/mockup/screen-capture-overlay.html * โœจ feat(desktop): open mini toolbar via double Option * ๐Ÿ› fix(desktop): separate quick composer hotkey * ๐Ÿ’„ fix(desktop): remove stale quick composer accelerator * ๐Ÿ› fix(desktop): stabilize double option monitor * ๐Ÿ› fix(desktop): read hardware option key state * ๐Ÿ› fix(desktop): standardize path imports and improve error handling - Replaced `join` imports with `path` imports for consistency across files. - Enhanced error handling in various modules to include error causes for better debugging. - Updated test files to reflect changes in variable naming and mock implementations. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ฅ chore(hotkey): drop orphan renderer quickComposer i18n entries The `quickComposer` hotkey is registered only on the Electron side (DESKTOP_GLOBAL_SHORTCUT_DEFAULTS + BrowserWindowsCtr.openQuickComposer); the renderer never referenced these i18n keys, so the entries were dead. `desktop.quickComposer` covers the app-level trigger. * โšก๏ธ perf(screen-capture): parallelize overlay upload with route navigation Overlay submit used to await screenshot upload before router.push, blocking the main window for several seconds when the user was on an unrelated page (e.g. /settings). Now we navigate immediately and run upload in a background IIFE; MessageFromUrl waits on a new `uploadStatus` field before calling sendMessage, so the chat page mount and the upload proceed in parallel. - Add `uploadStatus: 'uploading' | 'ready' | 'failed'` to PendingOverlayDispatch; canConsumePendingOverlayDispatch blocks while `'uploading'`. - Store gains `markDispatchUploadComplete`; on failure it clears screenshotFileNames so the prompt still delivers. - Dispatcher drops stale prev search params on push to prevent MessageFromUrl's message-param effect from double-firing. * โšก๏ธ perf(screen-capture): pre-upload captures in overlay preview + per-thumbnail status Move uploads from post-submit to preview time, bypassing dataUrl round-trips: - Main process assigns captureId at preview time and ships the PNG bytes as ArrayBuffer to the main renderer via `overlayUploadRequest`. - Main renderer uploads through a dedicated pool (uploadWithProgress, no chatUploadFileList pollution); reports status back to the overlay through `overlayCaptureUploadStatus`. - Overlay thumbnails render a spinner / error badge based on status; the send button stays grey until every capture resolves to `ready`. - Submit now carries only captureIds; MessageFromUrl awaits the pool promises before sendMessage, removing the second upload pass. - Carry overlay-selected modelId/provider into the agent config so the first message actually uses the user-chosen model (fixes the bug where switching the model on the overlay had no effect). * update * โœจ feat(popup): add Quick Chat tray entry backed by Inbox agent Tray menu now exposes a "Quick Chat" action that opens (or focuses) a single-instance popup window at `/popup/agent/inbox`. Each fresh open starts with no active topic; the first message creates one through the normal agent flow. - New `PopupAgentQuickPage` resolves the inbox slug via `builtinAgentSelectors.inboxAgentId` so `activeAgentId` points at the real entity in `agentMap` (fixes the stuck-loading / skeleton state from using the literal `'inbox'` slug). - `BrowserManager.openQuickChatPopup` wraps `createMultiInstanceWindow` with a fixed `topicPopup_quick_inbox` uniqueId so repeat clicks focus rather than spawn. - Wire the action into macOS / Windows / Linux tray menus and add the `tray.quickChat` i18n key. * Add quick chat shortcut and desktop hotkey support * โœจ feat(screen-capture): enhance window enumeration with scale factor support - Updated `enumerateWindows` to accept an optional `displayScaleFactor` parameter for improved window geometry normalization on high-DPI displays. - Refactored `normalizeWindowBounds` to handle scaling based on the provided scale factor, ensuring accurate window dimensions across different platforms. - Adjusted tests in `WindowSourceService.test.ts` to validate the new scaling behavior for both Windows and macOS environments. - Minor adjustments in `ScreenCaptureManager` to accommodate the updated window enumeration logic. --------- Signed-off-by: Innei <tukon479@gmail.com>1 ไธชๆœˆๅ‰
๐Ÿ“ docs: update documents (#12982) update document2 ไธชๆœˆๅ‰
๐Ÿ“ docs: update documents (#12982) update document2 ไธชๆœˆๅ‰
โœจ feat(desktop): screen capture overlay, Quick Chat tray, and upload pipeline improvements (#13818) * feat: add screen capture functionality with overlay support - Implemented ScreenCaptureManager to handle screen capture sessions. - Added ScreenCaptureCtr for IPC methods related to screen capture. - Created overlay.html and ScreenCaptureOverlay component for user interaction. - Integrated window enumeration and capture logic using node-screenshots and get-windows. - Updated menu options to include screen capture actions. - Enhanced RendererUrlManager to support overlay routing. - Introduced drag selection for capturing specific screen areas. - Added necessary types and events for screen capture in electron-client-ipc. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(desktop): refine screen capture overlay flow * โœจ feat(desktop): refine screen capture overlay flow * โšก feat(desktop): optimize screen capture overlay flow * Delete apps/desktop/mockup/screen-capture-overlay.html * โœจ feat(desktop): open mini toolbar via double Option * ๐Ÿ› fix(desktop): separate quick composer hotkey * ๐Ÿ’„ fix(desktop): remove stale quick composer accelerator * ๐Ÿ› fix(desktop): stabilize double option monitor * ๐Ÿ› fix(desktop): read hardware option key state * ๐Ÿ› fix(desktop): standardize path imports and improve error handling - Replaced `join` imports with `path` imports for consistency across files. - Enhanced error handling in various modules to include error causes for better debugging. - Updated test files to reflect changes in variable naming and mock implementations. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ฅ chore(hotkey): drop orphan renderer quickComposer i18n entries The `quickComposer` hotkey is registered only on the Electron side (DESKTOP_GLOBAL_SHORTCUT_DEFAULTS + BrowserWindowsCtr.openQuickComposer); the renderer never referenced these i18n keys, so the entries were dead. `desktop.quickComposer` covers the app-level trigger. * โšก๏ธ perf(screen-capture): parallelize overlay upload with route navigation Overlay submit used to await screenshot upload before router.push, blocking the main window for several seconds when the user was on an unrelated page (e.g. /settings). Now we navigate immediately and run upload in a background IIFE; MessageFromUrl waits on a new `uploadStatus` field before calling sendMessage, so the chat page mount and the upload proceed in parallel. - Add `uploadStatus: 'uploading' | 'ready' | 'failed'` to PendingOverlayDispatch; canConsumePendingOverlayDispatch blocks while `'uploading'`. - Store gains `markDispatchUploadComplete`; on failure it clears screenshotFileNames so the prompt still delivers. - Dispatcher drops stale prev search params on push to prevent MessageFromUrl's message-param effect from double-firing. * โšก๏ธ perf(screen-capture): pre-upload captures in overlay preview + per-thumbnail status Move uploads from post-submit to preview time, bypassing dataUrl round-trips: - Main process assigns captureId at preview time and ships the PNG bytes as ArrayBuffer to the main renderer via `overlayUploadRequest`. - Main renderer uploads through a dedicated pool (uploadWithProgress, no chatUploadFileList pollution); reports status back to the overlay through `overlayCaptureUploadStatus`. - Overlay thumbnails render a spinner / error badge based on status; the send button stays grey until every capture resolves to `ready`. - Submit now carries only captureIds; MessageFromUrl awaits the pool promises before sendMessage, removing the second upload pass. - Carry overlay-selected modelId/provider into the agent config so the first message actually uses the user-chosen model (fixes the bug where switching the model on the overlay had no effect). * update * โœจ feat(popup): add Quick Chat tray entry backed by Inbox agent Tray menu now exposes a "Quick Chat" action that opens (or focuses) a single-instance popup window at `/popup/agent/inbox`. Each fresh open starts with no active topic; the first message creates one through the normal agent flow. - New `PopupAgentQuickPage` resolves the inbox slug via `builtinAgentSelectors.inboxAgentId` so `activeAgentId` points at the real entity in `agentMap` (fixes the stuck-loading / skeleton state from using the literal `'inbox'` slug). - `BrowserManager.openQuickChatPopup` wraps `createMultiInstanceWindow` with a fixed `topicPopup_quick_inbox` uniqueId so repeat clicks focus rather than spawn. - Wire the action into macOS / Windows / Linux tray menus and add the `tray.quickChat` i18n key. * Add quick chat shortcut and desktop hotkey support * โœจ feat(screen-capture): enhance window enumeration with scale factor support - Updated `enumerateWindows` to accept an optional `displayScaleFactor` parameter for improved window geometry normalization on high-DPI displays. - Refactored `normalizeWindowBounds` to handle scaling based on the provided scale factor, ensuring accurate window dimensions across different platforms. - Adjusted tests in `WindowSourceService.test.ts` to validate the new scaling behavior for both Windows and macOS environments. - Minor adjustments in `ScreenCaptureManager` to accommodate the updated window enumeration logic. --------- Signed-off-by: Innei <tukon479@gmail.com>1 ไธชๆœˆๅ‰
โœจ feat(desktop): unified update channel switching with S3 distribution (#12644) * โœจ feat(desktop): add update channel settings for desktop app * ๐Ÿ”ง chore(desktop): update test scripts for multi-channel update flow - Support stable/nightly/canary channel structure in generate-manifest.sh - Add --all-channels flag for generating manifests across all channels - Dual-mode run-test.sh: packaged (full updater) and --dev (UI only) - Fix package:mac:local to skip signing for local builds - Document Squirrel.Mac signature validation limitation * ๐Ÿ”ง chore(desktop): update local app update configuration - Change provider from GitHub to Generic for local testing. - Update local server URL and cache directory settings. - Revise comments for clarity on usage and configuration. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ› fix(desktop): fix update channel switch race condition and downgrade flag - P1: Use generation counter to discard stale check results when channel is switched mid-flight. Pending recheck is scheduled after current check completes instead of forcing concurrent checks. - P2: Explicitly reset allowDowngrade=false on non-downgrade transitions to prevent stale downgrade permission from persisting. - Fix GitHub fallback repo name (lobe-chat -> lobehub). * ๐Ÿ”ง chore(settings): remove dynamic import for Beta component from componentMap - Eliminated the dynamic import for the Beta settings tab, streamlining the component map. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ง chore(settings): simplify UpdateChannel component structure - Refactored the UpdateChannel component to streamline the Select component usage by removing unnecessary nested children. Signed-off-by: Innei <tukon479@gmail.com> * update * ๐Ÿ› fix(desktop): strip channel suffix from UPDATE_SERVER_URL before appending channel The UPDATE_SERVER_URL secret may already contain a channel path (e.g., /stable). Previously, the code unconditionally appended /{channel}, resulting in double paths like /stable/stable/stable-mac.yml. Now both electron-builder.mjs and UpdaterManager strip any trailing channel suffix before re-appending the correct channel, supporting both legacy URLs (with channel) and clean base URLs. * update * update * redesign ui - Added `getUpdaterState` method to `UpdaterManager` for retrieving current update status. - Introduced `UpdaterState` type to encapsulate update progress, stage, and error messages. - Updated UI components to reflect update states, including checking, downloading, and latest version notifications. - Enhanced menu items for macOS and Windows to display appropriate update statuses. - Localized new update messages in English and Chinese. This improves user experience by providing real-time feedback during the update process. Signed-off-by: Innei <tukon479@gmail.com> * Enhance UpdaterManager tests and mock implementations - Updated tests for UpdaterManager to reflect changes in broadcasting update states, including 'checking', 'downloading', and 'error' stages. - Modified mock implementations in macOS and Windows test files to include `getUpdaterState` and `installNow` methods for better state management. - Improved test coverage for update availability and download processes. These changes ensure more accurate testing of the update flow and enhance the overall reliability of the UpdaterManager functionality. Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>2 ไธชๆœˆๅ‰
๐Ÿ› fix(desktop): split runtime externals from native deps (#14776)10 ๅคฉๅ‰
๐Ÿ› fix(local-system): forward all grepContent params + move executor to /client (#14888) * ๐Ÿ› fix(local-system): forward all grepContent params + move executor to /client The local-system executor was reducing the agent's full grepContent params ({pattern, glob, output_mode, -i/-n/-A/-B/-C, multiline, head_limit, type, scope, ...}) down to {directory, pattern} before handing them to the runtime. `directory` isn't recognized by the IPC layer (which expects path/scope), so cwd silently fell back to process.cwd() (= apps/desktop/ in dev), and with glob/-i/output_mode all stripped grep matched anything containing the pattern across the whole tree โ€” explaining LOBE-8666's dist/main/index.js + tsconfig.tsbuildinfo leaks. Also audited the rest of the executor layer: - listFiles: forward `limit` (was silently dropped โ†’ manifest default of 100 always won). - getCommandOutput: forward `filter` (was silently dropped โ†’ no regex filter ever applied to streamed output). - runCommand: mirror `run_in_background` โ†’ `background` so ComputerRuntime.RunCommandState.isBackground reflects reality (the IPC handler reads run_in_background directly, so the command itself ran in background โ€” only the state field was wrong). Structure: moved src/executor/ โ†’ src/client/executor/ to match the other builtin-tool packages (task / lobe-agent / knowledge-base) and consolidate renderer-only code under /client. Dropped the `./executor` package subpath; consumers now import from `โ€ฆ/client`. Defensive: also added a resolveSearchPath helper in apps/desktop's contentSearch module that reads params.scope as a fallback for params.path, so any non-executor caller (direct IPC, future Gateway path) that passes `scope` still gets routed correctly instead of falling through to process.cwd(). Regression coverage: - grepContent full forwarding (LOBE-8666 case + all optional flags) - listFiles.limit forwarding - getCommandOutput.filter forwarding - runCommand.run_in_background โ†’ background mirror - resolveSearchPath fallback semantics (3 cases in base.test.ts) Verified end-to-end via Electron CDP โ€” tool.invokeBuiltinTool with the LOBE-8666 params returns 9 clean .ts matches (no dist/, no .tsbuildinfo); listFiles {limit:3} returns 3 files (totalCount 10); runCommand {run_in_background:true} reports state.isBackground=true. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ๐Ÿ› fix(desktop): readFile fails with `protocol.registerSchemesAsPrivileged should be called before app is ready` Two-part fix for a regression where reading any text/JSON/source file via the local-system `readFile` tool surfaced an Electron protocol error in the response content. The error fired *after* `stat()` succeeded (so missing-file ENOENT was unaffected), making it look like the file couldn't be parsed. ## Root cause Stack trace (instrumented `read.ts` to capture it): ``` Error: protocol.registerSchemesAsPrivileged should be called before app is ready at new App (apps/desktop/dist/main/index.js:105339:21) at Module.<anonymous> (apps/desktop/dist/main/index.js:105615:11) at Module._compile (...) ``` `Module._compile` on `dist/main/index.js` means the main bundle is being freshly evaluated as a CJS module โ€” re-running its top-level `var app = new App(); โ€ฆ; app.bootstrap();` after the real Electron-launched App was already ready. Triggering chain: agent calls `readFile` โ†’ main runs `loadFile(path)` from `@lobechat/file-loaders` โ†’ `getFileLoader('txt')` โ†’ `await import('./text')`. The lazy text-loader chunk back-references the main bundle for the shared util `detectUtf16NoBom`: ```js // dist/main/text-Cbmlmtca.js const require_index = require("./index.js"); // โ† re-evaluates main โ€ฆ const variant = require_index.detectUtf16NoBom(buffer); ``` Electron's main entry is not in Node's CJS module cache (it's bootstrapped separately), so this `require("./index.js")` triggers a fresh compile of the main bundle โ€” re-running `new App()` and `protocol.registerSchemesAsPrivileged` *after* `app.whenReady()`, which is illegal per Electron's API contract. Introduced by #14602 (`fix(local-system): guard readFile against binary blobs and oversized output`): adding `isBinaryContent.ts` made `detectUtf16NoBom` shared between the main bundle (via `sniffBinaryFile`) and the lazy text chunk, so rolldown placed it in main and rewrote the text chunk's call as a `require_index.detectUtf16NoBom`. Identical class of bug previously fixed for the `debug` package in #11827. ## Fix 1. **`packages/file-loaders/src/loaders/index.ts`** โ€” TextLoader was lazy-imported for no real benefit. It's a 10KB module whose only deps are `node:fs/promises` and a tiny utf-16 detect util โ€” nothing like the multi-MB parsers (pdfjs-dist, xlsx, mammoth) that the lazy pattern was designed for. Make it a static import; `getFileLoader('txt')` returns it synchronously. Result: the text chunk disappears entirely, removing this back-reference at the source. 2. **`apps/desktop/electron.vite.config.ts`** โ€” defensive `manualChunks` rules so any future shared symbol doesn't recreate the same trap: - `vendor-file-loaders-utils` for the three small text/binary detection utils (`detectUtf16` / `isBinaryContent` / `isTextReadableFile`). Explicitly enumerated to avoid catching `parser-utils.ts`, which pulls in xmldom/yauzl/concat-stream (โ‰ˆ900KB) and belongs in the docx/pptx chunks instead. - `vendor-jszip` for JSZip โ€” same root cause for `.docx` reads: the docx chunk had `require_index.require_lib()` (JSZip) back-referencing main. Both ends now share the vendor chunk; no main re-eval. Follows the project precedent set by #11827 for `debug`. ## Verification (live Electron via CDP) Bundle inventory before/after: | Chunk | Before | After | | --- | --- | --- | | `text-*.js` | 9.7KB (back-refs main) | (gone, inlined into main) | | `vendor-file-loaders-utils-*.js` | n/a | 18KB | | `vendor-jszip-*.js` | n/a | 899KB | | `docx-*.js` back-refs | `require_index.require_lib` | none | End-to-end via `tool.invokeBuiltinTool('lobe-local-system', 'readFile', โ€ฆ)`: | File | Before | After | | --- | --- | --- | | `.md` / `.json` / `.ts` | `Error accessing or processing file: protocol.registerSchemesAsPrivileged should be called before app is ready` | real file content | `grep -o 'require_index\\.[a-zA-Z_]*' dist/main/*-*.js | sort -u` โ†’ empty. All 61 file-loaders tests pass; all 64 builtin-tool-local-system tests pass.6 ๅคฉๅ‰
๐Ÿ› fix(desktop): split runtime externals from native deps (#14776)10 ๅคฉๅ‰
๐Ÿ› fix(desktop): use stored locale from URL parameter instead of systeโ€ฆ (#13620) ๐Ÿ› fix(desktop): use stored locale from URL parameter instead of system language When the desktop app restarts, the UI language was reverting to the system language instead of respecting the user's saved language preference. Root cause: The inline script in index.html was setting document.documentElement.lang from navigator.language (system language) before i18n initialization could read the stored locale from Electron store. Fix: Check the URL's `lng` query parameter first (which is set by Electron main process from stored settings in Browser.ts:buildUrlWithLocale()), then fall back to navigator.language. Fixes #13616 https://claude.ai/code/session_0128LZAbJL1a5vkGboH4U5FP Co-authored-by: Claude <noreply@anthropic.com>1 ไธชๆœˆๅ‰
๐Ÿ› fix(desktop): split runtime externals from native deps (#14776)10 ๅคฉๅ‰
๐Ÿ› fix(desktop): split runtime externals from native deps (#14776)10 ๅคฉๅ‰
โœจ feat(desktop): screen capture overlay, Quick Chat tray, and upload pipeline improvements (#13818) * feat: add screen capture functionality with overlay support - Implemented ScreenCaptureManager to handle screen capture sessions. - Added ScreenCaptureCtr for IPC methods related to screen capture. - Created overlay.html and ScreenCaptureOverlay component for user interaction. - Integrated window enumeration and capture logic using node-screenshots and get-windows. - Updated menu options to include screen capture actions. - Enhanced RendererUrlManager to support overlay routing. - Introduced drag selection for capturing specific screen areas. - Added necessary types and events for screen capture in electron-client-ipc. Signed-off-by: Innei <tukon479@gmail.com> * โœจ feat(desktop): refine screen capture overlay flow * โœจ feat(desktop): refine screen capture overlay flow * โšก feat(desktop): optimize screen capture overlay flow * Delete apps/desktop/mockup/screen-capture-overlay.html * โœจ feat(desktop): open mini toolbar via double Option * ๐Ÿ› fix(desktop): separate quick composer hotkey * ๐Ÿ’„ fix(desktop): remove stale quick composer accelerator * ๐Ÿ› fix(desktop): stabilize double option monitor * ๐Ÿ› fix(desktop): read hardware option key state * ๐Ÿ› fix(desktop): standardize path imports and improve error handling - Replaced `join` imports with `path` imports for consistency across files. - Enhanced error handling in various modules to include error causes for better debugging. - Updated test files to reflect changes in variable naming and mock implementations. Signed-off-by: Innei <tukon479@gmail.com> * ๐Ÿ”ฅ chore(hotkey): drop orphan renderer quickComposer i18n entries The `quickComposer` hotkey is registered only on the Electron side (DESKTOP_GLOBAL_SHORTCUT_DEFAULTS + BrowserWindowsCtr.openQuickComposer); the renderer never referenced these i18n keys, so the entries were dead. `desktop.quickComposer` covers the app-level trigger. * โšก๏ธ perf(screen-capture): parallelize overlay upload with route navigation Overlay submit used to await screenshot upload before router.push, blocking the main window for several seconds when the user was on an unrelated page (e.g. /settings). Now we navigate immediately and run upload in a background IIFE; MessageFromUrl waits on a new `uploadStatus` field before calling sendMessage, so the chat page mount and the upload proceed in parallel. - Add `uploadStatus: 'uploading' | 'ready' | 'failed'` to PendingOverlayDispatch; canConsumePendingOverlayDispatch blocks while `'uploading'`. - Store gains `markDispatchUploadComplete`; on failure it clears screenshotFileNames so the prompt still delivers. - Dispatcher drops stale prev search params on push to prevent MessageFromUrl's message-param effect from double-firing. * โšก๏ธ perf(screen-capture): pre-upload captures in overlay preview + per-thumbnail status Move uploads from post-submit to preview time, bypassing dataUrl round-trips: - Main process assigns captureId at preview time and ships the PNG bytes as ArrayBuffer to the main renderer via `overlayUploadRequest`. - Main renderer uploads through a dedicated pool (uploadWithProgress, no chatUploadFileList pollution); reports status back to the overlay through `overlayCaptureUploadStatus`. - Overlay thumbnails render a spinner / error badge based on status; the send button stays grey until every capture resolves to `ready`. - Submit now carries only captureIds; MessageFromUrl awaits the pool promises before sendMessage, removing the second upload pass. - Carry overlay-selected modelId/provider into the agent config so the first message actually uses the user-chosen model (fixes the bug where switching the model on the overlay had no effect). * update * โœจ feat(popup): add Quick Chat tray entry backed by Inbox agent Tray menu now exposes a "Quick Chat" action that opens (or focuses) a single-instance popup window at `/popup/agent/inbox`. Each fresh open starts with no active topic; the first message creates one through the normal agent flow. - New `PopupAgentQuickPage` resolves the inbox slug via `builtinAgentSelectors.inboxAgentId` so `activeAgentId` points at the real entity in `agentMap` (fixes the stuck-loading / skeleton state from using the literal `'inbox'` slug). - `BrowserManager.openQuickChatPopup` wraps `createMultiInstanceWindow` with a fixed `topicPopup_quick_inbox` uniqueId so repeat clicks focus rather than spawn. - Wire the action into macOS / Windows / Linux tray menus and add the `tray.quickChat` i18n key. * Add quick chat shortcut and desktop hotkey support * โœจ feat(screen-capture): enhance window enumeration with scale factor support - Updated `enumerateWindows` to accept an optional `displayScaleFactor` parameter for improved window geometry normalization on high-DPI displays. - Refactored `normalizeWindowBounds` to handle scaling based on the provided scale factor, ensuring accurate window dimensions across different platforms. - Adjusted tests in `WindowSourceService.test.ts` to validate the new scaling behavior for both Windows and macOS environments. - Minor adjustments in `ScreenCaptureManager` to accommodate the updated window enumeration logic. --------- Signed-off-by: Innei <tukon479@gmail.com>1 ไธชๆœˆๅ‰
โšก๏ธ perf: warm route chunks after idle (#15109) * โšก๏ธ perf: warm route chunks after idle * ๐Ÿ› fix: normalize platform route chunk ids * โšก๏ธ perf: refine route chunk preloading * ๐Ÿ”ง chore: keep desktop renderer preload unchanged * โšก๏ธ perf: skip renderer chunks in route warmup * โšก๏ธ perf: preload agent route dynamic chunks * โšก๏ธ perf: align route preload deployment urls * โšก๏ธ perf: coalesce stable vendor chunks * โšก๏ธ perf: group shared data runtime chunks * โšก๏ธ perf: group model runtime chunks * โšก๏ธ perf: trim initial route preloads * โšก๏ธ perf: limit idle route micro preloads * โšก๏ธ perf: strip tiny html modulepreloads * โšก๏ธ perf: prune redundant route chunk imports * โšก๏ธ perf: enable rolldown devtools * โšก๏ธ perf: gate vite devtools output * โšก๏ธ perf: optimize react-scan integration and update global types Signed-off-by: Innei <tukon479@gmail.com> * โšก๏ธ perf: support cloud route chunk preload --------- Signed-off-by: Innei <tukon479@gmail.com>1 ๅคฉๅ‰
โ™ป๏ธ refactor(hetero-agent): extract producer pipeline into shared package (#14425) * ๐Ÿ’„ style(todo-progress): use colorFillSecondary so left/right borders are visible against QueueTray The colorBorderSecondary stroke nearly vanished against the dark elevated bg, so the TODO card looked open on the sides when stacked under QueueTray. Match QueueTray's outer border token (colorFillSecondary) for a consistent visible seam; inner dividers keep colorBorderSecondary as a softer secondary level. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * โ™ป๏ธ refactor(hetero-agent): extract producer pipeline into shared package LOBE-8516 phase 0. Move the JSONL framing + adapter conversion + toStreamEvent chain out of the renderer into a new `@lobechat/heterogeneous-agents/spawn` entry, then have desktop main run it before broadcasting. Renderer now consumes ready-made `AgentStreamEvent`s on `heteroAgentEvent`, dropping ~50 lines of in-renderer adapter wiring. This unifies the wire shape across desktop main, the upcoming `lh hetero exec` CLI, and the server `heteroIngest` handler โ€” every consumer gets the same stamped `AgentStreamEvent` with no per-consumer adapter step. The desktop CC flow is unchanged behavior-wise: same adapter, same persistence ordering, same step-boundary semantics; only the seam between main and renderer moved. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * โ™ป๏ธ refactor(hetero-agent): pull codex tracker into shared spawn, drop desktop's gateway-client dep Two cleanups on top of the phase 0 refactor: 1. Move `CodexFileChangeTracker` (+ its test) out of `apps/desktop/src/main/modules/heterogeneousAgent/` into `packages/heterogeneous-agents/src/spawn/`. `AgentStreamPipeline` now auto-instantiates it when `agentType === 'codex'`, so the desktop controller (and the future `lh hetero exec` CLI) stays agent-agnostic โ€” no more "if codex { wire tracker via transformPayload }" branching at the call site. The public `transformPayload` hook is removed since it had no other consumer. 2. Re-export `AgentStreamEvent` / `AgentStreamEventType` from `@lobechat/heterogeneous-agents/spawn` and drop `@lobechat/agent-gateway-client` from `apps/desktop/package.json`. The gateway-client package is a browser-side WebSocket client; producer-side callers (desktop main, sandbox CLI) shouldn't carry it as a direct dep โ€” they only need the type, which now flows through the producer-side entry. Type predicate on Codex payloads tightened to a non-`Required<>` shape so the moved file passes the root tsconfig's `strict: true` (apps/desktop's tsconfig was lax). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ๐Ÿง‘โ€๐Ÿ’ป chore(local-testing): harden electron-dev.sh process management Lifecycle improvements for the local-testing helper so smoke runs against the desktop dev session are reliable: - `find_project_pids` now also catches user-started `bun run dev` Electron sessions (matches by project electron path, not just `--remote-debugging-port`), the launcher subshell saved to PIDFILE, and any process bound to the CDP port. Vite match tightened to `electron-vite[/.].*\bdev\b` so unrelated Vite invocations aren't swept up. - `do_stop` expands seed PIDs into their descendant trees (DFS via `pgrep -P`), SIGTERMs the whole tree, waits 5s, then SIGKILLs survivors. Belt-and-suspenders sweep for stragglers + anything still bound to the CDP port. Closes the long-standing "Helper processes survive the kill" gotcha. - `do_start` detects existing project Electron/vite before tearing it down so the user sees what's being killed; waits for port + user-data-dir locks to release before relaunching to avoid the "user data directory in use" race. - `wait_for_cdp` uses an explicit deadline + early bail-out if the launcher PID dies, instead of the previous fixed-step loop. `wait_for_renderer` no longer pre-sleeps 10s. `setsid` use is intentional; it puts the launched Electron in its own session so the whole tree shares a PGID we can signal in one shot. Note: `setsid` is GNU coreutils โ€” on macOS without `brew install util-linux` the script will fail at the launch step. Documented as a known limitation; no fallback added. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ๐Ÿ› fix(hetero-agent): gate session-complete on stdout fully drained Node may emit `proc.on('exit')` BEFORE child stdio fully closes (documented in child_process: "stdio streams might still be open"). Phase 0 of LOBE-8516 moved adapter ownership to main, so renderer no longer flushes its own adapter on session-complete โ€” meaning trailing events synthesized by `pipeline.flush()` (e.g. Codex's `tool_end` for unfinished tool calls) would race against, and lose to, the `heteroAgentSessionComplete` broadcast, leaving renderer-side persistence to finalize on incomplete state. Fix: in `proc.on('exit')`, await `streamFinished(stdout)` (covers `'end'`, `'close'`, and `'error'`) BEFORE awaiting the broadcast queue. The first await ensures the `stdout.on('end')` handler has had a chance to schedule `pipeline.flush()` onto the queue; the second drains it. Only then do we broadcast complete / error. Regression test repros the documented Node race by emitting `exit` before `stdout.end()` and asserts every `heteroAgentEvent` (including the synthesized `tool_end` from `pipeline.flush()`) lands before `heteroAgentSessionComplete`. Bisected: test fails without the gate, passes with it. Also: add `packages/heterogeneous-agents` to `apps/desktop/pnpm-workspace.yaml` to mirror the new workspace dep added in the phase 0 refactor. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * ๐Ÿ› fix(hetero-agent): drop builtin-tool-claude-code dep, inline the 3 CC wire shapes the adapter needs Phase 0 added `@lobechat/heterogeneous-agents` as a runtime dep of the desktop main process. That transitively pulled in `@lobechat/builtin-tool-claude-code` (declared in the shared package's deps), which the desktop pnpm workspace doesn't list โ€” CI install on the desktop project fails: ERR_PNPM_WORKSPACE_PKG_NOT_FOUND In ../../packages/heterogeneous-agents: "@lobechat/builtin-tool-claude-code@workspace:*" is in the dependencies but no package named "@lobechat/builtin-tool-claude-code" is present in the workspace The dep is also a layer-violation: `heterogeneous-agents` is the producer side (CLI stream โ†’ AgentStreamEvent), `builtin-tool-claude-code` is the UI tool definition (renderers / inspectors / agent template). Producer shouldn't depend on UI-tool packages, even if today the import is just types/constants โ€” the dep cascade still drags `shared-tool-ui` etc. into every workspace that wants the adapter. Fix: inline the three things the adapter actually uses (`'TodoWrite'` tool name string, `TodoWriteArgs` interface, `ClaudeCodeTodoItem` interface). They reflect upstream Claude Code's wire schema โ€” if `claude` ever renames `TodoWrite`, the adapter and the downstream renderers must both update regardless of whether they share a constant. Renderer-side packages (`builtin-tools/codex/TodoListRender`, etc.) keep importing the canonical `ClaudeCodeApiName` from `@lobechat/builtin-tool-claude-code`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>19 ๅคฉๅ‰
โœจ feat(desktop): add dedicated topic popup window with cross-window sync (#13957) * โœจ feat(desktop): add dedicated topic popup window with cross-window sync Introduce a standalone Vite entry for the desktop "open topic in new window" action. The popup is a lightweight SPA (no sidebar, no portal) hosting only the Conversation, and stays in sync with the main window through a BroadcastChannel bus. - Add popup.html + entry.popup.tsx + popupRouter.config.tsx - Add /popup/agent/:aid/:tid and /popup/group/:gid/:tid routes - Reuse main Conversation/ChatInput; wrap in MarketAuth + Hotkeys providers - Pin-on-top button in the popup titlebar (new windows IPC: set/isAlwaysOnTop) - Group topic "open in new window" now uses groupId (previously misused agentId) - Cross-window sync: refreshMessages/refreshTopic emit via BroadcastChannel; subscriber revalidates local SWR caches with echo-loop suppression - Hide WorkingPanel toggle inside /popup (no WorkingSidebar present) - RendererUrlManager dispatches /popup/* to popup.html in prod; dev middleware rewrites SPA deep links while skipping asset/module requests * ๐Ÿ’„ style(desktop): restore loading splash in popup window * โ™ป๏ธ refactor(desktop): replace cross-window sync with popup-ownership guard The BroadcastChannel-based bidirectional sync between the main SPA and the topic popup window had edge cases during streaming. Drop it in favour of a simpler ownership model: when a topic is already open in a popup, the main window shows a "focus popup" redirect instead of rendering a second conversation. - Remove src/libs/crossWindowBus.ts and src/features/CrossWindowSync - Remove postMessagesMutation/postTopicsMutation calls from refresh actions - Add windows.listTopicPopups + windows.focusTopicPopup IPC - Main process broadcasts topicPopupsChanged on popup open/close; parses (scope, id, topicId) from the popup window's /popup/... path - Renderer useTopicPopupsRegistry subscribes to broadcasts and fetches the initial snapshot; useTopicInPopup selects by scope - New TopicInPopupGuard component with "Focus popup window" button - Desktop-only index.desktop.tsx variants for (main)/agent and (main)/group render the guard when the current topic is owned by a popup - i18n: topic.inPopup.title / description / focus in default + en/zh * ๐Ÿ› fix(desktop): re-evaluate popup guard when topic changes Subscribe to the popups array and derive findPopup via useMemo so scope changes (e.g. switching topic in the sidebar while a popup is open) correctly re-compute the guard and let the main window render the newly active topic. * ๐Ÿ› fix(desktop): focus detached topic popup from main window * โœจ feat(desktop): add open in popup window action to menu for active topic Signed-off-by: Innei <tukon479@gmail.com> * ๐ŸŽจ style: sort imports to satisfy simple-import-sort rule * โœจ feat(error): add resetPath prop to ErrorCapture and ErrorBoundary for customizable navigation Signed-off-by: Innei <tukon479@gmail.com> * โ™ป๏ธ refactor: restore ChatHydration in ConversationArea for web/mobile routes Reintroduce ChatHydration component to agent and group ConversationArea so that URL query sync (topic/thread) works on web and mobile routes, not only on desktop entry files. * โœจ feat(electron): enforce absolute base URL in renderer config to fix asset resolution in popup windows Signed-off-by: Innei <tukon479@gmail.com> --------- Signed-off-by: Innei <tukon479@gmail.com>1 ไธชๆœˆๅ‰
๐Ÿ”ง chore: update eslint v2 configuration and suppressions (#12133) * v2 init * chore: update eslint suppressions and package dependencies - Removed several eslint suppressions related to array sorting and reversing from eslint-suppressions.json to clean up the configuration. - Updated @lobehub/lint package version from 2.0.0-beta.6 to 2.0.0-beta.7 in package.json for improvements and bug fixes. - Made minor formatting adjustments in vitest.config.mts and various SKILL.md files for better readability and consistency. Signed-off-by: Innei <tukon479@gmail.com> * fix: clean up import statements and formatting - Removed unnecessary whitespace in replaceComponentImports.ts for improved readability. - Standardized import statements in contextEngineering.ts and createAgentExecutors.ts by adding missing spaces for consistency. Signed-off-by: Innei <tukon479@gmail.com> * chore: update eslint suppressions and clean up code formatting * ๐Ÿ› fix: use vi.hoisted for mock variable initialization Fix TDZ error in persona service test by using vi.hoisted() to ensure mock variables are available when vi.mock factory runs. --------- Signed-off-by: Innei <tukon479@gmail.com> 3 ไธชๆœˆๅ‰
๐Ÿ”ง chore: update eslint v2 configuration and suppressions (#12133) * v2 init * chore: update eslint suppressions and package dependencies - Removed several eslint suppressions related to array sorting and reversing from eslint-suppressions.json to clean up the configuration. - Updated @lobehub/lint package version from 2.0.0-beta.6 to 2.0.0-beta.7 in package.json for improvements and bug fixes. - Made minor formatting adjustments in vitest.config.mts and various SKILL.md files for better readability and consistency. Signed-off-by: Innei <tukon479@gmail.com> * fix: clean up import statements and formatting - Removed unnecessary whitespace in replaceComponentImports.ts for improved readability. - Standardized import statements in contextEngineering.ts and createAgentExecutors.ts by adding missing spaces for consistency. Signed-off-by: Innei <tukon479@gmail.com> * chore: update eslint suppressions and clean up code formatting * ๐Ÿ› fix: use vi.hoisted for mock variable initialization Fix TDZ error in persona service test by using vi.hoisted() to ensure mock variables are available when vi.mock factory runs. --------- Signed-off-by: Innei <tukon479@gmail.com> 3 ไธชๆœˆๅ‰
โœจ feat(electron): enhance native module handling and improve desktop features (#11867) * ๐Ÿ”ง refactor: streamline theme handling and title bar overlay * โœจ feat(titlebar): integrate theme update handling in SimpleTitleBar component * ๐Ÿ”ง chore: move `node-mac-permissions` to optionalDependencies and add TypeScript module declaration * โœจ feat(electron): implement connection drawer state management and enhance auth modal functionality * ๐Ÿ› fix(ci): fix Windows PowerShell Start-Job working directory issue Start-Job runs in a separate process with default user directory, causing npm install-isolated to fail. Fixed by setting correct working directory in each job using $using:workingDir. * ๐Ÿ› fix(ci): use Start-Process instead of Start-Job for Windows parallel install Start-Job runs in isolated PowerShell process without inheriting PATH, causing pnpm/npm commands to fail. Start-Process inherits environment and provides proper exit code handling. * ๐Ÿ› fix(ci): use desktop-build-setup action for Windows build Use the same composite action as other desktop workflows instead of custom PowerShell parallel install which has environment issues. * โœจ feat(menu): enhance context menu with additional options for image and link handling * ๐Ÿ”ง fix(auth-modal): prevent modal from opening during desktop onboarding * โœจ feat(electron): enhance native module handling and improve localization resource loading resolves LOBE-4370 - Added `copyNativeModulesToSource` function to resolve pnpm symlinks for native modules before packaging. - Introduced `getNativeModulesFilesConfig` to explicitly include native modules in the build process. - Updated `electron-builder` configuration to utilize the new functions for better native module management. - Enhanced localization resource loading by splitting JSON files by namespace. * ๐Ÿ› fix(lint): use slice instead of substring * ๐Ÿ› fix(desktop): include global.d.ts in tsconfig for node-mac-permissions types * ๐Ÿ› fix(desktop): add ts-ignore for optional node-mac-permissions module * fix: update ui3 ไธชๆœˆๅ‰
โ™ป๏ธ refactor(cli): extract shared `@lobechat/local-file-shell` package (#12865) * โ™ป๏ธ refactor(cli): extract shared @lobechat/local-file-shell package Extract common file and shell operations from Desktop and CLI into a shared package to eliminate ~1500 lines of duplicated code. CLI now uses @lobechat/file-loaders for rich format support (PDF, DOCX, etc.). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * update * update commands * update version * update deps * refactor version issue * โœจ feat(local-file-shell): add cwd support, move/rename ops, improve logging - Add missing `cwd` parameter to `runCommand` (align with Desktop) - Add `moveLocalFiles` with batch support and detailed error handling - Add `renameLocalFile` with path validation and traversal prevention - Add error logging in shell runner's error/completion handlers Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * support update model and provider in cli * fix desktop build * fix * ๐Ÿ› fix: pin fast-xml-parser to 5.4.2 in bun overrides Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>2 ไธชๆœˆๅ‰