| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
perf(app-server): isolate TypeScript generation from RPC | 1 个月前 | |
perf: multi-dimension optimization pass (build, runtime, UI fluency, startup & bundle size) (#1778) * perf(build): speed up dev and release build pipeline - Run web type-check and vite build in parallel (scripts/build-web-parallel.mjs); enable incremental tsc for web-ui and mobile-web; drop duplicate type-check in desktop packaging CI - Trim dev profile debuginfo to line-tables-only and inject CARGO_PROFILE_DEV_CODEGEN_UNITS=256 into tauri dev (matching preview path) - Switch release profile to thin LTO and panic=abort (packaging regression recommended); remove per-platform LTO override in desktop-package.yml - Skip mobile-web rebuild when inputs are unchanged (mtime short-circuit, --force escape hatch) - Unify image crate to workspace 0.25 (was pinned 0.24 in desktop), migrate computer_use call sites and bridge screenshots-crate buffers at the boundary - Remove forced 100ms polling watcher in vite dev (VITE_USE_POLLING opt-in) - Make build.rs codegen deterministic (sorted keys) in core and cli - Parallelize beforeBuildCommand (web + mobile-web) and dev.cjs prepare steps - Prune unused Monaco NLS language packs (keep en/zh-cn/zh-tw), with verify-monaco-assets guard * perf(runtime): cut hot-path allocations, blocking IO and redundant syscalls - Emit backend->frontend events without unconditional payload deep-copies: peer fanout guard now runs before clone/to_value (global + terminal emitters) - Wrap directory listing in spawn_blocking (aligning with grep/glob tools), drop per-entry re-stat, preallocate results - LSP: take diagnostics by value instead of cloning, share cached diagnostics via Arc, move diagnostics cache to its own lock (no read-lock across await) - Session persistence: sanitize messages copy-on-write, serialize turn snapshots compact instead of pretty - File tree scan: stat once per entry (sort comparator is now syscall-free), reuse metadata for permissions, canonicalize via spawn_blocking, preallocate - Terminal transcript: keep files open with BufWriter and flush on a timer / rotation / close instead of open+write+flush per chunk - ACP tool-call tracker: share raw_input via Arc, removing repeated deep copies - Search: match before allocating per line, drop redundant is_file stats, return sink results without split/join round-trip, mem::take result buffers - File watcher: replace per-event block_on with sync path-table snapshot, register watches incrementally instead of rebuilding the watcher - PTY output: zero-copy UTF-8 conversion, Arc<str> tap fan-out, byte ring buffer for head/tail capture - Statically cache front-matter regex; evict per-path persistence locks (Weak) * perf(startup): parallelize backend init, dedupe Monaco, shrink assets - Run independent startup steps (i18n, AI client factory, log level) with tokio::join! after config init; bound the workspace bootstrap snapshot block_on with a 4s timeout falling back to the frontend init command - Stop bundling a second ESM copy of Monaco into the entry chunk: all monaco-editor value imports become type imports, runtime access goes through the AMD loader singleton (new monacoRuntime accessor). Entry chunk 5.44 MB -> 2.14 MB (-61%) - Replace three static Noto Sans SC weights (12.7 MB) with the fontsource variable font (4.6 MB) - Recompress oversized PNGs (logo, panda art, pet spritesheet) preserving alpha and dimensions (-2.85 MB) * perf(ui): keep streaming and interactions off the re-render hot path - Split FlowChatContext into stable (callbacks + scalar ids) and volatile contexts; stop depending on the whole activeSession object so streaming flushes no longer re-render every visible message past React.memo - Stabilize Markdown renderer props (useCallback) so completed messages skip remark re-parsing during streaming - Nav divider drag writes --nav-width directly with rAF batching; state commits on mouseup; unmount cleanup for window listeners - Replace per-message window resize listeners with a shared ResizeObserver - Desktop pet: typewriter moves to rAF with ref targets (no interval churn), 120ms cursor polling pauses when hidden/idle and caches rects - Fine-grained zustand selectors for canvas store consumers and message edit state (editingTurnId gating) - rAF-throttle scroll handlers (file explorer, insights, explore groups) and Tooltip scroll tracking (passive, merged state) - EventBus history becomes a ring buffer; payload references only kept in dev - Fix listener leaks/races: GitStateManager dispose, PeerHostInvokeBridge and useWindowControls await-races, WorkspaceAPI abort listener, App.tsx disposed flags, tool-execution-service unlisten tracking - Cap second-tier session list expansion with incremental loading - Narrow transition properties in resizer/session styles (no layout-property hover animations) * docs(performance): add multi-dimension performance review reports Four review reports (compile/build, runtime, UI fluency, startup & bundle size) backing the optimizations in this branch, including the findings that were intentionally deferred as follow-ups. * fix(build): repair image 0.25 migration in test code, drop panic=abort The JpegEncoder in the computer_use integration test still used the image 0.24 by-value encode signature, breaking cargo test -p bitfun-desktop (CI Rust Build Check) even though cargo check on the lib target passed. Also revert panic = "abort" from the release profile: browser_get_url and the relay client's TLS setup deliberately use catch_unwind to contain known third-party panics, and aborting would convert those recoverable errors into process crashes. Thin LTO is kept. * fix(runtime): repair regressions found reviewing the optimization pass - file_watch: re-registering an existing path was a no-op after the switch to incremental watch registration. ensure_watch_roots marks a vanished root inactive without calling unwatch_path, so when the directory reappeared the watch was never restored and that root silently stopped reporting changes (the old code rebuilt the whole watcher every time, which hid this). Now re-registration always unwatches before watching again; covered by a new file_watch contract test. - transcript: buffering moved structured markers (command, cwd, exit code, resume/finish) off the immediate-write path, so a crash or force-quit could lose the anchors agents grep for. Markers now flush immediately (carrying any buffered output with them) while plain output keeps the buffered write. - grep: returning sink results as one entry per match changed head_limit and offset from physical lines to match blocks in multiline mode. Entries are split again only when they actually contain newlines. * fix(ui): repair regressions found reviewing the optimization pass - UserMessageItem: the shared ResizeObserver captured the content node at effect time, while the window listener it replaced re-read the ref on every event. contentRef is attached inside conditional branches, so leaving edit mode or a turn failing left the observer bound to a detached node — the overflow/expand affordance froze and the node leaked. Re-observe when those branches change. - Desktop pet: the new getBoundingClientRect cache was only invalidated on size/overlay/task changes, but typewriter output grows bubbles and shifts the ones below, so hover hit-testing used stale rects for a whole streaming task. The cache epoch now also advances on typed-output flush. - Nav drag: a drop landing between animation frames left the DOM at the last painted width because React only rewrites the CSS variable when the committed width actually changes. The final width is now applied synchronously on cleanup, while the transition is still suppressed. - SessionScene: narrowing the transition list dropped box-shadow, which those resizer handles animate on hover — restored. - sharedResizeObserver: one throwing subscriber aborted the entry batch and killed resize handling for every observed element (a failure mode introduced by sharing the observer). Each callback is now isolated. - EventBus: the dev gate used process.env.NODE_ENV, which never resolves in the Vite browser build, so payloads were dropped even in dev, contrary to the documented behavior. Use import.meta.env.DEV. - Add monacoRuntime tests asserting the lazy proxy fails diagnosably when the runtime has not been injected yet. * docs(build): document the new build escape hatches; keep piped output intact The optimization pass traded some flexibility for speed without saying so anywhere a contributor would look. Document CARGO_PROFILE_DEV_DEBUG=2 (the dev profile now ships line-tables-only), BITFUN_MOBILE_WEB_FORCE_BUILD=1 / --force (mobile-web builds are skipped when its dist is up to date) and VITE_USE_POLLING=1 (native watch events are the default again), plus a note that build:web now interleaves prefixed type-check and bundler output. The two parallel build wrappers also ended with process.exit(), which drops whatever is still queued on stdout when it is a pipe — as it is under CI. Set process.exitCode instead and let the process end on its own. * test(review): harden second-review findings - grep: add a multiline + head_limit test pinning pagination to physical lines (the property the earlier fix restored) - sharedResizeObserver: report subscriber callback errors instead of swallowing them silently - vite: when the project sits on a UNC share or WSL mount during dev, print a one-line hint about VITE_USE_POLLING=1 — users upgrading from the polling-based watcher would otherwise silently lose HMR there * chore(review): fix stale comments, drop dead API, gate new tests in CI Final read-through of the whole diff: - workspace_manager: the comment justified the dedicated cache handle by contention with "start_server's write lock", but nothing in the repo ever takes that lock for writing. Describe what the handle actually avoids. - markdown: front_matter_regex() was introduced with no callers (agent-runtime cannot depend on services-core and keeps its own static), so use the static directly and drop the exported wrapper. - dev.cjs / prune-monaco-nls.cjs: comments overstated what they do — the dev codegen-units override only matters with CARGO_INCREMENTAL=0, and the 1.4 MB figure covers the seven pruned NLS packs, not all nine. - fonts README still described the three deleted static weights as the directory's contents; rewrite it for the variable subset build. - CI: the file watch contract suite sits behind a non-default feature and neither it nor tool-runtime were in any cargo test step, so the regression guards added by this PR never ran. Add both to the OS matrix, matching the existing rationale for platform-sensitive contract suites. Also address the frontend read-through: move a render-phase ref write into the layout effect that already batches with it, use the repo's logger instead of a bare console.error, and assert repo-wide that monaco-editor is only ever imported as a type (the guard that keeps the 3.4 MB ESM copy out of the entry chunk). * ci: scope the new Rust test steps to green platform combinations Enabling these suites surfaced failures that predate this branch: - the file watch contracts fail on macOS (debounce and atomic-rename contracts time out under FSEvents coalescing) — tests this branch does not touch, on a suite that has never run in CI - tool-runtime's glob tests fail on Windows (walk-root derivation handles separators differently) — this branch does not touch glob at all Neither belongs to a performance change, so run what is green rather than either turning CI red or dropping the coverage: file watch on Linux and Windows (the platforms whose watch registration this branch alters), and the search module where the grep changes live. Both deserve their own fix. * ci: quote the search test filter so the workflow parses search:: at the end of an unquoted YAML scalar reads as a nested mapping, which made the whole workflow file invalid — GitHub failed the run at startup with no jobs at all. --------- Co-authored-by: bowen628 <bowen628@noreply.gitcode.com> | 2 个月前 | |
perf: multi-dimension optimization pass (build, runtime, UI fluency, startup & bundle size) (#1778) * perf(build): speed up dev and release build pipeline - Run web type-check and vite build in parallel (scripts/build-web-parallel.mjs); enable incremental tsc for web-ui and mobile-web; drop duplicate type-check in desktop packaging CI - Trim dev profile debuginfo to line-tables-only and inject CARGO_PROFILE_DEV_CODEGEN_UNITS=256 into tauri dev (matching preview path) - Switch release profile to thin LTO and panic=abort (packaging regression recommended); remove per-platform LTO override in desktop-package.yml - Skip mobile-web rebuild when inputs are unchanged (mtime short-circuit, --force escape hatch) - Unify image crate to workspace 0.25 (was pinned 0.24 in desktop), migrate computer_use call sites and bridge screenshots-crate buffers at the boundary - Remove forced 100ms polling watcher in vite dev (VITE_USE_POLLING opt-in) - Make build.rs codegen deterministic (sorted keys) in core and cli - Parallelize beforeBuildCommand (web + mobile-web) and dev.cjs prepare steps - Prune unused Monaco NLS language packs (keep en/zh-cn/zh-tw), with verify-monaco-assets guard * perf(runtime): cut hot-path allocations, blocking IO and redundant syscalls - Emit backend->frontend events without unconditional payload deep-copies: peer fanout guard now runs before clone/to_value (global + terminal emitters) - Wrap directory listing in spawn_blocking (aligning with grep/glob tools), drop per-entry re-stat, preallocate results - LSP: take diagnostics by value instead of cloning, share cached diagnostics via Arc, move diagnostics cache to its own lock (no read-lock across await) - Session persistence: sanitize messages copy-on-write, serialize turn snapshots compact instead of pretty - File tree scan: stat once per entry (sort comparator is now syscall-free), reuse metadata for permissions, canonicalize via spawn_blocking, preallocate - Terminal transcript: keep files open with BufWriter and flush on a timer / rotation / close instead of open+write+flush per chunk - ACP tool-call tracker: share raw_input via Arc, removing repeated deep copies - Search: match before allocating per line, drop redundant is_file stats, return sink results without split/join round-trip, mem::take result buffers - File watcher: replace per-event block_on with sync path-table snapshot, register watches incrementally instead of rebuilding the watcher - PTY output: zero-copy UTF-8 conversion, Arc<str> tap fan-out, byte ring buffer for head/tail capture - Statically cache front-matter regex; evict per-path persistence locks (Weak) * perf(startup): parallelize backend init, dedupe Monaco, shrink assets - Run independent startup steps (i18n, AI client factory, log level) with tokio::join! after config init; bound the workspace bootstrap snapshot block_on with a 4s timeout falling back to the frontend init command - Stop bundling a second ESM copy of Monaco into the entry chunk: all monaco-editor value imports become type imports, runtime access goes through the AMD loader singleton (new monacoRuntime accessor). Entry chunk 5.44 MB -> 2.14 MB (-61%) - Replace three static Noto Sans SC weights (12.7 MB) with the fontsource variable font (4.6 MB) - Recompress oversized PNGs (logo, panda art, pet spritesheet) preserving alpha and dimensions (-2.85 MB) * perf(ui): keep streaming and interactions off the re-render hot path - Split FlowChatContext into stable (callbacks + scalar ids) and volatile contexts; stop depending on the whole activeSession object so streaming flushes no longer re-render every visible message past React.memo - Stabilize Markdown renderer props (useCallback) so completed messages skip remark re-parsing during streaming - Nav divider drag writes --nav-width directly with rAF batching; state commits on mouseup; unmount cleanup for window listeners - Replace per-message window resize listeners with a shared ResizeObserver - Desktop pet: typewriter moves to rAF with ref targets (no interval churn), 120ms cursor polling pauses when hidden/idle and caches rects - Fine-grained zustand selectors for canvas store consumers and message edit state (editingTurnId gating) - rAF-throttle scroll handlers (file explorer, insights, explore groups) and Tooltip scroll tracking (passive, merged state) - EventBus history becomes a ring buffer; payload references only kept in dev - Fix listener leaks/races: GitStateManager dispose, PeerHostInvokeBridge and useWindowControls await-races, WorkspaceAPI abort listener, App.tsx disposed flags, tool-execution-service unlisten tracking - Cap second-tier session list expansion with incremental loading - Narrow transition properties in resizer/session styles (no layout-property hover animations) * docs(performance): add multi-dimension performance review reports Four review reports (compile/build, runtime, UI fluency, startup & bundle size) backing the optimizations in this branch, including the findings that were intentionally deferred as follow-ups. * fix(build): repair image 0.25 migration in test code, drop panic=abort The JpegEncoder in the computer_use integration test still used the image 0.24 by-value encode signature, breaking cargo test -p bitfun-desktop (CI Rust Build Check) even though cargo check on the lib target passed. Also revert panic = "abort" from the release profile: browser_get_url and the relay client's TLS setup deliberately use catch_unwind to contain known third-party panics, and aborting would convert those recoverable errors into process crashes. Thin LTO is kept. * fix(runtime): repair regressions found reviewing the optimization pass - file_watch: re-registering an existing path was a no-op after the switch to incremental watch registration. ensure_watch_roots marks a vanished root inactive without calling unwatch_path, so when the directory reappeared the watch was never restored and that root silently stopped reporting changes (the old code rebuilt the whole watcher every time, which hid this). Now re-registration always unwatches before watching again; covered by a new file_watch contract test. - transcript: buffering moved structured markers (command, cwd, exit code, resume/finish) off the immediate-write path, so a crash or force-quit could lose the anchors agents grep for. Markers now flush immediately (carrying any buffered output with them) while plain output keeps the buffered write. - grep: returning sink results as one entry per match changed head_limit and offset from physical lines to match blocks in multiline mode. Entries are split again only when they actually contain newlines. * fix(ui): repair regressions found reviewing the optimization pass - UserMessageItem: the shared ResizeObserver captured the content node at effect time, while the window listener it replaced re-read the ref on every event. contentRef is attached inside conditional branches, so leaving edit mode or a turn failing left the observer bound to a detached node — the overflow/expand affordance froze and the node leaked. Re-observe when those branches change. - Desktop pet: the new getBoundingClientRect cache was only invalidated on size/overlay/task changes, but typewriter output grows bubbles and shifts the ones below, so hover hit-testing used stale rects for a whole streaming task. The cache epoch now also advances on typed-output flush. - Nav drag: a drop landing between animation frames left the DOM at the last painted width because React only rewrites the CSS variable when the committed width actually changes. The final width is now applied synchronously on cleanup, while the transition is still suppressed. - SessionScene: narrowing the transition list dropped box-shadow, which those resizer handles animate on hover — restored. - sharedResizeObserver: one throwing subscriber aborted the entry batch and killed resize handling for every observed element (a failure mode introduced by sharing the observer). Each callback is now isolated. - EventBus: the dev gate used process.env.NODE_ENV, which never resolves in the Vite browser build, so payloads were dropped even in dev, contrary to the documented behavior. Use import.meta.env.DEV. - Add monacoRuntime tests asserting the lazy proxy fails diagnosably when the runtime has not been injected yet. * docs(build): document the new build escape hatches; keep piped output intact The optimization pass traded some flexibility for speed without saying so anywhere a contributor would look. Document CARGO_PROFILE_DEV_DEBUG=2 (the dev profile now ships line-tables-only), BITFUN_MOBILE_WEB_FORCE_BUILD=1 / --force (mobile-web builds are skipped when its dist is up to date) and VITE_USE_POLLING=1 (native watch events are the default again), plus a note that build:web now interleaves prefixed type-check and bundler output. The two parallel build wrappers also ended with process.exit(), which drops whatever is still queued on stdout when it is a pipe — as it is under CI. Set process.exitCode instead and let the process end on its own. * test(review): harden second-review findings - grep: add a multiline + head_limit test pinning pagination to physical lines (the property the earlier fix restored) - sharedResizeObserver: report subscriber callback errors instead of swallowing them silently - vite: when the project sits on a UNC share or WSL mount during dev, print a one-line hint about VITE_USE_POLLING=1 — users upgrading from the polling-based watcher would otherwise silently lose HMR there * chore(review): fix stale comments, drop dead API, gate new tests in CI Final read-through of the whole diff: - workspace_manager: the comment justified the dedicated cache handle by contention with "start_server's write lock", but nothing in the repo ever takes that lock for writing. Describe what the handle actually avoids. - markdown: front_matter_regex() was introduced with no callers (agent-runtime cannot depend on services-core and keeps its own static), so use the static directly and drop the exported wrapper. - dev.cjs / prune-monaco-nls.cjs: comments overstated what they do — the dev codegen-units override only matters with CARGO_INCREMENTAL=0, and the 1.4 MB figure covers the seven pruned NLS packs, not all nine. - fonts README still described the three deleted static weights as the directory's contents; rewrite it for the variable subset build. - CI: the file watch contract suite sits behind a non-default feature and neither it nor tool-runtime were in any cargo test step, so the regression guards added by this PR never ran. Add both to the OS matrix, matching the existing rationale for platform-sensitive contract suites. Also address the frontend read-through: move a render-phase ref write into the layout effect that already batches with it, use the repo's logger instead of a bare console.error, and assert repo-wide that monaco-editor is only ever imported as a type (the guard that keeps the 3.4 MB ESM copy out of the entry chunk). * ci: scope the new Rust test steps to green platform combinations Enabling these suites surfaced failures that predate this branch: - the file watch contracts fail on macOS (debounce and atomic-rename contracts time out under FSEvents coalescing) — tests this branch does not touch, on a suite that has never run in CI - tool-runtime's glob tests fail on Windows (walk-root derivation handles separators differently) — this branch does not touch glob at all Neither belongs to a performance change, so run what is green rather than either turning CI red or dropping the coverage: file watch on Linux and Windows (the platforms whose watch registration this branch alters), and the search module where the grep changes live. Both deserve their own fix. * ci: quote the search test filter so the workflow parses search:: at the end of an unquoted YAML scalar reads as a nested mapping, which made the whole workflow file invalid — GitHub failed the run at startup with no jobs at all. --------- Co-authored-by: bowen628 <bowen628@noreply.gitcode.com> | 2 个月前 | |
perf: multi-dimension optimization pass (build, runtime, UI fluency, startup & bundle size) (#1778) * perf(build): speed up dev and release build pipeline - Run web type-check and vite build in parallel (scripts/build-web-parallel.mjs); enable incremental tsc for web-ui and mobile-web; drop duplicate type-check in desktop packaging CI - Trim dev profile debuginfo to line-tables-only and inject CARGO_PROFILE_DEV_CODEGEN_UNITS=256 into tauri dev (matching preview path) - Switch release profile to thin LTO and panic=abort (packaging regression recommended); remove per-platform LTO override in desktop-package.yml - Skip mobile-web rebuild when inputs are unchanged (mtime short-circuit, --force escape hatch) - Unify image crate to workspace 0.25 (was pinned 0.24 in desktop), migrate computer_use call sites and bridge screenshots-crate buffers at the boundary - Remove forced 100ms polling watcher in vite dev (VITE_USE_POLLING opt-in) - Make build.rs codegen deterministic (sorted keys) in core and cli - Parallelize beforeBuildCommand (web + mobile-web) and dev.cjs prepare steps - Prune unused Monaco NLS language packs (keep en/zh-cn/zh-tw), with verify-monaco-assets guard * perf(runtime): cut hot-path allocations, blocking IO and redundant syscalls - Emit backend->frontend events without unconditional payload deep-copies: peer fanout guard now runs before clone/to_value (global + terminal emitters) - Wrap directory listing in spawn_blocking (aligning with grep/glob tools), drop per-entry re-stat, preallocate results - LSP: take diagnostics by value instead of cloning, share cached diagnostics via Arc, move diagnostics cache to its own lock (no read-lock across await) - Session persistence: sanitize messages copy-on-write, serialize turn snapshots compact instead of pretty - File tree scan: stat once per entry (sort comparator is now syscall-free), reuse metadata for permissions, canonicalize via spawn_blocking, preallocate - Terminal transcript: keep files open with BufWriter and flush on a timer / rotation / close instead of open+write+flush per chunk - ACP tool-call tracker: share raw_input via Arc, removing repeated deep copies - Search: match before allocating per line, drop redundant is_file stats, return sink results without split/join round-trip, mem::take result buffers - File watcher: replace per-event block_on with sync path-table snapshot, register watches incrementally instead of rebuilding the watcher - PTY output: zero-copy UTF-8 conversion, Arc<str> tap fan-out, byte ring buffer for head/tail capture - Statically cache front-matter regex; evict per-path persistence locks (Weak) * perf(startup): parallelize backend init, dedupe Monaco, shrink assets - Run independent startup steps (i18n, AI client factory, log level) with tokio::join! after config init; bound the workspace bootstrap snapshot block_on with a 4s timeout falling back to the frontend init command - Stop bundling a second ESM copy of Monaco into the entry chunk: all monaco-editor value imports become type imports, runtime access goes through the AMD loader singleton (new monacoRuntime accessor). Entry chunk 5.44 MB -> 2.14 MB (-61%) - Replace three static Noto Sans SC weights (12.7 MB) with the fontsource variable font (4.6 MB) - Recompress oversized PNGs (logo, panda art, pet spritesheet) preserving alpha and dimensions (-2.85 MB) * perf(ui): keep streaming and interactions off the re-render hot path - Split FlowChatContext into stable (callbacks + scalar ids) and volatile contexts; stop depending on the whole activeSession object so streaming flushes no longer re-render every visible message past React.memo - Stabilize Markdown renderer props (useCallback) so completed messages skip remark re-parsing during streaming - Nav divider drag writes --nav-width directly with rAF batching; state commits on mouseup; unmount cleanup for window listeners - Replace per-message window resize listeners with a shared ResizeObserver - Desktop pet: typewriter moves to rAF with ref targets (no interval churn), 120ms cursor polling pauses when hidden/idle and caches rects - Fine-grained zustand selectors for canvas store consumers and message edit state (editingTurnId gating) - rAF-throttle scroll handlers (file explorer, insights, explore groups) and Tooltip scroll tracking (passive, merged state) - EventBus history becomes a ring buffer; payload references only kept in dev - Fix listener leaks/races: GitStateManager dispose, PeerHostInvokeBridge and useWindowControls await-races, WorkspaceAPI abort listener, App.tsx disposed flags, tool-execution-service unlisten tracking - Cap second-tier session list expansion with incremental loading - Narrow transition properties in resizer/session styles (no layout-property hover animations) * docs(performance): add multi-dimension performance review reports Four review reports (compile/build, runtime, UI fluency, startup & bundle size) backing the optimizations in this branch, including the findings that were intentionally deferred as follow-ups. * fix(build): repair image 0.25 migration in test code, drop panic=abort The JpegEncoder in the computer_use integration test still used the image 0.24 by-value encode signature, breaking cargo test -p bitfun-desktop (CI Rust Build Check) even though cargo check on the lib target passed. Also revert panic = "abort" from the release profile: browser_get_url and the relay client's TLS setup deliberately use catch_unwind to contain known third-party panics, and aborting would convert those recoverable errors into process crashes. Thin LTO is kept. * fix(runtime): repair regressions found reviewing the optimization pass - file_watch: re-registering an existing path was a no-op after the switch to incremental watch registration. ensure_watch_roots marks a vanished root inactive without calling unwatch_path, so when the directory reappeared the watch was never restored and that root silently stopped reporting changes (the old code rebuilt the whole watcher every time, which hid this). Now re-registration always unwatches before watching again; covered by a new file_watch contract test. - transcript: buffering moved structured markers (command, cwd, exit code, resume/finish) off the immediate-write path, so a crash or force-quit could lose the anchors agents grep for. Markers now flush immediately (carrying any buffered output with them) while plain output keeps the buffered write. - grep: returning sink results as one entry per match changed head_limit and offset from physical lines to match blocks in multiline mode. Entries are split again only when they actually contain newlines. * fix(ui): repair regressions found reviewing the optimization pass - UserMessageItem: the shared ResizeObserver captured the content node at effect time, while the window listener it replaced re-read the ref on every event. contentRef is attached inside conditional branches, so leaving edit mode or a turn failing left the observer bound to a detached node — the overflow/expand affordance froze and the node leaked. Re-observe when those branches change. - Desktop pet: the new getBoundingClientRect cache was only invalidated on size/overlay/task changes, but typewriter output grows bubbles and shifts the ones below, so hover hit-testing used stale rects for a whole streaming task. The cache epoch now also advances on typed-output flush. - Nav drag: a drop landing between animation frames left the DOM at the last painted width because React only rewrites the CSS variable when the committed width actually changes. The final width is now applied synchronously on cleanup, while the transition is still suppressed. - SessionScene: narrowing the transition list dropped box-shadow, which those resizer handles animate on hover — restored. - sharedResizeObserver: one throwing subscriber aborted the entry batch and killed resize handling for every observed element (a failure mode introduced by sharing the observer). Each callback is now isolated. - EventBus: the dev gate used process.env.NODE_ENV, which never resolves in the Vite browser build, so payloads were dropped even in dev, contrary to the documented behavior. Use import.meta.env.DEV. - Add monacoRuntime tests asserting the lazy proxy fails diagnosably when the runtime has not been injected yet. * docs(build): document the new build escape hatches; keep piped output intact The optimization pass traded some flexibility for speed without saying so anywhere a contributor would look. Document CARGO_PROFILE_DEV_DEBUG=2 (the dev profile now ships line-tables-only), BITFUN_MOBILE_WEB_FORCE_BUILD=1 / --force (mobile-web builds are skipped when its dist is up to date) and VITE_USE_POLLING=1 (native watch events are the default again), plus a note that build:web now interleaves prefixed type-check and bundler output. The two parallel build wrappers also ended with process.exit(), which drops whatever is still queued on stdout when it is a pipe — as it is under CI. Set process.exitCode instead and let the process end on its own. * test(review): harden second-review findings - grep: add a multiline + head_limit test pinning pagination to physical lines (the property the earlier fix restored) - sharedResizeObserver: report subscriber callback errors instead of swallowing them silently - vite: when the project sits on a UNC share or WSL mount during dev, print a one-line hint about VITE_USE_POLLING=1 — users upgrading from the polling-based watcher would otherwise silently lose HMR there * chore(review): fix stale comments, drop dead API, gate new tests in CI Final read-through of the whole diff: - workspace_manager: the comment justified the dedicated cache handle by contention with "start_server's write lock", but nothing in the repo ever takes that lock for writing. Describe what the handle actually avoids. - markdown: front_matter_regex() was introduced with no callers (agent-runtime cannot depend on services-core and keeps its own static), so use the static directly and drop the exported wrapper. - dev.cjs / prune-monaco-nls.cjs: comments overstated what they do — the dev codegen-units override only matters with CARGO_INCREMENTAL=0, and the 1.4 MB figure covers the seven pruned NLS packs, not all nine. - fonts README still described the three deleted static weights as the directory's contents; rewrite it for the variable subset build. - CI: the file watch contract suite sits behind a non-default feature and neither it nor tool-runtime were in any cargo test step, so the regression guards added by this PR never ran. Add both to the OS matrix, matching the existing rationale for platform-sensitive contract suites. Also address the frontend read-through: move a render-phase ref write into the layout effect that already batches with it, use the repo's logger instead of a bare console.error, and assert repo-wide that monaco-editor is only ever imported as a type (the guard that keeps the 3.4 MB ESM copy out of the entry chunk). * ci: scope the new Rust test steps to green platform combinations Enabling these suites surfaced failures that predate this branch: - the file watch contracts fail on macOS (debounce and atomic-rename contracts time out under FSEvents coalescing) — tests this branch does not touch, on a suite that has never run in CI - tool-runtime's glob tests fail on Windows (walk-root derivation handles separators differently) — this branch does not touch glob at all Neither belongs to a performance change, so run what is green rather than either turning CI red or dropping the coverage: file watch on Linux and Windows (the platforms whose watch registration this branch alters), and the search module where the grep changes live. Both deserve their own fix. * ci: quote the search test filter so the workflow parses search:: at the end of an unquoted YAML scalar reads as a nested mapping, which made the whole workflow file invalid — GitHub failed the run at startup with no jobs at all. --------- Co-authored-by: bowen628 <bowen628@noreply.gitcode.com> | 2 个月前 |
| 文件 | 最后提交记录 | 最后更新时间 |
|---|---|---|
| 1 个月前 | ||
| 2 个月前 | ||
| 2 个月前 | ||
| 2 个月前 |